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 #include <vtkm/cont/ArrayHandle.h>
21 #include <vtkm/cont/ArrayHandleCartesianProduct.h>
22 #include <vtkm/cont/ArrayHandleCast.h>
23 #include <vtkm/cont/ArrayHandleCompositeVector.h>
24 #include <vtkm/cont/ArrayHandleConcatenate.h>
25 #include <vtkm/cont/ArrayHandleConstant.h>
26 #include <vtkm/cont/ArrayHandleCounting.h>
27 #include <vtkm/cont/ArrayHandleExtractComponent.h>
28 #include <vtkm/cont/ArrayHandleGroupVec.h>
29 #include <vtkm/cont/ArrayHandleGroupVecVariable.h>
30 #include <vtkm/cont/ArrayHandleImplicit.h>
31 #include <vtkm/cont/ArrayHandleIndex.h>
32 #include <vtkm/cont/ArrayHandlePermutation.h>
33 #include <vtkm/cont/ArrayHandleReverse.h>
34 #include <vtkm/cont/ArrayHandleSwizzle.h>
35 #include <vtkm/cont/ArrayHandleTransform.h>
36 #include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
37 #include <vtkm/cont/ArrayHandleVirtualCoordinates.h>
38 #include <vtkm/cont/ArrayHandleZip.h>
39 #include <vtkm/cont/DynamicArrayHandle.h>
40
41 #include <vtkm/cont/testing/TestingSerialization.h>
42
43 #include <vtkm/VecTraits.h>
44
45 #include <ctime>
46 #include <type_traits>
47 #include <vector>
48
49 using namespace vtkm::cont::testing::serialization;
50
51 namespace
52 {
53
54 //-----------------------------------------------------------------------------
55 struct TestEqualArrayHandle
56 {
57 public:
58 template <typename ArrayHandle1, typename ArrayHandle2>
operator ()__anon257a451a0111::TestEqualArrayHandle59 VTKM_CONT void operator()(const ArrayHandle1& array1, const ArrayHandle2& array2) const
60 {
61 auto result = vtkm::cont::testing::test_equal_ArrayHandles(array1, array2);
62 VTKM_TEST_ASSERT(result, result.GetMergedMessage());
63 }
64 };
65
66 //-----------------------------------------------------------------------------
67 template <typename T>
RunTest(const T & obj)68 inline void RunTest(const T& obj)
69 {
70 TestSerialization(obj, TestEqualArrayHandle{});
71 }
72
73 //-----------------------------------------------------------------------------
74 constexpr vtkm::Id ArraySize = 10;
75
76 using TestTypesList =
77 vtkm::ListTagBase<vtkm::Int8, vtkm::Id, vtkm::FloatDefault, vtkm::Vec<vtkm::FloatDefault, 3>>;
78 using TestStorageList = vtkm::ListTagBase<vtkm::cont::StorageTagBasic>;
79
80 template <typename T, typename S>
81 inline vtkm::cont::DynamicArrayHandleBase<vtkm::ListTagAppendUnique<TestTypesList, T>,
82 vtkm::ListTagAppendUnique<TestStorageList, S>>
MakeTestDynamicArrayHandle(const vtkm::cont::ArrayHandle<T,S> & array)83 MakeTestDynamicArrayHandle(const vtkm::cont::ArrayHandle<T, S>& array)
84 {
85 return array;
86 }
87
88 struct TestArrayHandleBasic
89 {
90 template <typename T>
operator ()__anon257a451a0111::TestArrayHandleBasic91 void operator()(T) const
92 {
93 auto array = RandomArrayHandle<T>::Make(ArraySize);
94 RunTest(array);
95 RunTest(MakeTestDynamicArrayHandle(array));
96 }
97 };
98
99 struct TestArrayHandleCartesianProduct
100 {
101 template <typename T>
operator ()__anon257a451a0111::TestArrayHandleCartesianProduct102 void operator()(T) const
103 {
104 auto array =
105 vtkm::cont::make_ArrayHandleCartesianProduct(RandomArrayHandle<T>::Make(ArraySize),
106 RandomArrayHandle<T>::Make(ArraySize),
107 RandomArrayHandle<T>::Make(ArraySize));
108 RunTest(array);
109 RunTest(MakeTestDynamicArrayHandle(array));
110 }
111 };
112
113 struct TestArrayHandleCast
114 {
115 template <typename T>
operator ()__anon257a451a0111::TestArrayHandleCast116 void operator()(T) const
117 {
118 auto array =
119 vtkm::cont::make_ArrayHandleCast(RandomArrayHandle<vtkm::Int8>::Make(ArraySize), T{});
120 RunTest(array);
121 RunTest(MakeTestDynamicArrayHandle(array));
122 }
123 };
124
125 struct TestArrayHandleCompositeVector
126 {
127 template <typename T>
operator ()__anon257a451a0111::TestArrayHandleCompositeVector128 void operator()(T) const
129 {
130 auto array = vtkm::cont::make_ArrayHandleCompositeVector(RandomArrayHandle<T>::Make(ArraySize),
131 RandomArrayHandle<T>::Make(ArraySize));
132 RunTest(array);
133 RunTest(MakeTestDynamicArrayHandle(array));
134 }
135 };
136
137 struct TestArrayHandleConcatenate
138 {
139 template <typename T>
operator ()__anon257a451a0111::TestArrayHandleConcatenate140 void operator()(T) const
141 {
142 auto array = vtkm::cont::make_ArrayHandleConcatenate(RandomArrayHandle<T>::Make(ArraySize),
143 RandomArrayHandle<T>::Make(ArraySize));
144 RunTest(array);
145 RunTest(MakeTestDynamicArrayHandle(array));
146 }
147 };
148
149 struct TestArrayHandleConstant
150 {
151 template <typename T>
operator ()__anon257a451a0111::TestArrayHandleConstant152 void operator()(T) const
153 {
154 T cval = RandomValue<T>::Make();
155 auto array = vtkm::cont::make_ArrayHandleConstant(cval, ArraySize);
156 RunTest(array);
157 RunTest(MakeTestDynamicArrayHandle(array));
158 }
159 };
160
161 struct TestArrayHandleCounting
162 {
163 template <typename T>
operator ()__anon257a451a0111::TestArrayHandleCounting164 void operator()(T) const
165 {
166 T start = RandomValue<T>::Make();
167 T step = RandomValue<T>::Make(0, 5);
168 auto array = vtkm::cont::make_ArrayHandleCounting(start, step, ArraySize);
169 RunTest(array);
170 RunTest(MakeTestDynamicArrayHandle(array));
171 }
172 };
173
174 struct TestArrayHandleExtractComponent
175 {
176 template <typename T>
operator ()__anon257a451a0111::TestArrayHandleExtractComponent177 void operator()(T) const
178 {
179 auto numComps = vtkm::VecTraits<T>::NUM_COMPONENTS;
180 auto array = vtkm::cont::make_ArrayHandleExtractComponent(
181 RandomArrayHandle<T>::Make(ArraySize), RandomValue<vtkm::IdComponent>::Make(0, numComps - 1));
182 RunTest(array);
183 RunTest(MakeTestDynamicArrayHandle(array));
184 }
185 };
186
187 struct TestArrayHandleGroupVec
188 {
189 template <typename T>
operator ()__anon257a451a0111::TestArrayHandleGroupVec190 void operator()(T) const
191 {
192 auto numComps = RandomValue<vtkm::IdComponent>::Make(2, 4);
193 auto flat = RandomArrayHandle<T>::Make(ArraySize * numComps);
194 switch (numComps)
195 {
196 case 3:
197 {
198 auto array = vtkm::cont::make_ArrayHandleGroupVec<3>(flat);
199 RunTest(array);
200 RunTest(MakeTestDynamicArrayHandle(array));
201 break;
202 }
203 case 4:
204 {
205 auto array = vtkm::cont::make_ArrayHandleGroupVec<4>(flat);
206 RunTest(array);
207 RunTest(MakeTestDynamicArrayHandle(array));
208 break;
209 }
210 default:
211 {
212 auto array = vtkm::cont::make_ArrayHandleGroupVec<2>(flat);
213 RunTest(array);
214 RunTest(MakeTestDynamicArrayHandle(array));
215 break;
216 }
217 }
218 }
219 };
220
221 struct TestArrayHandleGroupVecVariable
222 {
223 template <typename T>
operator ()__anon257a451a0111::TestArrayHandleGroupVecVariable224 void operator()(T) const
225 {
226 auto rangen = UniformRandomValueGenerator<vtkm::IdComponent>(1, 4);
227 vtkm::Id size = 0;
228
229 std::vector<vtkm::Id> comps(ArraySize);
230 std::generate(comps.begin(), comps.end(), [&size, &rangen]() {
231 auto offset = size;
232 size += rangen();
233 return offset;
234 });
235
236 auto array = vtkm::cont::make_ArrayHandleGroupVecVariable(RandomArrayHandle<T>::Make(size),
237 vtkm::cont::make_ArrayHandle(comps));
238 RunTest(array);
239
240 // cannot make a DynamicArrayHandle containing ArrayHandleGroupVecVariable
241 // because of the variable number of components of its values.
242 // RunTest(MakeTestDynamicArrayHandle(array));
243 }
244 };
245
246 struct TestArrayHandleImplicit
247 {
248 template <typename T>
249 struct ImplicitFunctor
250 {
251 ImplicitFunctor() = default;
252
ImplicitFunctor__anon257a451a0111::TestArrayHandleImplicit::ImplicitFunctor253 explicit ImplicitFunctor(const T& factor)
254 : Factor(factor)
255 {
256 }
257
operator ()__anon257a451a0111::TestArrayHandleImplicit::ImplicitFunctor258 VTKM_EXEC_CONT T operator()(vtkm::Id index) const
259 {
260 return static_cast<T>(this->Factor *
261 static_cast<typename vtkm::VecTraits<T>::ComponentType>(index));
262 }
263
264 T Factor;
265 };
266
267 template <typename T>
operator ()__anon257a451a0111::TestArrayHandleImplicit268 void operator()(T) const
269 {
270 ImplicitFunctor<T> functor(RandomValue<T>::Make(2, 9));
271 auto array = vtkm::cont::make_ArrayHandleImplicit(functor, ArraySize);
272 RunTest(array);
273 RunTest(MakeTestDynamicArrayHandle(array));
274 }
275 };
276
TestArrayHandleIndex()277 void TestArrayHandleIndex()
278 {
279 auto size = RandomValue<vtkm::Id>::Make(2, 10);
280 auto array = vtkm::cont::ArrayHandleIndex(size);
281 RunTest(array);
282 RunTest(MakeTestDynamicArrayHandle(array));
283 }
284
285 struct TestArrayHandlePermutation
286 {
287 template <typename T>
operator ()__anon257a451a0111::TestArrayHandlePermutation288 void operator()(T) const
289 {
290 std::uniform_int_distribution<vtkm::Id> distribution(0, ArraySize - 1);
291
292 std::vector<vtkm::Id> inds(ArraySize);
293 std::generate(inds.begin(), inds.end(), [&distribution]() { return distribution(generator); });
294
295 auto array = vtkm::cont::make_ArrayHandlePermutation(
296 RandomArrayHandle<vtkm::Id>::Make(ArraySize, 0, ArraySize - 1),
297 RandomArrayHandle<T>::Make(ArraySize));
298 RunTest(array);
299 RunTest(MakeTestDynamicArrayHandle(array));
300 }
301 };
302
303 struct TestArrayHandleReverse
304 {
305 template <typename T>
operator ()__anon257a451a0111::TestArrayHandleReverse306 void operator()(T) const
307 {
308 auto array = vtkm::cont::make_ArrayHandleReverse(RandomArrayHandle<T>::Make(ArraySize));
309 RunTest(array);
310 RunTest(MakeTestDynamicArrayHandle(array));
311 }
312 };
313
314 struct TestArrayHandleSwizzle
315 {
316 template <typename T>
operator ()__anon257a451a0111::TestArrayHandleSwizzle317 void operator()(T) const
318 {
319 static const vtkm::Vec<vtkm::IdComponent, 2> map2s[6] = { { 0, 1 }, { 0, 2 }, { 1, 0 },
320 { 1, 2 }, { 2, 0 }, { 2, 1 } };
321 static const vtkm::Vec<vtkm::IdComponent, 3> map3s[6] = {
322 { 0, 1, 2 }, { 0, 2, 1 }, { 1, 0, 2 }, { 1, 2, 0 }, { 2, 0, 1 }, { 2, 1, 0 }
323 };
324
325 auto numOutComps = RandomValue<vtkm::IdComponent>::Make(2, 3);
326 switch (numOutComps)
327 {
328 case 2:
329 {
330 auto array = make_ArrayHandleSwizzle(RandomArrayHandle<vtkm::Vec<T, 3>>::Make(ArraySize),
331 map2s[RandomValue<int>::Make(0, 5)]);
332 RunTest(array);
333 RunTest(MakeTestDynamicArrayHandle(array));
334 break;
335 }
336 case 3:
337 default:
338 {
339 auto array = make_ArrayHandleSwizzle(RandomArrayHandle<vtkm::Vec<T, 3>>::Make(ArraySize),
340 map3s[RandomValue<int>::Make(0, 5)]);
341 RunTest(array);
342 RunTest(MakeTestDynamicArrayHandle(array));
343 break;
344 }
345 }
346 }
347 };
348
349 struct TestArrayHandleTransform
350 {
351 struct TransformFunctor
352 {
353 template <typename T>
operator ()__anon257a451a0111::TestArrayHandleTransform::TransformFunctor354 VTKM_EXEC_CONT T operator()(const T& in) const
355 {
356 return static_cast<T>(in * T{ 2 });
357 }
358 };
359
360 struct InverseTransformFunctor
361 {
362 template <typename T>
operator ()__anon257a451a0111::TestArrayHandleTransform::InverseTransformFunctor363 VTKM_EXEC_CONT T operator()(const T& in) const
364 {
365 return in / T{ 2 };
366 }
367 };
368
369 template <typename T>
TestType1__anon257a451a0111::TestArrayHandleTransform370 void TestType1() const
371 {
372 auto array = vtkm::cont::make_ArrayHandleTransform(RandomArrayHandle<T>::Make(ArraySize),
373 TransformFunctor{});
374 RunTest(array);
375 RunTest(MakeTestDynamicArrayHandle(array));
376 }
377
378 template <typename T>
TestType2__anon257a451a0111::TestArrayHandleTransform379 void TestType2() const
380 {
381 auto array = vtkm::cont::make_ArrayHandleTransform(
382 RandomArrayHandle<T>::Make(ArraySize), TransformFunctor{}, InverseTransformFunctor{});
383 RunTest(array);
384 RunTest(MakeTestDynamicArrayHandle(array));
385 }
386
387 template <typename T>
operator ()__anon257a451a0111::TestArrayHandleTransform388 void operator()(T) const
389 {
390 this->TestType1<T>();
391 this->TestType2<T>();
392 }
393 };
394
MakeRandomArrayHandleUniformPointCoordinates()395 vtkm::cont::ArrayHandleUniformPointCoordinates MakeRandomArrayHandleUniformPointCoordinates()
396 {
397 auto dimensions = RandomValue<vtkm::Id3>::Make(1, 3);
398 auto origin = RandomValue<vtkm::Vec<vtkm::FloatDefault, 3>>::Make();
399 auto spacing = RandomValue<vtkm::Vec<vtkm::FloatDefault, 3>>::Make(0.1f, 10.0f);
400 return vtkm::cont::ArrayHandleUniformPointCoordinates(dimensions, origin, spacing);
401 }
402
TestArrayHandleUniformPointCoordinates()403 void TestArrayHandleUniformPointCoordinates()
404 {
405 auto array = MakeRandomArrayHandleUniformPointCoordinates();
406 RunTest(array);
407 RunTest(MakeTestDynamicArrayHandle(array));
408 }
409
TestArrayHandleVirtualCoordinates()410 void TestArrayHandleVirtualCoordinates()
411 {
412 int type = RandomValue<int>::Make(0, 2);
413
414 vtkm::cont::ArrayHandleVirtualCoordinates array;
415 switch (type)
416 {
417 case 0:
418 array =
419 vtkm::cont::ArrayHandleVirtualCoordinates(MakeRandomArrayHandleUniformPointCoordinates());
420 break;
421 case 1:
422 array =
423 vtkm::cont::ArrayHandleVirtualCoordinates(vtkm::cont::make_ArrayHandleCartesianProduct(
424 RandomArrayHandle<vtkm::FloatDefault>::Make(ArraySize),
425 RandomArrayHandle<vtkm::FloatDefault>::Make(ArraySize),
426 RandomArrayHandle<vtkm::FloatDefault>::Make(ArraySize)));
427 break;
428 default:
429 array = vtkm::cont::ArrayHandleVirtualCoordinates(
430 RandomArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>>::Make(ArraySize));
431 break;
432 }
433
434 RunTest(array);
435 RunTest(MakeTestDynamicArrayHandle(array));
436 }
437
438 struct TestArrayHandleZip
439 {
440 template <typename T>
operator ()__anon257a451a0111::TestArrayHandleZip441 void operator()(T) const
442 {
443 auto array = vtkm::cont::make_ArrayHandleZip(RandomArrayHandle<T>::Make(ArraySize),
444 vtkm::cont::ArrayHandleIndex(ArraySize));
445 RunTest(array);
446 RunTest(MakeTestDynamicArrayHandle(array));
447 }
448 };
449
450 //-----------------------------------------------------------------------------
TestArrayHandleSerialization()451 void TestArrayHandleSerialization()
452 {
453 std::cout << "Testing ArrayHandleBasic\n";
454 vtkm::testing::Testing::TryTypes(TestArrayHandleBasic(), TestTypesList());
455
456 std::cout << "Testing ArrayHandleCartesianProduct\n";
457 vtkm::testing::Testing::TryTypes(TestArrayHandleCartesianProduct(), TestTypesList());
458
459 std::cout << "Testing TestArrayHandleCast\n";
460 vtkm::testing::Testing::TryTypes(TestArrayHandleCast(), TestTypesList());
461
462 std::cout << "Testing ArrayHandleCompositeVector\n";
463 vtkm::testing::Testing::TryTypes(TestArrayHandleCompositeVector(), TestTypesList());
464
465 std::cout << "Testing ArrayHandleConcatenate\n";
466 vtkm::testing::Testing::TryTypes(TestArrayHandleConcatenate(), TestTypesList());
467
468 std::cout << "Testing ArrayHandleConstant\n";
469 vtkm::testing::Testing::TryTypes(TestArrayHandleConstant(), TestTypesList());
470
471 std::cout << "Testing ArrayHandleCounting\n";
472 vtkm::testing::Testing::TryTypes(TestArrayHandleCounting(), TestTypesList());
473
474 std::cout << "Testing ArrayHandleExtractComponent\n";
475 vtkm::testing::Testing::TryTypes(TestArrayHandleExtractComponent(), TestTypesList());
476
477 std::cout << "Testing ArrayHandleGroupVec\n";
478 vtkm::testing::Testing::TryTypes(TestArrayHandleGroupVec(), TestTypesList());
479
480 std::cout << "Testing ArrayHandleGroupVecVariable\n";
481 vtkm::testing::Testing::TryTypes(TestArrayHandleGroupVecVariable(), TestTypesList());
482
483 std::cout << "Testing ArrayHandleImplicit\n";
484 vtkm::testing::Testing::TryTypes(TestArrayHandleImplicit(), TestTypesList());
485
486 std::cout << "Testing ArrayHandleIndex\n";
487 TestArrayHandleIndex();
488
489 std::cout << "Testing ArrayHandlePermutation\n";
490 vtkm::testing::Testing::TryTypes(TestArrayHandlePermutation(), TestTypesList());
491
492 std::cout << "Testing ArrayHandleReverse\n";
493 vtkm::testing::Testing::TryTypes(TestArrayHandleReverse(), TestTypesList());
494
495 std::cout << "Testing ArrayHandleSwizzle\n";
496 vtkm::testing::Testing::TryTypes(TestArrayHandleSwizzle(), TestTypesList());
497
498 std::cout << "Testing ArrayHandleTransform\n";
499 vtkm::testing::Testing::TryTypes(TestArrayHandleTransform(), TestTypesList());
500
501 std::cout << "Testing ArrayHandleUniformPointCoordinates\n";
502 TestArrayHandleUniformPointCoordinates();
503
504 std::cout << "Testing ArrayHandleVirtualCoordinates\n";
505 TestArrayHandleVirtualCoordinates();
506
507 std::cout << "Testing ArrayHandleZip\n";
508 vtkm::testing::Testing::TryTypes(TestArrayHandleZip(), TestTypesList());
509 }
510
511 } // anonymous namespace
512
513 //-----------------------------------------------------------------------------
UnitTestSerializationArrayHandle(int,char * [])514 int UnitTestSerializationArrayHandle(int, char* [])
515 {
516 auto comm = vtkm::cont::EnvironmentTracker::GetCommunicator();
517
518 decltype(generator)::result_type seed = 0;
519 if (comm.rank() == 0)
520 {
521 seed = static_cast<decltype(seed)>(std::time(nullptr));
522 std::cout << "using seed: " << seed << "\n";
523 }
524 diy::mpi::broadcast(comm, seed, 0);
525 generator.seed(seed);
526
527 return vtkm::cont::testing::Testing::Run(TestArrayHandleSerialization);
528 }
529
530 //-----------------------------------------------------------------------------
531 namespace vtkm
532 {
533 namespace cont
534 {
535
536 template <typename T>
537 struct TypeString<TestArrayHandleImplicit::ImplicitFunctor<T>>
538 {
Getvtkm::cont::TypeString539 static VTKM_CONT const std::string& Get()
540 {
541 static std::string name =
542 "TestArrayHandleImplicit::ImplicitFunctor<" + TypeString<T>::Get() + ">";
543 return name;
544 }
545 };
546
547 template <>
548 struct TypeString<TestArrayHandleTransform::TransformFunctor>
549 {
Getvtkm::cont::TypeString550 static VTKM_CONT const std::string Get() { return "TestArrayHandleTransform::TransformFunctor"; }
551 };
552
553 template <>
554 struct TypeString<TestArrayHandleTransform::InverseTransformFunctor>
555 {
Getvtkm::cont::TypeString556 static VTKM_CONT const std::string Get()
557 {
558 return "TestArrayHandleTransform::InverseTransformFunctor";
559 }
560 };
561 }
562 } // vtkm::cont
563