Viskores  1.0
ArrayHandleRecombineVec.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_ArrayHandleRecombineVec_h
19 #define viskores_cont_ArrayHandleRecombineVec_h
20 
26 
28 
30 
31 namespace viskores
32 {
33 namespace internal
34 {
35 
36 // Forward declaration
37 template <typename SourcePortalType>
38 class ArrayPortalRecombineVec;
39 
40 template <typename PortalType>
41 class RecombineVec
42 {
45 
47  friend viskores::internal::ArrayPortalRecombineVec<PortalType>;
49 
50 public:
51  using ComponentType = typename std::remove_const<typename PortalType::ValueType>::type;
52 
53  RecombineVec(const RecombineVec&) = default;
54 
55  VISKORES_EXEC_CONT RecombineVec(const viskores::VecCConst<PortalType>& portals,
56  viskores::Id index)
57  : Portals(portals)
58  , Index(index)
59  {
60  }
61 
62  VISKORES_EXEC_CONT viskores::IdComponent GetNumberOfComponents() const
63  {
64  return this->Portals.GetNumberOfComponents();
65  }
66 
68  viskores::internal::ArrayPortalValueReference<PortalType> operator[](
69  viskores::IdComponent cIndex) const
70  {
71  return viskores::internal::ArrayPortalValueReference<PortalType>(this->Portals[cIndex],
72  this->Index);
73  }
74 
75  template <typename T, viskores::IdComponent DestSize>
76  VISKORES_EXEC_CONT void CopyInto(viskores::Vec<T, DestSize>& dest) const
77  {
78  viskores::IdComponent numComponents = viskores::Min(DestSize, this->GetNumberOfComponents());
79  for (viskores::IdComponent cIndex = 0; cIndex < numComponents; ++cIndex)
80  {
81  dest[cIndex] = this->Portals[cIndex].Get(this->Index);
82  }
83  // Clear out any components not held by this dynamic Vec-like
84  for (viskores::IdComponent cIndex = numComponents; cIndex < DestSize; ++cIndex)
85  {
87  }
88  }
89 
90  VISKORES_EXEC_CONT viskores::Id GetIndex() const { return this->Index; }
91 
92  VISKORES_EXEC_CONT RecombineVec& operator=(const RecombineVec& src)
93  {
94  if ((&this->Portals[0] != &src.Portals[0]) || (this->Index != src.Index))
95  {
96  this->DoCopy(src);
97  }
98  else
99  {
100  // Copying to myself. Do not need to do anything.
101  }
102  return *this;
103  }
104 
105  template <typename T>
106  VISKORES_EXEC_CONT RecombineVec& operator=(const T& src)
107  {
108  this->DoCopy(src);
109  return *this;
110  }
111 
112  VISKORES_EXEC_CONT operator ComponentType() const { return this->Portals[0].Get(this->Index); }
113 
114  template <viskores::IdComponent N>
116  {
118  this->CopyInto(result);
119  return result;
120  }
121 
122  template <typename T>
123  VISKORES_EXEC_CONT RecombineVec& operator+=(const T& src)
124  {
125  using VTraits = viskores::VecTraits<T>;
126  VISKORES_ASSERT(this->GetNumberOfComponents() == VTraits::GetNumberOfComponents(src));
127  for (viskores::IdComponent cIndex = 0; cIndex < this->GetNumberOfComponents(); ++cIndex)
128  {
129  (*this)[cIndex] += VTraits::GetComponent(src, cIndex);
130  }
131  return *this;
132  }
133  template <typename T>
134  VISKORES_EXEC_CONT RecombineVec& operator-=(const T& src)
135  {
136  using VTraits = viskores::VecTraits<T>;
137  VISKORES_ASSERT(this->GetNumberOfComponents() == VTraits::GetNumberOfComponents(src));
138  for (viskores::IdComponent cIndex = 0; cIndex < this->GetNumberOfComponents(); ++cIndex)
139  {
140  (*this)[cIndex] -= VTraits::GetComponent(src, cIndex);
141  }
142  return *this;
143  }
144  template <typename T>
145  VISKORES_EXEC_CONT RecombineVec& operator*=(const T& src)
146  {
147  using VTraits = viskores::VecTraits<T>;
148  VISKORES_ASSERT(this->GetNumberOfComponents() == VTraits::GetNumberOfComponents(src));
149  for (viskores::IdComponent cIndex = 0; cIndex < this->GetNumberOfComponents(); ++cIndex)
150  {
151  (*this)[cIndex] *= VTraits::GetComponent(src, cIndex);
152  }
153  return *this;
154  }
155  template <typename T>
156  VISKORES_EXEC_CONT RecombineVec& operator/=(const T& src)
157  {
158  using VTraits = viskores::VecTraits<T>;
159  VISKORES_ASSERT(this->GetNumberOfComponents() == VTraits::GetNumberOfComponents(src));
160  for (viskores::IdComponent cIndex = 0; cIndex < this->GetNumberOfComponents(); ++cIndex)
161  {
162  (*this)[cIndex] /= VTraits::GetComponent(src, cIndex);
163  }
164  return *this;
165  }
166  template <typename T>
167  VISKORES_EXEC_CONT RecombineVec& operator%=(const T& src)
168  {
169  using VTraits = viskores::VecTraits<T>;
170  VISKORES_ASSERT(this->GetNumberOfComponents() == VTraits::GetNumberOfComponents(src));
171  for (viskores::IdComponent cIndex = 0; cIndex < this->GetNumberOfComponents(); ++cIndex)
172  {
173  (*this)[cIndex] %= VTraits::GetComponent(src, cIndex);
174  }
175  return *this;
176  }
177  template <typename T>
178  VISKORES_EXEC_CONT RecombineVec& operator&=(const T& src)
179  {
180  using VTraits = viskores::VecTraits<T>;
181  VISKORES_ASSERT(this->GetNumberOfComponents() == VTraits::GetNumberOfComponents(src));
182  for (viskores::IdComponent cIndex = 0; cIndex < this->GetNumberOfComponents(); ++cIndex)
183  {
184  (*this)[cIndex] &= VTraits::GetComponent(src, cIndex);
185  }
186  return *this;
187  }
188  template <typename T>
189  VISKORES_EXEC_CONT RecombineVec& operator|=(const T& src)
190  {
191  using VTraits = viskores::VecTraits<T>;
192  VISKORES_ASSERT(this->GetNumberOfComponents() == VTraits::GetNumberOfComponents(src));
193  for (viskores::IdComponent cIndex = 0; cIndex < this->GetNumberOfComponents(); ++cIndex)
194  {
195  (*this)[cIndex] |= VTraits::GetComponent(src, cIndex);
196  }
197  return *this;
198  }
199  template <typename T>
200  VISKORES_EXEC_CONT RecombineVec& operator^=(const T& src)
201  {
202  using VTraits = viskores::VecTraits<T>;
203  VISKORES_ASSERT(this->GetNumberOfComponents() == VTraits::GetNumberOfComponents(src));
204  for (viskores::IdComponent cIndex = 0; cIndex < this->GetNumberOfComponents(); ++cIndex)
205  {
206  (*this)[cIndex] ^= VTraits::GetComponent(src, cIndex);
207  }
208  return *this;
209  }
210  template <typename T>
211  VISKORES_EXEC_CONT RecombineVec& operator>>=(const T& src)
212  {
213  using VTraits = viskores::VecTraits<T>;
214  VISKORES_ASSERT(this->GetNumberOfComponents() == VTraits::GetNumberOfComponents(src));
215  for (viskores::IdComponent cIndex = 0; cIndex < this->GetNumberOfComponents(); ++cIndex)
216  {
217  (*this)[cIndex] >>= VTraits::GetComponent(src, cIndex);
218  }
219  return *this;
220  }
221  template <typename T>
222  VISKORES_EXEC_CONT RecombineVec& operator<<=(const T& src)
223  {
224  using VTraits = viskores::VecTraits<T>;
225  VISKORES_ASSERT(this->GetNumberOfComponents() == VTraits::GetNumberOfComponents(src));
226  for (viskores::IdComponent cIndex = 0; cIndex < this->GetNumberOfComponents(); ++cIndex)
227  {
228  (*this)[cIndex] <<= VTraits::GetComponent(src, cIndex);
229  }
230  return *this;
231  }
232 
233 private:
234  template <typename T>
235  VISKORES_EXEC_CONT void DoCopy(const T& src)
236  {
237  using VTraits = viskores::VecTraits<T>;
238  viskores::IdComponent numComponents = VTraits::GetNumberOfComponents(src);
239  if (numComponents > 1)
240  {
241  if (numComponents > this->GetNumberOfComponents())
242  {
243  numComponents = this->GetNumberOfComponents();
244  }
245  for (viskores::IdComponent cIndex = 0; cIndex < numComponents; ++cIndex)
246  {
247  this->Portals[cIndex].Set(this->Index,
248  static_cast<ComponentType>(VTraits::GetComponent(src, cIndex)));
249  }
250  }
251  else
252  {
253  // Special case when copying from a scalar
254  for (viskores::IdComponent cIndex = 0; cIndex < this->GetNumberOfComponents(); ++cIndex)
255  {
256  this->Portals[cIndex].Set(this->Index,
257  static_cast<ComponentType>(VTraits::GetComponent(src, 0)));
258  }
259  }
260  }
261 };
262 
263 } // namespace internal
264 
265 template <typename PortalType>
266 struct TypeTraits<viskores::internal::RecombineVec<PortalType>>
267 {
268 private:
269  using VecType = viskores::internal::RecombineVec<PortalType>;
270  using ComponentType = typename VecType::ComponentType;
271 
272 public:
275 
276  VISKORES_EXEC_CONT static viskores::internal::RecombineVec<PortalType> ZeroInitialization()
277  {
278  // Return a vec-like of size 0.
279  return viskores::internal::RecombineVec<PortalType>{};
280  }
281 };
282 
283 template <typename PortalType>
284 struct VecTraits<viskores::internal::RecombineVec<PortalType>>
285 {
286  using VecType = viskores::internal::RecombineVec<PortalType>;
287  using ComponentType = typename VecType::ComponentType;
291 
293  {
294  return vector.GetNumberOfComponents();
295  }
296 
298  static ComponentType GetComponent(const VecType& vector, viskores::IdComponent componentIndex)
299  {
300  return vector[componentIndex];
301  }
302 
303  VISKORES_EXEC_CONT static void SetComponent(const VecType& vector,
304  viskores::IdComponent componentIndex,
305  const ComponentType& component)
306  {
307  vector[componentIndex] = component;
308  }
309 
310  template <viskores::IdComponent destSize>
311  VISKORES_EXEC_CONT static void CopyInto(const VecType& src,
313  {
314  src.CopyInto(dest);
315  }
316 };
317 
318 namespace internal
319 {
320 
321 template <typename SourcePortalType>
322 class ArrayPortalRecombineVec
323 {
324  // Note that this ArrayPortal has a pointer to a C array of other portals. We need to
325  // make sure that the pointer is valid on the device we are using it on. See the
326  // CreateReadPortal and CreateWritePortal in the Storage below to see how that is
327  // managed.
328  const SourcePortalType* Portals;
329  viskores::IdComponent NumberOfComponents;
330 
331 public:
332  using ValueType = viskores::internal::RecombineVec<SourcePortalType>;
333 
334  ArrayPortalRecombineVec() = default;
335  ArrayPortalRecombineVec(const SourcePortalType* portals, viskores::IdComponent numComponents)
336  : Portals(portals)
337  , NumberOfComponents(numComponents)
338  {
339  }
340 
341  VISKORES_EXEC_CONT viskores::Id GetNumberOfValues() const
342  {
343  return this->Portals[0].GetNumberOfValues();
344  }
345 
346  VISKORES_EXEC_CONT ValueType Get(viskores::Id index) const
347  {
348  return ValueType({ this->Portals, this->NumberOfComponents }, index);
349  }
350 
351  VISKORES_EXEC_CONT void Set(viskores::Id index, const ValueType& value) const
352  {
353  if ((value.GetIndex() == index) && (value.Portals.GetPointer() == this->Portals))
354  {
355  // The ValueType is actually a reference back to the portals. If this reference is
356  // actually pointing back to the same index, we don't need to do anything.
357  }
358  else
359  {
360  this->DoCopy(index, value);
361  }
362  }
363 
364  template <typename T>
365  VISKORES_EXEC_CONT void Set(viskores::Id index, const T& value) const
366  {
367  this->DoCopy(index, value);
368  }
369 
370 private:
371  template <typename T>
372  VISKORES_EXEC_CONT void DoCopy(viskores::Id index, const T& value) const
373  {
374  using Traits = viskores::VecTraits<T>;
375  VISKORES_ASSERT(Traits::GetNumberOfComponents(value) == this->NumberOfComponents);
376  for (viskores::IdComponent cIndex = 0; cIndex < this->NumberOfComponents; ++cIndex)
377  {
378  this->Portals[cIndex].Set(index, Traits::GetComponent(value, cIndex));
379  }
380  }
381 };
382 
383 }
384 } // namespace viskores::internal
385 
386 namespace viskores
387 {
388 namespace cont
389 {
390 
391 namespace internal
392 {
393 
394 struct StorageTagRecombineVec
395 {
396 };
397 
398 namespace detail
399 {
400 
401 struct RecombineVecMetaData
402 {
403  mutable std::vector<viskores::cont::internal::Buffer> PortalBuffers;
404  std::vector<std::size_t> ArrayBufferOffsets;
405 
406  RecombineVecMetaData() = default;
407 
408  RecombineVecMetaData(const RecombineVecMetaData& src) { *this = src; }
409 
410  RecombineVecMetaData& operator=(const RecombineVecMetaData& src)
411  {
412  this->ArrayBufferOffsets = src.ArrayBufferOffsets;
413 
414  this->PortalBuffers.clear();
415  // Intentionally not copying portals. Portals will be recreated from proper array when requsted.
416 
417  return *this;
418  }
419 };
420 
421 template <typename T>
422 using RecombinedPortalType = viskores::internal::ArrayPortalMultiplexer<
423  typename viskores::cont::internal::Storage<T, viskores::cont::StorageTagStride>::ReadPortalType,
424  typename viskores::cont::internal::Storage<T, viskores::cont::StorageTagStride>::WritePortalType>;
425 
426 template <typename T>
427 using RecombinedValueType = viskores::internal::RecombineVec<RecombinedPortalType<T>>;
428 
429 } // namespace detail
430 
431 template <typename ReadWritePortal>
432 class Storage<viskores::internal::RecombineVec<ReadWritePortal>,
433  viskores::cont::internal::StorageTagRecombineVec>
434 {
435  using ComponentType = typename ReadWritePortal::ValueType;
436  using SourceStorage =
437  viskores::cont::internal::Storage<ComponentType, viskores::cont::StorageTagStride>;
439 
441  (std::is_same<ReadWritePortal, detail::RecombinedPortalType<ComponentType>>::value));
442 
443  VISKORES_CONT static std::vector<viskores::cont::internal::Buffer> BuffersForComponent(
444  const std::vector<viskores::cont::internal::Buffer>& buffers,
445  viskores::IdComponent componentIndex)
446  {
447  auto& metaData = buffers[0].GetMetaData<detail::RecombineVecMetaData>();
448  std::size_t index = static_cast<std::size_t>(componentIndex);
449  return std::vector<viskores::cont::internal::Buffer>(
450  buffers.begin() + metaData.ArrayBufferOffsets[index],
451  buffers.begin() + metaData.ArrayBufferOffsets[index + 1]);
452  }
453 
454 public:
455  using ReadPortalType = viskores::internal::ArrayPortalRecombineVec<ReadWritePortal>;
456  using WritePortalType = viskores::internal::ArrayPortalRecombineVec<ReadWritePortal>;
457 
458  VISKORES_CONT static viskores::IdComponent GetNumberOfComponents(
459  const std::vector<viskores::cont::internal::Buffer>& buffers)
460  {
461  return static_cast<viskores::IdComponent>(
462  buffers[0].GetMetaData<detail::RecombineVecMetaData>().ArrayBufferOffsets.size() - 1);
463  }
464 
465  VISKORES_CONT static viskores::IdComponent GetNumberOfComponentsFlat(
466  const std::vector<viskores::cont::internal::Buffer>& buffers)
467  {
468  viskores::IdComponent numComponents = GetNumberOfComponents(buffers);
469  viskores::IdComponent numSubComponents =
470  SourceStorage::GetNumberOfComponentsFlat(BuffersForComponent(buffers, 0));
471  return numComponents * numSubComponents;
472  }
473 
474  VISKORES_CONT static viskores::Id GetNumberOfValues(
475  const std::vector<viskores::cont::internal::Buffer>& buffers)
476  {
477  return SourceStorage::GetNumberOfValues(BuffersForComponent(buffers, 0));
478  }
479 
480  VISKORES_CONT static void ResizeBuffers(
481  viskores::Id numValues,
482  const std::vector<viskores::cont::internal::Buffer>& buffers,
483  viskores::CopyFlag preserve,
484  viskores::cont::Token& token)
485  {
486  viskores::IdComponent numComponents = GetNumberOfComponents(buffers);
487  for (viskores::IdComponent component = 0; component < numComponents; ++component)
488  {
489  SourceStorage::ResizeBuffers(
490  numValues, BuffersForComponent(buffers, component), preserve, token);
491  }
492  }
493 
494  VISKORES_CONT static void Fill(const std::vector<viskores::cont::internal::Buffer>&,
495  const viskores::internal::RecombineVec<ReadWritePortal>&,
496  viskores::Id,
497  viskores::Id,
499  {
500  throw viskores::cont::ErrorBadType("Fill not supported for ArrayHandleRecombineVec.");
501  }
502 
503  VISKORES_CONT static ReadPortalType CreateReadPortal(
504  const std::vector<viskores::cont::internal::Buffer>& buffers,
506  viskores::cont::Token& token)
507  {
508  viskores::IdComponent numComponents = GetNumberOfComponents(buffers);
509 
510  // The array portal needs a runtime-allocated array of portals for each component.
511  // We use the viskores::cont::internal::Buffer object to allow us to allocate memory on the
512  // device and copy data there.
513  viskores::cont::internal::Buffer portalBuffer;
514  portalBuffer.SetNumberOfBytes(static_cast<viskores::BufferSizeType>(sizeof(ReadWritePortal)) *
515  numComponents,
517  token);
518 
519  // Save a reference of the portal in our metadata.
520  // Note that the buffer we create is going to hang around until the ArrayHandle gets
521  // destroyed. The buffers are small and should not be a problem unless you create a
522  // lot of portals.
523  buffers[0].GetMetaData<detail::RecombineVecMetaData>().PortalBuffers.push_back(portalBuffer);
524 
525  // Get the control-side memory and fill it with the execution-side portals
526  ReadWritePortal* portals =
527  reinterpret_cast<ReadWritePortal*>(portalBuffer.WritePointerHost(token));
528  for (viskores::IdComponent cIndex = 0; cIndex < numComponents; ++cIndex)
529  {
530  portals[cIndex] = ReadWritePortal(
531  SourceStorage::CreateReadPortal(BuffersForComponent(buffers, cIndex), device, token));
532  }
533 
534  // Now get the execution-side memory (portals will be copied as necessary) and create
535  // the portal for the appropriate device
536  return ReadPortalType(
537  reinterpret_cast<const ReadWritePortal*>(portalBuffer.ReadPointerDevice(device, token)),
538  numComponents);
539  }
540 
541  VISKORES_CONT static WritePortalType CreateWritePortal(
542  const std::vector<viskores::cont::internal::Buffer>& buffers,
544  viskores::cont::Token& token)
545  {
546  viskores::IdComponent numComponents = GetNumberOfComponents(buffers);
547 
548  // The array portal needs a runtime-allocated array of portals for each component.
549  // We use the viskores::cont::internal::Buffer object to allow us to allocate memory on the
550  // device and copy data there.
551  viskores::cont::internal::Buffer portalBuffer;
552  portalBuffer.SetNumberOfBytes(static_cast<viskores::BufferSizeType>(sizeof(ReadWritePortal)) *
553  numComponents,
555  token);
556 
557  // Save a reference of the portal in our metadata.
558  // Note that the buffer we create is going to hang around until the ArrayHandle gets
559  // destroyed. The buffers are small and should not be a problem unless you create a
560  // lot of portals.
561  buffers[0].GetMetaData<detail::RecombineVecMetaData>().PortalBuffers.push_back(portalBuffer);
562 
563  // Get the control-side memory and fill it with the execution-side portals
564  ReadWritePortal* portals =
565  reinterpret_cast<ReadWritePortal*>(portalBuffer.WritePointerHost(token));
566  for (viskores::IdComponent cIndex = 0; cIndex < numComponents; ++cIndex)
567  {
568  portals[cIndex] = ReadWritePortal(
569  SourceStorage::CreateWritePortal(BuffersForComponent(buffers, cIndex), device, token));
570  }
571 
572  // Now get the execution-side memory (portals will be copied as necessary) and create
573  // the portal for the appropriate device
574  return WritePortalType(
575  reinterpret_cast<const ReadWritePortal*>(portalBuffer.ReadPointerDevice(device, token)),
576  numComponents);
577  }
578 
579  VISKORES_CONT static ArrayType ArrayForComponent(
580  const std::vector<viskores::cont::internal::Buffer>& buffers,
581  viskores::IdComponent componentIndex)
582  {
583  return ArrayType(BuffersForComponent(buffers, componentIndex));
584  }
585 
586  VISKORES_CONT static std::vector<viskores::cont::internal::Buffer> CreateBuffers()
587  {
588  detail::RecombineVecMetaData metaData;
589  metaData.ArrayBufferOffsets.push_back(1);
590  return viskores::cont::internal::CreateBuffers(metaData);
591  }
592 
593  VISKORES_CONT static void AppendComponent(std::vector<viskores::cont::internal::Buffer>& buffers,
594  const ArrayType& array)
595  {
596  // Add buffers of new array to our list of buffers.
597  buffers.insert(buffers.end(), array.GetBuffers().begin(), array.GetBuffers().end());
598  // Update metadata for new offset to end.
599  buffers[0].GetMetaData<detail::RecombineVecMetaData>().ArrayBufferOffsets.push_back(
600  buffers.size());
601  }
602 };
603 
604 } // namespace internal
605 
625 template <typename ComponentType>
627  : public viskores::cont::ArrayHandle<internal::detail::RecombinedValueType<ComponentType>,
628  viskores::cont::internal::StorageTagRecombineVec>
629 {
630 public:
634  (viskores::cont::ArrayHandle<internal::detail::RecombinedValueType<ComponentType>,
635  viskores::cont::internal::StorageTagRecombineVec>));
636 
645  {
646  return StorageType::GetNumberOfComponents(this->GetBuffers());
647  }
648 
655  viskores::IdComponent componentIndex) const
656  {
657  return StorageType::ArrayForComponent(this->GetBuffers(), componentIndex);
658  }
659 
666  {
667  std::vector<viskores::cont::internal::Buffer> buffers = this->GetBuffers();
668  StorageType::AppendComponent(buffers, array);
669  this->SetBuffers(std::move(buffers));
670  }
671 };
672 
673 namespace internal
674 {
675 
676 template <>
677 struct ArrayExtractComponentImpl<viskores::cont::internal::StorageTagRecombineVec>
678 {
679  template <typename RecombineVec>
682  operator()(
683  const viskores::cont::ArrayHandle<RecombineVec,
684  viskores::cont::internal::StorageTagRecombineVec>& src,
685  viskores::IdComponent componentIndex,
686  viskores::CopyFlag allowCopy) const
687  {
688  using ComponentType = typename RecombineVec::ComponentType;
690  constexpr viskores::IdComponent subComponents =
693  array.GetComponentArray(componentIndex / subComponents),
694  componentIndex % subComponents,
695  allowCopy);
696  }
697 };
698 
699 //-------------------------------------------------------------------------------------------------
700 template <typename S>
701 struct ArrayRangeComputeImpl;
702 
703 template <typename S>
704 struct ArrayRangeComputeMagnitudeImpl;
705 
706 template <typename T, typename S>
707 inline viskores::cont::ArrayHandle<viskores::Range> ArrayRangeComputeImplCaller(
710  bool computeFiniteRange,
712 {
713  return viskores::cont::internal::ArrayRangeComputeImpl<S>{}(
714  input, maskArray, computeFiniteRange, device);
715 }
716 
717 template <typename T, typename S>
718 inline viskores::Range ArrayRangeComputeMagnitudeImplCaller(
721  bool computeFiniteRange,
723 {
724  return viskores::cont::internal::ArrayRangeComputeMagnitudeImpl<S>{}(
725  input, maskArray, computeFiniteRange, device);
726 }
727 
728 template <>
729 struct VISKORES_CONT_EXPORT ArrayRangeComputeImpl<viskores::cont::internal::StorageTagRecombineVec>
730 {
731  template <typename RecombineVecType>
733  const viskores::cont::ArrayHandle<RecombineVecType,
734  viskores::cont::internal::StorageTagRecombineVec>& input_,
736  bool computeFiniteRange,
737  viskores::cont::DeviceAdapterId device) const
738  {
739  auto input = static_cast<
741 
743  result.Allocate(input.GetNumberOfComponents());
744 
745  if (input.GetNumberOfValues() < 1)
746  {
747  result.Fill(viskores::Range{});
748  return result;
749  }
750 
751  auto resultPortal = result.WritePortal();
752  for (viskores::IdComponent i = 0; i < input.GetNumberOfComponents(); ++i)
753  {
754  auto rangeAH = ArrayRangeComputeImplCaller(
755  input.GetComponentArray(i), maskArray, computeFiniteRange, device);
756  resultPortal.Set(i, rangeAH.ReadPortal().Get(0));
757  }
758 
759  return result;
760  }
761 };
762 
763 template <typename ArrayHandleType>
764 struct ArrayValueIsNested;
765 
766 template <typename RecombineVecType>
767 struct ArrayValueIsNested<
768  viskores::cont::ArrayHandle<RecombineVecType, viskores::cont::internal::StorageTagRecombineVec>>
769 {
770  static constexpr bool Value = false;
771 };
772 
773 template <>
774 struct VISKORES_CONT_EXPORT
775  ArrayRangeComputeMagnitudeImpl<viskores::cont::internal::StorageTagRecombineVec>
776 {
777  template <typename RecombineVecType>
778  VISKORES_CONT viskores::Range operator()(
779  const viskores::cont::ArrayHandle<RecombineVecType,
780  viskores::cont::internal::StorageTagRecombineVec>& input_,
782  bool computeFiniteRange,
783  viskores::cont::DeviceAdapterId device) const
784  {
785  auto input = static_cast<
787 
788  if (input.GetNumberOfValues() < 1)
789  {
790  return viskores::Range{};
791  }
792  if (input.GetNumberOfComponents() == 1)
793  {
794  return ArrayRangeComputeMagnitudeImplCaller(
795  input.GetComponentArray(0), maskArray, computeFiniteRange, device);
796  }
797 
798  return ArrayRangeComputeMagnitudeGeneric(input_, maskArray, computeFiniteRange, device);
799  }
800 };
801 
802 } // namespace internal
803 
804 }
805 } // namespace viskores::cont
806 
807 #endif //viskores_cont_ArrayHandleRecombineVec_h
viskores::cont::ArrayHandleRecombineVec::GetComponentArray
viskores::cont::ArrayHandleStride< ComponentType > GetComponentArray(viskores::IdComponent componentIndex) const
Get the array storing the values for a particular component.
Definition: ArrayHandleRecombineVec.h:654
viskores::VecTraits::SetComponent
static void SetComponent(T &vector, viskores::IdComponent, ComponentType value)
Changes the value in a given component of the vector.
Definition: VecTraits.h:141
viskores::VecFlat
Treat a Vec or Vec-like object as a flat Vec.
Definition: VecFlat.h:240
ArrayExtractComponent.h
ArrayHandleStride.h
viskores::VecCConst
A const version of VecC.
Definition: Types.h:371
viskores::CopyFlag::Off
@ Off
viskores::VecCConst::GetNumberOfComponents
constexpr viskores::IdComponent GetNumberOfComponents() const
Definition: Types.h:1444
viskores::cont::ArrayHandle< internal::detail::RecombinedValueType< ComponentType >, viskores::cont::internal::StorageTagRecombineVec >::SetBuffers
void SetBuffers(const std::vector< viskores::cont::internal::Buffer > &buffers)
Definition: ArrayHandle.h:757
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::TypeTraits::ZeroInitialization
static T ZeroInitialization()
A static function that returns 0 (or the closest equivalent to it) for the given type.
Definition: TypeTraits.h:85
viskores::VecTraitsTagSizeVariable
A tag for vectors where the number of components are not determined until run time.
Definition: VecTraits.h:51
viskores::TypeTraits::NumericTag
viskores::TypeTraitsUnknownTag NumericTag
A tag to determine whether the type is integer or real.
Definition: TypeTraits.h:75
viskores::VecTraits::HasMultipleComponents
viskores::VecTraitsTagSingleComponent HasMultipleComponents
A tag specifying whether this vector has multiple components (i.e.
Definition: VecTraits.h:113
DeviceAdapterTag.h
ArrayHandleTransform.h
viskores::cont::ArrayHandle
Manages an array-worth of data.
Definition: ArrayHandle.h:313
viskores::VecTraitsTagMultipleComponents
A tag for vectors that are "true" vectors (i.e.
Definition: VecTraits.h:31
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
viskores::cont::ArrayHandleStride
An ArrayHandle that accesses a basic array with strides and offsets.
Definition: ArrayHandleStride.h:343
viskores::VecTraits::GetComponent
static const ComponentType & GetComponent(const T &vector, viskores::IdComponent)
Returns the value in a given component of the vector.
Definition: VecTraits.h:125
viskores::cont::ArrayExtractComponent
viskores::cont::ArrayHandleStride< typename viskores::VecTraits< T >::BaseComponentType > ArrayExtractComponent(const viskores::cont::ArrayHandle< T, S > &src, viskores::IdComponent componentIndex, viskores::CopyFlag allowCopy=viskores::CopyFlag::On)
Pulls a component out of an ArrayHandle.
Definition: ArrayExtractComponent.h:267
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::cont::ArrayHandleRecombineVec::AppendComponentArray
void AppendComponentArray(const viskores::cont::ArrayHandle< ComponentType, viskores::cont::StorageTagStride > &array)
Add a component array.
Definition: ArrayHandleRecombineVec.h:664
viskores::VecTraits::GetNumberOfComponents
static constexpr viskores::IdComponent GetNumberOfComponents(const T &)
Returns the number of components in the given vector.
Definition: VecTraits.h:102
viskores
Groups connected points that have the same field value.
Definition: Atomic.h:27
viskores::TypeTraitsUnknownTag
Tag used to identify types that aren't Real, Integer, Scalar or Vector.
Definition: TypeTraits.h:28
ArrayPortalValueReference.h
viskores::VecTraits
Traits that can be queried to treat any type as a Vec.
Definition: VecTraits.h:69
Index
int Index
Definition: ChooseCudaDevice.h:95
VISKORES_ASSERT
#define VISKORES_ASSERT(condition)
Definition: Assert.h:51
viskores::VecTraits::CopyInto
static void CopyInto(const T &src, viskores::Vec< ComponentType, destSize > &dest)
Copies the components in the given vector into a given Vec object.
Definition: VecTraits.h:176
viskores::BufferSizeType
viskores::Int64 BufferSizeType
Definition: DeviceAdapterMemoryManager.h:35
viskores::cont::DeviceAdapterId
An object used to specify a device.
Definition: DeviceAdapterTag.h:66
viskores::Range
Represent a continuous scalar range of values.
Definition: Range.h:39
viskores::cont::ArrayHandleRecombineVec::GetNumberOfComponents
viskores::IdComponent GetNumberOfComponents() const
Return the number of components in each value of the array.
Definition: ArrayHandleRecombineVec.h:644
ArrayHandleMultiplexer.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::VecTraits::ComponentType
T ComponentType
Type of the components in the vector.
Definition: VecTraits.h:79
viskores::cont::ArrayHandleRecombineVec
A grouping of ArrayHandleStrides into an ArrayHandle of viskores::Vecs.
Definition: ArrayHandleRecombineVec.h:626
viskores::VecTraits::BaseComponentType
T BaseComponentType
Base component type in the vector.
Definition: VecTraits.h:86
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::TypeTraits::DimensionalityTag
viskores::TypeTraitsUnknownTag DimensionalityTag
A tag to determine whether the type has multiple components.
Definition: TypeTraits.h:81
viskores::CopyFlag
CopyFlag
Identifier used to specify whether a function should deep copy data.
Definition: Flags.h:25
ArrayRangeComputeUtils.h
viskores::TypeTraitsVectorTag
Tag used to identify 1 dimensional types (vectors).
Definition: TypeTraits.h:59
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::VecTraits::IsSizeStatic
viskores::VecTraitsTagSizeStatic IsSizeStatic
A tag specifying whether the size of this vector is known at compile time.
Definition: VecTraits.h:121
viskores::cont::ArrayHandle< internal::detail::RecombinedValueType< ComponentType >, viskores::cont::internal::StorageTagRecombineVec >::GetBuffers
const std::vector< viskores::cont::internal::Buffer > & GetBuffers() const
Returns the internal Buffer structures that hold the data.
Definition: ArrayHandle.h:738
VISKORES_STATIC_ASSERT
#define VISKORES_STATIC_ASSERT(condition)
Definition: StaticAssert.h:24