10 #ifndef vtk_m_cont_ArrayHandleCartesianProduct_h
11 #define vtk_m_cont_ArrayHandleCartesianProduct_h
29 template <
typename ValueType_,
30 typename PortalTypeFirst_,
31 typename PortalTypeSecond_,
32 typename PortalTypeThird_>
36 using ValueType = ValueType_;
37 using IteratorType = ValueType_;
38 using PortalTypeFirst = PortalTypeFirst_;
39 using PortalTypeSecond = PortalTypeSecond_;
40 using PortalTypeThird = PortalTypeThird_;
42 using set_supported_p1 = vtkm::internal::PortalSupportsSets<PortalTypeFirst>;
43 using set_supported_p2 = vtkm::internal::PortalSupportsSets<PortalTypeSecond>;
44 using set_supported_p3 = vtkm::internal::PortalSupportsSets<PortalTypeThird>;
46 using Writable = std::integral_constant<bool,
47 set_supported_p1::value && set_supported_p2::value &&
48 set_supported_p3::value>;
52 ArrayPortalCartesianProduct()
60 ArrayPortalCartesianProduct(
const PortalTypeFirst& portalfirst,
61 const PortalTypeSecond& portalsecond,
62 const PortalTypeThird& portalthird)
63 : PortalFirst(portalfirst)
64 , PortalSecond(portalsecond)
65 , PortalThird(portalthird)
74 template <
class OtherV,
class OtherP1,
class OtherP2,
class OtherP3>
76 const ArrayPortalCartesianProduct<OtherV, OtherP1, OtherP2, OtherP3>& src)
77 : PortalFirst(src.GetPortalFirst())
78 , PortalSecond(src.GetPortalSecond())
79 , PortalThird(src.GetPortalThird())
87 return this->PortalFirst.GetNumberOfValues() * this->PortalSecond.GetNumberOfValues() *
88 this->PortalThird.GetNumberOfValues();
98 vtkm::Id dim1 = this->PortalFirst.GetNumberOfValues();
99 vtkm::Id dim2 = this->PortalSecond.GetNumberOfValues();
107 this->PortalFirst.Get(i1), this->PortalSecond.Get(i2), this->PortalThird.Get(i3));
112 template <
typename Writable_ = Writable,
113 typename =
typename std::enable_if<Writable_::value>::type>
119 vtkm::Id dim1 = this->PortalFirst.GetNumberOfValues();
120 vtkm::Id dim2 = this->PortalSecond.GetNumberOfValues();
128 this->PortalFirst.Set(i1, value[0]);
129 this->PortalSecond.Set(i2, value[1]);
130 this->PortalThird.Set(i3, value[2]);
135 const PortalTypeFirst& GetFirstPortal()
const {
return this->PortalFirst; }
139 const PortalTypeSecond& GetSecondPortal()
const {
return this->PortalSecond; }
143 const PortalTypeThird& GetThirdPortal()
const {
return this->PortalThird; }
146 PortalTypeFirst PortalFirst;
147 PortalTypeSecond PortalSecond;
148 PortalTypeThird PortalThird;
158 template <
typename StorageTag1,
typename StorageTag2,
typename StorageTag3>
169 template <
typename AH1,
typename AH2,
typename AH3>
170 struct ArrayHandleCartesianProductTraits
176 using ComponentType =
typename AH1::ValueType;
178 (std::is_same<ComponentType, typename AH2::ValueType>::value),
179 "All arrays for ArrayHandleCartesianProduct must have the same value type. "
180 "Use ArrayHandleCast as necessary to make types match.");
182 (std::is_same<ComponentType, typename AH3::ValueType>::value),
183 "All arrays for ArrayHandleCartesianProduct must have the same value type. "
184 "Use ArrayHandleCast as necessary to make types match.");
193 typename AH2::StorageTag,
194 typename AH3::StorageTag>;
201 template <
typename T,
typename ST1,
typename ST2,
typename ST3>
206 std::array<std::size_t, 4> BufferOffset;
209 using Storage1 = vtkm::cont::internal::Storage<T, ST1>;
210 using Storage2 = vtkm::cont::internal::Storage<T, ST2>;
211 using Storage3 = vtkm::cont::internal::Storage<T, ST3>;
217 VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> GetBuffers(
218 const std::vector<vtkm::cont::internal::Buffer>& buffers,
219 std::size_t subArray)
221 Info info = buffers[0].GetMetaData<Info>();
222 return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() +
223 info.BufferOffset[subArray - 1],
224 buffers.begin() + info.BufferOffset[subArray]);
230 using ReadPortalType =
231 vtkm::internal::ArrayPortalCartesianProduct<vtkm::Vec<T, 3>,
232 typename Storage1::ReadPortalType,
233 typename Storage2::ReadPortalType,
234 typename Storage3::ReadPortalType>;
235 using WritePortalType =
236 vtkm::internal::ArrayPortalCartesianProduct<vtkm::Vec<T, 3>,
237 typename Storage1::WritePortalType,
238 typename Storage2::WritePortalType,
239 typename Storage3::WritePortalType>;
242 const std::vector<vtkm::cont::internal::Buffer>& buffers)
244 return (Storage1::GetNumberOfValues(GetBuffers(buffers, 1)) *
245 Storage2::GetNumberOfValues(GetBuffers(buffers, 2)) *
246 Storage3::GetNumberOfValues(GetBuffers(buffers, 3)));
249 VTKM_CONT static void Fill(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
255 if ((startIndex != 0) || (endIndex != GetNumberOfValues(buffers)))
258 "Fill for ArrayHandleCartesianProduct can only be used to fill entire array.");
260 auto subBuffers = GetBuffers(buffers, 1);
261 Storage1::Fill(subBuffers, fillValue[0], 0, Storage1::GetNumberOfValues(subBuffers), token);
262 subBuffers = GetBuffers(buffers, 2);
263 Storage2::Fill(subBuffers, fillValue[1], 0, Storage2::GetNumberOfValues(subBuffers), token);
264 subBuffers = GetBuffers(buffers, 3);
265 Storage3::Fill(subBuffers, fillValue[2], 0, Storage3::GetNumberOfValues(subBuffers), token);
268 VTKM_CONT static ReadPortalType CreateReadPortal(
269 const std::vector<vtkm::cont::internal::Buffer>& buffers,
273 return ReadPortalType(Storage1::CreateReadPortal(GetBuffers(buffers, 1), device, token),
274 Storage2::CreateReadPortal(GetBuffers(buffers, 2), device, token),
275 Storage3::CreateReadPortal(GetBuffers(buffers, 3), device, token));
278 VTKM_CONT static WritePortalType CreateWritePortal(
279 const std::vector<vtkm::cont::internal::Buffer>& buffers,
283 return WritePortalType(Storage1::CreateWritePortal(GetBuffers(buffers, 1), device, token),
284 Storage2::CreateWritePortal(GetBuffers(buffers, 2), device, token),
285 Storage3::CreateWritePortal(GetBuffers(buffers, 3), device, token));
288 VTKM_CONT static Array1 GetArrayHandle1(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
290 return Array1(GetBuffers(buffers, 1));
292 VTKM_CONT static Array2 GetArrayHandle2(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
294 return Array2(GetBuffers(buffers, 2));
296 VTKM_CONT static Array3 GetArrayHandle3(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
298 return Array3(GetBuffers(buffers, 3));
301 VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
302 const Array1& array1 = Array1{},
303 const Array2& array2 = Array2{},
304 const Array3& array3 = Array3{})
306 const std::vector<vtkm::cont::internal::Buffer>& buffers1 = array1.GetBuffers();
307 const std::vector<vtkm::cont::internal::Buffer>& buffers2 = array2.GetBuffers();
308 const std::vector<vtkm::cont::internal::Buffer>& buffers3 = array3.GetBuffers();
311 info.BufferOffset[0] = 1;
312 info.BufferOffset[1] = info.BufferOffset[0] + buffers1.size();
313 info.BufferOffset[2] = info.BufferOffset[1] + buffers2.size();
314 info.BufferOffset[3] = info.BufferOffset[2] + buffers3.size();
316 return vtkm::cont::internal::CreateBuffers(info, buffers1, buffers2, buffers3);
325 template <
typename FirstHandleType,
typename SecondHandleType,
typename ThirdHandleType>
327 :
public internal::ArrayHandleCartesianProductTraits<FirstHandleType,
329 ThirdHandleType>::Superclass
341 (
typename internal::ArrayHandleCartesianProductTraits<FirstHandleType,
343 ThirdHandleType>::Superclass));
346 using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
351 const SecondHandleType& secondArray,
352 const ThirdHandleType& thirdArray)
353 : Superclass(
StorageType::CreateBuffers(firstArray, secondArray, thirdArray))
366 return StorageType::GetArrayHandle1(this->
GetBuffers());
370 return StorageType::GetArrayHandle2(this->
GetBuffers());
374 return StorageType::GetArrayHandle3(this->
GetBuffers());
381 template <
typename FirstHandleType,
typename SecondHandleType,
typename ThirdHandleType>
385 const SecondHandleType& second,
386 const ThirdHandleType& third)
389 first, second, third);
399 template <
typename... STs>
401 : vtkm::cont::internal::ArrayExtractComponentImplInherit<STs...>
403 template <
typename T>
416 modulo = dims[component];
433 template <
typename T,
typename ST,
typename CartesianArrayType>
436 const CartesianArrayType& cartesianArray,
442 ArrayExtractComponentImpl<ST>{}(componentArray, subIndex, allowCopy);
448 return vtkm::cont::internal::ArrayExtractComponentFallback(
449 cartesianArray, (productIndex * NUM_SUB_COMPONENTS) + subIndex, allowCopy);
452 vtkm::Id3 dims = { cartesianArray.GetFirstArray().GetNumberOfValues(),
453 cartesianArray.GetSecondArray().GetNumberOfValues(),
454 cartesianArray.GetThirdArray().GetNumberOfValues() };
456 return this->AdjustStrideForComponent(
457 strideArray, dims, productIndex, cartesianArray.GetNumberOfValues());
460 template <
typename T>
472 switch (productIndex)
475 return this->GetStrideForComponentArray(
476 array.GetFirstArray(), array, subIndex, productIndex, allowCopy);
478 return this->GetStrideForComponentArray(
479 array.GetSecondArray(), array, subIndex, productIndex, allowCopy);
481 return this->GetStrideForComponentArray(
482 array.GetThirdArray(), array, subIndex, productIndex, allowCopy);
502 template <
typename AH1,
typename AH2,
typename AH3>
503 struct SerializableTypeString<
vtkm::cont::ArrayHandleCartesianProduct<AH1, AH2, AH3>>
513 template <
typename T,
typename ST1,
typename ST2,
typename ST3>
514 struct SerializableTypeString<
515 vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, vtkm::cont::StorageTagCartesianProduct<ST1, ST2, ST3>>>
516 : SerializableTypeString<vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<T, ST1>,
517 vtkm::cont::ArrayHandle<T, ST2>,
518 vtkm::cont::ArrayHandle<T, ST3>>>
527 template <
typename AH1,
typename AH2,
typename AH3>
528 struct Serialization<
vtkm::cont::ArrayHandleCartesianProduct<AH1, AH2, AH3>>
535 static VTKM_CONT void save(BinaryBuffer& bb,
const BaseType& obj)
538 vtkmdiy::save(bb, array.GetFirstArray());
539 vtkmdiy::save(bb, array.GetSecondArray());
540 vtkmdiy::save(bb, array.GetThirdArray());
557 template <
typename T,
typename ST1,
typename ST2,
typename ST3>
558 struct Serialization<
559 vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, vtkm::cont::StorageTagCartesianProduct<ST1, ST2, ST3>>>
560 : Serialization<vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<T, ST1>,
561 vtkm::cont::ArrayHandle<T, ST2>,
562 vtkm::cont::ArrayHandle<T, ST3>>>
568 #endif //vtk_m_cont_ArrayHandleCartesianProduct_h