Viskores  1.0
ArrayHandleZip.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_ArrayHandleZip_h
19 #define viskores_cont_ArrayHandleZip_h
20 
21 #include <viskores/Pair.h>
24 
25 namespace viskores
26 {
27 namespace exec
28 {
29 namespace internal
30 {
31 
34 template <typename PortalTypeFirst, typename PortalTypeSecond>
35 class ArrayPortalZip
36 {
37  using ReadableP1 = viskores::internal::PortalSupportsGets<PortalTypeFirst>;
38  using ReadableP2 = viskores::internal::PortalSupportsGets<PortalTypeSecond>;
39  using WritableP1 = viskores::internal::PortalSupportsSets<PortalTypeFirst>;
40  using WritableP2 = viskores::internal::PortalSupportsSets<PortalTypeSecond>;
41 
42  using Readable = std::integral_constant<bool, ReadableP1::value && ReadableP2::value>;
43  using Writable = std::integral_constant<bool, WritableP1::value && WritableP2::value>;
44 
45 public:
46  using T = typename PortalTypeFirst::ValueType;
47  using U = typename PortalTypeSecond::ValueType;
48  using ValueType = viskores::Pair<T, U>;
49 
52  ArrayPortalZip()
53  : PortalFirst()
54  , PortalSecond()
55  {
56  } //needs to be host and device so that cuda can create lvalue of these
57 
59  ArrayPortalZip(const PortalTypeFirst& portalfirst, const PortalTypeSecond& portalsecond)
60  : PortalFirst(portalfirst)
61  , PortalSecond(portalsecond)
62  {
63  }
64 
69  template <class OtherF, class OtherS>
70  VISKORES_CONT ArrayPortalZip(const ArrayPortalZip<OtherF, OtherS>& src)
71  : PortalFirst(src.GetFirstPortal())
72  , PortalSecond(src.GetSecondPortal())
73  {
74  }
75 
78  viskores::Id GetNumberOfValues() const { return this->PortalFirst.GetNumberOfValues(); }
79 
81  template <typename Readable_ = Readable,
82  typename = typename std::enable_if<Readable_::value>::type>
83  VISKORES_EXEC_CONT ValueType Get(viskores::Id index) const noexcept
84  {
85  return viskores::make_Pair(this->PortalFirst.Get(index), this->PortalSecond.Get(index));
86  }
87 
89  template <typename Writable_ = Writable,
90  typename = typename std::enable_if<Writable_::value>::type>
91  VISKORES_EXEC_CONT void Set(viskores::Id index, const ValueType& value) const noexcept
92  {
93  this->PortalFirst.Set(index, value.first);
94  this->PortalSecond.Set(index, value.second);
95  }
96 
98  const PortalTypeFirst& GetFirstPortal() const { return this->PortalFirst; }
99 
101  const PortalTypeSecond& GetSecondPortal() const { return this->PortalSecond; }
102 
103 private:
104  PortalTypeFirst PortalFirst;
105  PortalTypeSecond PortalSecond;
106 };
107 }
108 }
109 } // namespace viskores::exec::internal
110 
111 namespace viskores
112 {
113 namespace cont
114 {
115 
116 template <typename ST1, typename ST2>
117 struct VISKORES_ALWAYS_EXPORT StorageTagZip
118 {
119 };
120 
121 namespace internal
122 {
123 
127 template <typename FirstHandleType, typename SecondHandleType>
128 struct ArrayHandleZipTraits
129 {
132  using ValueType =
134 
137  using Tag =
139 
143 };
144 
145 template <typename T1, typename T2, typename ST1, typename ST2>
146 class Storage<viskores::Pair<T1, T2>, viskores::cont::StorageTagZip<ST1, ST2>>
147 {
148  using FirstStorage = Storage<T1, ST1>;
149  using SecondStorage = Storage<T2, ST2>;
150  using ValueType = viskores::Pair<T1, T2>;
151 
152  using FirstArrayType = viskores::cont::ArrayHandle<T1, ST1>;
153  using SecondArrayType = viskores::cont::ArrayHandle<T2, ST2>;
154 
155  struct Info
156  {
157  std::size_t SecondBuffersOffset;
158  };
159 
160  VISKORES_CONT static std::vector<viskores::cont::internal::Buffer> FirstArrayBuffers(
161  const std::vector<viskores::cont::internal::Buffer>& buffers)
162  {
163  const Info& info = buffers[0].GetMetaData<Info>();
164  return std::vector<viskores::cont::internal::Buffer>(
165  buffers.begin() + 1, buffers.begin() + info.SecondBuffersOffset);
166  }
167  VISKORES_CONT static std::vector<viskores::cont::internal::Buffer> SecondArrayBuffers(
168  const std::vector<viskores::cont::internal::Buffer>& buffers)
169  {
170  const Info& info = buffers[0].GetMetaData<Info>();
171  return std::vector<viskores::cont::internal::Buffer>(buffers.begin() + info.SecondBuffersOffset,
172  buffers.end());
173  }
174 
175 public:
176  using ReadPortalType =
177  viskores::exec::internal::ArrayPortalZip<typename FirstStorage::ReadPortalType,
178  typename SecondStorage::ReadPortalType>;
179  using WritePortalType =
180  viskores::exec::internal::ArrayPortalZip<typename FirstStorage::WritePortalType,
181  typename SecondStorage::WritePortalType>;
182 
183  static std::vector<viskores::cont::internal::Buffer> CreateBuffers(
184  const FirstArrayType& firstArray = FirstArrayType{},
185  const SecondArrayType& secondArray = SecondArrayType{})
186  {
187  Info info;
188  info.SecondBuffersOffset = 1 + firstArray.GetBuffers().size();
189  return viskores::cont::internal::CreateBuffers(info, firstArray, secondArray);
190  }
191 
192  VISKORES_CONT static viskores::IdComponent GetNumberOfComponentsFlat(
193  const std::vector<viskores::cont::internal::Buffer>&)
194  {
195  return 1;
196  }
197 
198  VISKORES_CONT static void ResizeBuffers(
199  viskores::Id numValues,
200  const std::vector<viskores::cont::internal::Buffer>& buffers,
201  viskores::CopyFlag preserve,
202  viskores::cont::Token& token)
203  {
204  FirstStorage::ResizeBuffers(numValues, FirstArrayBuffers(buffers), preserve, token);
205  SecondStorage::ResizeBuffers(numValues, SecondArrayBuffers(buffers), preserve, token);
206  }
207 
208  VISKORES_CONT static viskores::Id GetNumberOfValues(
209  const std::vector<viskores::cont::internal::Buffer>& buffers)
210  {
211  viskores::Id numValues = FirstStorage::GetNumberOfValues(FirstArrayBuffers(buffers));
212  VISKORES_ASSERT(numValues == SecondStorage::GetNumberOfValues(SecondArrayBuffers(buffers)));
213  return numValues;
214  }
215 
216  VISKORES_CONT static void Fill(const std::vector<viskores::cont::internal::Buffer>& buffers,
217  const ValueType& fillValue,
218  viskores::Id startIndex,
219  viskores::Id endIndex,
220  viskores::cont::Token& token)
221  {
222  FirstStorage::Fill(FirstArrayBuffers(buffers), fillValue.first, startIndex, endIndex, token);
223  SecondStorage::Fill(SecondArrayBuffers(buffers), fillValue.second, startIndex, endIndex, token);
224  }
225 
226  VISKORES_CONT static ReadPortalType CreateReadPortal(
227  const std::vector<viskores::cont::internal::Buffer>& buffers,
229  viskores::cont::Token& token)
230  {
231  return ReadPortalType(
232  FirstStorage::CreateReadPortal(FirstArrayBuffers(buffers), device, token),
233  SecondStorage::CreateReadPortal(SecondArrayBuffers(buffers), device, token));
234  }
235 
236  VISKORES_CONT static WritePortalType CreateWritePortal(
237  const std::vector<viskores::cont::internal::Buffer>& buffers,
239  viskores::cont::Token& token)
240  {
241  return WritePortalType(
242  FirstStorage::CreateWritePortal(FirstArrayBuffers(buffers), device, token),
243  SecondStorage::CreateWritePortal(SecondArrayBuffers(buffers), device, token));
244  }
245 
246  static FirstArrayType GetFirstArray(const std::vector<viskores::cont::internal::Buffer>& buffers)
247  {
248  return FirstArrayType(FirstArrayBuffers(buffers));
249  }
250  static SecondArrayType GetSecondArray(
251  const std::vector<viskores::cont::internal::Buffer>& buffers)
252  {
253  return SecondArrayType(SecondArrayBuffers(buffers));
254  }
255 };
256 } // namespace internal
257 
262 template <typename FirstHandleType, typename SecondHandleType>
264  : public internal::ArrayHandleZipTraits<FirstHandleType, SecondHandleType>::Superclass
265 {
266  // If the following line gives a compile error, then the FirstHandleType
267  // template argument is not a valid ArrayHandle type.
268  VISKORES_IS_ARRAY_HANDLE(FirstHandleType);
269 
270  // If the following line gives a compile error, then the SecondHandleType
271  // template argument is not a valid ArrayHandle type.
272  VISKORES_IS_ARRAY_HANDLE(SecondHandleType);
273 
274 public:
279 
282  ArrayHandleZip(const FirstHandleType& firstArray, const SecondHandleType& secondArray)
283  : Superclass(StorageType::CreateBuffers(firstArray, secondArray))
284  {
285  }
286 
288  FirstHandleType GetFirstArray() const { return StorageType::GetFirstArray(this->GetBuffers()); }
290  SecondHandleType GetSecondArray() const
291  {
292  return StorageType::GetSecondArray(this->GetBuffers());
293  }
294 };
295 
299 template <typename FirstHandleType, typename SecondHandleType>
301  const FirstHandleType& first,
302  const SecondHandleType& second)
303 {
305 }
306 }
307 } // namespace viskores::cont
308 
309 //=============================================================================
310 // Specializations of serialization related classes
312 namespace viskores
313 {
314 namespace cont
315 {
316 
317 template <typename AH1, typename AH2>
318 struct SerializableTypeString<viskores::cont::ArrayHandleZip<AH1, AH2>>
319 {
320  static VISKORES_CONT const std::string& Get()
321  {
322  static std::string name = "AH_Zip<" + SerializableTypeString<AH1>::Get() + "," +
324  return name;
325  }
326 };
327 
328 template <typename T1, typename T2, typename ST1, typename ST2>
329 struct SerializableTypeString<
330  viskores::cont::ArrayHandle<viskores::Pair<T1, T2>, viskores::cont::StorageTagZip<ST1, ST2>>>
331  : SerializableTypeString<viskores::cont::ArrayHandleZip<viskores::cont::ArrayHandle<T1, ST1>,
332  viskores::cont::ArrayHandle<T2, ST2>>>
333 {
334 };
335 }
336 } // namespace viskores::cont
337 
338 namespace mangled_diy_namespace
339 {
340 
341 template <typename AH1, typename AH2>
342 struct Serialization<viskores::cont::ArrayHandleZip<AH1, AH2>>
343 {
344 private:
345  using Type = typename viskores::cont::ArrayHandleZip<AH1, AH2>;
347 
348 public:
349  static VISKORES_CONT void save(BinaryBuffer& bb, const BaseType& obj)
350  {
351  auto storage = obj.GetStorage();
352  viskoresdiy::save(bb, storage.GetFirstArray());
353  viskoresdiy::save(bb, storage.GetSecondArray());
354  }
355 
356  static VISKORES_CONT void load(BinaryBuffer& bb, BaseType& obj)
357  {
358  AH1 a1;
359  AH2 a2;
360 
361  viskoresdiy::load(bb, a1);
362  viskoresdiy::load(bb, a2);
363 
365  }
366 };
367 
368 template <typename T1, typename T2, typename ST1, typename ST2>
369 struct Serialization<
370  viskores::cont::ArrayHandle<viskores::Pair<T1, T2>, viskores::cont::StorageTagZip<ST1, ST2>>>
371  : Serialization<viskores::cont::ArrayHandleZip<viskores::cont::ArrayHandle<T1, ST1>,
372  viskores::cont::ArrayHandle<T2, ST2>>>
373 {
374 };
375 
376 } // diy
378 
379 #endif //viskores_cont_ArrayHandleZip_h
viskores::exec::arg::load
T load(const U &u, viskores::Id v)
Definition: FetchTagArrayDirectIn.h:44
viskores::cont::ArrayHandle::StorageType
viskores::cont::internal::Storage< ValueType, StorageTag > StorageType
Definition: ArrayHandle.h:322
viskores::make_Pair
viskores::Pair< typename std::decay< T1 >::type, typename std::decay< T2 >::type > make_Pair(T1 &&v1, T2 &&v2)
Definition: Pair.h:184
ArrayHandle.h
ArrayPortalHelpers.h
viskores::cont::make_ArrayHandleZip
viskores::cont::ArrayHandleZip< FirstHandleType, SecondHandleType > make_ArrayHandleZip(const FirstHandleType &first, const SecondHandleType &second)
A convenience function for creating an ArrayHandleZip.
Definition: ArrayHandleZip.h:300
Pair.h
viskores::cont::StorageTagZip
Definition: ArrayHandleZip.h:117
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::ArrayHandleZip::GetSecondArray
SecondHandleType GetSecondArray() const
Returns the the array for the second part of the zip pair.
Definition: ArrayHandleZip.h:290
VISKORES_SUPPRESS_EXEC_WARNINGS
#define VISKORES_SUPPRESS_EXEC_WARNINGS
Definition: ExportMacros.h:61
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_EXEC_CONT
#define VISKORES_EXEC_CONT
Definition: ExportMacros.h:60
viskores::cont::ArrayHandleZip
ArrayHandleZip is a specialization of ArrayHandle.
Definition: ArrayHandleZip.h:263
mangled_diy_namespace
Definition: Particle.h:373
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::cont::ArrayHandleZip::Superclass
typename viskores::cont::detail::GetTypeInParentheses< void(typename internal::ArrayHandleZipTraits< FirstHandleType, SecondHandleType >::Superclass) >::type Superclass
Definition: ArrayHandleZip.h:278
VISKORES_ASSERT
#define VISKORES_ASSERT(condition)
Definition: Assert.h:51
viskores::cont::ArrayHandleZip::GetFirstArray
FirstHandleType GetFirstArray() const
Returns the the array for the first part of the zip pair.
Definition: ArrayHandleZip.h:288
viskores::Pair
A viskores::Pair is essentially the same as an STL pair object except that the methods (constructors ...
Definition: Pair.h:37
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
viskores::cont::ArrayHandleZip::ArrayHandleZip
ArrayHandleZip(const FirstHandleType &firstArray, const SecondHandleType &secondArray)
Create ArrayHandleZip with two arrays.
Definition: ArrayHandleZip.h:282
viskores::Get
auto Get(const viskores::Tuple< Ts... > &tuple)
Retrieve the object from a viskores::Tuple at the given index.
Definition: Tuple.h:89
viskores::CopyFlag
CopyFlag
Identifier used to specify whether a function should deep copy data.
Definition: Flags.h:25
viskores::cont::Token
A token to hold the scope of an ArrayHandle or other object.
Definition: Token.h:43
viskores::cont::ArrayHandle::GetBuffers
const std::vector< viskores::cont::internal::Buffer > & GetBuffers() const
Returns the internal Buffer structures that hold the data.
Definition: ArrayHandle.h:738