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