From 0bee744384bb805d510983a28462c0f0d10e883b Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Tue, 9 Feb 2021 19:15:06 -0700 Subject: [PATCH 1/2] Support DeviceAdapterId in deprecated ArrayHandle The original `ArrayHandle` design had the `PrepareFor*` methods templated on the device adapter tag. This is no longer necessary (at least for any existing `ArrayHandle`), so support calling `PrepareFor*` with a `DeviceAdapterId` that is resolved at runtime. --- vtkm/cont/internal/ArrayHandleDeprecated.h | 115 ++++++++++++++++++--- 1 file changed, 99 insertions(+), 16 deletions(-) diff --git a/vtkm/cont/internal/ArrayHandleDeprecated.h b/vtkm/cont/internal/ArrayHandleDeprecated.h index 13debc4f3..b04c77b64 100644 --- a/vtkm/cont/internal/ArrayHandleDeprecated.h +++ b/vtkm/cont/internal/ArrayHandleDeprecated.h @@ -43,6 +43,10 @@ private: mutable vtkm::cont::internal::Buffer BufferAsStorageWrapper; + struct PrepareForInputFunctor; + struct PrepareForOutputFunctor; + struct PrepareForInPlaceFunctor; + public: using StorageType = vtkm::cont::internal::Storage; using ValueType = T; @@ -359,9 +363,9 @@ public: /// already attached. This can potentially lead to deadlocks. /// template - VTKM_CONT typename ExecutionTypes::PortalConst PrepareForInput( - DeviceAdapterTag, - vtkm::cont::Token& token) const; + VTKM_CONT ReadPortalType PrepareForInput(DeviceAdapterTag, vtkm::cont::Token& token) const; + VTKM_CONT ReadPortalType PrepareForInput(vtkm::cont::DeviceAdapterId device, + vtkm::cont::Token& token) const; /// Prepares (allocates) this array to be used as an output from an operation /// in the execution environment. The internal state of this class is set to @@ -378,8 +382,12 @@ public: /// already attached. This can potentially lead to deadlocks. /// template - VTKM_CONT typename ExecutionTypes::Portal - PrepareForOutput(vtkm::Id numberOfValues, DeviceAdapterTag, vtkm::cont::Token& token); + VTKM_CONT WritePortalType PrepareForOutput(vtkm::Id numberOfValues, + DeviceAdapterTag, + vtkm::cont::Token& token); + VTKM_CONT WritePortalType PrepareForOutput(vtkm::Id numberOfValues, + vtkm::cont::DeviceAdapterId device, + vtkm::cont::Token& token); /// Prepares this array to be used in an in-place operation (both as input /// and output) in the execution environment. If necessary, copies data to @@ -395,9 +403,9 @@ public: /// already attached. This can potentially lead to deadlocks. /// template - VTKM_CONT typename ExecutionTypes::Portal PrepareForInPlace( - DeviceAdapterTag, - vtkm::cont::Token& token); + VTKM_CONT WritePortalType PrepareForInPlace(DeviceAdapterTag, vtkm::cont::Token& token); + VTKM_CONT WritePortalType PrepareForInPlace(vtkm::cont::DeviceAdapterId device, + vtkm::cont::Token& token); template VTKM_CONT VTKM_DEPRECATED(1.6, "PrepareForInput now requires a vtkm::cont::Token object.") @@ -959,9 +967,9 @@ void ArrayHandleDeprecated::Shrink(vtkm::Id numberOfValues, vtkm::cont::To template template -typename ArrayHandleDeprecated::template ExecutionTypes::PortalConst -ArrayHandleDeprecated::PrepareForInput(DeviceAdapterTag device, - vtkm::cont::Token& token) const +typename ArrayHandleDeprecated::ReadPortalType ArrayHandleDeprecated::PrepareForInput( + DeviceAdapterTag device, + vtkm::cont::Token& token) const { VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapterTag); @@ -985,12 +993,36 @@ ArrayHandleDeprecated::PrepareForInput(DeviceAdapterTag device, return portal; } +template +struct ArrayHandleDeprecated::PrepareForInputFunctor +{ + template + bool operator()(Device device, + const ArrayHandleDeprecated& self, + vtkm::cont::Token& token, + ReadPortalType& portal) const + { + portal = self.PrepareForInput(device, token); + return true; + } +}; + +template +typename ArrayHandleDeprecated::ReadPortalType ArrayHandleDeprecated::PrepareForInput( + vtkm::cont::DeviceAdapterId device, + vtkm::cont::Token& token) const +{ + ReadPortalType portal; + vtkm::cont::TryExecuteOnDevice(device, PrepareForInputFunctor{}, *this, token, portal); + return portal; +} + template template -typename ArrayHandleDeprecated::template ExecutionTypes::Portal -ArrayHandleDeprecated::PrepareForOutput(vtkm::Id numberOfValues, - DeviceAdapterTag device, - vtkm::cont::Token& token) +typename ArrayHandleDeprecated::WritePortalType ArrayHandleDeprecated::PrepareForOutput( + vtkm::Id numberOfValues, + DeviceAdapterTag device, + vtkm::cont::Token& token) { VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapterTag); @@ -1020,9 +1052,36 @@ ArrayHandleDeprecated::PrepareForOutput(vtkm::Id numberOfValues, return portal; } +template +struct ArrayHandleDeprecated::PrepareForOutputFunctor +{ + template + bool operator()(Device device, + ArrayHandleDeprecated& self, + vtkm::Id numberOfValues, + vtkm::cont::Token& token, + WritePortalType& portal) const + { + portal = self.PrepareForOutput(numberOfValues, device, token); + return true; + } +}; + +template +typename ArrayHandleDeprecated::WritePortalType ArrayHandleDeprecated::PrepareForOutput( + vtkm::Id numberOfValues, + vtkm::cont::DeviceAdapterId device, + vtkm::cont::Token& token) +{ + WritePortalType portal; + vtkm::cont::TryExecuteOnDevice( + device, PrepareForOutputFunctor{}, *this, numberOfValues, token, portal); + return portal; +} + template template -typename ArrayHandleDeprecated::template ExecutionTypes::Portal +typename ArrayHandleDeprecated::WritePortalType ArrayHandleDeprecated::PrepareForInPlace(DeviceAdapterTag device, vtkm::cont::Token& token) { VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapterTag); @@ -1052,6 +1111,30 @@ ArrayHandleDeprecated::PrepareForInPlace(DeviceAdapterTag device, vtkm::co return portal; } +template +struct ArrayHandleDeprecated::PrepareForInPlaceFunctor +{ + template + bool operator()(Device device, + ArrayHandleDeprecated& self, + vtkm::cont::Token& token, + ReadPortalType& portal) const + { + portal = self.PrepareForInPlace(device, token); + return true; + } +}; + +template +typename ArrayHandleDeprecated::WritePortalType +ArrayHandleDeprecated::PrepareForInPlace(vtkm::cont::DeviceAdapterId device, + vtkm::cont::Token& token) +{ + WritePortalType portal; + vtkm::cont::TryExecuteOnDevice(device, PrepareForInPlaceFunctor{}, *this, token, portal); + return portal; +} + template template void ArrayHandleDeprecated::PrepareForDevice(LockType& lock, From 0797359c576bf885db76c3491f6c5821e219c0f0 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Tue, 9 Feb 2021 17:59:25 -0700 Subject: [PATCH 2/2] Make ExecutionWholeArray objects not depend on device type With recent changes to `Arrayhandle`, the type for the associated array portal is now the same across all devices. This means that almost all exec objects no longer need to be specialized on the device types. Thus, clean up the whole array exec objects to no longer need to be templated on device. --- benchmarking/BenchmarkFieldAlgorithms.cxx | 8 +- vtkm/cont/arg/TransportTagWholeArrayIn.h | 4 +- vtkm/cont/arg/TransportTagWholeArrayInOut.h | 4 +- vtkm/cont/arg/TransportTagWholeArrayOut.h | 4 +- vtkm/exec/ExecutionWholeArray.h | 116 ++++++++++++++------ 5 files changed, 94 insertions(+), 42 deletions(-) diff --git a/benchmarking/BenchmarkFieldAlgorithms.cxx b/benchmarking/BenchmarkFieldAlgorithms.cxx index a23c2c3b8..8a690f073 100644 --- a/benchmarking/BenchmarkFieldAlgorithms.cxx +++ b/benchmarking/BenchmarkFieldAlgorithms.cxx @@ -226,20 +226,20 @@ public: using ExecutionSignature = void(_1, _2, _3, _4); using InputDomain = _1; - template + template VTKM_EXEC void operator()(const vtkm::Id2& low_high, const WeightType& weight, - const vtkm::exec::ExecutionWholeArrayConst& inPortal, + const vtkm::exec::ExecutionWholeArrayConst& inPortal, T& result) const { //fetch the low / high values from inPortal result = vtkm::Lerp(inPortal.Get(low_high[0]), inPortal.Get(low_high[1]), weight); } - template + template VTKM_EXEC void operator()(const vtkm::Id2&, const WeightType&, - const vtkm::exec::ExecutionWholeArrayConst&, + const vtkm::exec::ExecutionWholeArrayConst&, U&) const { //the inPortal and result need to be the same type so this version only diff --git a/vtkm/cont/arg/TransportTagWholeArrayIn.h b/vtkm/cont/arg/TransportTagWholeArrayIn.h index c4dad8e93..86454234d 100644 --- a/vtkm/cont/arg/TransportTagWholeArrayIn.h +++ b/vtkm/cont/arg/TransportTagWholeArrayIn.h @@ -56,7 +56,7 @@ struct Transport; + using ExecObjectType = vtkm::exec::ExecutionWholeArrayConst; template VTKM_CONT ExecObjectType operator()(ContObjectType& array, @@ -69,7 +69,7 @@ struct Transport; + using ExecObjectType = vtkm::exec::ExecutionWholeArray; template VTKM_CONT ExecObjectType operator()(ContObjectType& array, @@ -71,7 +71,7 @@ struct Transport; + using ExecObjectType = vtkm::exec::ExecutionWholeArray; template VTKM_CONT ExecObjectType operator()(ContObjectType& array, @@ -71,7 +71,7 @@ struct Transport #include +#include + namespace vtkm { namespace exec { -/// The following classes have been deprecated and are meant to be used +/// The following classes have been sort of deprecated and are meant to be used /// internally only. Please use the \c WholeArrayIn, \c WholeArrayOut, and /// \c WholeArrayInOut \c ControlSignature tags instead. @@ -27,8 +29,11 @@ namespace exec /// function. This can be used to allow worklets to have a shared search /// structure. /// -template -class ExecutionWholeArray +template +class ExecutionWholeArray; + +template +class ExecutionWholeArray { public: using ValueType = T; @@ -41,29 +46,20 @@ public: { } - // This constructor is deprecated in VTK-m 1.6 VTKM_CONT - ExecutionWholeArray(HandleType& handle) - : Portal(handle.PrepareForInPlace(DeviceAdapterTag())) - { - } - - // This constructor is deprecated in VTK-m 1.6 - VTKM_CONT - ExecutionWholeArray(HandleType& handle, vtkm::Id length) - : Portal(handle.PrepareForOutput(length, DeviceAdapterTag())) + ExecutionWholeArray(HandleType& handle, + vtkm::cont::DeviceAdapterId device, + vtkm::cont::Token& token) + : Portal(handle.PrepareForInPlace(device, token)) { } VTKM_CONT - ExecutionWholeArray(HandleType& handle, vtkm::cont::Token& token) - : Portal(handle.PrepareForInPlace(DeviceAdapterTag(), token)) - { - } - - VTKM_CONT - ExecutionWholeArray(HandleType& handle, vtkm::Id length, vtkm::cont::Token& token) - : Portal(handle.PrepareForOutput(length, DeviceAdapterTag(), token)) + ExecutionWholeArray(HandleType& handle, + vtkm::Id length, + vtkm::cont::DeviceAdapterId device, + vtkm::cont::Token& token) + : Portal(handle.PrepareForOutput(length, device, token)) { } @@ -86,13 +82,50 @@ private: PortalType Portal; }; +template +class VTKM_DEPRECATED(1.6, "ExecutionWholeArray no longer uses Device template parameter.") + ExecutionWholeArray : public ExecutionWholeArray +{ + using Superclass = ExecutionWholeArray; + using HandleType = typename Superclass::HandleType; + +public: + using Superclass::Superclass; + + VTKM_CONT ExecutionWholeArray(HandleType& handle) + : Superclass(handle, Device{}, vtkm::cont::Token{}) + { + } + + VTKM_CONT + ExecutionWholeArray(HandleType& handle, vtkm::Id length) + : Superclass(handle, length, Device{}, vtkm::cont::Token{}) + { + } + + VTKM_CONT + ExecutionWholeArray(HandleType& handle, vtkm::cont::Token& token) + : Superclass(handle, Device{}, token) + { + } + + VTKM_CONT + ExecutionWholeArray(HandleType& handle, vtkm::Id length, vtkm::cont::Token& token) + : Superclass(handle, length, Device{}, token) + { + } +}; + /// \c ExecutionWholeArrayConst is an execution object that allows an array handle /// content to be a parameter in an execution environment /// function. This can be used to allow worklets to have a shared search /// structure /// -template -class ExecutionWholeArrayConst +template +class ExecutionWholeArrayConst; + +template +class ExecutionWholeArrayConst { public: using ValueType = T; @@ -105,16 +138,11 @@ public: { } - // This constructor is deprecated in VTK-m 1.6 VTKM_CONT - ExecutionWholeArrayConst(const HandleType& handle) - : Portal(handle.PrepareForInput(DeviceAdapterTag())) - { - } - - VTKM_CONT - ExecutionWholeArrayConst(const HandleType& handle, vtkm::cont::Token& token) - : Portal(handle.PrepareForInput(DeviceAdapterTag(), token)) + ExecutionWholeArrayConst(const HandleType& handle, + vtkm::cont::DeviceAdapterId device, + vtkm::cont::Token& token) + : Portal(handle.PrepareForInput(device, token)) { } @@ -133,6 +161,30 @@ public: private: PortalType Portal; }; + +template +class VTKM_DEPRECATED(1.6, "ExecutionWholeArray no longer uses Device template parameter.") + ExecutionWholeArrayConst : public ExecutionWholeArrayConst +{ + using Superclass = ExecutionWholeArrayConst; + using HandleType = typename Superclass::HandleType; + +public: + using Superclass::Superclass; + + VTKM_CONT ExecutionWholeArrayConst(HandleType& handle) + : Superclass(handle, Device{}, vtkm::cont::Token{}) + { + } + + VTKM_CONT + ExecutionWholeArrayConst(HandleType& handle, vtkm::cont::Token& token) + : Superclass(handle, Device{}, token) + { + } +}; + + } } // namespace vtkm::exec