Viskores  1.0
ArrayHandlePermutation.h
Go to the documentation of this file.
1 //============================================================================
2 // The contents of this file are covered by the Viskores license. See
3 // LICENSE.txt for details.
4 //
5 // By contributing to this file, all contributors agree to the Developer
6 // Certificate of Origin Version 1.1 (DCO 1.1) as stated in DCO.txt.
7 //============================================================================
8 
9 //============================================================================
10 // Copyright (c) Kitware, Inc.
11 // All rights reserved.
12 // See LICENSE.txt for details.
13 //
14 // This software is distributed WITHOUT ANY WARRANTY; without even
15 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 // PURPOSE. See the above copyright notice for more information.
17 //============================================================================
18 #ifndef viskores_cont_ArrayHandlePermutation_h
19 #define viskores_cont_ArrayHandlePermutation_h
20 
24 
25 namespace viskores
26 {
27 namespace internal
28 {
29 
30 template <typename IndexPortalType, typename ValuePortalType>
31 class VISKORES_ALWAYS_EXPORT ArrayPortalPermutation
32 {
33  using Writable = viskores::internal::PortalSupportsSets<ValuePortalType>;
34 
35 public:
36  using ValueType = typename ValuePortalType::ValueType;
37 
39  ArrayPortalPermutation()
40  : IndexPortal()
41  , ValuePortal()
42  {
43  }
44 
46  ArrayPortalPermutation(const IndexPortalType& indexPortal, const ValuePortalType& valuePortal)
47  : IndexPortal(indexPortal)
48  , ValuePortal(valuePortal)
49  {
50  }
51 
57  template <typename OtherIP, typename OtherVP>
58  VISKORES_EXEC_CONT ArrayPortalPermutation(const ArrayPortalPermutation<OtherIP, OtherVP>& src)
59  : IndexPortal(src.GetIndexPortal())
60  , ValuePortal(src.GetValuePortal())
61  {
62  }
63 
65  viskores::Id GetNumberOfValues() const { return this->IndexPortal.GetNumberOfValues(); }
66 
68  ValueType Get(viskores::Id index) const
69  {
70  viskores::Id permutedIndex = this->IndexPortal.Get(index);
71  return this->ValuePortal.Get(permutedIndex);
72  }
73 
74  template <typename Writable_ = Writable,
75  typename = typename std::enable_if<Writable_::value>::type>
76  VISKORES_EXEC void Set(viskores::Id index, const ValueType& value) const
77  {
78  viskores::Id permutedIndex = this->IndexPortal.Get(index);
79  this->ValuePortal.Set(permutedIndex, value);
80  }
81 
83  const IndexPortalType& GetIndexPortal() const { return this->IndexPortal; }
84 
86  const ValuePortalType& GetValuePortal() const { return this->ValuePortal; }
87 
88 private:
89  IndexPortalType IndexPortal;
90  ValuePortalType ValuePortal;
91 };
92 }
93 } // namespace viskores::internal
94 
95 namespace viskores
96 {
97 namespace cont
98 {
99 
100 template <typename IndexStorageTag, typename ValueStorageTag>
101 struct VISKORES_ALWAYS_EXPORT StorageTagPermutation
102 {
103 };
104 
105 namespace internal
106 {
107 
108 template <typename T, typename IndexStorageTag, typename ValueStorageTag>
109 class Storage<T, viskores::cont::StorageTagPermutation<IndexStorageTag, ValueStorageTag>>
110 {
112  (viskores::cont::internal::IsValidArrayHandle<viskores::Id, IndexStorageTag>::value),
113  "Invalid index storage tag.");
115  (viskores::cont::internal::IsValidArrayHandle<T, ValueStorageTag>::value),
116  "Invalid value storage tag.");
117 
118  using IndexStorage = viskores::cont::internal::Storage<viskores::Id, IndexStorageTag>;
119  using ValueStorage = viskores::cont::internal::Storage<T, ValueStorageTag>;
120 
123 
124  struct Info
125  {
126  std::size_t ValueBufferOffset;
127  };
128 
129  VISKORES_CONT static std::vector<viskores::cont::internal::Buffer> IndexBuffers(
130  const std::vector<viskores::cont::internal::Buffer>& buffers)
131  {
132  Info info = buffers[0].GetMetaData<Info>();
133  return std::vector<viskores::cont::internal::Buffer>(buffers.begin() + 1,
134  buffers.begin() + info.ValueBufferOffset);
135  }
136  VISKORES_CONT static std::vector<viskores::cont::internal::Buffer> ValueBuffers(
137  const std::vector<viskores::cont::internal::Buffer>& buffers)
138  {
139  Info info = buffers[0].GetMetaData<Info>();
140  return std::vector<viskores::cont::internal::Buffer>(buffers.begin() + info.ValueBufferOffset,
141  buffers.end());
142  }
143 
144 public:
146 
147  using ReadPortalType =
148  viskores::internal::ArrayPortalPermutation<typename IndexStorage::ReadPortalType,
149  typename ValueStorage::ReadPortalType>;
150  using WritePortalType =
151  viskores::internal::ArrayPortalPermutation<typename IndexStorage::ReadPortalType,
152  typename ValueStorage::WritePortalType>;
153 
154  VISKORES_CONT static viskores::IdComponent GetNumberOfComponentsFlat(
155  const std::vector<viskores::cont::internal::Buffer>& buffers)
156  {
157  return ValueStorage::GetNumberOfComponentsFlat(ValueBuffers(buffers));
158  }
159 
160  VISKORES_CONT static viskores::Id GetNumberOfValues(
161  const std::vector<viskores::cont::internal::Buffer>& buffers)
162  {
163  return IndexStorage::GetNumberOfValues(IndexBuffers(buffers));
164  }
165 
166  VISKORES_CONT static void Fill(const std::vector<viskores::cont::internal::Buffer>&,
167  const T&,
168  viskores::Id,
169  viskores::Id,
171  {
172  throw viskores::cont::ErrorBadType("Fill not supported for ArrayHandlePermutation.");
173  }
174 
175  VISKORES_CONT static ReadPortalType CreateReadPortal(
176  const std::vector<viskores::cont::internal::Buffer>& buffers,
178  viskores::cont::Token& token)
179  {
180  return ReadPortalType(IndexStorage::CreateReadPortal(IndexBuffers(buffers), device, token),
181  ValueStorage::CreateReadPortal(ValueBuffers(buffers), device, token));
182  }
183 
184  VISKORES_CONT static WritePortalType CreateWritePortal(
185  const std::vector<viskores::cont::internal::Buffer>& buffers,
187  viskores::cont::Token& token)
188  {
189  // Note: the index portal is always a read-only portal.
190  return WritePortalType(IndexStorage::CreateReadPortal(IndexBuffers(buffers), device, token),
191  ValueStorage::CreateWritePortal(ValueBuffers(buffers), device, token));
192  }
193 
194  VISKORES_CONT static std::vector<viskores::cont::internal::Buffer> CreateBuffers(
195  const IndexArray& indexArray = IndexArray{},
196  const ValueArray& valueArray = ValueArray{})
197  {
198  Info info;
199  info.ValueBufferOffset = 1 + indexArray.GetBuffers().size();
200  return viskores::cont::internal::CreateBuffers(info, indexArray, valueArray);
201  }
202 
203  VISKORES_CONT static IndexArray GetIndexArray(
204  const std::vector<viskores::cont::internal::Buffer>& buffers)
205  {
206  return IndexArray(IndexBuffers(buffers));
207  }
208 
209  VISKORES_CONT static ValueArray GetValueArray(
210  const std::vector<viskores::cont::internal::Buffer>& buffers)
211  {
212  return ValueArray(ValueBuffers(buffers));
213  }
214 };
215 
216 } // namespace internal
217 
241 template <typename IndexArrayHandleType, typename ValueArrayHandleType>
244  typename ValueArrayHandleType::ValueType,
245  viskores::cont::StorageTagPermutation<typename IndexArrayHandleType::StorageTag,
246  typename ValueArrayHandleType::StorageTag>>
247 {
248  // If the following line gives a compile error, then the ArrayHandleType
249  // template argument is not a valid ArrayHandle type.
250  VISKORES_IS_ARRAY_HANDLE(IndexArrayHandleType);
251  VISKORES_IS_ARRAY_HANDLE(ValueArrayHandleType);
252 
254  (std::is_same<viskores::Id, typename IndexArrayHandleType::ValueType>::value),
255  "Permutation array in ArrayHandlePermutation must have viskores::Id value type.");
256 
257 public:
262  typename ValueArrayHandleType::ValueType,
263  viskores::cont::StorageTagPermutation<typename IndexArrayHandleType::StorageTag,
264  typename ValueArrayHandleType::StorageTag>>));
265 
268  ArrayHandlePermutation(const IndexArrayHandleType& indexArray,
269  const ValueArrayHandleType& valueArray)
270  : Superclass(StorageType::CreateBuffers(indexArray, valueArray))
271  {
272  }
273 
279  VISKORES_CONT IndexArrayHandleType GetIndexArray() const
280  {
281  return StorageType::GetIndexArray(this->GetBuffers());
282  }
283 
289  VISKORES_CONT ValueArrayHandleType GetValueArray() const
290  {
291  return StorageType::GetValueArray(this->GetBuffers());
292  }
293 };
294 
298 template <typename IndexArrayHandleType, typename ValueArrayHandleType>
300 make_ArrayHandlePermutation(IndexArrayHandleType indexArray, ValueArrayHandleType valueArray)
301 {
303 }
304 
305 }
306 } // namespace viskores::cont
307 
308 //=============================================================================
309 // Specializations of serialization related classes
311 namespace viskores
312 {
313 namespace cont
314 {
315 
316 template <typename IdxAH, typename ValAH>
317 struct SerializableTypeString<viskores::cont::ArrayHandlePermutation<IdxAH, ValAH>>
318 {
319  static VISKORES_CONT const std::string& Get()
320  {
321  static std::string name = "AH_Permutation<" + SerializableTypeString<IdxAH>::Get() + "," +
323  return name;
324  }
325 };
326 
327 template <typename T, typename IdxST, typename ValST>
328 struct SerializableTypeString<
329  viskores::cont::ArrayHandle<T, viskores::cont::StorageTagPermutation<IdxST, ValST>>>
330  : SerializableTypeString<
331  viskores::cont::ArrayHandlePermutation<viskores::cont::ArrayHandle<viskores::Id, IdxST>,
332  viskores::cont::ArrayHandle<T, ValST>>>
333 {
334 };
335 }
336 } // viskores::cont
337 
338 namespace mangled_diy_namespace
339 {
340 
341 template <typename IdxAH, typename ValAH>
342 struct Serialization<viskores::cont::ArrayHandlePermutation<IdxAH, ValAH>>
343 {
344 private:
347 
348 public:
349  static VISKORES_CONT void save(BinaryBuffer& bb, const BaseType& obj)
350  {
351  viskoresdiy::save(bb, Type(obj).GetIndexArray());
352  viskoresdiy::save(bb, Type(obj).GetValueArray());
353  }
354 
355  static VISKORES_CONT void load(BinaryBuffer& bb, BaseType& obj)
356  {
357  IdxAH indices;
358  ValAH values;
359 
360  viskoresdiy::load(bb, indices);
361  viskoresdiy::load(bb, values);
362 
363  obj = viskores::cont::make_ArrayHandlePermutation(indices, values);
364  }
365 };
366 
367 template <typename T, typename IdxST, typename ValST>
368 struct Serialization<
369  viskores::cont::ArrayHandle<T, viskores::cont::StorageTagPermutation<IdxST, ValST>>>
370  : Serialization<
371  viskores::cont::ArrayHandlePermutation<viskores::cont::ArrayHandle<viskores::Id, IdxST>,
372  viskores::cont::ArrayHandle<T, ValST>>>
373 {
374 };
375 
376 } // diy
378 
379 #endif //viskores_cont_ArrayHandlePermutation_h
viskores::cont::ArrayHandlePermutation::ArrayHandlePermutation
ArrayHandlePermutation(const IndexArrayHandleType &indexArray, const ValueArrayHandleType &valueArray)
Construct a permuation array with index and value arrays.
Definition: ArrayHandlePermutation.h:268
viskores::cont::ArrayHandlePermutation::StorageType
typename Superclass::StorageType StorageType
Definition: ArrayHandlePermutation.h:264
viskores::exec::arg::load
T load(const U &u, viskores::Id v)
Definition: FetchTagArrayDirectIn.h:44
ArrayHandle.h
viskores::cont::ErrorBadType
This class is thrown when Viskores encounters data of a type that is incompatible with the current op...
Definition: ErrorBadType.h:33
VISKORES_IS_ARRAY_HANDLE
#define VISKORES_IS_ARRAY_HANDLE(T)
Checks that the given type is a viskores::cont::ArrayHandle.
Definition: ArrayHandle.h:145
viskores::cont::ArrayHandle
Manages an array-worth of data.
Definition: ArrayHandle.h:313
viskores::cont::LogLevel::Info
@ Info
Information messages (detected hardware, etc) and temporary debugging output.
viskores::IdComponent
viskores::Int32 IdComponent
Base type to use to index small lists.
Definition: Types.h:202
viskores::cont::ArrayHandlePermutation::GetIndexArray
IndexArrayHandleType GetIndexArray() const
Return the array used for indices.
Definition: ArrayHandlePermutation.h:279
VISKORES_EXEC_CONT
#define VISKORES_EXEC_CONT
Definition: ExportMacros.h:60
mangled_diy_namespace
Definition: Particle.h:373
viskores::cont::ArrayHandlePermutation::GetValueArray
ValueArrayHandleType GetValueArray() const
Return the array used for values.
Definition: ArrayHandlePermutation.h:289
viskores::Id
viskores::Int64 Id
Base type to use to index arrays.
Definition: Types.h:235
VISKORES_CONT
#define VISKORES_CONT
Definition: ExportMacros.h:65
viskores
Groups connected points that have the same field value.
Definition: Atomic.h:27
VISKORES_STORAGE_NO_RESIZE
#define VISKORES_STORAGE_NO_RESIZE
Definition: Storage.h:194
VISKORES_STATIC_ASSERT_MSG
#define VISKORES_STATIC_ASSERT_MSG(condition, message)
Definition: StaticAssert.h:26
viskores::cont::DeviceAdapterId
An object used to specify a device.
Definition: DeviceAdapterTag.h:66
VISKORES_ARRAY_HANDLE_SUBCLASS
#define VISKORES_ARRAY_HANDLE_SUBCLASS(classname, fullclasstype, superclass)
Macro to make default methods in ArrayHandle subclasses.
Definition: ArrayHandle.h:256
ErrorBadValue.h
viskores::Get
auto Get(const viskores::Tuple< Ts... > &tuple)
Retrieve the object from a viskores::Tuple at the given index.
Definition: Tuple.h:89
ErrorBadType.h
viskores::cont::StorageTagPermutation
Definition: ArrayHandlePermutation.h:101
viskores::cont::Token
A token to hold the scope of an ArrayHandle or other object.
Definition: Token.h:43
viskores::cont::ArrayHandle< ValueArrayHandleType::ValueType, viskores::cont::StorageTagPermutation< IndexArrayHandleType::StorageTag, ValueArrayHandleType::StorageTag > >::GetBuffers
const std::vector< viskores::cont::internal::Buffer > & GetBuffers() const
Returns the internal Buffer structures that hold the data.
Definition: ArrayHandle.h:738
viskores::cont::make_ArrayHandlePermutation
viskores::cont::ArrayHandlePermutation< IndexArrayHandleType, ValueArrayHandleType > make_ArrayHandlePermutation(IndexArrayHandleType indexArray, ValueArrayHandleType valueArray)
make_ArrayHandleTransform is convenience function to generate an ArrayHandleTransform.
Definition: ArrayHandlePermutation.h:300
viskores::cont::ArrayHandlePermutation::Superclass
typename viskores::cont::detail::GetTypeInParentheses< void(viskores::cont::ArrayHandle< typename ValueArrayHandleType::ValueType, viskores::cont::StorageTagPermutation< typename IndexArrayHandleType::StorageTag, typename ValueArrayHandleType::StorageTag > >) >::type Superclass
Definition: ArrayHandlePermutation.h:264
VISKORES_EXEC
#define VISKORES_EXEC
Definition: ExportMacros.h:59
viskores::cont::ArrayHandlePermutation
Implicitly permutes the values in an array.
Definition: ArrayHandlePermutation.h:242