VTK-m  2.2
ArrayHandleConcatenate.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_ArrayHandleConcatenate_h
11 #define vtk_m_cont_ArrayHandleConcatenate_h
12 
13 #include <vtkm/StaticAssert.h>
14 
15 #include <vtkm/cont/ArrayHandle.h>
16 
17 namespace vtkm
18 {
19 namespace internal
20 {
21 
22 template <typename PortalType1, typename PortalType2>
23 class VTKM_ALWAYS_EXPORT ArrayPortalConcatenate
24 {
25  using WritableP1 = vtkm::internal::PortalSupportsSets<PortalType1>;
26  using WritableP2 = vtkm::internal::PortalSupportsSets<PortalType2>;
27  using Writable = std::integral_constant<bool, WritableP1::value && WritableP2::value>;
28 
29 public:
30  using ValueType = typename PortalType1::ValueType;
31 
34  ArrayPortalConcatenate()
35  : portal1()
36  , portal2()
37  {
38  }
39 
42  ArrayPortalConcatenate(const PortalType1& p1, const PortalType2& p2)
43  : portal1(p1)
44  , portal2(p2)
45  {
46  }
47 
48  // Copy constructor
50  template <typename OtherP1, typename OtherP2>
51  VTKM_EXEC_CONT ArrayPortalConcatenate(const ArrayPortalConcatenate<OtherP1, OtherP2>& src)
52  : portal1(src.GetPortal1())
53  , portal2(src.GetPortal2())
54  {
55  }
56 
58  vtkm::Id GetNumberOfValues() const
59  {
60  return this->portal1.GetNumberOfValues() + this->portal2.GetNumberOfValues();
61  }
62 
65  ValueType Get(vtkm::Id index) const
66  {
67  if (index < this->portal1.GetNumberOfValues())
68  {
69  return this->portal1.Get(index);
70  }
71  else
72  {
73  return this->portal2.Get(index - this->portal1.GetNumberOfValues());
74  }
75  }
76 
78  template <typename Writable_ = Writable,
79  typename = typename std::enable_if<Writable_::value>::type>
80  VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const
81  {
82  if (index < this->portal1.GetNumberOfValues())
83  {
84  this->portal1.Set(index, value);
85  }
86  else
87  {
88  this->portal2.Set(index - this->portal1.GetNumberOfValues(), value);
89  }
90  }
91 
93  const PortalType1& GetPortal1() const { return this->portal1; }
94 
96  const PortalType2& GetPortal2() const { return this->portal2; }
97 
98 private:
99  PortalType1 portal1;
100  PortalType2 portal2;
101 }; // class ArrayPortalConcatenate
102 
103 }
104 } // namespace vtkm::internal
105 
106 namespace vtkm
107 {
108 namespace cont
109 {
110 
111 template <typename StorageTag1, typename StorageTag2>
113 {
114 };
115 
116 namespace internal
117 {
118 
119 template <typename T, typename ST1, typename ST2>
120 class Storage<T, StorageTagConcatenate<ST1, ST2>>
121 {
122  using SourceStorage1 = vtkm::cont::internal::Storage<T, ST1>;
123  using SourceStorage2 = vtkm::cont::internal::Storage<T, ST2>;
124 
125  using ArrayHandleType1 = vtkm::cont::ArrayHandle<T, ST1>;
126  using ArrayHandleType2 = vtkm::cont::ArrayHandle<T, ST2>;
127 
128  struct Info
129  {
130  std::size_t NumBuffers1;
131  std::size_t NumBuffers2;
132  };
133 
134  VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> Buffers1(
135  const std::vector<vtkm::cont::internal::Buffer>& buffers)
136  {
137  Info info = buffers[0].GetMetaData<Info>();
138  return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1,
139  buffers.begin() + 1 + info.NumBuffers1);
140  }
141 
142  VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> Buffers2(
143  const std::vector<vtkm::cont::internal::Buffer>& buffers)
144  {
145  Info info = buffers[0].GetMetaData<Info>();
146  return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1 + info.NumBuffers1,
147  buffers.end());
148  }
149 
150 public:
152 
153  using ReadPortalType =
154  vtkm::internal::ArrayPortalConcatenate<typename SourceStorage1::ReadPortalType,
155  typename SourceStorage2::ReadPortalType>;
156  using WritePortalType =
157  vtkm::internal::ArrayPortalConcatenate<typename SourceStorage1::WritePortalType,
158  typename SourceStorage2::WritePortalType>;
159 
160  VTKM_CONT static vtkm::IdComponent GetNumberOfComponentsFlat(
161  const std::vector<vtkm::cont::internal::Buffer>& buffers)
162  {
163  vtkm::IdComponent components1 = SourceStorage1::GetNumberOfComponentsFlat(Buffers1(buffers));
164  vtkm::IdComponent components2 = SourceStorage2::GetNumberOfComponentsFlat(Buffers2(buffers));
165  if (components1 == components2)
166  {
167  return components1;
168  }
169  else
170  {
171  // Inconsistent component size.
172  return 0;
173  }
174  }
175 
176  VTKM_CONT static vtkm::Id GetNumberOfValues(
177  const std::vector<vtkm::cont::internal::Buffer>& buffers)
178  {
179  return (SourceStorage1::GetNumberOfValues(Buffers1(buffers)) +
180  SourceStorage2::GetNumberOfValues(Buffers2(buffers)));
181  }
182 
183  VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
184  const T& fillValue,
185  vtkm::Id startIndex,
186  vtkm::Id endIndex,
187  vtkm::cont::Token& token)
188  {
189  vtkm::Id size1 = SourceStorage1::GetNumberOfValues(Buffers1(buffers));
190  if ((startIndex < size1) && (endIndex <= size1))
191  {
192  SourceStorage1::Fill(Buffers1(buffers), fillValue, startIndex, endIndex, token);
193  }
194  else if (startIndex < size1) // && (endIndex > size1)
195  {
196  SourceStorage1::Fill(Buffers1(buffers), fillValue, startIndex, size1, token);
197  SourceStorage2::Fill(Buffers2(buffers), fillValue, 0, endIndex - size1, token);
198  }
199  else // startIndex >= size1
200  {
201  SourceStorage2::Fill(
202  Buffers2(buffers), fillValue, startIndex - size1, endIndex - size1, token);
203  }
204  }
205 
206  VTKM_CONT static ReadPortalType CreateReadPortal(
207  const std::vector<vtkm::cont::internal::Buffer>& buffers,
209  vtkm::cont::Token& token)
210  {
211  return ReadPortalType(SourceStorage1::CreateReadPortal(Buffers1(buffers), device, token),
212  SourceStorage2::CreateReadPortal(Buffers2(buffers), device, token));
213  }
214 
215  VTKM_CONT static WritePortalType CreateWritePortal(
216  const std::vector<vtkm::cont::internal::Buffer>& buffers,
218  vtkm::cont::Token& token)
219  {
220  return WritePortalType(SourceStorage1::CreateWritePortal(Buffers1(buffers), device, token),
221  SourceStorage2::CreateWritePortal(Buffers2(buffers), device, token));
222  }
223 
224  VTKM_CONT static auto CreateBuffers(const ArrayHandleType1& array1 = ArrayHandleType1{},
225  const ArrayHandleType2& array2 = ArrayHandleType2{})
226  -> decltype(vtkm::cont::internal::CreateBuffers())
227  {
228  Info info;
229  info.NumBuffers1 = array1.GetBuffers().size();
230  info.NumBuffers2 = array2.GetBuffers().size();
231  return vtkm::cont::internal::CreateBuffers(info, array1, array2);
232  }
233 
234  VTKM_CONT static const ArrayHandleType1 GetArray1(
235  const std::vector<vtkm::cont::internal::Buffer>& buffers)
236  {
237  return ArrayHandleType1(Buffers1(buffers));
238  }
239 
240  VTKM_CONT static const ArrayHandleType2 GetArray2(
241  const std::vector<vtkm::cont::internal::Buffer>& buffers)
242  {
243  return ArrayHandleType2(Buffers2(buffers));
244  }
245 }; // class Storage
246 
247 }
248 }
249 } // namespace vtkm::cont::internal
250 
251 namespace vtkm
252 {
253 namespace cont
254 {
255 
256 template <typename ArrayHandleType1, typename ArrayHandleType2>
258  : public vtkm::cont::ArrayHandle<typename ArrayHandleType1::ValueType,
259  StorageTagConcatenate<typename ArrayHandleType1::StorageTag,
260  typename ArrayHandleType2::StorageTag>>
261 {
262 public:
266  (vtkm::cont::ArrayHandle<typename ArrayHandleType1::ValueType,
267  StorageTagConcatenate<typename ArrayHandleType1::StorageTag,
268  typename ArrayHandleType2::StorageTag>>));
269 
270  VTKM_CONT
271  ArrayHandleConcatenate(const ArrayHandleType1& array1, const ArrayHandleType2& array2)
272  : Superclass(StorageType::CreateBuffers(array1, array2))
273  {
274  }
275 };
276 
277 template <typename ArrayHandleType1, typename ArrayHandleType2>
279  const ArrayHandleType1& array1,
280  const ArrayHandleType2& array2)
281 {
283 }
284 }
285 } // namespace vtkm::cont
286 
287 //=============================================================================
288 // Specializations of serialization related classes
290 namespace vtkm
291 {
292 namespace cont
293 {
294 
295 template <typename AH1, typename AH2>
296 struct SerializableTypeString<vtkm::cont::ArrayHandleConcatenate<AH1, AH2>>
297 {
298  static VTKM_CONT const std::string& Get()
299  {
300  static std::string name = "AH_Concatenate<" + SerializableTypeString<AH1>::Get() + "," +
302  return name;
303  }
304 };
305 
306 template <typename T, typename ST1, typename ST2>
307 struct SerializableTypeString<
308  vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagConcatenate<ST1, ST2>>>
309  : SerializableTypeString<vtkm::cont::ArrayHandleConcatenate<vtkm::cont::ArrayHandle<T, ST1>,
310  vtkm::cont::ArrayHandle<T, ST2>>>
311 {
312 };
313 }
314 } // vtkm::cont
315 
316 namespace mangled_diy_namespace
317 {
318 
319 template <typename AH1, typename AH2>
320 struct Serialization<vtkm::cont::ArrayHandleConcatenate<AH1, AH2>>
321 {
322 private:
325 
326 public:
327  static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
328  {
329  auto storage = obj.GetStorage();
330  vtkmdiy::save(bb, storage.GetArray1());
331  vtkmdiy::save(bb, storage.GetArray2());
332  }
333 
334  static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj)
335  {
336  AH1 array1;
337  AH2 array2;
338 
339  vtkmdiy::load(bb, array1);
340  vtkmdiy::load(bb, array2);
341 
342  obj = vtkm::cont::make_ArrayHandleConcatenate(array1, array2);
343  }
344 };
345 
346 template <typename T, typename ST1, typename ST2>
347 struct Serialization<vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagConcatenate<ST1, ST2>>>
348  : Serialization<vtkm::cont::ArrayHandleConcatenate<vtkm::cont::ArrayHandle<T, ST1>,
349  vtkm::cont::ArrayHandle<T, ST2>>>
350 {
351 };
352 
353 } // diy
355 
356 #endif //vtk_m_cont_ArrayHandleConcatenate_h
vtkm::cont::ArrayHandle
Manages an array-worth of data.
Definition: ArrayHandle.h:300
ArrayHandle.h
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::ArrayHandleConcatenate
Definition: ArrayHandleConcatenate.h:257
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_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::ArrayHandleConcatenate::StorageType
typename Superclass::StorageType StorageType
Definition: ArrayHandleConcatenate.h:268
vtkm::cont::ArrayHandleConcatenate::ArrayHandleConcatenate
ArrayHandleConcatenate(const ArrayHandleType1 &array1, const ArrayHandleType2 &array2)
Definition: ArrayHandleConcatenate.h:271
VTKM_STORAGE_NO_RESIZE
#define VTKM_STORAGE_NO_RESIZE
Definition: Storage.h:185
mangled_diy_namespace
Definition: Particle.h:351
vtkm::cont::ArrayHandleConcatenate::Superclass
typename vtkm::cont::detail::GetTypeInParentheses< void(vtkm::cont::ArrayHandle< typename ArrayHandleType1::ValueType, StorageTagConcatenate< typename ArrayHandleType1::StorageTag, typename ArrayHandleType2::StorageTag > >) >::type Superclass
Definition: ArrayHandleConcatenate.h:268
vtkm::cont::Token
A token to hold the scope of an ArrayHandle or other object.
Definition: Token.h:35
vtkm::cont::StorageTagConcatenate
Definition: ArrayHandleConcatenate.h:112
vtkm::cont::LogLevel::Info
@ Info
Information messages (detected hardware, etc) and temporary debugging output.
vtkm::cont::make_ArrayHandleConcatenate
ArrayHandleConcatenate< ArrayHandleType1, ArrayHandleType2 > make_ArrayHandleConcatenate(const ArrayHandleType1 &array1, const ArrayHandleType2 &array2)
Definition: ArrayHandleConcatenate.h:278
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::DeviceAdapterId
An object used to specify a device.
Definition: DeviceAdapterTag.h:58
StaticAssert.h
VTKM_ALWAYS_EXPORT
#define VTKM_ALWAYS_EXPORT
Definition: ExportMacros.h:89
VTKM_SUPPRESS_EXEC_WARNINGS
#define VTKM_SUPPRESS_EXEC_WARNINGS
Definition: ExportMacros.h:53