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)
406 template <
typename... ArrayTs>
408 :
public ArrayHandle<typename internal::CompositeVectorTraits<ArrayTs...>::ValueType,
409 typename internal::CompositeVectorTraits<ArrayTs...>::StorageTag>
424 return StorageType::GetArrayTuple(this->
GetBuffers());
430 template <
typename... ArrayTs>
432 const ArrayTs&... arrays)
436 (void)checkArrayHandles;
448 template <
typename T>
449 struct ExtractComponentCompositeVecFunctor
458 template <
typename A0,
typename... As>
463 const As&... arrays)
const
465 if (compositeIndex == 0)
467 return vtkm::cont::internal::ArrayExtractComponentImpl<typename A0::StorageTag>{}(
468 array0, subIndex, allowCopy);
472 return (*
this)(--compositeIndex, subIndex, allowCopy, arrays...);
481 template <
typename... StorageTags>
482 struct ArrayExtractComponentImpl<StorageTagCompositeVec<StorageTags...>>
483 : vtkm::cont::internal::ArrayExtractComponentImplInherit<StorageTags...>
485 template <
typename VecT>
495 return array.GetArrayTuple().Apply(detail::ExtractComponentCompositeVecFunctor<T>{},
496 componentIndex / NUM_SUB_COMPONENTS,
497 componentIndex % NUM_SUB_COMPONENTS,
515 template <
typename... AHs>
516 struct SerializableTypeString<
vtkm::cont::ArrayHandleCompositeVector<AHs...>>
520 static std::string name =
521 "AH_CompositeVector<" + internal::GetVariadicSerializableTypeString(AHs{}...) +
">";
526 template <
typename T,
typename... STs>
527 struct SerializableTypeString<
528 vtkm::cont::ArrayHandle<vtkm::Vec<T, static_cast<vtkm::IdComponent>(sizeof...(STs))>,
529 vtkm::cont::StorageTagCompositeVec<STs...>>>
530 : SerializableTypeString<
531 vtkm::cont::ArrayHandleCompositeVector<vtkm::cont::ArrayHandle<T, STs>...>>
540 template <
typename... AHs>
541 struct Serialization<
vtkm::cont::ArrayHandleCompositeVector<AHs...>>
549 BinaryBuffer& Buffer;
550 SaveFunctor(BinaryBuffer& bb)
555 template <
typename AH>
556 void operator()(
const AH& ah)
const
558 vtkmdiy::save(this->Buffer, ah);
564 BinaryBuffer& Buffer;
565 LoadFunctor(BinaryBuffer& bb)
570 template <
typename AH>
571 void operator()(AH& ah)
const
577 static BaseType Create(
const AHs&... arrays) {
return Type(arrays...); }
580 static VTKM_CONT void save(BinaryBuffer& bb,
const BaseType& obj)
582 Type(obj).GetArrayTuple().ForEach(SaveFunctor{ bb });
588 tuple.ForEach(LoadFunctor{ bb });
589 obj = tuple.Apply(Create);
593 template <
typename T,
typename... STs>
594 struct Serialization<
595 vtkm::cont::ArrayHandle<vtkm::Vec<T, static_cast<vtkm::IdComponent>(sizeof...(STs))>,
596 vtkm::cont::StorageTagCompositeVec<STs...>>>
597 : Serialization<vtkm::cont::ArrayHandleCompositeVector<vtkm::cont::ArrayHandle<T, STs>...>>
603 #endif //vtk_m_ArrayHandleCompositeVector_h