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 /*
2 // @HEADER
3 // ***********************************************************************
4 //
5 // Tpetra: Templated Linear Algebra Services Package
6 // Copyright (2008) Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
39 //
40 // ************************************************************************
41 // @HEADER
42 */
43 
44 #ifndef TPETRA_DETAILS_FIXEDHASHTABLE_DECL_HPP
45 #define TPETRA_DETAILS_FIXEDHASHTABLE_DECL_HPP
46 
47 #include "Tpetra_Details_Hash.hpp"
51 
52 #include "Teuchos_Describable.hpp"
53 #include "Teuchos_FancyOStream.hpp"
54 #include "Teuchos_VerbosityLevel.hpp"
55 
56 #include "Kokkos_Core.hpp"
57 #include "Kokkos_ArithTraits.hpp"
58 
59 namespace Tpetra {
60 namespace Details {
61 
87 template<class KeyType,
88  class ValueType,
89  class DeviceType>
91 private:
92  typedef typename DeviceType::execution_space execution_space;
93  typedef typename DeviceType::memory_space memory_space;
94  typedef Kokkos::Device<execution_space, memory_space> device_type;
95 
97  typedef typename hash_type::offset_type offset_type;
98 
106  typedef typename Kokkos::View<const offset_type*, Kokkos::LayoutLeft,
107  device_type> ptr_type;
114  typedef typename Kokkos::View<const Kokkos::pair<KeyType, ValueType>*,
115  Kokkos::LayoutLeft, device_type> val_type;
116 
123  KOKKOS_INLINE_FUNCTION bool hasContiguousValues () const {
124  return contiguousValues_;
125  }
126 
127 public:
131  typedef Kokkos::View<const KeyType*, Kokkos::LayoutLeft, device_type> keys_type;
132 
134  KOKKOS_DEFAULTED_FUNCTION FixedHashTable() = default;
135 
145  FixedHashTable (const keys_type& keys);
146 
154  FixedHashTable (const Teuchos::ArrayView<const KeyType>& keys);
155 
169  FixedHashTable (const keys_type& keys,
170  const ValueType startingValue);
171 
183  FixedHashTable (const Teuchos::ArrayView<const KeyType>& keys,
184  const ValueType startingValue);
185 
204  FixedHashTable (const keys_type& keys,
205  const KeyType firstContigKey,
206  const KeyType lastContigKey,
207  const ValueType startingValue);
208 
224  FixedHashTable (const Teuchos::ArrayView<const KeyType>& keys,
225  const KeyType firstContigKey,
226  const KeyType lastContigKey,
227  const ValueType startingValue);
228 
237  FixedHashTable (const Teuchos::ArrayView<const KeyType>& keys,
238  const Teuchos::ArrayView<const ValueType>& vals);
239 
240  template<class K, class V, class D>
241  friend class FixedHashTable;
242 
248  template<class InDeviceType>
250  typename std::enable_if<! std::is_same<DeviceType, InDeviceType>::value, int>::type* = NULL)
251  {
252  using Kokkos::ViewAllocateWithoutInitializing;
253  typedef typename ptr_type::non_const_type nonconst_ptr_type;
254  typedef typename val_type::non_const_type nonconst_val_type;
255 
256  Tpetra::Details::ProfilingRegion pr("Tpetra::Details::FixedHashTable::ctor(InDeviceType)");
257 
258  // FIXME (mfh 28 May 2015) The code below _always_ copies. This
259  // shouldn't be necessary if the input and output memory spaces
260  // are the same. However, it is always correct.
261 
262  // Different Devices may have different offset_type, because
263  // offset_type comes from the memory space's size_type typedef.
264  // That's why we use a specialized deep copy function here instead
265  // of Kokkos::deep_copy.
266  nonconst_ptr_type ptr (ViewAllocateWithoutInitializing ("Tpetra::FixedHashTable::ptr"),
267  src.ptr_.extent (0));
268  ::Tpetra::Details::copyOffsets (ptr, src.ptr_);
269  nonconst_val_type val (ViewAllocateWithoutInitializing ("Tpetra::FixedHashTable::val"),
270  src.val_.extent (0));
271  // val and src.val_ have the same entry types, unlike (possibly)
272  // ptr and src.ptr_. Thus, we can use Kokkos::deep_copy here.
273  // DEEP_COPY REVIEW - DEVICE-TO-DEVICE
274  Kokkos::deep_copy (execution_space(), val, src.val_);
275 
276  this->ptr_ = ptr;
277  this->val_ = val;
278  this->minKey_ = src.minKey_;
279  this->maxKey_ = src.maxKey_;
280  this->minVal_ = src.minVal_;
281  this->maxVal_ = src.maxVal_;
282  this->firstContigKey_ = src.firstContigKey_;
283  this->lastContigKey_ = src.lastContigKey_;
284  this->contiguousValues_ = src.contiguousValues_;
285  this->checkedForDuplicateKeys_ = src.checkedForDuplicateKeys_;
286  this->hasDuplicateKeys_ = src.hasDuplicateKeys_;
287  }
288 
290  KOKKOS_INLINE_FUNCTION ValueType get (const KeyType& key) const {
291  const offset_type size = this->getSize ();
292  if (size == 0) {
293  // Don't use Teuchos::OrdinalTraits or std::numeric_limits here,
294  // because neither have the right device function markings.
295  return Tpetra::Details::OrdinalTraits<ValueType>::invalid ();
296  }
297 
298  // If this object assumes contiguous values, then it doesn't store
299  // the initial sequence of >= 1 contiguous keys in the table.
300  if (this->hasContiguousValues () &&
301  key >= firstContigKey_ && key <= lastContigKey_) {
302  return static_cast<ValueType> (key - firstContigKey_) + this->minVal ();
303  }
304 
305  const typename hash_type::result_type hashVal =
306  hash_type::hashFunc (key, size);
307 
308  const offset_type start = ptr_[hashVal];
309  const offset_type end = ptr_[hashVal+1];
310  for (offset_type k = start; k < end; ++k) {
311  if (val_[k].first == key) {
312  return val_[k].second;
313  }
314  }
315 
316  // Don't use Teuchos::OrdinalTraits or std::numeric_limits here,
317  // because neither have the right device function markings.
318  return Tpetra::Details::OrdinalTraits<ValueType>::invalid ();
319  }
320 
324  KOKKOS_INLINE_FUNCTION offset_type numPairs () const {
325  // NOTE (mfh 26 May 2015) Using val_.extent(0) only works
326  // because the table stores pairs with duplicate keys separately.
327  // If the table didn't do that, we would have to keep a separate
328  // numPairs_ field (remembering the size of the input array of
329  // keys).
330  if (this->hasContiguousValues ()) {
331  return val_.extent (0) + static_cast<offset_type> (lastContigKey_ - firstContigKey_);
332  }
333  else {
334  return val_.extent (0);
335  }
336  }
337 
346  KOKKOS_INLINE_FUNCTION KeyType minKey () const {
347  return minKey_;
348  }
349 
358  KOKKOS_INLINE_FUNCTION KeyType maxKey () const {
359  return maxKey_;
360  }
361 
369  KOKKOS_INLINE_FUNCTION ValueType minVal () const {
370  return minVal_;
371  }
372 
380  KOKKOS_INLINE_FUNCTION ValueType maxVal () const {
381  return maxVal_;
382  }
383 
396  bool hasDuplicateKeys ();
397 
403 
404  std::string description () const;
406 
408  void
409  describe (Teuchos::FancyOStream &out,
410  const Teuchos::EVerbosityLevel verbLevel=
411  Teuchos::Describable::verbLevel_default) const;
413 
414 private:
416  ptr_type ptr_;
418  val_type val_;
419 
425  KeyType minKey_ = ::Kokkos::ArithTraits<KeyType>::max();
426 
432  KeyType maxKey_ = ::Kokkos::ArithTraits<KeyType>::is_integer ?
433  ::Kokkos::ArithTraits<KeyType>::min() :
434  -::Kokkos::ArithTraits<KeyType>::max();
435 
440  ValueType minVal_ = ::Kokkos::ArithTraits<ValueType>::max();
441 
446  ValueType maxVal_ = ::Kokkos::ArithTraits<ValueType>::is_integer ?
447  ::Kokkos::ArithTraits<ValueType>::min() :
448  -::Kokkos::ArithTraits<ValueType>::max();
449 
456  KeyType firstContigKey_ = ::Kokkos::ArithTraits<KeyType>::max();
457 
464  KeyType lastContigKey_ = ::Kokkos::ArithTraits<KeyType>::is_integer ?
465  ::Kokkos::ArithTraits<KeyType>::min() :
466  -::Kokkos::ArithTraits<KeyType>::max();
467 
474  bool contiguousValues_ = true;
475 
482  bool checkedForDuplicateKeys_ = true;
483 
487  bool hasDuplicateKeys_ = false;
488 
493  bool checkForDuplicateKeys () const;
494 
496  KOKKOS_INLINE_FUNCTION offset_type getSize () const {
497  return ptr_.extent (0) == 0 ?
498  static_cast<offset_type> (0) :
499  static_cast<offset_type> (ptr_.extent (0) - 1);
500  }
501 
502  typedef Kokkos::View<const KeyType*,
503  typename ptr_type::HostMirror::array_layout,
504  typename ptr_type::HostMirror::execution_space,
505  Kokkos::MemoryUnmanaged> host_input_keys_type;
506 
507  typedef Kokkos::View<const ValueType*,
508  typename ptr_type::HostMirror::array_layout,
509  typename ptr_type::HostMirror::execution_space,
510  Kokkos::MemoryUnmanaged> host_input_vals_type;
511 
518  void
519  init (const keys_type& keys,
520  const ValueType startingValue,
521  KeyType initMinKey,
522  KeyType initMaxKey,
523  KeyType firstContigKey,
524  KeyType lastContigKey,
525  const bool computeInitContigKeys);
526 
533  void
534  init (const host_input_keys_type& keys,
535  const host_input_vals_type& vals,
536  KeyType initMinKey,
537  KeyType initMaxKey);
538 };
539 
540 } // Details namespace
541 } // Tpetra namespace
542 
543 #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.