VTK-m  2.1
ArrayCopy.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_ArrayCopy_h
11 #define vtk_m_cont_ArrayCopy_h
12 
20 
22 
24 
25 #include <vtkm/StaticAssert.h>
26 #include <vtkm/VecTraits.h>
27 
28 namespace vtkm
29 {
30 namespace cont
31 {
32 
33 namespace detail
34 {
35 
36 template <typename S>
37 struct ArrayCopyConcreteSrc;
38 
39 template <typename SrcIsArrayHandle>
40 inline void ArrayCopyImpl(const vtkm::cont::UnknownArrayHandle& source,
41  vtkm::cont::UnknownArrayHandle& destination,
42  SrcIsArrayHandle,
43  std::false_type)
44 {
45  destination.DeepCopyFrom(source);
46 }
47 template <typename SrcIsArrayHandle>
48 inline void ArrayCopyImpl(const vtkm::cont::UnknownArrayHandle& source,
49  const vtkm::cont::UnknownArrayHandle& destination,
50  SrcIsArrayHandle,
51  std::false_type)
52 {
53  destination.DeepCopyFrom(source);
54 }
55 
56 template <typename T, typename S>
57 void ArrayCopyImpl(const vtkm::cont::UnknownArrayHandle& source,
58  vtkm::cont::ArrayHandle<T, S>& destination,
59  std::false_type,
60  std::true_type)
61 {
62  using DestType = vtkm::cont::ArrayHandle<T, S>;
63  if (source.CanConvert<DestType>())
64  {
65  destination.DeepCopyFrom(source.AsArrayHandle<DestType>());
66  }
67  else
68  {
69  vtkm::cont::UnknownArrayHandle destWrapper(destination);
70  vtkm::cont::detail::ArrayCopyImpl(source, destWrapper, std::false_type{}, std::false_type{});
71  // Destination array should not change, but just in case.
72  destWrapper.AsArrayHandle(destination);
73  }
74 }
75 
76 template <typename TS, typename SS, typename TD, typename SD>
77 void ArrayCopyImpl(const vtkm::cont::ArrayHandle<TS, SS>& source,
79  std::true_type,
80  std::true_type)
81 {
82  detail::ArrayCopyConcreteSrc<SS>{}(source, destination);
83 }
84 
85 // Special case of copying data when type is the same.
86 template <typename T, typename S>
87 void ArrayCopyImpl(const vtkm::cont::ArrayHandle<T, S>& source,
88  vtkm::cont::ArrayHandle<T, S>& destination,
89  std::true_type,
90  std::true_type)
91 {
92  destination.DeepCopyFrom(source);
93 }
94 
95 }
96 
119 template <typename SourceArrayType, typename DestArrayType>
120 inline void ArrayCopy(const SourceArrayType& source, DestArrayType& destination)
121 {
122  detail::ArrayCopyImpl(source,
123  destination,
124  typename internal::ArrayHandleCheck<SourceArrayType>::type{},
125  typename internal::ArrayHandleCheck<DestArrayType>::type{});
126 }
127 
128 // Special case where we allow a const UnknownArrayHandle as output.
130 template <typename SourceArrayType>
131 inline void ArrayCopy(const SourceArrayType& source, vtkm::cont::UnknownArrayHandle& destination)
132 {
133  detail::ArrayCopyImpl(source,
134  destination,
135  typename internal::ArrayHandleCheck<SourceArrayType>::type{},
136  std::false_type{});
137 }
138 
139 // Invalid const ArrayHandle in destination, which is not allowed because it will
140 // not work in all cases.
141 template <typename T, typename S>
143 {
144  VTKM_STATIC_ASSERT_MSG(sizeof(T) == 0, "Copying to a constant ArrayHandle is not allowed.");
145 }
146 
158 template <typename T, typename S>
160  vtkm::cont::ArrayHandle<T, S>& destination)
161 {
162  using DestType = vtkm::cont::ArrayHandle<T, S>;
163  if (source.CanConvert<DestType>())
164  {
165  source.AsArrayHandle(destination);
166  }
167  else
168  {
169  vtkm::cont::UnknownArrayHandle destWrapper(destination);
170  vtkm::cont::ArrayCopy(source, destWrapper);
171  // Destination array should not change, but just in case.
172  destWrapper.AsArrayHandle(destination);
173  }
174 }
175 
176 namespace detail
177 {
178 
179 template <typename S>
180 struct ArrayCopyConcreteSrc
181 {
182  template <typename T, typename DestArray>
183  void operator()(const vtkm::cont::ArrayHandle<T, S>& source, DestArray& destination) const
184  {
185  using ArrayType = vtkm::cont::ArrayHandle<T, S>;
186  this->DoIt(
187  source, destination, vtkm::cont::internal::ArrayExtractComponentIsInefficient<ArrayType>{});
188  }
189 
190  template <typename T, typename DestArray>
191  void DoIt(const vtkm::cont::ArrayHandle<T, S>& source,
192  DestArray& destination,
193  std::false_type vtkmNotUsed(isInefficient)) const
194  {
196  }
197 
198  template <typename T, typename DestArray>
199  void DoIt(const vtkm::cont::ArrayHandle<T, S>& source,
200  DestArray& destination,
201  std::true_type vtkmNotUsed(isInefficient)) const
202  {
204  "Attempting to copy from an array of type " +
206  " with ArrayCopy is inefficient. It is highly recommended you use another method "
207  "such as vtkm::cont::ArrayCopyDevice.");
208  // Still call the precompiled `ArrayCopy`. You will get another warning after this,
209  // but it will still technically work, albiet slowly.
211  }
212 };
213 
214 // Special case for constant arrays to be efficient.
215 template <>
216 struct ArrayCopyConcreteSrc<vtkm::cont::StorageTagConstant>
217 {
218  template <typename T1, typename T2, typename S2>
220  vtkm::cont::ArrayHandle<T2, S2>& destination) const
221  {
222  vtkm::cont::ArrayHandleConstant<T1> source = source_;
223  destination.AllocateAndFill(source.GetNumberOfValues(), static_cast<T2>(source.GetValue()));
224  }
225 };
226 
227 // Special case for ArrayHandleIndex to be efficient.
228 template <>
229 struct ArrayCopyConcreteSrc<vtkm::cont::StorageTagIndex>
230 {
231  template <typename T, typename S>
232  void operator()(const vtkm::cont::ArrayHandleIndex& source,
233  vtkm::cont::ArrayHandle<T, S>& destination) const
234  {
235  // Skip warning about inefficient copy because there is a special case in ArrayCopyUnknown.cxx
236  // to copy ArrayHandleIndex efficiently.
238  }
239 };
240 
241 // Special case for ArrayHandleCounting to be efficient.
242 template <>
243 struct VTKM_CONT_EXPORT ArrayCopyConcreteSrc<vtkm::cont::StorageTagCounting>
244 {
245  template <typename T1, typename T2, typename S2>
247  vtkm::cont::ArrayHandle<T2, S2>& destination) const
248  {
249  vtkm::cont::ArrayHandleCounting<T1> countingSource = source;
250  T1 start = countingSource.GetStart();
251  T1 step = countingSource.GetStep();
252  vtkm::Id size = countingSource.GetNumberOfValues();
253  destination.Allocate(size);
254  vtkm::cont::UnknownArrayHandle unknownDest = destination;
255 
256  using VTraits1 = vtkm::VecTraits<T1>;
257  using VTraits2 = vtkm::VecTraits<T2>;
258  for (vtkm::IdComponent comp = 0; comp < VTraits1::GetNumberOfComponents(start); ++comp)
259  {
260  this->CopyCountingFloat(
261  static_cast<vtkm::FloatDefault>(VTraits1::GetComponent(start, comp)),
262  static_cast<vtkm::FloatDefault>(VTraits1::GetComponent(step, comp)),
263  size,
264  unknownDest.ExtractComponent<typename VTraits2::BaseComponentType>(comp));
265  }
266  }
267 
269  vtkm::cont::ArrayHandle<vtkm::Id>& destination) const
270  {
271  destination = this->CopyCountingId(source);
272  }
273 
274 private:
275  void CopyCountingFloat(vtkm::FloatDefault start,
276  vtkm::FloatDefault step,
277  vtkm::Id size,
278  const vtkm::cont::UnknownArrayHandle& result) const;
279  vtkm::cont::ArrayHandle<Id> CopyCountingId(
280  const vtkm::cont::ArrayHandleCounting<vtkm::Id>& source) const;
281 };
282 
283 // Special case for ArrayHandleConcatenate to be efficient
284 template <typename ST1, typename ST2>
285 struct ArrayCopyConcreteSrc<vtkm::cont::StorageTagConcatenate<ST1, ST2>>
286 {
287  template <typename SourceArrayType, typename DestArrayType>
288  void operator()(const SourceArrayType& source, DestArrayType& destination) const
289  {
290  auto source1 = source.GetStorage().GetArray1(source.GetBuffers());
291  auto source2 = source.GetStorage().GetArray2(source.GetBuffers());
292 
293  // Need to preallocate because view decorator will not be able to resize.
294  destination.Allocate(source.GetNumberOfValues());
295  auto dest1 = vtkm::cont::make_ArrayHandleView(destination, 0, source1.GetNumberOfValues());
297  destination, source1.GetNumberOfValues(), source2.GetNumberOfValues());
298 
299  vtkm::cont::ArrayCopy(source1, dest1);
300  vtkm::cont::ArrayCopy(source2, dest2);
301  }
302 };
303 
304 // Special case for ArrayHandlePermutation to be efficient
305 template <typename SIndex, typename SValue>
306 struct ArrayCopyConcreteSrc<vtkm::cont::StorageTagPermutation<SIndex, SValue>>
307 {
308  using SourceStorageTag = vtkm::cont::StorageTagPermutation<SIndex, SValue>;
309  template <typename T1, typename T2, typename S2>
310  void operator()(const vtkm::cont::ArrayHandle<T1, SourceStorageTag>& source,
311  vtkm::cont::ArrayHandle<T2, S2>& destination) const
312  {
313  auto indexArray = source.GetStorage().GetIndexArray(source.GetBuffers());
314  auto valueArray = source.GetStorage().GetValueArray(source.GetBuffers());
316  vtkm::cont::internal::MapArrayPermutation(valueArray, indexArray);
317  vtkm::cont::ArrayCopyShallowIfPossible(copy, destination);
318  }
319 };
320 
321 } // namespace detail
322 
323 } // namespace cont
324 } // namespace vtkm
325 
326 #endif //vtk_m_cont_ArrayCopy_h
ArrayHandleConcatenate.h
vtkm::cont::UnknownArrayHandle::CanConvert
bool CanConvert() const
Determine if the contained array can be passed to the given array type.
Definition: UnknownArrayHandle.h:998
vtkm::cont::TypeToString
std::string TypeToString(const std::type_info &t)
Use RTTI information to retrieve the name of the type T.
vtkm::cont::ArrayHandle
Manages an array-worth of data.
Definition: ArrayHandle.h:300
vtkm::cont::ArrayHandle::GetBuffers
const std::vector< vtkm::cont::internal::Buffer > & GetBuffers() const
Returns the internal Buffer structures that hold the data.
Definition: ArrayHandle.h:719
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::cont::ArrayHandle::GetStorage
StorageType GetStorage() const
Get the storage.
Definition: ArrayHandle.h:419
vtkm::cont::make_ArrayHandleView
ArrayHandleView< ArrayHandleType > make_ArrayHandleView(const ArrayHandleType &array, vtkm::Id startIndex, vtkm::Id numValues)
Definition: ArrayHandleView.h:224
vtkm::cont::LogLevel::Warn
@ Warn
Less important user errors, such as out-of-bounds parameters.
vtkm::IdComponent
vtkm::Int32 IdComponent
Base type to use to index small lists.
Definition: Types.h:194
vtkm::cont::ArrayHandleConstant::GetValue
T GetValue() const
Returns the constant value stored in this array.
Definition: ArrayHandleConstant.h:88
vtkm::cont::ArrayHandleCounting::GetStart
CountingValueType GetStart() const
Definition: ArrayHandleCounting.h:136
vtkm::cont::UnknownArrayHandle
An ArrayHandle of an unknown value type and storage.
Definition: UnknownArrayHandle.h:430
vtkm::cont::ArrayHandle< T, vtkm::cont::StorageTagConstant >::GetNumberOfValues
vtkm::Id GetNumberOfValues() const
Returns the number of entries in the array.
Definition: ArrayHandle.h:466
vtkm::cont::ArrayCopyShallowIfPossible
void ArrayCopyShallowIfPossible(const vtkm::cont::UnknownArrayHandle source, vtkm::cont::ArrayHandle< T, S > &destination)
Copies from an unknown to a known array type.
Definition: ArrayCopy.h:159
ArrayHandleConstant.h
vtkm::cont::UnknownArrayHandle::AsArrayHandle
void AsArrayHandle(vtkm::cont::ArrayHandle< T, S > &array) const
Definition: UnknownArrayHandle.h:660
vtkm::cont::StorageTagPermutation
Definition: ArrayHandlePermutation.h:93
ArrayHandleView.h
vtkm::cont::UnknownArrayHandle::DeepCopyFrom
void DeepCopyFrom(const vtkm::cont::UnknownArrayHandle &source)
Deep copies data from another UnknownArrayHandle.
UnknownArrayHandle.h
ArrayHandlePermutation.h
MapArrayPermutation.h
ArrayHandleIndex.h
vtkm::cont::ArrayHandleCounting
ArrayHandleCounting is a specialization of ArrayHandle.
Definition: ArrayHandleCounting.h:121
VTKM_STATIC_ASSERT_MSG
#define VTKM_STATIC_ASSERT_MSG(condition, message)
Definition: StaticAssert.h:18
VTKM_CONT_EXPORT
#define VTKM_CONT_EXPORT
Definition: vtkm_cont_export.h:44
vtkm::cont::ArrayCopy
void ArrayCopy(const SourceArrayType &source, DestArrayType &destination)
Does a deep copy from one array to another array.
Definition: ArrayCopy.h:120
vtkm_cont_export.h
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::ArrayHandleConstant
An array handle with a constant value.
Definition: ArrayHandleConstant.h:70
vtkmNotUsed
#define vtkmNotUsed(parameter_name)
Simple macro to identify a parameter as unused.
Definition: ExportMacros.h:128
vtkm::cont::ArrayHandleCounting::GetStep
CountingValueType GetStep() const
Definition: ArrayHandleCounting.h:138
vtkm::cont::ArrayHandle::DeepCopyFrom
void DeepCopyFrom(const vtkm::cont::ArrayHandle< ValueType, StorageTag > &source) const
Deep copies the data in the array.
Definition: ArrayHandle.h:705
VTKM_LOG_S
#define VTKM_LOG_S(level,...)
Writes a message using stream syntax to the indicated log level.
Definition: Logging.h:208
vtkm::FloatDefault
vtkm::Float32 FloatDefault
The floating point type to use when no other precision is specified.
Definition: Types.h:236
StaticAssert.h
ArrayHandleCounting.h
vtkm::cont::ArrayHandle::Allocate
void Allocate(vtkm::Id numberOfValues, vtkm::CopyFlag preserve, vtkm::cont::Token &token) const
Allocates an array large enough to hold the given number of values.
Definition: ArrayHandle.h:488
vtkm::VecTraits
Traits that can be queried to treat any type as a Vec.
Definition: VecTraits.h:61
vtkm::cont::UnknownArrayHandle::ExtractComponent
vtkm::cont::ArrayHandleStride< BaseComponentType > ExtractComponent(vtkm::IdComponent componentIndex, vtkm::CopyFlag allowCopy=vtkm::CopyFlag::On) const
Extract a component of the array.
Definition: UnknownArrayHandle.h:790
VecTraits.h
vtkm::cont::ArrayHandle::AllocateAndFill
void AllocateAndFill(vtkm::Id numberOfValues, const ValueType &fillValue, vtkm::CopyFlag preserve, vtkm::cont::Token &token) const
Allocates an array and fills it with an initial value.
Definition: ArrayHandle.h:517
vtkm::cont::ArrayHandleIndex
An implicit array handle containing the its own indices.
Definition: ArrayHandleIndex.h:55