/* * Copyright 2008-2012 NVIDIA Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in ccudaliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*! \file thrust/system/cuda/memory.h * \brief Managing memory associated with Thrust's CUDA system. */ #pragma once #include #include #include #include #include #include namespace thrust { namespace system { namespace cuda { template class pointer; } // end cuda } // end system } // end thrust /*! \cond */ // specialize std::iterator_traits to avoid problems with the name of // pointer's constructor shadowing its nested pointer type // do this before pointer is defined so the specialization is correctly // used inside the definition namespace std { template struct iterator_traits > { private: typedef thrust::system::cuda::pointer ptr; public: typedef typename ptr::iterator_category iterator_category; typedef typename ptr::value_type value_type; typedef typename ptr::difference_type difference_type; typedef ptr pointer; typedef typename ptr::reference reference; }; // end iterator_traits } // end std /*! \endcond */ namespace thrust { namespace system { /*! \addtogroup system_backends Systems * \ingroup system * \{ */ /*! \namespace thrust::system::cuda * \brief \p thrust::system::cuda is the namespace containing functionality for allocating, manipulating, * and deallocating memory available to Thrust's CUDA backend system. * The identifiers are provided in a separate namespace underneath thrust::system * for import convenience but are also aliased in the top-level thrust::tbb * namespace for easy access. * */ namespace cuda { // forward declaration of reference for pointer template class reference; /*! \cond */ // XXX nvcc + msvc have trouble instantiating reference below // this is a workaround namespace detail { template struct reference_msvc_workaround { typedef thrust::system::cuda::reference type; }; // end reference_msvc_workaround } // end detail /*! \endcond */ #if 0 /*! \p cuda::tag is type representing Thrust's CUDA backend system in C++'s type system. * Iterators "tagged" with a type which is convertible to \p cuda::tag assert that they may be * "dispatched" to algorithm implementations in the \p cuda system. */ struct tag { unspecified }; #endif /*! \p pointer stores a pointer to an object allocated in memory available to the cuda system. * This type provides type safety when dispatching standard algorithms on ranges resident * in cuda memory. * * \p pointer has pointer semantics: it may be dereferenced and manipulated with pointer arithmetic. * * \p pointer can be created with the function \p cuda::malloc, or by explicitly calling its constructor * with a raw pointer. * * The raw pointer encapsulated by a \p pointer may be obtained by eiter its get member function * or the \p raw_pointer_cast function. * * \note \p pointer is not a "smart" pointer; it is the programmer's responsibility to deallocate memory * pointed to by \p pointer. * * \tparam T specifies the type of the pointee. * * \see cuda::malloc * \see cuda::free * \see raw_pointer_cast */ template class pointer : public thrust::pointer< T, thrust::system::cuda::tag, thrust::system::cuda::reference, thrust::system::cuda::pointer > { /*! \cond */ private: typedef thrust::pointer< T, thrust::system::cuda::tag, //thrust::system::cuda::reference, typename detail::reference_msvc_workaround::type, thrust::system::cuda::pointer > super_t; /*! \endcond */ public: /*! \p pointer's no-argument constructor initializes its encapsulated pointer to \c 0. */ __host__ __device__ pointer() : super_t() {} /*! This constructor allows construction of a pointer from a T*. * * \param ptr A raw pointer to copy from, presumed to point to a location in memory * accessible by the \p tbb system. * \tparam OtherT \p OtherT shall be convertible to \p T. */ template __host__ __device__ explicit pointer(OtherT *ptr) : super_t(ptr) {} /*! This constructor allows construction from another pointer-like object with related type. * * \param other The \p OtherPointer to copy. * \tparam OtherPointer The system tag associated with \p OtherPointer shall be convertible * to \p thrust::system::cuda::tag and its element type shall be convertible to \p T. */ template __host__ __device__ pointer(const OtherPointer &other, typename thrust::detail::enable_if_pointer_is_convertible< OtherPointer, pointer >::type * = 0) : super_t(other) {} /*! Assignment operator allows assigning from another pointer-like object with related type. * * \param other The other pointer-like object to assign from. * \tparam OtherPointer The system tag associated with \p OtherPointer shall be convertible * to \p thrust::system::cuda::tag and its element type shall be convertible to \p T. */ template __host__ __device__ typename thrust::detail::enable_if_pointer_is_convertible< OtherPointer, pointer, pointer & >::type operator=(const OtherPointer &other) { return super_t::operator=(other); } }; // end pointer /*! \p reference is a wrapped reference to an object stored in memory available to the \p cuda system. * \p reference is the type of the result of dereferencing a \p cuda::pointer. * * \tparam T Specifies the type of the referenced object. */ template class reference : public thrust::reference< T, thrust::system::cuda::pointer, thrust::system::cuda::reference > { /*! \cond */ private: typedef thrust::reference< T, thrust::system::cuda::pointer, thrust::system::cuda::reference > super_t; /*! \endcond */ public: /*! \cond */ typedef typename super_t::value_type value_type; typedef typename super_t::pointer pointer; /*! \endcond */ /*! This constructor initializes this \p reference to refer to an object * pointed to by the given \p pointer. After this \p reference is constructed, * it shall refer to the object pointed to by \p ptr. * * \param ptr A \p pointer to copy from. */ __host__ __device__ explicit reference(const pointer &ptr) : super_t(ptr) {} /*! This constructor accepts a const reference to another \p reference of related type. * After this \p reference is constructed, it shall refer to the same object as \p other. * * \param other A \p reference to copy from. * \tparam OtherT The element type of the other \p reference. * * \note This constructor is templated primarily to allow initialization of reference * from reference. */ template __host__ __device__ reference(const reference &other, typename thrust::detail::enable_if_convertible< typename reference::pointer, pointer >::type * = 0) : super_t(other) {} /*! Copy assignment operator copy assigns from another \p reference of related type. * * \param other The other \p reference to assign from. * \return *this * \tparam OtherT The element type of the other \p reference. */ template __host__ __device__ reference &operator=(const reference &other); /*! Assignment operator assigns from a \p value_type. * * \param x The \p value_type to assign from. * \return *this */ __host__ __device__ reference &operator=(const value_type &x); }; // end reference /*! Exchanges the values of two objects referred to by \p reference. * \p x The first \p reference of interest. * \p y The second \p reference ot interest. */ template __host__ __device__ void swap(reference x, reference y); /*! Allocates an area of memory available to Thrust's cuda system. * \param n Number of bytes to allocate. * \return A cuda::pointer pointing to the beginning of the newly * allocated memory. A null cuda::pointer is returned if * an error occurs. * \note The cuda::pointer returned by this function must be * deallocated with \p cuda::free. * \see cuda::free * \see std::malloc */ inline pointer malloc(std::size_t n); /*! Allocates a typed area of memory available to Thrust's cuda system. * \param n Number of elements to allocate. * \return A cuda::pointer pointing to the beginning of the newly * allocated memory. A null cuda::pointer is returned if * an error occurs. * \note The cuda::pointer returned by this function must be * deallocated with \p cuda::free. * \see cuda::free * \see std::malloc */ template inline pointer malloc(std::size_t n); /*! Deallocates an area of memory previously allocated by cuda::malloc. * \param ptr A cuda::pointer pointing to the beginning of an area * of memory previously allocated with cuda::malloc. * \see cuda::malloc * \see std::free */ inline void free(pointer ptr); // XXX upon c++11 // template using allocator = thrust::detail::malloc_allocator >; /*! \p cuda::allocator is the default allocator used by the \p cuda system's containers such as * cuda::vector if no user-specified allocator is provided. \p cuda::allocator allocates * (deallocates) storage with \p cuda::malloc (\p cuda::free). */ template struct allocator : thrust::detail::malloc_allocator< T, tag, pointer > { /*! The \p rebind metafunction provides the type of an \p allocator * instantiated with another type. * * \tparam U The other type to use for instantiation. */ template struct rebind { /*! The typedef \p other gives the type of the rebound \p allocator. */ typedef allocator other; }; /*! No-argument constructor has no effect. */ __host__ __device__ inline allocator() {} /*! Copy constructor has no effect. */ __host__ __device__ inline allocator(const allocator &) {} /*! Constructor from other \p allocator has no effect. */ template __host__ __device__ inline allocator(const allocator &) {} /*! Destructor has no effect. */ __host__ __device__ inline ~allocator() {} }; // end allocator } // end cuda /*! \} */ } // end system /*! \namespace thrust::cuda * \brief \p thrust::cuda is a top-level alias for thrust::system::cuda. */ namespace cuda { using thrust::system::cuda::pointer; using thrust::system::cuda::reference; using thrust::system::cuda::malloc; using thrust::system::cuda::free; using thrust::system::cuda::allocator; } // end cuda } // end thrust #include