10 #ifndef vtk_m_ArrayHandleCompositeVector_h
11 #define vtk_m_ArrayHandleCompositeVector_h
20 #include <vtkmstd/integer_sequence.h>
23 #include <type_traits>
33 template <
typename... PortalList>
34 using AllPortalsAreWritable =
42 template <
typename ExpectedValueType,
typename ArrayType>
46 "ArrayHandleCompositeVector must be built from "
47 "ArrayHandles with the same ValueTypes.");
50 template <
typename ArrayType0,
typename... ArrayTypes>
55 using ComponentType =
typename ArrayType0::ValueType;
61 template <
typename ArrayType>
62 struct GetValueType<ArrayType>
65 using ComponentType =
typename ArrayType::ValueType;
66 using ValueType =
typename ArrayType::ValueType;
75 const ValueType& value,
76 vtkmstd::integer_sequence<vtkm::IdComponent, I...>,
77 const Portals&... portals)
80 (void)std::initializer_list<bool>{ (portals.Set(index, Traits::GetComponent(value, I)),
85 template <
typename ValueType,
typename... Portals>
97 template <
typename... PortalTypes>
100 using Writable = compvec::AllPortalsAreWritable<PortalTypes...>;
105 using ValueType =
typename compvec::GetValueType<PortalTypes...>::ValueType;
108 ArrayPortalCompositeVector() {}
111 ArrayPortalCompositeVector(
const PortalTypes&... portals)
112 : Portals(portals...)
117 ArrayPortalCompositeVector(
const TupleType& portals)
123 vtkm::Id GetNumberOfValues()
const {
return vtkm::Get<0>(this->Portals).GetNumberOfValues(); }
128 auto getFromPortals = [index](
const auto&... portals) {
129 return ValueType{ portals.Get(index)... };
131 return this->Portals.Apply(getFromPortals);
134 template <
typename Writable_ = Writable,
135 typename =
typename std::enable_if<Writable_::value>::type>
141 auto setToPortal = [index, &value](
const auto&... portals) {
142 compvec::SetToPortals(index, value, portals...);
144 this->Portals.Apply(setToPortal);
161 template <
typename ArrayType>
162 struct VerifyArrayHandle
165 "Template parameters for ArrayHandleCompositeVector "
166 "must be a list of ArrayHandle types.");
173 template <
typename... StorageTags>
181 template <
typename... ArrayTs>
182 struct CompositeVectorTraits
189 using ValueType =
typename vtkm::internal::compvec::GetValueType<ArrayTs...>::ValueType;
194 template <
typename T,
typename... StorageTags>
195 class Storage<
vtkm::
Vec<T, static_cast<vtkm::IdComponent>(sizeof...(StorageTags))>,
202 std::array<std::size_t,
sizeof...(StorageTags) + 1> BufferOffset;
205 template <
typename S>
206 using StorageFor = vtkm::cont::internal::Storage<T, S>;
210 VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> GetBuffers(
211 const std::vector<vtkm::cont::internal::Buffer>& buffers,
212 std::size_t subArray)
214 Info info = buffers[0].GetMetaData<Info>();
215 return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + info.BufferOffset[subArray],
217 info.BufferOffset[subArray + 1]);
220 template <std::
size_t I>
221 VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> Buffers(
222 const std::vector<vtkm::cont::internal::Buffer>& buffers)
224 return GetBuffers(buffers, I);
227 using IndexList = vtkmstd::make_index_sequence<
sizeof...(StorageTags)>;
230 using ReadPortalType =
231 vtkm::internal::ArrayPortalCompositeVector<typename StorageFor<StorageTags>::ReadPortalType...>;
232 using WritePortalType = vtkm::internal::ArrayPortalCompositeVector<
233 typename StorageFor<StorageTags>::WritePortalType...>;
236 template <std::size_t... Is>
237 static void ResizeBuffersImpl(vtkmstd::index_sequence<Is...>,
239 const std::vector<vtkm::cont::internal::Buffer>& buffers,
243 std::vector<std::vector<vtkm::cont::internal::Buffer>> bufferPartitions = { Buffers<Is>(
246 numValues, bufferPartitions[Is], preserve, token),
251 template <std::size_t... Is>
252 static void FillImpl(vtkmstd::index_sequence<Is...>,
253 const std::vector<vtkm::cont::internal::Buffer>& buffers,
254 const ValueType& fillValue,
269 template <std::size_t... Is>
270 static ReadPortalType CreateReadPortalImpl(
271 vtkmstd::index_sequence<Is...>,
272 const std::vector<vtkm::cont::internal::Buffer>& buffers,
277 Buffers<Is>(buffers), device, token)...);
280 template <std::size_t... Is>
281 static WritePortalType CreateWritePortalImpl(
282 vtkmstd::index_sequence<Is...>,
283 const std::vector<vtkm::cont::internal::Buffer>& buffers,
288 Buffers<Is>(buffers), device, token)...);
293 const std::vector<vtkm::cont::internal::Buffer>& buffers)
297 GetBuffers(buffers, 0)) *
298 ValueType::NUM_COMPONENTS;
302 const std::vector<vtkm::cont::internal::Buffer>& buffers)
308 const std::vector<vtkm::cont::internal::Buffer>& buffers,
312 ResizeBuffersImpl(IndexList{}, numValues, buffers, preserve, token);
315 VTKM_CONT static void Fill(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
316 const ValueType& fillValue,
321 FillImpl(IndexList{}, buffers, fillValue, startIndex, endIndex, token);
324 VTKM_CONT static ReadPortalType CreateReadPortal(
325 const std::vector<vtkm::cont::internal::Buffer>& buffers,
329 return CreateReadPortalImpl(IndexList{}, buffers, device, token);
332 VTKM_CONT static WritePortalType CreateWritePortal(
333 const std::vector<vtkm::cont::internal::Buffer>& buffers,
337 return CreateWritePortalImpl(IndexList{}, buffers, device, token);
341 VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
344 auto numBuffers = { std::size_t{ 1 }, arrays.
GetBuffers().size()... };
346 std::partial_sum(numBuffers.begin(), numBuffers.end(), info.BufferOffset.begin());
347 return vtkm::cont::internal::CreateBuffers(info, arrays...);
350 VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
358 template <std::size_t... Is>
359 VTKM_CONT static ArrayTupleType GetArrayTupleImpl(
360 vtkmstd::index_sequence<Is...>,
361 const std::vector<vtkm::cont::internal::Buffer>& buffers)
367 VTKM_CONT static ArrayTupleType GetArrayTuple(
368 const std::vector<vtkm::cont::internal::Buffer>& buffers)
370 return GetArrayTupleImpl(IndexList{}, buffers);
375 template <
typename T,
typename StorageTag>
376 struct Storage<T,
vtkm::cont::StorageTagCompositeVec<StorageTag>> : Storage<T, StorageTag>
378 VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
381 return vtkm::cont::internal::CreateBuffers(array);
385 const std::vector<vtkm::cont::internal::Buffer>& buffers)
409 template <
typename... ArrayTs>
411 :
public ArrayHandle<typename internal::CompositeVectorTraits<ArrayTs...>::ValueType,
412 typename internal::CompositeVectorTraits<ArrayTs...>::StorageTag>
429 return StorageType::GetArrayTuple(this->
GetBuffers());
435 template <
typename... ArrayTs>
437 const ArrayTs&... arrays)
441 (void)checkArrayHandles;
453 template <
typename T>
454 struct ExtractComponentCompositeVecFunctor
463 template <
typename A0,
typename... As>
468 const As&... arrays)
const
470 if (compositeIndex == 0)
472 return vtkm::cont::internal::ArrayExtractComponentImpl<typename A0::StorageTag>{}(
473 array0, subIndex, allowCopy);
477 return (*
this)(--compositeIndex, subIndex, allowCopy, arrays...);
486 template <
typename... StorageTags>
487 struct ArrayExtractComponentImpl<StorageTagCompositeVec<StorageTags...>>
488 : vtkm::cont::internal::ArrayExtractComponentImplInherit<StorageTags...>
490 template <
typename VecT>
500 return array.GetArrayTuple().Apply(detail::ExtractComponentCompositeVecFunctor<T>{},
501 componentIndex / NUM_SUB_COMPONENTS,
502 componentIndex % NUM_SUB_COMPONENTS,
520 template <
typename... AHs>
521 struct SerializableTypeString<
vtkm::cont::ArrayHandleCompositeVector<AHs...>>
525 static std::string name =
526 "AH_CompositeVector<" + internal::GetVariadicSerializableTypeString(AHs{}...) +
">";
531 template <
typename T,
typename... STs>
532 struct SerializableTypeString<
533 vtkm::cont::ArrayHandle<vtkm::Vec<T, static_cast<vtkm::IdComponent>(sizeof...(STs))>,
534 vtkm::cont::StorageTagCompositeVec<STs...>>>
535 : SerializableTypeString<
536 vtkm::cont::ArrayHandleCompositeVector<vtkm::cont::ArrayHandle<T, STs>...>>
545 template <
typename... AHs>
546 struct Serialization<
vtkm::cont::ArrayHandleCompositeVector<AHs...>>
554 BinaryBuffer& Buffer;
555 SaveFunctor(BinaryBuffer& bb)
560 template <
typename AH>
561 void operator()(
const AH& ah)
const
563 vtkmdiy::save(this->Buffer, ah);
569 BinaryBuffer& Buffer;
570 LoadFunctor(BinaryBuffer& bb)
575 template <
typename AH>
576 void operator()(AH& ah)
const
582 static BaseType Create(
const AHs&... arrays) {
return Type(arrays...); }
585 static VTKM_CONT void save(BinaryBuffer& bb,
const BaseType& obj)
587 Type(obj).GetArrayTuple().ForEach(SaveFunctor{ bb });
593 tuple.ForEach(LoadFunctor{ bb });
594 obj = tuple.Apply(Create);
598 template <
typename T,
typename... STs>
599 struct Serialization<
600 vtkm::cont::ArrayHandle<vtkm::Vec<T, static_cast<vtkm::IdComponent>(sizeof...(STs))>,
601 vtkm::cont::StorageTagCompositeVec<STs...>>>
602 : Serialization<vtkm::cont::ArrayHandleCompositeVector<vtkm::cont::ArrayHandle<T, STs>...>>
608 #endif //vtk_m_ArrayHandleCompositeVector_h