VTK-m  2.1
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 
270  VTKM_CONT
271  ArrayHandleZip(const FirstHandleType& firstArray, const SecondHandleType& secondArray)
272  : Superclass(StorageType::CreateBuffers(firstArray, secondArray))
273  {
274  }
275 
276  FirstHandleType GetFirstArray() const { return StorageType::GetFirstArray(this->GetBuffers()); }
277  SecondHandleType GetSecondArray() const
278  {
279  return StorageType::GetSecondArray(this->GetBuffers());
280  }
281 };
282 
286 template <typename FirstHandleType, typename SecondHandleType>
288  const FirstHandleType& first,
289  const SecondHandleType& second)
290 {
292 }
293 }
294 } // namespace vtkm::cont
295 
296 //=============================================================================
297 // Specializations of serialization related classes
299 namespace vtkm
300 {
301 namespace cont
302 {
303 
304 template <typename AH1, typename AH2>
305 struct SerializableTypeString<vtkm::cont::ArrayHandleZip<AH1, AH2>>
306 {
307  static VTKM_CONT const std::string& Get()
308  {
309  static std::string name = "AH_Zip<" + SerializableTypeString<AH1>::Get() + "," +
311  return name;
312  }
313 };
314 
315 template <typename T1, typename T2, typename ST1, typename ST2>
316 struct SerializableTypeString<
317  vtkm::cont::ArrayHandle<vtkm::Pair<T1, T2>, vtkm::cont::StorageTagZip<ST1, ST2>>>
318  : SerializableTypeString<vtkm::cont::ArrayHandleZip<vtkm::cont::ArrayHandle<T1, ST1>,
319  vtkm::cont::ArrayHandle<T2, ST2>>>
320 {
321 };
322 }
323 } // namespace vtkm::cont
324 
325 namespace mangled_diy_namespace
326 {
327 
328 template <typename AH1, typename AH2>
329 struct Serialization<vtkm::cont::ArrayHandleZip<AH1, AH2>>
330 {
331 private:
332  using Type = typename vtkm::cont::ArrayHandleZip<AH1, AH2>;
334 
335 public:
336  static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
337  {
338  auto storage = obj.GetStorage();
339  vtkmdiy::save(bb, storage.GetFirstArray());
340  vtkmdiy::save(bb, storage.GetSecondArray());
341  }
342 
343  static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj)
344  {
345  AH1 a1;
346  AH2 a2;
347 
348  vtkmdiy::load(bb, a1);
349  vtkmdiy::load(bb, a2);
350 
351  obj = vtkm::cont::make_ArrayHandleZip(a1, a2);
352  }
353 };
354 
355 template <typename T1, typename T2, typename ST1, typename ST2>
356 struct Serialization<
357  vtkm::cont::ArrayHandle<vtkm::Pair<T1, T2>, vtkm::cont::StorageTagZip<ST1, ST2>>>
358  : Serialization<vtkm::cont::ArrayHandleZip<vtkm::cont::ArrayHandle<T1, ST1>,
359  vtkm::cont::ArrayHandle<T2, ST2>>>
360 {
361 };
362 
363 } // diy
365 
366 #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:719
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:287
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
Definition: ArrayHandleZip.h:276
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)
Definition: ArrayHandleZip.h:271
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
Definition: ArrayHandleZip.h:277
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