//============================================================================ // 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. // // Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS). // Copyright 2014 UT-Battelle, LLC. // Copyright 2014 Los Alamos National Security. // // Under the terms of Contract DE-NA0003525 with NTESS, // the U.S. Government retains certain rights in this software. // // Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National // Laboratory (LANL), the U.S. Government retains certain rights in // this software. //============================================================================ #ifndef vtk_m_cont_StorageVirtual_h #define vtk_m_cont_StorageVirtual_h #include #include #include #include #include #include namespace vtkm { namespace cont { struct VTKM_ALWAYS_EXPORT StorageTagVirtual { }; namespace internal { template <> class VTKM_CONT_EXPORT Storage { public: /// \brief construct storage that VTK-m is responsible for Storage() = default; Storage(const Storage& src); Storage(Storage&& src) noexcept; Storage& operator=(const Storage& src); Storage& operator=(Storage&& src) noexcept; virtual ~Storage(); /// Releases any resources being used in the execution environment (that are /// not being shared by the control environment). /// /// Only needs to overridden by subclasses such as Zip that have member /// variables that themselves have execution memory virtual void ReleaseResourcesExecution(); /// Releases all resources in both the control and execution environments. /// /// Only needs to overridden by subclasses such as Zip that have member /// variables that themselves have execution memory virtual void ReleaseResources(); /// Returns the number of entries in the array. /// virtual vtkm::Id GetNumberOfValues() const = 0; /// \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). /// void Allocate(vtkm::Id numberOfValues) { std::cout << "StorageVirtual::Allocate(" << numberOfValues << ") Not Implemented!" << std::endl; } //return this->DoAllocate(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) { std::cout << "StorageVirtual::Shrink(" << numberOfValues << ") Not Implemented!." << std::endl; } //return this->DoShrink(numberOfValues); } /// Determines if storage types matches the type passed in. /// template bool IsType() const { //needs optimizations based on platform. !OSX can use typeid return nullptr != dynamic_cast(this); } /// \brief Create a new storage of the same type as this storage. /// /// This method creates a new storage that is the same type as this one and /// returns a unique_ptr for it. This method is convenient when /// creating output arrays that should be the same type as some input array. /// std::unique_ptr> NewInstance() const; template const DerivedStorage* Cast() const { const DerivedStorage* derived = dynamic_cast(this); if (!derived) { VTKM_LOG_CAST_FAIL(*this, DerivedStorage); throwFailedDynamicCast("StorageVirtual", vtkm::cont::TypeName()); } VTKM_LOG_CAST_SUCC(*this, derived); return derived; } const vtkm::internal::PortalVirtualBase* PrepareForInput(vtkm::cont::DeviceAdapterId devId) const; const vtkm::internal::PortalVirtualBase* PrepareForOutput(vtkm::Id numberOfValues, vtkm::cont::DeviceAdapterId devId); const vtkm::internal::PortalVirtualBase* PrepareForInPlace(vtkm::cont::DeviceAdapterId devId); //This needs to cause a host side sync! //This needs to work before we execute on a device const vtkm::internal::PortalVirtualBase* GetPortalControl(); //This needs to cause a host side sync! //This needs to work before we execute on a device const vtkm::internal::PortalVirtualBase* GetPortalConstControl() const; /// 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. DeviceAdapterId GetDeviceAdapterId() const noexcept; enum struct OutputMode { WRITE, READ_WRITE }; private: //Memory management routines // virtual void DoAllocate(vtkm::Id numberOfValues) = 0; // virtual void DoShrink(vtkm::Id numberOfValues) = 0; //RTTI routines virtual std::unique_ptr> MakeNewInstance() const = 0; //Portal routines virtual void ControlPortalForInput(vtkm::cont::internal::TransferInfoArray& payload) const = 0; virtual void ControlPortalForOutput(vtkm::cont::internal::TransferInfoArray& payload); virtual void TransferPortalForInput(vtkm::cont::internal::TransferInfoArray& payload, vtkm::cont::DeviceAdapterId devId) const = 0; virtual void TransferPortalForOutput(vtkm::cont::internal::TransferInfoArray& payload, OutputMode mode, vtkm::Id numberOfValues, vtkm::cont::DeviceAdapterId devId); //These might need to exist in TransferInfoArray mutable bool HostUpToDate = false; mutable bool DeviceUpToDate = false; std::shared_ptr DeviceTransferState = std::make_shared(); }; } // namespace internal using StorageVirtual = internal::Storage; } } // namespace vtkm::cont #endif