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,
355 const SecondHandleType& secondArray,
356 const ThirdHandleType& thirdArray)
370 return StorageType::GetArrayHandle1(this->
GetBuffers());
374 return StorageType::GetArrayHandle2(this->
GetBuffers());
378 return StorageType::GetArrayHandle3(this->
GetBuffers());
385 template <
typename FirstHandleType,
typename SecondHandleType,
typename ThirdHandleType>
389 const SecondHandleType& second,
390 const ThirdHandleType& third)
393 first, second, third);
403 template <
typename... STs>
405 : vtkm::cont::internal::ArrayExtractComponentImplInherit<STs...>
407 template <
typename T>
420 modulo = dims[component];
437 template <
typename T,
typename ST,
typename CartesianArrayType>
440 const CartesianArrayType& cartesianArray,
446 ArrayExtractComponentImpl<ST>{}(componentArray, subIndex, allowCopy);
452 return vtkm::cont::internal::ArrayExtractComponentFallback(
453 cartesianArray, (productIndex * NUM_SUB_COMPONENTS) + subIndex, allowCopy);
456 vtkm::Id3 dims = { cartesianArray.GetFirstArray().GetNumberOfValues(),
457 cartesianArray.GetSecondArray().GetNumberOfValues(),
458 cartesianArray.GetThirdArray().GetNumberOfValues() };
460 return this->AdjustStrideForComponent(
461 strideArray, dims, productIndex, cartesianArray.GetNumberOfValues());
464 template <
typename T>
476 switch (productIndex)
479 return this->GetStrideForComponentArray(
480 array.GetFirstArray(), array, subIndex, productIndex, allowCopy);
482 return this->GetStrideForComponentArray(
483 array.GetSecondArray(), array, subIndex, productIndex, allowCopy);
485 return this->GetStrideForComponentArray(
486 array.GetThirdArray(), array, subIndex, productIndex, allowCopy);
493 template <
typename T,
typename S>
497 bool computeFiniteRange,
500 template <
typename S>
501 struct ArrayRangeComputeImpl;
503 template <
typename ST1,
typename ST2,
typename ST3>
504 struct VTKM_CONT_EXPORT ArrayRangeComputeImpl<
vtkm::cont::StorageTagCartesianProduct<ST1, ST2, ST3>>
506 template <
typename T>
511 bool computeFiniteRange,
516 return vtkm::cont::internal::ArrayRangeComputeGeneric(
517 input_, maskArray, computeFiniteRange, device);
527 ranges[0] = vtkm::cont::internal::ArrayRangeComputeImpl<ST1>{}(
528 input.GetFirstArray(), maskArray, computeFiniteRange, device);
529 ranges[1] = vtkm::cont::internal::ArrayRangeComputeImpl<ST2>{}(
530 input.GetSecondArray(), maskArray, computeFiniteRange, device);
531 ranges[2] = vtkm::cont::internal::ArrayRangeComputeImpl<ST3>{}(
532 input.GetThirdArray(), maskArray, computeFiniteRange, device);
539 for (
vtkm::Id i = 0, index = 0; i < 3; ++i)
542 for (
vtkm::Id j = 0; j < rangePortal.GetNumberOfValues(); ++j, ++index)
544 resultPortal.Set(index, rangePortal.Get(j));
564 template <
typename AH1,
typename AH2,
typename AH3>
565 struct SerializableTypeString<
vtkm::cont::ArrayHandleCartesianProduct<AH1, AH2, AH3>>
575 template <
typename T,
typename ST1,
typename ST2,
typename ST3>
576 struct SerializableTypeString<
577 vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, vtkm::cont::StorageTagCartesianProduct<ST1, ST2, ST3>>>
578 : SerializableTypeString<vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<T, ST1>,
579 vtkm::cont::ArrayHandle<T, ST2>,
580 vtkm::cont::ArrayHandle<T, ST3>>>
589 template <
typename AH1,
typename AH2,
typename AH3>
590 struct Serialization<
vtkm::cont::ArrayHandleCartesianProduct<AH1, AH2, AH3>>
597 static VTKM_CONT void save(BinaryBuffer& bb,
const BaseType& obj)
600 vtkmdiy::save(bb, array.GetFirstArray());
601 vtkmdiy::save(bb, array.GetSecondArray());
602 vtkmdiy::save(bb, array.GetThirdArray());
619 template <
typename T,
typename ST1,
typename ST2,
typename ST3>
620 struct Serialization<
621 vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, vtkm::cont::StorageTagCartesianProduct<ST1, ST2, ST3>>>
622 : Serialization<vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<T, ST1>,
623 vtkm::cont::ArrayHandle<T, ST2>,
624 vtkm::cont::ArrayHandle<T, ST3>>>
630 #endif //vtk_m_cont_ArrayHandleCartesianProduct_h