VTK-m  1.8
Keys.h
Go to the documentation of this file.
1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10 #ifndef vtk_m_worklet_Keys_h
11 #define vtk_m_worklet_Keys_h
12 
13 #include <vtkm/cont/Algorithm.h>
14 #include <vtkm/cont/ArrayHandle.h>
20 #include <vtkm/cont/Logging.h>
21 
22 #include <vtkm/Hash.h>
23 
25 
31 
33 
35 #include <vtkm/worklet/vtkm_worklet_export.h>
36 
37 #include <vtkm/BinaryOperators.h>
38 
39 namespace vtkm
40 {
41 namespace worklet
42 {
43 
44 namespace internal
45 {
46 
47 class VTKM_WORKLET_EXPORT KeysBase
48 {
49 public:
50  KeysBase(const KeysBase&) = default;
51  KeysBase& operator=(const KeysBase&) = default;
52  ~KeysBase() = default;
53 
54  VTKM_CONT
55  vtkm::Id GetInputRange() const { return this->Counts.GetNumberOfValues(); }
56 
57  VTKM_CONT
58  vtkm::cont::ArrayHandle<vtkm::Id> GetSortedValuesMap() const { return this->SortedValuesMap; }
59 
60  VTKM_CONT
61  vtkm::cont::ArrayHandle<vtkm::Id> GetOffsets() const { return this->Offsets; }
62 
63  VTKM_CONT
64  vtkm::cont::ArrayHandle<vtkm::IdComponent> GetCounts() const { return this->Counts; }
65 
66  VTKM_CONT
67  vtkm::Id GetNumberOfValues() const { return this->SortedValuesMap.GetNumberOfValues(); }
68 
69  using ExecLookup = vtkm::exec::internal::ReduceByKeyLookupBase<
72 
73  template <typename Device>
74  struct VTKM_DEPRECATED(1.6, "Replace ExecutionTypes<D>::Lookup with ExecLookup.") ExecutionTypes
75  {
76  using Lookup = ExecLookup;
77  };
78 
79  VTKM_CONT ExecLookup PrepareForInput(vtkm::cont::DeviceAdapterId device,
80  vtkm::cont::Token& token) const
81  {
82  return ExecLookup(this->SortedValuesMap.PrepareForInput(device, token),
83  this->Offsets.PrepareForInput(device, token),
84  this->Counts.PrepareForInput(device, token));
85  }
86 
88  "PrepareForInput now requires a vtkm::cont::Token object.") ExecLookup
89  PrepareForInput(vtkm::cont::DeviceAdapterId device) const
90  {
91  vtkm::cont::Token token;
92  return this->PrepareForInput(device, token);
93  }
94 
95  VTKM_CONT
96  bool operator==(const vtkm::worklet::internal::KeysBase& other) const
97  {
98  return ((this->SortedValuesMap == other.SortedValuesMap) && (this->Offsets == other.Offsets) &&
99  (this->Counts == other.Counts));
100  }
101 
102  VTKM_CONT
103  bool operator!=(const vtkm::worklet::internal::KeysBase& other) const
104  {
105  return !(*this == other);
106  }
107 
108 protected:
109  KeysBase() = default;
110 
111  vtkm::cont::ArrayHandle<vtkm::Id> SortedValuesMap;
114 };
115 
116 } // namespace internal
117 
121 enum class KeysSortType
122 {
123  Unstable = 0,
124  Stable = 1
125 };
126 
144 template <typename T>
145 class VTKM_ALWAYS_EXPORT Keys : public internal::KeysBase
146 {
147 public:
148  using KeyType = T;
150 
151  VTKM_CONT
152  Keys();
153 
163  template <typename KeyStorage>
165  vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny())
166  {
167  this->BuildArrays(keys, KeysSortType::Unstable, device);
168  }
169 
173  template <typename KeyArrayType>
174  VTKM_CONT void BuildArrays(
175  const KeyArrayType& keys,
176  KeysSortType sort,
177  vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny());
178 
182  template <typename KeyArrayType>
183  VTKM_CONT void BuildArraysInPlace(
184  KeyArrayType& keys,
185  KeysSortType sort,
186  vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny());
187 
188  VTKM_CONT
189  KeyArrayHandleType GetUniqueKeys() const { return this->UniqueKeys; }
190 
191  using ExecLookup = vtkm::exec::internal::ReduceByKeyLookup<
192  typename KeyArrayHandleType::ReadPortalType,
195 
196  template <typename Device>
197  struct VTKM_DEPRECATED(1.6, "Replace ExecutionTypes<D>::Lookup with ExecLookup.") ExecutionTypes
198  {
199  using Lookup = ExecLookup;
200  };
201 
203  vtkm::cont::Token& token) const
204  {
205  return ExecLookup(this->UniqueKeys.PrepareForInput(device, token),
206  this->SortedValuesMap.PrepareForInput(device, token),
207  this->Offsets.PrepareForInput(device, token),
208  this->Counts.PrepareForInput(device, token));
209  }
210 
212  "PrepareForInput now requires a vtkm::cont::Token object.") ExecLookup
213  PrepareForInput(vtkm::cont::DeviceAdapterId device) const
214  {
215  vtkm::cont::Token token;
216  return this->PrepareForInput(device, token);
217  }
218 
219  VTKM_CONT
220  bool operator==(const vtkm::worklet::Keys<KeyType>& other) const
221  {
222  return ((this->UniqueKeys == other.UniqueKeys) &&
223  (this->SortedValuesMap == other.SortedValuesMap) && (this->Offsets == other.Offsets) &&
224  (this->Counts == other.Counts));
225  }
226 
227  VTKM_CONT
228  bool operator!=(const vtkm::worklet::Keys<KeyType>& other) const { return !(*this == other); }
229 
230 private:
232  KeyArrayHandleType UniqueKeys;
233 
234  template <typename KeyArrayType>
235  VTKM_CONT void BuildArraysInternal(KeyArrayType& keys, vtkm::cont::DeviceAdapterId device);
236 
237  template <typename KeyArrayType>
238  VTKM_CONT void BuildArraysInternalStable(const KeyArrayType& keys,
241 };
242 
243 template <typename T>
244 VTKM_CONT Keys<T>::Keys() = default;
245 
246 namespace internal
247 {
248 
249 template <typename KeyType>
250 inline auto SchedulingRange(const vtkm::worklet::Keys<KeyType>& inputDomain)
251  -> decltype(inputDomain.GetInputRange())
252 {
253  return inputDomain.GetInputRange();
254 }
255 
256 template <typename KeyType>
257 inline auto SchedulingRange(const vtkm::worklet::Keys<KeyType>* const inputDomain)
258  -> decltype(inputDomain->GetInputRange())
259 {
260  return inputDomain->GetInputRange();
261 }
262 
263 inline auto SchedulingRange(const vtkm::worklet::internal::KeysBase& inputDomain)
264  -> decltype(inputDomain.GetInputRange())
265 {
266  return inputDomain.GetInputRange();
267 }
268 
269 inline auto SchedulingRange(const vtkm::worklet::internal::KeysBase* const inputDomain)
270  -> decltype(inputDomain->GetInputRange())
271 {
272  return inputDomain->GetInputRange();
273 }
274 } // namespace internal
275 }
276 } // namespace vtkm::worklet
277 
278 // Here we implement the type checks and transports that rely on the Keys
279 // class. We implement them here because the Keys class is not accessible to
280 // the arg classes. (The worklet package depends on the cont and exec packages,
281 // not the other way around.)
282 
283 namespace vtkm
284 {
285 namespace cont
286 {
287 namespace arg
288 {
289 
290 template <typename KeyType>
292 {
293  static constexpr bool value =
294  std::is_base_of<vtkm::worklet::internal::KeysBase, typename std::decay<KeyType>::type>::value;
295 };
296 
297 template <typename KeyType, typename Device>
299 {
300  using ContObjectType = KeyType;
301  using ExecObjectType = typename ContObjectType::ExecLookup;
302 
303  VTKM_CONT
305  const ContObjectType& inputDomain,
306  vtkm::Id,
307  vtkm::Id,
308  vtkm::cont::Token& token) const
309  {
310  if (object != inputDomain)
311  {
312  throw vtkm::cont::ErrorBadValue("A Keys object must be the input domain.");
313  }
314 
315  return object.PrepareForInput(Device(), token);
316  }
317 
318  // If you get a compile error here, it means that you have used a KeysIn
319  // tag in your ControlSignature that was not marked as the InputDomain.
320  template <typename InputDomainType>
322  operator()(const ContObjectType&, const InputDomainType&, vtkm::Id, vtkm::Id) const = delete;
323 };
324 
325 template <typename ArrayHandleType, typename Device>
326 struct Transport<vtkm::cont::arg::TransportTagKeyedValuesIn, ArrayHandleType, Device>
327 {
328  VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
329 
330  using ContObjectType = ArrayHandleType;
331 
335 
337 
339  const vtkm::worklet::internal::KeysBase& keys,
340  vtkm::Id,
341  vtkm::Id,
342  vtkm::cont::Token& token) const
343  {
344  if (object.GetNumberOfValues() != keys.GetNumberOfValues())
345  {
346  throw vtkm::cont::ErrorBadValue("Input values array is wrong size.");
347  }
348 
349  PermutedArrayType permutedArray(keys.GetSortedValuesMap(), object);
350  GroupedArrayType groupedArray(permutedArray, keys.GetOffsets());
351  // There is a bit of an issue here where groupedArray goes out of scope,
352  // and array portals usually rely on the associated array handle
353  // maintaining the resources it points to. However, the entire state of the
354  // portal should be self contained except for the data managed by the
355  // object argument, which should stay in scope.
356  return groupedArray.PrepareForInput(Device(), token);
357  }
358 };
359 
360 template <typename ArrayHandleType, typename Device>
361 struct Transport<vtkm::cont::arg::TransportTagKeyedValuesInOut, ArrayHandleType, Device>
362 {
363  VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
364 
365  using ContObjectType = ArrayHandleType;
366 
370 
372 
374  const vtkm::worklet::internal::KeysBase& keys,
375  vtkm::Id,
376  vtkm::Id,
377  vtkm::cont::Token& token) const
378  {
379  if (object.GetNumberOfValues() != keys.GetNumberOfValues())
380  {
381  throw vtkm::cont::ErrorBadValue("Input/output values array is wrong size.");
382  }
383 
384  PermutedArrayType permutedArray(keys.GetSortedValuesMap(), object);
385  GroupedArrayType groupedArray(permutedArray, keys.GetOffsets());
386  // There is a bit of an issue here where groupedArray goes out of scope,
387  // and array portals usually rely on the associated array handle
388  // maintaining the resources it points to. However, the entire state of the
389  // portal should be self contained except for the data managed by the
390  // object argument, which should stay in scope.
391  return groupedArray.PrepareForInPlace(Device(), token);
392  }
393 };
394 
395 template <typename ArrayHandleType, typename Device>
396 struct Transport<vtkm::cont::arg::TransportTagKeyedValuesOut, ArrayHandleType, Device>
397 {
398  VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
399 
400  using ContObjectType = ArrayHandleType;
401 
405 
407 
409  const vtkm::worklet::internal::KeysBase& keys,
410  vtkm::Id,
411  vtkm::Id,
412  vtkm::cont::Token& token) const
413  {
414  // The PrepareForOutput for ArrayHandleGroupVecVariable and
415  // ArrayHandlePermutation cannot determine the actual size expected for the
416  // target array (object), so we have to make sure it gets allocated here.
417  object.PrepareForOutput(keys.GetNumberOfValues(), Device(), token);
418 
419  PermutedArrayType permutedArray(keys.GetSortedValuesMap(), object);
420  GroupedArrayType groupedArray(permutedArray, keys.GetOffsets());
421  // There is a bit of an issue here where groupedArray goes out of scope,
422  // and array portals usually rely on the associated array handle
423  // maintaining the resources it points to. However, the entire state of the
424  // portal should be self contained except for the data managed by the
425  // object argument, which should stay in scope.
426  return groupedArray.PrepareForOutput(keys.GetInputRange(), Device(), token);
427  }
428 };
429 }
430 }
431 } // namespace vtkm::cont::arg
432 
433 #ifndef vtk_m_worklet_Keys_cxx
434 
435 #define VTK_M_KEYS_EXPORT(T) \
436  extern template class VTKM_WORKLET_TEMPLATE_EXPORT vtkm::worklet::Keys<T>; \
437  extern template VTKM_WORKLET_TEMPLATE_EXPORT VTKM_CONT void vtkm::worklet::Keys<T>::BuildArrays( \
438  const vtkm::cont::ArrayHandle<T>& keys, \
439  vtkm::worklet::KeysSortType sort, \
440  vtkm::cont::DeviceAdapterId device)
441 
442 VTK_M_KEYS_EXPORT(vtkm::UInt8);
443 VTK_M_KEYS_EXPORT(vtkm::HashType);
444 VTK_M_KEYS_EXPORT(vtkm::Id);
445 VTK_M_KEYS_EXPORT(vtkm::Id2);
446 VTK_M_KEYS_EXPORT(vtkm::Id3);
448 VTK_M_KEYS_EXPORT(Pair_UInt8_Id2);
449 #ifdef VTKM_USE_64BIT_IDS
450 VTK_M_KEYS_EXPORT(vtkm::IdComponent);
451 #endif
452 
453 #undef VTK_M_KEYS_EXPORT
454 
455 #endif // !vtk_m_worklet_Keys_cxx
456 
457 #endif //vtk_m_worklet_Keys_h
vtkm::cont::arg::Transport::ExecObjectType
typename ContObjectType::ReadPortalType ExecObjectType
The type used in the execution environment.
Definition: Transport.h:48
TransportTagKeyedValuesInOut.h
vtkm::cont::ArrayHandle< vtkm::Id >
ArrayHandle.h
vtkm::cont::arg::Transport< vtkm::cont::arg::TransportTagKeyedValuesInOut, ArrayHandleType, Device >::ContObjectType
ArrayHandleType ContObjectType
Definition: Keys.h:365
vtkm::cont::arg::Transport< vtkm::cont::arg::TransportTagKeyedValuesOut, ArrayHandleType, Device >::ContObjectType
ArrayHandleType ContObjectType
Definition: Keys.h:400
TransportTagKeyedValuesIn.h
vtkm
VTKM_NO_DEPRECATED_VIRTUAL.
Definition: Algorithms.h:18
StableSortIndices.h
ArrayHandleCast.h
TransportTagKeyedValuesOut.h
vtkm::worklet::VTKM_DEPRECATED
class VTKM_DEPRECATED(1.7, "K-D tree recursive searches are not well supported on GPU devices.") KdTree3D
Definition: KdTree3D.h:21
vtkm::cont::ArrayHandle::PrepareForInput
VTKM_CONT ReadPortalType PrepareForInput(vtkm::cont::DeviceAdapterId device, vtkm::cont::Token &token) const
Prepares this array to be used as an input to an operation in the execution environment.
Definition: ArrayHandle.h:629
vtkm::IdComponent
vtkm::Int32 IdComponent
Represents a component ID (index of component in a vector).
Definition: Types.h:168
vtkm::cont::arg::Transport< vtkm::cont::arg::TransportTagKeyedValuesOut, ArrayHandleType, Device >::operator()
VTKM_CONT ExecObjectType operator()(ContObjectType object, const vtkm::worklet::internal::KeysBase &keys, vtkm::Id, vtkm::Id, vtkm::cont::Token &token) const
Definition: Keys.h:408
vtkm::worklet::Keys::Keys
VTKM_CONT Keys()
vtkm::worklet::Keys::PrepareForInput
VTKM_CONT ExecLookup PrepareForInput(vtkm::cont::DeviceAdapterId device, vtkm::cont::Token &token) const
Definition: Keys.h:202
vtkm::cont::ArrayHandleGroupVecVariable
Fancy array handle that groups values into vectors of different sizes.
Definition: ArrayHandleGroupVecVariable.h:252
vtkm::cont::arg::Transport< vtkm::cont::arg::TransportTagKeyedValuesInOut, ArrayHandleType, Device >::ExecObjectType
typename GroupedArrayType::WritePortalType ExecObjectType
Definition: Keys.h:371
vtkm::cont::arg::Transport< vtkm::cont::arg::TransportTagKeysIn, KeyType, Device >::ContObjectType
KeyType ContObjectType
Definition: Keys.h:300
DispatcherBase.h
vtkm::worklet::Keys::Keys
VTKM_CONT Keys(const vtkm::cont::ArrayHandle< KeyType, KeyStorage > &keys, vtkm::cont::DeviceAdapterId device=vtkm::cont::DeviceAdapterTagAny())
Construct a Keys class from an array of keys.
Definition: Keys.h:164
ArrayHandleConstant.h
vtkm::cont::ArrayHandle::PrepareForInPlace
VTKM_CONT WritePortalType PrepareForInPlace(vtkm::cont::DeviceAdapterId device, vtkm::cont::Token &token) const
Prepares this array to be used in an in-place operation (both as input and output) in the execution e...
Definition: ArrayHandle.h:648
vtkm::cont::ArrayHandle::ReadPortalType
typename StorageType::ReadPortalType ReadPortalType
Definition: ArrayHandle.h:298
vtkm::HashType
vtkm::UInt32 HashType
Definition: Hash.h:20
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
vtkm::cont::arg::Transport< vtkm::cont::arg::TransportTagKeysIn, KeyType, Device >::ExecObjectType
typename ContObjectType::ExecLookup ExecObjectType
Definition: Keys.h:301
vtkm::cont::Token
A token to hold the scope of an ArrayHandle or other object.
Definition: Token.h:35
vtkm::cont::arg::TransportTagKeyedValuesIn
Transport tag for input values in a reduce by key.
Definition: TransportTagKeyedValuesIn.h:28
vtkm::cont::arg::Transport< vtkm::cont::arg::TransportTagKeyedValuesIn, ArrayHandleType, Device >::operator()
VTKM_CONT ExecObjectType operator()(const ContObjectType &object, const vtkm::worklet::internal::KeysBase &keys, vtkm::Id, vtkm::Id, vtkm::cont::Token &token) const
Definition: Keys.h:338
ArrayHandlePermutation.h
Algorithm.h
ArrayHandleIndex.h
VTKM_IS_ARRAY_HANDLE
#define VTKM_IS_ARRAY_HANDLE(T)
Definition: ArrayHandle.h:133
vtkm::cont::arg::TransportTagKeysIn
Transport tag for keys in a reduce by key.
Definition: TransportTagKeysIn.h:28
vtkm::cont::ArrayHandlePermutation
Implicitly permutes the values in an array.
Definition: ArrayHandlePermutation.h:208
vtkm::cont::arg::TypeCheck
Class for checking that a type matches the semantics for an argument.
Definition: TypeCheck.h:34
TransportTagKeysIn.h
vtkm::cont::arg::Transport< vtkm::cont::arg::TransportTagKeyedValuesIn, ArrayHandleType, Device >::ContObjectType
ArrayHandleType ContObjectType
Definition: Keys.h:330
vtkm::worklet::KeysSortType::Stable
@ Stable
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
vtkm::worklet::KeysSortType
KeysSortType
Select the type of sort for BuildArrays calls.
Definition: Keys.h:121
vtkm::worklet::KeysSortType::Unstable
@ Unstable
vtkm::operator==
VTKM_EXEC_CONT bool operator==(const vtkm::Matrix< T, NumRow, NumCol > &a, const vtkm::Matrix< T, NumRow, NumCol > &b)
Definition: Matrix.h:615
vtkm::cont::ArrayHandle< vtkm::VecFromPortal< ComponentsArrayHandleType::WritePortalType >, vtkm::cont::StorageTagGroupVecVariable< ComponentsArrayHandleType::StorageTag, OffsetsArrayHandleType::StorageTag > >::WritePortalType
typename StorageType::WritePortalType WritePortalType
Definition: ArrayHandle.h:299
vtkm::worklet::Keys::GetUniqueKeys
VTKM_CONT KeyArrayHandleType GetUniqueKeys() const
Definition: Keys.h:189
vtkm::UInt8
uint8_t UInt8
Definition: Types.h:157
vtkm::cont::arg::TransportTagKeyedValuesOut
Transport tag for input values in a reduce by key.
Definition: TransportTagKeyedValuesOut.h:28
BinaryOperators.h
vtkm::cont::arg::Transport< vtkm::cont::arg::TransportTagKeyedValuesIn, ArrayHandleType, Device >::ExecObjectType
typename GroupedArrayType::ReadPortalType ExecObjectType
Definition: Keys.h:336
vtkm::cont::DeviceAdapterId
Definition: DeviceAdapterTag.h:52
vtkm::Vec
A short fixed-length array.
Definition: Types.h:767
vtkm::operator!=
VTKM_EXEC_CONT bool operator!=(const vtkm::Matrix< T, NumRow, NumCol > &a, const vtkm::Matrix< T, NumRow, NumCol > &b)
Definition: Matrix.h:629
vtkm::cont::ErrorBadValue
This class is thrown when a VTKm function or method encounters an invalid value that inhibits progres...
Definition: ErrorBadValue.h:25
vtkm::cont::arg::TypeCheck::value
static constexpr bool value
The static constant boolean value is set to true if the type is valid for the given check tag and fal...
Definition: TypeCheck.h:39
vtkm::cont::arg::Transport< vtkm::cont::arg::TransportTagKeyedValuesOut, ArrayHandleType, Device >::ExecObjectType
typename GroupedArrayType::WritePortalType ExecObjectType
Definition: Keys.h:406
vtkm::cont::ArrayHandle::PrepareForOutput
VTKM_CONT WritePortalType PrepareForOutput(vtkm::Id numberOfValues, vtkm::cont::DeviceAdapterId device, vtkm::cont::Token &token) const
Prepares (allocates) this array to be used as an output from an operation in the execution environmen...
Definition: ArrayHandle.h:668
vtkm::cont::arg::Transport< vtkm::cont::arg::TransportTagKeysIn, KeyType, Device >::operator()
VTKM_CONT ExecObjectType operator()(const ContObjectType &object, const ContObjectType &inputDomain, vtkm::Id, vtkm::Id, vtkm::cont::Token &token) const
Definition: Keys.h:304
vtkm::worklet::Keys
Manage keys for a WorkletReduceByKey.
Definition: Keys.h:145
vtkm::worklet::Keys< vtkm::Id >::KeyType
vtkm::Id KeyType
Definition: Keys.h:148
vtkm::cont::arg::Transport
Class for transporting from the control to the execution environment.
Definition: Transport.h:38
ArrayHandleGroupVecVariable.h
VTKM_ALWAYS_EXPORT
#define VTKM_ALWAYS_EXPORT
Definition: ExportMacros.h:92
Logging.h
Logging utilities.
TypeCheckTagKeys.h
vtkm::cont::arg::TypeCheckTagKeys
Check for a Keys object.
Definition: TypeCheckTagKeys.h:24
Hash.h
vtkm::Pair
A vtkm::Pair is essentially the same as an STL pair object except that the methods (constructors and ...
Definition: Pair.h:29
vtkm::cont::arg::Transport::operator()
VTKM_CONT ExecObjectType operator()(const ContObjectType contData, const InputDomainType &inputDomain vtkm::Id outputSize) const
Send data to the execution environment.
vtkm::cont::arg::Transport< vtkm::cont::arg::TransportTagKeyedValuesInOut, ArrayHandleType, Device >::operator()
VTKM_CONT ExecObjectType operator()(ContObjectType object, const vtkm::worklet::internal::KeysBase &keys, vtkm::Id, vtkm::Id, vtkm::cont::Token &token) const
Definition: Keys.h:373
ReduceByKeyLookup.h
vtkm::cont::arg::TransportTagKeyedValuesInOut
Transport tag for input values in a reduce by key.
Definition: TransportTagKeyedValuesInOut.h:28