VTK-m  2.0
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 Storage = vtkm::cont::internal::Storage<ValueType, Tag>;
135 
138  using Superclass = vtkm::cont::ArrayHandle<ValueType, Tag>;
139 };
140 
141 template <typename T1, typename T2, typename ST1, typename ST2>
142 class Storage<vtkm::Pair<T1, T2>, vtkm::cont::StorageTagZip<ST1, ST2>>
143 {
144  using FirstStorage = Storage<T1, ST1>;
145  using SecondStorage = Storage<T2, ST2>;
146  using ValueType = vtkm::Pair<T1, T2>;
147 
148  using FirstArrayType = vtkm::cont::ArrayHandle<T1, ST1>;
149  using SecondArrayType = vtkm::cont::ArrayHandle<T2, ST2>;
150 
151  struct Info
152  {
153  std::size_t SecondBuffersOffset;
154  };
155 
156  VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> FirstArrayBuffers(
157  const std::vector<vtkm::cont::internal::Buffer>& buffers)
158  {
159  const Info& info = buffers[0].GetMetaData<Info>();
160  return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1,
161  buffers.begin() + info.SecondBuffersOffset);
162  }
163  VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> SecondArrayBuffers(
164  const std::vector<vtkm::cont::internal::Buffer>& buffers)
165  {
166  const Info& info = buffers[0].GetMetaData<Info>();
167  return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + info.SecondBuffersOffset,
168  buffers.end());
169  }
170 
171 public:
172  using ReadPortalType =
173  vtkm::exec::internal::ArrayPortalZip<typename FirstStorage::ReadPortalType,
174  typename SecondStorage::ReadPortalType>;
175  using WritePortalType =
176  vtkm::exec::internal::ArrayPortalZip<typename FirstStorage::WritePortalType,
177  typename SecondStorage::WritePortalType>;
178 
179  static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
180  const FirstArrayType& firstArray = FirstArrayType{},
181  const SecondArrayType& secondArray = SecondArrayType{})
182  {
183  Info info;
184  info.SecondBuffersOffset = 1 + firstArray.GetBuffers().size();
185  return vtkm::cont::internal::CreateBuffers(info, firstArray, secondArray);
186  }
187 
188  VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
189  const std::vector<vtkm::cont::internal::Buffer>& buffers,
190  vtkm::CopyFlag preserve,
191  vtkm::cont::Token& token)
192  {
193  FirstStorage::ResizeBuffers(numValues, FirstArrayBuffers(buffers), preserve, token);
194  SecondStorage::ResizeBuffers(numValues, SecondArrayBuffers(buffers), preserve, token);
195  }
196 
197  VTKM_CONT static vtkm::Id GetNumberOfValues(
198  const std::vector<vtkm::cont::internal::Buffer>& buffers)
199  {
200  vtkm::Id numValues = FirstStorage::GetNumberOfValues(FirstArrayBuffers(buffers));
201  VTKM_ASSERT(numValues == SecondStorage::GetNumberOfValues(SecondArrayBuffers(buffers)));
202  return numValues;
203  }
204 
205  VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
206  const ValueType& fillValue,
207  vtkm::Id startIndex,
208  vtkm::Id endIndex,
209  vtkm::cont::Token& token)
210  {
211  FirstStorage::Fill(FirstArrayBuffers(buffers), fillValue.first, startIndex, endIndex, token);
212  SecondStorage::Fill(SecondArrayBuffers(buffers), fillValue.second, startIndex, endIndex, token);
213  }
214 
215  VTKM_CONT static ReadPortalType CreateReadPortal(
216  const std::vector<vtkm::cont::internal::Buffer>& buffers,
218  vtkm::cont::Token& token)
219  {
220  return ReadPortalType(
221  FirstStorage::CreateReadPortal(FirstArrayBuffers(buffers), device, token),
222  SecondStorage::CreateReadPortal(SecondArrayBuffers(buffers), device, token));
223  }
224 
225  VTKM_CONT static WritePortalType CreateWritePortal(
226  const std::vector<vtkm::cont::internal::Buffer>& buffers,
228  vtkm::cont::Token& token)
229  {
230  return WritePortalType(
231  FirstStorage::CreateWritePortal(FirstArrayBuffers(buffers), device, token),
232  SecondStorage::CreateWritePortal(SecondArrayBuffers(buffers), device, token));
233  }
234 
235  static FirstArrayType GetFirstArray(const std::vector<vtkm::cont::internal::Buffer>& buffers)
236  {
237  return { FirstArrayBuffers(buffers) };
238  }
239  static SecondArrayType GetSecondArray(const std::vector<vtkm::cont::internal::Buffer>& buffers)
240  {
241  return { SecondArrayBuffers(buffers) };
242  }
243 };
244 } // namespace internal
245 
250 template <typename FirstHandleType, typename SecondHandleType>
252  : public internal::ArrayHandleZipTraits<FirstHandleType, SecondHandleType>::Superclass
253 {
254  // If the following line gives a compile error, then the FirstHandleType
255  // template argument is not a valid ArrayHandle type.
256  VTKM_IS_ARRAY_HANDLE(FirstHandleType);
257 
258  // If the following line gives a compile error, then the SecondHandleType
259  // template argument is not a valid ArrayHandle type.
260  VTKM_IS_ARRAY_HANDLE(SecondHandleType);
261 
262  using StorageType =
263  typename internal::ArrayHandleZipTraits<FirstHandleType, SecondHandleType>::Storage;
264 
265 public:
270 
271  VTKM_CONT
272  ArrayHandleZip(const FirstHandleType& firstArray, const SecondHandleType& secondArray)
273  : Superclass(StorageType::CreateBuffers(firstArray, secondArray))
274  {
275  }
276 
277  FirstHandleType GetFirstArray() const { return StorageType::GetFirstArray(this->GetBuffers()); }
278  SecondHandleType GetSecondArray() const
279  {
280  return StorageType::GetSecondArray(this->GetBuffers());
281  }
282 };
283 
287 template <typename FirstHandleType, typename SecondHandleType>
289  const FirstHandleType& first,
290  const SecondHandleType& second)
291 {
293 }
294 }
295 } // namespace vtkm::cont
296 
297 //=============================================================================
298 // Specializations of serialization related classes
300 namespace vtkm
301 {
302 namespace cont
303 {
304 
305 template <typename AH1, typename AH2>
306 struct SerializableTypeString<vtkm::cont::ArrayHandleZip<AH1, AH2>>
307 {
308  static VTKM_CONT const std::string& Get()
309  {
310  static std::string name = "AH_Zip<" + SerializableTypeString<AH1>::Get() + "," +
312  return name;
313  }
314 };
315 
316 template <typename T1, typename T2, typename ST1, typename ST2>
317 struct SerializableTypeString<
318  vtkm::cont::ArrayHandle<vtkm::Pair<T1, T2>, vtkm::cont::StorageTagZip<ST1, ST2>>>
319  : SerializableTypeString<vtkm::cont::ArrayHandleZip<vtkm::cont::ArrayHandle<T1, ST1>,
320  vtkm::cont::ArrayHandle<T2, ST2>>>
321 {
322 };
323 }
324 } // namespace vtkm::cont
325 
326 namespace mangled_diy_namespace
327 {
328 
329 template <typename AH1, typename AH2>
330 struct Serialization<vtkm::cont::ArrayHandleZip<AH1, AH2>>
331 {
332 private:
333  using Type = typename vtkm::cont::ArrayHandleZip<AH1, AH2>;
335 
336 public:
337  static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
338  {
339  auto storage = obj.GetStorage();
340  vtkmdiy::save(bb, storage.GetFirstArray());
341  vtkmdiy::save(bb, storage.GetSecondArray());
342  }
343 
344  static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj)
345  {
346  AH1 a1;
347  AH2 a2;
348 
349  vtkmdiy::load(bb, a1);
350  vtkmdiy::load(bb, a2);
351 
352  obj = vtkm::cont::make_ArrayHandleZip(a1, a2);
353  }
354 };
355 
356 template <typename T1, typename T2, typename ST1, typename ST2>
357 struct Serialization<
358  vtkm::cont::ArrayHandle<vtkm::Pair<T1, T2>, vtkm::cont::StorageTagZip<ST1, ST2>>>
359  : Serialization<vtkm::cont::ArrayHandleZip<vtkm::cont::ArrayHandle<T1, ST1>,
360  vtkm::cont::ArrayHandle<T2, ST2>>>
361 {
362 };
363 
364 } // diy
366 
367 #endif //vtk_m_cont_ArrayHandleZip_h
vtkm::cont::ArrayHandle::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::ArrayHandleZip::VTKM_IS_ARRAY_HANDLE
VTKM_IS_ARRAY_HANDLE(FirstHandleType)
vtkm::cont::ArrayHandle
Manages an array-worth of data.
Definition: ArrayHandle.h:283
ArrayHandle.h
vtkm::make_Pair
VTKM_EXEC_CONT vtkm::Pair< typename std::decay< T1 >::type, typename std::decay< T2 >::type > make_Pair(T1 &&v1, T2 &&v2)
Definition: Pair.h:164
vtkm::cont::StorageTagZip
Definition: ArrayHandleZip.h:109
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
ArrayPortalHelpers.h
VTKM_ASSERT
#define VTKM_ASSERT(condition)
Definition: Assert.h:43
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
Pair.h
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::ArrayHandleZip
ArrayHandleZip is a specialization of ArrayHandle.
Definition: ArrayHandleZip.h:251
vtkm::cont::make_ArrayHandleZip
VTKM_CONT vtkm::cont::ArrayHandleZip< FirstHandleType, SecondHandleType > make_ArrayHandleZip(const FirstHandleType &first, const SecondHandleType &second)
A convenience function for creating an ArrayHandleZip.
Definition: ArrayHandleZip.h:288
vtkm::cont::ArrayHandleZip::ArrayHandleZip
VTKM_CONT ArrayHandleZip(const FirstHandleType &firstArray, const SecondHandleType &secondArray)
Definition: ArrayHandleZip.h:272
vtkm::cont::ArrayHandleZip::GetFirstArray
FirstHandleType GetFirstArray() const
Definition: ArrayHandleZip.h:277
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
vtkm::cont::DeviceAdapterId
Definition: DeviceAdapterTag.h:52
vtkm::cont::ArrayHandle::StorageType
vtkm::cont::internal::Storage< ValueType, StorageTag > StorageType
Definition: ArrayHandle.h:292
vtkm::CopyFlag
CopyFlag
Definition: Flags.h:16
vtkm::cont::ArrayHandleZip::GetSecondArray
SecondHandleType GetSecondArray() const
Definition: ArrayHandleZip.h:278
VTKM_ALWAYS_EXPORT
#define VTKM_ALWAYS_EXPORT
Definition: ExportMacros.h:92
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::cont::ArrayHandleZip::VTKM_ARRAY_HANDLE_SUBCLASS
VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandleZip,(ArrayHandleZip< FirstHandleType, SecondHandleType >),(typename internal::ArrayHandleZipTraits< FirstHandleType, SecondHandleType >::Superclass))
VTKM_SUPPRESS_EXEC_WARNINGS
#define VTKM_SUPPRESS_EXEC_WARNINGS
Definition: ExportMacros.h:53