1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632
|
//===----------------------------------------------------------------------===//
//
// Part of the CUDA Toolkit, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//
#ifndef _CUDA_MEMORY_RESOURCE
#define _CUDA_MEMORY_RESOURCE
// clang-format off
/*
memory_resource synopsis
namespace cuda {
namespace mr {
template <class Resource>
concept resource = equality_comparable<Resource>
&& requires(Resource& res, void* ptr, size_t size, size_t alignment) {
{ res.allocate(size, alignment) } -> same_as<void*>;
{ res.deallocate(ptr, size, alignment) } -> same_as<void>;
};
template <class Resource>
concept async_resource = resource<Resource>
&& requires(Resource& res, void* ptr, size_t size, size_t alignment, cuda_stream_ref stream) {
{ res.allocate_async(size, alignment, stream) } -> same_as<void*>;
{ res.deallocate_async(ptr, size, alignment, stream) } -> same_as<void>;
};
template <class Resource, class Property>
concept has_property = resource<Resource> && requires(const Resource& res, Property prop) {
get_property(res, prop);
};
template <class Property>
concept property_with_value = requires {
typename Property::value_type;
};
template <class Resource, class Property, class Return>
concept has_property_with = resource<Resource>
&& property_with_value<Property>
&& same_as<Return, typename Property::value_type>
&& requires(const Resource& res, Property prop) {
get_property(res, prop) -> Return;
};
template <class Resource, class... Properties>
concept resource_with = resource<Resource> && (has_property<Resource, Properties> && ...);
template <class Resource, class... Properties>
concept async_resource_with = async_resource<Resource> && (has_property<Resource, Properties> && ...);
template <class... Properties>
class resource_ref {
template <resource_with<Properties...> Resource>
resource_ref(Resource&) noexcept;
void* allocate(size_t size, size_t alignment);
void deallocate(void* ptr, size_t size, size_t alignment);
template <class... OtherProperties>
requires resource_with<resource_ref, OtherProperties...>
&& resource_with<resource_ref<OtherProperties...>, Properties...>
friend bool operator==(const resource_ref& left, const resource_ref<OtherProperties...>& right);
template <property_with_value Property>
requires has_property<resource_ref, Property>
friend typename Property::value_type get_property(const resource_ref& ref, Property) noexcept;
template <class Property>
requires (has_property<resource_ref, Property> && !property_with_value<Property>)
friend void get_property(const resource_ref& ref, Property) noexcept;
};
} // mr
} // cuda
*/
// clang-format on
#ifdef LIBCUDACXX_ENABLE_EXPERIMENTAL_MEMORY_RESOURCE
#include <cuda/stream_ref>
#include <cuda/std/concepts>
#include <cuda/std/type_traits>
#include <cuda/std/detail/__config>
#include <cuda/std/detail/__pragma_push>
#if _LIBCUDACXX_STD_VER > 11
_LIBCUDACXX_BEGIN_NAMESPACE_CUDA
///////////////////////////////////////////////////////////////////////////////
// properties
/// \concept has_property
/// \brief The \c has_property concept
template <class _Resource, class _Property>
_LIBCUDACXX_CONCEPT_FRAGMENT(
__has_property_,
requires(const _Resource& __res)(
get_property(__res, _Property{})
));
template <class _Resource, class _Property>
_LIBCUDACXX_CONCEPT has_property = _LIBCUDACXX_FRAGMENT(__has_property_, _Resource, _Property);
/// \concept property_with_value
/// \brief The \c property_with_value concept
template <class _Property>
using __property_value_t = typename _Property::value_type;
template <class _Property>
_LIBCUDACXX_CONCEPT_FRAGMENT(
__property_with_value_,
requires()(
typename(__property_value_t<_Property>)
));
template <class _Property>
_LIBCUDACXX_CONCEPT property_with_value = _LIBCUDACXX_FRAGMENT(__property_with_value_, _Property);
/// \concept has_property_with
/// \brief The \c has_property_with concept
template <class _Resource, class _Property, class _Return>
_LIBCUDACXX_CONCEPT_FRAGMENT(
__has_property_with_,
requires(const _Resource& __res)(
requires(property_with_value<_Property>),
requires(_CUDA_VSTD::same_as<_Return, decltype(get_property(__res, _Property{}))>)
));
template <class _Resource, class _Property, class _Return>
_LIBCUDACXX_CONCEPT has_property_with = _LIBCUDACXX_FRAGMENT(__has_property_with_, _Resource, _Property, _Return);
/// \concept __has_upstream_resource
/// \brief The \c __has_upstream_resource concept
template <class _Resource, class _Upstream>
_LIBCUDACXX_CONCEPT_FRAGMENT(
__has_upstream_resource_,
requires(const _Resource& __res)(
requires(_CUDA_VSTD::same_as<_CUDA_VSTD::__remove_const_ref_t<decltype(__res.upstream_resource())>, _Upstream>)
));
template <class _Resource, class _Upstream>
_LIBCUDACXX_CONCEPT __has_upstream_resource = _LIBCUDACXX_FRAGMENT(__has_upstream_resource_, _Resource, _Upstream);
/// class forward_property
/// \brief The \c forward_property crtp template simplifies the user facing side of forwarding properties
/// We can just derive from it to properly forward all properties
_LIBCUDACXX_BEGIN_NAMESPACE_CPO(__forward_property)
template <class _Derived, class _Upstream>
struct __fn {
_LIBCUDACXX_DISABLE_EXEC_CHECK
_LIBCUDACXX_TEMPLATE(class _Property)
_LIBCUDACXX_REQUIRES( (!property_with_value<_Property>) _LIBCUDACXX_AND has_property<_Upstream, _Property>)
_LIBCUDACXX_INLINE_VISIBILITY friend constexpr void get_property(const _Derived&, _Property) noexcept {}
// The indirection is needed, otherwise the compiler might believe that _Derived is an incomplete type
_LIBCUDACXX_DISABLE_EXEC_CHECK
_LIBCUDACXX_TEMPLATE(class _Property, class _Derived2 = _Derived)
_LIBCUDACXX_REQUIRES( property_with_value<_Property> _LIBCUDACXX_AND has_property<_Upstream, _Property> _LIBCUDACXX_AND
__has_upstream_resource<_Derived2, _Upstream>)
_LIBCUDACXX_INLINE_VISIBILITY friend constexpr __property_value_t<_Property> get_property(
const _Derived& __res, _Property __prop) {
return get_property(__res.upstream_resource(), __prop);
}
};
_LIBCUDACXX_END_NAMESPACE_CPO
template <class _Derived, class _Upstream>
using forward_property = __forward_property::__fn<_Derived, _Upstream>;
/// class get_property
/// \brief The \c get_property crtp temaplate simplifies the user facing side of forwarding properties
/// We can always tell people to just derive from it to properly forward all properties
_LIBCUDACXX_BEGIN_NAMESPACE_CPO(__get_property)
struct __fn {
_LIBCUDACXX_DISABLE_EXEC_CHECK
_LIBCUDACXX_TEMPLATE(class _Upstream, class _Property)
_LIBCUDACXX_REQUIRES( (!property_with_value<_Property>) _LIBCUDACXX_AND has_property<_Upstream, _Property>)
_LIBCUDACXX_INLINE_VISIBILITY constexpr void operator()(const _Upstream&, _Property) const noexcept {}
_LIBCUDACXX_DISABLE_EXEC_CHECK
_LIBCUDACXX_TEMPLATE(class _Upstream, class _Property)
_LIBCUDACXX_REQUIRES( (property_with_value<_Property>) _LIBCUDACXX_AND has_property<_Upstream, _Property>)
_LIBCUDACXX_INLINE_VISIBILITY constexpr __property_value_t<_Property> operator()(
const _Upstream& __res, _Property __prop) const {
return get_property(__res, __prop);
}
};
_LIBCUDACXX_END_NAMESPACE_CPO
inline namespace __cpo {
_LIBCUDACXX_CPO_ACCESSIBILITY auto get_property = __get_property::__fn{};
} // namespace __cpo
namespace mr
{
///////////////////////////////////////////////////////////////////////////////
// memory_resource
/// \concept resource
/// \brief The \c resource concept
template <class _Resource>
_LIBCUDACXX_CONCEPT_FRAGMENT(
__resource_,
requires(_Resource& __res, void* __ptr, size_t __bytes, size_t __alignment) (
requires(_CUDA_VSTD::same_as<void*, decltype(__res.allocate(__bytes, __alignment))>),
requires(_CUDA_VSTD::same_as<void, decltype(__res.deallocate(__ptr, __bytes, __alignment))>),
requires(_CUDA_VSTD::equality_comparable<_Resource>)
));
template <class _Resource>
_LIBCUDACXX_CONCEPT resource = _LIBCUDACXX_FRAGMENT(__resource_, _Resource);
/// \concept async_resource
/// \brief The \c async_resource concept
template <class _Resource>
_LIBCUDACXX_CONCEPT_FRAGMENT(
__async_resource_,
requires(_Resource& __res, void* __ptr, size_t __bytes, size_t __alignment, cuda::stream_ref __stream) (
requires(resource<_Resource>),
requires(_CUDA_VSTD::same_as<void*, decltype(__res.allocate_async(__bytes, __alignment, __stream))>),
requires(_CUDA_VSTD::same_as<void, decltype(__res.deallocate_async(__ptr, __bytes, __alignment, __stream))>),
requires(_CUDA_VSTD::equality_comparable<_Resource>)
));
template <class _Resource>
_LIBCUDACXX_CONCEPT async_resource = _LIBCUDACXX_FRAGMENT(__async_resource_, _Resource);
/// \concept resource_with
/// \brief The \c resource_with concept
template <class _Resource, class... _Properties>
#if _LIBCUDACXX_STD_VER < 17
_LIBCUDACXX_CONCEPT resource_with =
resource<_Resource>&& _CUDA_VSTD::conjunction_v<_CUDA_VSTD::bool_constant<has_property<_Resource, _Properties>>...>;
#else
_LIBCUDACXX_CONCEPT resource_with = resource<_Resource> && (has_property<_Resource, _Properties> && ...);
#endif
/// \concept async_resource_with
/// \brief The \c async_resource_with concept
template <class _Resource, class... _Properties>
#if _LIBCUDACXX_STD_VER < 17
_LIBCUDACXX_CONCEPT async_resource_with = async_resource<_Resource> &&
_CUDA_VSTD::conjunction_v<_CUDA_VSTD::bool_constant<has_property<_Resource, _Properties>>...>;
#else
_LIBCUDACXX_CONCEPT async_resource_with = async_resource<_Resource> &&
(has_property<_Resource, _Properties> && ...);
#endif
///////////////////////////////////////////////////////////////////////////////
/// class resource_ref
/// class async_resource_ref
enum class _AllocType
{
_Default,
_Async,
};
struct _Alloc_vtable
{
using _AllocFn = void* (*)(void*, size_t, size_t);
using _DeallocFn = void (*)(void*, void*, size_t, size_t);
using _EqualFn = bool (*)(void*, void*);
_AllocFn __alloc_fn;
_DeallocFn __dealloc_fn;
_EqualFn __equal_fn;
constexpr _Alloc_vtable(_AllocFn __alloc_fn_, _DeallocFn __dealloc_fn_, _EqualFn __equal_fn_) noexcept
: __alloc_fn(__alloc_fn_)
, __dealloc_fn(__dealloc_fn_)
, __equal_fn(__equal_fn_)
{}
};
struct _Async_alloc_vtable : public _Alloc_vtable
{
using _AsyncAllocFn = void* (*)(void*, size_t, size_t, cuda::stream_ref);
using _AsyncDeallocFn = void (*)(void*, void*, size_t, size_t, cuda::stream_ref);
_AsyncAllocFn __async_alloc_fn;
_AsyncDeallocFn __async_dealloc_fn;
constexpr _Async_alloc_vtable(_Alloc_vtable::_AllocFn __alloc_fn_,
_Alloc_vtable::_DeallocFn __dealloc_fn_,
_Alloc_vtable::_EqualFn __equal_fn_,
_AsyncAllocFn __async_alloc_fn_,
_AsyncDeallocFn __async_dealloc_fn_) noexcept
: _Alloc_vtable(__alloc_fn_, __dealloc_fn_, __equal_fn_)
, __async_alloc_fn(__async_alloc_fn_)
, __async_dealloc_fn(__async_dealloc_fn_)
{}
};
// clang-format off
struct _Resource_vtable_builder
{
template <class _Resource, class _Property>
static __property_value_t<_Property> _Get_property(void* __res) noexcept {
return get_property(*static_cast<const _Resource *>(__res), _Property{});
}
template <class _Resource>
static void* _Alloc(void* __object, size_t __bytes, size_t __alignment) {
return static_cast<_Resource *>(__object)->allocate(__bytes, __alignment);
}
template <class _Resource>
static void _Dealloc(void* __object, void* __ptr, size_t __bytes, size_t __alignment) {
return static_cast<_Resource *>(__object)->deallocate(__ptr, __bytes, __alignment);
}
template <class _Resource>
static void* _Alloc_async(void* __object, size_t __bytes, size_t __alignment, cuda::stream_ref __stream) {
return static_cast<_Resource *>(__object)->allocate_async(__bytes, __alignment, __stream);
}
template <class _Resource>
static void _Dealloc_async(void* __object, void* __ptr, size_t __bytes, size_t __alignment, cuda::stream_ref __stream) {
return static_cast<_Resource *>(__object)->deallocate_async(__ptr, __bytes, __alignment, __stream);
}
template <class _Resource>
static bool _Equal(void* __left, void* __right) {
return *static_cast<_Resource *>(__left) == *static_cast<_Resource *>(__right);
}
_LIBCUDACXX_TEMPLATE(class _Resource, _AllocType _Alloc_type)
_LIBCUDACXX_REQUIRES((_Alloc_type == _AllocType::_Default)) //
static constexpr _Alloc_vtable _Create() noexcept
{
return {&_Resource_vtable_builder::_Alloc<_Resource>,
&_Resource_vtable_builder::_Dealloc<_Resource>,
&_Resource_vtable_builder::_Equal<_Resource>};
}
_LIBCUDACXX_TEMPLATE(class _Resource, _AllocType _Alloc_type)
_LIBCUDACXX_REQUIRES((_Alloc_type == _AllocType::_Async)) //
static constexpr _Async_alloc_vtable _Create() noexcept
{
return {&_Resource_vtable_builder::_Alloc<_Resource>,
&_Resource_vtable_builder::_Dealloc<_Resource>,
&_Resource_vtable_builder::_Equal<_Resource>,
&_Resource_vtable_builder::_Alloc_async<_Resource>,
&_Resource_vtable_builder::_Dealloc_async<_Resource>};
}
};
// clang-format on
template <class _Property>
struct _Property_vtable
{
using _PropertyFn = __property_value_t<_Property> (*)(void*);
_PropertyFn __property_fn = nullptr;
constexpr _Property_vtable(_PropertyFn __property_fn_) noexcept
: __property_fn(__property_fn_)
{}
};
template <_AllocType _Alloc_type, class... _Properties> //
class basic_resource_ref;
template <class... _Properties>
struct _Resource_vtable : public _Property_vtable<_Properties>...
{
template <class... _PropertyFns>
constexpr _Resource_vtable(_PropertyFns... __property_fn_) noexcept
: _Property_vtable<_Properties>(__property_fn_)...
{}
template <_AllocType _Alloc_type, class... _OtherProperties>
constexpr _Resource_vtable(basic_resource_ref<_Alloc_type, _OtherProperties...>& __ref) noexcept
: _Property_vtable<_Properties>(__ref._Property_vtable<_Properties>::__property_fn)...
{}
template <class _Resource>
static constexpr _Resource_vtable _Create() noexcept
{
return {&_Resource_vtable_builder::_Get_property<_Resource, _Properties>...};
}
};
template <class... _Properties>
struct _Filtered;
template <bool _IsUniqueProperty>
struct _Property_filter
{
template <class _Property, class... _Properties>
using _Filtered_properties =
typename _Filtered<_Properties...>::_Filtered_vtable::template _Append_property<_Property>;
};
template <>
struct _Property_filter<false>
{
template <class _Property, class... _Properties>
using _Filtered_properties = typename _Filtered<_Properties...>::_Filtered_vtable;
};
template <class _Property, class... _Properties>
struct _Filtered<_Property, _Properties...>
{
using _Filtered_vtable =
typename _Property_filter<property_with_value<_Property> && !_CUDA_VSTD::_One_of<_Property, _Properties...>>::
template _Filtered_properties<_Property, _Properties...>;
template <class _OtherPropery>
using _Append_property = _Filtered<_OtherPropery, _Property, _Properties...>;
using _Vtable = _Resource_vtable<_Property, _Properties...>;
};
template <>
struct _Filtered<>
{
using _Filtered_vtable = _Filtered<>;
template <class _OtherPropery>
using _Append_property = _Filtered<_OtherPropery>;
using _Vtable = _Resource_vtable<>;
};
template <class... _Properties>
using _Filtered_vtable = typename _Filtered<_Properties...>::_Filtered_vtable::_Vtable;
template <class _Vtable>
struct _Alloc_base
{
static_assert(_CUDA_VSTD::is_base_of_v<_Alloc_vtable, _Vtable>, "");
_Alloc_base(void* __object_, const _Vtable* __static_vtabl_) noexcept
: __object(__object_)
, __static_vtable(__static_vtabl_)
{}
void* allocate(size_t __bytes, size_t __alignment = alignof(max_align_t))
{
return __static_vtable->__alloc_fn(__object, __bytes, __alignment);
}
void deallocate(void* _Ptr, size_t __bytes, size_t __alignment = alignof(max_align_t))
{
__static_vtable->__dealloc_fn(__object, _Ptr, __bytes, __alignment);
}
protected:
void* __object = nullptr;
const _Vtable* __static_vtable = nullptr;
};
template <class _Vtable>
struct _Async_alloc_base : public _Alloc_base<_Vtable>
{
static_assert(_CUDA_VSTD::is_base_of_v<_Async_alloc_vtable, _Vtable>, "");
_Async_alloc_base(void* __object_, const _Vtable* __static_vtabl_) noexcept
: _Alloc_base<_Vtable>(__object_, __static_vtabl_)
{}
void* allocate_async(size_t __bytes, size_t __alignment, cuda::stream_ref __stream)
{
return this->__static_vtable->__async_alloc_fn(this->__object, __bytes, __alignment, __stream);
}
void* allocate_async(size_t __bytes, cuda::stream_ref __stream)
{
return this->__static_vtable->__async_alloc_fn(this->__object, __bytes, alignof(max_align_t), __stream);
}
void deallocate_async(void* _Ptr, size_t __bytes, cuda::stream_ref __stream)
{
this->__static_vtable->__async_dealloc_fn(this->__object, _Ptr, __bytes, alignof(max_align_t), __stream);
}
void deallocate_async(void* _Ptr, size_t __bytes, size_t __alignment, cuda::stream_ref __stream)
{
this->__static_vtable->__async_dealloc_fn(this->__object, _Ptr, __bytes, __alignment, __stream);
}
};
template <_AllocType _Alloc_type>
using _Resource_ref_base = _CUDA_VSTD::
_If<_Alloc_type == _AllocType::_Default, _Alloc_base<_Alloc_vtable>, _Async_alloc_base<_Async_alloc_vtable>>;
template <_AllocType _Alloc_type>
using _Vtable_store = _CUDA_VSTD::_If<_Alloc_type == _AllocType::_Default, _Alloc_vtable, _Async_alloc_vtable>;
template <_AllocType _Alloc_type, class _Resource>
_LIBCUDACXX_INLINE_VAR constexpr _Vtable_store<_Alloc_type>
__alloc_vtable = _Resource_vtable_builder::template _Create<_Resource, _Alloc_type>();
template <class>
_LIBCUDACXX_INLINE_VAR constexpr bool _Is_basic_resource_ref = false;
template <_AllocType _Alloc_type, class... _Properties> //
class basic_resource_ref
: public _Resource_ref_base<_Alloc_type>
, private _Filtered_vtable<_Properties...>
{
private:
template <_AllocType, class...>
friend class basic_resource_ref;
template <class...>
friend struct _Resource_vtable;
public:
// clang-format off
_LIBCUDACXX_TEMPLATE(class _Resource)
_LIBCUDACXX_REQUIRES( (!_Is_basic_resource_ref<_Resource>
&& (((_Alloc_type == _AllocType::_Default) && resource_with<_Resource, _Properties...>) //
||((_Alloc_type == _AllocType::_Async) && async_resource_with<_Resource, _Properties...>)))) //
basic_resource_ref(_Resource& __res) noexcept
: _Resource_ref_base<_Alloc_type>(_CUDA_VSTD::addressof(__res), &__alloc_vtable<_Alloc_type, _Resource>)
, _Filtered_vtable<_Properties...>(_Filtered_vtable<_Properties...>::template _Create<_Resource>())
{}
_LIBCUDACXX_TEMPLATE(class _Resource)
_LIBCUDACXX_REQUIRES( (!_Is_basic_resource_ref<_Resource>
&& (((_Alloc_type == _AllocType::_Default) && resource_with<_Resource, _Properties...>) //
||((_Alloc_type == _AllocType::_Async) && async_resource_with<_Resource, _Properties...>)))) //
basic_resource_ref(_Resource* __res) noexcept
: _Resource_ref_base<_Alloc_type>(__res, &__alloc_vtable<_Alloc_type, _Resource>)
, _Filtered_vtable<_Properties...>(_Filtered_vtable<_Properties...>::template _Create<_Resource>())
{}
#if _LIBCUDACXX_STD_VER > 14
_LIBCUDACXX_TEMPLATE(class... _OtherProperties)
_LIBCUDACXX_REQUIRES( (_CUDA_VSTD::_One_of<_Properties, _OtherProperties...> && ...))
#else
_LIBCUDACXX_TEMPLATE(class... _OtherProperties)
_LIBCUDACXX_REQUIRES( _CUDA_VSTD::conjunction_v<_CUDA_VSTD::bool_constant<
_CUDA_VSTD::_One_of<_Properties, _OtherProperties...>>...>)
#endif
basic_resource_ref(
basic_resource_ref<_Alloc_type, _OtherProperties...> __ref) noexcept
: _Resource_ref_base<_Alloc_type>(__ref.__object, __ref.__static_vtable)
, _Filtered_vtable<_Properties...>(__ref)
{}
#if _LIBCUDACXX_STD_VER > 14
_LIBCUDACXX_TEMPLATE(class... _OtherProperties)
_LIBCUDACXX_REQUIRES( (_Alloc_type == _AllocType::_Default)
&& (_CUDA_VSTD::_One_of<_Properties, _OtherProperties...> && ...))
#else
_LIBCUDACXX_TEMPLATE(class... _OtherProperties)
_LIBCUDACXX_REQUIRES( (_Alloc_type == _AllocType::_Default)
&& _CUDA_VSTD::conjunction_v<_CUDA_VSTD::bool_constant<
_CUDA_VSTD::_One_of<_Properties, _OtherProperties...>>...>)
#endif
basic_resource_ref(
basic_resource_ref<_AllocType::_Async, _OtherProperties...> __ref) noexcept
: _Resource_ref_base<_Alloc_type>(__ref.__object, __ref.__static_vtable)
, _Filtered_vtable<_Properties...>(__ref)
{}
#if _LIBCUDACXX_STD_VER > 14
_LIBCUDACXX_TEMPLATE(class... _OtherProperties)
_LIBCUDACXX_REQUIRES((sizeof...(_Properties) == sizeof...(_OtherProperties))
&& (_CUDA_VSTD::_One_of<_Properties, _OtherProperties...> && ...))
#else
_LIBCUDACXX_TEMPLATE(class... _OtherProperties)
_LIBCUDACXX_REQUIRES( (sizeof...(_Properties) == sizeof...(_OtherProperties))
&& _CUDA_VSTD::conjunction_v<_CUDA_VSTD::bool_constant<
_CUDA_VSTD::_One_of<_Properties, _OtherProperties...>>...>)
#endif
bool operator==(
const basic_resource_ref<_Alloc_type, _OtherProperties...> &__right) const {
return (this->__static_vtable->__equal_fn == __right.__static_vtable->__equal_fn) //
&& this->__static_vtable->__equal_fn(this->__object, __right.__object);
}
#if _LIBCUDACXX_STD_VER > 14
_LIBCUDACXX_TEMPLATE(class... _OtherProperties)
_LIBCUDACXX_REQUIRES( (sizeof...(_Properties) == sizeof...(_OtherProperties))
&& (_CUDA_VSTD::_One_of<_Properties, _OtherProperties...> && ...))
#else
_LIBCUDACXX_TEMPLATE(class... _OtherProperties)
_LIBCUDACXX_REQUIRES( (sizeof...(_Properties) == sizeof...(_OtherProperties))
&& _CUDA_VSTD::conjunction_v<_CUDA_VSTD::bool_constant<
_CUDA_VSTD::_One_of<_Properties, _OtherProperties...>>...>)
#endif
bool operator!=(
const basic_resource_ref<_Alloc_type, _OtherProperties...> &__right) const {
return !(*this == __right);
}
_LIBCUDACXX_TEMPLATE(class _Property)
_LIBCUDACXX_REQUIRES( (!property_with_value<_Property>) _LIBCUDACXX_AND _CUDA_VSTD::_One_of<_Property, _Properties...>) //
friend void get_property(const basic_resource_ref &, _Property) noexcept {}
_LIBCUDACXX_TEMPLATE(class _Property)
_LIBCUDACXX_REQUIRES( property_with_value<_Property> _LIBCUDACXX_AND _CUDA_VSTD::_One_of<_Property, _Properties...>) //
friend __property_value_t<_Property> get_property(
const basic_resource_ref &__res, _Property) noexcept {
return __res._Property_vtable<_Property>::__property_fn(__res.__object);
}
// clang-format on
};
template <_AllocType _Alloc_type, class... _Properties>
_LIBCUDACXX_INLINE_VAR constexpr bool _Is_basic_resource_ref<basic_resource_ref<_Alloc_type, _Properties...>> = true;
template <class... _Properties> //
using resource_ref = basic_resource_ref<_AllocType::_Default, _Properties...>;
template <class... _Properties> //
using async_resource_ref = basic_resource_ref<_AllocType::_Async, _Properties...>;
/// \struct device_accessible
/// \brief The \c device_accessible property signals that the allocated memory is device accessible
struct device_accessible{};
/// \struct host_accessible
/// \brief The \c host_accessible property signals that the allocated memory is host accessible
struct host_accessible{};
} // namespace mr
_LIBCUDACXX_END_NAMESPACE_CUDA
#endif // _LIBCUDACXX_STD_VER > 11
#include <cuda/std/detail/__pragma_pop>
#endif // LIBCUDACXX_ENABLE_EXPERIMENTAL_MEMORY_RESOURCE
#endif //_LIBCUDACXX_BEGIN_NAMESPACE_CUDA
|