diff --git a/vtkm/ImplicitFunction.h b/vtkm/ImplicitFunction.h index 8a62ea0a4..ae0b43914 100644 --- a/vtkm/ImplicitFunction.h +++ b/vtkm/ImplicitFunction.h @@ -75,6 +75,17 @@ public: { return reinterpret_cast(this)->Gradient(Vector(x, y, z)); } + + VTKM_CONT const Derived& PrepareForExecution(vtkm::cont::DeviceAdapterId, + vtkm::cont::Token&) const + { + return *reinterpret_cast(this); + } + + VTKM_CONT const Derived& PrepareForControl() const + { + return *reinterpret_cast(this); + } }; } // namespace vtkm::internal diff --git a/vtkm/cont/ExecutionAndControlObjectBase.h b/vtkm/cont/ExecutionAndControlObjectBase.h index d61b60385..a8b473a52 100644 --- a/vtkm/cont/ExecutionAndControlObjectBase.h +++ b/vtkm/cont/ExecutionAndControlObjectBase.h @@ -17,11 +17,12 @@ namespace vtkm namespace cont { -/// Base \c ExecutionAndControlObjectBase class. These are objects that behave +/// Base `ExecutionAndControlObjectBase` class. These are objects that behave /// as execution objects but can also be use din the control environment. -/// Any subclass of \c ExecutionAndControlObjectBase must implement a -/// \c PrepareForExecution method that takes a device adapter tag and returns -/// an object for that device as well as a \c PrepareForControl that simply +/// Any subclass of `ExecutionAndControlObjectBase` must implement a +/// `PrepareForExecution` method that takes a device adapter tag and a +/// `vtkm::cont::Token` reference and returns +/// an object for that device. It also must implement `PrepareForControl` that simply /// returns an object that works in the control environment. /// struct ExecutionAndControlObjectBase : vtkm::cont::ExecutionObjectBase diff --git a/vtkm/cont/testing/TestingImplicitFunction.h b/vtkm/cont/testing/TestingImplicitFunction.h index 046f36a99..7841ffccb 100644 --- a/vtkm/cont/testing/TestingImplicitFunction.h +++ b/vtkm/cont/testing/TestingImplicitFunction.h @@ -13,11 +13,12 @@ #include #include #include -#include #include #include -#include +#ifndef VTKM_NO_DEPRECATED_VIRTUAL +#include +#endif //!VTKM_NO_DEPRECATED_VIRTUAL #include #include @@ -37,85 +38,43 @@ namespace implicit_function_detail class EvaluateImplicitFunction : public vtkm::worklet::WorkletMapField { public: - using ControlSignature = void(FieldIn, FieldOut, FieldOut); - using ExecutionSignature = void(_1, _2, _3); + using ControlSignature = void(FieldIn, FieldOut, FieldOut, ExecObject); + using ExecutionSignature = void(_1, _2, _3, _4); - EvaluateImplicitFunction(const vtkm::ImplicitFunction* function) - : Function(function) + template + VTKM_EXEC void operator()(const VecType& point, + ScalarType& val, + VecType& gradient, + const FunctionType& function) const { + val = function.Value(point); + gradient = function.Gradient(point); } - template - VTKM_EXEC void operator()(const VecType& point, ScalarType& val, VecType& gradient) const +#ifndef VTKM_NO_DEPRECATED_VIRTUAL + VTKM_DEPRECATED_SUPPRESS_BEGIN + template + VTKM_EXEC void operator()(const VecType& point, + ScalarType& val, + VecType& gradient, + const FunctionType* function) const { - val = this->Function->Value(point); - gradient = this->Function->Gradient(point); + val = function->Value(point); + gradient = function->Gradient(point); } - -private: - const vtkm::ImplicitFunction* Function; + VTKM_DEPRECATED_SUPPRESS_END +#endif //!VTKM_NO_DEPRECATED_VIRTUAL }; -template +template void EvaluateOnCoordinates(vtkm::cont::CoordinateSystem points, - const vtkm::cont::ImplicitFunctionHandle& function, + const ImplicitFunctionType& function, vtkm::cont::ArrayHandle& values, vtkm::cont::ArrayHandle>& gradients, - DeviceAdapter device) + vtkm::cont::DeviceAdapterId device) { - using EvalDispatcher = vtkm::worklet::DispatcherMapField; - - vtkm::cont::Token token; - EvaluateImplicitFunction eval(function.PrepareForExecution(device, token)); - EvalDispatcher dispatcher(eval); - dispatcher.SetDevice(DeviceAdapter()); - dispatcher.Invoke(points.GetDataAsMultiplexer(), values, gradients); -} - -template -bool TestArrayEqual(const vtkm::cont::ArrayHandle& result, - const std::array& expected) -{ - bool success = false; - auto portal = result.ReadPortal(); - vtkm::Id count = portal.GetNumberOfValues(); - - if (static_cast(count) == N) - { - success = true; - for (vtkm::Id i = 0; i < count; ++i) - { - if (!test_equal(portal.Get(i), expected[static_cast(i)])) - { - success = false; - break; - } - } - } - if (!success) - { - if (count == 0) - { - std::cout << "result: \n"; - } - else - { - std::cout << "result: " << portal.Get(0); - for (vtkm::Id i = 1; i < count; ++i) - { - std::cout << ", " << portal.Get(i); - } - std::cout << "\n"; - std::cout << "expected: " << expected[0]; - for (vtkm::Id i = 1; i < count; ++i) - { - std::cout << ", " << expected[static_cast(i)]; - } - std::cout << "\n"; - } - } - - return success; + vtkm::cont::Invoker invoke{ device }; + invoke(EvaluateImplicitFunction{}, points.GetDataAsMultiplexer(), values, gradients, function); } } // anonymous namespace @@ -139,22 +98,42 @@ public: } private: - template - void Try(vtkm::cont::ImplicitFunctionHandle& function, + template + void Try(ImplicitFunctorType& function, const std::array& expectedValues, const std::array& expectedGradients, - DeviceAdapter device) + vtkm::cont::DeviceAdapterId device) { - vtkm::cont::ArrayHandle values; - vtkm::cont::ArrayHandle> gradients; - implicit_function_detail::EvaluateOnCoordinates( - this->Input.GetCoordinateSystem(0), function, values, gradients, device); + auto expectedValuesArray = + vtkm::cont::make_ArrayHandle(expectedValues.data(), 8, vtkm::CopyFlag::Off); + auto expectedGradientsArray = + vtkm::cont::make_ArrayHandle(expectedGradients.data(), 8, vtkm::CopyFlag::Off); - VTKM_TEST_ASSERT(implicit_function_detail::TestArrayEqual(values, expectedValues), - "Result does not match expected values"); - VTKM_TEST_ASSERT(implicit_function_detail::TestArrayEqual(gradients, expectedGradients), - "Result does not match expected gradients values"); + { + vtkm::cont::ArrayHandle values; + vtkm::cont::ArrayHandle> gradients; + implicit_function_detail::EvaluateOnCoordinates( + this->Input.GetCoordinateSystem(0), function, values, gradients, device); + + VTKM_TEST_ASSERT(test_equal_ArrayHandles(values, expectedValuesArray)); + VTKM_TEST_ASSERT(test_equal_ArrayHandles(gradients, expectedGradientsArray)); + } + +#ifndef VTKM_NO_DEPRECATED_VIRTUAL + VTKM_DEPRECATED_SUPPRESS_BEGIN + { + vtkm::cont::ImplicitFunctionHandle functionHandle(&function, false); + vtkm::cont::ArrayHandle values; + vtkm::cont::ArrayHandle> gradients; + implicit_function_detail::EvaluateOnCoordinates( + this->Input.GetCoordinateSystem(0), functionHandle, values, gradients, device); + + VTKM_TEST_ASSERT(test_equal_ArrayHandles(values, expectedValuesArray)); + VTKM_TEST_ASSERT(test_equal_ArrayHandles(gradients, expectedGradientsArray)); + } } + VTKM_DEPRECATED_SUPPRESS_END +#endif //!VTKM_NO_DEPRECATED_VIRTUAL template void TestBox(DeviceAdapter device) @@ -164,8 +143,7 @@ private: std::cout << " default box" << std::endl; vtkm::Box box; - vtkm::cont::ImplicitFunctionHandle boxHandle(&box, false); - this->Try(boxHandle, + this->Try(box, { { -0.5f, 0.5f, 0.707107f, 0.5f, 0.5f, 0.707107f, 0.866025f, 0.707107f } }, { { vtkm::Vec3f{ -1.0f, 0.0f, 0.0f }, vtkm::Vec3f{ 1.0f, 0.0f, 0.0f }, @@ -180,8 +158,7 @@ private: std::cout << " Specified min/max box" << std::endl; box.SetMinPoint({ 0.0f, -0.5f, -0.5f }); box.SetMaxPoint({ 1.5f, 1.5f, 0.5f }); - boxHandle.Reset(&box, false); - this->Try(boxHandle, + this->Try(box, { { 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, -0.5f, 0.5f, 0.5f } }, { { vtkm::Vec3f{ -1.0f, 0.0f, 0.0f }, vtkm::Vec3f{ 1.0f, 0.0f, 0.0f }, @@ -195,8 +172,7 @@ private: std::cout << " Specified bounds box" << std::endl; box.SetBounds({ vtkm::Range(0.0, 1.5), vtkm::Range(-0.5, 1.5), vtkm::Range(-0.5, 0.5) }); - boxHandle.Reset(&box, false); - this->Try(boxHandle, + this->Try(box, { { 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, -0.5f, 0.5f, 0.5f } }, { { vtkm::Vec3f{ -1.0f, 0.0f, 0.0f }, vtkm::Vec3f{ 1.0f, 0.0f, 0.0f }, @@ -217,8 +193,7 @@ private: std::cout << " Default cylinder" << std::endl; vtkm::Cylinder cylinder; - vtkm::cont::ImplicitFunctionHandle cylinderHandle(&cylinder, false); - this->Try(cylinderHandle, + this->Try(cylinder, { { -0.25f, 0.75f, 1.75f, 0.75f, -0.25f, 0.75f, 1.75f, 0.75f } }, { { vtkm::Vec3f{ 0.0f, 0.0f, 0.0f }, vtkm::Vec3f{ 2.0f, 0.0f, 0.0f }, @@ -234,8 +209,7 @@ private: cylinder.SetCenter({ 0.0f, 0.0f, 1.0f }); cylinder.SetAxis({ 0.0f, 1.0f, 0.0f }); cylinder.SetRadius(1.0f); - cylinderHandle.Reset(&cylinder, false); - this->Try(cylinderHandle, + this->Try(cylinder, { { 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, -1.0f } }, { { vtkm::Vec3f{ 0.0f, 0.0f, -2.0f }, vtkm::Vec3f{ 2.0f, 0.0f, -2.0f }, @@ -251,8 +225,7 @@ private: cylinder.SetCenter({ 0.0f, 0.0f, 0.0f }); cylinder.SetAxis({ 1.0f, 1.0f, 0.0f }); cylinder.SetRadius(1.0f); - cylinderHandle.Reset(&cylinder, false); - this->Try(cylinderHandle, + this->Try(cylinder, { { -1.0f, -0.5f, 0.5f, 0.0f, -0.5f, -1.0f, 0.0f, 0.5f } }, { { vtkm::Vec3f{ 0.0f, 0.0f, 0.0f }, vtkm::Vec3f{ 1.0f, -1.0f, 0.0f }, @@ -283,8 +256,7 @@ private: { 1.5f, 1.0f, -0.5f } // 7 }; vtkm::Frustum frustum{ cornerPoints }; - vtkm::cont::ImplicitFunctionHandle frustumHandle(&frustum, false); - this->Try(frustumHandle, + this->Try(frustum, { { 0.0f, 0.353553f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f } }, { { vtkm::Vec3f{ 0.0f, -1.0f, 0.0f }, vtkm::Vec3f{ 0.707107f, -0.707107f, 0.0f }, @@ -303,9 +275,8 @@ private: vtkm::Vec3f planeNormals[6] = { { 0.0f, -1.0f, 0.0f }, { 0.707107f, 0.707107f, 0.0f }, { -1.0f, 0.0f, 0.0f }, { 0.707107f, -0.707107f, 0.0f }, { 0.0f, 0.0f, -1.0f }, { 0.0f, 0.0f, 1.0f } }; - frustum->SetPlanes(planePoints, planeNormals); - frustumHandle.Reset(&frustum, false); - this->Try(frustumHandle, + frustum.SetPlanes(planePoints, planeNormals); + this->Try(frustum, { { 0.0f, 0.353553f, 0.5f, 0.5f, -0.5f, 0.0f, 0.5f, 0.5f } }, { { vtkm::Vec3f{ 0.0f, -1.0f, 0.0f }, vtkm::Vec3f{ 0.707107f, -0.707107f, 0.0f }, @@ -326,8 +297,7 @@ private: std::cout << " Default plane" << std::endl; vtkm::Plane plane; - vtkm::cont::ImplicitFunctionHandle planeHandle = vtkm::cont::make_ImplicitFunctionHandle(plane); - this->Try(planeHandle, + this->Try(plane, { { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f } }, { { vtkm::Vec3f{ 0.0f, 0.0f, 1.0f }, vtkm::Vec3f{ 0.0f, 0.0f, 1.0f }, @@ -340,10 +310,9 @@ private: device); std::cout << " Normal of length 2" << std::endl; - plane->SetOrigin({ 1.0f, 1.0f, 1.0f }); - plane->SetNormal({ 0.0f, 0.0f, 2.0f }); - planeHandle.Reset(&plane, false); - this->Try(planeHandle, + plane.SetOrigin({ 1.0f, 1.0f, 1.0f }); + plane.SetNormal({ 0.0f, 0.0f, 2.0f }); + this->Try(plane, { { -2.0f, -2.0f, 0.0f, 0.0f, -2.0f, -2.0f, 0.0f, 0.0f } }, { { vtkm::Vec3f{ 0.0f, 0.0f, 2.0f }, vtkm::Vec3f{ 0.0f, 0.0f, 2.0f }, @@ -356,10 +325,9 @@ private: device); std::cout << " Oblique plane" << std::endl; - plane->SetOrigin({ 0.5f, 0.5f, 0.5f }); - plane->SetNormal({ 1.0f, 0.0f, 1.0f }); - planeHandle.Reset(&plane, false); - this->Try(planeHandle, + plane.SetOrigin({ 0.5f, 0.5f, 0.5f }); + plane.SetNormal({ 1.0f, 0.0f, 1.0f }); + this->Try(plane, { { -1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f } }, { { vtkm::Vec3f{ 1.0f, 0.0f, 1.0f }, vtkm::Vec3f{ 1.0f, 0.0f, 1.0f }, @@ -372,9 +340,8 @@ private: device); std::cout << " Another oblique plane" << std::endl; - plane->SetNormal({ -1.0f, 0.0f, -1.0f }); - planeHandle.Reset(&plane, false); - this->Try(planeHandle, + plane.SetNormal({ -1.0f, 0.0f, -1.0f }); + this->Try(plane, { { 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f } }, { { vtkm::Vec3f{ -1.0f, 0.0f, -1.0f }, vtkm::Vec3f{ -1.0f, 0.0f, -1.0f }, @@ -395,8 +362,7 @@ private: std::cout << " Default sphere" << std::endl; vtkm::Sphere sphere; - vtkm::cont::ImplicitFunctionHandle sphereHandle(&sphere, false); - this->Try(sphereHandle, + this->Try(sphere, { { -0.25f, 0.75f, 1.75f, 0.75f, 0.75f, 1.75f, 2.75f, 1.75f } }, { { vtkm::Vec3f{ 0.0f, 0.0f, 0.0f }, vtkm::Vec3f{ 2.0f, 0.0f, 0.0f }, @@ -411,8 +377,7 @@ private: std::cout << " Shifted and scaled sphere" << std::endl; sphere.SetCenter({ 1.0f, 1.0f, 1.0f }); sphere.SetRadius(1.0f); - sphereHandle.Reset(&sphere, false); - this->Try(sphereHandle, + this->Try(sphere, { { 2.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, -1.0f, 0.0f } }, { { vtkm::Vec3f{ -2.0f, -2.0f, -2.0f }, vtkm::Vec3f{ 0.0f, -2.0f, -2.0f },