//============================================================================ // 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 namespace { constexpr vtkm::Id ARRAY_SIZE = 10; // GroupVecVariable is a bit strange because it supports values of different // lengths, so a simple pass through worklet will not work. Use custom // worklets. struct GroupVariableInputWorklet : public vtkm::worklet::WorkletMapField { using ControlSignature = void(FieldIn, FieldOut); using ExecutionSignature = void(_1, WorkIndex, _2); template VTKM_EXEC void operator()(const InputType& input, vtkm::Id workIndex, vtkm::Id& dummyOut) const { using ComponentType = typename InputType::ComponentType; vtkm::IdComponent expectedSize = static_cast(workIndex); if (expectedSize != input.GetNumberOfComponents()) { this->RaiseError("Got unexpected number of components."); } vtkm::Id valueIndex = workIndex * (workIndex - 1) / 2; dummyOut = valueIndex; for (vtkm::IdComponent componentIndex = 0; componentIndex < expectedSize; componentIndex++) { ComponentType expectedValue = TestValue(valueIndex, ComponentType()); if (vtkm::Abs(expectedValue - input[componentIndex]) > 0.000001) { this->RaiseError("Got bad value in GroupVariableInputWorklet."); } valueIndex++; } } }; struct TestGroupVecVariableAsInput { template VTKM_CONT void operator()(ComponentType) const { vtkm::cont::Invoker invoke; vtkm::Id sourceArraySize; vtkm::cont::ArrayHandle numComponentsArray; vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleIndex(ARRAY_SIZE), numComponentsArray); vtkm::cont::ArrayHandle offsetsArray = vtkm::cont::ConvertNumComponentsToOffsets(numComponentsArray, sourceArraySize); vtkm::cont::ArrayHandle sourceArray; sourceArray.Allocate(sourceArraySize); SetPortal(sourceArray.WritePortal()); vtkm::cont::ArrayHandle dummyArray; auto groupVecArray = vtkm::cont::make_ArrayHandleGroupVecVariable(sourceArray, offsetsArray); invoke(GroupVariableInputWorklet{}, groupVecArray, dummyArray); dummyArray.ReadPortal(); groupVecArray.ReleaseResources(); } }; // GroupVecVariable is a bit strange because it supports values of different // lengths, so a simple pass through worklet will not work. Use custom // worklets. struct GroupVariableOutputWorklet : public vtkm::worklet::WorkletMapField { using ControlSignature = void(FieldIn, FieldOut); using ExecutionSignature = void(_2, WorkIndex); template VTKM_EXEC void operator()(OutputType& output, vtkm::Id workIndex) const { using ComponentType = typename OutputType::ComponentType; vtkm::IdComponent expectedSize = static_cast(workIndex); if (expectedSize != output.GetNumberOfComponents()) { this->RaiseError("Got unexpected number of components."); } vtkm::Id valueIndex = workIndex * (workIndex - 1) / 2; for (vtkm::IdComponent componentIndex = 0; componentIndex < expectedSize; componentIndex++) { output[componentIndex] = TestValue(valueIndex, ComponentType()); valueIndex++; } } }; struct TestGroupVecVariableAsOutput { template VTKM_CONT void operator()(ComponentType) const { vtkm::Id sourceArraySize; vtkm::cont::ArrayHandle numComponentsArray; vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleIndex(ARRAY_SIZE), numComponentsArray); vtkm::cont::ArrayHandle offsetsArray = vtkm::cont::ConvertNumComponentsToOffsets(numComponentsArray, sourceArraySize); vtkm::cont::ArrayHandle sourceArray; sourceArray.Allocate(sourceArraySize); vtkm::worklet::DispatcherMapField dispatcher; dispatcher.Invoke(vtkm::cont::ArrayHandleIndex(ARRAY_SIZE), vtkm::cont::make_ArrayHandleGroupVecVariable(sourceArray, offsetsArray)); CheckPortal(sourceArray.ReadPortal()); } }; void Run() { using ScalarTypesToTest = vtkm::List; std::cout << "-------------------------------------------" << std::endl; std::cout << "Testing ArrayHandleGroupVecVariable as Input" << std::endl; vtkm::testing::Testing::TryTypes(TestGroupVecVariableAsInput(), ScalarTypesToTest()); std::cout << "-------------------------------------------" << std::endl; std::cout << "Testing ArrayHandleGroupVecVariable as Output" << std::endl; vtkm::testing::Testing::TryTypes(TestGroupVecVariableAsOutput(), ScalarTypesToTest()); } } // anonymous namespace int UnitTestArrayHandleGroupVecVariable(int argc, char* argv[]) { return vtkm::cont::testing::Testing::Run(Run, argc, argv); }