From 7d4be266f36988abe0de944db74d655dd24c8b4d Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Wed, 28 Aug 2024 17:59:28 +0200 Subject: [PATCH] Add documentation for `any_resource` (#2309) * Add documentation for `any_resource` * Apply suggestions from code review Co-authored-by: Bernhard Manfred Gruber --------- Co-authored-by: Bernhard Manfred Gruber --- .../__memory_resource/any_resource.h | 79 ++++++++++++++----- docs/cudax/index.rst | 2 + docs/cudax/memory_resource.rst | 16 ++++ docs/repo.toml | 10 +-- 4 files changed, 80 insertions(+), 27 deletions(-) create mode 100644 docs/cudax/memory_resource.rst diff --git a/cudax/include/cuda/experimental/__memory_resource/any_resource.h b/cudax/include/cuda/experimental/__memory_resource/any_resource.h index 1ddbfa0d96..eafd626739 100644 --- a/cudax/include/cuda/experimental/__memory_resource/any_resource.h +++ b/cudax/include/cuda/experimental/__memory_resource/any_resource.h @@ -53,6 +53,16 @@ namespace cuda::experimental::mr template > _LIBCUDACXX_INLINE_VAR constexpr bool __is_basic_any_resource = false; +//! @rst +//! .. _cudax-memory-resource-basic-any-resource: +//! +//! Base class for a type erased owning wrapper around a memory resource +//! --------------------------------------------------------------------- +//! +//! ``basic_any_resource`` abstracts the differences between a resource and an async resource away, allowing efficient +//! interoperability between the two. +//! +//! @endrst template <_CUDA_VMR::_AllocType _Alloc_type, class... _Properties> class basic_any_resource : public _CUDA_VMR::_Resource_base<_Alloc_type, _CUDA_VMR::_WrapperType::_Owning> @@ -73,13 +83,13 @@ class basic_any_resource public: //! @brief Constructs a \c basic_any_resource from a type that satisfies the \c resource or \c async_resource - //! concept as well as all properties - //! @param __res The resource to be wrapped within the \c basic_any_resource + //! concept as well as all properties. + //! @param __res The resource to be wrapped within the \c basic_any_resource. _LIBCUDACXX_TEMPLATE(class _Resource, class __resource_t = _CUDA_VSTD::remove_cvref_t<_Resource>) _LIBCUDACXX_REQUIRES( - (!__is_basic_any_resource<_Resource>) - _LIBCUDACXX_AND _CUDA_VMR::resource_with<__resource_t, _Properties...> _LIBCUDACXX_AND( - _Alloc_type != _CUDA_VMR::_AllocType::_Async || _CUDA_VMR::async_resource_with<__resource_t, _Properties...>)) + (!__is_basic_any_resource<_Resource>) _LIBCUDACXX_AND(_CUDA_VMR::resource_with<__resource_t, _Properties...>) + _LIBCUDACXX_AND(_Alloc_type != _CUDA_VMR::_AllocType::_Async + || (_CUDA_VMR::async_resource_with<__resource_t, _Properties...>) )) basic_any_resource(_Resource&& __res) noexcept : _CUDA_VMR::_Resource_base<_Alloc_type, _CUDA_VMR::_WrapperType::_Owning>( nullptr, &_CUDA_VMR::__alloc_vtable<_Alloc_type, _CUDA_VMR::_WrapperType::_Owning, __resource_t>) @@ -95,10 +105,12 @@ class basic_any_resource } } -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Doxygen misparses the below constructor, so dumb it down for it. + //! @brief Conversion from a \c basic_any_resource with the same set of properties but in a different order. + //! This constructor also handles conversion from \c async_any_resource to \c any_resource + //! @param __other The other \c basic_any_resource. _LIBCUDACXX_TEMPLATE(_CUDA_VMR::_AllocType _OtherAllocType, class... _OtherProperties) _LIBCUDACXX_REQUIRES( - _CUDA_VSTD::_IsNotSame>::value + (_CUDA_VSTD::_IsNotSame>::value) _LIBCUDACXX_AND(_OtherAllocType == _Alloc_type || _OtherAllocType == _CUDA_VMR::_AllocType::_Async) _LIBCUDACXX_AND __properties_match<_OtherProperties...>) basic_any_resource(basic_any_resource<_OtherAllocType, _OtherProperties...> __other) noexcept @@ -109,14 +121,9 @@ class basic_any_resource _LIBCUDACXX_ASSERT(this->__static_vtable != nullptr, "copying from a moved-from object"); this->__static_vtable->__move_fn(&this->__object, &__other.__object); } -#else - //! @brief Conversion from a \c basic_any_resource with the same set of properties but in a different order. - //! This constructor also handles conversion from \c async_any_resource to \c any_resource - //! @param __ref The other \c basic_any_resource - template <_CUDA_VMR::_AllocType _OtherAllocType, class... _OtherProperties> - basic_any_resource(basic_any_resource<_OtherAllocType, _OtherProperties...> __other) noexcept; -#endif + //! @brief Move-constructs a \c basic_any_resource from another one, taking ownership of the stored resource. + //! @param __other The other \c basic_any_resource. basic_any_resource(basic_any_resource&& __other) noexcept : _CUDA_VMR::_Resource_base<_Alloc_type, _CUDA_VMR::_WrapperType::_Owning>( nullptr, _CUDA_VSTD::exchange(__other.__static_vtable, nullptr)) @@ -126,6 +133,8 @@ class basic_any_resource this->__static_vtable->__move_fn(&this->__object, &__other.__object); } + //! @brief Move-assigns another \c basic_any_resource, taking ownership of the stored resource. + //! @param __other The other \c basic_any_resource. basic_any_resource& operator=(basic_any_resource&& __other) noexcept { if (this->__static_vtable != nullptr) @@ -143,6 +152,8 @@ class basic_any_resource return *this; } + //! @brief Copy-constructs a \c basic_any_resource from another one. + //! @param __other The other \c basic_any_resource. basic_any_resource(const basic_any_resource& __other) : _CUDA_VMR::_Resource_base<_Alloc_type, _CUDA_VMR::_WrapperType::_Owning>(nullptr, __other.__static_vtable) , __vtable(__other) @@ -151,6 +162,8 @@ class basic_any_resource this->__static_vtable->__copy_fn(&this->__object, &__other.__object); } + //! @brief Copy-assigns another \c basic_any_resource. + //! @param __other The other \c basic_any_resource. basic_any_resource& operator=(const basic_any_resource& __other) { return this == &__other ? *this : operator=(basic_any_resource(__other)); @@ -165,16 +178,20 @@ class basic_any_resource } } + //! @brief Converts a \c basic_any_resource to a \c resource_ref with a potential subset of properties. + //! @return The \c resource_ref to this resource. _LIBCUDACXX_TEMPLATE(_CUDA_VMR::_AllocType _OtherAllocType, class... _OtherProperties) _LIBCUDACXX_REQUIRES( (_OtherAllocType == _CUDA_VMR::_AllocType::_Default || _OtherAllocType == _Alloc_type) - _LIBCUDACXX_AND _CUDA_VSTD::__type_set_contains<_CUDA_VSTD::__make_type_set<_Properties...>, _OtherProperties...>) + _LIBCUDACXX_AND(_CUDA_VSTD::__type_set_contains<_CUDA_VSTD::__make_type_set<_Properties...>, _OtherProperties...>)) operator _CUDA_VMR::basic_resource_ref<_OtherAllocType, _OtherProperties...>() noexcept { return _CUDA_VMR::_Resource_ref_helper::_Construct<_Alloc_type, _OtherProperties...>( this->_Get_object(), this->__static_vtable, static_cast(*this)); } + //! @brief Swaps a \c basic_any_resource with another one. + //! @param __other The other \c basic_any_resource. void swap(basic_any_resource& __other) noexcept { auto __tmp = _CUDA_VSTD::move(__other); @@ -209,12 +226,12 @@ class basic_any_resource //! @brief Forwards the stateless properties _LIBCUDACXX_TEMPLATE(class _Property) - _LIBCUDACXX_REQUIRES((!property_with_value<_Property>) _LIBCUDACXX_AND _CUDA_VSTD::_One_of<_Property, _Properties...>) + _LIBCUDACXX_REQUIRES((!property_with_value<_Property>) _LIBCUDACXX_AND(_CUDA_VSTD::_One_of<_Property, _Properties...>)) friend void get_property(const basic_any_resource&, _Property) noexcept {} //! @brief Forwards the stateful properties _LIBCUDACXX_TEMPLATE(class _Property) - _LIBCUDACXX_REQUIRES(property_with_value<_Property> _LIBCUDACXX_AND _CUDA_VSTD::_One_of<_Property, _Properties...>) + _LIBCUDACXX_REQUIRES(property_with_value<_Property> _LIBCUDACXX_AND(_CUDA_VSTD::_One_of<_Property, _Properties...>)) _CCCL_NODISCARD_FRIEND __property_value_t<_Property> get_property(const basic_any_resource& __res, _Property) noexcept { _CUDA_VMR::_Property_vtable<_Property> const& __prop = __res; @@ -227,13 +244,33 @@ template _LIBCUDACXX_INLINE_VAR constexpr bool __is_basic_any_resource<_Ty, basic_any_resource<_Alloc_type, _Properties...>> = true; -//! @brief Type erased wrapper around a `resource` that satisfies \tparam _Properties -//! @tparam _Properties The properties that any resource wrapped within the `any_resource` needs to satisfy +//! @rst +//! .. _cudax-memory-resource-any-resource: +//! +//! Type erased wrapper around a `resource` +//! ---------------------------------------- +//! +//! ``any_resource`` wraps any given :ref:`resource ` that +//! satisfies the required properties. It owns the contained resource, taking care of construction / destruction. +//! This makes it especially suited for use in e.g. container types that need to ensure that the lifetime of the +//! container exceeds the lifetime of the memory resource used to allocate the storage +//! +//! @endrst template using any_resource = basic_any_resource<_CUDA_VMR::_AllocType::_Default, _Properties...>; -//! @brief Type erased wrapper around a `async_resource` that satisfies \tparam _Properties -//! @tparam _Properties The properties that any async resource wrapped within the `async_any_resource` needs to satisfy +//! @rst +//! .. _cudax-memory-resource-async-any-resource: +//! +//! Type erased wrapper around an `async_resource` +//! ----------------------------------------------- +//! +//! ``async_any_resource`` wraps any given :ref:`async resource ` +//! that satisfies the required properties. It owns the contained resource, taking care of construction / destruction. +//! This makes it especially suited for use in e.g. container types that need to ensure that the lifetime of the +//! container exceeds the lifetime of the memory resource used to allocate the storage +//! +//! @endrst template using async_any_resource = basic_any_resource<_CUDA_VMR::_AllocType::_Async, _Properties...>; diff --git a/docs/cudax/index.rst b/docs/cudax/index.rst index 9b066b61c0..21d13c8f5b 100644 --- a/docs/cudax/index.rst +++ b/docs/cudax/index.rst @@ -8,6 +8,7 @@ CUDA Experimental :maxdepth: 3 container + memory_resource ${repo_docs_api_path}/cudax_api ``CUDA Experimental`` (``cudax``) provides experimental new features that are still in development and subject to change. @@ -15,6 +16,7 @@ However, any feature within this library has important use cases and we encourag Specifically, ``cudax`` provides: - :ref:`uninitialized storage ` + - :ref:`an ownning type erased memory resource ` - dimensions description functionality Stability Guarantees diff --git a/docs/cudax/memory_resource.rst b/docs/cudax/memory_resource.rst new file mode 100644 index 0000000000..06a1dfcf14 --- /dev/null +++ b/docs/cudax/memory_resource.rst @@ -0,0 +1,16 @@ +.. _cudax-memory-resource: + +Memory Resources +================= + +.. toctree:: + :glob: + :maxdepth: 3 + + ${repo_docs_api_path}/*any__resource* + +The ```` header provides: + - :ref:`any_resource ` and + :ref:`async_any_resource ` type erased memory resources similar to + ``std::any``. In contrast to :ref:`resource_ref ` they + own the contained resource. diff --git a/docs/repo.toml b/docs/repo.toml index fa27eebc70..159645c8c5 100644 --- a/docs/repo.toml +++ b/docs/repo.toml @@ -371,21 +371,19 @@ doxygen_predefined = [ "_CCCL_GLOBAL_CONSTANT=constexpr", "_CCCL_HOST=", "_CCCL_HOST_DEVICE=", + "_CCCL_IF_CONSTEXPR=if constexpr", "_CCCL_NODISCARD=[[nodiscard]]", "_CCCL_NODISCARD_FRIEND=", "_CCCL_STD_VER=2020", + "_CCCL_TRAIT(x, y)=x::value", "_CUDA_VMR=cuda::mr", "_CUDA_VSTD=cuda::std", "_LIBCUDACXX_AND=&&", "_LIBCUDACXX_EAT_REST(x)=", "_LIBCUDACXX_GLOBAL_CONSTANT=inline", "_LIBCUDACXX_INLINE_VAR=inline", - "_LIBCUDACXX_REQUIRES(...)=", - "_LIBCUDACXX_TEMPLATE(A)=template", - "_LIBCUDACXX_TEMPLATE(A, B)=template", - "_LIBCUDACXX_TEMPLATE(A, B, C)=template", - "_LIBCUDACXX_TEMPLATE(A, B, C, D)=template", - "_LIBCUDACXX_TEMPLATE(A, B, C, D, E)=template", + "_LIBCUDACXX_REQUIRES(x)= ::cuda::std::__enable_if_t = 0>", + "_LIBCUDACXX_TEMPLATE(x)=template x _LIBCUDACXX_EAT_REST", "LIBCUDACXX_ENABLE_EXPERIMENTAL_MEMORY_RESOURCE=", ]