18 #ifndef viskores_ArrayHandleCompositeVector_h
19 #define viskores_ArrayHandleCompositeVector_h
28 #include <viskoresstd/integer_sequence.h>
31 #include <type_traits>
41 template <
typename... PortalList>
42 using AllPortalsAreWritable =
50 template <
typename ExpectedValueType,
typename ArrayType>
54 (std::is_same<ExpectedValueType, typename ArrayType::ValueType>::value),
55 "ArrayHandleCompositeVector must be built from "
56 "ArrayHandles with the same ValueTypes.");
59 template <
typename ArrayType0,
typename... ArrayTypes>
64 using ComponentType =
typename ArrayType0::ValueType;
70 template <
typename ArrayType>
71 struct GetValueType<ArrayType>
74 using ComponentType =
typename ArrayType::ValueType;
75 using ValueType =
typename ArrayType::ValueType;
84 const ValueType& value,
85 viskoresstd::integer_sequence<viskores::IdComponent, I...>,
86 const Portals&... portals)
89 (void)std::initializer_list<bool>{ (portals.Set(index, Traits::GetComponent(value, I)),
94 template <
typename ValueType,
typename... Portals>
96 const ValueType& value,
97 const Portals&... portals)
99 SetToPortalsImpl(index,
108 template <
typename... PortalTypes>
109 class VISKORES_ALWAYS_EXPORT ArrayPortalCompositeVector
111 using Writable = compvec::AllPortalsAreWritable<PortalTypes...>;
116 using ValueType =
typename compvec::GetValueType<PortalTypes...>::ValueType;
119 ArrayPortalCompositeVector() {}
122 ArrayPortalCompositeVector(
const PortalTypes&... portals)
123 : Portals(portals...)
128 ArrayPortalCompositeVector(
const TupleType& portals)
136 return viskores::Get<0>(this->Portals).GetNumberOfValues();
142 auto getFromPortals = [index](
const auto&... portals)
143 {
return ValueType{ portals.Get(index)... }; };
144 return this->Portals.Apply(getFromPortals);
147 template <
typename Writable_ = Writable,
148 typename =
typename std::enable_if<Writable_::value>::type>
154 auto setToPortal = [index, &value](
const auto&... portals)
155 { compvec::SetToPortals(index, value, portals...); };
156 this->Portals.Apply(setToPortal);
173 template <
typename ArrayType>
174 struct VerifyArrayHandle
177 "Template parameters for ArrayHandleCompositeVector "
178 "must be a list of ArrayHandle types.");
185 template <
typename... StorageTags>
193 template <
typename... ArrayTs>
194 struct CompositeVectorTraits
201 using ValueType =
typename viskores::internal::compvec::GetValueType<ArrayTs...>::ValueType;
206 template <
typename T,
typename... StorageTags>
207 class Storage<
viskores::
Vec<T, static_cast<viskores::IdComponent>(sizeof...(StorageTags))>,
214 std::array<std::size_t,
sizeof...(StorageTags) + 1> BufferOffset;
217 template <
typename S>
218 using StorageFor = viskores::cont::internal::Storage<T, S>;
222 VISKORES_CONT static std::vector<viskores::cont::internal::Buffer> GetBuffers(
223 const std::vector<viskores::cont::internal::Buffer>& buffers,
224 std::size_t subArray)
226 Info info = buffers[0].GetMetaData<Info>();
227 return std::vector<viskores::cont::internal::Buffer>(
228 buffers.begin() + info.BufferOffset[subArray],
229 buffers.begin() + info.BufferOffset[subArray + 1]);
232 template <std::
size_t I>
233 VISKORES_CONT static std::vector<viskores::cont::internal::Buffer> Buffers(
234 const std::vector<viskores::cont::internal::Buffer>& buffers)
236 return GetBuffers(buffers, I);
239 using IndexList = viskoresstd::make_index_sequence<
sizeof...(StorageTags)>;
242 using ReadPortalType = viskores::internal::ArrayPortalCompositeVector<
243 typename StorageFor<StorageTags>::ReadPortalType...>;
244 using WritePortalType = viskores::internal::ArrayPortalCompositeVector<
245 typename StorageFor<StorageTags>::WritePortalType...>;
248 template <std::size_t... Is>
249 static void ResizeBuffersImpl(viskoresstd::index_sequence<Is...>,
251 const std::vector<viskores::cont::internal::Buffer>& buffers,
255 std::vector<std::vector<viskores::cont::internal::Buffer>> bufferPartitions = { Buffers<Is>(
258 numValues, bufferPartitions[Is], preserve, token),
263 template <std::size_t... Is>
264 static void FillImpl(viskoresstd::index_sequence<Is...>,
265 const std::vector<viskores::cont::internal::Buffer>& buffers,
266 const ValueType& fillValue,
272 Buffers<Is>(buffers),
281 template <std::size_t... Is>
282 static ReadPortalType CreateReadPortalImpl(
283 viskoresstd::index_sequence<Is...>,
284 const std::vector<viskores::cont::internal::Buffer>& buffers,
289 Buffers<Is>(buffers), device, token)...);
292 template <std::size_t... Is>
293 static WritePortalType CreateWritePortalImpl(
294 viskoresstd::index_sequence<Is...>,
295 const std::vector<viskores::cont::internal::Buffer>& buffers,
300 Buffers<Is>(buffers), device, token)...);
305 const std::vector<viskores::cont::internal::Buffer>& buffers)
309 GetBuffers(buffers, 0)) *
310 ValueType::NUM_COMPONENTS;
314 const std::vector<viskores::cont::internal::Buffer>& buffers)
321 const std::vector<viskores::cont::internal::Buffer>& buffers,
325 ResizeBuffersImpl(IndexList{}, numValues, buffers, preserve, token);
328 VISKORES_CONT static void Fill(
const std::vector<viskores::cont::internal::Buffer>& buffers,
329 const ValueType& fillValue,
334 FillImpl(IndexList{}, buffers, fillValue, startIndex, endIndex, token);
338 const std::vector<viskores::cont::internal::Buffer>& buffers,
342 return CreateReadPortalImpl(IndexList{}, buffers, device, token);
346 const std::vector<viskores::cont::internal::Buffer>& buffers,
350 return CreateWritePortalImpl(IndexList{}, buffers, device, token);
354 VISKORES_CONT static std::vector<viskores::cont::internal::Buffer> CreateBuffers(
357 auto numBuffers = { std::size_t{ 1 }, arrays.
GetBuffers().size()... };
359 std::partial_sum(numBuffers.begin(), numBuffers.end(), info.BufferOffset.begin());
360 return viskores::cont::internal::CreateBuffers(info, arrays...);
363 VISKORES_CONT static std::vector<viskores::cont::internal::Buffer> CreateBuffers()
371 template <std::size_t... Is>
373 viskoresstd::index_sequence<Is...>,
374 const std::vector<viskores::cont::internal::Buffer>& buffers)
381 const std::vector<viskores::cont::internal::Buffer>& buffers)
383 return GetArrayTupleImpl(IndexList{}, buffers);
388 template <
typename T,
typename StorageTag>
389 struct Storage<T,
viskores::cont::StorageTagCompositeVec<StorageTag>> : Storage<T, StorageTag>
391 VISKORES_CONT static std::vector<viskores::cont::internal::Buffer> CreateBuffers(
395 return viskores::cont::internal::CreateBuffers(array);
399 const std::vector<viskores::cont::internal::Buffer>& buffers)
423 template <
typename... ArrayTs>
425 :
public ArrayHandle<typename internal::CompositeVectorTraits<ArrayTs...>::ValueType,
426 typename internal::CompositeVectorTraits<ArrayTs...>::StorageTag>
444 return StorageType::GetArrayTuple(this->
GetBuffers());
450 template <
typename... ArrayTs>
452 const ArrayTs&... arrays)
456 (void)checkArrayHandles;
468 template <
typename T>
469 struct ExtractComponentCompositeVecFunctor
479 template <
typename A0,
typename... As>
484 const As&... arrays)
const
486 if (compositeIndex == 0)
488 return viskores::cont::internal::ArrayExtractComponentImpl<typename A0::StorageTag>{}(
489 array0, subIndex, allowCopy);
493 return (*
this)(--compositeIndex, subIndex, allowCopy, arrays...);
502 template <
typename... StorageTags>
503 struct ArrayExtractComponentImpl<StorageTagCompositeVec<StorageTags...>>
504 : viskores::cont::internal::ArrayExtractComponentImplInherit<StorageTags...>
506 template <
typename VecT>
518 return array.GetArrayTuple().Apply(detail::ExtractComponentCompositeVecFunctor<T>{},
519 componentIndex / NUM_SUB_COMPONENTS,
520 componentIndex % NUM_SUB_COMPONENTS,
538 template <
typename... AHs>
539 struct SerializableTypeString<
viskores::cont::ArrayHandleCompositeVector<AHs...>>
543 static std::string name =
544 "AH_CompositeVector<" + internal::GetVariadicSerializableTypeString(AHs{}...) +
">";
549 template <
typename T,
typename... STs>
550 struct SerializableTypeString<
551 viskores::cont::ArrayHandle<viskores::Vec<T, static_cast<viskores::IdComponent>(sizeof...(STs))>,
552 viskores::cont::StorageTagCompositeVec<STs...>>>
553 : SerializableTypeString<
554 viskores::cont::ArrayHandleCompositeVector<viskores::cont::ArrayHandle<T, STs>...>>
563 template <
typename... AHs>
564 struct Serialization<
viskores::cont::ArrayHandleCompositeVector<AHs...>>
572 BinaryBuffer& Buffer;
573 SaveFunctor(BinaryBuffer& bb)
578 template <
typename AH>
579 void operator()(
const AH& ah)
const
581 viskoresdiy::save(this->Buffer, ah);
587 BinaryBuffer& Buffer;
588 LoadFunctor(BinaryBuffer& bb)
593 template <
typename AH>
594 void operator()(AH& ah)
const
600 static BaseType Create(
const AHs&... arrays) {
return Type(arrays...); }
603 static VISKORES_CONT void save(BinaryBuffer& bb,
const BaseType& obj)
605 Type(obj).GetArrayTuple().ForEach(SaveFunctor{ bb });
611 tuple.ForEach(LoadFunctor{ bb });
612 obj = tuple.Apply(Create);
616 template <
typename T,
typename... STs>
617 struct Serialization<
618 viskores::cont::ArrayHandle<viskores::Vec<T, static_cast<viskores::IdComponent>(sizeof...(STs))>,
619 viskores::cont::StorageTagCompositeVec<STs...>>>
621 viskores::cont::ArrayHandleCompositeVector<viskores::cont::ArrayHandle<T, STs>...>>
627 #endif //viskores_ArrayHandleCompositeVector_h