VTK-m  2.1
ArrayHandlePermutation.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_cont_ArrayHandlePermutation_h
11 #define vtk_m_cont_ArrayHandlePermutation_h
12 
13 #include <vtkm/cont/ArrayHandle.h>
14 #include <vtkm/cont/ErrorBadType.h>
16 
17 namespace vtkm
18 {
19 namespace internal
20 {
21 
22 template <typename IndexPortalType, typename ValuePortalType>
23 class VTKM_ALWAYS_EXPORT ArrayPortalPermutation
24 {
25  using Writable = vtkm::internal::PortalSupportsSets<ValuePortalType>;
26 
27 public:
28  using ValueType = typename ValuePortalType::ValueType;
29 
31  ArrayPortalPermutation()
32  : IndexPortal()
33  , ValuePortal()
34  {
35  }
36 
38  ArrayPortalPermutation(const IndexPortalType& indexPortal, const ValuePortalType& valuePortal)
39  : IndexPortal(indexPortal)
40  , ValuePortal(valuePortal)
41  {
42  }
43 
49  template <typename OtherIP, typename OtherVP>
50  VTKM_EXEC_CONT ArrayPortalPermutation(const ArrayPortalPermutation<OtherIP, OtherVP>& src)
51  : IndexPortal(src.GetIndexPortal())
52  , ValuePortal(src.GetValuePortal())
53  {
54  }
55 
57  vtkm::Id GetNumberOfValues() const { return this->IndexPortal.GetNumberOfValues(); }
58 
59  VTKM_EXEC
60  ValueType Get(vtkm::Id index) const
61  {
62  vtkm::Id permutedIndex = this->IndexPortal.Get(index);
63  return this->ValuePortal.Get(permutedIndex);
64  }
65 
66  template <typename Writable_ = Writable,
67  typename = typename std::enable_if<Writable_::value>::type>
68  VTKM_EXEC void Set(vtkm::Id index, const ValueType& value) const
69  {
70  vtkm::Id permutedIndex = this->IndexPortal.Get(index);
71  this->ValuePortal.Set(permutedIndex, value);
72  }
73 
75  const IndexPortalType& GetIndexPortal() const { return this->IndexPortal; }
76 
78  const ValuePortalType& GetValuePortal() const { return this->ValuePortal; }
79 
80 private:
81  IndexPortalType IndexPortal;
82  ValuePortalType ValuePortal;
83 };
84 }
85 } // namespace vtkm::internal
86 
87 namespace vtkm
88 {
89 namespace cont
90 {
91 
92 template <typename IndexStorageTag, typename ValueStorageTag>
94 {
95 };
96 
97 namespace internal
98 {
99 
100 template <typename T, typename IndexStorageTag, typename ValueStorageTag>
101 class Storage<T, vtkm::cont::StorageTagPermutation<IndexStorageTag, ValueStorageTag>>
102 {
104  (vtkm::cont::internal::IsValidArrayHandle<vtkm::Id, IndexStorageTag>::value),
105  "Invalid index storage tag.");
106  VTKM_STATIC_ASSERT_MSG((vtkm::cont::internal::IsValidArrayHandle<T, ValueStorageTag>::value),
107  "Invalid value storage tag.");
108 
109  using IndexStorage = vtkm::cont::internal::Storage<vtkm::Id, IndexStorageTag>;
110  using ValueStorage = vtkm::cont::internal::Storage<T, ValueStorageTag>;
111 
114 
115  struct Info
116  {
117  std::size_t ValueBufferOffset;
118  };
119 
120  VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> IndexBuffers(
121  const std::vector<vtkm::cont::internal::Buffer>& buffers)
122  {
123  Info info = buffers[0].GetMetaData<Info>();
124  return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1,
125  buffers.begin() + info.ValueBufferOffset);
126  }
127  VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> ValueBuffers(
128  const std::vector<vtkm::cont::internal::Buffer>& buffers)
129  {
130  Info info = buffers[0].GetMetaData<Info>();
131  return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + info.ValueBufferOffset,
132  buffers.end());
133  }
134 
135 public:
137 
138  using ReadPortalType =
139  vtkm::internal::ArrayPortalPermutation<typename IndexStorage::ReadPortalType,
140  typename ValueStorage::ReadPortalType>;
141  using WritePortalType =
142  vtkm::internal::ArrayPortalPermutation<typename IndexStorage::ReadPortalType,
143  typename ValueStorage::WritePortalType>;
144 
145  VTKM_CONT static vtkm::IdComponent GetNumberOfComponentsFlat(
146  const std::vector<vtkm::cont::internal::Buffer>& buffers)
147  {
148  return ValueStorage::GetNumberOfComponentsFlat(ValueBuffers(buffers));
149  }
150 
151  VTKM_CONT static vtkm::Id GetNumberOfValues(
152  const std::vector<vtkm::cont::internal::Buffer>& buffers)
153  {
154  return IndexStorage::GetNumberOfValues(IndexBuffers(buffers));
155  }
156 
157  VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>&,
158  const T&,
159  vtkm::Id,
160  vtkm::Id,
162  {
163  throw vtkm::cont::ErrorBadType("Fill not supported for ArrayHandlePermutation.");
164  }
165 
166  VTKM_CONT static ReadPortalType CreateReadPortal(
167  const std::vector<vtkm::cont::internal::Buffer>& buffers,
169  vtkm::cont::Token& token)
170  {
171  return ReadPortalType(IndexStorage::CreateReadPortal(IndexBuffers(buffers), device, token),
172  ValueStorage::CreateReadPortal(ValueBuffers(buffers), device, token));
173  }
174 
175  VTKM_CONT static WritePortalType CreateWritePortal(
176  const std::vector<vtkm::cont::internal::Buffer>& buffers,
178  vtkm::cont::Token& token)
179  {
180  // Note: the index portal is always a read-only portal.
181  return WritePortalType(IndexStorage::CreateReadPortal(IndexBuffers(buffers), device, token),
182  ValueStorage::CreateWritePortal(ValueBuffers(buffers), device, token));
183  }
184 
185  VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
186  const IndexArray& indexArray = IndexArray{},
187  const ValueArray& valueArray = ValueArray{})
188  {
189  Info info;
190  info.ValueBufferOffset = 1 + indexArray.GetBuffers().size();
191  return vtkm::cont::internal::CreateBuffers(info, indexArray, valueArray);
192  }
193 
194  VTKM_CONT static IndexArray GetIndexArray(
195  const std::vector<vtkm::cont::internal::Buffer>& buffers)
196  {
197  return IndexArray(IndexBuffers(buffers));
198  }
199 
200  VTKM_CONT static ValueArray GetValueArray(
201  const std::vector<vtkm::cont::internal::Buffer>& buffers)
202  {
203  return ValueArray(ValueBuffers(buffers));
204  }
205 };
206 
207 } // namespace internal
208 
232 template <typename IndexArrayHandleType, typename ValueArrayHandleType>
234  : public vtkm::cont::ArrayHandle<
235  typename ValueArrayHandleType::ValueType,
236  vtkm::cont::StorageTagPermutation<typename IndexArrayHandleType::StorageTag,
237  typename ValueArrayHandleType::StorageTag>>
238 {
239  // If the following line gives a compile error, then the ArrayHandleType
240  // template argument is not a valid ArrayHandle type.
241  VTKM_IS_ARRAY_HANDLE(IndexArrayHandleType);
242  VTKM_IS_ARRAY_HANDLE(ValueArrayHandleType);
243 
245  (std::is_same<vtkm::Id, typename IndexArrayHandleType::ValueType>::value),
246  "Permutation array in ArrayHandlePermutation must have vtkm::Id value type.");
247 
248 public:
253  typename ValueArrayHandleType::ValueType,
254  vtkm::cont::StorageTagPermutation<typename IndexArrayHandleType::StorageTag,
255  typename ValueArrayHandleType::StorageTag>>));
256 
257  VTKM_CONT
258  ArrayHandlePermutation(const IndexArrayHandleType& indexArray,
259  const ValueArrayHandleType& valueArray)
260  : Superclass(StorageType::CreateBuffers(indexArray, valueArray))
261  {
262  }
263 
264  VTKM_CONT IndexArrayHandleType GetIndexArray() const
265  {
266  return StorageType::GetIndexArray(this->GetBuffers());
267  }
268 
269  VTKM_CONT ValueArrayHandleType GetValueArray() const
270  {
271  return StorageType::GetValueArray(this->GetBuffers());
272  }
273 };
274 
278 
279 template <typename IndexArrayHandleType, typename ValueArrayHandleType>
281 make_ArrayHandlePermutation(IndexArrayHandleType indexArray, ValueArrayHandleType valueArray)
282 {
284 }
285 }
286 } // namespace vtkm::cont
287 
288 //=============================================================================
289 // Specializations of serialization related classes
291 namespace vtkm
292 {
293 namespace cont
294 {
295 
296 template <typename IdxAH, typename ValAH>
297 struct SerializableTypeString<vtkm::cont::ArrayHandlePermutation<IdxAH, ValAH>>
298 {
299  static VTKM_CONT const std::string& Get()
300  {
301  static std::string name = "AH_Permutation<" + SerializableTypeString<IdxAH>::Get() + "," +
303  return name;
304  }
305 };
306 
307 template <typename T, typename IdxST, typename ValST>
308 struct SerializableTypeString<
309  vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagPermutation<IdxST, ValST>>>
310  : SerializableTypeString<
311  vtkm::cont::ArrayHandlePermutation<vtkm::cont::ArrayHandle<vtkm::Id, IdxST>,
312  vtkm::cont::ArrayHandle<T, ValST>>>
313 {
314 };
315 }
316 } // vtkm::cont
317 
318 namespace mangled_diy_namespace
319 {
320 
321 template <typename IdxAH, typename ValAH>
322 struct Serialization<vtkm::cont::ArrayHandlePermutation<IdxAH, ValAH>>
323 {
324 private:
327 
328 public:
329  static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
330  {
331  vtkmdiy::save(bb, Type(obj).GetIndexArray());
332  vtkmdiy::save(bb, Type(obj).GetValueArray());
333  }
334 
335  static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj)
336  {
337  IdxAH indices;
338  ValAH values;
339 
340  vtkmdiy::load(bb, indices);
341  vtkmdiy::load(bb, values);
342 
343  obj = vtkm::cont::make_ArrayHandlePermutation(indices, values);
344  }
345 };
346 
347 template <typename T, typename IdxST, typename ValST>
348 struct Serialization<vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagPermutation<IdxST, ValST>>>
349  : Serialization<vtkm::cont::ArrayHandlePermutation<vtkm::cont::ArrayHandle<vtkm::Id, IdxST>,
350  vtkm::cont::ArrayHandle<T, ValST>>>
351 {
352 };
353 
354 } // diy
356 
357 #endif //vtk_m_cont_ArrayHandlePermutation_h
vtkm::cont::ArrayHandlePermutation::GetValueArray
ValueArrayHandleType GetValueArray() const
Definition: ArrayHandlePermutation.h:269
vtkm::cont::ArrayHandle
Manages an array-worth of data.
Definition: ArrayHandle.h:300
ArrayHandle.h
vtkm::cont::ArrayHandle< ValueArrayHandleType::ValueType, vtkm::cont::StorageTagPermutation< IndexArrayHandleType::StorageTag, ValueArrayHandleType::StorageTag > >::GetBuffers
const std::vector< vtkm::cont::internal::Buffer > & GetBuffers() const
Returns the internal Buffer structures that hold the data.
Definition: ArrayHandle.h:719
vtkm::exec::arg::load
T load(const U &u, vtkm::Id v)
Definition: FetchTagArrayDirectIn.h:36
VTKM_EXEC
#define VTKM_EXEC
Definition: ExportMacros.h:51
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::cont::ArrayHandlePermutation::GetIndexArray
IndexArrayHandleType GetIndexArray() const
Definition: ArrayHandlePermutation.h:264
vtkm::Get
auto Get(const vtkm::Tuple< Ts... > &tuple)
Retrieve the object from a vtkm::Tuple at the given index.
Definition: Tuple.h:81
VTKM_ARRAY_HANDLE_SUBCLASS
#define VTKM_ARRAY_HANDLE_SUBCLASS(classname, fullclasstype, superclass)
Macro to make default methods in ArrayHandle subclasses.
Definition: ArrayHandle.h:243
VTKM_EXEC_CONT
#define VTKM_EXEC_CONT
Definition: ExportMacros.h:52
vtkm::IdComponent
vtkm::Int32 IdComponent
Base type to use to index small lists.
Definition: Types.h:194
vtkm::cont::StorageTagPermutation
Definition: ArrayHandlePermutation.h:93
vtkm::cont::ErrorBadType
This class is thrown when VTK-m encounters data of a type that is incompatible with the current opera...
Definition: ErrorBadType.h:25
VTKM_STORAGE_NO_RESIZE
#define VTKM_STORAGE_NO_RESIZE
Definition: Storage.h:185
mangled_diy_namespace
Definition: Particle.h:351
vtkm::cont::Token
A token to hold the scope of an ArrayHandle or other object.
Definition: Token.h:35
vtkm::cont::LogLevel::Info
@ Info
Information messages (detected hardware, etc) and temporary debugging output.
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::ArrayHandlePermutation
Implicitly permutes the values in an array.
Definition: ArrayHandlePermutation.h:233
VTKM_STATIC_ASSERT_MSG
#define VTKM_STATIC_ASSERT_MSG(condition, message)
Definition: StaticAssert.h:18
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
vtkm::Id
vtkm::Int64 Id
Base type to use to index arrays.
Definition: Types.h:227
vtkm::cont::ArrayHandlePermutation::StorageType
typename Superclass::StorageType StorageType
Definition: ArrayHandlePermutation.h:255
vtkm::cont::DeviceAdapterId
An object used to specify a device.
Definition: DeviceAdapterTag.h:58
vtkm::cont::ArrayHandlePermutation::Superclass
typename vtkm::cont::detail::GetTypeInParentheses< void(vtkm::cont::ArrayHandle< typename ValueArrayHandleType::ValueType, vtkm::cont::StorageTagPermutation< typename IndexArrayHandleType::StorageTag, typename ValueArrayHandleType::StorageTag > >) >::type Superclass
Definition: ArrayHandlePermutation.h:255
vtkm::cont::ArrayHandlePermutation::ArrayHandlePermutation
ArrayHandlePermutation(const IndexArrayHandleType &indexArray, const ValueArrayHandleType &valueArray)
Definition: ArrayHandlePermutation.h:258
ErrorBadValue.h
VTKM_ALWAYS_EXPORT
#define VTKM_ALWAYS_EXPORT
Definition: ExportMacros.h:89
ErrorBadType.h
vtkm::cont::make_ArrayHandlePermutation
vtkm::cont::ArrayHandlePermutation< IndexArrayHandleType, ValueArrayHandleType > make_ArrayHandlePermutation(IndexArrayHandleType indexArray, ValueArrayHandleType valueArray)
make_ArrayHandleTransform is convenience function to generate an ArrayHandleTransform.
Definition: ArrayHandlePermutation.h:281