VTK-m  2.0
ArrayHandleStride.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_ArrayHandleStride_h
11 #define vtk_m_cont_ArrayHandleStride_h
12 
14 #include <vtkm/cont/ErrorBadType.h>
15 
17 
18 namespace vtkm
19 {
20 namespace internal
21 {
22 
23 struct ArrayStrideInfo
24 {
25  vtkm::Id NumberOfValues = 0;
26  vtkm::Id Stride = 1;
27  vtkm::Id Offset = 0;
28  vtkm::Id Modulo = 0;
29  vtkm::Id Divisor = 0;
30 
31  ArrayStrideInfo() = default;
32 
33  ArrayStrideInfo(vtkm::Id numValues,
34  vtkm::Id stride,
35  vtkm::Id offset,
36  vtkm::Id modulo,
37  vtkm::Id divisor)
38  : NumberOfValues(numValues)
39  , Stride(stride)
40  , Offset(offset)
41  , Modulo(modulo)
42  , Divisor(divisor)
43  {
44  }
45 
46  VTKM_EXEC_CONT vtkm::Id ArrayIndex(vtkm::Id index) const
47  {
48  vtkm::Id arrayIndex = index;
49  if (this->Divisor > 1)
50  {
51  arrayIndex = arrayIndex / this->Divisor;
52  }
53  if (this->Modulo > 0)
54  {
55  arrayIndex = arrayIndex % this->Modulo;
56  }
57  arrayIndex = (arrayIndex * this->Stride) + this->Offset;
58  return arrayIndex;
59  }
60 };
61 
62 template <typename T>
63 class ArrayPortalStrideRead
64 {
65  const T* Array = nullptr;
66  ArrayStrideInfo Info;
67 
68 public:
69  ArrayPortalStrideRead() = default;
70  ArrayPortalStrideRead(ArrayPortalStrideRead&&) = default;
71  ArrayPortalStrideRead(const ArrayPortalStrideRead&) = default;
72  ArrayPortalStrideRead& operator=(ArrayPortalStrideRead&&) = default;
73  ArrayPortalStrideRead& operator=(const ArrayPortalStrideRead&) = default;
74 
75  ArrayPortalStrideRead(const T* array, const ArrayStrideInfo& info)
76  : Array(array)
77  , Info(info)
78  {
79  }
80 
81  using ValueType = T;
82 
83  VTKM_EXEC_CONT vtkm::Id GetNumberOfValues() const { return this->Info.NumberOfValues; }
84 
85  VTKM_EXEC_CONT ValueType Get(vtkm::Id index) const
86  {
87  VTKM_ASSERT(index >= 0);
88  VTKM_ASSERT(index < this->GetNumberOfValues());
89 
90  return detail::ArrayPortalBasicReadGet(this->Array + this->Info.ArrayIndex(index));
91  }
92 
93  VTKM_EXEC_CONT const ValueType* GetArray() const { return this->Array; }
94  VTKM_EXEC_CONT const ArrayStrideInfo& GetInfo() const { return this->Info; }
95 };
96 
97 template <typename T>
98 class ArrayPortalStrideWrite
99 {
100  T* Array = nullptr;
101  ArrayStrideInfo Info;
102 
103 public:
104  ArrayPortalStrideWrite() = default;
105  ArrayPortalStrideWrite(ArrayPortalStrideWrite&&) = default;
106  ArrayPortalStrideWrite(const ArrayPortalStrideWrite&) = default;
107  ArrayPortalStrideWrite& operator=(ArrayPortalStrideWrite&&) = default;
108  ArrayPortalStrideWrite& operator=(const ArrayPortalStrideWrite&) = default;
109 
110  ArrayPortalStrideWrite(T* array, const ArrayStrideInfo& info)
111  : Array(array)
112  , Info(info)
113  {
114  }
115 
116  using ValueType = T;
117 
118  VTKM_EXEC_CONT vtkm::Id GetNumberOfValues() const { return this->Info.NumberOfValues; }
119 
120  VTKM_EXEC_CONT ValueType Get(vtkm::Id index) const
121  {
122  VTKM_ASSERT(index >= 0);
123  VTKM_ASSERT(index < this->GetNumberOfValues());
124 
125  return detail::ArrayPortalBasicWriteGet(this->Array + this->Info.ArrayIndex(index));
126  }
127 
128  VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const
129  {
130  VTKM_ASSERT(index >= 0);
131  VTKM_ASSERT(index < this->GetNumberOfValues());
132 
133  detail::ArrayPortalBasicWriteSet(this->Array + this->Info.ArrayIndex(index), value);
134  }
135 
136  VTKM_EXEC_CONT ValueType* GetArray() const { return this->Array; }
137  VTKM_EXEC_CONT const ArrayStrideInfo& GetInfo() const { return this->Info; }
138 };
139 
140 }
141 } // namespace vtkm::internal
142 
143 namespace vtkm
144 {
145 namespace cont
146 {
147 
149 {
150 };
151 
152 namespace internal
153 {
154 
155 template <typename T>
157 {
158  using StrideInfo = vtkm::internal::ArrayStrideInfo;
159 
160 public:
162 
163  using ReadPortalType = vtkm::internal::ArrayPortalStrideRead<T>;
164  using WritePortalType = vtkm::internal::ArrayPortalStrideWrite<T>;
165 
166  VTKM_CONT static StrideInfo& GetInfo(const std::vector<vtkm::cont::internal::Buffer>& buffers)
167  {
168  return buffers[0].GetMetaData<StrideInfo>();
169  }
170 
171  VTKM_CONT static vtkm::Id GetNumberOfValues(
172  const std::vector<vtkm::cont::internal::Buffer>& buffers)
173  {
174  return GetInfo(buffers).NumberOfValues;
175  }
176 
177  VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>&,
178  const T&,
179  vtkm::Id,
180  vtkm::Id,
182  {
183  throw vtkm::cont::ErrorBadType("Fill not supported for ArrayHandleStride.");
184  }
185 
186  VTKM_CONT static ReadPortalType CreateReadPortal(
187  const std::vector<vtkm::cont::internal::Buffer>& buffers,
189  vtkm::cont::Token& token)
190  {
191  return ReadPortalType(reinterpret_cast<const T*>(buffers[1].ReadPointerDevice(device, token)),
192  GetInfo(buffers));
193  }
194 
195  VTKM_CONT static WritePortalType CreateWritePortal(
196  const std::vector<vtkm::cont::internal::Buffer>& buffers,
198  vtkm::cont::Token& token)
199  {
200  return WritePortalType(reinterpret_cast<T*>(buffers[1].WritePointerDevice(device, token)),
201  GetInfo(buffers));
202  }
203 
204  static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
205  const vtkm::cont::internal::Buffer& sourceBuffer = vtkm::cont::internal::Buffer{},
206  vtkm::internal::ArrayStrideInfo&& info = vtkm::internal::ArrayStrideInfo{})
207  {
208  return vtkm::cont::internal::CreateBuffers(info, sourceBuffer);
209  }
210 
211  static vtkm::cont::ArrayHandleBasic<T> GetBasicArray(
212  const std::vector<vtkm::cont::internal::Buffer>& buffers)
213  {
215  }
216 };
217 
218 } // namespace internal
219 
250 template <typename T>
252  : public vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagStride>
253 {
254 public:
258 
259 private:
260  using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
261 
262 public:
263  ArrayHandleStride(vtkm::Id stride, vtkm::Id offset, vtkm::Id modulo = 0, vtkm::Id divisor = 1)
264  : Superclass(StorageType::CreateBuffers(
265  vtkm::cont::internal::Buffer{},
266  vtkm::internal::ArrayStrideInfo(0, stride, offset, modulo, divisor)))
267  {
268  }
269 
271  vtkm::Id numValues,
272  vtkm::Id stride,
273  vtkm::Id offset,
274  vtkm::Id modulo = 0,
275  vtkm::Id divisor = 1)
276  : Superclass(StorageType::CreateBuffers(
277  array.GetBuffers()[0],
278  vtkm::internal::ArrayStrideInfo(numValues, stride, offset, modulo, divisor)))
279  {
280  }
281 
282  ArrayHandleStride(const vtkm::cont::internal::Buffer& buffer,
283  vtkm::Id numValues,
284  vtkm::Id stride,
285  vtkm::Id offset,
286  vtkm::Id modulo = 0,
287  vtkm::Id divisor = 1)
288  : Superclass(StorageType::CreateBuffers(
289  buffer,
290  vtkm::internal::ArrayStrideInfo(numValues, stride, offset, modulo, divisor)))
291  {
292  }
293 
294  vtkm::Id GetStride() const { return StorageType::GetInfo(this->GetBuffers()).Stride; }
295  vtkm::Id GetOffset() const { return StorageType::GetInfo(this->GetBuffers()).Offset; }
296  vtkm::Id GetModulo() const { return StorageType::GetInfo(this->GetBuffers()).Modulo; }
297  vtkm::Id GetDivisor() const { return StorageType::GetInfo(this->GetBuffers()).Divisor; }
298 
300  {
301  return StorageType::GetBasicArray(this->GetBuffers());
302  }
303 };
304 
305 }
306 } // namespace vtkm::cont
307 
308 //=============================================================================
309 // Specializations of serialization related classes
311 namespace vtkm
312 {
313 namespace cont
314 {
315 
316 template <typename T>
317 struct SerializableTypeString<vtkm::cont::ArrayHandleStride<T>>
318 {
319  static VTKM_CONT const std::string& Get()
320  {
321  static std::string name = "AHStride<" + SerializableTypeString<T>::Get() + ">";
322  return name;
323  }
324 };
325 
326 template <typename T>
327 struct SerializableTypeString<vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagStride>>
328  : SerializableTypeString<vtkm::cont::ArrayHandleStride<T>>
329 {
330 };
331 
332 }
333 } // namespace vtkm::cont
334 
335 namespace mangled_diy_namespace
336 {
337 
338 template <typename T>
339 struct Serialization<vtkm::cont::ArrayHandleStride<T>>
340 {
341 private:
343 
344 public:
345  static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj_)
346  {
348  vtkmdiy::save(bb, obj.GetNumberOfValues());
349  vtkmdiy::save(bb, obj.GetStride());
350  vtkmdiy::save(bb, obj.GetOffset());
351  vtkmdiy::save(bb, obj.GetModulo());
352  vtkmdiy::save(bb, obj.GetDivisor());
353  vtkmdiy::save(bb, obj.GetBuffers()[1]);
354  }
355 
356  static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj)
357  {
358  vtkm::Id numValues;
359  vtkm::Id stride;
360  vtkm::Id offset;
361  vtkm::Id modulo;
362  vtkm::Id divisor;
363  vtkm::cont::internal::Buffer buffer;
364 
365  vtkmdiy::load(bb, numValues);
366  vtkmdiy::load(bb, stride);
367  vtkmdiy::load(bb, offset);
368  vtkmdiy::load(bb, modulo);
369  vtkmdiy::load(bb, divisor);
370  vtkmdiy::load(bb, buffer);
371 
372  obj = vtkm::cont::ArrayHandleStride<T>(buffer, stride, offset, modulo, divisor);
373  }
374 };
375 
376 } // namespace diy
378 
381 #ifndef vtk_m_cont_ArrayHandleStride_cxx
382 
383 namespace vtkm
384 {
385 namespace cont
386 {
387 
388 namespace internal
389 {
390 
391 extern template class VTKM_CONT_TEMPLATE_EXPORT Storage<char, StorageTagStride>;
392 extern template class VTKM_CONT_TEMPLATE_EXPORT Storage<vtkm::Int8, StorageTagStride>;
393 extern template class VTKM_CONT_TEMPLATE_EXPORT Storage<vtkm::UInt8, StorageTagStride>;
394 extern template class VTKM_CONT_TEMPLATE_EXPORT Storage<vtkm::Int16, StorageTagStride>;
395 extern template class VTKM_CONT_TEMPLATE_EXPORT Storage<vtkm::UInt16, StorageTagStride>;
396 extern template class VTKM_CONT_TEMPLATE_EXPORT Storage<vtkm::Int32, StorageTagStride>;
397 extern template class VTKM_CONT_TEMPLATE_EXPORT Storage<vtkm::UInt32, StorageTagStride>;
398 extern template class VTKM_CONT_TEMPLATE_EXPORT Storage<vtkm::Int64, StorageTagStride>;
399 extern template class VTKM_CONT_TEMPLATE_EXPORT Storage<vtkm::UInt64, StorageTagStride>;
400 extern template class VTKM_CONT_TEMPLATE_EXPORT Storage<vtkm::Float32, StorageTagStride>;
401 extern template class VTKM_CONT_TEMPLATE_EXPORT Storage<vtkm::Float64, StorageTagStride>;
402 
403 } // namespace internal
404 
405 extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<char, StorageTagStride>;
406 extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Int8, StorageTagStride>;
407 extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::UInt8, StorageTagStride>;
408 extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Int16, StorageTagStride>;
409 extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::UInt16, StorageTagStride>;
410 extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Int32, StorageTagStride>;
411 extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::UInt32, StorageTagStride>;
412 extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Int64, StorageTagStride>;
413 extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::UInt64, StorageTagStride>;
414 extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Float32, StorageTagStride>;
415 extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Float64, StorageTagStride>;
416 
417 }
418 } // namespace vtkm::cont
419 
420 #endif //vtk_m_cont_ArrayHandleStride_cxx
421 
423 #endif //vtk_m_cont_ArrayHandleStride_h
vtkm::cont::ArrayHandle< T, vtkm::cont::StorageTagStride >::GetBuffers
const VTKM_CONT std::vector< vtkm::cont::internal::Buffer > & GetBuffers() const
Returns the internal Buffer structures that hold the data.
Definition: ArrayHandle.h:696
vtkm::cont::ArrayHandle< T, vtkm::cont::StorageTagStride >::GetNumberOfValues
VTKM_CONT vtkm::Id GetNumberOfValues() const
Returns the number of entries in the array.
Definition: ArrayHandle.h:448
vtkm::cont::ArrayHandle< T, vtkm::cont::StorageTagBasic >
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
VTKM_ARRAY_HANDLE_SUBCLASS
#define VTKM_ARRAY_HANDLE_SUBCLASS(classname, fullclasstype, superclass)
Macro to make default methods in ArrayHandle subclasses.
Definition: ArrayHandle.h:226
VTKM_ASSERT
#define VTKM_ASSERT(condition)
Definition: Assert.h:43
VTKM_EXEC_CONT
#define VTKM_EXEC_CONT
Definition: ExportMacros.h:52
vtkm::cont::StorageTagStride
Definition: ArrayHandleStride.h:148
vtkm::Get
VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_CONT auto Get(const vtkm::Tuple< Ts... > &tuple) -> decltype(tuple.template Get< Index >())
Retrieve the object from a vtkm::Tuple at the given index.
Definition: Tuple.h:83
vtkm::cont::ArrayHandleStride::GetStride
vtkm::Id GetStride() const
Definition: ArrayHandleStride.h:294
ArrayHandleBasic.h
vtkm::cont::ArrayHandleStride::GetOffset
vtkm::Id GetOffset() const
Definition: ArrayHandleStride.h:295
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
VTKM_STORAGE_NO_RESIZE
#define VTKM_STORAGE_NO_RESIZE
Definition: Storage.h:185
mangled_diy_namespace
Definition: Particle.h:331
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
vtkm::exec::arg::load
VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC T load(const U &u, vtkm::Id v)
Definition: FetchTagArrayDirectIn.h:36
vtkm::cont::ArrayHandleStride
An ArrayHandle that accesses a basic array with strides and offsets.
Definition: ArrayHandleStride.h:251
vtkm::cont::Token
A token to hold the scope of an ArrayHandle or other object.
Definition: Token.h:35
vtkm::cont::LogLevel::Info
@ Info
Information messages (detected hardware, etc) and temporary debugging output.
ArrayPortalBasic.h
vtkm::cont::ArrayHandleStride::GetDivisor
vtkm::Id GetDivisor() const
Definition: ArrayHandleStride.h:297
vtkm::cont::ArrayHandleStride::GetBasicArray
vtkm::cont::ArrayHandleBasic< T > GetBasicArray() const
Definition: ArrayHandleStride.h:299
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
vtkm::cont::ArrayHandleStride::GetModulo
vtkm::Id GetModulo() const
Definition: ArrayHandleStride.h:296
vtkm::cont::DeviceAdapterId
Definition: DeviceAdapterTag.h:52
vtkm::cont::ArrayHandleStride::ArrayHandleStride
ArrayHandleStride(const vtkm::cont::ArrayHandle< T, vtkm::cont::StorageTagBasic > &array, vtkm::Id numValues, vtkm::Id stride, vtkm::Id offset, vtkm::Id modulo=0, vtkm::Id divisor=1)
Definition: ArrayHandleStride.h:270
vtkm::cont::ArrayHandleStride::ArrayHandleStride
ArrayHandleStride(vtkm::Id stride, vtkm::Id offset, vtkm::Id modulo=0, vtkm::Id divisor=1)
Definition: ArrayHandleStride.h:263
Offset
vtkm::Float32 Offset
Definition: Wireframer.h:391
vtkm::cont::ArrayHandleStride::StorageType
vtkm::cont::internal::Storage< ValueType, StorageTag > StorageType
Definition: ArrayHandleStride.h:260
vtkm::cont::ArrayHandleBasic
Definition: ArrayHandleBasic.h:97
VTKM_ALWAYS_EXPORT
#define VTKM_ALWAYS_EXPORT
Definition: ExportMacros.h:92
ErrorBadType.h
vtkm::cont::ArrayHandleStride::ArrayHandleStride
ArrayHandleStride(const vtkm::cont::internal::Buffer &buffer, vtkm::Id numValues, vtkm::Id stride, vtkm::Id offset, vtkm::Id modulo=0, vtkm::Id divisor=1)
Definition: ArrayHandleStride.h:282