Viskores  1.0
ArrayHandleGroupVec.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_cont_ArrayHandleGroupVec_h
19 #define viskores_cont_ArrayHandleGroupVec_h
20 
25 
26 namespace viskores
27 {
28 namespace internal
29 {
30 
31 template <typename PortalType, viskores::IdComponent N_COMPONENTS>
32 class VISKORES_ALWAYS_EXPORT ArrayPortalGroupVec
33 {
34  using Writable = viskores::internal::PortalSupportsSets<PortalType>;
35 
36 public:
37  static constexpr viskores::IdComponent NUM_COMPONENTS = N_COMPONENTS;
38  using ComponentsPortalType = PortalType;
39 
40  using ComponentType = typename std::remove_const<typename ComponentsPortalType::ValueType>::type;
42 
45  ArrayPortalGroupVec()
46  : ComponentsPortal()
47  {
48  }
49 
52  ArrayPortalGroupVec(const ComponentsPortalType& componentsPortal)
53  : ComponentsPortal(componentsPortal)
54  {
55  }
56 
61  template <typename OtherComponentsPortalType>
62  VISKORES_EXEC_CONT ArrayPortalGroupVec(
63  const ArrayPortalGroupVec<OtherComponentsPortalType, NUM_COMPONENTS>& src)
64  : ComponentsPortal(src.GetPortal())
65  {
66  }
67 
70  viskores::Id GetNumberOfValues() const
71  {
72  return this->ComponentsPortal.GetNumberOfValues() / NUM_COMPONENTS;
73  }
74 
77  ValueType Get(viskores::Id index) const
78  {
79  ValueType result;
80  viskores::Id componentsIndex = index * NUM_COMPONENTS;
81  for (viskores::IdComponent componentIndex = 0; componentIndex < NUM_COMPONENTS;
82  componentIndex++)
83  {
84  result[componentIndex] = this->ComponentsPortal.Get(componentsIndex);
85  componentsIndex++;
86  }
87  return result;
88  }
89 
91  template <typename Writable_ = Writable,
92  typename = typename std::enable_if<Writable_::value>::type>
93  VISKORES_EXEC_CONT void Set(viskores::Id index, const ValueType& value) const
94  {
95  viskores::Id componentsIndex = index * NUM_COMPONENTS;
96  for (viskores::IdComponent componentIndex = 0; componentIndex < NUM_COMPONENTS;
97  componentIndex++)
98  {
99  this->ComponentsPortal.Set(componentsIndex, value[componentIndex]);
100  componentsIndex++;
101  }
102  }
103 
106  const ComponentsPortalType& GetPortal() const { return this->ComponentsPortal; }
107 
108 private:
109  ComponentsPortalType ComponentsPortal;
110 };
111 }
112 } // namespace viskores::internal
113 
114 namespace viskores
115 {
116 namespace cont
117 {
118 
119 template <typename ComponentsStorageTag, viskores::IdComponent NUM_COMPONENTS>
120 struct VISKORES_ALWAYS_EXPORT StorageTagGroupVec
121 {
122 };
123 
124 namespace internal
125 {
126 
127 template <typename ComponentType,
128  viskores::IdComponent NUM_COMPONENTS,
129  typename ComponentsStorageTag>
130 class Storage<viskores::Vec<ComponentType, NUM_COMPONENTS>,
131  viskores::cont::StorageTagGroupVec<ComponentsStorageTag, NUM_COMPONENTS>>
132 {
133  using ComponentsStorage = viskores::cont::internal::Storage<ComponentType, ComponentsStorageTag>;
135 
136 public:
137  using ReadPortalType =
138  viskores::internal::ArrayPortalGroupVec<typename ComponentsStorage::ReadPortalType,
139  NUM_COMPONENTS>;
140  using WritePortalType =
141  viskores::internal::ArrayPortalGroupVec<typename ComponentsStorage::WritePortalType,
142  NUM_COMPONENTS>;
143 
144  VISKORES_CONT static std::vector<viskores::cont::internal::Buffer> CreateBuffers()
145  {
146  return ComponentsStorage::CreateBuffers();
147  }
148 
149  VISKORES_CONT static void ResizeBuffers(
150  viskores::Id numValues,
151  const std::vector<viskores::cont::internal::Buffer>& buffers,
152  viskores::CopyFlag preserve,
153  viskores::cont::Token& token)
154  {
155  ComponentsStorage::ResizeBuffers(NUM_COMPONENTS * numValues, buffers, preserve, token);
156  }
157 
158  VISKORES_CONT static viskores::IdComponent GetNumberOfComponentsFlat(
159  const std::vector<viskores::cont::internal::Buffer>& buffers)
160  {
161  return ComponentsStorage::GetNumberOfComponentsFlat(buffers) * NUM_COMPONENTS;
162  }
163 
164  VISKORES_CONT static viskores::Id GetNumberOfValues(
165  const std::vector<viskores::cont::internal::Buffer>& buffers)
166  {
167  viskores::Id componentsSize = ComponentsStorage::GetNumberOfValues(buffers);
168  return componentsSize / NUM_COMPONENTS;
169  }
170 
171  VISKORES_CONT static void Fill(const std::vector<viskores::cont::internal::Buffer>&,
172  const ValueType&,
173  viskores::Id,
174  viskores::Id,
176  {
177  throw viskores::cont::ErrorBadType("Fill not supported for ArrayHandleGroupVec.");
178  }
179 
180  VISKORES_CONT static ReadPortalType CreateReadPortal(
181  const std::vector<viskores::cont::internal::Buffer>& buffers,
183  viskores::cont::Token& token)
184  {
185  if ((ComponentsStorage::GetNumberOfValues(buffers) % NUM_COMPONENTS) != 0)
186  {
188  "ArrayHandleGroupVec's components array does not divide evenly into Vecs.");
189  }
190  return ReadPortalType(ComponentsStorage::CreateReadPortal(buffers, device, token));
191  }
192 
193  VISKORES_CONT static WritePortalType CreateWritePortal(
194  const std::vector<viskores::cont::internal::Buffer>& buffers,
196  viskores::cont::Token& token)
197  {
198  if ((ComponentsStorage::GetNumberOfValues(buffers) % NUM_COMPONENTS) != 0)
199  {
201  "ArrayHandleGroupVec's components array does not divide evenly into Vecs.");
202  }
203  return WritePortalType(ComponentsStorage::CreateWritePortal(buffers, device, token));
204  }
205 };
206 
207 } // namespace internal
208 
226 template <typename ComponentsArrayHandleType, viskores::IdComponent NUM_COMPONENTS>
229  viskores::Vec<typename ComponentsArrayHandleType::ValueType, NUM_COMPONENTS>,
230  viskores::cont::StorageTagGroupVec<typename ComponentsArrayHandleType::StorageTag,
231  NUM_COMPONENTS>>
232 {
233  VISKORES_IS_ARRAY_HANDLE(ComponentsArrayHandleType);
234 
235 public:
241  viskores::cont::StorageTagGroupVec<typename ComponentsArrayHandleType::StorageTag,
242  NUM_COMPONENTS>>));
243 
244  using ComponentType = typename ComponentsArrayHandleType::ValueType;
245 
248  ArrayHandleGroupVec(const ComponentsArrayHandleType& componentsArray)
249  : Superclass(componentsArray.GetBuffers())
250  {
251  }
252 
254  VISKORES_CONT ComponentsArrayHandleType GetComponentsArray() const
255  {
256  return ComponentsArrayHandleType(this->GetBuffers());
257  }
258 };
259 
265 template <viskores::IdComponent NUM_COMPONENTS, typename ArrayHandleType>
267 make_ArrayHandleGroupVec(const ArrayHandleType& array)
268 {
270 }
271 
272 //--------------------------------------------------------------------------------
273 // Specialization of ArrayExtractComponent
274 namespace internal
275 {
276 
277 // Superclass will inherit the ArrayExtractComponentImplInefficient property if
278 // the sub-storage is inefficient (thus making everything inefficient).
279 template <typename ComponentsStorageTag, viskores::IdComponent NUM_COMPONENTS>
280 struct ArrayExtractComponentImpl<
281  viskores::cont::StorageTagGroupVec<ComponentsStorageTag, NUM_COMPONENTS>>
282  : viskores::cont::internal::ArrayExtractComponentImpl<ComponentsStorageTag>
283 {
284  template <typename T>
289  viskores::IdComponent componentIndex,
290  viskores::CopyFlag allowCopy) const
291  {
293  NUM_COMPONENTS>
294  srcArray(src);
295  constexpr viskores::IdComponent NUM_SUB_COMPONENTS = viskores::VecFlat<T>::NUM_COMPONENTS;
297  ArrayExtractComponentImpl<ComponentsStorageTag>{}(
298  srcArray.GetComponentsArray(), componentIndex % NUM_SUB_COMPONENTS, allowCopy);
299 
300  // Adjust stride and offset to expectations of grouped values
302  dest.GetBasicArray(),
303  dest.GetNumberOfValues() / NUM_COMPONENTS,
304  dest.GetStride() * NUM_COMPONENTS,
305  dest.GetOffset() + (dest.GetStride() * (componentIndex / NUM_SUB_COMPONENTS)),
306  dest.GetModulo(),
307  dest.GetDivisor());
308  }
309 };
310 
311 } // namespace internal
312 
313 }
314 } // namespace viskores::cont
315 
316 //=============================================================================
317 // Specializations of serialization related classes
319 namespace viskores
320 {
321 namespace cont
322 {
323 
324 template <typename AH, viskores::IdComponent NUM_COMPS>
325 struct SerializableTypeString<viskores::cont::ArrayHandleGroupVec<AH, NUM_COMPS>>
326 {
327  static VISKORES_CONT const std::string& Get()
328  {
329  static std::string name =
330  "AH_GroupVec<" + SerializableTypeString<AH>::Get() + "," + std::to_string(NUM_COMPS) + ">";
331  return name;
332  }
333 };
334 
335 template <typename T, viskores::IdComponent NUM_COMPS, typename ST>
336 struct SerializableTypeString<
337  viskores::cont::ArrayHandle<viskores::Vec<T, NUM_COMPS>,
338  viskores::cont::StorageTagGroupVec<ST, NUM_COMPS>>>
339  : SerializableTypeString<
340  viskores::cont::ArrayHandleGroupVec<viskores::cont::ArrayHandle<T, ST>, NUM_COMPS>>
341 {
342 };
343 }
344 } // viskores::cont
345 
346 namespace mangled_diy_namespace
347 {
348 
349 template <typename AH, viskores::IdComponent NUM_COMPS>
350 struct Serialization<viskores::cont::ArrayHandleGroupVec<AH, NUM_COMPS>>
351 {
352 private:
355 
356 public:
357  static VISKORES_CONT void save(BinaryBuffer& bb, const BaseType& obj)
358  {
359  viskoresdiy::save(bb, Type(obj).GetComponentsArray());
360  }
361 
362  static VISKORES_CONT void load(BinaryBuffer& bb, BaseType& obj)
363  {
364  AH array;
365  viskoresdiy::load(bb, array);
366 
367  obj = viskores::cont::make_ArrayHandleGroupVec<NUM_COMPS>(array);
368  }
369 };
370 
371 template <typename T, viskores::IdComponent NUM_COMPS, typename ST>
372 struct Serialization<viskores::cont::ArrayHandle<viskores::Vec<T, NUM_COMPS>,
373  viskores::cont::StorageTagGroupVec<ST, NUM_COMPS>>>
374  : Serialization<
375  viskores::cont::ArrayHandleGroupVec<viskores::cont::ArrayHandle<T, ST>, NUM_COMPS>>
376 {
377 };
378 
379 } // diy
381 
382 #endif //viskores_cont_ArrayHandleGroupVec_h
viskores::cont::ArrayHandleGroupVec::GetComponentsArray
ComponentsArrayHandleType GetComponentsArray() const
Retrieve the components array being grouped.
Definition: ArrayHandleGroupVec.h:254
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::cont::LogLevel::Warn
@ Warn
Less important user errors, such as out-of-bounds parameters.
viskores::cont::ErrorBadType
This class is thrown when Viskores encounters data of a type that is incompatible with the current op...
Definition: ErrorBadType.h:33
VISKORES_IS_ARRAY_HANDLE
#define VISKORES_IS_ARRAY_HANDLE(T)
Checks that the given type is a viskores::cont::ArrayHandle.
Definition: ArrayHandle.h:145
viskores::cont::StorageTagGroupVec
Definition: ArrayHandleGroupVec.h:120
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::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::Id
viskores::Int64 Id
Base type to use to index arrays.
Definition: Types.h:235
VISKORES_CONT
#define VISKORES_CONT
Definition: ExportMacros.h:65
ArrayPortal.h
viskores
Groups connected points that have the same field value.
Definition: Atomic.h:27
viskores::cont::ArrayHandleGroupVec
Fancy array handle that groups values into vectors.
Definition: ArrayHandleGroupVec.h:227
viskores::cont::ArrayHandleStride::GetDivisor
viskores::Id GetDivisor() const
Get the divisor of the array index.
Definition: ArrayHandleStride.h:418
viskores::cont::ArrayHandleStride::GetOffset
viskores::Id GetOffset() const
Get the offset to start reading values.
Definition: ArrayHandleStride.h:402
viskores::cont::ArrayHandle< T, viskores::cont::StorageTagStride >::GetNumberOfValues
viskores::Id GetNumberOfValues() const
Returns the number of entries in the array.
Definition: ArrayHandle.h:482
viskores::cont::ArrayHandleGroupVec::Superclass
typename viskores::cont::detail::GetTypeInParentheses< void(viskores::cont::ArrayHandle< viskores::Vec< typename ComponentsArrayHandleType::ValueType, NUM_COMPONENTS >, viskores::cont::StorageTagGroupVec< typename ComponentsArrayHandleType::StorageTag, NUM_COMPONENTS > >) >::type Superclass
Definition: ArrayHandleGroupVec.h:242
viskores::cont::make_ArrayHandleGroupVec
viskores::cont::ArrayHandleGroupVec< ArrayHandleType, NUM_COMPONENTS > make_ArrayHandleGroupVec(const ArrayHandleType &array)
make_ArrayHandleGroupVec is convenience function to generate an ArrayHandleGroupVec.
Definition: ArrayHandleGroupVec.h:267
viskores::cont::ArrayHandleGroupVec::ComponentType
typename ComponentsArrayHandleType::ValueType ComponentType
Definition: ArrayHandleGroupVec.h:244
viskores::cont::DeviceAdapterId
An object used to specify a device.
Definition: DeviceAdapterTag.h:66
VISKORES_LOG_S
#define VISKORES_LOG_S(level,...)
Writes a message using stream syntax to the indicated log level.
Definition: Logging.h:216
VISKORES_ARRAY_HANDLE_SUBCLASS
#define VISKORES_ARRAY_HANDLE_SUBCLASS(classname, fullclasstype, superclass)
Macro to make default methods in ArrayHandle subclasses.
Definition: ArrayHandle.h:256
ErrorBadValue.h
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::ArrayHandleGroupVec::ArrayHandleGroupVec
ArrayHandleGroupVec(const ComponentsArrayHandleType &componentsArray)
Construct an ArrayHandleGroupVec with a provided components array.
Definition: ArrayHandleGroupVec.h:248
viskores::CopyFlag
CopyFlag
Identifier used to specify whether a function should deep copy data.
Definition: Flags.h:25
viskores::cont::ArrayHandleStride::GetModulo
viskores::Id GetModulo() const
Get the modulus of the array index.
Definition: ArrayHandleStride.h:411
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< viskores::Vec< ComponentsArrayHandleType::ValueType, NUM_COMPONENTS >, viskores::cont::StorageTagGroupVec< ComponentsArrayHandleType::StorageTag, NUM_COMPONENTS > >::GetBuffers
const std::vector< viskores::cont::internal::Buffer > & GetBuffers() const
Returns the internal Buffer structures that hold the data.
Definition: ArrayHandle.h:738
viskores::cont::ArrayHandleStride::GetStride
viskores::Id GetStride() const
Get the stride that values are accessed.
Definition: ArrayHandleStride.h:391
viskores::cont::ArrayHandleStride::GetBasicArray
viskores::cont::ArrayHandleBasic< T > GetBasicArray() const
Return the underlying data as a basic array handle.
Definition: ArrayHandleStride.h:424