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 #include <vtkm/cont/ArrayCopy.h>
11 #include <vtkm/cont/ArrayHandle.h>
12 #include <vtkm/cont/ArrayHandleCartesianProduct.h>
13 #include <vtkm/cont/ArrayHandleCast.h>
14 #include <vtkm/cont/ArrayHandleCompositeVector.h>
15 #include <vtkm/cont/ArrayHandleConcatenate.h>
16 #include <vtkm/cont/ArrayHandleConstant.h>
17 #include <vtkm/cont/ArrayHandleCounting.h>
18 #include <vtkm/cont/ArrayHandleExtractComponent.h>
19 #include <vtkm/cont/ArrayHandleGroupVec.h>
20 #include <vtkm/cont/ArrayHandleGroupVecVariable.h>
21 #include <vtkm/cont/ArrayHandleImplicit.h>
22 #include <vtkm/cont/ArrayHandleIndex.h>
23 #include <vtkm/cont/ArrayHandlePermutation.h>
24 #include <vtkm/cont/ArrayHandleReverse.h>
25 #include <vtkm/cont/ArrayHandleSOA.h>
26 #include <vtkm/cont/ArrayHandleSwizzle.h>
27 #include <vtkm/cont/ArrayHandleTransform.h>
28 #include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
29 #include <vtkm/cont/ArrayHandleZip.h>
30
31 #include <vtkm/cont/UncertainArrayHandle.h>
32 #include <vtkm/cont/UnknownArrayHandle.h>
33
34 #include <vtkm/cont/testing/TestingSerialization.h>
35
36 #include <vtkm/VecTraits.h>
37
38 #include <ctime>
39 #include <type_traits>
40 #include <vector>
41
42 using namespace vtkm::cont::testing::serialization;
43
44 namespace
45 {
46
47 using StorageList = vtkm::List<
48 vtkm::cont::StorageTagBasic,
49 vtkm::cont::StorageTagSOA,
50 vtkm::cont::StorageTagCartesianProduct<vtkm::cont::StorageTagBasic,
51 vtkm::cont::StorageTagBasic,
52 vtkm::cont::StorageTagBasic>,
53 vtkm::cont::StorageTagCast<vtkm::Int8, vtkm::cont::StorageTagBasic>,
54 vtkm::cont::StorageTagConstant,
55 vtkm::cont::StorageTagCounting,
56 vtkm::cont::StorageTagGroupVec<vtkm::cont::StorageTagBasic, 2>,
57 vtkm::cont::StorageTagGroupVec<vtkm::cont::StorageTagBasic, 3>,
58 vtkm::cont::StorageTagGroupVec<vtkm::cont::StorageTagBasic, 4>,
59 vtkm::cont::StorageTagIndex,
60 vtkm::cont::StorageTagPermutation<vtkm::cont::StorageTagBasic, vtkm::cont::StorageTagBasic>,
61 vtkm::cont::StorageTagReverse<vtkm::cont::StorageTagBasic>,
62 vtkm::cont::StorageTagUniformPoints>;
63
64 //-----------------------------------------------------------------------------
65 struct TestEqualArrayHandle
66 {
67 public:
68 template <typename ArrayHandle1, typename ArrayHandle2>
operator ()__anon2c460e810111::TestEqualArrayHandle69 VTKM_CONT void operator()(const ArrayHandle1& array1, const ArrayHandle2& array2) const
70 {
71 VTKM_TEST_ASSERT(test_equal_ArrayHandles(array1, array2));
72 }
73
operator ()__anon2c460e810111::TestEqualArrayHandle74 VTKM_CONT void operator()(const vtkm::cont::UnknownArrayHandle& array1,
75 const vtkm::cont::UnknownArrayHandle& array2) const
76 {
77 VTKM_TEST_ASSERT(test_equal_ArrayHandles(array1.ResetTypes<vtkm::TypeListAll, StorageList>(),
78 array2.ResetTypes<vtkm::TypeListAll, StorageList>()));
79 }
80 };
81
82 //-----------------------------------------------------------------------------
83 template <typename T>
RunTest(const T & obj)84 inline void RunTest(const T& obj)
85 {
86 TestSerialization(obj, TestEqualArrayHandle{});
87 }
88
89 //-----------------------------------------------------------------------------
90 constexpr vtkm::Id ArraySize = 10;
91
92 using TestTypesListScalar = vtkm::List<vtkm::Int8, vtkm::Id, vtkm::FloatDefault>;
93 using TestTypesListVec = vtkm::List<vtkm::Vec3f_32, vtkm::Vec3f_64>;
94 using TestTypesList = vtkm::ListAppend<TestTypesListScalar, TestTypesListVec>;
95
96 template <typename T, typename S>
MakeTestUnknownArrayHandle(const vtkm::cont::ArrayHandle<T,S> & array)97 inline vtkm::cont::UnknownArrayHandle MakeTestUnknownArrayHandle(
98 const vtkm::cont::ArrayHandle<T, S>& array)
99 {
100 return array;
101 }
102
103 template <typename T, typename S>
MakeTestUncertainArrayHandle(const vtkm::cont::ArrayHandle<T,S> & array)104 inline vtkm::cont::UncertainArrayHandle<vtkm::List<T>, vtkm::List<S>> MakeTestUncertainArrayHandle(
105 const vtkm::cont::ArrayHandle<T, S>& array)
106 {
107 return array;
108 }
109
110 struct TestArrayHandleBasic
111 {
112 template <typename T>
operator ()__anon2c460e810111::TestArrayHandleBasic113 void operator()(T) const
114 {
115 auto array = RandomArrayHandle<T>::Make(ArraySize);
116 RunTest(array);
117 RunTest(MakeTestUnknownArrayHandle(array));
118 RunTest(MakeTestUncertainArrayHandle(array));
119 }
120 };
121
122 struct TestArrayHandleSOA
123 {
124 template <typename T>
operator ()__anon2c460e810111::TestArrayHandleSOA125 void operator()(T) const
126 {
127 vtkm::cont::ArrayHandleSOA<T> array;
128 vtkm::cont::ArrayCopy(RandomArrayHandle<T>::Make(ArraySize), array);
129 RunTest(array);
130 RunTest(MakeTestUnknownArrayHandle(array));
131 RunTest(MakeTestUncertainArrayHandle(array));
132 }
133 };
134
135 struct TestArrayHandleCartesianProduct
136 {
137 template <typename T>
operator ()__anon2c460e810111::TestArrayHandleCartesianProduct138 void operator()(T) const
139 {
140 auto array =
141 vtkm::cont::make_ArrayHandleCartesianProduct(RandomArrayHandle<T>::Make(ArraySize),
142 RandomArrayHandle<T>::Make(ArraySize),
143 RandomArrayHandle<T>::Make(ArraySize));
144 RunTest(array);
145 RunTest(MakeTestUnknownArrayHandle(array));
146 RunTest(MakeTestUncertainArrayHandle(array));
147 }
148 };
149
150 struct TestArrayHandleCast
151 {
152 template <typename T>
operator ()__anon2c460e810111::TestArrayHandleCast153 void operator()(T) const
154 {
155 auto array =
156 vtkm::cont::make_ArrayHandleCast<T>(RandomArrayHandle<vtkm::Int8>::Make(ArraySize));
157 RunTest(array);
158 RunTest(MakeTestUnknownArrayHandle(array));
159 RunTest(MakeTestUncertainArrayHandle(array));
160 }
161
162 template <typename T, vtkm::IdComponent N>
operator ()__anon2c460e810111::TestArrayHandleCast163 void operator()(vtkm::Vec<T, N>) const
164 {
165 auto array = vtkm::cont::make_ArrayHandleCast<vtkm::Vec<T, N>>(
166 RandomArrayHandle<vtkm::Vec<vtkm::Int8, N>>::Make(ArraySize));
167 RunTest(array);
168 RunTest(MakeTestUnknownArrayHandle(array));
169 RunTest(MakeTestUncertainArrayHandle(array));
170 }
171 };
172
173 struct TestArrayHandleConstant
174 {
175 template <typename T>
operator ()__anon2c460e810111::TestArrayHandleConstant176 void operator()(T) const
177 {
178 T cval = RandomValue<T>::Make();
179 auto array = vtkm::cont::make_ArrayHandleConstant(cval, ArraySize);
180 RunTest(array);
181 RunTest(MakeTestUnknownArrayHandle(array));
182 RunTest(MakeTestUncertainArrayHandle(array));
183 }
184 };
185
186 struct TestArrayHandleCounting
187 {
188 template <typename T>
operator ()__anon2c460e810111::TestArrayHandleCounting189 void operator()(T) const
190 {
191 T start = RandomValue<T>::Make();
192 T step = RandomValue<T>::Make(0, 5);
193 auto array = vtkm::cont::make_ArrayHandleCounting(start, step, ArraySize);
194 RunTest(array);
195 RunTest(MakeTestUnknownArrayHandle(array));
196 RunTest(MakeTestUncertainArrayHandle(array));
197 }
198 };
199
200 struct TestArrayHandleGroupVec
201 {
202 template <typename T>
operator ()__anon2c460e810111::TestArrayHandleGroupVec203 void operator()(T) const
204 {
205 auto numComps = RandomValue<vtkm::IdComponent>::Make(2, 4);
206 auto flat = RandomArrayHandle<T>::Make(ArraySize * numComps);
207 switch (numComps)
208 {
209 case 3:
210 {
211 auto array = vtkm::cont::make_ArrayHandleGroupVec<3>(flat);
212 RunTest(array);
213 RunTest(MakeTestUnknownArrayHandle(array));
214 RunTest(MakeTestUncertainArrayHandle(array));
215 break;
216 }
217 case 4:
218 {
219 auto array = vtkm::cont::make_ArrayHandleGroupVec<4>(flat);
220 RunTest(array);
221 RunTest(MakeTestUnknownArrayHandle(array));
222 RunTest(MakeTestUncertainArrayHandle(array));
223 break;
224 }
225 default:
226 {
227 auto array = vtkm::cont::make_ArrayHandleGroupVec<2>(flat);
228 RunTest(array);
229 RunTest(MakeTestUnknownArrayHandle(array));
230 RunTest(MakeTestUncertainArrayHandle(array));
231 break;
232 }
233 }
234 }
235 };
236
237 struct TestArrayHandleGroupVecVariable
238 {
239 template <typename T>
operator ()__anon2c460e810111::TestArrayHandleGroupVecVariable240 void operator()(T) const
241 {
242 auto rangen = UniformRandomValueGenerator<vtkm::IdComponent>(1, 4);
243 vtkm::Id size = 0;
244
245 std::vector<vtkm::Id> comps(ArraySize);
246 std::generate(comps.begin(), comps.end(), [&size, &rangen]() {
247 auto offset = size;
248 size += rangen();
249 return offset;
250 });
251
252 auto array = vtkm::cont::make_ArrayHandleGroupVecVariable(
253 RandomArrayHandle<T>::Make(size), vtkm::cont::make_ArrayHandle(comps, vtkm::CopyFlag::On));
254 RunTest(array);
255
256 // cannot make a UnknownArrayHandle containing ArrayHandleGroupVecVariable
257 // because of the variable number of components of its values.
258 // RunTest(MakeTestUnknownArrayHandle(array));
259 }
260 };
261
TestArrayHandleIndex()262 void TestArrayHandleIndex()
263 {
264 auto size = RandomValue<vtkm::Id>::Make(2, 10);
265 auto array = vtkm::cont::ArrayHandleIndex(size);
266 RunTest(array);
267 RunTest(MakeTestUnknownArrayHandle(array));
268 RunTest(MakeTestUncertainArrayHandle(array));
269 }
270
271 struct TestArrayHandlePermutation
272 {
273 template <typename T>
operator ()__anon2c460e810111::TestArrayHandlePermutation274 void operator()(T) const
275 {
276 std::uniform_int_distribution<vtkm::Id> distribution(0, ArraySize - 1);
277
278 std::vector<vtkm::Id> inds(ArraySize);
279 std::generate(inds.begin(), inds.end(), [&distribution]() { return distribution(generator); });
280
281 auto array = vtkm::cont::make_ArrayHandlePermutation(
282 RandomArrayHandle<vtkm::Id>::Make(ArraySize, 0, ArraySize - 1),
283 RandomArrayHandle<T>::Make(ArraySize));
284 RunTest(array);
285 RunTest(MakeTestUnknownArrayHandle(array));
286 RunTest(MakeTestUncertainArrayHandle(array));
287 }
288 };
289
290 struct TestArrayHandleReverse
291 {
292 template <typename T>
operator ()__anon2c460e810111::TestArrayHandleReverse293 void operator()(T) const
294 {
295 auto array = vtkm::cont::make_ArrayHandleReverse(RandomArrayHandle<T>::Make(ArraySize));
296 RunTest(array);
297 RunTest(MakeTestUnknownArrayHandle(array));
298 RunTest(MakeTestUncertainArrayHandle(array));
299 }
300 };
301
302 struct TestArrayHandleSwizzle
303 {
304 template <typename T>
operator ()__anon2c460e810111::TestArrayHandleSwizzle305 void operator()(T) const
306 {
307 constexpr vtkm::IdComponent NUM_COMPONENTS = vtkm::VecTraits<T>::NUM_COMPONENTS;
308 vtkm::Vec<vtkm::IdComponent, NUM_COMPONENTS> map;
309 for (vtkm::IdComponent i = 0; i < NUM_COMPONENTS; ++i)
310 {
311 map[i] = NUM_COMPONENTS - (i + 1);
312 }
313 auto array = vtkm::cont::make_ArrayHandleSwizzle(RandomArrayHandle<T>::Make(ArraySize), map);
314 RunTest(array);
315 }
316 };
317
318
MakeRandomArrayHandleUniformPointCoordinates()319 vtkm::cont::ArrayHandleUniformPointCoordinates MakeRandomArrayHandleUniformPointCoordinates()
320 {
321 auto dimensions = RandomValue<vtkm::Id3>::Make(1, 3);
322 auto origin = RandomValue<vtkm::Vec3f>::Make();
323 auto spacing = RandomValue<vtkm::Vec3f>::Make(0.1f, 10.0f);
324 return vtkm::cont::ArrayHandleUniformPointCoordinates(dimensions, origin, spacing);
325 }
326
TestArrayHandleUniformPointCoordinates()327 void TestArrayHandleUniformPointCoordinates()
328 {
329 auto array = MakeRandomArrayHandleUniformPointCoordinates();
330 RunTest(array);
331 RunTest(MakeTestUnknownArrayHandle(array));
332 RunTest(MakeTestUncertainArrayHandle(array));
333 }
334
335
336 //-----------------------------------------------------------------------------
TestArrayHandleSerialization()337 void TestArrayHandleSerialization()
338 {
339 std::cout << "Testing ArrayHandleBasic\n";
340 vtkm::testing::Testing::TryTypes(TestArrayHandleBasic(), TestTypesList());
341 vtkm::testing::Testing::TryTypes(
342 TestArrayHandleBasic(), vtkm::List<char, long, long long, unsigned long, unsigned long long>());
343
344 std::cout << "Testing ArrayHandleSOA\n";
345 vtkm::testing::Testing::TryTypes(TestArrayHandleSOA(), TestTypesListVec());
346
347 std::cout << "Testing ArrayHandleCartesianProduct\n";
348 vtkm::testing::Testing::TryTypes(TestArrayHandleCartesianProduct(), TestTypesListScalar());
349
350 std::cout << "Testing TestArrayHandleCast\n";
351 vtkm::testing::Testing::TryTypes(TestArrayHandleCast(), TestTypesList());
352
353 std::cout << "Testing ArrayHandleConstant\n";
354 vtkm::testing::Testing::TryTypes(TestArrayHandleConstant(), TestTypesList());
355
356 std::cout << "Testing ArrayHandleCounting\n";
357 vtkm::testing::Testing::TryTypes(TestArrayHandleCounting(), TestTypesList());
358
359 std::cout << "Testing ArrayHandleGroupVec\n";
360 vtkm::testing::Testing::TryTypes(TestArrayHandleGroupVec(), TestTypesListScalar());
361
362 std::cout << "Testing ArrayHandleGroupVecVariable\n";
363 vtkm::testing::Testing::TryTypes(TestArrayHandleGroupVecVariable(), TestTypesList());
364
365 std::cout << "Testing ArrayHandleIndex\n";
366 TestArrayHandleIndex();
367
368 std::cout << "Testing ArrayHandlePermutation\n";
369 vtkm::testing::Testing::TryTypes(TestArrayHandlePermutation(), TestTypesList());
370
371 std::cout << "Testing ArrayHandleReverse\n";
372 vtkm::testing::Testing::TryTypes(TestArrayHandleReverse(), TestTypesList());
373
374 std::cout << "Testing ArrayHandleSwizzle\n";
375 vtkm::testing::Testing::TryTypes(TestArrayHandleSwizzle(), TestTypesList());
376
377 std::cout << "Testing ArrayHandleUniformPointCoordinates\n";
378 TestArrayHandleUniformPointCoordinates();
379 }
380
381 } // anonymous namespace
382
383 //-----------------------------------------------------------------------------
UnitTestSerializationArrayHandle(int argc,char * argv[])384 int UnitTestSerializationArrayHandle(int argc, char* argv[])
385 {
386 // Normally VTK-m `Testing::Run` would setup the diy MPI env,
387 // but since we need to access it before execution we have
388 // to manually set it up
389 vtkmdiy::mpi::environment env(argc, argv);
390 auto comm = vtkm::cont::EnvironmentTracker::GetCommunicator();
391
392 decltype(generator)::result_type seed = 0;
393 if (comm.rank() == 0)
394 {
395 seed = static_cast<decltype(seed)>(std::time(nullptr));
396 std::cout << "using seed: " << seed << "\n";
397 }
398 vtkmdiy::mpi::broadcast(comm, seed, 0);
399 generator.seed(seed);
400
401 return vtkm::cont::testing::Testing::Run(TestArrayHandleSerialization, argc, argv);
402 }
403