Skip to content
Merged
Show file tree
Hide file tree
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
14 changes: 7 additions & 7 deletions libcudacxx/include/cuda/__container/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,7 @@ _CCCL_BEGIN_NAMESPACE_ARCH_DEPENDENT
//! @brief Copy-constructs elements in the range `[__first, __first + __count)`.
//! @param __first Pointer to the first element to be initialized.
//! @param __count The number of elements to be initialized.
template <typename _Tp, mr::__memory_accessability _Accessability>
template <typename _Tp, mr::__memory_accessibility _Accessability>
_CCCL_HOST_API void __fill_n(cuda::stream_ref __stream, _Tp* __first, ::cuda::std::size_t __count, const _Tp& __value)
{
if (__count == 0)
Expand All @@ -665,7 +665,7 @@ _CCCL_HOST_API void __fill_n(cuda::stream_ref __stream, _Tp* __first, ::cuda::st

// We don't know what to do with both device and host accessible buffers, so
// we need to check the attributes
if constexpr (_Accessability == mr::__memory_accessability::__host_device)
if constexpr (_Accessability == mr::__memory_accessibility ::__host_device)
{
__driver::__pointer_attribute_value_type_t<CU_POINTER_ATTRIBUTE_MEMORY_TYPE> __type;
bool __is_managed{};
Expand All @@ -678,14 +678,14 @@ _CCCL_HOST_API void __fill_n(cuda::stream_ref __stream, _Tp* __first, ::cuda::st
}
if (__type == ::CU_MEMORYTYPE_HOST && !__is_managed)
{
__fill_n<_Tp, mr::__memory_accessability::__host>(__stream, __first, __count, __value);
__fill_n<_Tp, mr::__memory_accessibility ::__host>(__stream, __first, __count, __value);
}
else
{
__fill_n<_Tp, mr::__memory_accessability::__device>(__stream, __first, __count, __value);
__fill_n<_Tp, mr::__memory_accessibility ::__device>(__stream, __first, __count, __value);
}
}
else if constexpr (_Accessability == mr::__memory_accessability::__host)
else if constexpr (_Accessability == mr::__memory_accessibility ::__host)
{
::cuda::host_launch(
__stream, ::cuda::std::uninitialized_fill_n<_Tp*, ::cuda::std::size_t, _Tp>, __first, __count, __value);
Expand Down Expand Up @@ -780,7 +780,7 @@ buffer<_Tp, _FirstProperty, _RestProperties...> make_buffer(
{
auto __res =
buffer<_Tp, _FirstProperty, _RestProperties...>{__stream, ::cuda::std::forward<_Resource>(__mr), __size, no_init};
__fill_n<_Tp, mr::__memory_accessability_from_properties<_FirstProperty, _RestProperties...>::value>(
__fill_n<_Tp, mr::__memory_accessibility_from_properties<_FirstProperty, _RestProperties...>::value>(
__stream, __res.__unwrapped_begin(), __size, __value);
return __res;
}
Expand All @@ -794,7 +794,7 @@ auto make_buffer(
using __default_queries = typename ::cuda::std::decay_t<_Resource>::default_queries;
using __buffer_type = __buffer_type_for_props<_Tp, __default_queries>;
auto __res = __buffer_type{__stream, ::cuda::std::forward<_Resource>(__mr), __size, no_init};
__fill_n<_Tp, __default_queries::template rebind<mr::__memory_accessability_from_properties>::value>(
__fill_n<_Tp, __default_queries::template rebind<mr::__memory_accessibility_from_properties>::value>(
__stream, __res.__unwrapped_begin(), __size, __value);
return __res;
}
Expand Down
12 changes: 6 additions & 6 deletions libcudacxx/include/cuda/__container/heterogeneous_iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ template <class _CvTp, class... _Properties>
class heterogeneous_iterator;

// We restrict all accessors of the iterator based on the execution space
template <class _Tp, __is_heterogeneous_const_iter _IsConst, ::cuda::mr::__memory_accessability _Space>
template <class _Tp, __is_heterogeneous_const_iter _IsConst, ::cuda::mr::__memory_accessibility _Space>
class __heterogeneous_iterator_access;

template <class _Tp, __is_heterogeneous_const_iter _IsConst>
class __heterogeneous_iterator_access<_Tp, _IsConst, ::cuda::mr::__memory_accessability::__host>
class __heterogeneous_iterator_access<_Tp, _IsConst, ::cuda::mr::__memory_accessibility ::__host>
{
public:
using iterator_concept = ::cuda::std::contiguous_iterator_tag;
Expand Down Expand Up @@ -111,7 +111,7 @@ class __heterogeneous_iterator_access<_Tp, _IsConst, ::cuda::mr::__memory_access
};

template <class _Tp, __is_heterogeneous_const_iter _IsConst>
class __heterogeneous_iterator_access<_Tp, _IsConst, ::cuda::mr::__memory_accessability::__device>
class __heterogeneous_iterator_access<_Tp, _IsConst, ::cuda::mr::__memory_accessibility ::__device>
{
public:
using iterator_concept = ::cuda::std::contiguous_iterator_tag;
Expand Down Expand Up @@ -157,7 +157,7 @@ class __heterogeneous_iterator_access<_Tp, _IsConst, ::cuda::mr::__memory_access
};

template <class _Tp, __is_heterogeneous_const_iter _IsConst>
class __heterogeneous_iterator_access<_Tp, _IsConst, ::cuda::mr::__memory_accessability::__host_device>
class __heterogeneous_iterator_access<_Tp, _IsConst, ::cuda::mr::__memory_accessibility ::__host_device>
{
public:
using iterator_concept = ::cuda::std::contiguous_iterator_tag;
Expand Down Expand Up @@ -207,12 +207,12 @@ class heterogeneous_iterator
: public __heterogeneous_iterator_access<
::cuda::std::remove_const_t<_CvTp>,
::cuda::std::is_const_v<_CvTp> ? __is_heterogeneous_const_iter::__yes : __is_heterogeneous_const_iter::__no,
::cuda::mr::__memory_accessability_from_properties<_Properties...>::value>
::cuda::mr::__memory_accessibility_from_properties<_Properties...>::value>
{
using __base = __heterogeneous_iterator_access<
::cuda::std::remove_const_t<_CvTp>,
::cuda::std::is_const_v<_CvTp> ? __is_heterogeneous_const_iter::__yes : __is_heterogeneous_const_iter::__no,
::cuda::mr::__memory_accessability_from_properties<_Properties...>::value>;
::cuda::mr::__memory_accessibility_from_properties<_Properties...>::value>;

public:
using iterator_concept = ::cuda::std::contiguous_iterator_tag;
Expand Down
12 changes: 11 additions & 1 deletion libcudacxx/include/cuda/__memory_resource/any_resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ template <class _Property>
using __iproperty = typename __with_property<_Property>::template __iproperty<>;

template <class... _Properties>
using __iproperty_set = ::cuda::__iset<__iproperty<_Properties>...>;
using __iproperty_set =
::cuda::__iset<__iproperty<_Properties>..., __iproperty<::cuda::mr::dynamic_accessibility_property>>;

// Wrap the calls of the allocate and deallocate member functions
// because of NVBUG#4967486
Expand Down Expand Up @@ -359,6 +360,15 @@ struct _CCCL_DECLSPEC_EMPTY_BASES resource_ref
}
};

template <class... _Properties>
inline constexpr bool __disable_default_dynamic_accessibility_property<any_resource<_Properties...>> = true;
template <class... _Properties>
inline constexpr bool __disable_default_dynamic_accessibility_property<resource_ref<_Properties...>> = true;
template <class... _Properties>
inline constexpr bool __disable_default_dynamic_accessibility_property<any_synchronous_resource<_Properties...>> = true;
template <class... _Properties>
inline constexpr bool __disable_default_dynamic_accessibility_property<synchronous_resource_ref<_Properties...>> = true;

_CCCL_TEMPLATE(class... _Properties, class _Resource)
_CCCL_REQUIRES(mr::synchronous_resource_with<_Resource, _Properties...>)
synchronous_resource_ref<_Properties...> __as_resource_ref(_Resource& __mr) noexcept
Expand Down
75 changes: 58 additions & 17 deletions libcudacxx/include/cuda/__memory_resource/get_property.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#if _CCCL_HAS_CTK()

# include <cuda/__memory_resource/properties.h>
# include <cuda/std/__concepts/same_as.h>
# include <cuda/std/__type_traits/remove_const_ref.h>
# include <cuda/std/__type_traits/void_t.h>
Expand Down Expand Up @@ -93,23 +94,21 @@ _CCCL_CONCEPT property_with_value = _CCCL_REQUIRES_EXPR((_Property))(typename(__
//! @endrst
# ifndef _CCCL_DOXYGEN_INVOKED // Doxygen chokes here
template <class _Resource, class _Property, class _Return>
_CCCL_CONCEPT_FRAGMENT(__has_property_with_,
requires(const _Resource& __res)(
requires(property_with_value<_Property>),
requires(::cuda::std::same_as<_Return, decltype(get_property(__res, _Property{}))>)));
# endif // ^^^ _CCCL_DOXYGEN_INVOKED ^^^
template <class _Resource, class _Property, class _Return>
_CCCL_CONCEPT has_property_with = _CCCL_FRAGMENT(__has_property_with_, _Resource, _Property, _Return);
_CCCL_CONCEPT has_property_with = _CCCL_REQUIRES_EXPR((_Resource, _Property, _Return), const _Resource& __res)(
requires(property_with_value<_Property>), _Same_as(_Return) get_property(__res, _Property{}));

# ifndef _CCCL_DOXYGEN_INVOKED // Doxygen chokes here
template <class _Resource, class _Upstream>
_CCCL_CONCEPT_FRAGMENT(
__has_upstream_resource_,
requires(const _Resource& __res)(
requires(::cuda::std::same_as<::cuda::std::__remove_const_ref_t<decltype(__res.upstream_resource())>, _Upstream>)));
_CCCL_CONCEPT __has_upstream_resource = _CCCL_REQUIRES_EXPR((_Resource, _Upstream), const _Resource& __res)(
requires(::cuda::std::same_as<::cuda::std::__remove_const_ref_t<decltype(__res.upstream_resource())>, _Upstream>));

template <class _Resource, class _Upstream>
_CCCL_CONCEPT __has_get_resource = _CCCL_REQUIRES_EXPR((_Resource, _Upstream), const _Resource& __res)(
requires(::cuda::std::same_as<::cuda::std::__remove_const_ref_t<decltype(__res.get())>, _Upstream>));
# endif // ^^^ _CCCL_DOXYGEN_INVOKED ^^^

template <class _Resource, class _Upstream>
_CCCL_CONCEPT __has_upstream_resource = _CCCL_FRAGMENT(__has_upstream_resource_, _Resource, _Upstream);
_CCCL_CONCEPT __has_forwarded_resource =
__has_upstream_resource<_Resource, _Upstream> || __has_get_resource<_Resource, _Upstream>;

_CCCL_BEGIN_NAMESPACE_CPO(__forward_property)
template <class _Derived, class _Upstream>
Expand All @@ -120,14 +119,35 @@ struct __fn
_CCCL_REQUIRES((!property_with_value<_Property>) _CCCL_AND has_property<_Upstream, _Property>)
_CCCL_API friend constexpr void get_property(const _Derived&, _Property) noexcept {}

_CCCL_EXEC_CHECK_DISABLE
_CCCL_API friend constexpr auto
get_property(const _Derived& __res, ::cuda::mr::dynamic_accessibility_property __prop) noexcept
{
if constexpr (__has_upstream_resource<_Derived, _Upstream>)
{
return get_property(__res.upstream_resource(), __prop);
}
else
{
return get_property(__res.get(), __prop);
}
}

// The indirection is needed, otherwise the compiler might believe that _Derived is an incomplete type
_CCCL_EXEC_CHECK_DISABLE
_CCCL_TEMPLATE(class _Property, class _Derived2 = _Derived)
_CCCL_REQUIRES(property_with_value<_Property> _CCCL_AND has_property<_Upstream, _Property> _CCCL_AND
__has_upstream_resource<_Derived2, _Upstream>)
__has_forwarded_resource<_Derived2, _Upstream>)
_CCCL_API friend constexpr __property_value_t<_Property> get_property(const _Derived& __res, _Property __prop)
{
return get_property(__res.upstream_resource(), __prop);
if constexpr (__has_upstream_resource<_Derived, _Upstream>)
{
return get_property(__res.upstream_resource(), __prop);
}
else
{
return get_property(__res.get(), __prop);
}
}
};
_CCCL_END_NAMESPACE_CPO
Expand All @@ -145,15 +165,36 @@ _CCCL_END_NAMESPACE_CPO
//!
//! .. note::
//!
//! In order to forward stateful properties, a type needs do implement an `upstream_resource()` method that returns
//! an instance of the upstream.
//! In order to forward stateful properties, a type needs to implement either:
//! - an `upstream_resource()` method returning the upstream resource, or
//! - a `get()` method returning the upstream resource.
//!
//! @endrst
template <class _Derived, class _Upstream>
using forward_property = __forward_property::__fn<_Derived, _Upstream>;

_CCCL_END_NAMESPACE_CUDA

_CCCL_BEGIN_NAMESPACE_CUDA_MR

template <class _Tp>
inline constexpr bool __disable_default_dynamic_accessibility_property = false;

//! Default implementation: infer from has_property<Resource, host_accessible> and
//! has_property<Resource, device_accessible>. Resources can override by providing
//! their own get_property(..., dynamic_accessibility_property).
//! Excluded for type-erased wrappers (any_resource, resource_ref, etc.) so that
//! get_property dispatches via their interface to the stored concrete resource.
_CCCL_TEMPLATE(class _Resource)
_CCCL_REQUIRES((!__disable_default_dynamic_accessibility_property<_Resource>) )
_CCCL_API constexpr __memory_accessibility
get_property([[maybe_unused]] const _Resource& __res, dynamic_accessibility_property) noexcept
{
return __memory_accessibility_from_static_properties<::cuda::has_property<_Resource, host_accessible>,
::cuda::has_property<_Resource, device_accessible>>();
}
_CCCL_END_NAMESPACE_CUDA_MR

# include <cuda/std/__cccl/epilogue.h>

#endif // _CCCL_HAS_CTK()
Expand Down
30 changes: 23 additions & 7 deletions libcudacxx/include/cuda/__memory_resource/properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,21 +108,37 @@ template <typename _Resource>
struct __copy_default_queries<_Resource, false>
{};

enum class __memory_accessability
enum class __memory_accessibility
{
__unknown,
__host,
__device,
__host_device,
};

//! @brief The dynamic_accessibility_property reports the resource's memory accessibility at runtime.
//! Compared to the static properties, it can be used to query the memory accessibility of a resource that is not known
//! at compile time.
struct dynamic_accessibility_property
{
using value_type = __memory_accessibility;
};

template <bool _HostAccessible, bool _DeviceAccessible>
_CCCL_API constexpr __memory_accessibility __memory_accessibility_from_static_properties() noexcept
{
return _HostAccessible && _DeviceAccessible ? __memory_accessibility ::__host_device
: _DeviceAccessible ? __memory_accessibility ::__device
: _HostAccessible ? __memory_accessibility ::__host
: __memory_accessibility ::__unknown;
}

template <class... _Properties>
struct __memory_accessability_from_properties
struct __memory_accessibility_from_properties
{
static constexpr __memory_accessability value =
::cuda::mr::__is_host_device_accessible<_Properties...> ? __memory_accessability::__host_device
: ::cuda::mr::__is_device_accessible<_Properties...>
? __memory_accessability::__device
: __memory_accessability::__host;
static constexpr __memory_accessibility value =
__memory_accessibility_from_static_properties<::cuda::mr::__is_host_accessible<_Properties...>,
::cuda::mr::__is_device_accessible<_Properties...>>();
};

_CCCL_END_NAMESPACE_CUDA_MR
Expand Down
17 changes: 3 additions & 14 deletions libcudacxx/include/cuda/__memory_resource/shared_resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ _CCCL_BEGIN_NAMESPACE_CUDA_MR
//! @tparam _Resource The resource type to hold.
//! @endrst
template <class _Resource>
struct shared_resource : ::cuda::mr::__copy_default_queries<_Resource>
struct shared_resource
: ::cuda::mr::__copy_default_queries<_Resource>
, ::cuda::forward_property<shared_resource<_Resource>, _Resource>
{
static_assert(::cuda::mr::synchronous_resource<_Resource>, "");

Expand Down Expand Up @@ -255,19 +257,6 @@ struct shared_resource : ::cuda::mr::__copy_default_queries<_Resource>
return !(__lhs == __rhs);
}

//! @brief Forwards the stateless properties
_CCCL_TEMPLATE(class _Property)
_CCCL_REQUIRES((!property_with_value<_Property>) _CCCL_AND(has_property<_Resource, _Property>))
friend void get_property(const shared_resource&, _Property) noexcept {}

//! @brief Forwards the stateful properties
_CCCL_TEMPLATE(class _Property)
_CCCL_REQUIRES(property_with_value<_Property> _CCCL_AND(has_property<_Resource, _Property>))
[[nodiscard]] friend __property_value_t<_Property> get_property(const shared_resource& __self, _Property) noexcept
{
return get_property(__self.__control_block->__resource, _Property{});
}

private:
// Use a custom shared_ptr implementation because (a) we don't need to support weak_ptr so we only
// need one pointer, not two, and (b) this implementation can work on device also.
Expand Down
39 changes: 39 additions & 0 deletions libcudacxx/include/cuda/__utility/__basic_any/iset.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,49 @@ using __iset_flatten _CCCL_NODEBUG_ALIAS = ::cuda::std::__as_type_list<
// using __iset _CCCL_NODEBUG_ALIAS = ::cuda::std::__type_call<
// ::cuda::std::__type_unique<::cuda::std::__type_sort<::cuda::std::__type_concat<__iset_flatten<_Interfaces>...>>>,
// ::cuda::std::__type_quote<__iset_>>;
// GCC 7 had a problem with the original implementation, so we use a workaround.
#if _CCCL_COMPILER(GCC, <, 8)
template <class _Lhs, class _Rhs>
struct __iset_cat;

template <class... _Lhs, class... _Rhs>
struct __iset_cat<::cuda::std::__type_list<_Lhs...>, ::cuda::std::__type_list<_Rhs...>>
{
using type = ::cuda::std::__type_list<_Lhs..., _Rhs...>;
};

template <class... _Interfaces>
struct __iset_flatten_all;

template <>
struct __iset_flatten_all<>
{
using type = ::cuda::std::__type_list<>;
};

template <class... _Nested, class... _Rest>
struct __iset_flatten_all<__iset_<_Nested...>, _Rest...>
{
using type = typename __iset_cat<typename __iset_flatten_all<_Nested...>::type,
typename __iset_flatten_all<_Rest...>::type>::type;
};

template <class _Interface, class... _Rest>
struct __iset_flatten_all<_Interface, _Rest...>
{
using type =
typename __iset_cat<::cuda::std::__type_list<_Interface>, typename __iset_flatten_all<_Rest...>::type>::type;
};

template <class... _Interfaces>
using __iset = ::cuda::std::__type_call<::cuda::std::__type_unique<typename __iset_flatten_all<_Interfaces...>::type>,
::cuda::std::__type_quote<__iset_>>;
#else // ^^^ _CCCL_COMPILER(GCC, <, 8) ^^^ / vvv _CCCL_COMPILER(GCC, >=, 8) vvv
template <class... _Interfaces>
using __iset =
::cuda::std::__type_call<::cuda::std::__type_unique<::cuda::std::__type_concat<__iset_flatten<_Interfaces>...>>,
::cuda::std::__type_quote<__iset_>>;
#endif // _CCCL_COMPILER(GCC, >=, 8)

//!
//! Virtual table pointers
Expand Down
Loading
Loading