Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add documentation for any_resource #2309

Merged
merged 2 commits into from
Aug 28, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
@@ -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.
Comment on lines +62 to +63
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm not sure what this is referring to. any_resource and any_async_resource are different types with different interfaces. the differences haven 't been abstracted away.

//!
//! @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.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think we should require properties to have a UUID. that way we can have a canonical global ordering of properties. not for this PR obviously.

//! 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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, much better. thanks.

_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<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);
@@ -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 <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...>;

2 changes: 2 additions & 0 deletions docs/cudax/index.rst
Original file line number Diff line number Diff line change
@@ -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
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
@@ -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, ",
Comment on lines +385 to +386
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really want our docs to have the enable_if gunk?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue is that doxygen does not support requires so we either have SFINAE or nothing

"_LIBCUDACXX_TRAILING_REQUIRES(x)=-> x _LIBCUDACXX_EAT_REST",
"LIBCUDACXX_ENABLE_EXPERIMENTAL_MEMORY_RESOURCE=",
]