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 #if KOKKOS_VERSION >= 40799
24 #include "KokkosKernels_ArithTraits.hpp"
25 #else
26 #include "Kokkos_ArithTraits.hpp"
27 #endif
28 
29 namespace Tpetra {
30 namespace Details {
31 
57 template <class KeyType,
58  class ValueType,
59  class DeviceType>
61  private:
62  typedef typename DeviceType::execution_space execution_space;
63  typedef typename DeviceType::memory_space memory_space;
64  typedef Kokkos::Device<execution_space, memory_space> device_type;
65 
67  typedef typename hash_type::offset_type offset_type;
68 
76  typedef typename Kokkos::View<const offset_type*, Kokkos::LayoutLeft,
77  device_type>
78  ptr_type;
85  typedef typename Kokkos::View<const Kokkos::pair<KeyType, ValueType>*,
86  Kokkos::LayoutLeft, device_type>
87  val_type;
88 
95  KOKKOS_INLINE_FUNCTION bool hasContiguousValues() const {
96  return contiguousValues_;
97  }
98 
99  public:
103  typedef Kokkos::View<const KeyType*, Kokkos::LayoutLeft, device_type> keys_type;
104 
106  KOKKOS_DEFAULTED_FUNCTION FixedHashTable() = default;
107 
117  FixedHashTable(const keys_type& keys);
118 
126  FixedHashTable(const Teuchos::ArrayView<const KeyType>& keys);
127 
141  FixedHashTable(const keys_type& keys,
142  const ValueType startingValue);
143 
155  FixedHashTable(const Teuchos::ArrayView<const KeyType>& keys,
156  const ValueType startingValue);
157 
176  FixedHashTable(const keys_type& keys,
177  const KeyType firstContigKey,
178  const KeyType lastContigKey,
179  const ValueType startingValue);
180 
196  FixedHashTable(const Teuchos::ArrayView<const KeyType>& keys,
197  const KeyType firstContigKey,
198  const KeyType lastContigKey,
199  const ValueType startingValue);
200 
209  FixedHashTable(const Teuchos::ArrayView<const KeyType>& keys,
210  const Teuchos::ArrayView<const ValueType>& vals);
211 
212  template <class K, class V, class D>
213  friend class FixedHashTable;
214 
220  template <class InDeviceType>
222  typename std::enable_if<!std::is_same<DeviceType, InDeviceType>::value, int>::type* = NULL) {
223  using Kokkos::ViewAllocateWithoutInitializing;
224  typedef typename ptr_type::non_const_type nonconst_ptr_type;
225  typedef typename val_type::non_const_type nonconst_val_type;
226 
227  Tpetra::Details::ProfilingRegion pr("Tpetra::Details::FixedHashTable::ctor(InDeviceType)");
228 
229  // FIXME (mfh 28 May 2015) The code below _always_ copies. This
230  // shouldn't be necessary if the input and output memory spaces
231  // are the same. However, it is always correct.
232 
233  // Different Devices may have different offset_type, because
234  // offset_type comes from the memory space's size_type typedef.
235  // That's why we use a specialized deep copy function here instead
236  // of Kokkos::deep_copy.
237  nonconst_ptr_type ptr(ViewAllocateWithoutInitializing("Tpetra::FixedHashTable::ptr"),
238  src.ptr_.extent(0));
239  ::Tpetra::Details::copyOffsets(ptr, src.ptr_);
240  nonconst_val_type val(ViewAllocateWithoutInitializing("Tpetra::FixedHashTable::val"),
241  src.val_.extent(0));
242  // val and src.val_ have the same entry types, unlike (possibly)
243  // ptr and src.ptr_. Thus, we can use Kokkos::deep_copy here.
244  // DEEP_COPY REVIEW - DEVICE-TO-DEVICE
245  Kokkos::deep_copy(execution_space(), val, src.val_);
246 
247  this->ptr_ = ptr;
248  this->val_ = val;
249  this->minKey_ = src.minKey_;
250  this->maxKey_ = src.maxKey_;
251  this->minVal_ = src.minVal_;
252  this->maxVal_ = src.maxVal_;
253  this->firstContigKey_ = src.firstContigKey_;
254  this->lastContigKey_ = src.lastContigKey_;
255  this->contiguousValues_ = src.contiguousValues_;
256  this->checkedForDuplicateKeys_ = src.checkedForDuplicateKeys_;
257  this->hasDuplicateKeys_ = src.hasDuplicateKeys_;
258  }
259 
261  KOKKOS_INLINE_FUNCTION ValueType get(const KeyType& key) const {
262  const offset_type size = this->getSize();
263  if (size == 0) {
264  // Don't use Teuchos::OrdinalTraits or std::numeric_limits here,
265  // because neither have the right device function markings.
266  return Tpetra::Details::OrdinalTraits<ValueType>::invalid();
267  }
268 
269  // If this object assumes contiguous values, then it doesn't store
270  // the initial sequence of >= 1 contiguous keys in the table.
271  if (this->hasContiguousValues() &&
272  key >= firstContigKey_ && key <= lastContigKey_) {
273  return static_cast<ValueType>(key - firstContigKey_) + this->minVal();
274  }
275 
276  const typename hash_type::result_type hashVal =
277  hash_type::hashFunc(key, size);
278 
279  const offset_type start = ptr_[hashVal];
280  const offset_type end = ptr_[hashVal + 1];
281  for (offset_type k = start; k < end; ++k) {
282  if (val_[k].first == key) {
283  return val_[k].second;
284  }
285  }
286 
287  // Don't use Teuchos::OrdinalTraits or std::numeric_limits here,
288  // because neither have the right device function markings.
289  return Tpetra::Details::OrdinalTraits<ValueType>::invalid();
290  }
291 
295  KOKKOS_INLINE_FUNCTION offset_type numPairs() const {
296  // NOTE (mfh 26 May 2015) Using val_.extent(0) only works
297  // because the table stores pairs with duplicate keys separately.
298  // If the table didn't do that, we would have to keep a separate
299  // numPairs_ field (remembering the size of the input array of
300  // keys).
301  if (this->hasContiguousValues()) {
302  return val_.extent(0) + static_cast<offset_type>(lastContigKey_ - firstContigKey_);
303  } else {
304  return val_.extent(0);
305  }
306  }
307 
316  KOKKOS_INLINE_FUNCTION KeyType minKey() const {
317  return minKey_;
318  }
319 
328  KOKKOS_INLINE_FUNCTION KeyType maxKey() const {
329  return maxKey_;
330  }
331 
339  KOKKOS_INLINE_FUNCTION ValueType minVal() const {
340  return minVal_;
341  }
342 
350  KOKKOS_INLINE_FUNCTION ValueType maxVal() const {
351  return maxVal_;
352  }
353 
366  bool hasDuplicateKeys();
367 
373 
374  std::string description() const;
376 
378  void
379  describe(Teuchos::FancyOStream& out,
380  const Teuchos::EVerbosityLevel verbLevel =
381  Teuchos::Describable::verbLevel_default) const;
383 
384  private:
386  ptr_type ptr_;
388  val_type val_;
389 
395 #if KOKKOS_VERSION >= 40799
396  KeyType minKey_ = ::KokkosKernels::ArithTraits<KeyType>::max();
397 #else
398  KeyType minKey_ = ::Kokkos::ArithTraits<KeyType>::max();
399 #endif
400 
406 #if KOKKOS_VERSION >= 40799
407  KeyType maxKey_ = ::KokkosKernels::ArithTraits<KeyType>::max();
408 #else
409  KeyType maxKey_ = ::Kokkos::ArithTraits<KeyType>::max();
410 #endif
411 
416 #if KOKKOS_VERSION >= 40799
417  ValueType minVal_ = ::KokkosKernels::ArithTraits<ValueType>::max();
418 #else
419  ValueType minVal_ = ::Kokkos::ArithTraits<ValueType>::max();
420 #endif
421 
426 #if KOKKOS_VERSION >= 40799
427  ValueType maxVal_ = ::KokkosKernels::ArithTraits<ValueType>::is_integer ? ::KokkosKernels::ArithTraits<ValueType>::min() : -::KokkosKernels::ArithTraits<ValueType>::max();
428 #else
429  ValueType maxVal_ = ::Kokkos::ArithTraits<ValueType>::is_integer ? ::Kokkos::ArithTraits<ValueType>::min() : -::Kokkos::ArithTraits<ValueType>::max();
430 #endif
431 
438 #if KOKKOS_VERSION >= 40799
439  KeyType firstContigKey_ = ::KokkosKernels::ArithTraits<KeyType>::max();
440 #else
441  KeyType firstContigKey_ = ::Kokkos::ArithTraits<KeyType>::max();
442 #endif
443 
450 #if KOKKOS_VERSION >= 40799
451  KeyType lastContigKey_ = ::KokkosKernels::ArithTraits<KeyType>::max();
452 #else
453  KeyType lastContigKey_ = ::Kokkos::ArithTraits<KeyType>::max();
454 #endif
455 
462  bool contiguousValues_ = true;
463 
470  bool checkedForDuplicateKeys_ = true;
471 
475  bool hasDuplicateKeys_ = false;
476 
481  bool checkForDuplicateKeys() const;
482 
484  KOKKOS_INLINE_FUNCTION offset_type getSize() const {
485  return ptr_.extent(0) == 0 ? static_cast<offset_type>(0) : static_cast<offset_type>(ptr_.extent(0) - 1);
486  }
487 
488  typedef Kokkos::View<const KeyType*,
489  typename ptr_type::host_mirror_type::array_layout,
490  typename ptr_type::host_mirror_type::execution_space,
491  Kokkos::MemoryUnmanaged>
492  host_input_keys_type;
493 
494  typedef Kokkos::View<const ValueType*,
495  typename ptr_type::host_mirror_type::array_layout,
496  typename ptr_type::host_mirror_type::execution_space,
497  Kokkos::MemoryUnmanaged>
498  host_input_vals_type;
499 
506  void
507  init(const keys_type& keys,
508  const ValueType startingValue,
509  KeyType initMinKey,
510  KeyType initMaxKey,
511  KeyType firstContigKey,
512  KeyType lastContigKey,
513  const bool computeInitContigKeys);
514 
521  void
522  init(const host_input_keys_type& keys,
523  const host_input_vals_type& vals,
524  KeyType initMinKey,
525  KeyType initMaxKey);
526 };
527 
528 } // namespace Details
529 } // namespace Tpetra
530 
531 #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.