Skip to content

Commit

Permalink
Add documentation for any_resource (#2309)
Browse files Browse the repository at this point in the history
* Add documentation for `any_resource`

* Apply suggestions from code review

Co-authored-by: Bernhard Manfred Gruber <[email protected]>

---------

Co-authored-by: Bernhard Manfred Gruber <[email protected]>
  • Loading branch information
miscco and bernhardmgruber authored Aug 28, 2024
1 parent 942f59f commit 7d4be26
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 27 deletions.
79 changes: 58 additions & 21 deletions cudax/include/cuda/experimental/__memory_resource/any_resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@ namespace cuda::experimental::mr
template <class _Ty, class _Uy = _CUDA_VSTD::remove_cvref_t<_Ty>>
_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>
Expand All @@ -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>)
Expand All @@ -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<basic_any_resource, basic_any_resource<_OtherAllocType, _OtherProperties...>>::value
(_CUDA_VSTD::_IsNotSame<basic_any_resource, basic_any_resource<_OtherAllocType, _OtherProperties...>>::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
Expand All @@ -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))
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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));
Expand All @@ -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<const __vtable&>(*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);
Expand Down Expand Up @@ -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;
Expand All @@ -227,13 +244,33 @@ template <class _Ty, _CUDA_VMR::_AllocType _Alloc_type, class... _Properties>
_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 <libcudacxx-extended-api-memory-resources-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 <class... _Properties>
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 <libcudacxx-extended-api-memory-resources-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 <class... _Properties>
using async_any_resource = basic_any_resource<_CUDA_VMR::_AllocType::_Async, _Properties...>;

Expand Down
2 changes: 2 additions & 0 deletions docs/cudax/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ 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.
However, any feature within this library has important use cases and we encourage users to experiment with them.

Specifically, ``cudax`` provides:
- :ref:`uninitialized storage <cudax-containers-uninitialized-buffer>`
- :ref:`an ownning type erased memory resource <cudax-memory-resource-async-any-resource>`
- dimensions description functionality

Stability Guarantees
Expand Down
16 changes: 16 additions & 0 deletions docs/cudax/memory_resource.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.. _cudax-memory-resource:

Memory Resources
=================

.. toctree::
:glob:
:maxdepth: 3

${repo_docs_api_path}/*any__resource*

The ``<cuda/experimental/memory_resource.cuh>`` header provides:
- :ref:`any_resource <cudax-memory-resource-any-resource>` and
:ref:`async_any_resource <cudax-memory-resource-async-any-resource>` type erased memory resources similar to
``std::any``. In contrast to :ref:`resource_ref <libcudacxx-extended-api-memory-resources-resource-ref>` they
own the contained resource.
10 changes: 4 additions & 6 deletions docs/repo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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<y>::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<A>",
"_LIBCUDACXX_TEMPLATE(A, B)=template<A, B>",
"_LIBCUDACXX_TEMPLATE(A, B, C)=template<A, B, C>",
"_LIBCUDACXX_TEMPLATE(A, B, C, D)=template<A, B, C, D>",
"_LIBCUDACXX_TEMPLATE(A, B, C, D, E)=template<A, B, C, D, E>",
"_LIBCUDACXX_REQUIRES(x)= ::cuda::std::__enable_if_t<x, int> = 0>",
"_LIBCUDACXX_TEMPLATE(x)=template<x, ",
"_LIBCUDACXX_TRAILING_REQUIRES(x)=-> x _LIBCUDACXX_EAT_REST",
"LIBCUDACXX_ENABLE_EXPERIMENTAL_MEMORY_RESOURCE=",
]
Expand Down

0 comments on commit 7d4be26

Please sign in to comment.