1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 // This software is distributed WITHOUT ANY WARRANTY; without even
6 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
7 // PURPOSE. See the above copyright notice for more information.
8 //
9 // Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
10 // Copyright 2014 UT-Battelle, LLC.
11 // Copyright 2014 Los Alamos National Security.
12 //
13 // Under the terms of Contract DE-NA0003525 with NTESS,
14 // the U.S. Government retains certain rights in this software.
15 //
16 // Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
17 // Laboratory (LANL), the U.S. Government retains certain rights in
18 // this software.
19 //============================================================================
20 #ifndef vtk_m_cont_ArrayHandleCounting_h
21 #define vtk_m_cont_ArrayHandleCounting_h
22
23 #include <vtkm/cont/ArrayHandle.h>
24 #include <vtkm/cont/StorageImplicit.h>
25
26 #include <vtkm/VecTraits.h>
27
28 namespace vtkm
29 {
30 namespace cont
31 {
32
33 namespace internal
34 {
35
36 /// \brief An implicit array portal that returns an counting value.
37 template <class CountingValueType>
38 class VTKM_ALWAYS_EXPORT ArrayPortalCounting
39 {
40 using ComponentType = typename vtkm::VecTraits<CountingValueType>::ComponentType;
41
42 public:
43 using ValueType = CountingValueType;
44
45 VTKM_EXEC_CONT
ArrayPortalCounting()46 ArrayPortalCounting()
47 : Start(0)
48 , Step(1)
49 , NumberOfValues(0)
50 {
51 }
52
53 VTKM_EXEC_CONT
ArrayPortalCounting(ValueType start,ValueType step,vtkm::Id numValues)54 ArrayPortalCounting(ValueType start, ValueType step, vtkm::Id numValues)
55 : Start(start)
56 , Step(step)
57 , NumberOfValues(numValues)
58 {
59 }
60
61 template <typename OtherValueType>
ArrayPortalCounting(const ArrayPortalCounting<OtherValueType> & src)62 VTKM_EXEC_CONT ArrayPortalCounting(const ArrayPortalCounting<OtherValueType>& src)
63 : Start(src.Start)
64 , Step(src.Step)
65 , NumberOfValues(src.NumberOfValues)
66 {
67 }
68
69 template <typename OtherValueType>
70 VTKM_EXEC_CONT ArrayPortalCounting<ValueType>& operator=(
71 const ArrayPortalCounting<OtherValueType>& src)
72 {
73 this->Start = src.Start;
74 this->Step = src.Step;
75 this->NumberOfValues = src.NumberOfValues;
76 return *this;
77 }
78
79 VTKM_EXEC_CONT
GetStart()80 ValueType GetStart() const { return this->Start; }
81
82 VTKM_EXEC_CONT
GetStep()83 ValueType GetStep() const { return this->Step; }
84
85 VTKM_EXEC_CONT
GetNumberOfValues()86 vtkm::Id GetNumberOfValues() const { return this->NumberOfValues; }
87
88 VTKM_EXEC_CONT
Get(vtkm::Id index)89 ValueType Get(vtkm::Id index) const
90 {
91 return ValueType(this->Start + this->Step * ValueType(static_cast<ComponentType>(index)));
92 }
93
94 VTKM_EXEC_CONT
Set(vtkm::Id vtkmNotUsed (index),const ValueType & vtkmNotUsed (value))95 void Set(vtkm::Id vtkmNotUsed(index), const ValueType& vtkmNotUsed(value)) const
96 {
97 VTKM_ASSERT(false && "Cannot write to read-only counting array.");
98 }
99
100 private:
101 ValueType Start;
102 ValueType Step;
103 vtkm::Id NumberOfValues;
104 };
105
106 /// A convenience class that provides a typedef to the appropriate tag for
107 /// a counting storage.
108 template <typename ConstantValueType>
109 struct ArrayHandleCountingTraits
110 {
111 using Tag =
112 vtkm::cont::StorageTagImplicit<vtkm::cont::internal::ArrayPortalCounting<ConstantValueType>>;
113 };
114
115 } // namespace internal
116
117 /// ArrayHandleCounting is a specialization of ArrayHandle. By default it
118 /// contains a increment value, that is increment for each step between zero
119 /// and the passed in length
120 template <typename CountingValueType>
121 class ArrayHandleCounting : public vtkm::cont::ArrayHandle<
122 CountingValueType,
123 typename internal::ArrayHandleCountingTraits<CountingValueType>::Tag>
124 {
125 public:
126 VTKM_ARRAY_HANDLE_SUBCLASS(
127 ArrayHandleCounting,
128 (ArrayHandleCounting<CountingValueType>),
129 (vtkm::cont::ArrayHandle<
130 CountingValueType,
131 typename internal::ArrayHandleCountingTraits<CountingValueType>::Tag>));
132
133 VTKM_CONT
ArrayHandleCounting(CountingValueType start,CountingValueType step,vtkm::Id length)134 ArrayHandleCounting(CountingValueType start, CountingValueType step, vtkm::Id length)
135 : Superclass(typename Superclass::PortalConstControl(start, step, length))
136 {
137 }
138 };
139
140 /// A convenience function for creating an ArrayHandleCounting. It takes the
141 /// value to start counting from and and the number of times to increment.
142 template <typename CountingValueType>
143 VTKM_CONT vtkm::cont::ArrayHandleCounting<CountingValueType>
make_ArrayHandleCounting(CountingValueType start,CountingValueType step,vtkm::Id length)144 make_ArrayHandleCounting(CountingValueType start, CountingValueType step, vtkm::Id length)
145 {
146 return vtkm::cont::ArrayHandleCounting<CountingValueType>(start, step, length);
147 }
148 }
149 } // namespace vtkm::cont
150
151 //=============================================================================
152 // Specializations of serialization related classes
153 namespace vtkm
154 {
155 namespace cont
156 {
157
158 template <typename T>
159 struct TypeString<vtkm::cont::ArrayHandleCounting<T>>
160 {
161 static VTKM_CONT const std::string& Get()
162 {
163 static std::string name = "AH_Counting<" + TypeString<T>::Get() + ">";
164 return name;
165 }
166 };
167
168 template <typename T>
169 struct TypeString<
170 vtkm::cont::ArrayHandle<T, typename vtkm::cont::ArrayHandleCounting<T>::StorageTag>>
171 : TypeString<vtkm::cont::ArrayHandleCounting<T>>
172 {
173 };
174 }
175 } // vtkm::cont
176
177 namespace diy
178 {
179
180 template <typename T>
181 struct Serialization<vtkm::cont::ArrayHandleCounting<T>>
182 {
183 private:
184 using Type = vtkm::cont::ArrayHandleCounting<T>;
185 using BaseType = vtkm::cont::ArrayHandle<typename Type::ValueType, typename Type::StorageTag>;
186
187 public:
188 static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
189 {
190 auto portal = obj.GetPortalConstControl();
191 diy::save(bb, portal.GetStart());
192 diy::save(bb, portal.GetStep());
193 diy::save(bb, portal.GetNumberOfValues());
194 }
195
196 static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj)
197 {
198 T start{}, step{};
199 vtkm::Id count = 0;
200
201 diy::load(bb, start);
202 diy::load(bb, step);
203 diy::load(bb, count);
204
205 obj = vtkm::cont::make_ArrayHandleCounting(start, step, count);
206 }
207 };
208
209 template <typename T>
210 struct Serialization<
211 vtkm::cont::ArrayHandle<T, typename vtkm::cont::ArrayHandleCounting<T>::StorageTag>>
212 : Serialization<vtkm::cont::ArrayHandleCounting<T>>
213 {
214 };
215 } // diy
216
217 #endif //vtk_m_cont_ArrayHandleCounting_h
218