//============================================================================ // 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 namespace { const vtkm::Id ARRAY_SIZE = 10; using StorageTag = vtkm::cont::StorageTagBasic; vtkm::FloatDefault TestValue3Ids(vtkm::Id index, vtkm::IdComponent inComponentIndex, int inArrayId) { return (vtkm::FloatDefault(index) + 0.1f * vtkm::FloatDefault(inComponentIndex) + 0.01f * vtkm::FloatDefault(inArrayId)); } template vtkm::cont::ArrayHandle MakeInputArray(int arrayId) { using VTraits = vtkm::VecTraits; // Create a buffer with valid test values. ValueType buffer[ARRAY_SIZE]; for (vtkm::Id index = 0; index < ARRAY_SIZE; index++) { for (vtkm::IdComponent componentIndex = 0; componentIndex < VTraits::NUM_COMPONENTS; componentIndex++) { VTraits::SetComponent( buffer[index], componentIndex, TestValue3Ids(index, componentIndex, arrayId)); } } // Make an array handle that points to this buffer. return vtkm::cont::make_ArrayHandle(buffer, ARRAY_SIZE, vtkm::CopyFlag::On); } template void CheckArray(const vtkm::cont::ArrayHandle& outArray, const vtkm::IdComponent* inComponents, const int* inArrayIds) { // ArrayHandleCompositeVector currently does not implement the ability to // get to values on the control side, so copy to an array that is accessible. using ArrayHandleType = vtkm::cont::ArrayHandle; ArrayHandleType arrayCopy; vtkm::cont::ArrayCopy(outArray, arrayCopy); typename ArrayHandleType::ReadPortalType portal = arrayCopy.ReadPortal(); using VTraits = vtkm::VecTraits; for (vtkm::Id index = 0; index < ARRAY_SIZE; index++) { ValueType retreivedValue = portal.Get(index); for (vtkm::IdComponent componentIndex = 0; componentIndex < VTraits::NUM_COMPONENTS; componentIndex++) { vtkm::FloatDefault retrievedComponent = VTraits::GetComponent(retreivedValue, componentIndex); vtkm::FloatDefault expectedComponent = TestValue3Ids(index, inComponents[componentIndex], inArrayIds[componentIndex]); VTKM_TEST_ASSERT(retrievedComponent == expectedComponent, "Got bad value."); } } } template void TryScalarArray() { std::cout << "Creating a scalar array from one of " << inComponents << " components." << std::endl; using InValueType = vtkm::Vec; using InArrayType = vtkm::cont::ArrayHandle; int inArrayId = 0; InArrayType inArray = MakeInputArray(inArrayId); for (vtkm::IdComponent inComponentIndex = 0; inComponentIndex < inComponents; inComponentIndex++) { auto c1 = vtkm::cont::make_ArrayHandleExtractComponent(inArray, inComponentIndex); auto composite = vtkm::cont::make_ArrayHandleCompositeVector(c1); CheckArray(composite, &inComponentIndex, &inArrayId); } } template void TryVector4(vtkm::cont::ArrayHandle array1, vtkm::cont::ArrayHandle array2, vtkm::cont::ArrayHandle array3, vtkm::cont::ArrayHandle array4) { int arrayIds[4] = { 0, 1, 2, 3 }; vtkm::IdComponent inComponents[4]; for (inComponents[0] = 0; inComponents[0] < vtkm::VecTraits::NUM_COMPONENTS; inComponents[0]++) { auto c1 = vtkm::cont::make_ArrayHandleExtractComponent(array1, inComponents[0]); for (inComponents[1] = 0; inComponents[1] < vtkm::VecTraits::NUM_COMPONENTS; inComponents[1]++) { auto c2 = vtkm::cont::make_ArrayHandleExtractComponent(array2, inComponents[1]); for (inComponents[2] = 0; inComponents[2] < vtkm::VecTraits::NUM_COMPONENTS; inComponents[2]++) { auto c3 = vtkm::cont::make_ArrayHandleExtractComponent(array3, inComponents[2]); for (inComponents[3] = 0; inComponents[3] < vtkm::VecTraits::NUM_COMPONENTS; inComponents[3]++) { auto c4 = vtkm::cont::make_ArrayHandleExtractComponent(array4, inComponents[3]); CheckArray( vtkm::cont::make_ArrayHandleCompositeVector(c1, c2, c3, c4), inComponents, arrayIds); } } } } } template void TryVector3(vtkm::cont::ArrayHandle array1, vtkm::cont::ArrayHandle array2, vtkm::cont::ArrayHandle array3) { int arrayIds[3] = { 0, 1, 2 }; vtkm::IdComponent inComponents[3]; for (inComponents[0] = 0; inComponents[0] < vtkm::VecTraits::NUM_COMPONENTS; inComponents[0]++) { auto c1 = vtkm::cont::make_ArrayHandleExtractComponent(array1, inComponents[0]); for (inComponents[1] = 0; inComponents[1] < vtkm::VecTraits::NUM_COMPONENTS; inComponents[1]++) { auto c2 = vtkm::cont::make_ArrayHandleExtractComponent(array2, inComponents[1]); for (inComponents[2] = 0; inComponents[2] < vtkm::VecTraits::NUM_COMPONENTS; inComponents[2]++) { auto c3 = vtkm::cont::make_ArrayHandleExtractComponent(array3, inComponents[2]); CheckArray(vtkm::cont::make_ArrayHandleCompositeVector(c1, c2, c3), inComponents, arrayIds); } } } std::cout << " Fourth component from Scalar." << std::endl; TryVector4(array1, array2, array3, MakeInputArray(3)); std::cout << " Fourth component from Vector4." << std::endl; TryVector4(array1, array2, array3, MakeInputArray(3)); } template void TryVector2(vtkm::cont::ArrayHandle array1, vtkm::cont::ArrayHandle array2) { int arrayIds[2] = { 0, 1 }; vtkm::IdComponent inComponents[2]; for (inComponents[0] = 0; inComponents[0] < vtkm::VecTraits::NUM_COMPONENTS; inComponents[0]++) { auto c1 = vtkm::cont::make_ArrayHandleExtractComponent(array1, inComponents[0]); for (inComponents[1] = 0; inComponents[1] < vtkm::VecTraits::NUM_COMPONENTS; inComponents[1]++) { auto c2 = vtkm::cont::make_ArrayHandleExtractComponent(array2, inComponents[1]); CheckArray(vtkm::cont::make_ArrayHandleCompositeVector(c1, c2), inComponents, arrayIds); } } std::cout << " Third component from Scalar." << std::endl; TryVector3(array1, array2, MakeInputArray(2)); std::cout << " Third component from Vector2." << std::endl; TryVector3(array1, array2, MakeInputArray(2)); } template void TryVector1(vtkm::cont::ArrayHandle array1) { int arrayIds[1] = { 0 }; vtkm::IdComponent inComponents[1]; for (inComponents[0] = 0; inComponents[0] < vtkm::VecTraits::NUM_COMPONENTS; inComponents[0]++) { auto testArray = vtkm::cont::make_ArrayHandleExtractComponent(array1, inComponents[0]); CheckArray(vtkm::cont::make_ArrayHandleCompositeVector(testArray), inComponents, arrayIds); } std::cout << " Second component from Scalar." << std::endl; TryVector2(array1, MakeInputArray(1)); std::cout << " Second component from Vector4." << std::endl; TryVector2(array1, MakeInputArray(1)); } void TryVector() { std::cout << "Trying many permutations of composite vectors." << std::endl; std::cout << " First component from Scalar." << std::endl; TryVector1(MakeInputArray(0)); std::cout << " First component from Vector3." << std::endl; TryVector1(MakeInputArray(0)); } void TryFill() { std::cout << "Trying fill." << std::endl; vtkm::cont::ArrayHandle array0; vtkm::cont::ArrayHandle array1; vtkm::cont::ArrayHandle array2; auto composite = vtkm::cont::make_ArrayHandleCompositeVector(array0, array1, array2); const vtkm::Vec3f testValue = TestValue(0, vtkm::Vec3f{}); composite.AllocateAndFill(ARRAY_SIZE, testValue); auto portal0 = array0.ReadPortal(); auto portal1 = array1.ReadPortal(); auto portal2 = array2.ReadPortal(); VTKM_TEST_ASSERT(portal0.GetNumberOfValues() == ARRAY_SIZE); VTKM_TEST_ASSERT(portal1.GetNumberOfValues() == ARRAY_SIZE); VTKM_TEST_ASSERT(portal2.GetNumberOfValues() == ARRAY_SIZE); for (vtkm::Id index = 0; index < ARRAY_SIZE; ++index) { VTKM_TEST_ASSERT(portal0.Get(index) == testValue[0]); VTKM_TEST_ASSERT(portal1.Get(index) == testValue[1]); VTKM_TEST_ASSERT(portal2.Get(index) == testValue[2]); } } void TrySpecialArrays() { std::cout << "Trying special arrays." << std::endl; using ArrayType1 = vtkm::cont::ArrayHandleIndex; ArrayType1 array1(ARRAY_SIZE); using ArrayType2 = vtkm::cont::ArrayHandleConstant; ArrayType2 array2(295, ARRAY_SIZE); auto compositeArray = vtkm::cont::make_ArrayHandleCompositeVector(array1, array2); vtkm::cont::printSummary_ArrayHandle(compositeArray, std::cout); std::cout << std::endl; VTKM_TEST_ASSERT(compositeArray.GetNumberOfValues() == ARRAY_SIZE, "Wrong array size."); auto compositePortal = compositeArray.ReadPortal(); for (vtkm::Id index = 0; index < ARRAY_SIZE; index++) { VTKM_TEST_ASSERT(test_equal(compositePortal.Get(index), vtkm::Id2(index, 295)), "Bad value."); } } void TestCompositeVector() { TryScalarArray<2>(); TryScalarArray<3>(); TryScalarArray<4>(); TryVector(); TryFill(); TrySpecialArrays(); } } // anonymous namespace int UnitTestArrayHandleCompositeVector(int argc, char* argv[]) { return vtkm::cont::testing::Testing::Run(TestCompositeVector, argc, argv); }