Viskores  1.0
ArrayHandleCompositeVector.h
Go to the documentation of this file.
1 //============================================================================
2 // The contents of this file are covered by the Viskores license. See
3 // LICENSE.txt for details.
4 //
5 // By contributing to this file, all contributors agree to the Developer
6 // Certificate of Origin Version 1.1 (DCO 1.1) as stated in DCO.txt.
7 //============================================================================
8 
9 //============================================================================
10 // Copyright (c) Kitware, Inc.
11 // All rights reserved.
12 // See LICENSE.txt for details.
13 //
14 // This software is distributed WITHOUT ANY WARRANTY; without even
15 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 // PURPOSE. See the above copyright notice for more information.
17 //============================================================================
18 #ifndef viskores_ArrayHandleCompositeVector_h
19 #define viskores_ArrayHandleCompositeVector_h
20 
23 
24 #include <viskores/StaticAssert.h>
25 #include <viskores/Tuple.h>
26 #include <viskores/VecTraits.h>
27 
28 #include <viskoresstd/integer_sequence.h>
29 
30 #include <numeric>
31 #include <type_traits>
32 
33 namespace viskores
34 {
35 namespace internal
36 {
37 
38 namespace compvec
39 {
40 
41 template <typename... PortalList>
42 using AllPortalsAreWritable =
43  viskores::ListAll<viskores::List<PortalList...>, viskores::internal::PortalSupportsSets>;
44 
45 // GetValueType: ---------------------------------------------------------------
46 // Determines the output `ValueType` of the set of `ArrayHandle` objects. For example, if the input
47 // set contains 3 types with `viskores::Float32` ValueTypes, then the ValueType defined here will be
48 // `viskores::Vec<Float32, 3>`. This also validates that all members have the same `ValueType`.
49 
50 template <typename ExpectedValueType, typename ArrayType>
51 struct CheckValueType
52 {
54  (std::is_same<ExpectedValueType, typename ArrayType::ValueType>::value),
55  "ArrayHandleCompositeVector must be built from "
56  "ArrayHandles with the same ValueTypes.");
57 };
58 
59 template <typename ArrayType0, typename... ArrayTypes>
60 struct GetValueType
61 {
62  static constexpr viskores::IdComponent COUNT =
63  static_cast<viskores::IdComponent>(sizeof...(ArrayTypes)) + 1;
64  using ComponentType = typename ArrayType0::ValueType;
66  using ValueType = viskores::Vec<ComponentType, COUNT>;
67 };
68 
69 // Special case for only one component
70 template <typename ArrayType>
71 struct GetValueType<ArrayType>
72 {
73  static constexpr viskores::IdComponent COUNT = 1;
74  using ComponentType = typename ArrayType::ValueType;
75  using ValueType = typename ArrayType::ValueType;
76 };
77 
78 // SetToPortals: ---------------------------------------------------------------
79 // Given a Vec-like object, and index, and a set of array portals, sets each of
80 // the portals to the respective component of the Vec.
82 template <typename ValueType, viskores::IdComponent... I, typename... Portals>
83 VISKORES_EXEC_CONT void SetToPortalsImpl(viskores::Id index,
84  const ValueType& value,
85  viskoresstd::integer_sequence<viskores::IdComponent, I...>,
86  const Portals&... portals)
87 {
88  using Traits = viskores::VecTraits<ValueType>;
89  (void)std::initializer_list<bool>{ (portals.Set(index, Traits::GetComponent(value, I)),
90  false)... };
91 }
92 
94 template <typename ValueType, typename... Portals>
95 VISKORES_EXEC_CONT void SetToPortals(viskores::Id index,
96  const ValueType& value,
97  const Portals&... portals)
98 {
99  SetToPortalsImpl(index,
100  value,
101  viskoresstd::make_integer_sequence<viskores::IdComponent,
102  viskores::IdComponent(sizeof...(Portals))>{},
103  portals...);
104 }
105 
106 } // namespace compvec
107 
108 template <typename... PortalTypes>
109 class VISKORES_ALWAYS_EXPORT ArrayPortalCompositeVector
110 {
111  using Writable = compvec::AllPortalsAreWritable<PortalTypes...>;
112  using TupleType = viskores::Tuple<PortalTypes...>;
113  TupleType Portals;
114 
115 public:
116  using ValueType = typename compvec::GetValueType<PortalTypes...>::ValueType;
117 
119  ArrayPortalCompositeVector() {}
120 
122  ArrayPortalCompositeVector(const PortalTypes&... portals)
123  : Portals(portals...)
124  {
125  }
126 
128  ArrayPortalCompositeVector(const TupleType& portals)
129  : Portals(portals)
130  {
131  }
132 
134  viskores::Id GetNumberOfValues() const
135  {
136  return viskores::Get<0>(this->Portals).GetNumberOfValues();
137  }
138 
140  ValueType Get(viskores::Id index) const
141  {
142  auto getFromPortals = [index](const auto&... portals)
143  { return ValueType{ portals.Get(index)... }; };
144  return this->Portals.Apply(getFromPortals);
145  }
146 
147  template <typename Writable_ = Writable,
148  typename = typename std::enable_if<Writable_::value>::type>
149  VISKORES_EXEC_CONT void Set(viskores::Id index, const ValueType& value) const
150  {
151  // Note that we are using a lambda function here to implicitly construct a
152  // functor to pass to Apply. Some device compilers will not allow passing a
153  // function or function pointer to Tuple::Apply.
154  auto setToPortal = [index, &value](const auto&... portals)
155  { compvec::SetToPortals(index, value, portals...); };
156  this->Portals.Apply(setToPortal);
157  }
158 };
159 
160 }
161 } // viskores::internal
162 
163 namespace viskores
164 {
165 namespace cont
166 {
167 namespace internal
168 {
169 
170 namespace compvec
171 {
172 
173 template <typename ArrayType>
174 struct VerifyArrayHandle
175 {
176  VISKORES_STATIC_ASSERT_MSG(viskores::cont::internal::ArrayHandleCheck<ArrayType>::type::value,
177  "Template parameters for ArrayHandleCompositeVector "
178  "must be a list of ArrayHandle types.");
179 };
180 
181 } // end namespace compvec
182 
183 } // namespace internal
184 
185 template <typename... StorageTags>
186 struct VISKORES_ALWAYS_EXPORT StorageTagCompositeVec
187 {
188 };
189 
190 namespace internal
191 {
192 
193 template <typename... ArrayTs>
194 struct CompositeVectorTraits
195 {
196  // Need to check this here, since this traits struct is used in the
197  // ArrayHandleCompositeVector superclass definition before any other
198  // static_asserts could be used.
199  using CheckArrayHandles = viskores::List<compvec::VerifyArrayHandle<ArrayTs>...>;
200 
201  using ValueType = typename viskores::internal::compvec::GetValueType<ArrayTs...>::ValueType;
202  using StorageTag = viskores::cont::StorageTagCompositeVec<typename ArrayTs::StorageTag...>;
203  using Superclass = ArrayHandle<ValueType, StorageTag>;
204 };
205 
206 template <typename T, typename... StorageTags>
207 class Storage<viskores::Vec<T, static_cast<viskores::IdComponent>(sizeof...(StorageTags))>,
209 {
210  using ValueType = viskores::Vec<T, static_cast<viskores::IdComponent>(sizeof...(StorageTags))>;
211 
212  struct Info
213  {
214  std::array<std::size_t, sizeof...(StorageTags) + 1> BufferOffset;
215  };
216 
217  template <typename S>
218  using StorageFor = viskores::cont::internal::Storage<T, S>;
219 
220  using StorageTuple = viskores::Tuple<StorageFor<StorageTags>...>;
221 
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)
225  {
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]);
230  }
231 
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)
235  {
236  return GetBuffers(buffers, I);
237  }
238 
239  using IndexList = viskoresstd::make_index_sequence<sizeof...(StorageTags)>;
240 
241 public:
242  using ReadPortalType = viskores::internal::ArrayPortalCompositeVector<
243  typename StorageFor<StorageTags>::ReadPortalType...>;
244  using WritePortalType = viskores::internal::ArrayPortalCompositeVector<
245  typename StorageFor<StorageTags>::WritePortalType...>;
246 
247 private:
248  template <std::size_t... Is>
249  static void ResizeBuffersImpl(viskoresstd::index_sequence<Is...>,
250  viskores::Id numValues,
251  const std::vector<viskores::cont::internal::Buffer>& buffers,
252  viskores::CopyFlag preserve,
253  viskores::cont::Token& token)
254  {
255  std::vector<std::vector<viskores::cont::internal::Buffer>> bufferPartitions = { Buffers<Is>(
256  buffers)... };
258  numValues, bufferPartitions[Is], preserve, token),
259  false)... };
260  (void)init_list;
261  }
262 
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,
267  viskores::Id startIndex,
268  viskores::Id endIndex,
269  viskores::cont::Token& token)
270  {
272  Buffers<Is>(buffers),
273  fillValue[static_cast<viskores::IdComponent>(Is)],
274  startIndex,
275  endIndex,
276  token),
277  false)... };
278  (void)init_list;
279  }
280 
281  template <std::size_t... Is>
282  static ReadPortalType CreateReadPortalImpl(
283  viskoresstd::index_sequence<Is...>,
284  const std::vector<viskores::cont::internal::Buffer>& buffers,
286  viskores::cont::Token& token)
287  {
289  Buffers<Is>(buffers), device, token)...);
290  }
291 
292  template <std::size_t... Is>
293  static WritePortalType CreateWritePortalImpl(
294  viskoresstd::index_sequence<Is...>,
295  const std::vector<viskores::cont::internal::Buffer>& buffers,
297  viskores::cont::Token& token)
298  {
300  Buffers<Is>(buffers), device, token)...);
301  }
302 
303 public:
304  VISKORES_CONT static viskores::IdComponent GetNumberOfComponentsFlat(
305  const std::vector<viskores::cont::internal::Buffer>& buffers)
306  {
307  // Assume that all subcomponents are the same size. Things are not well defined otherwise.
309  GetBuffers(buffers, 0)) *
310  ValueType::NUM_COMPONENTS;
311  }
312 
313  VISKORES_CONT static viskores::Id GetNumberOfValues(
314  const std::vector<viskores::cont::internal::Buffer>& buffers)
315  {
317  }
318 
319  VISKORES_CONT static void ResizeBuffers(
320  viskores::Id numValues,
321  const std::vector<viskores::cont::internal::Buffer>& buffers,
322  viskores::CopyFlag preserve,
323  viskores::cont::Token& token)
324  {
325  ResizeBuffersImpl(IndexList{}, numValues, buffers, preserve, token);
326  }
327 
328  VISKORES_CONT static void Fill(const std::vector<viskores::cont::internal::Buffer>& buffers,
329  const ValueType& fillValue,
330  viskores::Id startIndex,
331  viskores::Id endIndex,
332  viskores::cont::Token& token)
333  {
334  FillImpl(IndexList{}, buffers, fillValue, startIndex, endIndex, token);
335  }
336 
337  VISKORES_CONT static ReadPortalType CreateReadPortal(
338  const std::vector<viskores::cont::internal::Buffer>& buffers,
340  viskores::cont::Token& token)
341  {
342  return CreateReadPortalImpl(IndexList{}, buffers, device, token);
343  }
344 
345  VISKORES_CONT static WritePortalType CreateWritePortal(
346  const std::vector<viskores::cont::internal::Buffer>& buffers,
348  viskores::cont::Token& token)
349  {
350  return CreateWritePortalImpl(IndexList{}, buffers, device, token);
351  }
352 
353 public:
354  VISKORES_CONT static std::vector<viskores::cont::internal::Buffer> CreateBuffers(
356  {
357  auto numBuffers = { std::size_t{ 1 }, arrays.GetBuffers().size()... };
358  Info info;
359  std::partial_sum(numBuffers.begin(), numBuffers.end(), info.BufferOffset.begin());
360  return viskores::cont::internal::CreateBuffers(info, arrays...);
361  }
362 
363  VISKORES_CONT static std::vector<viskores::cont::internal::Buffer> CreateBuffers()
364  {
365  return CreateBuffers(viskores::cont::ArrayHandle<T, StorageTags>{}...);
366  }
367 
368 private:
370 
371  template <std::size_t... Is>
372  VISKORES_CONT static ArrayTupleType GetArrayTupleImpl(
373  viskoresstd::index_sequence<Is...>,
374  const std::vector<viskores::cont::internal::Buffer>& buffers)
375  {
376  return ArrayTupleType(viskores::cont::ArrayHandle<T, StorageTags>(Buffers<Is>(buffers))...);
377  }
378 
379 public:
380  VISKORES_CONT static ArrayTupleType GetArrayTuple(
381  const std::vector<viskores::cont::internal::Buffer>& buffers)
382  {
383  return GetArrayTupleImpl(IndexList{}, buffers);
384  }
385 };
386 
387 // Special degenerative case when there is only one array being composited
388 template <typename T, typename StorageTag>
389 struct Storage<T, viskores::cont::StorageTagCompositeVec<StorageTag>> : Storage<T, StorageTag>
390 {
391  VISKORES_CONT static std::vector<viskores::cont::internal::Buffer> CreateBuffers(
394  {
395  return viskores::cont::internal::CreateBuffers(array);
396  }
397 
399  const std::vector<viskores::cont::internal::Buffer>& buffers)
400  {
402  }
403 };
404 
405 } // namespace internal
406 
423 template <typename... ArrayTs>
425  : public ArrayHandle<typename internal::CompositeVectorTraits<ArrayTs...>::ValueType,
426  typename internal::CompositeVectorTraits<ArrayTs...>::StorageTag>
427 {
428 public:
433 
436  ArrayHandleCompositeVector(const ArrayTs&... arrays)
437  : Superclass(StorageType::CreateBuffers(arrays...))
438  {
439  }
440 
443  {
444  return StorageType::GetArrayTuple(this->GetBuffers());
445  }
446 };
447 
450 template <typename... ArrayTs>
452  const ArrayTs&... arrays)
453 {
454  // Will issue compiler error if any of ArrayTs is not a valid ArrayHandle.
456  (void)checkArrayHandles;
457  return ArrayHandleCompositeVector<ArrayTs...>(arrays...);
458 }
459 
460 //--------------------------------------------------------------------------------
461 // Specialization of ArrayExtractComponent
462 namespace internal
463 {
464 
465 namespace detail
466 {
467 
468 template <typename T>
469 struct ExtractComponentCompositeVecFunctor
470 {
471  using ResultArray =
473 
474  ResultArray operator()(viskores::IdComponent, viskores::IdComponent, viskores::CopyFlag) const
475  {
476  throw viskores::cont::ErrorBadValue("Invalid component index given to ArrayExtractComponent.");
477  }
478 
479  template <typename A0, typename... As>
480  ResultArray operator()(viskores::IdComponent compositeIndex,
481  viskores::IdComponent subIndex,
482  viskores::CopyFlag allowCopy,
483  const A0& array0,
484  const As&... arrays) const
485  {
486  if (compositeIndex == 0)
487  {
488  return viskores::cont::internal::ArrayExtractComponentImpl<typename A0::StorageTag>{}(
489  array0, subIndex, allowCopy);
490  }
491  else
492  {
493  return (*this)(--compositeIndex, subIndex, allowCopy, arrays...);
494  }
495  }
496 };
497 
498 } // namespace detail
499 
500 // Superclass will inherit the ArrayExtractComponentImplInefficient property if any
501 // of the sub-storage are inefficient (thus making everything inefficient).
502 template <typename... StorageTags>
503 struct ArrayExtractComponentImpl<StorageTagCompositeVec<StorageTags...>>
504  : viskores::cont::internal::ArrayExtractComponentImplInherit<StorageTags...>
505 {
506  template <typename VecT>
507  auto operator()(
509  src,
510  viskores::IdComponent componentIndex,
511  viskores::CopyFlag allowCopy) const
512  {
513  using T = typename viskores::VecTraits<VecT>::ComponentType;
515  array(src);
516  constexpr viskores::IdComponent NUM_SUB_COMPONENTS = viskores::VecFlat<T>::NUM_COMPONENTS;
517 
518  return array.GetArrayTuple().Apply(detail::ExtractComponentCompositeVecFunctor<T>{},
519  componentIndex / NUM_SUB_COMPONENTS,
520  componentIndex % NUM_SUB_COMPONENTS,
521  allowCopy);
522  }
523 };
524 
525 } // namespace internal
526 
527 }
528 } // namespace viskores::cont
529 
530 //=============================================================================
531 // Specializations of serialization related classes
533 namespace viskores
534 {
535 namespace cont
536 {
537 
538 template <typename... AHs>
539 struct SerializableTypeString<viskores::cont::ArrayHandleCompositeVector<AHs...>>
540 {
541  static VISKORES_CONT const std::string& Get()
542  {
543  static std::string name =
544  "AH_CompositeVector<" + internal::GetVariadicSerializableTypeString(AHs{}...) + ">";
545  return name;
546  }
547 };
548 
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>...>>
555 {
556 };
557 }
558 } // viskores::cont
559 
560 namespace mangled_diy_namespace
561 {
562 
563 template <typename... AHs>
564 struct Serialization<viskores::cont::ArrayHandleCompositeVector<AHs...>>
565 {
566 private:
567  using Type = typename viskores::cont::ArrayHandleCompositeVector<AHs...>;
569 
570  struct SaveFunctor
571  {
572  BinaryBuffer& Buffer;
573  SaveFunctor(BinaryBuffer& bb)
574  : Buffer(bb)
575  {
576  }
577 
578  template <typename AH>
579  void operator()(const AH& ah) const
580  {
581  viskoresdiy::save(this->Buffer, ah);
582  }
583  };
584 
585  struct LoadFunctor
586  {
587  BinaryBuffer& Buffer;
588  LoadFunctor(BinaryBuffer& bb)
589  : Buffer(bb)
590  {
591  }
592 
593  template <typename AH>
594  void operator()(AH& ah) const
595  {
596  viskoresdiy::load(this->Buffer, ah);
597  }
598  };
599 
600  static BaseType Create(const AHs&... arrays) { return Type(arrays...); }
601 
602 public:
603  static VISKORES_CONT void save(BinaryBuffer& bb, const BaseType& obj)
604  {
605  Type(obj).GetArrayTuple().ForEach(SaveFunctor{ bb });
606  }
607 
608  static VISKORES_CONT void load(BinaryBuffer& bb, BaseType& obj)
609  {
610  viskores::Tuple<AHs...> tuple;
611  tuple.ForEach(LoadFunctor{ bb });
612  obj = tuple.Apply(Create);
613  }
614 };
615 
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...>>>
620  : Serialization<
621  viskores::cont::ArrayHandleCompositeVector<viskores::cont::ArrayHandle<T, STs>...>>
622 {
623 };
624 } // diy
626 
627 #endif //viskores_ArrayHandleCompositeVector_h
viskores::exec::arg::load
T load(const U &u, viskores::Id v)
Definition: FetchTagArrayDirectIn.h:44
viskores::VecFlat
Treat a Vec or Vec-like object as a flat Vec.
Definition: VecFlat.h:240
ArrayHandle.h
ArrayExtractComponent.h
viskores::tuple_element_t
typename tuple_element< Index, TupleType >::type tuple_element_t
Compatible with std::tuple_element_t for viskores::Tuple.
Definition: Tuple.h:84
viskores::TupleElement
typename detail::TupleElementImpl< Index, TupleType >::type TupleElement
Becomes the type of the given index for the given viskores::Tuple.
Definition: Tuple.h:71
VISKORES_SUPPRESS_EXEC_WARNINGS
#define VISKORES_SUPPRESS_EXEC_WARNINGS
Definition: ExportMacros.h:61
viskores::cont::ArrayHandle
Manages an array-worth of data.
Definition: ArrayHandle.h:313
viskores::cont::ArrayHandleCompositeVector
An ArrayHandle that combines components from other arrays.
Definition: ArrayHandleCompositeVector.h:424
viskores::cont::StorageTagCompositeVec
Definition: ArrayHandleCompositeVector.h:186
viskores::cont::LogLevel::Info
@ Info
Information messages (detected hardware, etc) and temporary debugging output.
viskores::IdComponent
viskores::Int32 IdComponent
Base type to use to index small lists.
Definition: Types.h:202
VISKORES_EXEC_CONT
#define VISKORES_EXEC_CONT
Definition: ExportMacros.h:60
mangled_diy_namespace
Definition: Particle.h:373
viskores::cont::ArrayHandleStride
An ArrayHandle that accesses a basic array with strides and offsets.
Definition: ArrayHandleStride.h:343
viskores::List
A template used to hold a list of types.
Definition: List.h:47
viskores::Id
viskores::Int64 Id
Base type to use to index arrays.
Definition: Types.h:235
VISKORES_CONT
#define VISKORES_CONT
Definition: ExportMacros.h:65
viskores
Groups connected points that have the same field value.
Definition: Atomic.h:27
viskores::ListAll
viskores::ListReduce< viskores::ListTransform< List, Predicate >, viskores::internal::meta::And, std::true_type > ListAll
Determines whether all the types in the list are "true.".
Definition: List.h:865
viskores::VecTraits
Traits that can be queried to treat any type as a Vec.
Definition: VecTraits.h:69
viskores::cont::make_ArrayHandleCompositeVector
ArrayHandleCompositeVector< ArrayTs... > make_ArrayHandleCompositeVector(const ArrayTs &... arrays)
Create a composite vector array from other arrays.
Definition: ArrayHandleCompositeVector.h:451
VISKORES_STATIC_ASSERT_MSG
#define VISKORES_STATIC_ASSERT_MSG(condition, message)
Definition: StaticAssert.h:26
viskores::cont::DeviceAdapterId
An object used to specify a device.
Definition: DeviceAdapterTag.h:66
viskores::cont::ErrorBadValue
This class is thrown when a Viskores function or method encounters an invalid value that inhibits pro...
Definition: ErrorBadValue.h:33
StaticAssert.h
VISKORES_ARRAY_HANDLE_SUBCLASS
#define VISKORES_ARRAY_HANDLE_SUBCLASS(classname, fullclasstype, superclass)
Macro to make default methods in ArrayHandle subclasses.
Definition: ArrayHandle.h:256
viskores::VecTraits::ComponentType
T ComponentType
Type of the components in the vector.
Definition: VecTraits.h:79
viskores::cont::ArrayHandleCompositeVector::GetArrayTuple
viskores::Tuple< ArrayTs... > GetArrayTuple() const
Return the arrays of all of the components in a viskores::Tuple object.
Definition: ArrayHandleCompositeVector.h:442
viskores::Tuple
Viskores replacement for std::tuple.
Definition: Tuple.h:43
viskores::cont::ArrayHandleCompositeVector::Superclass
typename viskores::cont::detail::GetTypeInParentheses< void(typename internal::CompositeVectorTraits< ArrayTs... >::Superclass) >::type Superclass
Definition: ArrayHandleCompositeVector.h:432
viskores::Get
auto Get(const viskores::Tuple< Ts... > &tuple)
Retrieve the object from a viskores::Tuple at the given index.
Definition: Tuple.h:89
viskores::cont::ArrayHandleCompositeVector::ArrayHandleCompositeVector
ArrayHandleCompositeVector(const ArrayTs &... arrays)
Construct an ArrayHandleCompositeVector from a set of component vectors.
Definition: ArrayHandleCompositeVector.h:436
viskores::CopyFlag
CopyFlag
Identifier used to specify whether a function should deep copy data.
Definition: Flags.h:25
viskores::Vec
A short fixed-length array.
Definition: Types.h:365
viskores::cont::Token
A token to hold the scope of an ArrayHandle or other object.
Definition: Token.h:43
viskores::cont::ArrayHandle::GetBuffers
const std::vector< viskores::cont::internal::Buffer > & GetBuffers() const
Returns the internal Buffer structures that hold the data.
Definition: ArrayHandle.h:738
Tuple.h
VecTraits.h
viskores::cont::ArrayHandleCompositeVector::StorageType
typename Superclass::StorageType StorageType
Definition: ArrayHandleCompositeVector.h:432