Tpetra parallel linear algebra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Tpetra_Details_FixedHashTable_decl.hpp
1 // @HEADER
2 // *****************************************************************************
3 // Tpetra: Templated Linear Algebra Services Package
4 //
5 // Copyright 2008 NTESS and the Tpetra contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef TPETRA_DETAILS_FIXEDHASHTABLE_DECL_HPP
11 #define TPETRA_DETAILS_FIXEDHASHTABLE_DECL_HPP
12 
13 #include "Tpetra_Details_Hash.hpp"
17 
18 #include "Teuchos_Describable.hpp"
19 #include "Teuchos_FancyOStream.hpp"
20 #include "Teuchos_VerbosityLevel.hpp"
21 
22 #include "Kokkos_Core.hpp"
23 #include "Kokkos_ArithTraits.hpp"
24 
25 namespace Tpetra {
26 namespace Details {
27 
53 template<class KeyType,
54  class ValueType,
55  class DeviceType>
57 private:
58  typedef typename DeviceType::execution_space execution_space;
59  typedef typename DeviceType::memory_space memory_space;
60  typedef Kokkos::Device<execution_space, memory_space> device_type;
61 
63  typedef typename hash_type::offset_type offset_type;
64 
72  typedef typename Kokkos::View<const offset_type*, Kokkos::LayoutLeft,
73  device_type> ptr_type;
80  typedef typename Kokkos::View<const Kokkos::pair<KeyType, ValueType>*,
81  Kokkos::LayoutLeft, device_type> val_type;
82 
89  KOKKOS_INLINE_FUNCTION bool hasContiguousValues () const {
90  return contiguousValues_;
91  }
92 
93 public:
97  typedef Kokkos::View<const KeyType*, Kokkos::LayoutLeft, device_type> keys_type;
98 
100  KOKKOS_DEFAULTED_FUNCTION FixedHashTable() = default;
101 
111  FixedHashTable (const keys_type& keys);
112 
120  FixedHashTable (const Teuchos::ArrayView<const KeyType>& keys);
121 
135  FixedHashTable (const keys_type& keys,
136  const ValueType startingValue);
137 
149  FixedHashTable (const Teuchos::ArrayView<const KeyType>& keys,
150  const ValueType startingValue);
151 
170  FixedHashTable (const keys_type& keys,
171  const KeyType firstContigKey,
172  const KeyType lastContigKey,
173  const ValueType startingValue);
174 
190  FixedHashTable (const Teuchos::ArrayView<const KeyType>& keys,
191  const KeyType firstContigKey,
192  const KeyType lastContigKey,
193  const ValueType startingValue);
194 
203  FixedHashTable (const Teuchos::ArrayView<const KeyType>& keys,
204  const Teuchos::ArrayView<const ValueType>& vals);
205 
206  template<class K, class V, class D>
207  friend class FixedHashTable;
208 
214  template<class InDeviceType>
216  typename std::enable_if<! std::is_same<DeviceType, InDeviceType>::value, int>::type* = NULL)
217  {
218  using Kokkos::ViewAllocateWithoutInitializing;
219  typedef typename ptr_type::non_const_type nonconst_ptr_type;
220  typedef typename val_type::non_const_type nonconst_val_type;
221 
222  Tpetra::Details::ProfilingRegion pr("Tpetra::Details::FixedHashTable::ctor(InDeviceType)");
223 
224  // FIXME (mfh 28 May 2015) The code below _always_ copies. This
225  // shouldn't be necessary if the input and output memory spaces
226  // are the same. However, it is always correct.
227 
228  // Different Devices may have different offset_type, because
229  // offset_type comes from the memory space's size_type typedef.
230  // That's why we use a specialized deep copy function here instead
231  // of Kokkos::deep_copy.
232  nonconst_ptr_type ptr (ViewAllocateWithoutInitializing ("Tpetra::FixedHashTable::ptr"),
233  src.ptr_.extent (0));
234  ::Tpetra::Details::copyOffsets (ptr, src.ptr_);
235  nonconst_val_type val (ViewAllocateWithoutInitializing ("Tpetra::FixedHashTable::val"),
236  src.val_.extent (0));
237  // val and src.val_ have the same entry types, unlike (possibly)
238  // ptr and src.ptr_. Thus, we can use Kokkos::deep_copy here.
239  // DEEP_COPY REVIEW - DEVICE-TO-DEVICE
240  Kokkos::deep_copy (execution_space(), val, src.val_);
241 
242  this->ptr_ = ptr;
243  this->val_ = val;
244  this->minKey_ = src.minKey_;
245  this->maxKey_ = src.maxKey_;
246  this->minVal_ = src.minVal_;
247  this->maxVal_ = src.maxVal_;
248  this->firstContigKey_ = src.firstContigKey_;
249  this->lastContigKey_ = src.lastContigKey_;
250  this->contiguousValues_ = src.contiguousValues_;
251  this->checkedForDuplicateKeys_ = src.checkedForDuplicateKeys_;
252  this->hasDuplicateKeys_ = src.hasDuplicateKeys_;
253  }
254 
256  KOKKOS_INLINE_FUNCTION ValueType get (const KeyType& key) const {
257  const offset_type size = this->getSize ();
258  if (size == 0) {
259  // Don't use Teuchos::OrdinalTraits or std::numeric_limits here,
260  // because neither have the right device function markings.
261  return Tpetra::Details::OrdinalTraits<ValueType>::invalid ();
262  }
263 
264  // If this object assumes contiguous values, then it doesn't store
265  // the initial sequence of >= 1 contiguous keys in the table.
266  if (this->hasContiguousValues () &&
267  key >= firstContigKey_ && key <= lastContigKey_) {
268  return static_cast<ValueType> (key - firstContigKey_) + this->minVal ();
269  }
270 
271  const typename hash_type::result_type hashVal =
272  hash_type::hashFunc (key, size);
273 
274  const offset_type start = ptr_[hashVal];
275  const offset_type end = ptr_[hashVal+1];
276  for (offset_type k = start; k < end; ++k) {
277  if (val_[k].first == key) {
278  return val_[k].second;
279  }
280  }
281 
282  // Don't use Teuchos::OrdinalTraits or std::numeric_limits here,
283  // because neither have the right device function markings.
284  return Tpetra::Details::OrdinalTraits<ValueType>::invalid ();
285  }
286 
290  KOKKOS_INLINE_FUNCTION offset_type numPairs () const {
291  // NOTE (mfh 26 May 2015) Using val_.extent(0) only works
292  // because the table stores pairs with duplicate keys separately.
293  // If the table didn't do that, we would have to keep a separate
294  // numPairs_ field (remembering the size of the input array of
295  // keys).
296  if (this->hasContiguousValues ()) {
297  return val_.extent (0) + static_cast<offset_type> (lastContigKey_ - firstContigKey_);
298  }
299  else {
300  return val_.extent (0);
301  }
302  }
303 
312  KOKKOS_INLINE_FUNCTION KeyType minKey () const {
313  return minKey_;
314  }
315 
324  KOKKOS_INLINE_FUNCTION KeyType maxKey () const {
325  return maxKey_;
326  }
327 
335  KOKKOS_INLINE_FUNCTION ValueType minVal () const {
336  return minVal_;
337  }
338 
346  KOKKOS_INLINE_FUNCTION ValueType maxVal () const {
347  return maxVal_;
348  }
349 
362  bool hasDuplicateKeys ();
363 
369 
370  std::string description () const;
372 
374  void
375  describe (Teuchos::FancyOStream &out,
376  const Teuchos::EVerbosityLevel verbLevel=
377  Teuchos::Describable::verbLevel_default) const;
379 
380 private:
382  ptr_type ptr_;
384  val_type val_;
385 
391  KeyType minKey_ = ::Kokkos::ArithTraits<KeyType>::max();
392 
398  KeyType maxKey_ = ::Kokkos::ArithTraits<KeyType>::max();
399 
404  ValueType minVal_ = ::Kokkos::ArithTraits<ValueType>::max();
405 
410  ValueType maxVal_ = ::Kokkos::ArithTraits<ValueType>::is_integer ?
411  ::Kokkos::ArithTraits<ValueType>::min() :
412  -::Kokkos::ArithTraits<ValueType>::max();
413 
420  KeyType firstContigKey_ = ::Kokkos::ArithTraits<KeyType>::max();
421 
428  KeyType lastContigKey_ = ::Kokkos::ArithTraits<KeyType>::max();
429 
436  bool contiguousValues_ = true;
437 
444  bool checkedForDuplicateKeys_ = true;
445 
449  bool hasDuplicateKeys_ = false;
450 
455  bool checkForDuplicateKeys () const;
456 
458  KOKKOS_INLINE_FUNCTION offset_type getSize () const {
459  return ptr_.extent (0) == 0 ?
460  static_cast<offset_type> (0) :
461  static_cast<offset_type> (ptr_.extent (0) - 1);
462  }
463 
464  typedef Kokkos::View<const KeyType*,
465  typename ptr_type::HostMirror::array_layout,
466  typename ptr_type::HostMirror::execution_space,
467  Kokkos::MemoryUnmanaged> host_input_keys_type;
468 
469  typedef Kokkos::View<const ValueType*,
470  typename ptr_type::HostMirror::array_layout,
471  typename ptr_type::HostMirror::execution_space,
472  Kokkos::MemoryUnmanaged> host_input_vals_type;
473 
480  void
481  init (const keys_type& keys,
482  const ValueType startingValue,
483  KeyType initMinKey,
484  KeyType initMaxKey,
485  KeyType firstContigKey,
486  KeyType lastContigKey,
487  const bool computeInitContigKeys);
488 
495  void
496  init (const host_input_keys_type& keys,
497  const host_input_vals_type& vals,
498  KeyType initMinKey,
499  KeyType initMaxKey);
500 };
501 
502 } // Details namespace
503 } // Tpetra namespace
504 
505 #endif // TPETRA_DETAILS_FIXEDHASHTABLE_DECL_HPP
void copyOffsets(const OutputViewType &dst, const InputViewType &src)
Copy row offsets (in a sparse graph or matrix) from src to dst. The offsets may have different types...
Import KokkosSparse::OrdinalTraits, a traits class for &quot;invalid&quot; (flag) values of integer types...
KOKKOS_DEFAULTED_FUNCTION FixedHashTable()=default
Default constructor; makes an empty table.
static KOKKOS_INLINE_FUNCTION result_type hashFunc(const argument_type &, const offset_type &)
The hash function.
KOKKOS_INLINE_FUNCTION ValueType minVal() const
The minimum value in the table.
Declaration of Tpetra::Details::Profiling, a scope guard for Kokkos Profiling.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Print this object with the given verbosity to the output stream.
ResultType result_type
Type of the return value of the hash function.
Declare and define Tpetra::Details::copyOffsets, an implementation detail of Tpetra (in particular...
KOKKOS_INLINE_FUNCTION KeyType minKey() const
The minimum key in the table.
void deep_copy(MultiVector< DS, DL, DG, DN > &dst, const MultiVector< SS, SL, SG, SN > &src)
Copy the contents of the MultiVector src into dst.
The hash function for FixedHashTable.
std::string description() const
Implementation of Teuchos::Describable interface.
KOKKOS_INLINE_FUNCTION offset_type numPairs() const
Number of (key, value) pairs in the table.
FixedHashTable(const FixedHashTable< KeyType, ValueType, InDeviceType > &src, typename std::enable_if<!std::is_same< DeviceType, InDeviceType >::value, int >::type *=NULL)
&quot;Copy&quot; constructor that takes a FixedHashTable with the same KeyType and ValueType, but a different DeviceType.
void start()
Start the deep_copy counter.
KOKKOS_INLINE_FUNCTION KeyType maxKey() const
The maximum key in the table.
OffsetType offset_type
Type of offsets into the hash table&#39;s array of (key,value) pairs.
bool hasDuplicateKeys()
Whether the table has any duplicate keys.
KOKKOS_INLINE_FUNCTION ValueType maxVal() const
The maximum value in the table.
Kokkos::View< const KeyType *, Kokkos::LayoutLeft, device_type > keys_type
Type of a 1-D Kokkos::View (array) used to store keys.