VTK-m  2.1
ArrayExtractComponent.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_ArrayExtractComponent_h
11 #define vtk_m_cont_ArrayExtractComponent_h
12 
16 #include <vtkm/cont/Logging.h>
17 
18 #include <vtkm/TypeTraits.h>
19 #include <vtkm/VecFlat.h>
20 #include <vtkm/VecTraits.h>
21 
22 #include <vtkmstd/integer_sequence.h>
23 
25 
26 namespace vtkm
27 {
28 namespace cont
29 {
30 
31 namespace internal
32 {
33 
34 // Note: Using partial template specialization instead of function overloading to
35 // specialize ArrayExtractComponent for different types of array handles. This is
36 // because function overloading from a templated function is done when the template
37 // is defined rather than where it is resolved. This causes problems when extracting
38 // components of, say, an ArrayHandleMultiplexer holding an ArrayHandleSOA.
39 template <typename T, typename S>
41 ArrayExtractComponentFallback(const vtkm::cont::ArrayHandle<T, S>& src,
42  vtkm::IdComponent componentIndex,
43  vtkm::CopyFlag allowCopy)
44 {
45  if (allowCopy != vtkm::CopyFlag::On)
46  {
47  throw vtkm::cont::ErrorBadValue("Cannot extract component of " +
49  " without copying");
50  }
52  "Extracting component " << componentIndex << " of "
54  << " requires an inefficient memory copy.");
55 
56  using BaseComponentType = typename vtkm::VecTraits<T>::BaseComponentType;
57  vtkm::Id numValues = src.GetNumberOfValues();
59  dest.Allocate(numValues);
60  auto srcPortal = src.ReadPortal();
61  auto destPortal = dest.WritePortal();
62  for (vtkm::Id arrayIndex = 0; arrayIndex < numValues; ++arrayIndex)
63  {
64  destPortal.Set(arrayIndex,
65  vtkm::internal::GetFlatVecComponent(srcPortal.Get(arrayIndex), componentIndex));
66  }
67 
68  return vtkm::cont::ArrayHandleStride<BaseComponentType>(dest, numValues, 1, 0);
69 }
70 
71 // Used as a superclass for ArrayHandleComponentImpls that are inefficient (and should be
72 // avoided).
73 struct ArrayExtractComponentImplInefficient
74 {
75 };
76 
77 template <typename S>
78 struct ArrayExtractComponentImpl : ArrayExtractComponentImplInefficient
79 {
80  template <typename T>
83  vtkm::IdComponent componentIndex,
84  vtkm::CopyFlag allowCopy) const
85  {
86  // This is the slow "default" implementation. ArrayHandle implementations should provide
87  // more efficient overloads where applicable.
88  return vtkm::cont::internal::ArrayExtractComponentFallback(src, componentIndex, allowCopy);
89  }
90 };
91 
92 template <>
93 struct ArrayExtractComponentImpl<vtkm::cont::StorageTagStride>
94 {
95  template <typename T>
98  vtkm::IdComponent componentIndex,
99  vtkm::CopyFlag allowCopy) const
100  {
101  return this->DoExtract(
102  src, componentIndex, allowCopy, typename vtkm::VecTraits<T>::HasMultipleComponents{});
103  }
104 
105 private:
106  template <typename T>
108  vtkm::IdComponent componentIndex,
109  vtkm::CopyFlag vtkmNotUsed(allowCopy),
111  {
112  VTKM_ASSERT(componentIndex == 0);
113  using VTraits = vtkm::VecTraits<T>;
114  using TBase = typename VTraits::BaseComponentType;
115  VTKM_STATIC_ASSERT(VTraits::NUM_COMPONENTS == 1);
116 
118 
119  // Note, we are initializing the result in this strange way for cases where type
120  // T has a single component but does not equal its own BaseComponentType. A vtkm::Vec
121  // of size 1 fits into this category.
122  return vtkm::cont::ArrayHandleStride<TBase>(array.GetBuffers()[1],
123  array.GetNumberOfValues(),
124  array.GetStride(),
125  array.GetOffset(),
126  array.GetModulo(),
127  array.GetDivisor());
128  }
129 
130  template <typename VecType>
132  vtkm::IdComponent componentIndex,
133  vtkm::CopyFlag allowCopy,
135  {
136  using VTraits = vtkm::VecTraits<VecType>;
137  using T = typename VTraits::ComponentType;
138  constexpr vtkm::IdComponent N = VTraits::NUM_COMPONENTS;
139 
140  constexpr vtkm::IdComponent subStride = vtkm::internal::TotalNumComponents<T>::value;
142  vtkm::cont::ArrayHandleStride<T> tmpIn(array.GetBuffers()[1],
143  array.GetNumberOfValues(),
144  array.GetStride() * N,
145  (array.GetOffset() * N) + (componentIndex / subStride),
146  array.GetModulo() * N,
147  array.GetDivisor());
148  return (*this)(tmpIn, componentIndex % subStride, allowCopy);
149  }
150 };
151 
152 template <>
153 struct ArrayExtractComponentImpl<vtkm::cont::StorageTagBasic>
154 {
155  template <typename T>
157  vtkm::IdComponent componentIndex,
158  vtkm::CopyFlag allowCopy) const
159  -> decltype(
160  ArrayExtractComponentImpl<vtkm::cont::StorageTagStride>{}(vtkm::cont::ArrayHandleStride<T>{},
161  componentIndex,
162  allowCopy))
163  {
164  return ArrayExtractComponentImpl<vtkm::cont::StorageTagStride>{}(
166  componentIndex,
167  allowCopy);
168  }
169 };
170 
171 namespace detail
172 {
173 
174 template <std::size_t, typename Super>
175 struct ForwardSuper : Super
176 {
177 };
178 
179 template <typename sequence, typename... Supers>
180 struct SharedSupersImpl;
181 
182 template <std::size_t... Indices, typename... Supers>
183 struct SharedSupersImpl<vtkmstd::index_sequence<Indices...>, Supers...>
184  : ForwardSuper<Indices, Supers>...
185 {
186 };
187 
188 } // namespace detail
189 
190 // `ArrayExtractComponentImpl`s that modify the behavior from other storage types might
191 // want to inherit from the `ArrayExtractComponentImpl`s of these storage types. However,
192 // if the template specifies multiple storage types, two of the same might be specified,
193 // and it is illegal in C++ to directly inherit from the same type twice. This special
194 // superclass accepts a variable amout of superclasses. Inheriting from this will inherit
195 // from all these superclasses, and duplicates are allowed.
196 template <typename... Supers>
197 using DuplicatedSuperclasses =
198  detail::SharedSupersImpl<vtkmstd::make_index_sequence<sizeof...(Supers)>, Supers...>;
199 
200 template <typename... StorageTags>
201 using ArrayExtractComponentImplInherit =
202  DuplicatedSuperclasses<vtkm::cont::internal::ArrayExtractComponentImpl<StorageTags>...>;
203 
206 template <typename ArrayHandleType>
207 using ArrayExtractComponentIsInefficient = typename std::is_base_of<
208  vtkm::cont::internal::ArrayExtractComponentImplInefficient,
209  vtkm::cont::internal::ArrayExtractComponentImpl<typename ArrayHandleType::StorageTag>>::type;
210 
211 } // namespace internal
212 
254 template <typename T, typename S>
257  vtkm::IdComponent componentIndex,
259 {
260  return internal::ArrayExtractComponentImpl<S>{}(src, componentIndex, allowCopy);
261 }
262 
263 }
264 } // namespace vtkm::cont
265 
266 #endif //vtk_m_cont_ArrayExtractComponent_h
vtkm::cont::TypeToString
std::string TypeToString(const std::type_info &t)
Use RTTI information to retrieve the name of the type T.
VecFlat.h
vtkm::cont::ArrayHandle
Manages an array-worth of data.
Definition: ArrayHandle.h:300
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
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::cont::LogLevel::Warn
@ Warn
Less important user errors, such as out-of-bounds parameters.
VTKM_ASSERT
#define VTKM_ASSERT(condition)
Definition: Assert.h:43
vtkm::IdComponent
vtkm::Int32 IdComponent
Base type to use to index small lists.
Definition: Types.h:194
ArrayHandleBasic.h
vtkm::cont::ArrayHandle::GetNumberOfValues
vtkm::Id GetNumberOfValues() const
Returns the number of entries in the array.
Definition: ArrayHandle.h:466
vtkm::cont::ArrayHandleStride
An ArrayHandle that accesses a basic array with strides and offsets.
Definition: ArrayHandleStride.h:332
vtkm::VecTraits::BaseComponentType
T BaseComponentType
Base component type in the vector.
Definition: VecTraits.h:78
TypeTraits.h
VTKM_STATIC_ASSERT
#define VTKM_STATIC_ASSERT(condition)
Definition: StaticAssert.h:16
vtkm_cont_export.h
vtkm::Id
vtkm::Int64 Id
Base type to use to index arrays.
Definition: Types.h:227
vtkm::CopyFlag::On
@ On
vtkmNotUsed
#define vtkmNotUsed(parameter_name)
Simple macro to identify a parameter as unused.
Definition: ExportMacros.h:128
vtkm::cont::ArrayHandle::ReadPortal
ReadPortalType ReadPortal() const
Get an array portal that can be used in the control environment.
Definition: ArrayHandle.h:431
VTKM_LOG_S
#define VTKM_LOG_S(level,...)
Writes a message using stream syntax to the indicated log level.
Definition: Logging.h:208
vtkm::VecTraitsTagSingleComponent
A tag for vectors that are really just scalars (i.e.
Definition: VecTraits.h:30
vtkm::cont::ErrorBadValue
This class is thrown when a VTKm function or method encounters an invalid value that inhibits progres...
Definition: ErrorBadValue.h:25
ErrorBadValue.h
vtkm::CopyFlag
CopyFlag
Identifier used to specify whether a function should deep copy data.
Definition: Flags.h:17
vtkm::cont::ArrayHandle< T, vtkm::cont::StorageTagBasic >::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::cont::ArrayHandleBasic
Basic array storage for an array handle.
Definition: ArrayHandleBasic.h:111
vtkm::VecTraits
Traits that can be queried to treat any type as a Vec.
Definition: VecTraits.h:61
Logging.h
Logging utilities.
vtkm::cont::ArrayHandle< T, vtkm::cont::StorageTagBasic >::WritePortal
WritePortalType WritePortal() const
Get an array portal that can be used in the control environment.
Definition: ArrayHandle.h:452
VecTraits.h