VTK-m  2.0
ArrayGetValues.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_ArrayGetValues_h
11 #define vtk_m_cont_ArrayGetValues_h
12 
13 #include <vtkm/cont/vtkm_cont_export.h>
14 
15 #include <vtkm/cont/ArrayHandle.h>
17 
18 #include <initializer_list>
19 #include <vector>
20 
21 namespace vtkm
22 {
23 namespace cont
24 {
25 
26 // Work around circular dependancy with UnknownArrayHandle.
27 class UnknownArrayHandle;
28 
29 namespace internal
30 {
31 
32 VTKM_CONT_EXPORT void ArrayGetValuesImpl(const vtkm::cont::UnknownArrayHandle& ids,
34  const vtkm::cont::UnknownArrayHandle& output,
35  std::false_type extractComponentInefficient);
36 
37 template <typename IdsArrayHandle, typename DataArrayHandle, typename OutputArrayHandle>
38 void ArrayGetValuesImpl(const IdsArrayHandle& ids,
39  const DataArrayHandle& data,
40  const OutputArrayHandle& output,
41  std::true_type vtkmNotUsed(extractComponentInefficient))
42 {
43  // Fallback implementation. Using UnknownArrayHandle to extract the data would be more
44  // inefficient than simply getting the ReadPortal (which could potentially copy everything
45  // form device to host), so we do that here. The only other alternative would be to write
46  // a custom worklet, but that would require a device compiler, and we are avoiding that for
47  // this header.
48  vtkm::Id outputSize = ids.GetNumberOfValues();
49  output.Allocate(outputSize);
50  auto idsPortal = ids.ReadPortal();
51  auto dataPortal = data.ReadPortal();
52  auto outputPortal = output.WritePortal();
53  for (vtkm::Id index = 0; index < outputSize; ++index)
54  {
55  outputPortal.Set(index, dataPortal.Get(idsPortal.Get(index)));
56  }
57 }
58 
59 } // namespace internal
60 
118 template <typename SIds, typename T, typename SData, typename SOut>
122 {
125  "ArrayGetValues can only be used with arrays containing value types with VecTraits defined.");
126  using DataArrayHandle = vtkm::cont::ArrayHandle<T, SData>;
127  using InefficientExtract =
128  vtkm::cont::internal::ArrayExtractComponentIsInefficient<DataArrayHandle>;
129  internal::ArrayGetValuesImpl(ids, data, output, InefficientExtract{});
130 }
131 
134 template <typename SIds, typename TIn, typename SData, typename TOut, typename SOut>
139 {
140  // In this specialization, we extract the values from the cast array's source array and
141  // then cast and copy to output.
144  ArrayGetValues(ids, castArray.GetSourceArray(), tempOutput);
145 
146  vtkm::Id numExtracted = tempOutput.GetNumberOfValues();
147  output.Allocate(numExtracted);
148  auto inp = tempOutput.ReadPortal();
149  auto outp = output.WritePortal();
150  for (vtkm::Id i = 0; i < numExtracted; ++i)
151  {
152  outp.Set(i, static_cast<TOut>(inp.Get(i)));
153  }
154 }
155 
156 template <typename SIds, typename T, typename SData, typename Alloc>
159  std::vector<T, Alloc>& output)
160 {
161  const std::size_t numVals = static_cast<std::size_t>(ids.GetNumberOfValues());
162 
163  // Allocate the vector and toss its data pointer into the array handle.
164  output.resize(numVals);
165  auto result = vtkm::cont::make_ArrayHandle(output, vtkm::CopyFlag::Off);
166  vtkm::cont::ArrayGetValues(ids, data, result);
167  // Make sure to pull the data back to control before we dealloc the handle
168  // that wraps the vec memory:
169  result.SyncControlArray();
170 }
171 
172 template <typename SIds, typename T, typename SData>
175 {
176  std::vector<T> result;
177  vtkm::cont::ArrayGetValues(ids, data, result);
178  return result;
179 }
180 
181 template <typename T, typename Alloc, typename SData, typename SOut>
182 VTKM_CONT void ArrayGetValues(const std::vector<vtkm::Id, Alloc>& ids,
185 {
186  const auto idsAH = vtkm::cont::make_ArrayHandle(ids, vtkm::CopyFlag::Off);
187  ArrayGetValues(idsAH, data, output);
188 }
189 
190 template <typename T, typename AllocId, typename SData, typename AllocOut>
191 VTKM_CONT void ArrayGetValues(const std::vector<vtkm::Id, AllocId>& ids,
193  std::vector<T, AllocOut>& output)
194 {
195  const auto idsAH = vtkm::cont::make_ArrayHandle(ids, vtkm::CopyFlag::Off);
196  ArrayGetValues(idsAH, data, output);
197 }
198 
199 template <typename T, typename Alloc, typename SData>
200 VTKM_CONT std::vector<T> ArrayGetValues(const std::vector<vtkm::Id, Alloc>& ids,
202 {
203  const auto idsAH = vtkm::cont::make_ArrayHandle(ids, vtkm::CopyFlag::Off);
204  return ArrayGetValues(idsAH, data);
205 }
206 
207 template <typename T, typename SData, typename SOut>
208 VTKM_CONT void ArrayGetValues(const std::initializer_list<vtkm::Id>& ids,
211 {
212  const auto idsAH = vtkm::cont::make_ArrayHandle(
213  ids.begin(), static_cast<vtkm::Id>(ids.size()), vtkm::CopyFlag::Off);
214  ArrayGetValues(idsAH, data, output);
215 }
216 
217 template <typename T, typename SData, typename Alloc>
218 VTKM_CONT void ArrayGetValues(const std::initializer_list<vtkm::Id>& ids,
220  std::vector<T, Alloc>& output)
221 {
222  const auto idsAH = vtkm::cont::make_ArrayHandle(
223  ids.begin(), static_cast<vtkm::Id>(ids.size()), vtkm::CopyFlag::Off);
224  ArrayGetValues(idsAH, data, output);
225 }
226 template <typename T, typename SData>
227 VTKM_CONT std::vector<T> ArrayGetValues(const std::initializer_list<vtkm::Id>& ids,
229 {
230  const auto idsAH = vtkm::cont::make_ArrayHandle(
231  ids.begin(), static_cast<vtkm::Id>(ids.size()), vtkm::CopyFlag::Off);
232  return ArrayGetValues(idsAH, data);
233 }
234 
235 template <typename T, typename SData, typename SOut>
237  const vtkm::Id numIds,
240 {
241  const auto idsAH = vtkm::cont::make_ArrayHandle(ids, numIds, vtkm::CopyFlag::Off);
242  ArrayGetValues(idsAH, data, output);
243 }
244 
245 template <typename T, typename SData, typename Alloc>
247  const vtkm::Id numIds,
249  std::vector<T, Alloc>& output)
250 {
251  const auto idsAH = vtkm::cont::make_ArrayHandle(ids, numIds, vtkm::CopyFlag::Off);
252  ArrayGetValues(idsAH, data, output);
253 }
254 template <typename T, typename SData>
255 VTKM_CONT std::vector<T> ArrayGetValues(const vtkm::Id* ids,
256  const vtkm::Id numIds,
258 {
259  const auto idsAH = vtkm::cont::make_ArrayHandle(ids, numIds, vtkm::CopyFlag::Off);
260  return ArrayGetValues(idsAH, data);
261 }
262 
263 template <typename T, typename S>
265 {
266  const auto idAH = vtkm::cont::make_ArrayHandle(&id, 1, vtkm::CopyFlag::Off);
267  auto result = vtkm::cont::ArrayGetValues(idAH, data);
268  return result[0];
269 }
270 
271 template <typename T, typename S>
273 {
274  val = ArrayGetValue(id, data);
275 }
277 }
278 } // namespace vtkm::cont
279 
280 #endif //vtk_m_cont_ArrayGetValues_h
vtkm::cont::ArrayHandle< T, vtkm::cont::StorageTagBasic >::GetNumberOfValues
VTKM_CONT vtkm::Id GetNumberOfValues() const
Returns the number of entries in the array.
Definition: ArrayHandle.h:448
vtkm::cont::make_ArrayHandle
VTKM_CONT vtkm::cont::ArrayHandleBasic< T > make_ArrayHandle(const T *array, vtkm::Id numberOfValues, vtkm::CopyFlag copy)
A convenience function for creating an ArrayHandle from a standard C array.
Definition: ArrayHandleBasic.h:217
vtkm::cont::ArrayHandle
Manages an array-worth of data.
Definition: ArrayHandle.h:283
ArrayHandle.h
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::cont::ArrayHandle::Allocate
VTKM_CONT 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:465
vtkm::cont::UnknownArrayHandle
An ArrayHandle of an unknown value type and storage.
Definition: UnknownArrayHandle.h:406
vtkm::HasVecTraits
typename detail::HasVecTraitsImpl< T >::Type HasVecTraits
Determines whether the given type has VecTraits defined.
Definition: VecTraits.h:176
vtkm::cont::ArrayGetValues
VTKM_CONT void ArrayGetValues(const vtkm::cont::ArrayHandle< vtkm::Id, SIds > &ids, const vtkm::cont::ArrayHandle< T, SData > &data, vtkm::cont::ArrayHandle< T, SOut > &output)
Obtain a small set of values from an ArrayHandle with minimal device transfers.
Definition: ArrayGetValues.h:119
vtkm::cont::ArrayGetValue
VTKM_CONT T ArrayGetValue(vtkm::Id id, const vtkm::cont::ArrayHandle< T, S > &data)
Obtain a small set of values from an ArrayHandle with minimal device transfers.
Definition: ArrayGetValues.h:264
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
vtkm::cont::StorageTagCast
Definition: ArrayHandleCast.h:28
UnknownArrayHandle.h
vtkm::cont::ArrayHandleCast::GetSourceArray
ArrayHandleType GetSourceArray() const
Returns the ArrayHandle that is being transformed.
Definition: ArrayHandleCast.h:169
VTKM_STATIC_ASSERT_MSG
#define VTKM_STATIC_ASSERT_MSG(condition, message)
Definition: StaticAssert.h:18
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
vtkm::cont::ArrayHandle::WritePortal
VTKM_CONT WritePortalType WritePortal() const
Get an array portal that can be used in the control environment.
Definition: ArrayHandle.h:435
vtkmNotUsed
#define vtkmNotUsed(parameter_name)
Simple macro to identify a parameter as unused.
Definition: ExportMacros.h:128
vtkm::CopyFlag::Off
@ Off
vtkm::cont::ArrayHandleCast
Cast the values of an array to the specified type, on demand.
Definition: ArrayHandleCast.h:141
vtkm::cont::ArrayHandle< T, vtkm::cont::StorageTagBasic >::ReadPortal
VTKM_CONT ReadPortalType ReadPortal() const
Get an array portal that can be used in the control environment.
Definition: ArrayHandle.h:414
vtkm::cont::ArrayHandleBasic
Definition: ArrayHandleBasic.h:97