VTK-m  2.2
ArrayHandleGroupVec.h
Go to the documentation of this file.
1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10 #ifndef vtk_m_cont_ArrayHandleGroupVec_h
11 #define vtk_m_cont_ArrayHandleGroupVec_h
12 
14 #include <vtkm/cont/ArrayHandle.h>
15 #include <vtkm/cont/ArrayPortal.h>
17 
18 namespace vtkm
19 {
20 namespace internal
21 {
22 
23 template <typename PortalType, vtkm::IdComponent N_COMPONENTS>
24 class VTKM_ALWAYS_EXPORT ArrayPortalGroupVec
25 {
26  using Writable = vtkm::internal::PortalSupportsSets<PortalType>;
27 
28 public:
29  static constexpr vtkm::IdComponent NUM_COMPONENTS = N_COMPONENTS;
30  using ComponentsPortalType = PortalType;
31 
32  using ComponentType = typename std::remove_const<typename ComponentsPortalType::ValueType>::type;
34 
37  ArrayPortalGroupVec()
38  : ComponentsPortal()
39  {
40  }
41 
44  ArrayPortalGroupVec(const ComponentsPortalType& componentsPortal)
45  : ComponentsPortal(componentsPortal)
46  {
47  }
48 
53  template <typename OtherComponentsPortalType>
54  VTKM_EXEC_CONT ArrayPortalGroupVec(
55  const ArrayPortalGroupVec<OtherComponentsPortalType, NUM_COMPONENTS>& src)
56  : ComponentsPortal(src.GetPortal())
57  {
58  }
59 
62  vtkm::Id GetNumberOfValues() const
63  {
64  return this->ComponentsPortal.GetNumberOfValues() / NUM_COMPONENTS;
65  }
66 
69  ValueType Get(vtkm::Id index) const
70  {
71  ValueType result;
72  vtkm::Id componentsIndex = index * NUM_COMPONENTS;
73  for (vtkm::IdComponent componentIndex = 0; componentIndex < NUM_COMPONENTS; componentIndex++)
74  {
75  result[componentIndex] = this->ComponentsPortal.Get(componentsIndex);
76  componentsIndex++;
77  }
78  return result;
79  }
80 
82  template <typename Writable_ = Writable,
83  typename = typename std::enable_if<Writable_::value>::type>
84  VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const
85  {
86  vtkm::Id componentsIndex = index * NUM_COMPONENTS;
87  for (vtkm::IdComponent componentIndex = 0; componentIndex < NUM_COMPONENTS; componentIndex++)
88  {
89  this->ComponentsPortal.Set(componentsIndex, value[componentIndex]);
90  componentsIndex++;
91  }
92  }
93 
96  const ComponentsPortalType& GetPortal() const { return this->ComponentsPortal; }
97 
98 private:
99  ComponentsPortalType ComponentsPortal;
100 };
101 }
102 } // namespace vtkm::internal
103 
104 namespace vtkm
105 {
106 namespace cont
107 {
108 
109 template <typename ComponentsStorageTag, vtkm::IdComponent NUM_COMPONENTS>
111 {
112 };
113 
114 namespace internal
115 {
116 
117 template <typename ComponentType, vtkm::IdComponent NUM_COMPONENTS, typename ComponentsStorageTag>
118 class Storage<vtkm::Vec<ComponentType, NUM_COMPONENTS>,
119  vtkm::cont::StorageTagGroupVec<ComponentsStorageTag, NUM_COMPONENTS>>
120 {
121  using ComponentsStorage = vtkm::cont::internal::Storage<ComponentType, ComponentsStorageTag>;
123 
124 public:
125  using ReadPortalType =
126  vtkm::internal::ArrayPortalGroupVec<typename ComponentsStorage::ReadPortalType, NUM_COMPONENTS>;
127  using WritePortalType =
128  vtkm::internal::ArrayPortalGroupVec<typename ComponentsStorage::WritePortalType,
129  NUM_COMPONENTS>;
130 
131  VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
132  {
133  return ComponentsStorage::CreateBuffers();
134  }
135 
136  VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
137  const std::vector<vtkm::cont::internal::Buffer>& buffers,
138  vtkm::CopyFlag preserve,
139  vtkm::cont::Token& token)
140  {
141  ComponentsStorage::ResizeBuffers(NUM_COMPONENTS * numValues, buffers, preserve, token);
142  }
143 
144  VTKM_CONT static vtkm::IdComponent GetNumberOfComponentsFlat(
145  const std::vector<vtkm::cont::internal::Buffer>& buffers)
146  {
147  return ComponentsStorage::GetNumberOfComponentsFlat(buffers) * NUM_COMPONENTS;
148  }
149 
150  VTKM_CONT static vtkm::Id GetNumberOfValues(
151  const std::vector<vtkm::cont::internal::Buffer>& buffers)
152  {
153  vtkm::Id componentsSize = ComponentsStorage::GetNumberOfValues(buffers);
154  return componentsSize / NUM_COMPONENTS;
155  }
156 
157  VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>&,
158  const ValueType&,
159  vtkm::Id,
160  vtkm::Id,
162  {
163  throw vtkm::cont::ErrorBadType("Fill not supported for ArrayHandleGroupVec.");
164  }
165 
166  VTKM_CONT static ReadPortalType CreateReadPortal(
167  const std::vector<vtkm::cont::internal::Buffer>& buffers,
169  vtkm::cont::Token& token)
170  {
171  if ((ComponentsStorage::GetNumberOfValues(buffers) % NUM_COMPONENTS) != 0)
172  {
174  "ArrayHandleGroupVec's components array does not divide evenly into Vecs.");
175  }
176  return ReadPortalType(ComponentsStorage::CreateReadPortal(buffers, device, token));
177  }
178 
179  VTKM_CONT static WritePortalType CreateWritePortal(
180  const std::vector<vtkm::cont::internal::Buffer>& buffers,
182  vtkm::cont::Token& token)
183  {
184  if ((ComponentsStorage::GetNumberOfValues(buffers) % NUM_COMPONENTS) != 0)
185  {
187  "ArrayHandleGroupVec's components array does not divide evenly into Vecs.");
188  }
189  return WritePortalType(ComponentsStorage::CreateWritePortal(buffers, device, token));
190  }
191 };
192 
193 } // namespace internal
194 
212 template <typename ComponentsArrayHandleType, vtkm::IdComponent NUM_COMPONENTS>
214  : public vtkm::cont::ArrayHandle<
215  vtkm::Vec<typename ComponentsArrayHandleType::ValueType, NUM_COMPONENTS>,
216  vtkm::cont::StorageTagGroupVec<typename ComponentsArrayHandleType::StorageTag,
217  NUM_COMPONENTS>>
218 {
219  VTKM_IS_ARRAY_HANDLE(ComponentsArrayHandleType);
220 
221 public:
227  vtkm::cont::StorageTagGroupVec<typename ComponentsArrayHandleType::StorageTag,
228  NUM_COMPONENTS>>));
229 
230  using ComponentType = typename ComponentsArrayHandleType::ValueType;
231 
233  VTKM_CONT
234  ArrayHandleGroupVec(const ComponentsArrayHandleType& componentsArray)
235  : Superclass(componentsArray.GetBuffers())
236  {
237  }
238 
240  VTKM_CONT ComponentsArrayHandleType GetComponentsArray() const
241  {
242  return ComponentsArrayHandleType(this->GetBuffers());
243  }
244 };
245 
251 template <vtkm::IdComponent NUM_COMPONENTS, typename ArrayHandleType>
253  const ArrayHandleType& array)
254 {
256 }
257 
258 //--------------------------------------------------------------------------------
259 // Specialization of ArrayExtractComponent
260 namespace internal
261 {
262 
263 // Superclass will inherit the ArrayExtractComponentImplInefficient property if
264 // the sub-storage is inefficient (thus making everything inefficient).
265 template <typename ComponentsStorageTag, vtkm::IdComponent NUM_COMPONENTS>
266 struct ArrayExtractComponentImpl<
267  vtkm::cont::StorageTagGroupVec<ComponentsStorageTag, NUM_COMPONENTS>>
268  : vtkm::cont::internal::ArrayExtractComponentImpl<ComponentsStorageTag>
269 {
270  template <typename T>
275  vtkm::IdComponent componentIndex,
276  vtkm::CopyFlag allowCopy) const
277  {
279  NUM_COMPONENTS>
280  srcArray(src);
281  constexpr vtkm::IdComponent NUM_SUB_COMPONENTS = vtkm::VecFlat<T>::NUM_COMPONENTS;
283  ArrayExtractComponentImpl<ComponentsStorageTag>{}(
284  srcArray.GetComponentsArray(), componentIndex % NUM_SUB_COMPONENTS, allowCopy);
285 
286  // Adjust stride and offset to expectations of grouped values
288  dest.GetBasicArray(),
289  dest.GetNumberOfValues() / NUM_COMPONENTS,
290  dest.GetStride() * NUM_COMPONENTS,
291  dest.GetOffset() + (dest.GetStride() * (componentIndex / NUM_SUB_COMPONENTS)),
292  dest.GetModulo(),
293  dest.GetDivisor());
294  }
295 };
296 
297 } // namespace internal
298 
299 }
300 } // namespace vtkm::cont
301 
302 //=============================================================================
303 // Specializations of serialization related classes
305 namespace vtkm
306 {
307 namespace cont
308 {
309 
310 template <typename AH, vtkm::IdComponent NUM_COMPS>
311 struct SerializableTypeString<vtkm::cont::ArrayHandleGroupVec<AH, NUM_COMPS>>
312 {
313  static VTKM_CONT const std::string& Get()
314  {
315  static std::string name =
316  "AH_GroupVec<" + SerializableTypeString<AH>::Get() + "," + std::to_string(NUM_COMPS) + ">";
317  return name;
318  }
319 };
320 
321 template <typename T, vtkm::IdComponent NUM_COMPS, typename ST>
322 struct SerializableTypeString<
323  vtkm::cont::ArrayHandle<vtkm::Vec<T, NUM_COMPS>, vtkm::cont::StorageTagGroupVec<ST, NUM_COMPS>>>
324  : SerializableTypeString<
325  vtkm::cont::ArrayHandleGroupVec<vtkm::cont::ArrayHandle<T, ST>, NUM_COMPS>>
326 {
327 };
328 }
329 } // vtkm::cont
330 
331 namespace mangled_diy_namespace
332 {
333 
334 template <typename AH, vtkm::IdComponent NUM_COMPS>
335 struct Serialization<vtkm::cont::ArrayHandleGroupVec<AH, NUM_COMPS>>
336 {
337 private:
340 
341 public:
342  static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
343  {
344  vtkmdiy::save(bb, Type(obj).GetComponentsArray());
345  }
346 
347  static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj)
348  {
349  AH array;
350  vtkmdiy::load(bb, array);
351 
352  obj = vtkm::cont::make_ArrayHandleGroupVec<NUM_COMPS>(array);
353  }
354 };
355 
356 template <typename T, vtkm::IdComponent NUM_COMPS, typename ST>
357 struct Serialization<
358  vtkm::cont::ArrayHandle<vtkm::Vec<T, NUM_COMPS>, vtkm::cont::StorageTagGroupVec<ST, NUM_COMPS>>>
359  : Serialization<vtkm::cont::ArrayHandleGroupVec<vtkm::cont::ArrayHandle<T, ST>, NUM_COMPS>>
360 {
361 };
362 
363 } // diy
365 
366 #endif //vtk_m_cont_ArrayHandleGroupVec_h
vtkm::cont::ArrayHandle
Manages an array-worth of data.
Definition: ArrayHandle.h:300
ArrayHandle.h
ArrayExtractComponent.h
vtkm::cont::ArrayHandle< vtkm::Vec< ComponentsArrayHandleType::ValueType, NUM_COMPONENTS >, vtkm::cont::StorageTagGroupVec< ComponentsArrayHandleType::StorageTag, NUM_COMPONENTS > >::GetBuffers
const std::vector< vtkm::cont::internal::Buffer > & GetBuffers() const
Returns the internal Buffer structures that hold the data.
Definition: ArrayHandle.h:721
vtkm::cont::ArrayHandleGroupVec::GetComponentsArray
ComponentsArrayHandleType GetComponentsArray() const
Retrieve the components array being grouped.
Definition: ArrayHandleGroupVec.h:240
vtkm::exec::arg::load
T load(const U &u, vtkm::Id v)
Definition: FetchTagArrayDirectIn.h:36
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::cont::ArrayHandleGroupVec::ArrayHandleGroupVec
ArrayHandleGroupVec(const ComponentsArrayHandleType &componentsArray)
Construct an ArrayHandleGroupVec with a provided components array.
Definition: ArrayHandleGroupVec.h:234
vtkm::Get
auto Get(const vtkm::Tuple< Ts... > &tuple)
Retrieve the object from a vtkm::Tuple at the given index.
Definition: Tuple.h:81
VTKM_ARRAY_HANDLE_SUBCLASS
#define VTKM_ARRAY_HANDLE_SUBCLASS(classname, fullclasstype, superclass)
Macro to make default methods in ArrayHandle subclasses.
Definition: ArrayHandle.h:243
vtkm::cont::LogLevel::Warn
@ Warn
Less important user errors, such as out-of-bounds parameters.
VTKM_EXEC_CONT
#define VTKM_EXEC_CONT
Definition: ExportMacros.h:52
vtkm::IdComponent
vtkm::Int32 IdComponent
Base type to use to index small lists.
Definition: Types.h:194
vtkm::cont::ArrayHandleStride::GetStride
vtkm::Id GetStride() const
Get the stride that values are accessed.
Definition: ArrayHandleStride.h:377
vtkm::cont::ArrayHandleStride::GetOffset
vtkm::Id GetOffset() const
Get the offset to start reading values.
Definition: ArrayHandleStride.h:388
vtkm::cont::ArrayHandle< T, vtkm::cont::StorageTagStride >::GetNumberOfValues
vtkm::Id GetNumberOfValues() const
Returns the number of entries in the array.
Definition: ArrayHandle.h:468
vtkm::cont::ErrorBadType
This class is thrown when VTK-m encounters data of a type that is incompatible with the current opera...
Definition: ErrorBadType.h:25
mangled_diy_namespace
Definition: Particle.h:351
vtkm::cont::ArrayHandleStride
An ArrayHandle that accesses a basic array with strides and offsets.
Definition: ArrayHandleStride.h:332
vtkm::cont::Token
A token to hold the scope of an ArrayHandle or other object.
Definition: Token.h:35
vtkm::cont::ArrayHandleStride::GetDivisor
vtkm::Id GetDivisor() const
Get the divisor of the array index.
Definition: ArrayHandleStride.h:404
ArrayPortal.h
vtkm::cont::ArrayHandleStride::GetBasicArray
vtkm::cont::ArrayHandleBasic< T > GetBasicArray() const
Return the underlying data as a basic array handle.
Definition: ArrayHandleStride.h:410
VTKM_IS_ARRAY_HANDLE
#define VTKM_IS_ARRAY_HANDLE(T)
Checks that the given type is a vtkm::cont::ArrayHandle.
Definition: ArrayHandle.h:137
vtkm::cont::ArrayHandleGroupVec::Superclass
typename vtkm::cont::detail::GetTypeInParentheses< void(vtkm::cont::ArrayHandle< vtkm::Vec< typename ComponentsArrayHandleType::ValueType, NUM_COMPONENTS >, vtkm::cont::StorageTagGroupVec< typename ComponentsArrayHandleType::StorageTag, NUM_COMPONENTS > >) >::type Superclass
Definition: ArrayHandleGroupVec.h:228
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
vtkm::Id
vtkm::Int64 Id
Base type to use to index arrays.
Definition: Types.h:227
vtkm::cont::StorageTagGroupVec
Definition: ArrayHandleGroupVec.h:110
vtkm::VecFlat
Treat a Vec or Vec-like object as a flat Vec.
Definition: VecFlat.h:224
vtkm::cont::make_ArrayHandleGroupVec
vtkm::cont::ArrayHandleGroupVec< ArrayHandleType, NUM_COMPONENTS > make_ArrayHandleGroupVec(const ArrayHandleType &array)
make_ArrayHandleGroupVec is convenience function to generate an ArrayHandleGroupVec.
Definition: ArrayHandleGroupVec.h:252
VTKM_LOG_S
#define VTKM_LOG_S(level,...)
Writes a message using stream syntax to the indicated log level.
Definition: Logging.h:208
vtkm::cont::ArrayHandleStride::GetModulo
vtkm::Id GetModulo() const
Get the modulus of the array index.
Definition: ArrayHandleStride.h:397
vtkm::cont::DeviceAdapterId
An object used to specify a device.
Definition: DeviceAdapterTag.h:58
vtkm::Vec
A short fixed-length array.
Definition: Types.h:357
vtkm::cont::ArrayHandleGroupVec::ComponentType
typename ComponentsArrayHandleType::ValueType ComponentType
Definition: ArrayHandleGroupVec.h:230
ErrorBadValue.h
vtkm::CopyFlag
CopyFlag
Identifier used to specify whether a function should deep copy data.
Definition: Flags.h:17
vtkm::cont::ArrayHandleGroupVec
Fancy array handle that groups values into vectors.
Definition: ArrayHandleGroupVec.h:213
VTKM_ALWAYS_EXPORT
#define VTKM_ALWAYS_EXPORT
Definition: ExportMacros.h:89
VTKM_SUPPRESS_EXEC_WARNINGS
#define VTKM_SUPPRESS_EXEC_WARNINGS
Definition: ExportMacros.h:53