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