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