VTK-m  2.0
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::Id GetNumberOfValues(
146  const std::vector<vtkm::cont::internal::Buffer>& buffers)
147  {
148  return IndexStorage::GetNumberOfValues(IndexBuffers(buffers));
149  }
150 
151  VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>&,
152  const T&,
153  vtkm::Id,
154  vtkm::Id,
156  {
157  throw vtkm::cont::ErrorBadType("Fill not supported for ArrayHandlePermutation.");
158  }
159 
160  VTKM_CONT static ReadPortalType CreateReadPortal(
161  const std::vector<vtkm::cont::internal::Buffer>& buffers,
163  vtkm::cont::Token& token)
164  {
165  return ReadPortalType(IndexStorage::CreateReadPortal(IndexBuffers(buffers), device, token),
166  ValueStorage::CreateReadPortal(ValueBuffers(buffers), device, token));
167  }
168 
169  VTKM_CONT static WritePortalType CreateWritePortal(
170  const std::vector<vtkm::cont::internal::Buffer>& buffers,
172  vtkm::cont::Token& token)
173  {
174  // Note: the index portal is always a read-only portal.
175  return WritePortalType(IndexStorage::CreateReadPortal(IndexBuffers(buffers), device, token),
176  ValueStorage::CreateWritePortal(ValueBuffers(buffers), device, token));
177  }
178 
179  VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
180  const IndexArray& indexArray = IndexArray{},
181  const ValueArray& valueArray = ValueArray{})
182  {
183  Info info;
184  info.ValueBufferOffset = 1 + indexArray.GetBuffers().size();
185  return vtkm::cont::internal::CreateBuffers(info, indexArray, valueArray);
186  }
187 
188  VTKM_CONT static IndexArray GetIndexArray(
189  const std::vector<vtkm::cont::internal::Buffer>& buffers)
190  {
191  return IndexArray(IndexBuffers(buffers));
192  }
193 
194  VTKM_CONT static ValueArray GetValueArray(
195  const std::vector<vtkm::cont::internal::Buffer>& buffers)
196  {
197  return ValueArray(ValueBuffers(buffers));
198  }
199 };
200 
201 } // namespace internal
202 
226 template <typename IndexArrayHandleType, typename ValueArrayHandleType>
228  : public vtkm::cont::ArrayHandle<
229  typename ValueArrayHandleType::ValueType,
230  vtkm::cont::StorageTagPermutation<typename IndexArrayHandleType::StorageTag,
231  typename ValueArrayHandleType::StorageTag>>
232 {
233  // If the following line gives a compile error, then the ArrayHandleType
234  // template argument is not a valid ArrayHandle type.
235  VTKM_IS_ARRAY_HANDLE(IndexArrayHandleType);
236  VTKM_IS_ARRAY_HANDLE(ValueArrayHandleType);
237 
239  (std::is_same<vtkm::Id, typename IndexArrayHandleType::ValueType>::value),
240  "Permutation array in ArrayHandlePermutation must have vtkm::Id value type.");
241 
242 public:
247  typename ValueArrayHandleType::ValueType,
248  vtkm::cont::StorageTagPermutation<typename IndexArrayHandleType::StorageTag,
249  typename ValueArrayHandleType::StorageTag>>));
250 
251 private:
252  using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
253 
254 public:
255  VTKM_CONT
256  ArrayHandlePermutation(const IndexArrayHandleType& indexArray,
257  const ValueArrayHandleType& valueArray)
258  : Superclass(StorageType::CreateBuffers(indexArray, valueArray))
259  {
260  }
261 
262  VTKM_CONT IndexArrayHandleType GetIndexArray() const
263  {
264  return StorageType::GetIndexArray(this->GetBuffers());
265  }
266 
267  VTKM_CONT ValueArrayHandleType GetValueArray() const
268  {
269  return StorageType::GetValueArray(this->GetBuffers());
270  }
271 };
272 
276 
277 template <typename IndexArrayHandleType, typename ValueArrayHandleType>
279 make_ArrayHandlePermutation(IndexArrayHandleType indexArray, ValueArrayHandleType valueArray)
280 {
282 }
283 }
284 } // namespace vtkm::cont
285 
286 //=============================================================================
287 // Specializations of serialization related classes
289 namespace vtkm
290 {
291 namespace cont
292 {
293 
294 template <typename IdxAH, typename ValAH>
295 struct SerializableTypeString<vtkm::cont::ArrayHandlePermutation<IdxAH, ValAH>>
296 {
297  static VTKM_CONT const std::string& Get()
298  {
299  static std::string name = "AH_Permutation<" + SerializableTypeString<IdxAH>::Get() + "," +
301  return name;
302  }
303 };
304 
305 template <typename T, typename IdxST, typename ValST>
306 struct SerializableTypeString<
307  vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagPermutation<IdxST, ValST>>>
308  : SerializableTypeString<
309  vtkm::cont::ArrayHandlePermutation<vtkm::cont::ArrayHandle<vtkm::Id, IdxST>,
310  vtkm::cont::ArrayHandle<T, ValST>>>
311 {
312 };
313 }
314 } // vtkm::cont
315 
316 namespace mangled_diy_namespace
317 {
318 
319 template <typename IdxAH, typename ValAH>
320 struct Serialization<vtkm::cont::ArrayHandlePermutation<IdxAH, ValAH>>
321 {
322 private:
325 
326 public:
327  static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
328  {
329  vtkmdiy::save(bb, Type(obj).GetIndexArray());
330  vtkmdiy::save(bb, Type(obj).GetValueArray());
331  }
332 
333  static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj)
334  {
335  IdxAH indices;
336  ValAH values;
337 
338  vtkmdiy::load(bb, indices);
339  vtkmdiy::load(bb, values);
340 
341  obj = vtkm::cont::make_ArrayHandlePermutation(indices, values);
342  }
343 };
344 
345 template <typename T, typename IdxST, typename ValST>
346 struct Serialization<vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagPermutation<IdxST, ValST>>>
347  : Serialization<vtkm::cont::ArrayHandlePermutation<vtkm::cont::ArrayHandle<vtkm::Id, IdxST>,
348  vtkm::cont::ArrayHandle<T, ValST>>>
349 {
350 };
351 
352 } // diy
354 
355 #endif //vtk_m_cont_ArrayHandlePermutation_h
vtkm::cont::ArrayHandle< ValueArrayHandleType::ValueType, vtkm::cont::StorageTagPermutation< IndexArrayHandleType::StorageTag, ValueArrayHandleType::StorageTag > >::GetBuffers
const VTKM_CONT std::vector< vtkm::cont::internal::Buffer > & GetBuffers() const
Returns the internal Buffer structures that hold the data.
Definition: ArrayHandle.h:696
vtkm::cont::ArrayHandlePermutation::GetIndexArray
VTKM_CONT IndexArrayHandleType GetIndexArray() const
Definition: ArrayHandlePermutation.h:262
vtkm::cont::ArrayHandle
Manages an array-worth of data.
Definition: ArrayHandle.h:283
ArrayHandle.h
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::ArrayHandlePermutation
VTKM_CONT ArrayHandlePermutation(const IndexArrayHandleType &indexArray, const ValueArrayHandleType &valueArray)
Definition: ArrayHandlePermutation.h:256
VTKM_EXEC_CONT
#define VTKM_EXEC_CONT
Definition: ExportMacros.h:52
vtkm::Get
VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_CONT auto Get(const vtkm::Tuple< Ts... > &tuple) -> decltype(tuple.template Get< Index >())
Retrieve the object from a vtkm::Tuple at the given index.
Definition: Tuple.h:83
vtkm::cont::ArrayHandlePermutation::VTKM_ARRAY_HANDLE_SUBCLASS
VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandlePermutation,(ArrayHandlePermutation< IndexArrayHandleType, ValueArrayHandleType >),(vtkm::cont::ArrayHandle< typename ValueArrayHandleType::ValueType, vtkm::cont::StorageTagPermutation< typename IndexArrayHandleType::StorageTag, typename ValueArrayHandleType::StorageTag >>))
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:331
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
vtkm::exec::arg::load
VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC T load(const U &u, vtkm::Id v)
Definition: FetchTagArrayDirectIn.h:36
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::cont::ArrayHandlePermutation::VTKM_IS_ARRAY_HANDLE
VTKM_IS_ARRAY_HANDLE(IndexArrayHandleType)
vtkm::cont::ArrayHandlePermutation
Implicitly permutes the values in an array.
Definition: ArrayHandlePermutation.h:227
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::cont::ArrayHandlePermutation::GetValueArray
VTKM_CONT ValueArrayHandleType GetValueArray() const
Definition: ArrayHandlePermutation.h:267
vtkm::cont::ArrayHandlePermutation::StorageType
vtkm::cont::internal::Storage< ValueType, StorageTag > StorageType
Definition: ArrayHandlePermutation.h:252
vtkm::cont::ArrayHandlePermutation::VTKM_STATIC_ASSERT_MSG
VTKM_STATIC_ASSERT_MSG((std::is_same< vtkm::Id, typename IndexArrayHandleType::ValueType >::value), "Permutation array in ArrayHandlePermutation must have vtkm::Id value type.")
vtkm::cont::make_ArrayHandlePermutation
VTKM_CONT vtkm::cont::ArrayHandlePermutation< IndexArrayHandleType, ValueArrayHandleType > make_ArrayHandlePermutation(IndexArrayHandleType indexArray, ValueArrayHandleType valueArray)
make_ArrayHandleTransform is convenience function to generate an ArrayHandleTransform.
Definition: ArrayHandlePermutation.h:279
vtkm::cont::DeviceAdapterId
Definition: DeviceAdapterTag.h:52
ErrorBadValue.h
VTKM_ALWAYS_EXPORT
#define VTKM_ALWAYS_EXPORT
Definition: ExportMacros.h:92
ErrorBadType.h