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;
73 template <
typename... Portals>
74 VTKM_EXEC_CONT typename GetValueType<Portals...>::ValueType GetFromPortals(
76 const Portals&... portals)
78 return { portals.Get(index)... };
87 const ValueType& value,
88 vtkmstd::integer_sequence<vtkm::IdComponent, I...>,
89 const Portals&... portals)
92 (void)std::initializer_list<bool>{ (portals.Set(index, Traits::GetComponent(value, I)),
97 template <
typename ValueType,
typename... Portals>
109 template <
typename... PortalTypes>
112 using Writable = compvec::AllPortalsAreWritable<PortalTypes...>;
117 using ValueType =
typename compvec::GetValueType<PortalTypes...>::ValueType;
120 ArrayPortalCompositeVector() {}
123 ArrayPortalCompositeVector(
const PortalTypes&... portals)
124 : Portals(portals...)
129 ArrayPortalCompositeVector(
const TupleType& portals)
135 vtkm::Id GetNumberOfValues()
const {
return vtkm::Get<0>(this->Portals).GetNumberOfValues(); }
140 return this->Portals.Apply(compvec::GetFromPortals<PortalTypes...>, index);
143 template <
typename Writable_ = Writable,
144 typename =
typename std::enable_if<Writable_::value>::type>
147 this->Portals.Apply(compvec::SetToPortals<ValueType, PortalTypes...>, index, value);
164 template <
typename ArrayType>
165 struct VerifyArrayHandle
168 "Template parameters for ArrayHandleCompositeVector "
169 "must be a list of ArrayHandle types.");
176 template <
typename... StorageTags>
184 template <
typename... ArrayTs>
185 struct CompositeVectorTraits
192 using ValueType =
typename vtkm::internal::compvec::GetValueType<ArrayTs...>::ValueType;
194 using StorageType = Storage<ValueType, StorageTag>;
198 template <
typename T,
typename... StorageTags>
199 class Storage<
vtkm::
Vec<T, static_cast<vtkm::IdComponent>(sizeof...(StorageTags))>,
206 std::array<std::size_t,
sizeof...(StorageTags) + 1> BufferOffset;
209 template <
typename S>
210 using StorageFor = vtkm::cont::internal::Storage<T, S>;
214 VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> GetBuffers(
215 const std::vector<vtkm::cont::internal::Buffer>& buffers,
216 std::size_t subArray)
218 Info info = buffers[0].GetMetaData<Info>();
219 return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + info.BufferOffset[subArray],
221 info.BufferOffset[subArray + 1]);
224 template <std::
size_t I>
225 VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> Buffers(
226 const std::vector<vtkm::cont::internal::Buffer>& buffers)
228 return GetBuffers(buffers, I);
231 using IndexList = vtkmstd::make_index_sequence<
sizeof...(StorageTags)>;
234 using ReadPortalType =
235 vtkm::internal::ArrayPortalCompositeVector<typename StorageFor<StorageTags>::ReadPortalType...>;
236 using WritePortalType = vtkm::internal::ArrayPortalCompositeVector<
237 typename StorageFor<StorageTags>::WritePortalType...>;
240 template <std::size_t... Is>
241 static void ResizeBuffersImpl(vtkmstd::index_sequence<Is...>,
243 const std::vector<vtkm::cont::internal::Buffer>& buffers,
247 std::vector<std::vector<vtkm::cont::internal::Buffer>> bufferPartitions = { Buffers<Is>(
250 numValues, bufferPartitions[Is], preserve, token),
255 template <std::size_t... Is>
256 static void FillImpl(vtkmstd::index_sequence<Is...>,
257 const std::vector<vtkm::cont::internal::Buffer>& buffers,
258 const ValueType& fillValue,
273 template <std::size_t... Is>
274 static ReadPortalType CreateReadPortalImpl(
275 vtkmstd::index_sequence<Is...>,
276 const std::vector<vtkm::cont::internal::Buffer>& buffers,
281 Buffers<Is>(buffers), device, token)...);
284 template <std::size_t... Is>
285 static WritePortalType CreateWritePortalImpl(
286 vtkmstd::index_sequence<Is...>,
287 const std::vector<vtkm::cont::internal::Buffer>& buffers,
292 Buffers<Is>(buffers), device, token)...);
297 const std::vector<vtkm::cont::internal::Buffer>& buffers)
303 const std::vector<vtkm::cont::internal::Buffer>& buffers,
307 ResizeBuffersImpl(IndexList{}, numValues, buffers, preserve, token);
310 VTKM_CONT static void Fill(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
311 const ValueType& fillValue,
316 FillImpl(IndexList{}, buffers, fillValue, startIndex, endIndex, token);
319 VTKM_CONT static ReadPortalType CreateReadPortal(
320 const std::vector<vtkm::cont::internal::Buffer>& buffers,
324 return CreateReadPortalImpl(IndexList{}, buffers, device, token);
327 VTKM_CONT static WritePortalType CreateWritePortal(
328 const std::vector<vtkm::cont::internal::Buffer>& buffers,
332 return CreateWritePortalImpl(IndexList{}, buffers, device, token);
336 VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
339 auto numBuffers = { std::size_t{ 1 }, arrays.
GetBuffers().size()... };
341 std::partial_sum(numBuffers.begin(), numBuffers.end(), info.BufferOffset.begin());
342 return vtkm::cont::internal::CreateBuffers(info, arrays...);
345 VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
353 template <std::size_t... Is>
354 VTKM_CONT static ArrayTupleType GetArrayTupleImpl(
355 vtkmstd::index_sequence<Is...>,
356 const std::vector<vtkm::cont::internal::Buffer>& buffers)
362 VTKM_CONT static ArrayTupleType GetArrayTuple(
363 const std::vector<vtkm::cont::internal::Buffer>& buffers)
365 return GetArrayTupleImpl(IndexList{}, buffers);
370 template <
typename T,
typename StorageTag>
371 struct Storage<T,
vtkm::cont::StorageTagCompositeVec<StorageTag>> : Storage<T, StorageTag>
373 VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
376 return vtkm::cont::internal::CreateBuffers(array);
380 const std::vector<vtkm::cont::internal::Buffer>& buffers)
401 template <
typename... ArrayTs>
403 :
public ArrayHandle<typename internal::CompositeVectorTraits<ArrayTs...>::ValueType,
404 typename internal::CompositeVectorTraits<ArrayTs...>::StorageTag>
407 using Traits = internal::CompositeVectorTraits<ArrayTs...>;
417 : Superclass(
StorageType::CreateBuffers(arrays...))
423 return StorageType::GetArrayTuple(this->
GetBuffers());
429 template <
typename... ArrayTs>
431 const ArrayTs&... arrays)
435 (void)checkArrayHandles;
447 template <
typename T>
448 struct ExtractComponentCompositeVecFunctor
457 template <
typename A0,
typename... As>
462 const As&... arrays)
const
464 if (compositeIndex == 0)
466 return vtkm::cont::internal::ArrayExtractComponentImpl<typename A0::StorageTag>{}(
467 array0, subIndex, allowCopy);
471 return (*
this)(--compositeIndex, subIndex, allowCopy, arrays...);
480 template <
typename... StorageTags>
481 struct ArrayExtractComponentImpl<StorageTagCompositeVec<StorageTags...>>
482 : vtkm::cont::internal::ArrayExtractComponentImplInherit<StorageTags...>
484 template <
typename VecT>
494 return array.GetArrayTuple().Apply(detail::ExtractComponentCompositeVecFunctor<T>{},
495 componentIndex / NUM_SUB_COMPONENTS,
496 componentIndex % NUM_SUB_COMPONENTS,
514 template <
typename... AHs>
515 struct SerializableTypeString<
vtkm::cont::ArrayHandleCompositeVector<AHs...>>
519 static std::string name =
520 "AH_CompositeVector<" + internal::GetVariadicSerializableTypeString(AHs{}...) +
">";
525 template <
typename T,
typename... STs>
526 struct SerializableTypeString<
527 vtkm::cont::ArrayHandle<vtkm::Vec<T, static_cast<vtkm::IdComponent>(sizeof...(STs))>,
528 vtkm::cont::StorageTagCompositeVec<STs...>>>
529 : SerializableTypeString<
530 vtkm::cont::ArrayHandleCompositeVector<vtkm::cont::ArrayHandle<T, STs>...>>
539 template <
typename... AHs>
540 struct Serialization<
vtkm::cont::ArrayHandleCompositeVector<AHs...>>
548 BinaryBuffer& Buffer;
549 SaveFunctor(BinaryBuffer& bb)
554 template <
typename AH>
555 void operator()(
const AH& ah)
const
557 vtkmdiy::save(this->Buffer, ah);
563 BinaryBuffer& Buffer;
564 LoadFunctor(BinaryBuffer& bb)
569 template <
typename AH>
570 void operator()(AH& ah)
const
576 static BaseType Create(
const AHs&... arrays) {
return Type(arrays...); }
579 static VTKM_CONT void save(BinaryBuffer& bb,
const BaseType& obj)
581 Type(obj).GetArrayTuple().ForEach(SaveFunctor{ bb });
587 tuple.ForEach(LoadFunctor{ bb });
588 obj = tuple.Apply(Create);
592 template <
typename T,
typename... STs>
593 struct Serialization<
594 vtkm::cont::ArrayHandle<vtkm::Vec<T, static_cast<vtkm::IdComponent>(sizeof...(STs))>,
595 vtkm::cont::StorageTagCompositeVec<STs...>>>
596 : Serialization<vtkm::cont::ArrayHandleCompositeVector<vtkm::cont::ArrayHandle<T, STs>...>>
602 #endif //vtk_m_ArrayHandleCompositeVector_h