VTK-m  2.2
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/Deprecated.h>
23 #include <vtkm/Hash.h>
24 
26 
32 
34 
37 
38 #include <vtkm/BinaryOperators.h>
39 
40 namespace vtkm
41 {
42 namespace worklet
43 {
44 
45 namespace internal
46 {
47 
48 class VTKM_WORKLET_EXPORT KeysBase
49 {
50 public:
51  KeysBase(const KeysBase&) = default;
52  KeysBase& operator=(const KeysBase&) = default;
53  ~KeysBase() = default;
54 
55  VTKM_CONT
56  vtkm::Id GetInputRange() const { return this->Offsets.GetNumberOfValues() - 1; }
57 
58  VTKM_CONT
59  vtkm::cont::ArrayHandle<vtkm::Id> GetSortedValuesMap() const { return this->SortedValuesMap; }
60 
61  VTKM_CONT
62  vtkm::cont::ArrayHandle<vtkm::Id> GetOffsets() const { return this->Offsets; }
63 
64  VTKM_DEPRECATED(2.2, "Use the `GetOffsets()` array in an `ArrayHandleOffsetsToNumComponents`.")
65  VTKM_CONT
66  vtkm::cont::ArrayHandle<vtkm::IdComponent> GetCounts() const;
67 
68  VTKM_CONT
69  vtkm::Id GetNumberOfValues() const { return this->SortedValuesMap.GetNumberOfValues(); }
70 
71  using ExecLookup = vtkm::exec::internal::ReduceByKeyLookupBase<
74 
75  VTKM_CONT ExecLookup PrepareForInput(vtkm::cont::DeviceAdapterId device,
76  vtkm::cont::Token& token) const
77  {
78  return ExecLookup(this->SortedValuesMap.PrepareForInput(device, token),
79  this->Offsets.PrepareForInput(device, token));
80  }
81 
82  VTKM_CONT
83  bool operator==(const vtkm::worklet::internal::KeysBase& other) const
84  {
85  return ((this->SortedValuesMap == other.SortedValuesMap) && (this->Offsets == other.Offsets) &&
86  (this->Offsets == other.Offsets));
87  }
88 
89  VTKM_CONT
90  bool operator!=(const vtkm::worklet::internal::KeysBase& other) const
91  {
92  return !(*this == other);
93  }
94 
95 protected:
96  KeysBase() = default;
97 
98  vtkm::cont::ArrayHandle<vtkm::Id> SortedValuesMap;
100 };
101 
102 } // namespace internal
103 
107 enum class KeysSortType
108 {
109  Unstable = 0,
110  Stable = 1
111 };
112 
129 template <typename T>
130 class VTKM_ALWAYS_EXPORT Keys : public internal::KeysBase
131 {
132 public:
133  using KeyType = T;
135 
136  VTKM_CONT
137  Keys();
138 
148  template <typename KeyStorage>
151  {
152  this->BuildArrays(keys, KeysSortType::Unstable, device);
153  }
154 
158  template <typename KeyArrayType>
159  VTKM_CONT void BuildArrays(
160  const KeyArrayType& keys,
161  KeysSortType sort,
163 
167  template <typename KeyArrayType>
168  VTKM_CONT void BuildArraysInPlace(
169  KeyArrayType& keys,
170  KeysSortType sort,
172 
175  VTKM_CONT
176  KeyArrayHandleType GetUniqueKeys() const { return this->UniqueKeys; }
177 
178 #ifdef VTKM_DOXYGEN_ONLY
179  // Document the superclass' methods as methods in this class.
180 
184  vtkm::Id GetInputRange() const;
185 
192  vtkm::cont::ArrayHandle<vtkm::Id> GetSortedValuesMap() const;
193 
200  vtkm::cont::ArrayHandle<vtkm::Id> GetOffsets() const;
201 
205  vtkm::Id GetNumberOfValues() const;
206 #endif
207 
208  using ExecLookup = vtkm::exec::internal::ReduceByKeyLookup<
209  typename KeyArrayHandleType::ReadPortalType,
212 
214  vtkm::cont::Token& token) const
215  {
216  return ExecLookup(this->UniqueKeys.PrepareForInput(device, token),
217  this->SortedValuesMap.PrepareForInput(device, token),
218  this->Offsets.PrepareForInput(device, token));
219  }
220 
221  VTKM_CONT
222  bool operator==(const vtkm::worklet::Keys<KeyType>& other) const
223  {
224  return ((this->UniqueKeys == other.UniqueKeys) &&
225  (this->SortedValuesMap == other.SortedValuesMap) && (this->Offsets == other.Offsets));
226  }
227 
228  VTKM_CONT
229  bool operator!=(const vtkm::worklet::Keys<KeyType>& other) const { return !(*this == other); }
230 
231 private:
233  KeyArrayHandleType UniqueKeys;
234 
235  template <typename KeyArrayType>
236  VTKM_CONT void BuildArraysInternal(KeyArrayType& keys, vtkm::cont::DeviceAdapterId device);
237 
238  template <typename KeyArrayType>
239  VTKM_CONT void BuildArraysInternalStable(const KeyArrayType& keys,
242 };
243 
244 template <typename T>
245 VTKM_CONT Keys<T>::Keys() = default;
246 
247 namespace internal
248 {
249 
250 template <typename KeyType>
251 inline auto SchedulingRange(const vtkm::worklet::Keys<KeyType>& inputDomain)
252  -> decltype(inputDomain.GetInputRange())
253 {
254  return inputDomain.GetInputRange();
255 }
256 
257 template <typename KeyType>
258 inline auto SchedulingRange(const vtkm::worklet::Keys<KeyType>* const inputDomain)
259  -> decltype(inputDomain->GetInputRange())
260 {
261  return inputDomain->GetInputRange();
262 }
263 
264 inline auto SchedulingRange(const vtkm::worklet::internal::KeysBase& inputDomain)
265  -> decltype(inputDomain.GetInputRange())
266 {
267  return inputDomain.GetInputRange();
268 }
269 
270 inline auto SchedulingRange(const vtkm::worklet::internal::KeysBase* const inputDomain)
271  -> decltype(inputDomain->GetInputRange())
272 {
273  return inputDomain->GetInputRange();
274 }
275 } // namespace internal
276 }
277 } // namespace vtkm::worklet
278 
279 // Here we implement the type checks and transports that rely on the Keys
280 // class. We implement them here because the Keys class is not accessible to
281 // the arg classes. (The worklet package depends on the cont and exec packages,
282 // not the other way around.)
283 
284 namespace vtkm
285 {
286 namespace cont
287 {
288 namespace arg
289 {
290 
291 template <typename KeyType>
293 {
294  static constexpr bool value =
295  std::is_base_of<vtkm::worklet::internal::KeysBase, typename std::decay<KeyType>::type>::value;
296 };
297 
298 template <typename KeyType, typename Device>
300 {
301  using ContObjectType = KeyType;
302  using ExecObjectType = typename ContObjectType::ExecLookup;
303 
304  VTKM_CONT
306  const ContObjectType& inputDomain,
307  vtkm::Id,
308  vtkm::Id,
309  vtkm::cont::Token& token) const
310  {
311  if (object != inputDomain)
312  {
313  throw vtkm::cont::ErrorBadValue("A Keys object must be the input domain.");
314  }
315 
316  return object.PrepareForInput(Device(), token);
317  }
318 
319  // If you get a compile error here, it means that you have used a KeysIn
320  // tag in your ControlSignature that was not marked as the InputDomain.
321  template <typename InputDomainType>
323  operator()(const ContObjectType&, const InputDomainType&, vtkm::Id, vtkm::Id) const = delete;
324 };
325 
326 template <typename ArrayHandleType, typename Device>
327 struct Transport<vtkm::cont::arg::TransportTagKeyedValuesIn, ArrayHandleType, Device>
328 {
329  VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
330 
331  using ContObjectType = ArrayHandleType;
332 
336 
338 
340  const vtkm::worklet::internal::KeysBase& keys,
341  vtkm::Id,
342  vtkm::Id,
343  vtkm::cont::Token& token) const
344  {
345  if (object.GetNumberOfValues() != keys.GetNumberOfValues())
346  {
347  throw vtkm::cont::ErrorBadValue("Input values array is wrong size.");
348  }
349 
350  PermutedArrayType permutedArray(keys.GetSortedValuesMap(), object);
351  GroupedArrayType groupedArray(permutedArray, keys.GetOffsets());
352  // There is a bit of an issue here where groupedArray goes out of scope,
353  // and array portals usually rely on the associated array handle
354  // maintaining the resources it points to. However, the entire state of the
355  // portal should be self contained except for the data managed by the
356  // object argument, which should stay in scope.
357  return groupedArray.PrepareForInput(Device(), token);
358  }
359 };
360 
361 template <typename ArrayHandleType, typename Device>
362 struct Transport<vtkm::cont::arg::TransportTagKeyedValuesInOut, ArrayHandleType, Device>
363 {
364  VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
365 
366  using ContObjectType = ArrayHandleType;
367 
371 
373 
375  const vtkm::worklet::internal::KeysBase& keys,
376  vtkm::Id,
377  vtkm::Id,
378  vtkm::cont::Token& token) const
379  {
380  if (object.GetNumberOfValues() != keys.GetNumberOfValues())
381  {
382  throw vtkm::cont::ErrorBadValue("Input/output values array is wrong size.");
383  }
384 
385  PermutedArrayType permutedArray(keys.GetSortedValuesMap(), object);
386  GroupedArrayType groupedArray(permutedArray, keys.GetOffsets());
387  // There is a bit of an issue here where groupedArray goes out of scope,
388  // and array portals usually rely on the associated array handle
389  // maintaining the resources it points to. However, the entire state of the
390  // portal should be self contained except for the data managed by the
391  // object argument, which should stay in scope.
392  return groupedArray.PrepareForInPlace(Device(), token);
393  }
394 };
395 
396 template <typename ArrayHandleType, typename Device>
397 struct Transport<vtkm::cont::arg::TransportTagKeyedValuesOut, ArrayHandleType, Device>
398 {
399  VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
400 
401  using ContObjectType = ArrayHandleType;
402 
406 
408 
410  const vtkm::worklet::internal::KeysBase& keys,
411  vtkm::Id,
412  vtkm::Id,
413  vtkm::cont::Token& token) const
414  {
415  // The PrepareForOutput for ArrayHandleGroupVecVariable and
416  // ArrayHandlePermutation cannot determine the actual size expected for the
417  // target array (object), so we have to make sure it gets allocated here.
418  object.PrepareForOutput(keys.GetNumberOfValues(), Device(), token);
419 
420  PermutedArrayType permutedArray(keys.GetSortedValuesMap(), object);
421  GroupedArrayType groupedArray(permutedArray, keys.GetOffsets());
422  // There is a bit of an issue here where groupedArray goes out of scope,
423  // and array portals usually rely on the associated array handle
424  // maintaining the resources it points to. However, the entire state of the
425  // portal should be self contained except for the data managed by the
426  // object argument, which should stay in scope.
427  return groupedArray.PrepareForOutput(keys.GetInputRange(), Device(), token);
428  }
429 };
430 }
431 }
432 } // namespace vtkm::cont::arg
433 
434 #ifndef vtk_m_worklet_Keys_cxx
435 
436 #define VTK_M_KEYS_EXPORT(T) \
437  extern template class VTKM_WORKLET_TEMPLATE_EXPORT vtkm::worklet::Keys<T>; \
438  extern template VTKM_WORKLET_TEMPLATE_EXPORT VTKM_CONT void vtkm::worklet::Keys<T>::BuildArrays( \
439  const vtkm::cont::ArrayHandle<T>& keys, \
440  vtkm::worklet::KeysSortType sort, \
441  vtkm::cont::DeviceAdapterId device)
442 
443 VTK_M_KEYS_EXPORT(vtkm::UInt8);
444 VTK_M_KEYS_EXPORT(vtkm::HashType);
445 VTK_M_KEYS_EXPORT(vtkm::Id);
446 VTK_M_KEYS_EXPORT(vtkm::Id2);
447 VTK_M_KEYS_EXPORT(vtkm::Id3);
449 VTK_M_KEYS_EXPORT(Pair_UInt8_Id2);
450 #ifdef VTKM_USE_64BIT_IDS
451 VTK_M_KEYS_EXPORT(vtkm::IdComponent);
452 #endif
453 
454 #undef VTK_M_KEYS_EXPORT
455 
456 #endif // !vtk_m_worklet_Keys_cxx
457 
458 #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::operator!=
bool operator!=(const vtkm::Matrix< T, NumRow, NumCol > &a, const vtkm::Matrix< T, NumRow, NumCol > &b)
Definition: Matrix.h:631
VTKM_WORKLET_EXPORT
#define VTKM_WORKLET_EXPORT
Definition: vtkm_worklet_export.h:44
vtkm::cont::ArrayHandle< vtkm::Id >
ArrayHandle.h
vtkm::cont::arg::Transport< vtkm::cont::arg::TransportTagKeyedValuesInOut, ArrayHandleType, Device >::ContObjectType
ArrayHandleType ContObjectType
Definition: Keys.h:366
vtkm::cont::ArrayHandleGroupVecVariable::ReadPortalType
typename Superclass::ReadPortalType ReadPortalType
Definition: ArrayHandleGroupVecVariable.h:291
vtkm::cont::arg::Transport< vtkm::cont::arg::TransportTagKeyedValuesOut, ArrayHandleType, Device >::ContObjectType
ArrayHandleType ContObjectType
Definition: Keys.h:401
TransportTagKeyedValuesIn.h
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
StableSortIndices.h
ArrayHandleCast.h
TransportTagKeyedValuesOut.h
vtkm::IdComponent
vtkm::Int32 IdComponent
Base type to use to index small lists.
Definition: Types.h:194
vtkm::cont::ArrayHandleGroupVecVariable
Fancy array handle that groups values into vectors of different sizes.
Definition: ArrayHandleGroupVecVariable.h:271
vtkm::cont::arg::Transport< vtkm::cont::arg::TransportTagKeyedValuesInOut, ArrayHandleType, Device >::ExecObjectType
typename GroupedArrayType::WritePortalType ExecObjectType
Definition: Keys.h:372
vtkm::cont::arg::Transport< vtkm::cont::arg::TransportTagKeysIn, KeyType, Device >::ContObjectType
KeyType ContObjectType
Definition: Keys.h:301
DispatcherBase.h
ArrayHandleConstant.h
vtkm::cont::arg::Transport< vtkm::cont::arg::TransportTagKeysIn, KeyType, Device >::operator()
ExecObjectType operator()(const ContObjectType &object, const ContObjectType &inputDomain, vtkm::Id, vtkm::Id, vtkm::cont::Token &token) const
Definition: Keys.h:305
vtkm::cont::ArrayHandle::ReadPortalType
typename StorageType::ReadPortalType ReadPortalType
The type of portal used when accessing data in a read-only mode.
Definition: ArrayHandle.h:312
vtkm::HashType
vtkm::UInt32 HashType
Definition: Hash.h:20
vtkm::cont::arg::Transport< vtkm::cont::arg::TransportTagKeysIn, KeyType, Device >::ExecObjectType
typename ContObjectType::ExecLookup ExecObjectType
Definition: Keys.h:302
vtkm::operator==
bool operator==(const vtkm::Matrix< T, NumRow, NumCol > &a, const vtkm::Matrix< T, NumRow, NumCol > &b)
Definition: Matrix.h:617
vtkm::cont::arg::Transport< vtkm::cont::arg::TransportTagKeyedValuesIn, ArrayHandleType, Device >::operator()
ExecObjectType operator()(const ContObjectType &object, const vtkm::worklet::internal::KeysBase &keys, vtkm::Id, vtkm::Id, vtkm::cont::Token &token) const
Definition: Keys.h:339
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::worklet::Keys::operator==
bool operator==(const vtkm::worklet::Keys< KeyType > &other) const
Definition: Keys.h:222
vtkm::cont::ArrayHandle::PrepareForInPlace
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:618
vtkm::worklet::Keys::Keys
Keys()
ArrayHandlePermutation.h
Algorithm.h
ArrayHandleIndex.h
VTKM_IS_ARRAY_HANDLE
#define VTKM_IS_ARRAY_HANDLE(T)
Checks that the given type is a vtkm::cont::ArrayHandle.
Definition: ArrayHandle.h:137
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:233
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:331
vtkm_worklet_export.h
vtkm::cont::ArrayHandle::PrepareForOutput
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:638
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:107
vtkm::worklet::KeysSortType::Unstable
@ Unstable
vtkm::Id
vtkm::Int64 Id
Base type to use to index arrays.
Definition: Types.h:227
vtkm::cont::DeviceAdapterTagAny
Tag for a device adapter used to specify that any device may be used for an operation.
Definition: DeviceAdapterTag.h:180
vtkm::UInt8
uint8_t UInt8
Base type to use for 8-bit unsigned integer numbers.
Definition: Types.h:169
vtkm::cont::ArrayHandleGroupVecVariable::WritePortalType
typename Superclass::WritePortalType WritePortalType
Definition: ArrayHandleGroupVecVariable.h:291
vtkm::cont::arg::Transport< vtkm::cont::arg::TransportTagKeyedValuesOut, ArrayHandleType, Device >::operator()
ExecObjectType operator()(ContObjectType object, const vtkm::worklet::internal::KeysBase &keys, vtkm::Id, vtkm::Id, vtkm::cont::Token &token) const
Definition: Keys.h:409
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:337
vtkm::cont::DeviceAdapterId
An object used to specify a device.
Definition: DeviceAdapterTag.h:58
vtkm::Vec< vtkm::Id, 2 >
vtkm::worklet::Keys::PrepareForInput
ExecLookup PrepareForInput(vtkm::cont::DeviceAdapterId device, vtkm::cont::Token &token) const
Definition: Keys.h:213
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:407
vtkm::worklet::Keys::GetUniqueKeys
KeyArrayHandleType GetUniqueKeys() const
Returns an array of unique keys.
Definition: Keys.h:176
Deprecated.h
vtkm::worklet::Keys::operator!=
bool operator!=(const vtkm::worklet::Keys< KeyType > &other) const
Definition: Keys.h:229
vtkm::worklet::Keys
Manage keys for a vtkm::worklet::WorkletReduceByKey.
Definition: Keys.h:130
vtkm::worklet::Keys::KeyType
T KeyType
Definition: Keys.h:133
vtkm::cont::arg::Transport
Class for transporting from the control to the execution environment.
Definition: Transport.h:38
vtkm::cont::ArrayHandle::PrepareForInput
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:599
ArrayHandleGroupVecVariable.h
VTKM_ALWAYS_EXPORT
#define VTKM_ALWAYS_EXPORT
Definition: ExportMacros.h:89
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_DEPRECATED
#define VTKM_DEPRECATED(...)
Definition: Deprecated.h:145
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.
ReduceByKeyLookup.h
vtkm::cont::arg::TransportTagKeyedValuesInOut
Transport tag for input values in a reduce by key.
Definition: TransportTagKeyedValuesInOut.h:28
vtkm::cont::arg::Transport< vtkm::cont::arg::TransportTagKeyedValuesInOut, ArrayHandleType, Device >::operator()
ExecObjectType operator()(ContObjectType object, const vtkm::worklet::internal::KeysBase &keys, vtkm::Id, vtkm::Id, vtkm::cont::Token &token) const
Definition: Keys.h:374
vtkm::worklet::Keys::Keys
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:149