VTK-m  2.2
ArrayHandleZip.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_ArrayHandleZip_h
11 #define vtk_m_cont_ArrayHandleZip_h
12 
13 #include <vtkm/Pair.h>
14 #include <vtkm/cont/ArrayHandle.h>
16 
17 namespace vtkm
18 {
19 namespace exec
20 {
21 namespace internal
22 {
23 
26 template <typename PortalTypeFirst, typename PortalTypeSecond>
27 class ArrayPortalZip
28 {
29  using ReadableP1 = vtkm::internal::PortalSupportsGets<PortalTypeFirst>;
30  using ReadableP2 = vtkm::internal::PortalSupportsGets<PortalTypeSecond>;
31  using WritableP1 = vtkm::internal::PortalSupportsSets<PortalTypeFirst>;
32  using WritableP2 = vtkm::internal::PortalSupportsSets<PortalTypeSecond>;
33 
34  using Readable = std::integral_constant<bool, ReadableP1::value && ReadableP2::value>;
35  using Writable = std::integral_constant<bool, WritableP1::value && WritableP2::value>;
36 
37 public:
38  using T = typename PortalTypeFirst::ValueType;
39  using U = typename PortalTypeSecond::ValueType;
40  using ValueType = vtkm::Pair<T, U>;
41 
44  ArrayPortalZip()
45  : PortalFirst()
46  , PortalSecond()
47  {
48  } //needs to be host and device so that cuda can create lvalue of these
49 
50  VTKM_CONT
51  ArrayPortalZip(const PortalTypeFirst& portalfirst, const PortalTypeSecond& portalsecond)
52  : PortalFirst(portalfirst)
53  , PortalSecond(portalsecond)
54  {
55  }
56 
61  template <class OtherF, class OtherS>
62  VTKM_CONT ArrayPortalZip(const ArrayPortalZip<OtherF, OtherS>& src)
63  : PortalFirst(src.GetFirstPortal())
64  , PortalSecond(src.GetSecondPortal())
65  {
66  }
67 
70  vtkm::Id GetNumberOfValues() const { return this->PortalFirst.GetNumberOfValues(); }
71 
73  template <typename Readable_ = Readable,
74  typename = typename std::enable_if<Readable_::value>::type>
75  VTKM_EXEC_CONT ValueType Get(vtkm::Id index) const noexcept
76  {
77  return vtkm::make_Pair(this->PortalFirst.Get(index), this->PortalSecond.Get(index));
78  }
79 
81  template <typename Writable_ = Writable,
82  typename = typename std::enable_if<Writable_::value>::type>
83  VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const noexcept
84  {
85  this->PortalFirst.Set(index, value.first);
86  this->PortalSecond.Set(index, value.second);
87  }
88 
90  const PortalTypeFirst& GetFirstPortal() const { return this->PortalFirst; }
91 
93  const PortalTypeSecond& GetSecondPortal() const { return this->PortalSecond; }
94 
95 private:
96  PortalTypeFirst PortalFirst;
97  PortalTypeSecond PortalSecond;
98 };
99 }
100 }
101 } // namespace vtkm::exec::internal
102 
103 namespace vtkm
104 {
105 namespace cont
106 {
107 
108 template <typename ST1, typename ST2>
110 {
111 };
112 
113 namespace internal
114 {
115 
119 template <typename FirstHandleType, typename SecondHandleType>
120 struct ArrayHandleZipTraits
121 {
124  using ValueType =
126 
129  using Tag =
131 
134  using Superclass = vtkm::cont::ArrayHandle<ValueType, Tag>;
135 };
136 
137 template <typename T1, typename T2, typename ST1, typename ST2>
138 class Storage<vtkm::Pair<T1, T2>, vtkm::cont::StorageTagZip<ST1, ST2>>
139 {
140  using FirstStorage = Storage<T1, ST1>;
141  using SecondStorage = Storage<T2, ST2>;
142  using ValueType = vtkm::Pair<T1, T2>;
143 
144  using FirstArrayType = vtkm::cont::ArrayHandle<T1, ST1>;
145  using SecondArrayType = vtkm::cont::ArrayHandle<T2, ST2>;
146 
147  struct Info
148  {
149  std::size_t SecondBuffersOffset;
150  };
151 
152  VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> FirstArrayBuffers(
153  const std::vector<vtkm::cont::internal::Buffer>& buffers)
154  {
155  const Info& info = buffers[0].GetMetaData<Info>();
156  return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1,
157  buffers.begin() + info.SecondBuffersOffset);
158  }
159  VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> SecondArrayBuffers(
160  const std::vector<vtkm::cont::internal::Buffer>& buffers)
161  {
162  const Info& info = buffers[0].GetMetaData<Info>();
163  return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + info.SecondBuffersOffset,
164  buffers.end());
165  }
166 
167 public:
168  using ReadPortalType =
169  vtkm::exec::internal::ArrayPortalZip<typename FirstStorage::ReadPortalType,
170  typename SecondStorage::ReadPortalType>;
171  using WritePortalType =
172  vtkm::exec::internal::ArrayPortalZip<typename FirstStorage::WritePortalType,
173  typename SecondStorage::WritePortalType>;
174 
175  static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
176  const FirstArrayType& firstArray = FirstArrayType{},
177  const SecondArrayType& secondArray = SecondArrayType{})
178  {
179  Info info;
180  info.SecondBuffersOffset = 1 + firstArray.GetBuffers().size();
181  return vtkm::cont::internal::CreateBuffers(info, firstArray, secondArray);
182  }
183 
184  VTKM_CONT static vtkm::IdComponent GetNumberOfComponentsFlat(
185  const std::vector<vtkm::cont::internal::Buffer>&)
186  {
187  return 1;
188  }
189 
190  VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
191  const std::vector<vtkm::cont::internal::Buffer>& buffers,
192  vtkm::CopyFlag preserve,
193  vtkm::cont::Token& token)
194  {
195  FirstStorage::ResizeBuffers(numValues, FirstArrayBuffers(buffers), preserve, token);
196  SecondStorage::ResizeBuffers(numValues, SecondArrayBuffers(buffers), preserve, token);
197  }
198 
199  VTKM_CONT static vtkm::Id GetNumberOfValues(
200  const std::vector<vtkm::cont::internal::Buffer>& buffers)
201  {
202  vtkm::Id numValues = FirstStorage::GetNumberOfValues(FirstArrayBuffers(buffers));
203  VTKM_ASSERT(numValues == SecondStorage::GetNumberOfValues(SecondArrayBuffers(buffers)));
204  return numValues;
205  }
206 
207  VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
208  const ValueType& fillValue,
209  vtkm::Id startIndex,
210  vtkm::Id endIndex,
211  vtkm::cont::Token& token)
212  {
213  FirstStorage::Fill(FirstArrayBuffers(buffers), fillValue.first, startIndex, endIndex, token);
214  SecondStorage::Fill(SecondArrayBuffers(buffers), fillValue.second, startIndex, endIndex, token);
215  }
216 
217  VTKM_CONT static ReadPortalType CreateReadPortal(
218  const std::vector<vtkm::cont::internal::Buffer>& buffers,
220  vtkm::cont::Token& token)
221  {
222  return ReadPortalType(
223  FirstStorage::CreateReadPortal(FirstArrayBuffers(buffers), device, token),
224  SecondStorage::CreateReadPortal(SecondArrayBuffers(buffers), device, token));
225  }
226 
227  VTKM_CONT static WritePortalType CreateWritePortal(
228  const std::vector<vtkm::cont::internal::Buffer>& buffers,
230  vtkm::cont::Token& token)
231  {
232  return WritePortalType(
233  FirstStorage::CreateWritePortal(FirstArrayBuffers(buffers), device, token),
234  SecondStorage::CreateWritePortal(SecondArrayBuffers(buffers), device, token));
235  }
236 
237  static FirstArrayType GetFirstArray(const std::vector<vtkm::cont::internal::Buffer>& buffers)
238  {
239  return FirstArrayType(FirstArrayBuffers(buffers));
240  }
241  static SecondArrayType GetSecondArray(const std::vector<vtkm::cont::internal::Buffer>& buffers)
242  {
243  return SecondArrayType(SecondArrayBuffers(buffers));
244  }
245 };
246 } // namespace internal
247 
252 template <typename FirstHandleType, typename SecondHandleType>
254  : public internal::ArrayHandleZipTraits<FirstHandleType, SecondHandleType>::Superclass
255 {
256  // If the following line gives a compile error, then the FirstHandleType
257  // template argument is not a valid ArrayHandle type.
258  VTKM_IS_ARRAY_HANDLE(FirstHandleType);
259 
260  // If the following line gives a compile error, then the SecondHandleType
261  // template argument is not a valid ArrayHandle type.
262  VTKM_IS_ARRAY_HANDLE(SecondHandleType);
263 
264 public:
269 
271  VTKM_CONT
272  ArrayHandleZip(const FirstHandleType& firstArray, const SecondHandleType& secondArray)
273  : Superclass(StorageType::CreateBuffers(firstArray, secondArray))
274  {
275  }
276 
278  FirstHandleType GetFirstArray() const { return StorageType::GetFirstArray(this->GetBuffers()); }
280  SecondHandleType GetSecondArray() const
281  {
282  return StorageType::GetSecondArray(this->GetBuffers());
283  }
284 };
285 
289 template <typename FirstHandleType, typename SecondHandleType>
291  const FirstHandleType& first,
292  const SecondHandleType& second)
293 {
295 }
296 }
297 } // namespace vtkm::cont
298 
299 //=============================================================================
300 // Specializations of serialization related classes
302 namespace vtkm
303 {
304 namespace cont
305 {
306 
307 template <typename AH1, typename AH2>
308 struct SerializableTypeString<vtkm::cont::ArrayHandleZip<AH1, AH2>>
309 {
310  static VTKM_CONT const std::string& Get()
311  {
312  static std::string name = "AH_Zip<" + SerializableTypeString<AH1>::Get() + "," +
314  return name;
315  }
316 };
317 
318 template <typename T1, typename T2, typename ST1, typename ST2>
319 struct SerializableTypeString<
320  vtkm::cont::ArrayHandle<vtkm::Pair<T1, T2>, vtkm::cont::StorageTagZip<ST1, ST2>>>
321  : SerializableTypeString<vtkm::cont::ArrayHandleZip<vtkm::cont::ArrayHandle<T1, ST1>,
322  vtkm::cont::ArrayHandle<T2, ST2>>>
323 {
324 };
325 }
326 } // namespace vtkm::cont
327 
328 namespace mangled_diy_namespace
329 {
330 
331 template <typename AH1, typename AH2>
332 struct Serialization<vtkm::cont::ArrayHandleZip<AH1, AH2>>
333 {
334 private:
335  using Type = typename vtkm::cont::ArrayHandleZip<AH1, AH2>;
337 
338 public:
339  static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
340  {
341  auto storage = obj.GetStorage();
342  vtkmdiy::save(bb, storage.GetFirstArray());
343  vtkmdiy::save(bb, storage.GetSecondArray());
344  }
345 
346  static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj)
347  {
348  AH1 a1;
349  AH2 a2;
350 
351  vtkmdiy::load(bb, a1);
352  vtkmdiy::load(bb, a2);
353 
354  obj = vtkm::cont::make_ArrayHandleZip(a1, a2);
355  }
356 };
357 
358 template <typename T1, typename T2, typename ST1, typename ST2>
359 struct Serialization<
360  vtkm::cont::ArrayHandle<vtkm::Pair<T1, T2>, vtkm::cont::StorageTagZip<ST1, ST2>>>
361  : Serialization<vtkm::cont::ArrayHandleZip<vtkm::cont::ArrayHandle<T1, ST1>,
362  vtkm::cont::ArrayHandle<T2, ST2>>>
363 {
364 };
365 
366 } // diy
368 
369 #endif //vtk_m_cont_ArrayHandleZip_h
vtkm::cont::ArrayHandle
Manages an array-worth of data.
Definition: ArrayHandle.h:300
ArrayHandle.h
vtkm::cont::ArrayHandle::GetBuffers
const std::vector< vtkm::cont::internal::Buffer > & GetBuffers() const
Returns the internal Buffer structures that hold the data.
Definition: ArrayHandle.h:721
vtkm::cont::StorageTagZip
Definition: ArrayHandleZip.h:109
vtkm::exec::arg::load
T load(const U &u, vtkm::Id v)
Definition: FetchTagArrayDirectIn.h:36
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
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
ArrayPortalHelpers.h
VTKM_ASSERT
#define VTKM_ASSERT(condition)
Definition: Assert.h:43
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
Pair.h
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::make_ArrayHandleZip
vtkm::cont::ArrayHandleZip< FirstHandleType, SecondHandleType > make_ArrayHandleZip(const FirstHandleType &first, const SecondHandleType &second)
A convenience function for creating an ArrayHandleZip.
Definition: ArrayHandleZip.h:290
vtkm::cont::LogLevel::Info
@ Info
Information messages (detected hardware, etc) and temporary debugging output.
vtkm::cont::ArrayHandleZip
ArrayHandleZip is a specialization of ArrayHandle.
Definition: ArrayHandleZip.h:253
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::ArrayHandleZip::GetFirstArray
FirstHandleType GetFirstArray() const
Returns the the array for the first part of the zip pair.
Definition: ArrayHandleZip.h:278
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::ArrayHandleZip::Superclass
typename vtkm::cont::detail::GetTypeInParentheses< void(typename internal::ArrayHandleZipTraits< FirstHandleType, SecondHandleType >::Superclass) >::type Superclass
Definition: ArrayHandleZip.h:268
vtkm::cont::DeviceAdapterId
An object used to specify a device.
Definition: DeviceAdapterTag.h:58
vtkm::cont::ArrayHandleZip::ArrayHandleZip
ArrayHandleZip(const FirstHandleType &firstArray, const SecondHandleType &secondArray)
Create ArrayHandleZip with two arrays.
Definition: ArrayHandleZip.h:272
vtkm::cont::ArrayHandle::StorageType
vtkm::cont::internal::Storage< ValueType, StorageTag > StorageType
Definition: ArrayHandle.h:309
vtkm::CopyFlag
CopyFlag
Identifier used to specify whether a function should deep copy data.
Definition: Flags.h:17
vtkm::cont::ArrayHandleZip::GetSecondArray
SecondHandleType GetSecondArray() const
Returns the the array for the second part of the zip pair.
Definition: ArrayHandleZip.h:280
VTKM_ALWAYS_EXPORT
#define VTKM_ALWAYS_EXPORT
Definition: ExportMacros.h:89
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_SUPPRESS_EXEC_WARNINGS
#define VTKM_SUPPRESS_EXEC_WARNINGS
Definition: ExportMacros.h:53
vtkm::make_Pair
vtkm::Pair< typename std::decay< T1 >::type, typename std::decay< T2 >::type > make_Pair(T1 &&v1, T2 &&v2)
Definition: Pair.h:164