網頁

2019年3月3日 星期日

Array Handle

//! Specifies where to acquire the data
struct access_location
    {
    //! The enum
    enum Enum
        {
        host,   //!< Ask to acquire the data on the host
#ifdef ENABLE_CUDA
        device  //!< Ask to acquire the data on the device
#endif
        };
    };

//! Defines where the data is currently stored
struct data_location
    {
    //! The enum
    enum Enum
        {
        host,       //!< Data was last updated on the host
#ifdef ENABLE_CUDA
        device,     //!< Data was last updated on the device
        hostdevice  //!< Data is up to date on both the host and device
#endif
        };
    };

//! Specify how the data is to be accessed
struct access_mode
    {
    //! The enum
    enum Enum
        {
        read,       //!< Data will be accessed read only
        readwrite,  //!< Data will be accessed for read and write
        overwrite   //!< The data is to be completely overwritten during this acquire
        };
    };

//! CRTP (Curiously recurring template pattern) interface for GPUArray/GlobalArray
template<class T, class Derived>
class GPUArrayBase
    {

    .....

    protected:
        //! Acquires the data pointer for use
        inline ArrayHandleDispatch<T> acquire(const access_location::Enum location, const access_mode::Enum mode
        #ifdef ENABLE_CUDA
                         , bool async = false
        #endif
                        ) const
            {
            return static_cast<Derived const&>(*this).acquire(location, mode
            #ifdef ENABLE_CUDA
                , async
            #endif
                );
            }

        //! Release the data pointer
        inline void release() const
            {
            return static_cast<Derived const&>(*this).release();
            }

        //! Returns the acquire state
        inline bool isAcquired() const
            {
            return static_cast<Derived const&>(*this).isAcquired();
            }

        // need to be friend of the ArrayHandle class
        friend class ArrayHandle<T>;
        friend class ArrayHandleAsync<T>;

    private:
        // Make constructor private to prevent mistakes
        GPUArrayBase() {};
        friend Derived;
    };

//! This base class is the glue between the ArrayHandle and a generic GPUArrayBase<Derived>
template<class T>
class ArrayHandleDispatch
    {
    public:
        //! Constructor
        ArrayHandleDispatch(T* const _data)
            : data(_data) {}

        //! Get the data pointer
        T * const get() const
            {
            return data;
            }

        //! Destructor
        virtual ~ArrayHandleDispatch() = default;

    private:
        //! The data pointer
        T* const data;
    };

//! Handle to access the data pointer handled by GPUArray
/*! The data in GPUArray is only accessible via ArrayHandle. The pointer is accessible for the lifetime of the
    ArrayHandle. When the ArrayHandle is destroyed, the GPUArray is notified that the data has been released. This
    tracking mechanism provides for error checking that will cause code assertions to fail if the data is acquired
    more than once.
    ArrayHandle is intended to be used within a scope limiting its use. For example:
    \code
GPUArray<int> gpu_array(100);
    {
    ArrayHandle<int> h_handle(gpu_array, access_location::host, access_mode::readwrite);
    ... use h_handle.data ...
    }
    \endcode
    The actual raw pointer \a data should \b NOT be assumed to be the same after the handle is released.
    The pointer may in fact be re-allocated somewhere else after the handle is released and before the next handle
    is acquired.
    \ingroup data_structs
*/
template<class T>
class ArrayHandle
    {
    public:
        //! Aquires the data and sets \a data
        /*! \tparam Derived the type of GPUArray implementation
         */
        template<class Derived>
        inline ArrayHandle(const GPUArrayBase<T, Derived>& gpu_array, const access_location::Enum location = access_location::host,
                           const access_mode::Enum mode = access_mode::readwrite);
        //! Notifies the containing GPUArray that the handle has been released
        virtual inline ~ArrayHandle() = default;

    private:
        ArrayHandleDispatch<T> dispatch; //!< Reference to the dispatch object that manages the acquire/release

    public:
        T* const data;          //!< Pointer to data
    };




沒有留言:

張貼留言