VTK-m  2.0
ArrayHandleSwizzle.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_ArrayHandleSwizzle_h
11 #define vtk_m_cont_ArrayHandleSwizzle_h
12 
14 
15 #include <vtkm/VecTraits.h>
16 
17 #include <vtkmstd/integer_sequence.h>
18 
19 namespace vtkm
20 {
21 namespace internal
22 {
23 
24 template <typename InType, typename OutType>
25 class SwizzleFunctor
26 {
27  using InTraits = vtkm::VecTraits<InType>;
28  using InComponentType = typename InTraits::ComponentType;
29  static constexpr vtkm::IdComponent NUM_IN_COMPONENTS = InTraits::NUM_COMPONENTS;
30 
31  using OutTraits = vtkm::VecTraits<OutType>;
32  using OutComponentType = typename OutTraits::ComponentType;
33  static constexpr vtkm::IdComponent NUM_OUT_COMPONENTS = OutTraits::NUM_COMPONENTS;
34 
35  template <vtkm::IdComponent... Is>
36  using IndexSequence = vtkmstd::integer_sequence<vtkm::IdComponent, Is...>;
37  using IndexList = vtkmstd::make_integer_sequence<vtkm::IdComponent, NUM_OUT_COMPONENTS>;
38 
39 public:
41 
42  VTKM_CONT SwizzleFunctor(const MapType& map)
43  : Map(map)
44  {
45  }
46 
47  VTKM_CONT SwizzleFunctor() = default;
48 
49  VTKM_EXEC_CONT OutType operator()(const InType& vec) const
50  {
51  return this->Swizzle(vec, IndexList{});
52  }
53 
54  VTKM_CONT static MapType InitMap() { return IndexListAsMap(IndexList{}); }
55 
56 private:
57  template <vtkm::IdComponent... Is>
58  VTKM_CONT static MapType IndexListAsMap(IndexSequence<Is...>)
59  {
60  return { Is... };
61  }
62 
63  template <vtkm::IdComponent... Is>
64  VTKM_EXEC_CONT OutType Swizzle(const InType& vec, IndexSequence<Is...>) const
65  {
66  return { InTraits::GetComponent(vec, this->Map[Is])... };
67  }
68 
69  MapType Map = InitMap();
70 };
71 
72 namespace detail
73 {
74 
75 template <typename InType, typename OutType, typename Invertible>
76 struct GetInverseSwizzleImpl;
77 
78 template <typename InType, typename OutType>
79 struct GetInverseSwizzleImpl<InType, OutType, std::true_type>
80 {
81  using Type = vtkm::internal::SwizzleFunctor<OutType, InType>;
82  template <typename ForwardMapType>
83  VTKM_CONT static Type Value(const ForwardMapType& forwardMap)
84  {
85  // Note that when reversing the map, if the forwardMap repeats any indices, then
86  // the map is not 1:1 and is not invertible. We cannot check that at compile time.
87  // In this case, results can become unpredictible.
88  using InverseMapType = typename Type::MapType;
89  InverseMapType inverseMap = Type::InitMap();
90  for (vtkm::IdComponent inIndex = 0; inIndex < ForwardMapType::NUM_COMPONENTS; ++inIndex)
91  {
92  inverseMap[forwardMap[inIndex]] = inIndex;
93  }
94 
95  return Type(inverseMap);
96  }
97 };
98 
99 template <typename InType, typename OutType>
100 struct GetInverseSwizzleImpl<InType, OutType, std::false_type>
101 {
102  using Type = vtkm::cont::internal::NullFunctorType;
103  template <typename ForwardMapType>
104  VTKM_CONT static Type Value(const ForwardMapType&)
105  {
106  return Type{};
107  }
108 };
109 
110 template <typename InType, typename OutType>
111 using SwizzleInvertible = std::integral_constant<bool,
114 
115 } // namespace detail
116 
117 template <typename InType, typename OutType>
118 VTKM_CONT vtkm::internal::SwizzleFunctor<InType, OutType> GetSwizzleFunctor(
120 {
121  return vtkm::internal::SwizzleFunctor<InType, OutType>(forwardMap);
122 }
123 
124 template <typename InType, typename OutType>
125 using InverseSwizzleType = typename detail::
126  GetInverseSwizzleImpl<InType, OutType, detail::SwizzleInvertible<InType, OutType>>::Type;
127 
128 template <typename InType, typename OutType>
129 VTKM_CONT InverseSwizzleType<InType, OutType> GetInverseSwizzleFunctor(
131 {
132  return detail::
133  GetInverseSwizzleImpl<InType, OutType, detail::SwizzleInvertible<InType, OutType>>::Value(
134  forwardMap);
135 }
136 
137 }
138 } // namespace vtkm::internal
139 
140 namespace vtkm
141 {
142 namespace cont
143 {
144 
145 namespace detail
146 {
147 
148 template <typename ArrayHandleType, vtkm::IdComponent OutSize>
149 struct ArrayHandleSwizzleTraits
150 {
151  VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
152 
153  using InType = typename ArrayHandleType::ValueType;
155  using SwizzleFunctor = vtkm::internal::SwizzleFunctor<InType, OutType>;
156  using InverseSwizzleFunctor = vtkm::internal::InverseSwizzleType<InType, OutType>;
157  using MapType = typename SwizzleFunctor::MapType;
158 
159  static SwizzleFunctor GetFunctor(const MapType& forwardMap)
160  {
161  return vtkm::internal::GetSwizzleFunctor<InType, OutType>(forwardMap);
162  }
163 
164  static InverseSwizzleFunctor GetInverseFunctor(const MapType& forwardMap)
165  {
166  return vtkm::internal::GetInverseSwizzleFunctor<InType, OutType>(forwardMap);
167  }
168 
169  using Superclass =
171 };
172 
173 } // namespace detail
174 
192 template <typename ArrayHandleType, vtkm::IdComponent OutSize>
194  : public detail::ArrayHandleSwizzleTraits<ArrayHandleType, OutSize>::Superclass
195 {
196  VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
197 
198  using Traits = detail::ArrayHandleSwizzleTraits<ArrayHandleType, OutSize>;
199 
200 public:
203  (typename Traits::Superclass));
204 
205  using MapType = typename Traits::MapType;
206 
207  VTKM_CONT ArrayHandleSwizzle(const ArrayHandleType& array, const MapType& map)
208  : Superclass(array, Traits::GetFunctor(map), Traits::GetInverseFunctor(map))
209  {
210  }
211 };
212 
213 template <typename ArrayHandleType, vtkm::IdComponent OutSize>
215  const ArrayHandleType& array,
217 {
219 }
220 
221 template <typename ArrayHandleType, typename... SwizzleIndexTypes>
222 VTKM_CONT ArrayHandleSwizzle<ArrayHandleType, vtkm::IdComponent(sizeof...(SwizzleIndexTypes) + 1)>
223 make_ArrayHandleSwizzle(const ArrayHandleType& array,
224  vtkm::IdComponent swizzleIndex0,
225  SwizzleIndexTypes... swizzleIndices)
226 {
227  return make_ArrayHandleSwizzle(array, vtkm::make_Vec(swizzleIndex0, swizzleIndices...));
228 }
229 }
230 } // namespace vtkm::cont
231 
232 //=============================================================================
233 // Specializations of serialization related classes
235 namespace vtkm
236 {
237 namespace cont
238 {
239 
240 template <typename InType, typename OutType>
241 struct SerializableTypeString<vtkm::internal::SwizzleFunctor<InType, OutType>>
242 {
243  static VTKM_CONT const std::string& Get()
244  {
245  static std::string name = "Swizzle<" + SerializableTypeString<InType>::Get() + "," +
247  return name;
248  }
249 };
250 
251 template <typename AH, vtkm::IdComponent NComps>
252 struct SerializableTypeString<vtkm::cont::ArrayHandleSwizzle<AH, NComps>>
253  : SerializableTypeString<typename vtkm::cont::ArrayHandleSwizzle<AH, NComps>::Superclass>
254 {
255 };
256 }
257 } // vtkm::cont
258 
259 namespace mangled_diy_namespace
260 {
261 
262 template <typename AH, vtkm::IdComponent NComps>
263 struct Serialization<vtkm::cont::ArrayHandleSwizzle<AH, NComps>>
264  : Serialization<typename vtkm::cont::ArrayHandleSwizzle<AH, NComps>::Superclass>
265 {
266 };
267 
268 } // diy
270 
271 #endif // vtk_m_cont_ArrayHandleSwizzle_h
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::cont::ArrayHandleTransform::GetFunctor
FunctorType GetFunctor() const
Returns the functor transforming the ArrayHandle.
Definition: ArrayHandleTransform.h:525
VTKM_EXEC_CONT
#define VTKM_EXEC_CONT
Definition: ExportMacros.h:52
vtkm::cont::ArrayHandleTransform::GetInverseFunctor
InverseFunctorType GetInverseFunctor() const
Returns the inverse functor transforming the ArrayHandle
Definition: ArrayHandleTransform.h:529
vtkm::cont::make_ArrayHandleSwizzle
VTKM_CONT ArrayHandleSwizzle< ArrayHandleType, OutSize > make_ArrayHandleSwizzle(const ArrayHandleType &array, const vtkm::Vec< vtkm::IdComponent, OutSize > &map)
Definition: ArrayHandleSwizzle.h:214
vtkm::Get
VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_CONT auto Get(const vtkm::Tuple< Ts... > &tuple) -> decltype(tuple.template Get< Index >())
Retrieve the object from a vtkm::Tuple at the given index.
Definition: Tuple.h:83
vtkm::IdComponent
vtkm::Int32 IdComponent
Represents a component ID (index of component in a vector).
Definition: Types.h:168
ArrayHandleTransform.h
mangled_diy_namespace
Definition: Particle.h:331
vtkm::VecTraits::GetComponent
static const VTKM_EXEC_CONT ComponentType & GetComponent(const typename std::remove_const< VecType >::type &vector, vtkm::IdComponent component)
Returns the value in a given component of the vector.
vtkm::cont::ArrayHandleSwizzle
Swizzle the components of the values in an ArrayHandle.
Definition: ArrayHandleSwizzle.h:193
VTKM_IS_ARRAY_HANDLE
#define VTKM_IS_ARRAY_HANDLE(T)
Definition: ArrayHandle.h:132
vtkm::cont::ArrayHandleSwizzle::MapType
typename Traits::MapType MapType
Definition: ArrayHandleSwizzle.h:205
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
vtkm::cont::ArrayHandleTransform
Implicitly transform values of one array to another with a functor.
Definition: ArrayHandleTransform.h:437
vtkm::cont::ArrayHandleSwizzle::VTKM_ARRAY_HANDLE_SUBCLASS
VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandleSwizzle,(ArrayHandleSwizzle< ArrayHandleType, OutSize >),(typename Traits::Superclass))
vtkm::make_Vec
constexpr VTKM_EXEC_CONT vtkm::Vec< T, vtkm::IdComponent(sizeof...(Ts)+1)> make_Vec(T value0, Ts &&... args)
Initializes and returns a Vec containing all the arguments.
Definition: Types.h:1212
vtkm::Vec
A short fixed-length array.
Definition: Types.h:767
vtkm::cont::ArrayHandleSwizzle::ArrayHandleSwizzle
VTKM_CONT ArrayHandleSwizzle(const ArrayHandleType &array, const MapType &map)
Definition: ArrayHandleSwizzle.h:207
vtkm::VecTraits::ComponentType
typename VecType::ComponentType ComponentType
Type of the components in the vector.
Definition: VecTraits.h:73
vtkm::VecTraits
The VecTraits class gives several static members that define how to use a given type as a vector.
Definition: VecTraits.h:66
vtkm::cont::ArrayHandleSwizzle::Traits
detail::ArrayHandleSwizzleTraits< ArrayHandleType, OutSize > Traits
Definition: ArrayHandleSwizzle.h:198
VecTraits.h
vtkm::cont::ArrayHandleSwizzle::VTKM_IS_ARRAY_HANDLE
VTKM_IS_ARRAY_HANDLE(ArrayHandleType)
vtkm::VecTraits::NUM_COMPONENTS
static constexpr vtkm::IdComponent NUM_COMPONENTS
Number of components in the vector.
Definition: VecTraits.h:86