From ef83adf3bd24f88f72d2cce9c0869b14e0405b27 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Tue, 6 Nov 2018 11:40:39 -0500 Subject: [PATCH] Field, CoordinateSystem, VirtualCoordinates all use the new virtual code --- vtkm/cont/ArrayHandleVirtual.h | 159 +++-- vtkm/cont/ArrayHandleVirtualCoordinates.h | 619 ++---------------- vtkm/cont/CellSet.h | 2 +- vtkm/cont/CoordinateSystem.cxx | 33 +- vtkm/cont/CoordinateSystem.h | 39 +- vtkm/cont/CoordinateSystem.hxx | 14 +- vtkm/cont/DataSet.h | 15 +- vtkm/cont/DataSetFieldAdd.h | 6 +- vtkm/cont/Field.cxx | 30 +- vtkm/cont/Field.h | 162 ++--- vtkm/cont/FieldRangeCompute.cxx | 4 +- vtkm/cont/FieldRangeCompute.h | 37 +- vtkm/cont/FieldRangeCompute.hxx | 14 +- vtkm/cont/FieldRangeGlobalCompute.cxx | 6 +- vtkm/cont/FieldRangeGlobalCompute.h | 35 +- vtkm/cont/FieldRangeGlobalCompute.hxx | 14 +- vtkm/cont/MultiBlock.cxx | 1 - vtkm/cont/MultiBlock.h | 1 - .../cont/testing/UnitTestMoveConstructors.cxx | 34 +- 19 files changed, 339 insertions(+), 886 deletions(-) diff --git a/vtkm/cont/ArrayHandleVirtual.h b/vtkm/cont/ArrayHandleVirtual.h index e30afd9bf..6c78ca114 100644 --- a/vtkm/cont/ArrayHandleVirtual.h +++ b/vtkm/cont/ArrayHandleVirtual.h @@ -59,6 +59,12 @@ public: ArrayHandle() : Storage(nullptr){}; + + /// virtual destructor, as required to make sure derived classes that + /// might have member variables are properly cleaned up. + // + virtual ~ArrayHandle() = default; + ///Move existing shared_ptr of vtkm::cont::StorageVirtual to be ///owned by this ArrayHandleVirtual. ///This is generally how derived class construct a valid ArrayHandleVirtual @@ -107,23 +113,20 @@ public: VTKM_CONT bool IsType() const { VTKM_IS_ARRAY_HANDLE(ArrayHandleType); - //We need to go long the way to find the StorageType - //as StorageType is private on lots of derived ArrayHandles - //See Issue #314 - using VT = typename ArrayHandleType::ValueType; static_assert( std::is_same::value, "ArrayHandleVirtual can only be casted to an ArrayHandle of the same ValueType."); + //We need to determine if we are checking that `ArrayHandleType` + //is a virtual array handle since that is an easy check. + //Or if we have to go ask the storage if they are holding + // using ST = typename ArrayHandleType::StorageTag; - return this->Storage->IsType(typeid(vtkm::cont::internal::Storage)); + using is_base = std::is_same; + return this->IsSameType(is_base{}); } - /// Returns a view on the internal storage of the ArrayHandleVirtual - /// - VTKM_CONT const StorageType* GetStorage() const { return this->Storage.get(); } - /// Returns a new instance of an ArrayHandleVirtual with the same storage /// VTKM_CONT ArrayHandle NewInstance() const @@ -133,37 +136,9 @@ public: : ArrayHandle(); } - // Return a ArrayPortalRef that wraps the real virtual portal. We need a stack object for - // the following reasons: - // 1. Device Adapter algorithms only support const AH& and not const AH* - // 2. Devices will want to get the length of a portal before execution, but for CUDA - // we can't ask this information of the portal as it only valid on the device, instead - // we have to store this information also in the ref wrapper - vtkm::ArrayPortalRef PrepareForInput(vtkm::cont::DeviceAdapterId devId) const - { - return make_ArrayPortalRef( - static_cast*>(this->Storage->PrepareForInput(devId)), - this->GetNumberOfValues()); - } - - vtkm::ArrayPortalRef PrepareForOutput(vtkm::Id numberOfValues, - vtkm::cont::DeviceAdapterId devId) - { - return make_ArrayPortalRef(static_cast*>( - this->Storage->PrepareForOutput(numberOfValues, devId)), - numberOfValues); - } - - vtkm::Id GetNumberOfValues() const { return this->Storage->GetNumberOfValues(); } - - /// Releases any resources being used in the execution environment (that are - /// not being shared by the control environment). + /// Returns a view on the internal storage of the ArrayHandleVirtual /// - void ReleaseResourcesExecution() { return this->Storage->ReleaseResourcesExecution(); } - - /// Releases all resources in both the control and execution environments. - /// - void ReleaseResources() { return this->Storage->ReleaseResources(); } + VTKM_CONT const StorageType* GetStorage() const { return this->Storage.get(); } /// Get the array portal of the control array. /// Since worklet invocations are asynchronous and this routine is a synchronization point, @@ -187,8 +162,114 @@ public: this->GetNumberOfValues()); } + /// Returns the number of entries in the array. + /// + vtkm::Id GetNumberOfValues() const { return this->Storage->GetNumberOfValues(); } + + /// \brief Allocates an array large enough to hold the given number of values. + /// + /// The allocation may be done on an already existing array, but can wipe out + /// any data already in the array. This method can throw + /// ErrorBadAllocation if the array cannot be allocated or + /// ErrorBadValue if the allocation is not feasible (for example, the + /// array storage is read-only). + /// + VTKM_CONT + void Allocate(vtkm::Id numberOfValues) { return this->Storage->Allocate(numberOfValues); } + + /// \brief Reduces the size of the array without changing its values. + /// + /// This method allows you to resize the array without reallocating it. The + /// number of entries in the array is changed to \c numberOfValues. The data + /// in the array (from indices 0 to \c numberOfValues - 1) are the same, but + /// \c numberOfValues must be equal or less than the preexisting size + /// (returned from GetNumberOfValues). That is, this method can only be used + /// to shorten the array, not lengthen. + void Shrink(vtkm::Id numberOfValues) { return this->Storage->Shrink(numberOfValues); } + + /// Releases any resources being used in the execution environment (that are + /// not being shared by the control environment). + /// + void ReleaseResourcesExecution() { return this->Storage->ReleaseResourcesExecution(); } + + /// Releases all resources in both the control and execution environments. + /// + void ReleaseResources() { return this->Storage->ReleaseResources(); } + + /// Prepares this array to be used as an input to an operation in the + /// execution environment. If necessary, copies data to the execution + /// environment. Can throw an exception if this array does not yet contain + /// any data. Returns a portal that can be used in code running in the + /// execution environment. + /// + /// Return a ArrayPortalRef that wraps the real virtual portal. We need a stack object for + /// the following reasons: + /// 1. Device Adapter algorithms only support const AH& and not const AH* + /// 2. Devices will want to get the length of a portal before execution, but for CUDA + /// we can't ask this information of the portal as it only valid on the device, instead + /// we have to store this information also in the ref wrapper + vtkm::ArrayPortalRef PrepareForInput(vtkm::cont::DeviceAdapterId devId) const + { + return make_ArrayPortalRef( + static_cast*>(this->Storage->PrepareForInput(devId)), + this->GetNumberOfValues()); + } + + /// 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 + /// have valid data in the execution array with the assumption that the array + /// will be filled soon (i.e. before any other methods of this object are + /// called). Returns a portal that can be used in code running in the + /// execution environment. + /// + vtkm::ArrayPortalRef PrepareForOutput(vtkm::Id numberOfValues, + vtkm::cont::DeviceAdapterId devId) + { + return make_ArrayPortalRef(static_cast*>( + this->Storage->PrepareForOutput(numberOfValues, devId)), + numberOfValues); + } + + /// 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 + /// the execution environment. Can throw an exception if this array does not + /// yet contain any data. Returns a portal that can be used in code running + /// in the execution environment. + /// + vtkm::ArrayPortalRef PrepareForInPlace(vtkm::cont::DeviceAdapterId devId) + { + return make_ArrayPortalRef( + static_cast*>(this->Storage->PrepareForInput(devId)), + this->GetNumberOfValues()); + } + + /// Returns the DeviceAdapterId for the current device. If there is no device + /// with an up-to-date copy of the data, VTKM_DEVICE_ADAPTER_UNDEFINED is + /// returned. + VTKM_CONT + DeviceAdapterId GetDeviceAdapterId() const { return this->Storage->GetDeviceAdapterId(); } + protected: std::shared_ptr Storage = nullptr; + +private: + template + bool IsSameType(std::true_type vtkmNotUsed(inheritsFromArrayHandleVirtual)) const + { + //All classes that derive from ArrayHandleVirtual have virtual methods so we can use + //typeid directly + return typeid(*this) == typeid(ArrayHandleType); + } + + template + bool IsSameType(std::false_type vtkmNotUsed(notFromArrayHandleVirtual)) const + { + //We need to go long the way to find the StorageType + //as StorageType is private on lots of derived ArrayHandles + //See Issue #314 + using ST = typename ArrayHandleType::StorageTag; + return this->Storage->IsType(typeid(vtkm::cont::internal::Storage)); + } }; template diff --git a/vtkm/cont/ArrayHandleVirtualCoordinates.h b/vtkm/cont/ArrayHandleVirtualCoordinates.h index f99543b70..ed0aa7c2d 100644 --- a/vtkm/cont/ArrayHandleVirtualCoordinates.h +++ b/vtkm/cont/ArrayHandleVirtualCoordinates.h @@ -20,17 +20,16 @@ #ifndef vtk_m_cont_ArrayHandleVirtualCoordinates_h #define vtk_m_cont_ArrayHandleVirtualCoordinates_h -#include +#include +#include + #include +#include #include + #include #include #include -#include -#include - -#include -#include #include #include @@ -40,473 +39,57 @@ namespace vtkm namespace cont { -namespace internal -{ - -//============================================================================= -class VTKM_ALWAYS_EXPORT CoordinatesPortalBase : public VirtualObjectBase -{ -public: - VTKM_EXEC_CONT virtual vtkm::Vec Get(vtkm::Id i) const = 0; - VTKM_EXEC_CONT virtual void Set(vtkm::Id i, - const vtkm::Vec& val) const = 0; -}; - -template -class VTKM_ALWAYS_EXPORT CoordinatesPortalImpl : public CoordinatesPortalBase -{ -public: - VTKM_CONT CoordinatesPortalImpl() = default; - VTKM_CONT explicit CoordinatesPortalImpl(const PortalType& portal) - : Portal(portal) - { - } - - VTKM_CONT void SetPortal(const PortalType& portal) { this->Portal = portal; } - - VTKM_EXEC_CONT vtkm::Vec Get(vtkm::Id i) const override - { - auto val = this->Portal.Get(i); - return { static_cast(val[0]), - static_cast(val[1]), - static_cast(val[2]) }; - } - - VTKM_EXEC_CONT void Set(vtkm::Id i, const vtkm::Vec& val) const override - { - using VecType = typename PortalType::ValueType; - using ComponentType = typename vtkm::VecTraits::ComponentType; - - this->Portal.Set(i, - { static_cast(val[0]), - static_cast(val[1]), - static_cast(val[2]) }); - } - -private: - PortalType Portal; -}; - -template -class VTKM_ALWAYS_EXPORT CoordinatesPortalImpl : public CoordinatesPortalBase -{ -public: - VTKM_CONT CoordinatesPortalImpl() = default; - VTKM_CONT explicit CoordinatesPortalImpl(const PortalType&) {} - VTKM_CONT void SetPortal(const PortalType&) {} - VTKM_EXEC_CONT vtkm::Vec Get(vtkm::Id) const override { return {}; } - VTKM_EXEC_CONT void Set(vtkm::Id, const vtkm::Vec&) const override {} -}; - -template -class VTKM_ALWAYS_EXPORT CoordinatesPortal - : public CoordinatesPortalImpl -{ -public: - VTKM_CONT CoordinatesPortal() = default; - VTKM_CONT explicit CoordinatesPortal(const PortalType& portal) - : CoordinatesPortalImpl(portal) - { - } -}; - -template -class VTKM_ALWAYS_EXPORT CoordinatesPortalConst : public CoordinatesPortalBase -{ -public: - VTKM_CONT CoordinatesPortalConst() = default; - VTKM_CONT explicit CoordinatesPortalConst(const PortalType& portal) - : Portal(portal) - { - } - - VTKM_CONT void SetPortal(const PortalType& portal) { this->Portal = portal; } - - VTKM_EXEC_CONT vtkm::Vec Get(vtkm::Id i) const override - { - auto val = this->Portal.Get(i); - return { static_cast(val[0]), - static_cast(val[1]), - static_cast(val[2]) }; - } - - VTKM_EXEC_CONT void Set(vtkm::Id, const vtkm::Vec&) const override {} - -private: - PortalType Portal; -}; - -class VTKM_ALWAYS_EXPORT ArrayPortalVirtualCoordinates +/// ArrayHandleVirtualCoordinates is a specialization of ArrayHandle. +class VTKM_CONT_EXPORT ArrayHandleVirtualCoordinates final + : public vtkm::cont::ArrayHandleVirtual> { public: using ValueType = vtkm::Vec; + using StorageTag = vtkm::cont::StorageTagVirtual; - VTKM_EXEC_CONT ArrayPortalVirtualCoordinates() - : NumberOfValues(0) - , VirtualPortal(nullptr) + using NonDefaultCoord = typename std::conditional::value, + vtkm::Vec, + vtkm::Vec>::type; + + ArrayHandleVirtualCoordinates() + : vtkm::cont::ArrayHandleVirtual() { } - VTKM_EXEC_CONT ArrayPortalVirtualCoordinates(vtkm::Id numberOfValues, - const CoordinatesPortalBase* virtualPortal) - : NumberOfValues(numberOfValues) - , VirtualPortal(virtualPortal) - { - } - - VTKM_EXEC_CONT vtkm::Id GetNumberOfValues() const { return this->NumberOfValues; } - - VTKM_EXEC_CONT ValueType Get(vtkm::Id i) const { return this->VirtualPortal->Get(i); } - - VTKM_EXEC_CONT void Set(vtkm::Id i, const ValueType& val) const - { - this->VirtualPortal->Set(i, val); - } - -private: - vtkm::Id NumberOfValues; - const CoordinatesPortalBase* VirtualPortal; -}; - -//============================================================================= -class VTKM_ALWAYS_EXPORT CoordinatesArrayHandleBase -{ -public: - using Portal = ArrayPortalVirtualCoordinates; - using PortalConst = ArrayPortalVirtualCoordinates; - - virtual ~CoordinatesArrayHandleBase() = default; - - VTKM_CONT virtual vtkm::Id GetNumberOfValues() const = 0; - - VTKM_CONT virtual Portal GetPortalControl() = 0; - VTKM_CONT virtual PortalConst GetPortalConstControl() = 0; - VTKM_CONT virtual void Allocate(vtkm::Id numberOfValues) = 0; - VTKM_CONT virtual void Shrink(vtkm::Id numberOfValues) = 0; - VTKM_CONT virtual void ReleaseResources() = 0; - VTKM_CONT virtual void ReleaseResourcesExecution() = 0; - - VTKM_CONT virtual PortalConst PrepareForInput(vtkm::cont::DeviceAdapterId deviceId) = 0; - VTKM_CONT virtual Portal PrepareForOutput(vtkm::Id numberOfValues, - vtkm::cont::DeviceAdapterId deviceId) = 0; - VTKM_CONT virtual Portal PrepareForInPlace(vtkm::cont::DeviceAdapterId deviceId) = 0; -}; - -template -class VTKM_ALWAYS_EXPORT CoordinatesArrayHandleArrayWrapper : public CoordinatesArrayHandleBase -{ -public: - VTKM_CONT explicit CoordinatesArrayHandleArrayWrapper(const ArrayHandleType& array) - : Array(array) - { - } - - VTKM_CONT const ArrayHandleType& GetArray() const { return this->Array; } - -protected: - ArrayHandleType Array; -}; - -template -class VTKM_ALWAYS_EXPORT CoordinatesArrayHandle - : public CoordinatesArrayHandleArrayWrapper -{ -public: - static_assert(std::is_same::value, "error"); - - using Portal = CoordinatesArrayHandleBase::Portal; - using PortalConst = CoordinatesArrayHandleBase::PortalConst; - - VTKM_CONT explicit CoordinatesArrayHandle(const ArrayHandleType& array) - : CoordinatesArrayHandleArrayWrapper(array) - { - } - - VTKM_CONT vtkm::Id GetNumberOfValues() const override { return this->Array.GetNumberOfValues(); } - - VTKM_CONT Portal GetPortalControl() override - { - this->ControlPortal.SetPortal(this->Array.GetPortalControl()); - return Portal(this->GetNumberOfValues(), &this->ControlPortal); - } - - VTKM_CONT PortalConst GetPortalConstControl() override - { - this->ControlConstPortal.SetPortal(this->Array.GetPortalConstControl()); - return PortalConst(this->GetNumberOfValues(), &this->ControlConstPortal); - } - - VTKM_CONT void Allocate(vtkm::Id numberOfValues) override - { - this->Array.Allocate(numberOfValues); - } - - VTKM_CONT void Shrink(vtkm::Id numberOfValues) override { this->Array.Shrink(numberOfValues); } - - VTKM_CONT void ReleaseResources() override { this->Array.ReleaseResources(); } - - VTKM_CONT void ReleaseResourcesExecution() override { this->Array.ReleaseResourcesExecution(); } - - VTKM_CONT PortalConst PrepareForInput(vtkm::cont::DeviceAdapterId deviceId) override - { - - PortalConst portal; - bool success = vtkm::cont::TryExecuteOnDevice( - deviceId, PrepareForInputFunctor(), DeviceList(), this, portal); - if (!success) - { - throwFailedRuntimeDeviceTransfer("ArrayHandleVirtualCoordinates", deviceId); - } - return portal; - } - - VTKM_CONT Portal PrepareForOutput(vtkm::Id numberOfValues, - vtkm::cont::DeviceAdapterId deviceId) override - { - Portal portal; - bool success = vtkm::cont::TryExecuteOnDevice( - deviceId, PrepareForOutputFunctor(), DeviceList(), this, numberOfValues, portal); - if (!success) - { - throwFailedRuntimeDeviceTransfer("ArrayHandleVirtualCoordinates", deviceId); - } - return portal; - } - - VTKM_CONT Portal PrepareForInPlace(vtkm::cont::DeviceAdapterId deviceId) override - { - Portal portal; - bool success = vtkm::cont::TryExecuteOnDevice( - deviceId, PrepareForInPlaceFunctor(), DeviceList(), this, portal); - if (!success) - { - throwFailedRuntimeDeviceTransfer("ArrayHandleVirtualCoordinates", deviceId); - } - return portal; - } - -private: - struct PrepareForInputFunctor - { - template - VTKM_CONT bool operator()(DeviceAdapter device, - CoordinatesArrayHandle* instance, - PortalConst& ret) const - { - auto portal = instance->Array.PrepareForInput(device); - instance->DevicePortalHandle.Reset(new CoordinatesPortalConst(portal), - true, - vtkm::ListTagBase()); - ret = PortalConst(portal.GetNumberOfValues(), - instance->DevicePortalHandle.PrepareForExecution(device)); - return true; - } - }; - - struct PrepareForOutputFunctor - { - template - VTKM_CONT bool operator()(DeviceAdapter device, - CoordinatesArrayHandle* instance, - vtkm::Id numberOfValues, - Portal& ret) const - { - auto portal = instance->Array.PrepareForOutput(numberOfValues, device); - instance->DevicePortalHandle.Reset( - new CoordinatesPortal(portal), true, vtkm::ListTagBase()); - ret = Portal(numberOfValues, instance->DevicePortalHandle.PrepareForExecution(device)); - return true; - } - }; - - struct PrepareForInPlaceFunctor - { - template - VTKM_CONT bool operator()(DeviceAdapter device, - CoordinatesArrayHandle* instance, - Portal& ret) const - { - auto portal = instance->Array.PrepareForInPlace(device); - instance->DevicePortalHandle.Reset( - new CoordinatesPortal(portal), true, vtkm::ListTagBase()); - ret = Portal(instance->Array.GetNumberOfValues(), - instance->DevicePortalHandle.PrepareForExecution(device)); - return true; - } - }; - - CoordinatesPortal ControlPortal; - CoordinatesPortalConst ControlConstPortal; - vtkm::cont::VirtualObjectHandle DevicePortalHandle; -}; - -//============================================================================= -struct VTKM_ALWAYS_EXPORT StorageTagVirtualCoordinates -{ -}; - -template <> -class VTKM_ALWAYS_EXPORT Storage, StorageTagVirtualCoordinates> -{ -public: - using ValueType = vtkm::Vec; - using PortalType = CoordinatesArrayHandleBase::Portal; - using PortalConstType = CoordinatesArrayHandleBase::PortalConst; - - VTKM_CONT Storage() = default; - - template - VTKM_CONT explicit Storage(const ArrayHandleType& array, DeviceList) - : Array(new CoordinatesArrayHandle(array)) - { - } - - VTKM_CONT PortalType GetPortal() { return this->Array->GetPortalControl(); } - - VTKM_CONT PortalConstType GetPortalConst() const { return this->Array->GetPortalConstControl(); } - - VTKM_CONT vtkm::Id GetNumberOfValues() const { return this->Array->GetNumberOfValues(); } - - VTKM_CONT void Allocate(vtkm::Id numberOfValues) { this->Array->Allocate(numberOfValues); } - - VTKM_CONT void Shrink(vtkm::Id numberOfValues) { this->Array->Shrink(numberOfValues); } - - VTKM_CONT void ReleaseResources() { this->Array->ReleaseResources(); } - - VTKM_CONT CoordinatesArrayHandleBase* GetVirtualArray() const { return this->Array.get(); } - -private: - std::shared_ptr Array; -}; - -//============================================================================= -template -class VTKM_ALWAYS_EXPORT - ArrayTransfer, StorageTagVirtualCoordinates, DeviceAdapter> -{ -public: - using ValueType = vtkm::Vec; - using StorageType = vtkm::cont::internal::Storage; - - using PortalControl = typename StorageType::PortalType; - using PortalConstControl = typename StorageType::PortalConstType; - using PortalExecution = CoordinatesArrayHandleBase::Portal; - using PortalConstExecution = CoordinatesArrayHandleBase::PortalConst; - - VTKM_CONT - ArrayTransfer(StorageType* storage) - : Array(storage->GetVirtualArray()) - { - } - - VTKM_CONT - vtkm::Id GetNumberOfValues() const { return this->Array->GetNumberOfValues(); } - - VTKM_CONT - PortalConstExecution PrepareForInput(bool) - { - return this->Array->PrepareForInput(DeviceAdapter()); - } - - VTKM_CONT - PortalExecution PrepareForInPlace(bool) - { - return this->Array->PrepareForInPlace(DeviceAdapter()); - } - - VTKM_CONT - PortalExecution PrepareForOutput(vtkm::Id numberOfValues) - { - return this->Array->PrepareForOutput(numberOfValues, DeviceAdapter()); - } - - VTKM_CONT - void RetrieveOutputData(StorageType*) const - { - // Implementation of this method should be unnecessary. - } - - VTKM_CONT - void Shrink(vtkm::Id numberOfValues) { this->Array->Shrink(numberOfValues); } - - // ArrayTransfer should only be capable of releasing resources in the execution - // environment - VTKM_CONT - void ReleaseResources() { this->Array->ReleaseResourcesExecution(); } - -private: - CoordinatesArrayHandleBase* Array; -}; - -} // internal - -//============================================================================= -class VTKM_ALWAYS_EXPORT ArrayHandleVirtualCoordinates - : public ArrayHandle, internal::StorageTagVirtualCoordinates> -{ -public: - VTKM_ARRAY_HANDLE_SUBCLASS_NT( - ArrayHandleVirtualCoordinates, - (ArrayHandle, internal::StorageTagVirtualCoordinates>)); - - template explicit ArrayHandleVirtualCoordinates( - const vtkm::cont::ArrayHandle, StorageTag>& array, - DeviceList devices = DeviceList()) - : Superclass(typename Superclass::StorageType(array, devices)) + const vtkm::cont::ArrayHandle& ah) + : vtkm::cont::ArrayHandleVirtual(ah) { } - template - explicit ArrayHandleVirtualCoordinates( - const vtkm::cont::ArrayHandle, StorageTag>& array, - DeviceList devices = DeviceList()) - : Superclass(typename Superclass::StorageType(array, devices)) + template + explicit ArrayHandleVirtualCoordinates(const vtkm::cont::ArrayHandle& ah) + : vtkm::cont::ArrayHandleVirtual( + std::make_shared>(ah)) { } - template - bool IsType() const + template + explicit ArrayHandleVirtualCoordinates(const vtkm::cont::ArrayHandle& ah) + : vtkm::cont::ArrayHandleVirtual() { - return this->GetArrayHandleWrapper() != nullptr; + auto castedHandle = vtkm::cont::make_ArrayHandleCast(ah); + using ST = typename decltype(castedHandle)::StorageTag; + this->Storage = std::make_shared>(castedHandle); } + /// Returns this array cast to the given \c ArrayHandle type. Throws \c + /// ErrorBadType if the cast does not work. Use \c IsType + /// to check if the cast can happen. + /// template - bool IsSameType(const ArrayHandleType&) const + VTKM_CONT ArrayHandleType Cast() const { - return this->GetArrayHandleWrapper() != nullptr; - } - - template - const ArrayHandleType Cast() const - { - auto wrapper = this->GetArrayHandleWrapper(); - if (!wrapper) - { - VTKM_LOG_CAST_FAIL(*this, ArrayHandleType); - throw vtkm::cont::ErrorBadType("dynamic cast failed"); - } - VTKM_LOG_CAST_SUCC(*this, wrapper->GetArray()); - return ArrayHandleType(wrapper->GetArray()); - } - -private: - template - struct WrapperType - { - VTKM_IS_ARRAY_HANDLE(ArrayHandleType); - - using ValueType = typename ArrayHandleType::ValueType; - using StorageTag = typename ArrayHandleType::StorageTag; - using BaseArrayHandleType = vtkm::cont::ArrayHandle; - using Type = internal::CoordinatesArrayHandleArrayWrapper; - }; - - template - VTKM_CONT const typename WrapperType::Type* GetArrayHandleWrapper() const - { - auto va = this->GetStorage().GetVirtualArray(); - return dynamic_cast::Type*>(va); + using T = typename ArrayHandleType::ValueType; + using S = typename ArrayHandleType::StorageTag; + const vtkm::cont::StorageVirtual* storage = this->GetStorage(); + const auto* any = storage->Cast>(); + return any->GetHandle(); } }; @@ -515,9 +98,11 @@ void CastAndCall(const vtkm::cont::ArrayHandleVirtualCoordinates& coords, Functor&& f, Args&&... args) { - if (coords.IsType()) + using HandleType = ArrayHandleUniformPointCoordinates; + if (coords.IsType()) { - f(coords.Cast(), std::forward(args)...); + HandleType uniform = coords.Cast(); + f(uniform, std::forward(args)...); } else { @@ -525,113 +110,13 @@ void CastAndCall(const vtkm::cont::ArrayHandleVirtualCoordinates& coords, } } -template -void CastAndCall(const typename vtkm::cont::ArrayHandleVirtualCoordinates::Superclass& coords, - Functor&& f, - Args&&... args) -{ - CastAndCall(static_cast(coords), - std::forward(f), - std::forward(args)...); -} -} -} // vtkm::cont -#ifdef VTKM_CUDA - -// Cuda seems to have a bug where it expects the template class VirtualObjectTransfer -// to be instantiated in a consistent order among all the translation units of an -// executable. Failing to do so results in random crashes and incorrect results. -// We workaroud this issue by explicitly instantiating VirtualObjectTransfer for -// all the portal types here. - -#include - -#include -#include -#include -#include -#include -#include - -namespace vtkm -{ -namespace cont -{ -namespace internal -{ - -template -struct CudaPortalTypes -{ - using PortalConst = typename ArrayHandleType::template ExecutionTypes< - vtkm::cont::DeviceAdapterTagCuda>::PortalConst; - using Portal = - typename ArrayHandleType::template ExecutionTypes::Portal; -}; - -using CudaPortalsBasicF32 = CudaPortalTypes>>; -using CudaPortalsBasicF64 = CudaPortalTypes>>; -using CudaPortalsUniformPointCoordinates = - CudaPortalTypes; -using CudaPortalsRectilinearCoords = CudaPortalTypes< - vtkm::cont::ArrayHandleCartesianProduct, - vtkm::cont::ArrayHandle, - vtkm::cont::ArrayHandle>>; -using CudaPortalsCompositeCoords = CudaPortalTypes< - vtkm::cont::ArrayHandleCompositeVector, - vtkm::cont::ArrayHandle, - vtkm::cont::ArrayHandle>>; -} -} -} // vtkm::cont::internal - -VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::cont::internal::CoordinatesPortalConst< - vtkm::cont::internal::CudaPortalsBasicF32::PortalConst>); -VTKM_EXPLICITLY_INSTANTIATE_TRANSFER( - vtkm::cont::internal::CoordinatesPortal); -VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::cont::internal::CoordinatesPortalConst< - vtkm::cont::internal::CudaPortalsBasicF64::PortalConst>); -VTKM_EXPLICITLY_INSTANTIATE_TRANSFER( - vtkm::cont::internal::CoordinatesPortal); -VTKM_EXPLICITLY_INSTANTIATE_TRANSFER( - vtkm::cont::internal::CoordinatesPortalConst< - vtkm::cont::internal::CudaPortalsUniformPointCoordinates::PortalConst>); -VTKM_EXPLICITLY_INSTANTIATE_TRANSFER( - vtkm::cont::internal::CoordinatesPortal< - vtkm::cont::internal::CudaPortalsUniformPointCoordinates::Portal>); -VTKM_EXPLICITLY_INSTANTIATE_TRANSFER( - vtkm::cont::internal::CoordinatesPortalConst< - vtkm::cont::internal::CudaPortalsRectilinearCoords::PortalConst>); -VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::cont::internal::CoordinatesPortal< - vtkm::cont::internal::CudaPortalsRectilinearCoords::Portal>); -VTKM_EXPLICITLY_INSTANTIATE_TRANSFER( - vtkm::cont::internal::CoordinatesPortalConst< - vtkm::cont::internal::CudaPortalsCompositeCoords::PortalConst>); -VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::cont::internal::CoordinatesPortal< - vtkm::cont::internal::CudaPortalsCompositeCoords::Portal>); - -#endif // VTKM_CUDA - -//============================================================================= -// Specializations of serialization related classes -namespace vtkm -{ -namespace cont -{ template <> struct TypeString { static VTKM_CONT const std::string Get() { return "AH_VirtualCoordinates"; } }; - -template <> -struct TypeString, - vtkm::cont::internal::StorageTagVirtualCoordinates>> - : TypeString -{ -}; } } // vtkm::cont @@ -655,16 +140,23 @@ public: static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj) { const auto& virtArray = static_cast(obj); + const vtkm::cont::StorageVirtual* storage = virtArray.GetStorage(); if (virtArray.IsType()) { - auto array = virtArray.Cast(); - diy::save(bb, vtkm::cont::TypeString::Get()); + using HandleType = vtkm::cont::ArrayHandleUniformPointCoordinates; + using T = typename HandleType::ValueType; + using S = typename HandleType::StorageTag; + auto array = storage->Cast>(); + diy::save(bb, vtkm::cont::TypeString::Get()); diy::save(bb, array); } else if (virtArray.IsType()) { - auto array = virtArray.Cast(); - diy::save(bb, vtkm::cont::TypeString::Get()); + using HandleType = RectilinearCoordsArrayType; + using T = typename HandleType::ValueType; + using S = typename HandleType::StorageTag; + auto array = storage->Cast>(); + diy::save(bb, vtkm::cont::TypeString::Get()); diy::save(bb, array); } else @@ -705,13 +197,6 @@ public: } }; -template <> -struct Serialization, - vtkm::cont::internal::StorageTagVirtualCoordinates>> - : Serialization -{ -}; - } // diy #endif // vtk_m_cont_ArrayHandleVirtualCoordinates_h diff --git a/vtkm/cont/CellSet.h b/vtkm/cont/CellSet.h index 54b0734b2..8f05fc585 100644 --- a/vtkm/cont/CellSet.h +++ b/vtkm/cont/CellSet.h @@ -25,8 +25,8 @@ #include #include +#include #include -#include #include namespace vtkm diff --git a/vtkm/cont/CoordinateSystem.cxx b/vtkm/cont/CoordinateSystem.cxx index a5e416492..7973ee2b0 100644 --- a/vtkm/cont/CoordinateSystem.cxx +++ b/vtkm/cont/CoordinateSystem.cxx @@ -27,10 +27,6 @@ namespace vtkm namespace cont { -using CoordinatesTypeList = vtkm::ListTagBase; -using CoordinatesStorageList = - vtkm::ListTagBase; - VTKM_CONT CoordinateSystem::CoordinateSystem() : Superclass() { @@ -38,7 +34,7 @@ VTKM_CONT CoordinateSystem::CoordinateSystem() VTKM_CONT CoordinateSystem::CoordinateSystem( std::string name, - const vtkm::cont::ArrayHandleVirtualCoordinates::Superclass& data) + const vtkm::cont::ArrayHandleVirtual>& data) : Superclass(name, Association::POINTS, data) { } @@ -64,7 +60,8 @@ vtkm::cont::ArrayHandleVirtualCoordinates CoordinateSystem::GetData() const } VTKM_CONT -void CoordinateSystem::SetData(const vtkm::cont::ArrayHandleVirtualCoordinates::Superclass& newdata) +void CoordinateSystem::SetData( + const vtkm::cont::ArrayHandleVirtual>& newdata) { this->Superclass::SetData(newdata); } @@ -76,26 +73,6 @@ void CoordinateSystem::PrintSummary(std::ostream& out) const this->Superclass::PrintSummary(out); } -VTKM_CONT -void CoordinateSystem::GetRange(vtkm::Range* range) const -{ - this->Superclass::GetRange(range, CoordinatesTypeList(), CoordinatesStorageList()); -} - -VTKM_CONT -const vtkm::cont::ArrayHandle& CoordinateSystem::GetRange() const -{ - return this->Superclass::GetRange(CoordinatesTypeList(), CoordinatesStorageList()); -} - -VTKM_CONT -vtkm::Bounds CoordinateSystem::GetBounds() const -{ - vtkm::Range ranges[3]; - this->GetRange(ranges); - return vtkm::Bounds(ranges[0], ranges[1], ranges[2]); -} - template VTKM_CONT_EXPORT CoordinateSystem::CoordinateSystem( std::string name, const vtkm::cont::ArrayHandle>&); @@ -141,12 +118,12 @@ template VTKM_CONT_EXPORT CoordinateSystem::CoordinateSystem( vtkm::cont::ArrayHandle>::StorageTag>&); template VTKM_CONT_EXPORT CoordinateSystem::CoordinateSystem(std::string name, - const vtkm::cont::DynamicArrayHandle&); + const vtkm::cont::ArrayHandleVariant&); template VTKM_CONT_EXPORT void CoordinateSystem::SetData( const vtkm::cont::ArrayHandle>&); template VTKM_CONT_EXPORT void CoordinateSystem::SetData( const vtkm::cont::ArrayHandle>&); -template VTKM_CONT_EXPORT void CoordinateSystem::SetData(const vtkm::cont::DynamicArrayHandle&); +template VTKM_CONT_EXPORT void CoordinateSystem::SetData(const vtkm::cont::ArrayHandleVariant&); } } // namespace vtkm::cont diff --git a/vtkm/cont/CoordinateSystem.h b/vtkm/cont/CoordinateSystem.h index 3a303d555..abf0cdf75 100644 --- a/vtkm/cont/CoordinateSystem.h +++ b/vtkm/cont/CoordinateSystem.h @@ -33,17 +33,20 @@ namespace cont class VTKM_CONT_EXPORT CoordinateSystem : public vtkm::cont::Field { using Superclass = vtkm::cont::Field; + using CoordinatesTypeList = + vtkm::ListTagBase; public: VTKM_CONT CoordinateSystem(); - VTKM_CONT CoordinateSystem(std::string name, - const vtkm::cont::ArrayHandleVirtualCoordinates::Superclass& data); + VTKM_CONT CoordinateSystem( + std::string name, + const vtkm::cont::ArrayHandleVirtual>& data); - template + template VTKM_CONT CoordinateSystem(std::string name, - const vtkm::cont::DynamicArrayHandleBase& data); + const vtkm::cont::ArrayHandleVariantBase& data); template VTKM_CONT CoordinateSystem(std::string name, const ArrayHandle& data); @@ -60,23 +63,35 @@ public: VTKM_CONT vtkm::cont::ArrayHandleVirtualCoordinates GetData() const; - VTKM_CONT void SetData(const vtkm::cont::ArrayHandleVirtualCoordinates::Superclass& newdata); + VTKM_CONT void SetData( + const vtkm::cont::ArrayHandleVirtual>& newdata); - template - VTKM_CONT void SetData(const vtkm::cont::ArrayHandle& newdata); + template + VTKM_CONT void SetData(const vtkm::cont::ArrayHandle& newdata); VTKM_CONT - template - void SetData(const vtkm::cont::DynamicArrayHandleBase& newdata); + template + void SetData(const vtkm::cont::ArrayHandleVariantBase& newdata); VTKM_CONT - void GetRange(vtkm::Range* range) const; + void GetRange(vtkm::Range* range) const + { + this->Superclass::GetRange(range, CoordinatesTypeList()); + } VTKM_CONT - const vtkm::cont::ArrayHandle& GetRange() const; + const vtkm::cont::ArrayHandle& GetRange() const + { + return this->Superclass::GetRange(CoordinatesTypeList()); + } VTKM_CONT - vtkm::Bounds GetBounds() const; + vtkm::Bounds GetBounds() const + { + vtkm::Range ranges[3]; + this->GetRange(ranges); + return vtkm::Bounds(ranges[0], ranges[1], ranges[2]); + } virtual void PrintSummary(std::ostream& out) const override; diff --git a/vtkm/cont/CoordinateSystem.hxx b/vtkm/cont/CoordinateSystem.hxx index 184fedc90..f009e7192 100644 --- a/vtkm/cont/CoordinateSystem.hxx +++ b/vtkm/cont/CoordinateSystem.hxx @@ -48,22 +48,22 @@ struct MakeArrayHandleVirtualCoordinatesFunctor } }; -template +template VTKM_CONT vtkm::cont::ArrayHandleVirtualCoordinates MakeArrayHandleVirtualCoordinates( - const vtkm::cont::DynamicArrayHandleBase& array) + const vtkm::cont::ArrayHandleVariantBase& array) { vtkm::cont::ArrayHandleVirtualCoordinates output; - vtkm::cont::CastAndCall(array.ResetTypeList(vtkm::TypeListTagFieldVec3{}), + vtkm::cont::CastAndCall(array.ResetTypes(vtkm::TypeListTagFieldVec3{}), MakeArrayHandleVirtualCoordinatesFunctor{}, output); return output; } } // namespace detail -template +template VTKM_CONT CoordinateSystem::CoordinateSystem( std::string name, - const vtkm::cont::DynamicArrayHandleBase& data) + const vtkm::cont::ArrayHandleVariantBase& data) : Superclass(name, Association::POINTS, detail::MakeArrayHandleVirtualCoordinates(data)) { } @@ -81,9 +81,9 @@ VTKM_CONT void CoordinateSystem::SetData(const vtkm::cont::ArrayHandleSetData(vtkm::cont::ArrayHandleVirtualCoordinates(newdata)); } -template +template VTKM_CONT void CoordinateSystem::SetData( - const vtkm::cont::DynamicArrayHandleBase& newdata) + const vtkm::cont::ArrayHandleVariantBase& newdata) { this->SetData(detail::MakeArrayHandleVirtualCoordinates(newdata)); } diff --git a/vtkm/cont/DataSet.h b/vtkm/cont/DataSet.h index 555d7c41a..80c06cff2 100644 --- a/vtkm/cont/DataSet.h +++ b/vtkm/cont/DataSet.h @@ -23,9 +23,9 @@ #include #include +#include #include #include -#include #include #include #include @@ -193,7 +193,6 @@ namespace cont { template struct SerializableDataSet { @@ -212,12 +211,11 @@ struct SerializableDataSet namespace diy { -template -struct Serialization< - vtkm::cont::SerializableDataSet> +template +struct Serialization> { private: - using Type = vtkm::cont::SerializableDataSet; + using Type = vtkm::cont::SerializableDataSet; public: static VTKM_CONT void save(BinaryBuffer& bb, const Type& serializable) @@ -242,8 +240,7 @@ public: diy::save(bb, numberOfFields); for (vtkm::IdComponent i = 0; i < numberOfFields; ++i) { - diy::save( - bb, vtkm::cont::SerializableField(dataset.GetField(i))); + diy::save(bb, vtkm::cont::SerializableField(dataset.GetField(i))); } } @@ -274,7 +271,7 @@ public: diy::load(bb, numberOfFields); for (vtkm::IdComponent i = 0; i < numberOfFields; ++i) { - vtkm::cont::SerializableField field; + vtkm::cont::SerializableField field; diy::load(bb, field); dataset.AddField(field.Field); } diff --git a/vtkm/cont/DataSetFieldAdd.h b/vtkm/cont/DataSetFieldAdd.h index 8e5a04924..ae99538ae 100644 --- a/vtkm/cont/DataSetFieldAdd.h +++ b/vtkm/cont/DataSetFieldAdd.h @@ -38,7 +38,7 @@ public: VTKM_CONT static void AddPointField(vtkm::cont::DataSet& dataSet, const std::string& fieldName, - const vtkm::cont::DynamicArrayHandle& field) + const vtkm::cont::ArrayHandleVariant& field) { dataSet.AddField(Field(fieldName, vtkm::cont::Field::Association::POINTS, field)); } @@ -74,7 +74,7 @@ public: VTKM_CONT static void AddCellField(vtkm::cont::DataSet& dataSet, const std::string& fieldName, - const vtkm::cont::DynamicArrayHandle& field, + const vtkm::cont::ArrayHandleVariant& field, const std::string& cellSetName) { dataSet.AddField( @@ -119,7 +119,7 @@ public: VTKM_CONT static void AddCellField(vtkm::cont::DataSet& dataSet, const std::string& fieldName, - const vtkm::cont::DynamicArrayHandle& field, + const vtkm::cont::ArrayHandleVariant& field, vtkm::Id cellSetIndex = 0) { std::string cellSetName = dataSet.GetCellSet(cellSetIndex).GetName(); diff --git a/vtkm/cont/Field.cxx b/vtkm/cont/Field.cxx index ae5977f78..20093a89a 100644 --- a/vtkm/cont/Field.cxx +++ b/vtkm/cont/Field.cxx @@ -18,7 +18,7 @@ // this software. //============================================================================ -#include +#include "Field.h" namespace vtkm { @@ -27,7 +27,7 @@ namespace cont /// constructors for points / whole mesh VTKM_CONT -Field::Field(std::string name, Association association, const vtkm::cont::DynamicArrayHandle& data) +Field::Field(std::string name, Association association, const vtkm::cont::ArrayHandleVariant& data) : Name(name) , FieldAssociation(association) , AssocCellSetName() @@ -45,7 +45,7 @@ VTKM_CONT Field::Field(std::string name, Association association, const std::string& cellSetName, - const vtkm::cont::DynamicArrayHandle& data) + const vtkm::cont::ArrayHandleVariant& data) : Name(name) , FieldAssociation(association) , AssocCellSetName(cellSetName) @@ -62,7 +62,7 @@ VTKM_CONT Field::Field(std::string name, Association association, vtkm::IdComponent logicalDim, - const vtkm::cont::DynamicArrayHandle& data) + const vtkm::cont::ArrayHandleVariant& data) : Name(name) , FieldAssociation(association) , AssocCellSetName() @@ -155,36 +155,18 @@ Field::~Field() { } -VTKM_CONT -const vtkm::cont::ArrayHandle& Field::GetRange() const -{ - return this->GetRange(VTKM_DEFAULT_TYPE_LIST_TAG(), VTKM_DEFAULT_STORAGE_LIST_TAG()); -} VTKM_CONT -void Field::GetRange(vtkm::Range* range) const -{ - this->GetRange(range, VTKM_DEFAULT_TYPE_LIST_TAG(), VTKM_DEFAULT_STORAGE_LIST_TAG()); -} - -VTKM_CONT -const vtkm::cont::DynamicArrayHandle& Field::GetData() const +const vtkm::cont::ArrayHandleVariant& Field::GetData() const { return this->Data; } VTKM_CONT -vtkm::cont::DynamicArrayHandle& Field::GetData() +vtkm::cont::ArrayHandleVariant& Field::GetData() { this->ModifiedFlag = true; return this->Data; } - -VTKM_CONT -const vtkm::cont::ArrayHandle& Field::GetRange(VTKM_DEFAULT_TYPE_LIST_TAG, - VTKM_DEFAULT_STORAGE_LIST_TAG) const -{ - return this->GetRangeImpl(VTKM_DEFAULT_TYPE_LIST_TAG(), VTKM_DEFAULT_STORAGE_LIST_TAG()); -} } } // namespace vtkm::cont diff --git a/vtkm/cont/Field.h b/vtkm/cont/Field.h index 66abbe658..a75accfe5 100644 --- a/vtkm/cont/Field.h +++ b/vtkm/cont/Field.h @@ -26,9 +26,10 @@ #include #include +#include #include #include -#include +#include namespace vtkm { @@ -38,26 +39,18 @@ namespace cont namespace internal { -class ComputeRange +struct ComputeRange { -public: - ComputeRange(ArrayHandle& range) - : Range(&range) - { - } - template - void operator()(const ArrayHandleType& input) const + void operator()(const ArrayHandleType& input, vtkm::cont::ArrayHandle& range) const { - *this->Range = vtkm::cont::ArrayRangeCompute(input); + range = vtkm::cont::ArrayRangeCompute(input); } - -private: - vtkm::cont::ArrayHandle* Range; }; } // namespace internal + /// A \c Field encapsulates an array on some piece of the mesh, such as /// the points, a cell set, a point logical dimension, or the whole mesh. /// @@ -78,11 +71,13 @@ public: /// constructors for points / whole mesh VTKM_CONT - Field(std::string name, Association association, const vtkm::cont::DynamicArrayHandle& data); + Field(std::string name, Association association, const vtkm::cont::ArrayHandleVariant& data); template - VTKM_CONT Field(std::string name, Association association, const ArrayHandle& data) - : Field(name, association, vtkm::cont::DynamicArrayHandle{ data }) + VTKM_CONT Field(std::string name, + Association association, + const vtkm::cont::ArrayHandle& data) + : Field(name, association, vtkm::cont::ArrayHandleVariant{ data }) { } @@ -91,14 +86,14 @@ public: Field(std::string name, Association association, const std::string& cellSetName, - const vtkm::cont::DynamicArrayHandle& data); + const vtkm::cont::ArrayHandleVariant& data); template VTKM_CONT Field(std::string name, Association association, const std::string& cellSetName, const vtkm::cont::ArrayHandle& data) - : Field(name, association, cellSetName, vtkm::cont::DynamicArrayHandle{ data }) + : Field(name, association, cellSetName, vtkm::cont::ArrayHandleVariant{ data }) { } @@ -107,14 +102,14 @@ public: Field(std::string name, Association association, vtkm::IdComponent logicalDim, - const vtkm::cont::DynamicArrayHandle& data); + const vtkm::cont::ArrayHandleVariant& data); template VTKM_CONT Field(std::string name, Association association, vtkm::IdComponent logicalDim, const vtkm::cont::ArrayHandle& data) - : Field(name, association, logicalDim, vtkm::cont::DynamicArrayHandle{ data }) + : Field(name, association, logicalDim, vtkm::cont::ArrayHandleVariant{ data }) { } @@ -126,40 +121,19 @@ public: VTKM_CONT Field& operator=(const vtkm::cont::Field& src); VTKM_CONT Field& operator=(vtkm::cont::Field&& src) noexcept; - VTKM_CONT - const std::string& GetName() const { return this->Name; } + VTKM_CONT const std::string& GetName() const { return this->Name; } + VTKM_CONT Association GetAssociation() const { return this->FieldAssociation; } + VTKM_CONT std::string GetAssocCellSet() const { return this->AssocCellSetName; } + VTKM_CONT vtkm::IdComponent GetAssocLogicalDim() const { return this->AssocLogicalDim; } + const vtkm::cont::ArrayHandleVariant& GetData() const; + vtkm::cont::ArrayHandleVariant& GetData(); - VTKM_CONT - Association GetAssociation() const { return this->FieldAssociation; } - VTKM_CONT - std::string GetAssocCellSet() const { return this->AssocCellSetName; } - - VTKM_CONT - vtkm::IdComponent GetAssocLogicalDim() const { return this->AssocLogicalDim; } - - template - VTKM_CONT const vtkm::cont::ArrayHandle& GetRange(TypeList, StorageList) const + template + VTKM_CONT void GetRange(vtkm::Range* range, TypeList) const { - VTKM_IS_LIST_TAG(TypeList); - VTKM_IS_LIST_TAG(StorageList); - - return this->GetRangeImpl(TypeList(), StorageList()); - } - - VTKM_CONT - const vtkm::cont::ArrayHandle& GetRange(VTKM_DEFAULT_TYPE_LIST_TAG, - VTKM_DEFAULT_STORAGE_LIST_TAG) const; - - template - VTKM_CONT void GetRange(vtkm::Range* range, TypeList, StorageList) const - { - VTKM_IS_LIST_TAG(TypeList); - VTKM_IS_LIST_TAG(StorageList); - - this->GetRange(TypeList(), StorageList()); - - vtkm::Id length = this->Range.GetNumberOfValues(); + this->GetRangeImpl(TypeList()); + const vtkm::Id length = this->Range.GetNumberOfValues(); for (vtkm::Id i = 0; i < length; ++i) { range[i] = this->Range.GetPortalConstControl().Get(i); @@ -169,28 +143,19 @@ public: template VTKM_CONT const vtkm::cont::ArrayHandle& GetRange(TypeList) const { - VTKM_IS_LIST_TAG(TypeList); - - return this->GetRange(TypeList(), VTKM_DEFAULT_STORAGE_LIST_TAG()); + return this->GetRangeImpl(TypeList()); } - template - VTKM_CONT void GetRange(vtkm::Range* range, TypeList) const + VTKM_CONT + const vtkm::cont::ArrayHandle& GetRange() const { - VTKM_IS_LIST_TAG(TypeList); + return this->GetRangeImpl(VTKM_DEFAULT_TYPE_LIST_TAG()); + }; - this->GetRange(range, TypeList(), VTKM_DEFAULT_STORAGE_LIST_TAG()); - } - - VTKM_CONT - const vtkm::cont::ArrayHandle& GetRange() const; - - VTKM_CONT - void GetRange(vtkm::Range* range) const; - - const vtkm::cont::DynamicArrayHandle& GetData() const; - - vtkm::cont::DynamicArrayHandle& GetData(); + VTKM_CONT void GetRange(vtkm::Range* range) const + { + return this->GetRange(range, VTKM_DEFAULT_TYPE_LIST_TAG()); + }; template VTKM_CONT void SetData(const vtkm::cont::ArrayHandle& newdata) @@ -200,27 +165,19 @@ public: } VTKM_CONT - void SetData(const vtkm::cont::DynamicArrayHandle& newdata) + void SetData(const vtkm::cont::ArrayHandleVariant& newdata) { this->Data = newdata; this->ModifiedFlag = true; } - template - VTKM_CONT void CopyData(const T* ptr, vtkm::Id nvals) - { - this->Data = vtkm::cont::make_ArrayHandle(ptr, nvals, true); - this->ModifiedFlag = true; - } - VTKM_CONT virtual void PrintSummary(std::ostream& out) const; VTKM_CONT virtual void ReleaseResourcesExecution() { - // TODO: Call ReleaseResourcesExecution on the data when - // the DynamicArrayHandle class is able to do so. + this->Data.ReleaseResourcesExecution(); this->Range.ReleaseResourcesExecution(); } @@ -231,20 +188,19 @@ private: std::string AssocCellSetName; ///< only populate if assoc is cells vtkm::IdComponent AssocLogicalDim; ///< only populate if assoc is logical dim - vtkm::cont::DynamicArrayHandle Data; + vtkm::cont::ArrayHandleVariant Data; mutable vtkm::cont::ArrayHandle Range; mutable bool ModifiedFlag = true; - template - VTKM_CONT const vtkm::cont::ArrayHandle& GetRangeImpl(TypeList, StorageList) const + template + VTKM_CONT const vtkm::cont::ArrayHandle& GetRangeImpl(TypeList) const { VTKM_IS_LIST_TAG(TypeList); - VTKM_IS_LIST_TAG(StorageList); if (this->ModifiedFlag) { - internal::ComputeRange computeRange(this->Range); - this->Data.ResetTypeAndStorageLists(TypeList(), StorageList()).CastAndCall(computeRange); + vtkm::cont::CastAndCall( + this->Data.ResetTypes(TypeList()), internal::ComputeRange{}, this->Range); this->ModifiedFlag = false; } @@ -255,7 +211,7 @@ private: template void CastAndCall(const vtkm::cont::Field& field, Functor&& f, Args&&... args) { - field.GetData().CastAndCall(std::forward(f), std::forward(args)...); + vtkm::cont::CastAndCall(field.GetData(), std::forward(f), std::forward(args)...); } //@{ @@ -325,15 +281,21 @@ vtkm::cont::Field make_Field(std::string name, } //@} +} // namespace cont +} // namespace vtkm + + +namespace vtkm +{ +namespace cont +{ namespace internal { - template <> struct DynamicTransformTraits { using DynamicTag = vtkm::cont::internal::DynamicTransformTagCastAndCall; }; - } // namespace internal } // namespace cont } // namespace vtkm @@ -344,9 +306,7 @@ namespace vtkm { namespace cont { - -template +template struct SerializableField { SerializableField() = default; @@ -358,17 +318,17 @@ struct SerializableField vtkm::cont::Field Field; }; -} -} // vtkm::cont +} // namespace cont +} // namespace vtkm namespace diy { -template -struct Serialization> +template +struct Serialization> { private: - using Type = vtkm::cont::SerializableField; + using Type = vtkm::cont::SerializableField; public: static VTKM_CONT void save(BinaryBuffer& bb, const Type& serializable) @@ -385,7 +345,7 @@ public: { diy::save(bb, field.GetAssocLogicalDim()); } - diy::save(bb, field.GetData().ResetTypeAndStorageLists(TypeList{}, StorageList{})); + diy::save(bb, field.GetData().ResetTypes(TypeList{})); } static VTKM_CONT void load(BinaryBuffer& bb, Type& serializable) @@ -398,26 +358,26 @@ public: diy::load(bb, assocVal); auto assoc = static_cast(assocVal); - vtkm::cont::DynamicArrayHandleBase data; + vtkm::cont::ArrayHandleVariantBase data; if (assoc == vtkm::cont::Field::Association::CELL_SET) { std::string assocCellSetName; diy::load(bb, assocCellSetName); diy::load(bb, data); field = - vtkm::cont::Field(name, assoc, assocCellSetName, vtkm::cont::DynamicArrayHandle(data)); + vtkm::cont::Field(name, assoc, assocCellSetName, vtkm::cont::ArrayHandleVariant(data)); } else if (assoc == vtkm::cont::Field::Association::LOGICAL_DIM) { vtkm::IdComponent assocLogicalDim; diy::load(bb, assocLogicalDim); diy::load(bb, data); - field = vtkm::cont::Field(name, assoc, assocLogicalDim, vtkm::cont::DynamicArrayHandle(data)); + field = vtkm::cont::Field(name, assoc, assocLogicalDim, vtkm::cont::ArrayHandleVariant(data)); } else { diy::load(bb, data); - field = vtkm::cont::Field(name, assoc, vtkm::cont::DynamicArrayHandle(data)); + field = vtkm::cont::Field(name, assoc, vtkm::cont::ArrayHandleVariant(data)); } } }; diff --git a/vtkm/cont/FieldRangeCompute.cxx b/vtkm/cont/FieldRangeCompute.cxx index 9cf5c518e..29cfd4750 100644 --- a/vtkm/cont/FieldRangeCompute.cxx +++ b/vtkm/cont/FieldRangeCompute.cxx @@ -34,7 +34,7 @@ vtkm::cont::ArrayHandle FieldRangeCompute(const vtkm::cont::DataSet vtkm::cont::Field::Association assoc) { return vtkm::cont::detail::FieldRangeComputeImpl( - dataset, name, assoc, VTKM_DEFAULT_TYPE_LIST_TAG(), VTKM_DEFAULT_STORAGE_LIST_TAG()); + dataset, name, assoc, VTKM_DEFAULT_TYPE_LIST_TAG()); } //----------------------------------------------------------------------------- @@ -44,7 +44,7 @@ vtkm::cont::ArrayHandle FieldRangeCompute(const vtkm::cont::MultiBl vtkm::cont::Field::Association assoc) { return vtkm::cont::detail::FieldRangeComputeImpl( - multiblock, name, assoc, VTKM_DEFAULT_TYPE_LIST_TAG(), VTKM_DEFAULT_STORAGE_LIST_TAG()); + multiblock, name, assoc, VTKM_DEFAULT_TYPE_LIST_TAG()); } } } // namespace vtkm::cont diff --git a/vtkm/cont/FieldRangeCompute.h b/vtkm/cont/FieldRangeCompute.h index 233d543c0..2a971483c 100644 --- a/vtkm/cont/FieldRangeCompute.h +++ b/vtkm/cont/FieldRangeCompute.h @@ -47,20 +47,6 @@ vtkm::cont::ArrayHandle FieldRangeCompute( const std::string& name, vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::ANY); -template -VTKM_CONT vtkm::cont::ArrayHandle FieldRangeCompute( - const vtkm::cont::DataSet& dataset, - const std::string& name, - vtkm::cont::Field::Association assoc, - TypeList, - StorageList) -{ - VTKM_IS_LIST_TAG(TypeList); - VTKM_IS_LIST_TAG(StorageList); - - return vtkm::cont::detail::FieldRangeComputeImpl(dataset, name, assoc, TypeList(), StorageList()); -} - template VTKM_CONT vtkm::cont::ArrayHandle FieldRangeCompute( const vtkm::cont::DataSet& dataset, @@ -69,9 +55,9 @@ VTKM_CONT vtkm::cont::ArrayHandle FieldRangeCompute( TypeList) { VTKM_IS_LIST_TAG(TypeList); - return vtkm::cont::detail::FieldRangeComputeImpl( - dataset, name, assoc, TypeList(), VTKM_DEFAULT_STORAGE_LIST_TAG()); + return vtkm::cont::detail::FieldRangeComputeImpl(dataset, name, assoc, TypeList()); } + //@} //{@ @@ -88,21 +74,6 @@ vtkm::cont::ArrayHandle FieldRangeCompute( const std::string& name, vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::ANY); -template -VTKM_CONT vtkm::cont::ArrayHandle FieldRangeCompute( - const vtkm::cont::MultiBlock& multiblock, - const std::string& name, - vtkm::cont::Field::Association assoc, - TypeList, - StorageList) -{ - VTKM_IS_LIST_TAG(TypeList); - VTKM_IS_LIST_TAG(StorageList); - - return vtkm::cont::detail::FieldRangeComputeImpl( - multiblock, name, assoc, TypeList(), StorageList()); -} - template VTKM_CONT vtkm::cont::ArrayHandle FieldRangeCompute( const vtkm::cont::MultiBlock& multiblock, @@ -111,9 +82,9 @@ VTKM_CONT vtkm::cont::ArrayHandle FieldRangeCompute( TypeList) { VTKM_IS_LIST_TAG(TypeList); - return vtkm::cont::detail::FieldRangeComputeImpl( - multiblock, name, assoc, TypeList(), VTKM_DEFAULT_STORAGE_LIST_TAG()); + return vtkm::cont::detail::FieldRangeComputeImpl(multiblock, name, assoc, TypeList()); } + //@} } } // namespace vtkm::cont diff --git a/vtkm/cont/FieldRangeCompute.hxx b/vtkm/cont/FieldRangeCompute.hxx index 954d0f9ba..aef17a839 100644 --- a/vtkm/cont/FieldRangeCompute.hxx +++ b/vtkm/cont/FieldRangeCompute.hxx @@ -29,13 +29,12 @@ namespace cont namespace detail { -template +template VTKM_CONT vtkm::cont::ArrayHandle FieldRangeComputeImpl( const vtkm::cont::DataSet& dataset, const std::string& name, vtkm::cont::Field::Association assoc, - TypeList, - StorageList) + TypeList) { vtkm::cont::Field field; try @@ -48,16 +47,15 @@ VTKM_CONT vtkm::cont::ArrayHandle FieldRangeComputeImpl( return vtkm::cont::ArrayHandle(); } - return field.GetRange(TypeList(), StorageList()); + return field.GetRange(TypeList()); } -template +template VTKM_CONT vtkm::cont::ArrayHandle FieldRangeComputeImpl( const vtkm::cont::MultiBlock& multiblock, const std::string& name, vtkm::cont::Field::Association assoc, - TypeList, - StorageList) + TypeList) { std::vector result_vector = std::accumulate( multiblock.begin(), @@ -65,7 +63,7 @@ VTKM_CONT vtkm::cont::ArrayHandle FieldRangeComputeImpl( std::vector(), [&](const std::vector& accumulated_value, const vtkm::cont::DataSet& dataset) { vtkm::cont::ArrayHandle block_range = - vtkm::cont::detail::FieldRangeComputeImpl(dataset, name, assoc, TypeList(), StorageList()); + vtkm::cont::detail::FieldRangeComputeImpl(dataset, name, assoc, TypeList()); std::vector result = accumulated_value; diff --git a/vtkm/cont/FieldRangeGlobalCompute.cxx b/vtkm/cont/FieldRangeGlobalCompute.cxx index 368d83659..b39e23d02 100644 --- a/vtkm/cont/FieldRangeGlobalCompute.cxx +++ b/vtkm/cont/FieldRangeGlobalCompute.cxx @@ -45,8 +45,7 @@ vtkm::cont::ArrayHandle FieldRangeGlobalCompute(const vtkm::cont::D const std::string& name, vtkm::cont::Field::Association assoc) { - return detail::FieldRangeGlobalComputeImpl( - dataset, name, assoc, VTKM_DEFAULT_TYPE_LIST_TAG(), VTKM_DEFAULT_STORAGE_LIST_TAG()); + return detail::FieldRangeGlobalComputeImpl(dataset, name, assoc, VTKM_DEFAULT_TYPE_LIST_TAG()); } //----------------------------------------------------------------------------- @@ -56,8 +55,7 @@ vtkm::cont::ArrayHandle FieldRangeGlobalCompute( const std::string& name, vtkm::cont::Field::Association assoc) { - return detail::FieldRangeGlobalComputeImpl( - multiblock, name, assoc, VTKM_DEFAULT_TYPE_LIST_TAG(), VTKM_DEFAULT_STORAGE_LIST_TAG()); + return detail::FieldRangeGlobalComputeImpl(multiblock, name, assoc, VTKM_DEFAULT_TYPE_LIST_TAG()); } //----------------------------------------------------------------------------- diff --git a/vtkm/cont/FieldRangeGlobalCompute.h b/vtkm/cont/FieldRangeGlobalCompute.h index b7861436a..9c15b7248 100644 --- a/vtkm/cont/FieldRangeGlobalCompute.h +++ b/vtkm/cont/FieldRangeGlobalCompute.h @@ -45,20 +45,6 @@ vtkm::cont::ArrayHandle FieldRangeGlobalCompute( const std::string& name, vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::ANY); -template -VTKM_CONT vtkm::cont::ArrayHandle FieldRangeGlobalCompute( - const vtkm::cont::DataSet& dataset, - const std::string& name, - vtkm::cont::Field::Association assoc, - TypeList, - StorageList) -{ - VTKM_IS_LIST_TAG(TypeList); - VTKM_IS_LIST_TAG(StorageList); - - return detail::FieldRangeGlobalComputeImpl(dataset, name, assoc, TypeList(), StorageList()); -} - template VTKM_CONT vtkm::cont::ArrayHandle FieldRangeGlobalCompute( const vtkm::cont::DataSet& dataset, @@ -67,9 +53,9 @@ VTKM_CONT vtkm::cont::ArrayHandle FieldRangeGlobalCompute( TypeList) { VTKM_IS_LIST_TAG(TypeList); - return detail::FieldRangeGlobalComputeImpl( - dataset, name, assoc, TypeList(), VTKM_DEFAULT_STORAGE_LIST_TAG()); + return detail::FieldRangeGlobalComputeImpl(dataset, name, assoc, TypeList()); } + //@} //{@ @@ -86,20 +72,6 @@ vtkm::cont::ArrayHandle FieldRangeGlobalCompute( const std::string& name, vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::ANY); -template -VTKM_CONT vtkm::cont::ArrayHandle FieldRangeGlobalCompute( - const vtkm::cont::MultiBlock& multiblock, - const std::string& name, - vtkm::cont::Field::Association assoc, - TypeList, - StorageList) -{ - VTKM_IS_LIST_TAG(TypeList); - VTKM_IS_LIST_TAG(StorageList); - - return detail::FieldRangeGlobalComputeImpl(multiblock, name, assoc, TypeList(), StorageList()); -} - template VTKM_CONT vtkm::cont::ArrayHandle FieldRangeGlobalCompute( const vtkm::cont::MultiBlock& multiblock, @@ -108,8 +80,7 @@ VTKM_CONT vtkm::cont::ArrayHandle FieldRangeGlobalCompute( TypeList) { VTKM_IS_LIST_TAG(TypeList); - return detail::FieldRangeGlobalComputeImpl( - multiblock, name, assoc, TypeList(), VTKM_DEFAULT_STORAGE_LIST_TAG()); + return detail::FieldRangeGlobalComputeImpl(multiblock, name, assoc, TypeList()); } //@} } diff --git a/vtkm/cont/FieldRangeGlobalCompute.hxx b/vtkm/cont/FieldRangeGlobalCompute.hxx index d3f7b3671..be4dc554d 100644 --- a/vtkm/cont/FieldRangeGlobalCompute.hxx +++ b/vtkm/cont/FieldRangeGlobalCompute.hxx @@ -32,27 +32,25 @@ VTKM_CONT vtkm::cont::ArrayHandle MergeRangesGlobal( const vtkm::cont::ArrayHandle& range); -template +template VTKM_CONT vtkm::cont::ArrayHandle FieldRangeGlobalComputeImpl( const vtkm::cont::DataSet& dataset, const std::string& name, vtkm::cont::Field::Association assoc, - TypeList, - StorageList) + TypeList) { - auto lrange = vtkm::cont::FieldRangeCompute(dataset, name, assoc, TypeList(), StorageList()); + auto lrange = vtkm::cont::FieldRangeCompute(dataset, name, assoc, TypeList()); return vtkm::cont::detail::MergeRangesGlobal(lrange); } -template +template VTKM_CONT vtkm::cont::ArrayHandle FieldRangeGlobalComputeImpl( const vtkm::cont::MultiBlock& multiblock, const std::string& name, vtkm::cont::Field::Association assoc, - TypeList, - StorageList) + TypeList) { - auto lrange = vtkm::cont::FieldRangeCompute(multiblock, name, assoc, TypeList(), StorageList()); + auto lrange = vtkm::cont::FieldRangeCompute(multiblock, name, assoc, TypeList()); return vtkm::cont::detail::MergeRangesGlobal(lrange); } } diff --git a/vtkm/cont/MultiBlock.cxx b/vtkm/cont/MultiBlock.cxx index 2ce2a1c9f..11a914073 100644 --- a/vtkm/cont/MultiBlock.cxx +++ b/vtkm/cont/MultiBlock.cxx @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/vtkm/cont/MultiBlock.h b/vtkm/cont/MultiBlock.h index f6775fc20..279399bb0 100644 --- a/vtkm/cont/MultiBlock.h +++ b/vtkm/cont/MultiBlock.h @@ -25,7 +25,6 @@ #include #include #include -#include #include namespace vtkm diff --git a/vtkm/cont/testing/UnitTestMoveConstructors.cxx b/vtkm/cont/testing/UnitTestMoveConstructors.cxx index eec7c4319..de8c872ac 100644 --- a/vtkm/cont/testing/UnitTestMoveConstructors.cxx +++ b/vtkm/cont/testing/UnitTestMoveConstructors.cxx @@ -18,6 +18,7 @@ // this software. //============================================================================ #include +#include #include #include @@ -77,10 +78,32 @@ struct IsNoExceptHandle template void operator()(T) const { - is_noexcept_movable< vtkm::cont::ArrayHandle >(); + using HandleType = vtkm::cont::ArrayHandle; + using AnyType = vtkm::cont::ArrayHandleAny; + using VirtualType = vtkm::cont::ArrayHandleVirtual; + + //verify the handle type + is_noexcept_movable< HandleType >(); + is_noexcept_movable(); + is_noexcept_movable(); + + //verify the input portals of the handle + is_noexcept_movable().PrepareForInput(vtkm::cont::DeviceAdapterTagSerial{}))>(); + is_noexcept_movable().PrepareForInput(vtkm::cont::DeviceAdapterTagSerial{}))>(); + is_noexcept_movable().PrepareForInput(vtkm::cont::DeviceAdapterTagSerial{}))>(); + + //verify the output portals of the handle + is_noexcept_movable().PrepareForOutput(2, vtkm::cont::DeviceAdapterTagSerial{}))>(); + is_noexcept_movable().PrepareForOutput(2, vtkm::cont::DeviceAdapterTagSerial{}))>(); + is_noexcept_movable().PrepareForOutput(2, vtkm::cont::DeviceAdapterTagSerial{}))>(); } }; - } //----------------------------------------------------------------------------- @@ -91,23 +114,22 @@ void TestContDataTypesHaveMoveSemantics() is_triv_noexcept_movable,3>>(); - //verify that ArrayHandles are noexcept movable + //verify that ArrayHandles and related portals are noexcept movable //allowing for efficient storage in containers such as std::vector vtkm::testing::Testing::TryTypes( IsNoExceptHandle{}, vtkm::TypeListTagAll{} ); - //verify the DataSet, Field, and CoordinateSystem, + //verify the DataSet, Field, CoordinateSystem, and ArrayHandleVirtualCoordinates //all have efficient storage in containers such as std::vector is_noexcept_movable(); is_noexcept_movable(); is_noexcept_movable(); - + is_noexcept_movable(); //verify the CellSetStructured, and CellSetExplicit //have efficient storage in containers such as std::vector is_noexcept_movable>(); is_noexcept_movable>(); is_noexcept_movable>(); - }