//============================================================================ // Copyright (c) Kitware, Inc. // All rights reserved. // See LICENSE.txt for details. // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace vtkm::cont::testing::serialization; namespace { //----------------------------------------------------------------------------- struct TestEqualArrayHandle { public: template VTKM_CONT void operator()(const ArrayHandle1& array1, const ArrayHandle2& array2) const { auto result = vtkm::cont::testing::test_equal_ArrayHandles(array1, array2); VTKM_TEST_ASSERT(result, result.GetMergedMessage()); } }; //----------------------------------------------------------------------------- template inline void RunTest(const T& obj) { TestSerialization(obj, TestEqualArrayHandle{}); } //----------------------------------------------------------------------------- constexpr vtkm::Id ArraySize = 10; using TestTypesList = vtkm::ListTagBase>; template inline vtkm::cont::VariantArrayHandleBase> MakeTestVariantArrayHandle(const vtkm::cont::ArrayHandle& array) { return array; } struct TestArrayHandleBasic { template void operator()(T) const { auto array = RandomArrayHandle::Make(ArraySize); RunTest(array); RunTest(MakeTestVariantArrayHandle(array)); } }; struct TestArrayHandleCartesianProduct { template void operator()(T) const { auto array = vtkm::cont::make_ArrayHandleCartesianProduct(RandomArrayHandle::Make(ArraySize), RandomArrayHandle::Make(ArraySize), RandomArrayHandle::Make(ArraySize)); RunTest(array); RunTest(MakeTestVariantArrayHandle(array)); } }; struct TestArrayHandleCast { template void operator()(T) const { auto array = vtkm::cont::make_ArrayHandleCast(RandomArrayHandle::Make(ArraySize)); RunTest(array); RunTest(MakeTestVariantArrayHandle(array)); } template void operator()(vtkm::Vec) const { auto array = vtkm::cont::make_ArrayHandleCast>( RandomArrayHandle>::Make(ArraySize)); RunTest(array); RunTest(MakeTestVariantArrayHandle(array)); } }; struct TestArrayHandleCompositeVector { template void operator()(T) const { auto array = vtkm::cont::make_ArrayHandleCompositeVector(RandomArrayHandle::Make(ArraySize), RandomArrayHandle::Make(ArraySize)); RunTest(array); RunTest(MakeTestVariantArrayHandle(array)); } }; struct TestArrayHandleConcatenate { template void operator()(T) const { auto array = vtkm::cont::make_ArrayHandleConcatenate(RandomArrayHandle::Make(ArraySize), RandomArrayHandle::Make(ArraySize)); RunTest(array); RunTest(MakeTestVariantArrayHandle(array)); } }; struct TestArrayHandleConstant { template void operator()(T) const { T cval = RandomValue::Make(); auto array = vtkm::cont::make_ArrayHandleConstant(cval, ArraySize); RunTest(array); RunTest(MakeTestVariantArrayHandle(array)); } }; struct TestArrayHandleCounting { template void operator()(T) const { T start = RandomValue::Make(); T step = RandomValue::Make(0, 5); auto array = vtkm::cont::make_ArrayHandleCounting(start, step, ArraySize); RunTest(array); RunTest(MakeTestVariantArrayHandle(array)); } }; struct TestArrayHandleExtractComponent { template void operator()(T) const { auto numComps = vtkm::VecTraits::NUM_COMPONENTS; auto array = vtkm::cont::make_ArrayHandleExtractComponent( RandomArrayHandle::Make(ArraySize), RandomValue::Make(0, numComps - 1)); RunTest(array); RunTest(MakeTestVariantArrayHandle(array)); } }; struct TestArrayHandleGroupVec { template void operator()(T) const { auto numComps = RandomValue::Make(2, 4); auto flat = RandomArrayHandle::Make(ArraySize * numComps); switch (numComps) { case 3: { auto array = vtkm::cont::make_ArrayHandleGroupVec<3>(flat); RunTest(array); RunTest(MakeTestVariantArrayHandle(array)); break; } case 4: { auto array = vtkm::cont::make_ArrayHandleGroupVec<4>(flat); RunTest(array); RunTest(MakeTestVariantArrayHandle(array)); break; } default: { auto array = vtkm::cont::make_ArrayHandleGroupVec<2>(flat); RunTest(array); RunTest(MakeTestVariantArrayHandle(array)); break; } } } }; struct TestArrayHandleGroupVecVariable { template void operator()(T) const { auto rangen = UniformRandomValueGenerator(1, 4); vtkm::Id size = 0; std::vector comps(ArraySize); std::generate(comps.begin(), comps.end(), [&size, &rangen]() { auto offset = size; size += rangen(); return offset; }); auto array = vtkm::cont::make_ArrayHandleGroupVecVariable(RandomArrayHandle::Make(size), vtkm::cont::make_ArrayHandle(comps)); RunTest(array); // cannot make a VariantArrayHandle containing ArrayHandleGroupVecVariable // because of the variable number of components of its values. // RunTest(MakeTestVariantArrayHandle(array)); } }; struct TestArrayHandleImplicit { template struct ImplicitFunctor { ImplicitFunctor() = default; explicit ImplicitFunctor(const T& factor) : Factor(factor) { } VTKM_EXEC_CONT T operator()(vtkm::Id index) const { return static_cast(this->Factor * static_cast::ComponentType>(index)); } T Factor; }; template void operator()(T) const { ImplicitFunctor functor(RandomValue::Make(2, 9)); auto array = vtkm::cont::make_ArrayHandleImplicit(functor, ArraySize); RunTest(array); RunTest(MakeTestVariantArrayHandle(array)); } }; void TestArrayHandleIndex() { auto size = RandomValue::Make(2, 10); auto array = vtkm::cont::ArrayHandleIndex(size); RunTest(array); RunTest(MakeTestVariantArrayHandle(array)); } struct TestArrayHandlePermutation { template void operator()(T) const { std::uniform_int_distribution distribution(0, ArraySize - 1); std::vector inds(ArraySize); std::generate(inds.begin(), inds.end(), [&distribution]() { return distribution(generator); }); auto array = vtkm::cont::make_ArrayHandlePermutation( RandomArrayHandle::Make(ArraySize, 0, ArraySize - 1), RandomArrayHandle::Make(ArraySize)); RunTest(array); RunTest(MakeTestVariantArrayHandle(array)); } }; struct TestArrayHandleReverse { template void operator()(T) const { auto array = vtkm::cont::make_ArrayHandleReverse(RandomArrayHandle::Make(ArraySize)); RunTest(array); RunTest(MakeTestVariantArrayHandle(array)); } }; struct TestArrayHandleSwizzle { template void operator()(T) const { static const vtkm::Vec map2s[6] = { { 0, 1 }, { 0, 2 }, { 1, 0 }, { 1, 2 }, { 2, 0 }, { 2, 1 } }; static const vtkm::Vec map3s[6] = { { 0, 1, 2 }, { 0, 2, 1 }, { 1, 0, 2 }, { 1, 2, 0 }, { 2, 0, 1 }, { 2, 1, 0 } }; auto numOutComps = RandomValue::Make(2, 3); switch (numOutComps) { case 2: { auto array = make_ArrayHandleSwizzle(RandomArrayHandle>::Make(ArraySize), map2s[RandomValue::Make(0, 5)]); RunTest(array); RunTest(MakeTestVariantArrayHandle(array)); break; } case 3: default: { auto array = make_ArrayHandleSwizzle(RandomArrayHandle>::Make(ArraySize), map3s[RandomValue::Make(0, 5)]); RunTest(array); RunTest(MakeTestVariantArrayHandle(array)); break; } } } }; struct TestArrayHandleTransform { struct TransformFunctor { template VTKM_EXEC_CONT T operator()(const T& in) const { return static_cast(in * T{ 2 }); } }; struct InverseTransformFunctor { template VTKM_EXEC_CONT T operator()(const T& in) const { return static_cast(in / T{ 2 }); } }; template void TestType1() const { auto array = vtkm::cont::make_ArrayHandleTransform(RandomArrayHandle::Make(ArraySize), TransformFunctor{}); RunTest(array); RunTest(MakeTestVariantArrayHandle(array)); } template void TestType2() const { auto array = vtkm::cont::make_ArrayHandleTransform( RandomArrayHandle::Make(ArraySize), TransformFunctor{}, InverseTransformFunctor{}); RunTest(array); RunTest(MakeTestVariantArrayHandle(array)); } template void operator()(T) const { this->TestType1(); this->TestType2(); } }; vtkm::cont::ArrayHandleUniformPointCoordinates MakeRandomArrayHandleUniformPointCoordinates() { auto dimensions = RandomValue::Make(1, 3); auto origin = RandomValue>::Make(); auto spacing = RandomValue>::Make(0.1f, 10.0f); return vtkm::cont::ArrayHandleUniformPointCoordinates(dimensions, origin, spacing); } void TestArrayHandleUniformPointCoordinates() { auto array = MakeRandomArrayHandleUniformPointCoordinates(); RunTest(array); RunTest(MakeTestVariantArrayHandle(array)); } void TestArrayHandleVirtualCoordinates() { int type = RandomValue::Make(0, 2); vtkm::cont::ArrayHandleVirtualCoordinates array; switch (type) { case 0: array = vtkm::cont::ArrayHandleVirtualCoordinates(MakeRandomArrayHandleUniformPointCoordinates()); break; case 1: array = vtkm::cont::ArrayHandleVirtualCoordinates(vtkm::cont::make_ArrayHandleCartesianProduct( RandomArrayHandle::Make(ArraySize), RandomArrayHandle::Make(ArraySize), RandomArrayHandle::Make(ArraySize))); break; default: array = vtkm::cont::ArrayHandleVirtualCoordinates( RandomArrayHandle>::Make(ArraySize)); break; } RunTest(array); RunTest(MakeTestVariantArrayHandle(array)); } struct TestArrayHandleZip { template void operator()(T) const { auto array = vtkm::cont::make_ArrayHandleZip(RandomArrayHandle::Make(ArraySize), vtkm::cont::ArrayHandleIndex(ArraySize)); RunTest(array); RunTest(MakeTestVariantArrayHandle(array)); } }; //----------------------------------------------------------------------------- void TestArrayHandleSerialization() { std::cout << "Testing ArrayHandleBasic\n"; vtkm::testing::Testing::TryTypes(TestArrayHandleBasic(), TestTypesList()); std::cout << "Testing ArrayHandleCartesianProduct\n"; vtkm::testing::Testing::TryTypes(TestArrayHandleCartesianProduct(), TestTypesList()); std::cout << "Testing TestArrayHandleCast\n"; vtkm::testing::Testing::TryTypes(TestArrayHandleCast(), TestTypesList()); std::cout << "Testing ArrayHandleCompositeVector\n"; vtkm::testing::Testing::TryTypes(TestArrayHandleCompositeVector(), TestTypesList()); std::cout << "Testing ArrayHandleConcatenate\n"; vtkm::testing::Testing::TryTypes(TestArrayHandleConcatenate(), TestTypesList()); std::cout << "Testing ArrayHandleConstant\n"; vtkm::testing::Testing::TryTypes(TestArrayHandleConstant(), TestTypesList()); std::cout << "Testing ArrayHandleCounting\n"; vtkm::testing::Testing::TryTypes(TestArrayHandleCounting(), TestTypesList()); std::cout << "Testing ArrayHandleExtractComponent\n"; vtkm::testing::Testing::TryTypes(TestArrayHandleExtractComponent(), TestTypesList()); std::cout << "Testing ArrayHandleGroupVec\n"; vtkm::testing::Testing::TryTypes(TestArrayHandleGroupVec(), TestTypesList()); std::cout << "Testing ArrayHandleGroupVecVariable\n"; vtkm::testing::Testing::TryTypes(TestArrayHandleGroupVecVariable(), TestTypesList()); std::cout << "Testing ArrayHandleImplicit\n"; vtkm::testing::Testing::TryTypes(TestArrayHandleImplicit(), TestTypesList()); std::cout << "Testing ArrayHandleIndex\n"; TestArrayHandleIndex(); std::cout << "Testing ArrayHandlePermutation\n"; vtkm::testing::Testing::TryTypes(TestArrayHandlePermutation(), TestTypesList()); std::cout << "Testing ArrayHandleReverse\n"; vtkm::testing::Testing::TryTypes(TestArrayHandleReverse(), TestTypesList()); std::cout << "Testing ArrayHandleSwizzle\n"; vtkm::testing::Testing::TryTypes(TestArrayHandleSwizzle(), TestTypesList()); std::cout << "Testing ArrayHandleTransform\n"; vtkm::testing::Testing::TryTypes(TestArrayHandleTransform(), TestTypesList()); std::cout << "Testing ArrayHandleUniformPointCoordinates\n"; TestArrayHandleUniformPointCoordinates(); std::cout << "Testing ArrayHandleVirtualCoordinates\n"; TestArrayHandleVirtualCoordinates(); std::cout << "Testing ArrayHandleZip\n"; vtkm::testing::Testing::TryTypes(TestArrayHandleZip(), TestTypesList()); } } // anonymous namespace //----------------------------------------------------------------------------- int UnitTestSerializationArrayHandle(int argc, char* argv[]) { auto comm = vtkm::cont::EnvironmentTracker::GetCommunicator(); decltype(generator)::result_type seed = 0; if (comm.rank() == 0) { seed = static_cast(std::time(nullptr)); std::cout << "using seed: " << seed << "\n"; } vtkmdiy::mpi::broadcast(comm, seed, 0); generator.seed(seed); return vtkm::cont::testing::Testing::Run(TestArrayHandleSerialization, argc, argv); } //----------------------------------------------------------------------------- namespace vtkm { namespace cont { template struct SerializableTypeString> { static VTKM_CONT const std::string& Get() { static std::string name = "TestArrayHandleImplicit::ImplicitFunctor<" + SerializableTypeString::Get() + ">"; return name; } }; template <> struct SerializableTypeString { static VTKM_CONT const std::string Get() { return "TestArrayHandleTransform::TransformFunctor"; } }; template <> struct SerializableTypeString { static VTKM_CONT const std::string Get() { return "TestArrayHandleTransform::InverseTransformFunctor"; } }; } } // vtkm::cont