10 #ifndef vtk_m_cont_ArrayHandleCartesianProduct_h
11 #define vtk_m_cont_ArrayHandleCartesianProduct_h
31 template <
typename ValueType_,
32 typename PortalTypeFirst_,
33 typename PortalTypeSecond_,
34 typename PortalTypeThird_>
38 using ValueType = ValueType_;
39 using IteratorType = ValueType_;
40 using PortalTypeFirst = PortalTypeFirst_;
41 using PortalTypeSecond = PortalTypeSecond_;
42 using PortalTypeThird = PortalTypeThird_;
44 using set_supported_p1 = vtkm::internal::PortalSupportsSets<PortalTypeFirst>;
45 using set_supported_p2 = vtkm::internal::PortalSupportsSets<PortalTypeSecond>;
46 using set_supported_p3 = vtkm::internal::PortalSupportsSets<PortalTypeThird>;
48 using Writable = std::integral_constant<bool,
49 set_supported_p1::value && set_supported_p2::value &&
50 set_supported_p3::value>;
54 ArrayPortalCartesianProduct()
62 ArrayPortalCartesianProduct(
const PortalTypeFirst& portalfirst,
63 const PortalTypeSecond& portalsecond,
64 const PortalTypeThird& portalthird)
65 : PortalFirst(portalfirst)
66 , PortalSecond(portalsecond)
67 , PortalThird(portalthird)
76 template <
class OtherV,
class OtherP1,
class OtherP2,
class OtherP3>
78 const ArrayPortalCartesianProduct<OtherV, OtherP1, OtherP2, OtherP3>& src)
79 : PortalFirst(src.GetPortalFirst())
80 , PortalSecond(src.GetPortalSecond())
81 , PortalThird(src.GetPortalThird())
89 return this->PortalFirst.GetNumberOfValues() * this->PortalSecond.GetNumberOfValues() *
90 this->PortalThird.GetNumberOfValues();
100 vtkm::Id dim1 = this->PortalFirst.GetNumberOfValues();
101 vtkm::Id dim2 = this->PortalSecond.GetNumberOfValues();
109 this->PortalFirst.Get(i1), this->PortalSecond.Get(i2), this->PortalThird.Get(i3));
114 template <
typename Writable_ = Writable,
115 typename =
typename std::enable_if<Writable_::value>::type>
121 vtkm::Id dim1 = this->PortalFirst.GetNumberOfValues();
122 vtkm::Id dim2 = this->PortalSecond.GetNumberOfValues();
130 this->PortalFirst.Set(i1, value[0]);
131 this->PortalSecond.Set(i2, value[1]);
132 this->PortalThird.Set(i3, value[2]);
137 const PortalTypeFirst& GetFirstPortal()
const {
return this->PortalFirst; }
141 const PortalTypeSecond& GetSecondPortal()
const {
return this->PortalSecond; }
145 const PortalTypeThird& GetThirdPortal()
const {
return this->PortalThird; }
148 PortalTypeFirst PortalFirst;
149 PortalTypeSecond PortalSecond;
150 PortalTypeThird PortalThird;
160 template <
typename StorageTag1,
typename StorageTag2,
typename StorageTag3>
171 template <
typename AH1,
typename AH2,
typename AH3>
172 struct ArrayHandleCartesianProductTraits
178 using ComponentType =
typename AH1::ValueType;
180 (std::is_same<ComponentType, typename AH2::ValueType>::value),
181 "All arrays for ArrayHandleCartesianProduct must have the same value type. "
182 "Use ArrayHandleCast as necessary to make types match.");
184 (std::is_same<ComponentType, typename AH3::ValueType>::value),
185 "All arrays for ArrayHandleCartesianProduct must have the same value type. "
186 "Use ArrayHandleCast as necessary to make types match.");
195 typename AH2::StorageTag,
196 typename AH3::StorageTag>;
203 template <
typename T,
typename ST1,
typename ST2,
typename ST3>
208 std::array<std::size_t, 4> BufferOffset;
211 using Storage1 = vtkm::cont::internal::Storage<T, ST1>;
212 using Storage2 = vtkm::cont::internal::Storage<T, ST2>;
213 using Storage3 = vtkm::cont::internal::Storage<T, ST3>;
219 VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> GetBuffers(
220 const std::vector<vtkm::cont::internal::Buffer>& buffers,
221 std::size_t subArray)
223 Info info = buffers[0].GetMetaData<Info>();
224 return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() +
225 info.BufferOffset[subArray - 1],
226 buffers.begin() + info.BufferOffset[subArray]);
232 using ReadPortalType =
233 vtkm::internal::ArrayPortalCartesianProduct<vtkm::Vec<T, 3>,
234 typename Storage1::ReadPortalType,
235 typename Storage2::ReadPortalType,
236 typename Storage3::ReadPortalType>;
237 using WritePortalType =
238 vtkm::internal::ArrayPortalCartesianProduct<vtkm::Vec<T, 3>,
239 typename Storage1::WritePortalType,
240 typename Storage2::WritePortalType,
241 typename Storage3::WritePortalType>;
244 const std::vector<vtkm::cont::internal::Buffer>&)
250 const std::vector<vtkm::cont::internal::Buffer>& buffers)
252 return (Storage1::GetNumberOfValues(GetBuffers(buffers, 1)) *
253 Storage2::GetNumberOfValues(GetBuffers(buffers, 2)) *
254 Storage3::GetNumberOfValues(GetBuffers(buffers, 3)));
257 VTKM_CONT static void Fill(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
263 if ((startIndex != 0) || (endIndex != GetNumberOfValues(buffers)))
266 "Fill for ArrayHandleCartesianProduct can only be used to fill entire array.");
268 auto subBuffers = GetBuffers(buffers, 1);
269 Storage1::Fill(subBuffers, fillValue[0], 0, Storage1::GetNumberOfValues(subBuffers), token);
270 subBuffers = GetBuffers(buffers, 2);
271 Storage2::Fill(subBuffers, fillValue[1], 0, Storage2::GetNumberOfValues(subBuffers), token);
272 subBuffers = GetBuffers(buffers, 3);
273 Storage3::Fill(subBuffers, fillValue[2], 0, Storage3::GetNumberOfValues(subBuffers), token);
276 VTKM_CONT static ReadPortalType CreateReadPortal(
277 const std::vector<vtkm::cont::internal::Buffer>& buffers,
281 return ReadPortalType(Storage1::CreateReadPortal(GetBuffers(buffers, 1), device, token),
282 Storage2::CreateReadPortal(GetBuffers(buffers, 2), device, token),
283 Storage3::CreateReadPortal(GetBuffers(buffers, 3), device, token));
286 VTKM_CONT static WritePortalType CreateWritePortal(
287 const std::vector<vtkm::cont::internal::Buffer>& buffers,
291 return WritePortalType(Storage1::CreateWritePortal(GetBuffers(buffers, 1), device, token),
292 Storage2::CreateWritePortal(GetBuffers(buffers, 2), device, token),
293 Storage3::CreateWritePortal(GetBuffers(buffers, 3), device, token));
296 VTKM_CONT static Array1 GetArrayHandle1(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
298 return Array1(GetBuffers(buffers, 1));
300 VTKM_CONT static Array2 GetArrayHandle2(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
302 return Array2(GetBuffers(buffers, 2));
304 VTKM_CONT static Array3 GetArrayHandle3(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
306 return Array3(GetBuffers(buffers, 3));
309 VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
310 const Array1& array1 = Array1{},
311 const Array2& array2 = Array2{},
312 const Array3& array3 = Array3{})
314 const std::vector<vtkm::cont::internal::Buffer>& buffers1 = array1.GetBuffers();
315 const std::vector<vtkm::cont::internal::Buffer>& buffers2 = array2.GetBuffers();
316 const std::vector<vtkm::cont::internal::Buffer>& buffers3 = array3.GetBuffers();
319 info.BufferOffset[0] = 1;
320 info.BufferOffset[1] = info.BufferOffset[0] + buffers1.size();
321 info.BufferOffset[2] = info.BufferOffset[1] + buffers2.size();
322 info.BufferOffset[3] = info.BufferOffset[2] + buffers3.size();
324 return vtkm::cont::internal::CreateBuffers(info, buffers1, buffers2, buffers3);
333 template <
typename FirstHandleType,
typename SecondHandleType,
typename ThirdHandleType>
335 :
public internal::ArrayHandleCartesianProductTraits<FirstHandleType,
349 (
typename internal::ArrayHandleCartesianProductTraits<FirstHandleType,
357 const SecondHandleType& secondArray,
358 const ThirdHandleType& thirdArray)
373 return StorageType::GetArrayHandle1(this->
GetBuffers());
378 return StorageType::GetArrayHandle2(this->
GetBuffers());
383 return StorageType::GetArrayHandle3(this->
GetBuffers());
390 template <
typename FirstHandleType,
typename SecondHandleType,
typename ThirdHandleType>
394 const SecondHandleType& second,
395 const ThirdHandleType& third)
398 first, second, third);
408 template <
typename... STs>
410 : vtkm::cont::internal::ArrayExtractComponentImplInherit<STs...>
412 template <
typename T>
425 modulo = dims[component];
442 template <
typename T,
typename ST,
typename CartesianArrayType>
445 const CartesianArrayType& cartesianArray,
451 ArrayExtractComponentImpl<ST>{}(componentArray, subIndex, allowCopy);
457 return vtkm::cont::internal::ArrayExtractComponentFallback(
458 cartesianArray, (productIndex * NUM_SUB_COMPONENTS) + subIndex, allowCopy);
461 vtkm::Id3 dims = { cartesianArray.GetFirstArray().GetNumberOfValues(),
462 cartesianArray.GetSecondArray().GetNumberOfValues(),
463 cartesianArray.GetThirdArray().GetNumberOfValues() };
465 return this->AdjustStrideForComponent(
466 strideArray, dims, productIndex, cartesianArray.GetNumberOfValues());
469 template <
typename T>
481 switch (productIndex)
484 return this->GetStrideForComponentArray(
485 array.GetFirstArray(), array, subIndex, productIndex, allowCopy);
487 return this->GetStrideForComponentArray(
488 array.GetSecondArray(), array, subIndex, productIndex, allowCopy);
490 return this->GetStrideForComponentArray(
491 array.GetThirdArray(), array, subIndex, productIndex, allowCopy);
498 template <
typename T,
typename S>
502 bool computeFiniteRange,
505 template <
typename S>
506 struct ArrayRangeComputeImpl;
508 template <
typename ST1,
typename ST2,
typename ST3>
509 struct VTKM_CONT_EXPORT ArrayRangeComputeImpl<
vtkm::cont::StorageTagCartesianProduct<ST1, ST2, ST3>>
511 template <
typename T>
516 bool computeFiniteRange,
521 return vtkm::cont::internal::ArrayRangeComputeGeneric(
522 input_, maskArray, computeFiniteRange, device);
532 ranges[0] = vtkm::cont::internal::ArrayRangeComputeImpl<ST1>{}(
533 input.GetFirstArray(), maskArray, computeFiniteRange, device);
534 ranges[1] = vtkm::cont::internal::ArrayRangeComputeImpl<ST2>{}(
535 input.GetSecondArray(), maskArray, computeFiniteRange, device);
536 ranges[2] = vtkm::cont::internal::ArrayRangeComputeImpl<ST3>{}(
537 input.GetThirdArray(), maskArray, computeFiniteRange, device);
544 for (
vtkm::Id i = 0, index = 0; i < 3; ++i)
547 for (
vtkm::Id j = 0; j < rangePortal.GetNumberOfValues(); ++j, ++index)
549 resultPortal.Set(index, rangePortal.Get(j));
569 template <
typename AH1,
typename AH2,
typename AH3>
570 struct SerializableTypeString<
vtkm::cont::ArrayHandleCartesianProduct<AH1, AH2, AH3>>
580 template <
typename T,
typename ST1,
typename ST2,
typename ST3>
581 struct SerializableTypeString<
582 vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, vtkm::cont::StorageTagCartesianProduct<ST1, ST2, ST3>>>
583 : SerializableTypeString<vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<T, ST1>,
584 vtkm::cont::ArrayHandle<T, ST2>,
585 vtkm::cont::ArrayHandle<T, ST3>>>
594 template <
typename AH1,
typename AH2,
typename AH3>
595 struct Serialization<
vtkm::cont::ArrayHandleCartesianProduct<AH1, AH2, AH3>>
602 static VTKM_CONT void save(BinaryBuffer& bb,
const BaseType& obj)
605 vtkmdiy::save(bb, array.GetFirstArray());
606 vtkmdiy::save(bb, array.GetSecondArray());
607 vtkmdiy::save(bb, array.GetThirdArray());
624 template <
typename T,
typename ST1,
typename ST2,
typename ST3>
625 struct Serialization<
626 vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, vtkm::cont::StorageTagCartesianProduct<ST1, ST2, ST3>>>
627 : Serialization<vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<T, ST1>,
628 vtkm::cont::ArrayHandle<T, ST2>,
629 vtkm::cont::ArrayHandle<T, ST3>>>
635 #endif //vtk_m_cont_ArrayHandleCartesianProduct_h