[INFRA] Import NVIDIA/CCCL upstream as optimization reference library
CCCL (CUDA C++ Core Libraries) provides: - CUB: device/block/warp-level GPU primitives (reduce, scan, sort, topk) - Thrust: high-level parallel algorithms (transform_reduce, sort, scan) - libcudacxx: CUDA C++ standard library (atomics, barriers, memory) - cudax: experimental features (memory resources, allocators) - Tuning policies: per-SM hardware-specific algorithm parameters Competition optimization vectors mapped to CCCL: - Output TPS (83% weight): warp_reduce, block_reduce, device_topk - Input TPS (14% weight): device_scan, block_load, prefetch - Cache TPS (3% weight): prefix caching strategy patterns - Memory (0.9 util): pooled/cached/buddy allocators Source: https://github.com/NVIDIA/cccl (shallow clone, HEAD only) License: Apache-2.0
This commit is contained in:
142
cccl_upstream/libcudacxx/include/cuda/__device/all_devices.h
Normal file
142
cccl_upstream/libcudacxx/include/cuda/__device/all_devices.h
Normal file
@@ -0,0 +1,142 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of libcu++, the C++ Standard Library for your entire system,
|
||||
// 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) 2025 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA___DEVICE_ALL_DEVICES_H
|
||||
#define _CUDA___DEVICE_ALL_DEVICES_H
|
||||
|
||||
#include <cuda/std/detail/__config>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#if _CCCL_HAS_CTK() && !_CCCL_COMPILER(NVRTC)
|
||||
|
||||
# include <cuda/__device/device_ref.h>
|
||||
# include <cuda/__device/physical_device.h>
|
||||
# include <cuda/__driver/driver_api.h>
|
||||
# include <cuda/__fwd/devices.h>
|
||||
# include <cuda/std/__cstddef/types.h>
|
||||
# include <cuda/std/__exception/exception_macros.h>
|
||||
# include <cuda/std/__host_stdlib/stdexcept>
|
||||
# include <cuda/std/span>
|
||||
|
||||
# include <vector>
|
||||
|
||||
# include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_API inline ::std::vector<device_ref> __make_devices()
|
||||
{
|
||||
::std::vector<device_ref> __ret{};
|
||||
__ret.reserve(::cuda::__physical_devices().size());
|
||||
for (::cuda::std::size_t __i = 0; __i < ::cuda::__physical_devices().size(); ++__i)
|
||||
{
|
||||
__ret.emplace_back(static_cast<int>(__i));
|
||||
}
|
||||
return __ret;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline ::cuda::std::span<const device_ref> __devices()
|
||||
{
|
||||
static const auto __devices = ::cuda::__make_devices();
|
||||
return ::cuda::std::span<const device_ref>{__devices.data(), __devices.size()};
|
||||
}
|
||||
|
||||
//! @brief A random-access range of all available CUDA devices
|
||||
class __all_devices
|
||||
{
|
||||
public:
|
||||
using value_type = ::cuda::std::span<const device_ref>::value_type;
|
||||
using size_type = ::cuda::std::span<const device_ref>::size_type;
|
||||
using iterator = ::cuda::std::span<const device_ref>::iterator;
|
||||
|
||||
_CCCL_HIDE_FROM_ABI __all_devices() = default;
|
||||
__all_devices(const __all_devices&) = delete;
|
||||
__all_devices(__all_devices&&) = delete;
|
||||
__all_devices& operator=(const __all_devices&) = delete;
|
||||
__all_devices& operator=(__all_devices&&) = delete;
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_API device_ref operator[](size_type __i) const
|
||||
{
|
||||
if (__i >= size())
|
||||
{
|
||||
_CCCL_THROW(::std::out_of_range, "device index out of range");
|
||||
}
|
||||
return ::cuda::__devices()[__i];
|
||||
}
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_API size_type size() const
|
||||
{
|
||||
return ::cuda::__devices().size();
|
||||
}
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_API iterator begin() const
|
||||
{
|
||||
return ::cuda::__devices().begin();
|
||||
}
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_API iterator end() const
|
||||
{
|
||||
return ::cuda::__devices().end();
|
||||
}
|
||||
};
|
||||
|
||||
//! @brief A range of all available CUDA devices
|
||||
//!
|
||||
//! `cuda::devices` provides a view of all available CUDA devices. It is useful for
|
||||
//! determining the number of supported devices and for iterating over all devices
|
||||
//! in a range-based for loop (e.g., to print device properties, perhaps).
|
||||
//!
|
||||
//! @par Class synopsis
|
||||
//! @code
|
||||
//! class __all_devices { // exposition only
|
||||
//! public:
|
||||
//! using size_type = ::std::size_t;
|
||||
//! struct iterator;
|
||||
//! using const_iterator = iterator;
|
||||
//!
|
||||
//! [[nodiscard]] device_ref operator[](size_type i) const noexcept;
|
||||
//!
|
||||
//! [[nodiscard]] size_type size() const;
|
||||
//!
|
||||
//! [[nodiscard]] iterator begin() const noexcept;
|
||||
//!
|
||||
//! [[nodiscard]] iterator end() const noexcept;
|
||||
//! };
|
||||
//! @endcode
|
||||
//!
|
||||
//! @par
|
||||
//! `__all_devices::iterator` is a random access iterator with a `reference`
|
||||
//! type of `const device_ref&`.
|
||||
//!
|
||||
//! @par Example
|
||||
//! @code
|
||||
//! auto& dev0 = cuda::devices[0];
|
||||
//! assert(cuda::devices.size() == cuda::std::distance(cuda::devices.begin(), cuda::devices.end()));
|
||||
//! @endcode
|
||||
//!
|
||||
//! @sa
|
||||
//! * device
|
||||
//! * device_ref
|
||||
inline constexpr __all_devices devices{};
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA
|
||||
|
||||
# include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CCCL_HAS_CTK() && !_CCCL_COMPILER(NVRTC)
|
||||
|
||||
#endif // _CUDA___DEVICE_ALL_DEVICES_H
|
||||
227
cccl_upstream/libcudacxx/include/cuda/__device/arch_id.h
Normal file
227
cccl_upstream/libcudacxx/include/cuda/__device/arch_id.h
Normal file
@@ -0,0 +1,227 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of libcu++, the C++ Standard Library for your entire system,
|
||||
// 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) 2025 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA___DEVICE_ARCH_ID_H
|
||||
#define _CUDA___DEVICE_ARCH_ID_H
|
||||
|
||||
#include <cuda/std/detail/__config>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#include <cuda/__device/compute_capability.h>
|
||||
#include <cuda/__fwd/devices.h>
|
||||
#include <cuda/std/__fwd/format.h>
|
||||
#include <cuda/std/__type_traits/always_false.h>
|
||||
#include <cuda/std/__utility/to_underlying.h>
|
||||
#include <cuda/std/array>
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA
|
||||
|
||||
//! @brief Architecture identifier
|
||||
//! This type identifies an architecture. It has more possible entries than just numeric values of the compute
|
||||
//! capability. For example, sm_90 and sm_90a have the same compute capability, but the identifier is different.
|
||||
enum class arch_id : int
|
||||
{
|
||||
#define _CCCL_DEFINE_ARCH_ID(_CC) sm_##_CC = _CC,
|
||||
#define _CCCL_DEFINE_ARCH_SPECIFIC_ID(_CC) sm_##_CC##a = _CC * __arch_specific_id_multiplier,
|
||||
_CCCL_PP_FOR_EACH(_CCCL_DEFINE_ARCH_ID, _CCCL_KNOWN_CUDA_ARCH_LIST)
|
||||
_CCCL_PP_FOR_EACH(_CCCL_DEFINE_ARCH_SPECIFIC_ID, _CCCL_KNOWN_CUDA_ARCH_SPECIFIC_LIST)
|
||||
#undef _CCCL_DEFINE_ARCH_ID
|
||||
#undef _CCCL_DEFINE_ARCH_SPECIFIC_ID
|
||||
};
|
||||
|
||||
// todo: = delete these in 4.0.
|
||||
#define _CCCL_DEPRECATED_ARCH_ID_COMPARISONS(_OP) \
|
||||
CCCL_DEPRECATED_BECAUSE("Comparing cuda::arch_id using operator" _CCCL_TO_STRING( \
|
||||
_OP) " is deprecated and will be deleted in the next major release. Compare cuda::compute_capabilities of the " \
|
||||
"given " \
|
||||
"cuda::arch_id instead.")
|
||||
[[nodiscard]] _CCCL_DEPRECATED_ARCH_ID_COMPARISONS(<) _CCCL_HOST_DEVICE_API constexpr bool
|
||||
operator<(arch_id __lhs, arch_id __rhs) noexcept
|
||||
{
|
||||
return ::cuda::std::to_underlying(__lhs) < ::cuda::std::to_underlying(__rhs);
|
||||
}
|
||||
[[nodiscard]] _CCCL_DEPRECATED_ARCH_ID_COMPARISONS(<=) _CCCL_HOST_DEVICE_API constexpr bool
|
||||
operator<=(arch_id __lhs, arch_id __rhs) noexcept
|
||||
{
|
||||
return ::cuda::std::to_underlying(__lhs) <= ::cuda::std::to_underlying(__rhs);
|
||||
}
|
||||
[[nodiscard]] _CCCL_DEPRECATED_ARCH_ID_COMPARISONS(>) _CCCL_HOST_DEVICE_API constexpr bool
|
||||
operator>(arch_id __lhs, arch_id __rhs) noexcept
|
||||
{
|
||||
return ::cuda::std::to_underlying(__lhs) > ::cuda::std::to_underlying(__rhs);
|
||||
}
|
||||
[[nodiscard]] _CCCL_DEPRECATED_ARCH_ID_COMPARISONS(>=) _CCCL_HOST_DEVICE_API constexpr bool
|
||||
operator>=(arch_id __lhs, arch_id __rhs) noexcept
|
||||
{
|
||||
return ::cuda::std::to_underlying(__lhs) >= ::cuda::std::to_underlying(__rhs);
|
||||
}
|
||||
#undef _CCCL_DEPRECATED_ARCH_ID_COMPARISONS
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr auto __all_arch_ids() noexcept
|
||||
{
|
||||
return ::cuda::std::array{
|
||||
#define _CCCL_MAKE_ARCH_ID(_CC) arch_id::sm_##_CC,
|
||||
#define _CCCL_MAKE_ARCH_SPECIFIC_ID(_CC) arch_id::sm_##_CC##a,
|
||||
_CCCL_PP_FOR_EACH(_CCCL_MAKE_ARCH_ID, _CCCL_KNOWN_CUDA_ARCH_LIST)
|
||||
_CCCL_PP_FOR_EACH(_CCCL_MAKE_ARCH_SPECIFIC_ID, _CCCL_KNOWN_CUDA_ARCH_SPECIFIC_LIST)
|
||||
#undef _CCCL_MAKE_ARCH_ID
|
||||
#undef _CCCL_MAKE_ARCH_SPECIFIC_ID
|
||||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr bool __is_specific_arch(arch_id __arch) noexcept
|
||||
{
|
||||
return ::cuda::std::to_underlying(__arch) > __arch_specific_id_multiplier;
|
||||
}
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr bool __has_known_arch(compute_capability __cc) noexcept
|
||||
{
|
||||
switch (__cc.get())
|
||||
{
|
||||
#define _CCCL_HAS_KNOWN_ARCH_CASE(_CC) case _CC:
|
||||
_CCCL_PP_FOR_EACH(_CCCL_HAS_KNOWN_ARCH_CASE, _CCCL_KNOWN_CUDA_ARCH_LIST)
|
||||
#undef _CCCL_HAS_KNOWN_ARCH_CASE
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr bool __has_known_specific_arch(compute_capability __cc) noexcept
|
||||
{
|
||||
switch (__cc.get())
|
||||
{
|
||||
#define _CCCL_HAS_KNOWN_SPECFIC_ARCH_CASE(_CC) case _CC:
|
||||
_CCCL_PP_FOR_EACH(_CCCL_HAS_KNOWN_SPECFIC_ARCH_CASE, _CCCL_KNOWN_CUDA_ARCH_SPECIFIC_LIST)
|
||||
#undef _CCCL_HAS_KNOWN_SPECFIC_ARCH_CASE
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//! @brief Converts the compute capability to the architecture id.
|
||||
//!
|
||||
//! @param __cc The compute capability. Must have a corresponding architecture id.
|
||||
//!
|
||||
//! @returns The architecture id.
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_id to_arch_id(compute_capability __cc) noexcept
|
||||
{
|
||||
_CCCL_ASSERT(::cuda::__has_known_arch(__cc), "this compute capability cannot be converted to arch id");
|
||||
return static_cast<arch_id>(__cc.get());
|
||||
}
|
||||
|
||||
//! @brief Converts the compute capability to the architecture specific id.
|
||||
//!
|
||||
//! @param __cc The compute capability. Must have a corresponding architecture specific id.
|
||||
//!
|
||||
//! @returns The architecture specific id.
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_id to_arch_specific_id(compute_capability __cc) noexcept
|
||||
{
|
||||
_CCCL_ASSERT(::cuda::__has_known_specific_arch(__cc),
|
||||
"this compute capability cannot be converted to arch specific id");
|
||||
return static_cast<arch_id>(__cc.get() * __arch_specific_id_multiplier);
|
||||
}
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA
|
||||
|
||||
#if __cpp_lib_format >= 201907L
|
||||
_CCCL_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _CharT>
|
||||
struct formatter<::cuda::arch_id, _CharT> : private formatter<::cuda::compute_capability, _CharT>
|
||||
{
|
||||
template <class _ParseCtx>
|
||||
_CCCL_HOST_API constexpr auto parse(_ParseCtx& __ctx)
|
||||
{
|
||||
return __ctx.begin();
|
||||
}
|
||||
|
||||
template <class _FmtCtx>
|
||||
_CCCL_HOST_API auto format(const ::cuda::arch_id& __arch, _FmtCtx& __ctx) const
|
||||
{
|
||||
auto __it = __ctx.out();
|
||||
*__it++ = _CharT{'s'};
|
||||
*__it++ = _CharT{'m'};
|
||||
*__it++ = _CharT{'_'};
|
||||
__ctx.advance_to(__it);
|
||||
__it = formatter<::cuda::compute_capability, _CharT>::format(::cuda::compute_capability{__arch}, __ctx);
|
||||
if (::cuda::__is_specific_arch(__arch))
|
||||
{
|
||||
*__it++ = _CharT{'a'};
|
||||
}
|
||||
return __it;
|
||||
}
|
||||
};
|
||||
|
||||
_CCCL_END_NAMESPACE_STD
|
||||
#endif // __cpp_lib_format >= 201907L
|
||||
|
||||
// todo: specialize cuda::std::formatter for cuda::arch_id
|
||||
|
||||
#if _CCCL_CUDA_COMPILATION()
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_DEVICE
|
||||
|
||||
//! @brief This function should cause a link error. If it happens, you are trying to compile the code for an unsupported
|
||||
//! architecture (too new/old).
|
||||
_CCCL_DEVICE_API ::cuda::arch_id __unknown_cuda_architecture();
|
||||
|
||||
//! @brief Returns the \c cuda::arch_id that is currently being compiled.
|
||||
//!
|
||||
//! If the current architecture is not a known architecture from \c cuda::arch_id enumeration, the compilation
|
||||
//! will fail.
|
||||
//!
|
||||
//! @note This API cannot be used in constexpr context when compiling with nvc++ in CUDA mode.
|
||||
template <class _Dummy = void>
|
||||
[[nodiscard]] _CCCL_DEVICE_API inline _CCCL_TARGET_CONSTEXPR ::cuda::arch_id current_arch_id() noexcept
|
||||
{
|
||||
# if _CCCL_CUDA_COMPILER(NVHPC)
|
||||
const auto __cc = ::cuda::device::current_compute_capability();
|
||||
if (::cuda::__has_known_arch(__cc))
|
||||
{
|
||||
return ::cuda::to_arch_id(__cc);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ::cuda::device::__unknown_cuda_architecture();
|
||||
}
|
||||
# elif _CCCL_DEVICE_COMPILATION()
|
||||
constexpr auto __cc = ::cuda::device::current_compute_capability();
|
||||
# if defined(__CUDA_ARCH_SPECIFIC__)
|
||||
constexpr auto __is_known_cc = ::cuda::std::__always_false_v<_Dummy> || ::cuda::__has_known_specific_arch(__cc);
|
||||
static_assert(__is_known_cc, "unknown CUDA specific architecture");
|
||||
return ::cuda::to_arch_specific_id(__cc);
|
||||
# else // ^^^ __CUDA_ARCH_SPECIFIC__ ^^^ / vvv !__CUDA_ARCH_SPECIFIC__ vvv
|
||||
constexpr auto __is_known_cc = ::cuda::std::__always_false_v<_Dummy> || ::cuda::__has_known_arch(__cc);
|
||||
static_assert(__is_known_cc, "unknown CUDA architecture");
|
||||
return ::cuda::to_arch_id(__cc);
|
||||
# endif // ^^^ __CUDA_ARCH_SPECIFIC__ ^^^
|
||||
# else
|
||||
return {};
|
||||
# endif // ^^^ single-pass cuda compiler ^^^
|
||||
}
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_DEVICE
|
||||
|
||||
#endif // _CCCL_CUDA_COMPILATION()
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA___DEVICE_ARCH_ID_H
|
||||
559
cccl_upstream/libcudacxx/include/cuda/__device/arch_traits.h
Normal file
559
cccl_upstream/libcudacxx/include/cuda/__device/arch_traits.h
Normal file
@@ -0,0 +1,559 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of libcu++, the C++ Standard Library for your entire system,
|
||||
// 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) 2026 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA___DEVICE_ARCH_TRAITS_H
|
||||
#define _CUDA___DEVICE_ARCH_TRAITS_H
|
||||
|
||||
#include <cuda/std/detail/__config>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#include <cuda/__device/arch_id.h>
|
||||
#include <cuda/__device/compute_capability.h>
|
||||
#include <cuda/__fwd/devices.h>
|
||||
#include <cuda/std/__exception/cuda_error.h>
|
||||
#include <cuda/std/__exception/exception_macros.h>
|
||||
#include <cuda/std/__type_traits/always_false.h>
|
||||
#include <cuda/std/cstdint>
|
||||
#include <cuda/std/limits>
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA
|
||||
|
||||
//! @brief Architecture traits
|
||||
//! This type contains information about an architecture that is constant across devices of that architecture.
|
||||
struct arch_traits_t
|
||||
{
|
||||
// Maximum number of threads per block
|
||||
int max_threads_per_block;
|
||||
|
||||
// Maximum x-dimension of a block
|
||||
int max_block_dim_x;
|
||||
|
||||
// Maximum y-dimension of a block
|
||||
int max_block_dim_y;
|
||||
|
||||
// Maximum z-dimension of a block
|
||||
int max_block_dim_z;
|
||||
|
||||
// Maximum x-dimension of a grid
|
||||
int max_grid_dim_x;
|
||||
|
||||
// Maximum y-dimension of a grid
|
||||
int max_grid_dim_y;
|
||||
|
||||
// Maximum z-dimension of a grid
|
||||
int max_grid_dim_z;
|
||||
|
||||
// Maximum amount of shared memory available to a thread block in bytes
|
||||
::cuda::std::size_t max_shared_memory_per_block;
|
||||
|
||||
// Memory available on device for __constant__ variables in a CUDA C kernel in bytes
|
||||
::cuda::std::size_t total_constant_memory;
|
||||
|
||||
// Warp size in threads
|
||||
int warp_size;
|
||||
|
||||
// Maximum number of concurrent grids on the device
|
||||
int max_resident_grids;
|
||||
|
||||
// true if the device can concurrently copy memory between host and device
|
||||
// while executing a kernel, or false if not
|
||||
bool gpu_overlap;
|
||||
|
||||
// true if the device can map host memory into CUDA address space
|
||||
bool can_map_host_memory;
|
||||
|
||||
// true if the device supports executing multiple kernels within the same
|
||||
// context simultaneously, or false if not. It is not guaranteed that multiple
|
||||
// kernels will be resident on the device concurrently so this feature should
|
||||
// not be relied upon for correctness.
|
||||
bool concurrent_kernels;
|
||||
|
||||
// true if the device supports stream priorities, or false if not
|
||||
bool stream_priorities_supported;
|
||||
|
||||
// true if device supports caching globals in L1 cache, false if not
|
||||
bool global_l1_cache_supported;
|
||||
|
||||
// true if device supports caching locals in L1 cache, false if not
|
||||
bool local_l1_cache_supported;
|
||||
|
||||
// TODO: We might want to have these per-arch
|
||||
// Maximum number of 32-bit registers available to a thread block
|
||||
int max_registers_per_block;
|
||||
|
||||
// Maximum number of 32-bit registers available to a multiprocessor; this
|
||||
// number is shared by all thread blocks simultaneously resident on a
|
||||
// multiprocessor
|
||||
int max_registers_per_multiprocessor;
|
||||
|
||||
// Maximum number of 32-bit registers available to a thread
|
||||
int max_registers_per_thread;
|
||||
|
||||
// Identifier for the architecture
|
||||
::cuda::arch_id arch_id;
|
||||
|
||||
// Major compute capability version number
|
||||
int compute_capability_major;
|
||||
|
||||
// Minor compute capability version number
|
||||
int compute_capability_minor;
|
||||
|
||||
// Compute capability version number in 100 * major + 10 * minor format
|
||||
::cuda::compute_capability compute_capability;
|
||||
|
||||
// Maximum amount of shared memory available to a multiprocessor in bytes;
|
||||
// this amount is shared by all thread blocks simultaneously resident on a
|
||||
// multiprocessor
|
||||
::cuda::std::size_t max_shared_memory_per_multiprocessor;
|
||||
|
||||
// Maximum number of thread blocks that can reside on a multiprocessor
|
||||
int max_blocks_per_multiprocessor;
|
||||
|
||||
// Maximum resident threads per multiprocessor
|
||||
int max_threads_per_multiprocessor;
|
||||
|
||||
// Maximum resident warps per multiprocessor
|
||||
int max_warps_per_multiprocessor;
|
||||
|
||||
// Shared memory reserved by CUDA driver per block in bytes
|
||||
::cuda::std::size_t reserved_shared_memory_per_block;
|
||||
|
||||
// Maximum per block shared memory size on the device. This value can be opted
|
||||
// into when using dynamic_shared_memory with NonPortableSize set to true
|
||||
::cuda::std::size_t max_shared_memory_per_block_optin;
|
||||
|
||||
// TODO: Do we want these?:
|
||||
// true if architecture supports clusters
|
||||
bool cluster_supported;
|
||||
|
||||
// true if architecture supports redux intrinsic instructions
|
||||
bool redux_intrinisic;
|
||||
|
||||
// true if architecture supports elect intrinsic instructions
|
||||
bool elect_intrinsic;
|
||||
|
||||
// true if architecture supports asynchronous copy instructions
|
||||
bool cp_async_supported;
|
||||
|
||||
// true if architecture supports tensor memory access instructions
|
||||
bool tma_supported;
|
||||
};
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t __common_arch_traits(arch_id __arch_id) noexcept
|
||||
{
|
||||
const compute_capability __cc{__arch_id};
|
||||
|
||||
arch_traits_t __traits{};
|
||||
__traits.max_threads_per_block = 1024;
|
||||
__traits.max_block_dim_x = 1024;
|
||||
__traits.max_block_dim_y = 1024;
|
||||
__traits.max_block_dim_z = 64;
|
||||
__traits.max_grid_dim_x = ::cuda::std::numeric_limits<::cuda::std::int32_t>::max();
|
||||
__traits.max_grid_dim_y = 64 * 1024 - 1;
|
||||
__traits.max_grid_dim_z = 64 * 1024 - 1;
|
||||
__traits.max_shared_memory_per_block = 48 * 1024;
|
||||
__traits.total_constant_memory = 64 * 1024;
|
||||
__traits.warp_size = 32;
|
||||
__traits.max_resident_grids = 128;
|
||||
__traits.gpu_overlap = true;
|
||||
__traits.can_map_host_memory = true;
|
||||
__traits.concurrent_kernels = true;
|
||||
__traits.stream_priorities_supported = true;
|
||||
__traits.global_l1_cache_supported = true;
|
||||
__traits.local_l1_cache_supported = true;
|
||||
__traits.max_registers_per_block = 64 * 1024;
|
||||
__traits.max_registers_per_multiprocessor = 64 * 1024;
|
||||
__traits.max_registers_per_thread = 255;
|
||||
__traits.arch_id = __arch_id;
|
||||
__traits.compute_capability_major = __cc.major_cap();
|
||||
__traits.compute_capability_minor = __cc.minor_cap();
|
||||
__traits.compute_capability = __cc;
|
||||
// __traits.max_shared_memory_per_multiprocessor; // set up individually
|
||||
// __traits.max_blocks_per_multiprocessor; // set up individually
|
||||
// __traits.max_threads_per_multiprocessor; // set up individually
|
||||
// __traits.max_warps_per_multiprocessor; // set up individually
|
||||
__traits.reserved_shared_memory_per_block = (__cc >= compute_capability{80}) ? 1024 : 0;
|
||||
// __traits.max_shared_memory_per_block_optin; // set up individually
|
||||
__traits.cluster_supported = (__cc >= compute_capability{90});
|
||||
__traits.redux_intrinisic = (__cc >= compute_capability{80});
|
||||
__traits.elect_intrinsic = (__cc >= compute_capability{90});
|
||||
__traits.cp_async_supported = (__cc >= compute_capability{80});
|
||||
__traits.tma_supported = (__cc >= compute_capability{90});
|
||||
return __traits;
|
||||
}
|
||||
|
||||
//! @brief Gets the architecture traits for the given architecture id \c _Id.
|
||||
template <arch_id _Id>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits() noexcept;
|
||||
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_50>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::__common_arch_traits(arch_id::sm_50);
|
||||
__traits.max_resident_grids = 32;
|
||||
__traits.max_shared_memory_per_multiprocessor = 64 * 1024;
|
||||
__traits.max_blocks_per_multiprocessor = 32;
|
||||
__traits.max_threads_per_multiprocessor = 2048;
|
||||
__traits.max_warps_per_multiprocessor = __traits.max_threads_per_multiprocessor / __traits.warp_size;
|
||||
__traits.max_shared_memory_per_block_optin = 48 * 1024;
|
||||
return __traits;
|
||||
};
|
||||
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_52>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::__common_arch_traits(arch_id::sm_52);
|
||||
__traits.max_resident_grids = 32;
|
||||
__traits.max_shared_memory_per_multiprocessor = 96 * 1024;
|
||||
__traits.max_blocks_per_multiprocessor = 32;
|
||||
__traits.max_threads_per_multiprocessor = 2048;
|
||||
__traits.max_warps_per_multiprocessor = __traits.max_threads_per_multiprocessor / __traits.warp_size;
|
||||
__traits.max_shared_memory_per_block_optin = 48 * 1024;
|
||||
return __traits;
|
||||
};
|
||||
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_53>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::__common_arch_traits(arch_id::sm_53);
|
||||
__traits.max_resident_grids = 32;
|
||||
__traits.max_shared_memory_per_multiprocessor = 64 * 1024;
|
||||
__traits.max_blocks_per_multiprocessor = 32;
|
||||
__traits.max_threads_per_multiprocessor = 2048;
|
||||
__traits.max_warps_per_multiprocessor = __traits.max_threads_per_multiprocessor / __traits.warp_size;
|
||||
__traits.max_shared_memory_per_block_optin = 48 * 1024;
|
||||
__traits.max_registers_per_block = 32 * 1024;
|
||||
return __traits;
|
||||
};
|
||||
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_60>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::__common_arch_traits(arch_id::sm_60);
|
||||
__traits.max_shared_memory_per_multiprocessor = 64 * 1024;
|
||||
__traits.max_blocks_per_multiprocessor = 32;
|
||||
__traits.max_threads_per_multiprocessor = 2048;
|
||||
__traits.max_warps_per_multiprocessor = __traits.max_threads_per_multiprocessor / __traits.warp_size;
|
||||
__traits.max_shared_memory_per_block_optin = 48 * 1024;
|
||||
return __traits;
|
||||
};
|
||||
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_61>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::__common_arch_traits(arch_id::sm_61);
|
||||
__traits.max_shared_memory_per_multiprocessor = 96 * 1024;
|
||||
__traits.max_blocks_per_multiprocessor = 32;
|
||||
__traits.max_threads_per_multiprocessor = 2048;
|
||||
__traits.max_warps_per_multiprocessor = __traits.max_threads_per_multiprocessor / __traits.warp_size;
|
||||
__traits.max_shared_memory_per_block_optin = 48 * 1024;
|
||||
return __traits;
|
||||
};
|
||||
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_62>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::__common_arch_traits(arch_id::sm_62);
|
||||
__traits.max_shared_memory_per_multiprocessor = 64 * 1024;
|
||||
__traits.max_blocks_per_multiprocessor = 32;
|
||||
__traits.max_threads_per_multiprocessor = 2048;
|
||||
__traits.max_warps_per_multiprocessor = __traits.max_threads_per_multiprocessor / __traits.warp_size;
|
||||
__traits.max_shared_memory_per_block_optin = 48 * 1024;
|
||||
__traits.max_registers_per_block = 32 * 1024;
|
||||
|
||||
return __traits;
|
||||
};
|
||||
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_70>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::__common_arch_traits(arch_id::sm_70);
|
||||
__traits.max_shared_memory_per_multiprocessor = 96 * 1024;
|
||||
__traits.max_blocks_per_multiprocessor = 32;
|
||||
__traits.max_threads_per_multiprocessor = 2048;
|
||||
__traits.max_warps_per_multiprocessor = __traits.max_threads_per_multiprocessor / __traits.warp_size;
|
||||
__traits.reserved_shared_memory_per_block = 0;
|
||||
__traits.max_shared_memory_per_block_optin =
|
||||
__traits.max_shared_memory_per_multiprocessor - __traits.reserved_shared_memory_per_block;
|
||||
return __traits;
|
||||
};
|
||||
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_75>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::__common_arch_traits(arch_id::sm_75);
|
||||
__traits.max_shared_memory_per_multiprocessor = 64 * 1024;
|
||||
__traits.max_blocks_per_multiprocessor = 16;
|
||||
__traits.max_threads_per_multiprocessor = 1024;
|
||||
__traits.max_warps_per_multiprocessor = __traits.max_threads_per_multiprocessor / __traits.warp_size;
|
||||
__traits.max_shared_memory_per_block_optin =
|
||||
__traits.max_shared_memory_per_multiprocessor - __traits.reserved_shared_memory_per_block;
|
||||
return __traits;
|
||||
};
|
||||
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_80>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::__common_arch_traits(arch_id::sm_80);
|
||||
__traits.max_shared_memory_per_multiprocessor = 164 * 1024;
|
||||
__traits.max_blocks_per_multiprocessor = 32;
|
||||
__traits.max_threads_per_multiprocessor = 2048;
|
||||
__traits.max_warps_per_multiprocessor = __traits.max_threads_per_multiprocessor / __traits.warp_size;
|
||||
__traits.max_shared_memory_per_block_optin =
|
||||
__traits.max_shared_memory_per_multiprocessor - __traits.reserved_shared_memory_per_block;
|
||||
return __traits;
|
||||
};
|
||||
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_86>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::__common_arch_traits(arch_id::sm_86);
|
||||
__traits.max_shared_memory_per_multiprocessor = 100 * 1024;
|
||||
__traits.max_blocks_per_multiprocessor = 16;
|
||||
__traits.max_threads_per_multiprocessor = 1536;
|
||||
__traits.max_warps_per_multiprocessor = __traits.max_threads_per_multiprocessor / __traits.warp_size;
|
||||
__traits.max_shared_memory_per_block_optin =
|
||||
__traits.max_shared_memory_per_multiprocessor - __traits.reserved_shared_memory_per_block;
|
||||
return __traits;
|
||||
};
|
||||
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_87>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::__common_arch_traits(arch_id::sm_87);
|
||||
__traits.max_shared_memory_per_multiprocessor = 164 * 1024;
|
||||
__traits.max_blocks_per_multiprocessor = 16;
|
||||
__traits.max_threads_per_multiprocessor = 1536;
|
||||
__traits.max_warps_per_multiprocessor = __traits.max_threads_per_multiprocessor / __traits.warp_size;
|
||||
__traits.max_shared_memory_per_block_optin =
|
||||
__traits.max_shared_memory_per_multiprocessor - __traits.reserved_shared_memory_per_block;
|
||||
return __traits;
|
||||
};
|
||||
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_88>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::arch_traits<arch_id::sm_86>();
|
||||
__traits.arch_id = arch_id::sm_88;
|
||||
__traits.compute_capability_major = 8;
|
||||
__traits.compute_capability_minor = 8;
|
||||
__traits.compute_capability = compute_capability{88};
|
||||
return __traits;
|
||||
};
|
||||
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_89>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::__common_arch_traits(arch_id::sm_89);
|
||||
__traits.max_shared_memory_per_multiprocessor = 100 * 1024;
|
||||
__traits.max_blocks_per_multiprocessor = 24;
|
||||
__traits.max_threads_per_multiprocessor = 1536;
|
||||
__traits.max_warps_per_multiprocessor = __traits.max_threads_per_multiprocessor / __traits.warp_size;
|
||||
__traits.max_shared_memory_per_block_optin =
|
||||
__traits.max_shared_memory_per_multiprocessor - __traits.reserved_shared_memory_per_block;
|
||||
return __traits;
|
||||
};
|
||||
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_90>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::__common_arch_traits(arch_id::sm_90);
|
||||
__traits.max_shared_memory_per_multiprocessor = 228 * 1024;
|
||||
__traits.max_blocks_per_multiprocessor = 32;
|
||||
__traits.max_threads_per_multiprocessor = 2048;
|
||||
__traits.max_warps_per_multiprocessor = __traits.max_threads_per_multiprocessor / __traits.warp_size;
|
||||
__traits.max_shared_memory_per_block_optin =
|
||||
__traits.max_shared_memory_per_multiprocessor - __traits.reserved_shared_memory_per_block;
|
||||
return __traits;
|
||||
};
|
||||
|
||||
// No sm_90a specific fields for now.
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_90a>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::arch_traits<arch_id::sm_90>();
|
||||
__traits.arch_id = arch_id::sm_90a;
|
||||
return __traits;
|
||||
};
|
||||
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_100>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::__common_arch_traits(arch_id::sm_90);
|
||||
__traits.max_shared_memory_per_multiprocessor = 228 * 1024;
|
||||
__traits.max_blocks_per_multiprocessor = 32;
|
||||
__traits.max_threads_per_multiprocessor = 2048;
|
||||
__traits.max_warps_per_multiprocessor = __traits.max_threads_per_multiprocessor / __traits.warp_size;
|
||||
__traits.max_shared_memory_per_block_optin =
|
||||
__traits.max_shared_memory_per_multiprocessor - __traits.reserved_shared_memory_per_block;
|
||||
return __traits;
|
||||
};
|
||||
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_100a>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::arch_traits<arch_id::sm_100>();
|
||||
__traits.arch_id = arch_id::sm_100a;
|
||||
return __traits;
|
||||
};
|
||||
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_103>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::arch_traits<arch_id::sm_100>();
|
||||
__traits.arch_id = arch_id::sm_103;
|
||||
__traits.compute_capability_major = 10;
|
||||
__traits.compute_capability_minor = 3;
|
||||
__traits.compute_capability = compute_capability{103};
|
||||
return __traits;
|
||||
};
|
||||
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_103a>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::arch_traits<arch_id::sm_103>();
|
||||
__traits.arch_id = arch_id::sm_103a;
|
||||
return __traits;
|
||||
};
|
||||
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_110>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::arch_traits<arch_id::sm_100>();
|
||||
__traits.arch_id = arch_id::sm_110;
|
||||
__traits.compute_capability_major = 11;
|
||||
__traits.compute_capability_minor = 0;
|
||||
__traits.compute_capability = compute_capability{110};
|
||||
__traits.max_blocks_per_multiprocessor = 24;
|
||||
__traits.max_threads_per_multiprocessor = 1536;
|
||||
__traits.max_warps_per_multiprocessor = __traits.max_threads_per_multiprocessor / __traits.warp_size;
|
||||
return __traits;
|
||||
};
|
||||
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_110a>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::arch_traits<arch_id::sm_110>();
|
||||
__traits.arch_id = arch_id::sm_110a;
|
||||
return __traits;
|
||||
};
|
||||
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_120>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::__common_arch_traits(arch_id::sm_120);
|
||||
__traits.max_shared_memory_per_multiprocessor = 100 * 1024;
|
||||
__traits.max_blocks_per_multiprocessor = 24;
|
||||
__traits.max_threads_per_multiprocessor = 1536;
|
||||
__traits.max_warps_per_multiprocessor = __traits.max_threads_per_multiprocessor / __traits.warp_size;
|
||||
__traits.max_shared_memory_per_block_optin =
|
||||
__traits.max_shared_memory_per_multiprocessor - __traits.reserved_shared_memory_per_block;
|
||||
return __traits;
|
||||
};
|
||||
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_120a>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::arch_traits<arch_id::sm_120>();
|
||||
__traits.arch_id = arch_id::sm_120a;
|
||||
return __traits;
|
||||
};
|
||||
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_121>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::arch_traits<arch_id::sm_120>();
|
||||
__traits.arch_id = arch_id::sm_121;
|
||||
__traits.compute_capability_major = 12;
|
||||
__traits.compute_capability_minor = 1;
|
||||
__traits.compute_capability = compute_capability{121};
|
||||
return __traits;
|
||||
};
|
||||
|
||||
template <>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits<arch_id::sm_121a>() noexcept
|
||||
{
|
||||
auto __traits = ::cuda::arch_traits<arch_id::sm_121>();
|
||||
__traits.arch_id = arch_id::sm_121a;
|
||||
return __traits;
|
||||
};
|
||||
|
||||
//! @brief Gets the architecture traits for the given architecture id \c __id.
|
||||
//!
|
||||
//! @throws cuda::cuda_error if the \c __id is not a known architecture.
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits_for(arch_id __id)
|
||||
{
|
||||
switch (__id)
|
||||
{
|
||||
#define _CCCL_ARCH_TRAITS_FOR_CASE(_CC) \
|
||||
case arch_id::sm_##_CC: \
|
||||
return ::cuda::arch_traits<arch_id::sm_##_CC>();
|
||||
#define _CCCL_ARCH_TRAITS_FOR_SPECIFIC_CASE(_CC) \
|
||||
case arch_id::sm_##_CC##a: \
|
||||
return ::cuda::arch_traits<arch_id::sm_##_CC##a>();
|
||||
_CCCL_PP_FOR_EACH(_CCCL_ARCH_TRAITS_FOR_CASE, _CCCL_KNOWN_CUDA_ARCH_LIST)
|
||||
_CCCL_PP_FOR_EACH(_CCCL_ARCH_TRAITS_FOR_SPECIFIC_CASE, _CCCL_KNOWN_CUDA_ARCH_SPECIFIC_LIST)
|
||||
#undef _CCCL_ARCH_TRAITS_FOR_CASE
|
||||
#undef _CCCL_ARCH_TRAITS_FOR_SPECIFIC_CASE
|
||||
default:
|
||||
#if _CCCL_HAS_CTK()
|
||||
_CCCL_THROW(::cuda::cuda_error, ::cudaErrorInvalidValue, "Traits requested for an unknown architecture");
|
||||
#else // ^^^ _CCCL_HAS_CTK() ^^^ / vvv !_CCCL_HAS_CTK() vvv
|
||||
_CCCL_THROW(::cuda::cuda_error, /*cudaErrorInvalidValue*/ 1, "Traits requested for an unknown architecture");
|
||||
#endif // ^^^ !_CCCL_HAS_CTK() ^^^
|
||||
}
|
||||
}
|
||||
|
||||
//! @brief Gets the architecture traits for the given compute capability \c __cc.
|
||||
//!
|
||||
//! @throws cuda::cuda_error if the \c __cc doesn't have a corresponding architecture id.
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr arch_traits_t arch_traits_for(compute_capability __cc)
|
||||
{
|
||||
return ::cuda::arch_traits_for(::cuda::to_arch_id(__cc));
|
||||
}
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA
|
||||
|
||||
#if _CCCL_CUDA_COMPILATION()
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_DEVICE
|
||||
|
||||
//! @brief Returns the \c cuda::arch_trait_t of the architecture that is currently being compiled.
|
||||
//!
|
||||
//! If the current architecture is not a known architecture from \c cuda::arch_id enumeration, the compilation
|
||||
//! will fail.
|
||||
//!
|
||||
//! @note This API cannot be used in constexpr context when compiling with nvc++ in CUDA mode.
|
||||
template <class _Dummy = void>
|
||||
[[nodiscard]] _CCCL_DEVICE_API inline _CCCL_TARGET_CONSTEXPR ::cuda::arch_traits_t current_arch_traits() noexcept
|
||||
{
|
||||
# if _CCCL_DEVICE_COMPILATION()
|
||||
return ::cuda::arch_traits_for(::cuda::device::current_arch_id<_Dummy>());
|
||||
# else // ^^^ _CCCL_DEVICE_COMPILATION() ^^^ / vvv !_CCCL_DEVICE_COMPILATION() vvv
|
||||
return {};
|
||||
# endif // ^^^ !_CCCL_DEVICE_COMPILATION() ^^^
|
||||
}
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_DEVICE
|
||||
|
||||
#endif // _CCCL_CUDA_COMPILATION
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA___DEVICE_ARCH_TRAITS_H
|
||||
807
cccl_upstream/libcudacxx/include/cuda/__device/attributes.h
Normal file
807
cccl_upstream/libcudacxx/include/cuda/__device/attributes.h
Normal file
@@ -0,0 +1,807 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of libcu++, the C++ Standard Library for your entire system,
|
||||
// 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) 2025 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA___DEVICE_ATTRIBUTES_H
|
||||
#define _CUDA___DEVICE_ATTRIBUTES_H
|
||||
|
||||
#include <cuda/std/detail/__config>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#if _CCCL_HAS_CTK() && !_CCCL_COMPILER(NVRTC)
|
||||
|
||||
# include <cuda/__device/compute_capability.h>
|
||||
# include <cuda/__device/device_ref.h>
|
||||
# include <cuda/__driver/driver_api.h>
|
||||
# include <cuda/__fwd/devices.h>
|
||||
# include <cuda/std/__cstddef/types.h>
|
||||
|
||||
# include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA
|
||||
|
||||
template <::cudaDeviceAttr _Attr, typename _Type>
|
||||
struct __dev_attr_impl
|
||||
{
|
||||
using type = _Type;
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_API constexpr operator ::cudaDeviceAttr() const noexcept
|
||||
{
|
||||
return _Attr;
|
||||
}
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_API type operator()(device_ref __dev) const
|
||||
{
|
||||
return static_cast<type>(::cuda::__driver::__deviceGetAttribute(
|
||||
static_cast<::CUdevice_attribute>(_Attr), ::cuda::__driver::__deviceGet(__dev.get())));
|
||||
}
|
||||
};
|
||||
|
||||
template <::cudaDeviceAttr _Attr>
|
||||
struct __dev_attr : __dev_attr_impl<_Attr, int>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrMaxSharedMemoryPerBlock> //
|
||||
: __dev_attr_impl<::cudaDevAttrMaxSharedMemoryPerBlock, ::cuda::std::size_t>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrTotalConstantMemory> //
|
||||
: __dev_attr_impl<::cudaDevAttrTotalConstantMemory, ::cuda::std::size_t>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrMaxPitch> //
|
||||
: __dev_attr_impl<::cudaDevAttrMaxPitch, ::cuda::std::size_t>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrMaxTexture2DLinearPitch> //
|
||||
: __dev_attr_impl<::cudaDevAttrMaxTexture2DLinearPitch, ::cuda::std::size_t>
|
||||
{};
|
||||
// TODO: give this a strong type for kilohertz
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrClockRate> //
|
||||
: __dev_attr_impl<::cudaDevAttrClockRate, int>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrTextureAlignment> //
|
||||
: __dev_attr_impl<::cudaDevAttrTextureAlignment, ::cuda::std::size_t>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrTexturePitchAlignment> //
|
||||
: __dev_attr_impl<::cudaDevAttrTexturePitchAlignment, ::cuda::std::size_t>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrGpuOverlap> //
|
||||
: __dev_attr_impl<::cudaDevAttrGpuOverlap, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrKernelExecTimeout> //
|
||||
: __dev_attr_impl<::cudaDevAttrKernelExecTimeout, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrIntegrated> //
|
||||
: __dev_attr_impl<::cudaDevAttrIntegrated, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrCanMapHostMemory> //
|
||||
: __dev_attr_impl<::cudaDevAttrCanMapHostMemory, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrComputeMode> //
|
||||
: __dev_attr_impl<::cudaDevAttrComputeMode, ::cudaComputeMode>
|
||||
{
|
||||
static constexpr type default_mode = ::cudaComputeModeDefault;
|
||||
static constexpr type prohibited_mode = ::cudaComputeModeProhibited;
|
||||
static constexpr type exclusive_process_mode = ::cudaComputeModeExclusiveProcess;
|
||||
};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrConcurrentKernels> //
|
||||
: __dev_attr_impl<::cudaDevAttrConcurrentKernels, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrEccEnabled> //
|
||||
: __dev_attr_impl<::cudaDevAttrEccEnabled, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrTccDriver> //
|
||||
: __dev_attr_impl<::cudaDevAttrTccDriver, bool>
|
||||
{};
|
||||
// TODO: give this a strong type for kilohertz
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrMemoryClockRate> //
|
||||
: __dev_attr_impl<::cudaDevAttrMemoryClockRate, int>
|
||||
{};
|
||||
// TODO: give this a strong type for bits
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrGlobalMemoryBusWidth> //
|
||||
: __dev_attr_impl<::cudaDevAttrGlobalMemoryBusWidth, int>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrL2CacheSize> //
|
||||
: __dev_attr_impl<::cudaDevAttrL2CacheSize, ::cuda::std::size_t>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrUnifiedAddressing> //
|
||||
: __dev_attr_impl<::cudaDevAttrUnifiedAddressing, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrStreamPrioritiesSupported> //
|
||||
: __dev_attr_impl<::cudaDevAttrStreamPrioritiesSupported, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrGlobalL1CacheSupported> //
|
||||
: __dev_attr_impl<::cudaDevAttrGlobalL1CacheSupported, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrLocalL1CacheSupported> //
|
||||
: __dev_attr_impl<::cudaDevAttrLocalL1CacheSupported, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrMaxSharedMemoryPerMultiprocessor> //
|
||||
: __dev_attr_impl<::cudaDevAttrMaxSharedMemoryPerMultiprocessor, ::cuda::std::size_t>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrManagedMemory> //
|
||||
: __dev_attr_impl<::cudaDevAttrManagedMemory, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrIsMultiGpuBoard> //
|
||||
: __dev_attr_impl<::cudaDevAttrIsMultiGpuBoard, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrHostNativeAtomicSupported> //
|
||||
: __dev_attr_impl<::cudaDevAttrHostNativeAtomicSupported, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrPageableMemoryAccess> //
|
||||
: __dev_attr_impl<::cudaDevAttrPageableMemoryAccess, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrConcurrentManagedAccess> //
|
||||
: __dev_attr_impl<::cudaDevAttrConcurrentManagedAccess, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrComputePreemptionSupported> //
|
||||
: __dev_attr_impl<::cudaDevAttrComputePreemptionSupported, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrCanUseHostPointerForRegisteredMem> //
|
||||
: __dev_attr_impl<::cudaDevAttrCanUseHostPointerForRegisteredMem, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrCooperativeLaunch> //
|
||||
: __dev_attr_impl<::cudaDevAttrCooperativeLaunch, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrCanFlushRemoteWrites> //
|
||||
: __dev_attr_impl<::cudaDevAttrCanFlushRemoteWrites, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrHostRegisterSupported> //
|
||||
: __dev_attr_impl<::cudaDevAttrHostRegisterSupported, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrDirectManagedMemAccessFromHost> //
|
||||
: __dev_attr_impl<::cudaDevAttrDirectManagedMemAccessFromHost, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrMaxSharedMemoryPerBlockOptin> //
|
||||
: __dev_attr_impl<::cudaDevAttrMaxSharedMemoryPerBlockOptin, ::cuda::std::size_t>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrMaxPersistingL2CacheSize> //
|
||||
: __dev_attr_impl<::cudaDevAttrMaxPersistingL2CacheSize, ::cuda::std::size_t>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrMaxAccessPolicyWindowSize> //
|
||||
: __dev_attr_impl<::cudaDevAttrMaxAccessPolicyWindowSize, ::cuda::std::size_t>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrReservedSharedMemoryPerBlock> //
|
||||
: __dev_attr_impl<::cudaDevAttrReservedSharedMemoryPerBlock, ::cuda::std::size_t>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrSparseCudaArraySupported> //
|
||||
: __dev_attr_impl<::cudaDevAttrSparseCudaArraySupported, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrMemoryPoolsSupported> //
|
||||
: __dev_attr_impl<::cudaDevAttrMemoryPoolsSupported, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrGPUDirectRDMASupported> //
|
||||
: __dev_attr_impl<::cudaDevAttrGPUDirectRDMASupported, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrDeferredMappingCudaArraySupported> //
|
||||
: __dev_attr_impl<::cudaDevAttrDeferredMappingCudaArraySupported, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrIpcEventSupport> //
|
||||
: __dev_attr_impl<::cudaDevAttrIpcEventSupport, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrPageableMemoryAccessUsesHostPageTables>
|
||||
: __dev_attr_impl<::cudaDevAttrPageableMemoryAccessUsesHostPageTables, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrHostRegisterReadOnlySupported> //
|
||||
: __dev_attr_impl<::cudaDevAttrHostRegisterReadOnlySupported, bool>
|
||||
{};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrGPUDirectRDMAFlushWritesOptions> //
|
||||
: __dev_attr_impl<::cudaDevAttrGPUDirectRDMAFlushWritesOptions, ::cudaFlushGPUDirectRDMAWritesOptions>
|
||||
{
|
||||
static constexpr type host = ::cudaFlushGPUDirectRDMAWritesOptionHost;
|
||||
static constexpr type mem_ops = ::cudaFlushGPUDirectRDMAWritesOptionMemOps;
|
||||
};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrGPUDirectRDMAWritesOrdering> //
|
||||
: __dev_attr_impl<::cudaDevAttrGPUDirectRDMAWritesOrdering, ::cudaGPUDirectRDMAWritesOrdering>
|
||||
{
|
||||
static constexpr type none = ::cudaGPUDirectRDMAWritesOrderingNone;
|
||||
static constexpr type owner = ::cudaGPUDirectRDMAWritesOrderingOwner;
|
||||
static constexpr type all_devices = ::cudaGPUDirectRDMAWritesOrderingAllDevices;
|
||||
};
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrMemoryPoolSupportedHandleTypes> //
|
||||
: __dev_attr_impl<::cudaDevAttrMemoryPoolSupportedHandleTypes, ::cudaMemAllocationHandleType>
|
||||
{
|
||||
static constexpr type none = ::cudaMemHandleTypeNone;
|
||||
static constexpr type posix_file_descriptor = ::cudaMemHandleTypePosixFileDescriptor;
|
||||
static constexpr type win32 = ::cudaMemHandleTypeWin32;
|
||||
static constexpr type win32_kmt = ::cudaMemHandleTypeWin32Kmt;
|
||||
# if _CCCL_CTK_AT_LEAST(12, 4)
|
||||
static constexpr type fabric = ::cudaMemHandleTypeFabric;
|
||||
# else // ^^^ _CCCL_CTK_AT_LEAST(12, 4) ^^^ / vvv _CCCL_CTK_BELOW(12, 4) vvv
|
||||
static inline const type fabric = static_cast<::cudaMemAllocationHandleType>(0x8);
|
||||
# endif // ^^^ _CCCL_CTK_BELOW(12, 4) ^^^
|
||||
};
|
||||
# if _CCCL_CTK_AT_LEAST(12, 2)
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrNumaConfig> //
|
||||
: __dev_attr_impl<::cudaDevAttrNumaConfig, ::cudaDeviceNumaConfig>
|
||||
{
|
||||
static constexpr type none = ::cudaDeviceNumaConfigNone;
|
||||
static constexpr type numa_node = ::cudaDeviceNumaConfigNumaNode;
|
||||
};
|
||||
# endif // _CCCL_CTK_AT_LEAST(12, 2)
|
||||
|
||||
# if _CCCL_CTK_AT_LEAST(12, 9)
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrHostNumaMemoryPoolsSupported>
|
||||
: __dev_attr_impl<::cudaDevAttrHostNumaMemoryPoolsSupported, bool>
|
||||
{};
|
||||
# endif // ^^^ _CCCL_CTK_AT_LEAST(12, 9) ^^^
|
||||
|
||||
# if _CCCL_CTK_AT_LEAST(13, 0)
|
||||
template <>
|
||||
struct __dev_attr<::cudaDevAttrHostMemoryPoolsSupported> : __dev_attr_impl<::cudaDevAttrHostMemoryPoolsSupported, bool>
|
||||
{};
|
||||
# endif // ^^^ _CCCL_CTK_AT_LEAST(13, 0) ^^^
|
||||
|
||||
namespace device_attributes
|
||||
{
|
||||
// Maximum number of threads per block
|
||||
using max_threads_per_block_t = __dev_attr<::cudaDevAttrMaxThreadsPerBlock>;
|
||||
static constexpr max_threads_per_block_t max_threads_per_block{};
|
||||
|
||||
// Maximum x-dimension of a block
|
||||
using max_block_dim_x_t = __dev_attr<::cudaDevAttrMaxBlockDimX>;
|
||||
static constexpr max_block_dim_x_t max_block_dim_x{};
|
||||
|
||||
// Maximum y-dimension of a block
|
||||
using max_block_dim_y_t = __dev_attr<::cudaDevAttrMaxBlockDimY>;
|
||||
static constexpr max_block_dim_y_t max_block_dim_y{};
|
||||
|
||||
// Maximum z-dimension of a block
|
||||
using max_block_dim_z_t = __dev_attr<::cudaDevAttrMaxBlockDimZ>;
|
||||
static constexpr max_block_dim_z_t max_block_dim_z{};
|
||||
|
||||
// Maximum x-dimension of a grid
|
||||
using max_grid_dim_x_t = __dev_attr<::cudaDevAttrMaxGridDimX>;
|
||||
static constexpr max_grid_dim_x_t max_grid_dim_x{};
|
||||
|
||||
// Maximum y-dimension of a grid
|
||||
using max_grid_dim_y_t = __dev_attr<::cudaDevAttrMaxGridDimY>;
|
||||
static constexpr max_grid_dim_y_t max_grid_dim_y{};
|
||||
|
||||
// Maximum z-dimension of a grid
|
||||
using max_grid_dim_z_t = __dev_attr<::cudaDevAttrMaxGridDimZ>;
|
||||
static constexpr max_grid_dim_z_t max_grid_dim_z{};
|
||||
|
||||
// Maximum amount of shared memory available to a thread block in bytes
|
||||
using max_shared_memory_per_block_t = __dev_attr<::cudaDevAttrMaxSharedMemoryPerBlock>;
|
||||
static constexpr max_shared_memory_per_block_t max_shared_memory_per_block{};
|
||||
|
||||
// Memory available on device for __constant__ variables in a CUDA C kernel in bytes
|
||||
using total_constant_memory_t = __dev_attr<::cudaDevAttrTotalConstantMemory>;
|
||||
static constexpr total_constant_memory_t total_constant_memory{};
|
||||
|
||||
// Warp size in threads
|
||||
using warp_size_t = __dev_attr<::cudaDevAttrWarpSize>;
|
||||
static constexpr warp_size_t warp_size{};
|
||||
|
||||
// Maximum pitch in bytes allowed by the memory copy functions that involve
|
||||
// memory regions allocated through cudaMallocPitch()
|
||||
using max_pitch_t = __dev_attr<::cudaDevAttrMaxPitch>;
|
||||
static constexpr max_pitch_t max_pitch{};
|
||||
|
||||
// Maximum 1D texture width
|
||||
using max_texture_1d_width_t = __dev_attr<::cudaDevAttrMaxTexture1DWidth>;
|
||||
static constexpr max_texture_1d_width_t max_texture_1d_width{};
|
||||
|
||||
// Maximum width for a 1D texture bound to linear memory
|
||||
using max_texture_1d_linear_width_t = __dev_attr<::cudaDevAttrMaxTexture1DLinearWidth>;
|
||||
static constexpr max_texture_1d_linear_width_t max_texture_1d_linear_width{};
|
||||
|
||||
// Maximum mipmapped 1D texture width
|
||||
using max_texture_1d_mipmapped_width_t = __dev_attr<::cudaDevAttrMaxTexture1DMipmappedWidth>;
|
||||
static constexpr max_texture_1d_mipmapped_width_t max_texture_1d_mipmapped_width{};
|
||||
|
||||
// Maximum 2D texture width
|
||||
using max_texture_2d_width_t = __dev_attr<::cudaDevAttrMaxTexture2DWidth>;
|
||||
static constexpr max_texture_2d_width_t max_texture_2d_width{};
|
||||
|
||||
// Maximum 2D texture height
|
||||
using max_texture_2d_height_t = __dev_attr<::cudaDevAttrMaxTexture2DHeight>;
|
||||
static constexpr max_texture_2d_height_t max_texture_2d_height{};
|
||||
|
||||
// Maximum width for a 2D texture bound to linear memory
|
||||
using max_texture_2d_linear_width_t = __dev_attr<::cudaDevAttrMaxTexture2DLinearWidth>;
|
||||
static constexpr max_texture_2d_linear_width_t max_texture_2d_linear_width{};
|
||||
|
||||
// Maximum height for a 2D texture bound to linear memory
|
||||
using max_texture_2d_linear_height_t = __dev_attr<::cudaDevAttrMaxTexture2DLinearHeight>;
|
||||
static constexpr max_texture_2d_linear_height_t max_texture_2d_linear_height{};
|
||||
|
||||
// Maximum pitch in bytes for a 2D texture bound to linear memory
|
||||
using max_texture_2d_linear_pitch_t = __dev_attr<::cudaDevAttrMaxTexture2DLinearPitch>;
|
||||
static constexpr max_texture_2d_linear_pitch_t max_texture_2d_linear_pitch{};
|
||||
|
||||
// Maximum mipmapped 2D texture width
|
||||
using max_texture_2d_mipmapped_width_t = __dev_attr<::cudaDevAttrMaxTexture2DMipmappedWidth>;
|
||||
static constexpr max_texture_2d_mipmapped_width_t max_texture_2d_mipmapped_width{};
|
||||
|
||||
// Maximum mipmapped 2D texture height
|
||||
using max_texture_2d_mipmapped_height_t = __dev_attr<::cudaDevAttrMaxTexture2DMipmappedHeight>;
|
||||
static constexpr max_texture_2d_mipmapped_height_t max_texture_2d_mipmapped_height{};
|
||||
|
||||
// Maximum 3D texture width
|
||||
using max_texture_3d_width_t = __dev_attr<::cudaDevAttrMaxTexture3DWidth>;
|
||||
static constexpr max_texture_3d_width_t max_texture_3d_width{};
|
||||
|
||||
// Maximum 3D texture height
|
||||
using max_texture_3d_height_t = __dev_attr<::cudaDevAttrMaxTexture3DHeight>;
|
||||
static constexpr max_texture_3d_height_t max_texture_3d_height{};
|
||||
|
||||
// Maximum 3D texture depth
|
||||
using max_texture_3d_depth_t = __dev_attr<::cudaDevAttrMaxTexture3DDepth>;
|
||||
static constexpr max_texture_3d_depth_t max_texture_3d_depth{};
|
||||
|
||||
// Alternate maximum 3D texture width, 0 if no alternate maximum 3D texture size is supported
|
||||
using max_texture_3d_width_alt_t = __dev_attr<::cudaDevAttrMaxTexture3DWidthAlt>;
|
||||
static constexpr max_texture_3d_width_alt_t max_texture_3d_width_alt{};
|
||||
|
||||
// Alternate maximum 3D texture height, 0 if no alternate maximum 3D texture size is supported
|
||||
using max_texture_3d_height_alt_t = __dev_attr<::cudaDevAttrMaxTexture3DHeightAlt>;
|
||||
static constexpr max_texture_3d_height_alt_t max_texture_3d_height_alt{};
|
||||
|
||||
// Alternate maximum 3D texture depth, 0 if no alternate maximum 3D texture size is supported
|
||||
using max_texture_3d_depth_alt_t = __dev_attr<::cudaDevAttrMaxTexture3DDepthAlt>;
|
||||
static constexpr max_texture_3d_depth_alt_t max_texture_3d_depth_alt{};
|
||||
|
||||
// Maximum cubemap texture width or height
|
||||
using max_texture_cubemap_width_t = __dev_attr<::cudaDevAttrMaxTextureCubemapWidth>;
|
||||
static constexpr max_texture_cubemap_width_t max_texture_cubemap_width{};
|
||||
|
||||
// Maximum 1D layered texture width
|
||||
using max_texture_1d_layered_width_t = __dev_attr<::cudaDevAttrMaxTexture1DLayeredWidth>;
|
||||
static constexpr max_texture_1d_layered_width_t max_texture_1d_layered_width{};
|
||||
|
||||
// Maximum layers in a 1D layered texture
|
||||
using max_texture_1d_layered_layers_t = __dev_attr<::cudaDevAttrMaxTexture1DLayeredLayers>;
|
||||
static constexpr max_texture_1d_layered_layers_t max_texture_1d_layered_layers{};
|
||||
|
||||
// Maximum 2D layered texture width
|
||||
using max_texture_2d_layered_width_t = __dev_attr<::cudaDevAttrMaxTexture2DLayeredWidth>;
|
||||
static constexpr max_texture_2d_layered_width_t max_texture_2d_layered_width{};
|
||||
|
||||
// Maximum 2D layered texture height
|
||||
using max_texture_2d_layered_height_t = __dev_attr<::cudaDevAttrMaxTexture2DLayeredHeight>;
|
||||
static constexpr max_texture_2d_layered_height_t max_texture_2d_layered_height{};
|
||||
|
||||
// Maximum layers in a 2D layered texture
|
||||
using max_texture_2d_layered_layers_t = __dev_attr<::cudaDevAttrMaxTexture2DLayeredLayers>;
|
||||
static constexpr max_texture_2d_layered_layers_t max_texture_2d_layered_layers{};
|
||||
|
||||
// Maximum cubemap layered texture width or height
|
||||
using max_texture_cubemap_layered_width_t = __dev_attr<::cudaDevAttrMaxTextureCubemapLayeredWidth>;
|
||||
static constexpr max_texture_cubemap_layered_width_t max_texture_cubemap_layered_width{};
|
||||
|
||||
// Maximum layers in a cubemap layered texture
|
||||
using max_texture_cubemap_layered_layers_t = __dev_attr<::cudaDevAttrMaxTextureCubemapLayeredLayers>;
|
||||
static constexpr max_texture_cubemap_layered_layers_t max_texture_cubemap_layered_layers{};
|
||||
|
||||
// Maximum 1D surface width
|
||||
using max_surface_1d_width_t = __dev_attr<::cudaDevAttrMaxSurface1DWidth>;
|
||||
static constexpr max_surface_1d_width_t max_surface_1d_width{};
|
||||
|
||||
// Maximum 2D surface width
|
||||
using max_surface_2d_width_t = __dev_attr<::cudaDevAttrMaxSurface2DWidth>;
|
||||
static constexpr max_surface_2d_width_t max_surface_2d_width{};
|
||||
|
||||
// Maximum 2D surface height
|
||||
using max_surface_2d_height_t = __dev_attr<::cudaDevAttrMaxSurface2DHeight>;
|
||||
static constexpr max_surface_2d_height_t max_surface_2d_height{};
|
||||
|
||||
// Maximum 3D surface width
|
||||
using max_surface_3d_width_t = __dev_attr<::cudaDevAttrMaxSurface3DWidth>;
|
||||
static constexpr max_surface_3d_width_t max_surface_3d_width{};
|
||||
|
||||
// Maximum 3D surface height
|
||||
using max_surface_3d_height_t = __dev_attr<::cudaDevAttrMaxSurface3DHeight>;
|
||||
static constexpr max_surface_3d_height_t max_surface_3d_height{};
|
||||
|
||||
// Maximum 3D surface depth
|
||||
using max_surface_3d_depth_t = __dev_attr<::cudaDevAttrMaxSurface3DDepth>;
|
||||
static constexpr max_surface_3d_depth_t max_surface_3d_depth{};
|
||||
|
||||
// Maximum 1D layered surface width
|
||||
using max_surface_1d_layered_width_t = __dev_attr<::cudaDevAttrMaxSurface1DLayeredWidth>;
|
||||
static constexpr max_surface_1d_layered_width_t max_surface_1d_layered_width{};
|
||||
|
||||
// Maximum layers in a 1D layered surface
|
||||
using max_surface_1d_layered_layers_t = __dev_attr<::cudaDevAttrMaxSurface1DLayeredLayers>;
|
||||
static constexpr max_surface_1d_layered_layers_t max_surface_1d_layered_layers{};
|
||||
|
||||
// Maximum 2D layered surface width
|
||||
using max_surface_2d_layered_width_t = __dev_attr<::cudaDevAttrMaxSurface2DLayeredWidth>;
|
||||
static constexpr max_surface_2d_layered_width_t max_surface_2d_layered_width{};
|
||||
|
||||
// Maximum 2D layered surface height
|
||||
using max_surface_2d_layered_height_t = __dev_attr<::cudaDevAttrMaxSurface2DLayeredHeight>;
|
||||
static constexpr max_surface_2d_layered_height_t max_surface_2d_layered_height{};
|
||||
|
||||
// Maximum layers in a 2D layered surface
|
||||
using max_surface_2d_layered_layers_t = __dev_attr<::cudaDevAttrMaxSurface2DLayeredLayers>;
|
||||
static constexpr max_surface_2d_layered_layers_t max_surface_2d_layered_layers{};
|
||||
|
||||
// Maximum cubemap surface width
|
||||
using max_surface_cubemap_width_t = __dev_attr<::cudaDevAttrMaxSurfaceCubemapWidth>;
|
||||
static constexpr max_surface_cubemap_width_t max_surface_cubemap_width{};
|
||||
|
||||
// Maximum cubemap layered surface width
|
||||
using max_surface_cubemap_layered_width_t = __dev_attr<::cudaDevAttrMaxSurfaceCubemapLayeredWidth>;
|
||||
static constexpr max_surface_cubemap_layered_width_t max_surface_cubemap_layered_width{};
|
||||
|
||||
// Maximum layers in a cubemap layered surface
|
||||
using max_surface_cubemap_layered_layers_t = __dev_attr<::cudaDevAttrMaxSurfaceCubemapLayeredLayers>;
|
||||
static constexpr max_surface_cubemap_layered_layers_t max_surface_cubemap_layered_layers{};
|
||||
|
||||
// Maximum number of 32-bit registers available to a thread block
|
||||
using max_registers_per_block_t = __dev_attr<::cudaDevAttrMaxRegistersPerBlock>;
|
||||
static constexpr max_registers_per_block_t max_registers_per_block{};
|
||||
|
||||
// Peak clock frequency in kilohertz
|
||||
using clock_rate_t = __dev_attr<::cudaDevAttrClockRate>;
|
||||
static constexpr clock_rate_t clock_rate{};
|
||||
|
||||
// Alignment requirement; texture base addresses aligned to textureAlign bytes
|
||||
// do not need an offset applied to texture fetches
|
||||
using texture_alignment_t = __dev_attr<::cudaDevAttrTextureAlignment>;
|
||||
static constexpr texture_alignment_t texture_alignment{};
|
||||
|
||||
// Pitch alignment requirement for 2D texture references bound to pitched memory
|
||||
using texture_pitch_alignment_t = __dev_attr<::cudaDevAttrTexturePitchAlignment>;
|
||||
static constexpr texture_pitch_alignment_t texture_pitch_alignment{};
|
||||
|
||||
// true if the device can concurrently copy memory between host and device
|
||||
// while executing a kernel, or false if not
|
||||
using gpu_overlap_t = __dev_attr<::cudaDevAttrGpuOverlap>;
|
||||
static constexpr gpu_overlap_t gpu_overlap{};
|
||||
|
||||
// Number of multiprocessors on the device
|
||||
using multiprocessor_count_t = __dev_attr<::cudaDevAttrMultiProcessorCount>;
|
||||
static constexpr multiprocessor_count_t multiprocessor_count{};
|
||||
|
||||
// true if there is a run time limit for kernels executed on the device, or
|
||||
// false if not
|
||||
using kernel_exec_timeout_t = __dev_attr<::cudaDevAttrKernelExecTimeout>;
|
||||
static constexpr kernel_exec_timeout_t kernel_exec_timeout{};
|
||||
|
||||
// true if the device is integrated with the memory subsystem, or false if not
|
||||
using integrated_t = __dev_attr<::cudaDevAttrIntegrated>;
|
||||
static constexpr integrated_t integrated{};
|
||||
|
||||
// true if the device can map host memory into CUDA address space
|
||||
using can_map_host_memory_t = __dev_attr<::cudaDevAttrCanMapHostMemory>;
|
||||
static constexpr can_map_host_memory_t can_map_host_memory{};
|
||||
|
||||
// Compute mode is the compute mode that the device is currently in.
|
||||
using compute_mode_t = __dev_attr<::cudaDevAttrComputeMode>;
|
||||
static constexpr compute_mode_t compute_mode{};
|
||||
|
||||
// true if the device supports executing multiple kernels within the same
|
||||
// context simultaneously, or false if not. It is not guaranteed that multiple
|
||||
// kernels will be resident on the device concurrently so this feature should
|
||||
// not be relied upon for correctness.
|
||||
using concurrent_kernels_t = __dev_attr<::cudaDevAttrConcurrentKernels>;
|
||||
static constexpr concurrent_kernels_t concurrent_kernels{};
|
||||
|
||||
// true if error correction is enabled on the device, 0 if error correction is
|
||||
// disabled or not supported by the device
|
||||
using ecc_enabled_t = __dev_attr<::cudaDevAttrEccEnabled>;
|
||||
static constexpr ecc_enabled_t ecc_enabled{};
|
||||
|
||||
// PCI bus identifier of the device
|
||||
using pci_bus_id_t = __dev_attr<::cudaDevAttrPciBusId>;
|
||||
static constexpr pci_bus_id_t pci_bus_id{};
|
||||
|
||||
// PCI device (also known as slot) identifier of the device
|
||||
using pci_device_id_t = __dev_attr<::cudaDevAttrPciDeviceId>;
|
||||
static constexpr pci_device_id_t pci_device_id{};
|
||||
|
||||
// true if the device is using a TCC driver. TCC is only available on Tesla
|
||||
// hardware running Windows Vista or later.
|
||||
using tcc_driver_t = __dev_attr<::cudaDevAttrTccDriver>;
|
||||
static constexpr tcc_driver_t tcc_driver{};
|
||||
|
||||
// Peak memory clock frequency in kilohertz
|
||||
using memory_clock_rate_t = __dev_attr<::cudaDevAttrMemoryClockRate>;
|
||||
static constexpr memory_clock_rate_t memory_clock_rate{};
|
||||
|
||||
// Global memory bus width in bits
|
||||
using global_memory_bus_width_t = __dev_attr<::cudaDevAttrGlobalMemoryBusWidth>;
|
||||
static constexpr global_memory_bus_width_t global_memory_bus_width{};
|
||||
|
||||
// Size of L2 cache in bytes. 0 if the device doesn't have L2 cache.
|
||||
using l2_cache_size_t = __dev_attr<::cudaDevAttrL2CacheSize>;
|
||||
static constexpr l2_cache_size_t l2_cache_size{};
|
||||
|
||||
// Maximum resident threads per multiprocessor
|
||||
using max_threads_per_multiprocessor_t = __dev_attr<::cudaDevAttrMaxThreadsPerMultiProcessor>;
|
||||
static constexpr max_threads_per_multiprocessor_t max_threads_per_multiprocessor{};
|
||||
|
||||
// true if the device shares a unified address space with the host, or false
|
||||
// if not
|
||||
using unified_addressing_t = __dev_attr<::cudaDevAttrUnifiedAddressing>;
|
||||
static constexpr unified_addressing_t unified_addressing{};
|
||||
|
||||
// Major compute capability version number
|
||||
using compute_capability_major_t = __dev_attr<::cudaDevAttrComputeCapabilityMajor>;
|
||||
static constexpr compute_capability_major_t compute_capability_major{};
|
||||
|
||||
// Minor compute capability version number
|
||||
using compute_capability_minor_t = __dev_attr<::cudaDevAttrComputeCapabilityMinor>;
|
||||
static constexpr compute_capability_minor_t compute_capability_minor{};
|
||||
|
||||
// true if the device supports stream priorities, or false if not
|
||||
using stream_priorities_supported_t = __dev_attr<::cudaDevAttrStreamPrioritiesSupported>;
|
||||
static constexpr stream_priorities_supported_t stream_priorities_supported{};
|
||||
|
||||
// true if device supports caching globals in L1 cache, false if not
|
||||
using global_l1_cache_supported_t = __dev_attr<::cudaDevAttrGlobalL1CacheSupported>;
|
||||
static constexpr global_l1_cache_supported_t global_l1_cache_supported{};
|
||||
|
||||
// true if device supports caching locals in L1 cache, false if not
|
||||
using local_l1_cache_supported_t = __dev_attr<::cudaDevAttrLocalL1CacheSupported>;
|
||||
static constexpr local_l1_cache_supported_t local_l1_cache_supported{};
|
||||
|
||||
// Maximum amount of shared memory available to a multiprocessor in bytes;
|
||||
// this amount is shared by all thread blocks simultaneously resident on a
|
||||
// multiprocessor
|
||||
using max_shared_memory_per_multiprocessor_t = __dev_attr<::cudaDevAttrMaxSharedMemoryPerMultiprocessor>;
|
||||
static constexpr max_shared_memory_per_multiprocessor_t max_shared_memory_per_multiprocessor{};
|
||||
|
||||
// Maximum number of 32-bit registers available to a multiprocessor; this
|
||||
// number is shared by all thread blocks simultaneously resident on a
|
||||
// multiprocessor
|
||||
using max_registers_per_multiprocessor_t = __dev_attr<::cudaDevAttrMaxRegistersPerMultiprocessor>;
|
||||
static constexpr max_registers_per_multiprocessor_t max_registers_per_multiprocessor{};
|
||||
|
||||
// true if device supports allocating managed memory, false if not
|
||||
using managed_memory_t = __dev_attr<::cudaDevAttrManagedMemory>;
|
||||
static constexpr managed_memory_t managed_memory{};
|
||||
|
||||
// true if device is on a multi-GPU board, false if not
|
||||
using is_multi_gpu_board_t = __dev_attr<::cudaDevAttrIsMultiGpuBoard>;
|
||||
static constexpr is_multi_gpu_board_t is_multi_gpu_board{};
|
||||
|
||||
// Unique identifier for a group of devices on the same multi-GPU board
|
||||
using multi_gpu_board_group_id_t = __dev_attr<::cudaDevAttrMultiGpuBoardGroupID>;
|
||||
static constexpr multi_gpu_board_group_id_t multi_gpu_board_group_id{};
|
||||
|
||||
// true if the link between the device and the host supports native atomic
|
||||
// operations
|
||||
using host_native_atomic_supported_t = __dev_attr<::cudaDevAttrHostNativeAtomicSupported>;
|
||||
static constexpr host_native_atomic_supported_t host_native_atomic_supported{};
|
||||
|
||||
// Ratio of single precision performance (in floating-point operations per
|
||||
// second) to double precision performance
|
||||
using single_to_double_precision_perf_ratio_t = __dev_attr<::cudaDevAttrSingleToDoublePrecisionPerfRatio>;
|
||||
static constexpr single_to_double_precision_perf_ratio_t single_to_double_precision_perf_ratio{};
|
||||
|
||||
// true if the device supports coherently accessing pageable memory without
|
||||
// calling cudaHostRegister on it, and false otherwise
|
||||
using pageable_memory_access_t = __dev_attr<::cudaDevAttrPageableMemoryAccess>;
|
||||
static constexpr pageable_memory_access_t pageable_memory_access{};
|
||||
|
||||
// true if the device can coherently access managed memory concurrently with
|
||||
// the CPU, and false otherwise
|
||||
using concurrent_managed_access_t = __dev_attr<::cudaDevAttrConcurrentManagedAccess>;
|
||||
static constexpr concurrent_managed_access_t concurrent_managed_access{};
|
||||
|
||||
// true if the device supports Compute Preemption, false if not
|
||||
using compute_preemption_supported_t = __dev_attr<::cudaDevAttrComputePreemptionSupported>;
|
||||
static constexpr compute_preemption_supported_t compute_preemption_supported{};
|
||||
|
||||
// true if the device can access host registered memory at the same virtual
|
||||
// address as the CPU, and false otherwise
|
||||
using can_use_host_pointer_for_registered_mem_t = __dev_attr<::cudaDevAttrCanUseHostPointerForRegisteredMem>;
|
||||
static constexpr can_use_host_pointer_for_registered_mem_t can_use_host_pointer_for_registered_mem{};
|
||||
|
||||
// true if the device supports launching cooperative kernels via
|
||||
// cudaLaunchCooperativeKernel, and false otherwise
|
||||
using cooperative_launch_t = __dev_attr<::cudaDevAttrCooperativeLaunch>;
|
||||
static constexpr cooperative_launch_t cooperative_launch{};
|
||||
|
||||
// true if the device supports flushing of outstanding remote writes, and
|
||||
// false otherwise
|
||||
using can_flush_remote_writes_t = __dev_attr<::cudaDevAttrCanFlushRemoteWrites>;
|
||||
static constexpr can_flush_remote_writes_t can_flush_remote_writes{};
|
||||
|
||||
// true if the device supports host memory registration via cudaHostRegister,
|
||||
// and false otherwise
|
||||
using host_register_supported_t = __dev_attr<::cudaDevAttrHostRegisterSupported>;
|
||||
static constexpr host_register_supported_t host_register_supported{};
|
||||
|
||||
// true if the device accesses pageable memory via the host's page tables, and
|
||||
// false otherwise
|
||||
using pageable_memory_access_uses_host_page_tables_t = __dev_attr<::cudaDevAttrPageableMemoryAccessUsesHostPageTables>;
|
||||
static constexpr pageable_memory_access_uses_host_page_tables_t pageable_memory_access_uses_host_page_tables{};
|
||||
|
||||
// true if the host can directly access managed memory on the device without
|
||||
// migration, and false otherwise
|
||||
using direct_managed_mem_access_from_host_t = __dev_attr<::cudaDevAttrDirectManagedMemAccessFromHost>;
|
||||
static constexpr direct_managed_mem_access_from_host_t direct_managed_mem_access_from_host{};
|
||||
|
||||
// Maximum per block shared memory size on the device. This value can be opted
|
||||
// into when using dynamic_shared_memory with NonPortableSize set to true
|
||||
using max_shared_memory_per_block_optin_t = __dev_attr<::cudaDevAttrMaxSharedMemoryPerBlockOptin>;
|
||||
static constexpr max_shared_memory_per_block_optin_t max_shared_memory_per_block_optin{};
|
||||
|
||||
// Maximum number of thread blocks that can reside on a multiprocessor
|
||||
using max_blocks_per_multiprocessor_t = __dev_attr<::cudaDevAttrMaxBlocksPerMultiprocessor>;
|
||||
static constexpr max_blocks_per_multiprocessor_t max_blocks_per_multiprocessor{};
|
||||
|
||||
// Maximum L2 persisting lines capacity setting in bytes
|
||||
using max_persisting_l2_cache_size_t = __dev_attr<::cudaDevAttrMaxPersistingL2CacheSize>;
|
||||
static constexpr max_persisting_l2_cache_size_t max_persisting_l2_cache_size{};
|
||||
|
||||
// Maximum value of cudaAccessPolicyWindow::num_bytes
|
||||
using max_access_policy_window_size_t = __dev_attr<::cudaDevAttrMaxAccessPolicyWindowSize>;
|
||||
static constexpr max_access_policy_window_size_t max_access_policy_window_size{};
|
||||
|
||||
// Shared memory reserved by CUDA driver per block in bytes
|
||||
using reserved_shared_memory_per_block_t = __dev_attr<::cudaDevAttrReservedSharedMemoryPerBlock>;
|
||||
static constexpr reserved_shared_memory_per_block_t reserved_shared_memory_per_block{};
|
||||
|
||||
// true if the device supports sparse CUDA arrays and sparse CUDA mipmapped arrays.
|
||||
using sparse_cuda_array_supported_t = __dev_attr<::cudaDevAttrSparseCudaArraySupported>;
|
||||
static constexpr sparse_cuda_array_supported_t sparse_cuda_array_supported{};
|
||||
|
||||
// Device supports using the cudaHostRegister flag cudaHostRegisterReadOnly to
|
||||
// register memory that must be mapped as read-only to the GPU
|
||||
using host_register_read_only_supported_t = __dev_attr<::cudaDevAttrHostRegisterReadOnlySupported>;
|
||||
static constexpr host_register_read_only_supported_t host_register_read_only_supported{};
|
||||
|
||||
// true if the device supports using the cudaMallocAsync and cudaMemPool
|
||||
// family of APIs, and false otherwise
|
||||
using memory_pools_supported_t = __dev_attr<::cudaDevAttrMemoryPoolsSupported>;
|
||||
static constexpr memory_pools_supported_t memory_pools_supported{};
|
||||
|
||||
// true if the device supports GPUDirect RDMA APIs, and false otherwise
|
||||
using gpu_direct_rdma_supported_t = __dev_attr<::cudaDevAttrGPUDirectRDMASupported>;
|
||||
static constexpr gpu_direct_rdma_supported_t gpu_direct_rdma_supported{};
|
||||
|
||||
// bitmask to be interpreted according to the
|
||||
// cudaFlushGPUDirectRDMAWritesOptions enum
|
||||
using gpu_direct_rdma_flush_writes_options_t = __dev_attr<::cudaDevAttrGPUDirectRDMAFlushWritesOptions>;
|
||||
static constexpr gpu_direct_rdma_flush_writes_options_t gpu_direct_rdma_flush_writes_options{};
|
||||
|
||||
// see the cudaGPUDirectRDMAWritesOrdering enum for numerical values
|
||||
using gpu_direct_rdma_writes_ordering_t = __dev_attr<::cudaDevAttrGPUDirectRDMAWritesOrdering>;
|
||||
static constexpr gpu_direct_rdma_writes_ordering_t gpu_direct_rdma_writes_ordering{};
|
||||
|
||||
// Bitmask of handle types supported with mempool based IPC
|
||||
using memory_pool_supported_handle_types_t = __dev_attr<::cudaDevAttrMemoryPoolSupportedHandleTypes>;
|
||||
static constexpr memory_pool_supported_handle_types_t memory_pool_supported_handle_types{};
|
||||
|
||||
// true if the device supports deferred mapping CUDA arrays and CUDA mipmapped
|
||||
// arrays.
|
||||
using deferred_mapping_cuda_array_supported_t = __dev_attr<::cudaDevAttrDeferredMappingCudaArraySupported>;
|
||||
static constexpr deferred_mapping_cuda_array_supported_t deferred_mapping_cuda_array_supported{};
|
||||
|
||||
// true if the device supports IPC Events, false otherwise.
|
||||
using ipc_event_support_t = __dev_attr<::cudaDevAttrIpcEventSupport>;
|
||||
static constexpr ipc_event_support_t ipc_event_support{};
|
||||
|
||||
# if _CCCL_CTK_AT_LEAST(12, 2)
|
||||
// NUMA configuration of a device: value is of type cudaDeviceNumaConfig enum
|
||||
using numa_config_t = __dev_attr<::cudaDevAttrNumaConfig>;
|
||||
static constexpr numa_config_t numa_config{};
|
||||
|
||||
// NUMA node ID of the GPU memory
|
||||
using numa_id_t = __dev_attr<::cudaDevAttrNumaId>;
|
||||
static constexpr numa_id_t numa_id{};
|
||||
# endif // _CCCL_CTK_AT_LEAST(12, 2)
|
||||
|
||||
# if _CCCL_CTK_AT_LEAST(12, 9)
|
||||
using host_numa_memory_pools_supported_t = __dev_attr<::cudaDevAttrHostNumaMemoryPoolsSupported>;
|
||||
static constexpr host_numa_memory_pools_supported_t host_numa_memory_pools_supported{};
|
||||
# endif // ^^^ _CCCL_CTK_AT_LEAST(12, 9) ^^^
|
||||
|
||||
# if _CCCL_CTK_AT_LEAST(13, 0)
|
||||
using host_memory_pools_supported_t = __dev_attr<::cudaDevAttrHostMemoryPoolsSupported>;
|
||||
static constexpr host_memory_pools_supported_t host_memory_pools_supported{};
|
||||
# endif // ^^^ _CCCL_CTK_AT_LEAST(13, 0) ^^^
|
||||
|
||||
// Total global memory available on the device in bytes
|
||||
struct total_global_memory_t
|
||||
{
|
||||
using type = ::cuda::std::size_t;
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_API type operator()(device_ref __dev) const
|
||||
{
|
||||
return ::cuda::__driver::__deviceTotalMem(__dev.get());
|
||||
}
|
||||
};
|
||||
static constexpr total_global_memory_t total_global_memory{};
|
||||
|
||||
// Combines major and minor compute capability in a 100 * major + 10 * minor format, allows to query full compute
|
||||
// capability in a single query
|
||||
struct compute_capability_t
|
||||
{
|
||||
using type = ::cuda::compute_capability;
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_API type operator()(device_ref __dev_id) const
|
||||
{
|
||||
return type{::cuda::device_attributes::compute_capability_major(__dev_id),
|
||||
::cuda::device_attributes::compute_capability_minor(__dev_id)};
|
||||
}
|
||||
};
|
||||
static constexpr compute_capability_t compute_capability{};
|
||||
} // namespace device_attributes
|
||||
|
||||
//! @brief For a given attribute, type of the attribute value.
|
||||
//!
|
||||
//! @par Example
|
||||
//! @code
|
||||
//! using threads_per_block_t = device::attr_result_t<device_attributes::max_threads_per_block>;
|
||||
//! static_assert(std::is_same_v<threads_per_block_t, int>);
|
||||
//! @endcode
|
||||
//!
|
||||
//! @sa device_attributes
|
||||
template <::cudaDeviceAttr _Attr>
|
||||
using device_attribute_result_t = typename __dev_attr<_Attr>::type;
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA
|
||||
|
||||
# include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CCCL_HAS_CTK() && !_CCCL_COMPILER(NVRTC)
|
||||
|
||||
#endif // _CUDA___DEVICE_ATTRIBUTES_H
|
||||
@@ -0,0 +1,272 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of libcu++, the C++ Standard Library for your entire system,
|
||||
// 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) 2025 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA___DEVICE_COMPUTE_CAPABILITY_H
|
||||
#define _CUDA___DEVICE_COMPUTE_CAPABILITY_H
|
||||
|
||||
#include <cuda/std/detail/__config>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#include <cuda/__fwd/devices.h>
|
||||
#include <cuda/std/__fwd/format.h>
|
||||
#include <cuda/std/__type_traits/always_false.h>
|
||||
#include <cuda/std/__utility/to_underlying.h>
|
||||
#include <cuda/std/array>
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA
|
||||
|
||||
//! @brief Type representing the CUDA compute capability.
|
||||
class compute_capability
|
||||
{
|
||||
public:
|
||||
int __cc_{}; //!< The stored compute capability in format 10 * major + minor.
|
||||
|
||||
_CCCL_HIDE_FROM_ABI constexpr compute_capability() noexcept = default;
|
||||
|
||||
//! @brief Constructs the object from compute capability \c __cc. The expected format is 10 * major + minor.
|
||||
//!
|
||||
//! @param __cc Compute capability.
|
||||
_CCCL_HOST_DEVICE_API explicit constexpr compute_capability(int __cc) noexcept
|
||||
: __cc_{__cc}
|
||||
{}
|
||||
|
||||
//! @brief Constructs the object by combining the \c __major and \c __minor compute capability.
|
||||
//!
|
||||
//! @param __major The major compute capability.
|
||||
//! @param __minor The minor compute capability. Must be less than 10.
|
||||
_CCCL_HOST_DEVICE_API constexpr compute_capability(int __major, int __minor) noexcept
|
||||
: __cc_{10 * __major + __minor}
|
||||
{
|
||||
_CCCL_ASSERT(__minor < 10, "invalid minor compute capability");
|
||||
}
|
||||
|
||||
//! @brief Constructs the object from the architecture id.
|
||||
//!
|
||||
//! @param __arch_id The architecture id.
|
||||
_CCCL_HOST_DEVICE_API explicit constexpr compute_capability(arch_id __arch_id) noexcept
|
||||
{
|
||||
const auto __val = ::cuda::std::to_underlying(__arch_id);
|
||||
if (__val > __arch_specific_id_multiplier)
|
||||
{
|
||||
__cc_ = __val / __arch_specific_id_multiplier;
|
||||
}
|
||||
else
|
||||
{
|
||||
__cc_ = __val;
|
||||
}
|
||||
}
|
||||
|
||||
_CCCL_HIDE_FROM_ABI constexpr compute_capability(const compute_capability&) noexcept = default;
|
||||
|
||||
_CCCL_HIDE_FROM_ABI constexpr compute_capability& operator=(const compute_capability& __other) noexcept = default;
|
||||
|
||||
//! @brief Gets the stored compute capability.
|
||||
//!
|
||||
//! @return The stored compute capability in format 10 * major + minor.
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr int get() const noexcept
|
||||
{
|
||||
return __cc_;
|
||||
}
|
||||
|
||||
//! @brief Gets the major compute capability.
|
||||
//!
|
||||
//! @return Major compute capability.
|
||||
//!
|
||||
//! @deprecated This symbol is deprecated because it collides with major(...) macro defined in <sys/sysmacros.h> and
|
||||
//! will be removed in next major release. Use cc.major_cap() instead.
|
||||
[[nodiscard]]
|
||||
CCCL_DEPRECATED_BECAUSE("This symbol is deprecated because it collides with major(...) macro defined in "
|
||||
"<sys/sysmacros.h> and will be removed in next major release. Use cc.major_cap() instead.")
|
||||
_CCCL_HOST_DEVICE_API constexpr int major() const noexcept
|
||||
{
|
||||
return major_cap();
|
||||
}
|
||||
|
||||
//! @brief Gets the major compute capability.
|
||||
//!
|
||||
//! @return Major compute capability.
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr int major_cap() const noexcept
|
||||
{
|
||||
return __cc_ / 10;
|
||||
}
|
||||
|
||||
//! @brief Gets the minor compute capability.
|
||||
//!
|
||||
//! @return Minor compute capability. The value is always less than 10.
|
||||
//!
|
||||
//! @deprecated This symbol is deprecated because it collides with minor(...) macro defined in <sys/sysmacros.h> and
|
||||
//! will be removed in next major release. Use cc.minor_cap() instead.
|
||||
[[nodiscard]]
|
||||
CCCL_DEPRECATED_BECAUSE("This symbol is deprecated because it collides with minor(...) macro defined in "
|
||||
"<sys/sysmacros.h> and will be removed in next major release. Use cc.minor_cap() instead.")
|
||||
_CCCL_HOST_DEVICE_API constexpr int minor() const noexcept
|
||||
{
|
||||
return minor_cap();
|
||||
}
|
||||
|
||||
//! @brief Gets the minor compute capability.
|
||||
//!
|
||||
//! @return Minor compute capability. The value is always less than 10.
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API constexpr int minor_cap() const noexcept
|
||||
{
|
||||
return __cc_ % 10;
|
||||
}
|
||||
|
||||
//! @brief Conversion operator to \c int.
|
||||
//!
|
||||
//! @return The stored compute capability in format 10 * major + minor.
|
||||
_CCCL_HOST_DEVICE_API explicit constexpr operator int() const noexcept
|
||||
{
|
||||
return __cc_;
|
||||
}
|
||||
|
||||
//! @brief Equality operator.
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API friend constexpr bool
|
||||
operator==(compute_capability __lhs, compute_capability __rhs) noexcept
|
||||
{
|
||||
return __lhs.__cc_ == __rhs.__cc_;
|
||||
}
|
||||
|
||||
//! @brief Inequality operator.
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API friend constexpr bool
|
||||
operator!=(compute_capability __lhs, compute_capability __rhs) noexcept
|
||||
{
|
||||
return __lhs.__cc_ != __rhs.__cc_;
|
||||
}
|
||||
|
||||
//! @brief Less than operator.
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API friend constexpr bool
|
||||
operator<(compute_capability __lhs, compute_capability __rhs) noexcept
|
||||
{
|
||||
return __lhs.__cc_ < __rhs.__cc_;
|
||||
}
|
||||
|
||||
//! @brief Less than or equal to operator.
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API friend constexpr bool
|
||||
operator<=(compute_capability __lhs, compute_capability __rhs) noexcept
|
||||
{
|
||||
return __lhs.__cc_ <= __rhs.__cc_;
|
||||
}
|
||||
|
||||
//! @brief Greater than operator.
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API friend constexpr bool
|
||||
operator>(compute_capability __lhs, compute_capability __rhs) noexcept
|
||||
{
|
||||
return __lhs.__cc_ > __rhs.__cc_;
|
||||
}
|
||||
|
||||
//! @brief Greater than or equal to operator.
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API friend constexpr bool
|
||||
operator>=(compute_capability __lhs, compute_capability __rhs) noexcept
|
||||
{
|
||||
return __lhs.__cc_ >= __rhs.__cc_;
|
||||
}
|
||||
};
|
||||
|
||||
template <int... _Vs>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API _CCCL_CONSTEVAL auto __make_all_compute_capabilities() noexcept
|
||||
{
|
||||
return ::cuda::std::array{compute_capability{_Vs}...};
|
||||
}
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API _CCCL_CONSTEVAL auto __all_compute_capabilities() noexcept
|
||||
{
|
||||
return ::cuda::__make_all_compute_capabilities<_CCCL_KNOWN_CUDA_ARCH_LIST>();
|
||||
}
|
||||
|
||||
#if _CCCL_CUDA_COMPILATION()
|
||||
template <int... _Vs>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API _CCCL_CONSTEVAL auto __make_cc_list() noexcept
|
||||
{
|
||||
# if defined(__CUDA_ARCH_LIST__)
|
||||
return ::cuda::std::array{compute_capability{_Vs / 10}...};
|
||||
# elif defined(NV_TARGET_SM_INTEGER_LIST)
|
||||
return ::cuda::std::array{compute_capability{_Vs}...};
|
||||
# else // ^^^ has arch list ^^^ / vvv no arch list vvv
|
||||
static_assert(::cuda::std::__always_false_v<decltype(sizeof...(_Vs))>,
|
||||
"This function can be instantiated only when __CUDA_ARCH_LIST__ or NV_TARGET_SM_INTEGER_LIST are "
|
||||
"defined");
|
||||
# endif // ^^^ no arch list ^^^
|
||||
}
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API _CCCL_CONSTEVAL auto __target_compute_capabilities() noexcept
|
||||
{
|
||||
# if defined(__CUDA_ARCH_LIST__)
|
||||
return ::cuda::__make_cc_list<__CUDA_ARCH_LIST__>();
|
||||
# elif defined(NV_TARGET_SM_INTEGER_LIST)
|
||||
return ::cuda::__make_cc_list<NV_TARGET_SM_INTEGER_LIST>();
|
||||
# else // ^^^ has arch list ^^^ / vvv no arch list vvv
|
||||
// Fallback to a list of all compute capabilities.
|
||||
return ::cuda::__all_compute_capabilities();
|
||||
# endif // ^^^ no arch list ^^^
|
||||
}
|
||||
#endif // _CCCL_CUDA_COMPILATION()
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA
|
||||
|
||||
#if __cpp_lib_format >= 201907L
|
||||
_CCCL_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _CharT>
|
||||
struct formatter<::cuda::compute_capability, _CharT> : private formatter<int, _CharT>
|
||||
{
|
||||
template <class _ParseCtx>
|
||||
_CCCL_HOST_API constexpr auto parse(_ParseCtx& __ctx)
|
||||
{
|
||||
return __ctx.begin();
|
||||
}
|
||||
|
||||
template <class _FmtCtx>
|
||||
_CCCL_HOST_API auto format(const ::cuda::compute_capability& __cc, _FmtCtx& __ctx) const
|
||||
{
|
||||
return formatter<int, _CharT>::format(__cc.get(), __ctx);
|
||||
}
|
||||
};
|
||||
|
||||
_CCCL_END_NAMESPACE_STD
|
||||
#endif // __cpp_lib_format >= 201907L
|
||||
|
||||
// todo: specialize cuda::std::formatter for cuda::compute_capability
|
||||
|
||||
#if _CCCL_CUDA_COMPILATION()
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_DEVICE
|
||||
|
||||
//! @brief Returns the \c cuda::compute_capability that is currently being compiled.
|
||||
//!
|
||||
//! @note This API cannot be used in constexpr context when compiling with nvc++ in CUDA mode.
|
||||
[[nodiscard]] _CCCL_DEVICE_API inline _CCCL_TARGET_CONSTEXPR ::cuda::compute_capability
|
||||
current_compute_capability() noexcept
|
||||
{
|
||||
# if _CCCL_CUDA_COMPILER(NVHPC)
|
||||
return ::cuda::compute_capability{__builtin_current_device_sm()};
|
||||
# elif _CCCL_DEVICE_COMPILATION()
|
||||
return ::cuda::compute_capability{__CUDA_ARCH__ / 10};
|
||||
# else // ^^^ _CCCL_DEVICE_COMPILATION() ^^^ / vvv !_CCCL_DEVICE_COMPILATION() vvv
|
||||
return {};
|
||||
# endif // ^^^ !_CCCL_DEVICE_COMPILATION() ^^^
|
||||
}
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_DEVICE
|
||||
|
||||
#endif // _CCCL_CUDA_COMPILATION()
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA___DEVICE_COMPUTE_CAPABILITY_H
|
||||
181
cccl_upstream/libcudacxx/include/cuda/__device/device_ref.h
Normal file
181
cccl_upstream/libcudacxx/include/cuda/__device/device_ref.h
Normal file
@@ -0,0 +1,181 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of libcu++, the C++ Standard Library for your entire system,
|
||||
// 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) 2026 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA___DEVICE_DEVICE_REF_H
|
||||
#define _CUDA___DEVICE_DEVICE_REF_H
|
||||
|
||||
#include <cuda/std/detail/__config>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#if _CCCL_HAS_CTK() && !_CCCL_COMPILER(NVRTC)
|
||||
|
||||
# include <cuda/__driver/driver_api.h>
|
||||
# include <cuda/__fwd/devices.h>
|
||||
# include <cuda/__runtime/types.h>
|
||||
# include <cuda/std/span>
|
||||
# include <cuda/std/string_view>
|
||||
|
||||
# include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA
|
||||
|
||||
_CCCL_DIAG_PUSH
|
||||
_CCCL_DIAG_SUPPRESS_CLANG("-Wmissing-braces")
|
||||
// clang complains about missing braces in CUmemLocation constructor but GCC complains if we add them
|
||||
|
||||
::cuda::std::size_t __physical_devices_count();
|
||||
|
||||
//! @brief A non-owning representation of a CUDA device
|
||||
class device_ref
|
||||
{
|
||||
int __id_ = 0;
|
||||
|
||||
public:
|
||||
//! @brief Create a `device_ref` object from a native device ordinal.
|
||||
/*implicit*/ _CCCL_HOST_API constexpr device_ref(int __id)
|
||||
: __id_(__id)
|
||||
{
|
||||
_CCCL_IF_CONSTEVAL_DEFAULT
|
||||
{
|
||||
_CCCL_VERIFY(__id >= 0, "Device ID must be a valid GPU device ordinal");
|
||||
}
|
||||
else
|
||||
{
|
||||
_CCCL_VERIFY(__id >= 0 && static_cast<::cuda::std::size_t>(__id) < ::cuda::__physical_devices_count(),
|
||||
"Device ID must be a valid GPU device ordinal");
|
||||
}
|
||||
}
|
||||
|
||||
//! @brief Retrieve the native ordinal of the `device_ref`
|
||||
//!
|
||||
//! @return int The native device ordinal held by the `device_ref` object
|
||||
[[nodiscard]] _CCCL_HOST_API constexpr int get() const noexcept
|
||||
{
|
||||
return __id_;
|
||||
}
|
||||
|
||||
//! @brief Compares two `device_ref`s for equality
|
||||
//!
|
||||
//! @note Allows comparison with `int` due to implicit conversion to
|
||||
//! `device_ref`.
|
||||
//!
|
||||
//! @param __lhs The first `device_ref` to compare
|
||||
//! @param __rhs The second `device_ref` to compare
|
||||
//! @return true if `lhs` and `rhs` refer to the same device ordinal
|
||||
[[nodiscard]] friend _CCCL_HOST_API constexpr bool operator==(device_ref __lhs, device_ref __rhs) noexcept
|
||||
{
|
||||
return __lhs.__id_ == __rhs.__id_;
|
||||
}
|
||||
|
||||
# if _CCCL_STD_VER <= 2017
|
||||
//! @brief Compares two `device_ref`s for inequality
|
||||
//!
|
||||
//! @note Allows comparison with `int` due to implicit conversion to
|
||||
//! `device_ref`.
|
||||
//!
|
||||
//! @param __lhs The first `device_ref` to compare
|
||||
//! @param __rhs The second `device_ref` to compare
|
||||
//! @return true if `lhs` and `rhs` refer to different device ordinal
|
||||
[[nodiscard]] friend _CCCL_HOST_API constexpr bool operator!=(device_ref __lhs, device_ref __rhs) noexcept
|
||||
{
|
||||
return __lhs.__id_ != __rhs.__id_;
|
||||
}
|
||||
# endif // _CCCL_STD_VER <= 2017
|
||||
|
||||
//! @brief Retrieve the specified attribute for the device
|
||||
//!
|
||||
//! @param __attr The attribute to query. See `device::attrs` for the available
|
||||
//! attributes.
|
||||
//!
|
||||
//! @throws cuda_error if the attribute query fails
|
||||
//!
|
||||
//! @sa device::attrs
|
||||
template <typename _Attr>
|
||||
[[nodiscard]] _CCCL_HOST_API auto attribute(_Attr __attr) const
|
||||
{
|
||||
return __attr(*this);
|
||||
}
|
||||
|
||||
//! @overload
|
||||
template <::cudaDeviceAttr _Attr>
|
||||
[[nodiscard]] _CCCL_HOST_API auto attribute() const
|
||||
{
|
||||
return attribute(__dev_attr<_Attr>());
|
||||
}
|
||||
|
||||
//! @brief Retrieve the memory location of this device
|
||||
//!
|
||||
//! @return The memory location of this device
|
||||
[[nodiscard]] _CCCL_HOST_API operator memory_location() const noexcept
|
||||
{
|
||||
return memory_location{::cudaMemLocationTypeDevice, get()};
|
||||
}
|
||||
|
||||
//! @brief Initializes the primary context of the device.
|
||||
_CCCL_HOST_API void init() const; // implemented in <cuda/__device/physical_device.h> to avoid circular dependency
|
||||
|
||||
//! @brief Retrieve the primary context of this device.
|
||||
//!
|
||||
//! @return The primary CUDA context for this device.
|
||||
[[nodiscard]] _CCCL_HOST_API ::CUcontext __primary_context() const; // implemented in
|
||||
// <cuda/__device/physical_device.h> to avoid
|
||||
// circular dependency
|
||||
|
||||
//! @brief Retrieve the name of this device.
|
||||
//!
|
||||
//! @return String view containing the name of this device.
|
||||
[[nodiscard]] _CCCL_HOST_API ::cuda::std::string_view name() const; // implemented in
|
||||
// <cuda/__device/physical_device.h> to avoid
|
||||
// circular dependency
|
||||
|
||||
//! @brief Queries if its possible for this device to directly access specified device's memory.
|
||||
//!
|
||||
//! If this function returns true, device supplied to this call can be passed into enable_peer_access
|
||||
//! on memory resource or pool that manages memory on this device. It will make allocations from that
|
||||
//! pool accessible by this device.
|
||||
//!
|
||||
//! @param __other_dev Device to query the peer access
|
||||
//! @return true if its possible for this device to access the specified device's memory
|
||||
[[nodiscard]] _CCCL_HOST_API bool has_peer_access_to(device_ref __other_dev) const
|
||||
{
|
||||
return ::cuda::__driver::__deviceCanAccessPeer(
|
||||
::cuda::__driver::__deviceGet(get()), ::cuda::__driver::__deviceGet(__other_dev.get()));
|
||||
}
|
||||
|
||||
// TODO this might return some more complex type in the future
|
||||
// TODO we might want to include the calling device, depends on what we decide
|
||||
// peer access APIs
|
||||
|
||||
//! @brief Retrieve `device_ref`s that are peers of this device
|
||||
//!
|
||||
//! The device on which this API is called is not included in the vector.
|
||||
//!
|
||||
//! @throws cuda_error if any peer access query fails
|
||||
[[nodiscard]] _CCCL_HOST_API ::cuda::std::span<const device_ref> peers() const; // implemented in
|
||||
// <cuda/__device/physical_device.h>
|
||||
// to avoid circular dependency
|
||||
};
|
||||
|
||||
_CCCL_DIAG_POP
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA
|
||||
|
||||
# include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CCCL_HAS_CTK() && !_CCCL_COMPILER(NVRTC)
|
||||
|
||||
#endif // _CUDA___DEVICE_DEVICE_REF_H
|
||||
227
cccl_upstream/libcudacxx/include/cuda/__device/physical_device.h
Normal file
227
cccl_upstream/libcudacxx/include/cuda/__device/physical_device.h
Normal file
@@ -0,0 +1,227 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of libcu++, the C++ Standard Library for your entire system,
|
||||
// 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) 2026 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA___DEVICE_PHYSICAL_DEVICE_H
|
||||
#define _CUDA___DEVICE_PHYSICAL_DEVICE_H
|
||||
|
||||
#include <cuda/std/detail/__config>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#if _CCCL_HAS_CTK() && !_CCCL_COMPILER(NVRTC)
|
||||
|
||||
# include <cuda/__device/device_ref.h>
|
||||
# include <cuda/__driver/driver_api.h>
|
||||
# include <cuda/__fwd/devices.h>
|
||||
# include <cuda/std/__cstddef/types.h>
|
||||
# include <cuda/std/__memory/unique_ptr.h>
|
||||
# include <cuda/std/cassert>
|
||||
# include <cuda/std/span>
|
||||
# include <cuda/std/string_view>
|
||||
|
||||
# if _CCCL_HOSTED()
|
||||
# include <mutex>
|
||||
# endif // _CCCL_HOSTED()
|
||||
|
||||
# include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA
|
||||
|
||||
[[nodiscard]] inline ::cuda::std::span<__physical_device> __physical_devices();
|
||||
|
||||
// This is the element type of the the global `devices` array. In the future, we
|
||||
// can cache device properties here.
|
||||
//
|
||||
//! @brief An immovable "owning" representation of a CUDA device.
|
||||
class __physical_device
|
||||
{
|
||||
friend _CCCL_HOST_API inline ::cuda::std::unique_ptr<__physical_device[]>
|
||||
__make_physical_devices(::cuda::std::size_t __device_count);
|
||||
|
||||
::CUdevice __device_{};
|
||||
|
||||
# if _CCCL_HOSTED()
|
||||
::std::once_flag __primary_ctx_once_flag_{};
|
||||
# endif // _CCCL_HOSTED()
|
||||
::CUcontext __primary_ctx_{};
|
||||
|
||||
static constexpr ::cuda::std::size_t __max_name_length{256};
|
||||
# if _CCCL_HOSTED()
|
||||
::std::once_flag __name_once_flag_{};
|
||||
# endif // _CCCL_HOSTED()
|
||||
char __name_[__max_name_length]{};
|
||||
::cuda::std::size_t __name_length_{};
|
||||
|
||||
# if _CCCL_HOSTED()
|
||||
::std::once_flag __peers_once_flag_{};
|
||||
# endif // _CCCL_HOSTED()
|
||||
::cuda::std::unique_ptr<device_ref[]> __peers_{};
|
||||
::cuda::std::size_t __num_peers_{};
|
||||
|
||||
_CCCL_HOST_API void __set_name()
|
||||
{
|
||||
const auto __id = ::cuda::__driver::__cudevice_to_ordinal(__device_);
|
||||
::cuda::__driver::__deviceGetName(__name_, __max_name_length, __id);
|
||||
__name_length_ = ::cuda::std::char_traits<char>::length(__name_);
|
||||
}
|
||||
|
||||
_CCCL_HOST_API void __set_peers()
|
||||
{
|
||||
const auto __count = static_cast<int>(::cuda::__physical_devices().size());
|
||||
const auto __id = ::cuda::__driver::__cudevice_to_ordinal(__device_);
|
||||
|
||||
// This overallocates, but given that we are talking about `device_ref` this is fine
|
||||
__peers_.reset(static_cast<device_ref*>(::operator new[](sizeof(device_ref) * __count)));
|
||||
size_t __num_peers = 0;
|
||||
for (int __other_id = 0; __other_id < __count; ++__other_id)
|
||||
{
|
||||
// Exclude the device this API is called on. The main use case for this API
|
||||
// is enable/disable peer access. While enable peer access can be called on
|
||||
// device on which memory resides, disable peer access will error-out.
|
||||
// Usage of the peer access control is smoother when *this is excluded,
|
||||
// while it can be easily added with .push_back() on the vector if a full
|
||||
// group of peers is needed (for cases other than peer access control)
|
||||
if (__other_id != __id)
|
||||
{
|
||||
device_ref __dev{__id};
|
||||
device_ref __other_dev{__other_id};
|
||||
|
||||
// While in almost all practical applications peer access should be symmetrical,
|
||||
// it is possible to build a system with one directional peer access, check
|
||||
// both ways here just to be safe
|
||||
if (__dev.has_peer_access_to(__other_dev) && __other_dev.has_peer_access_to(__dev))
|
||||
{
|
||||
__peers_[__num_peers] = __other_dev;
|
||||
++__num_peers;
|
||||
}
|
||||
}
|
||||
}
|
||||
__num_peers_ = __num_peers;
|
||||
}
|
||||
|
||||
public:
|
||||
_CCCL_HIDE_FROM_ABI __physical_device() = default;
|
||||
|
||||
_CCCL_HOST_API ~__physical_device()
|
||||
{
|
||||
if (__primary_ctx_ != nullptr)
|
||||
{
|
||||
[[maybe_unused]] const auto __ignore = ::cuda::__driver::__primaryCtxReleaseNoThrow(__device_);
|
||||
}
|
||||
}
|
||||
|
||||
//! @brief Retrieve the primary context for this device.
|
||||
//!
|
||||
//! @return A reference to the primary context for this device.
|
||||
[[nodiscard]] _CCCL_HOST_API ::CUcontext __primary_context()
|
||||
{
|
||||
# if _CCCL_HOSTED()
|
||||
::std::call_once(__primary_ctx_once_flag_, [this]() {
|
||||
__primary_ctx_ = ::cuda::__driver::__primaryCtxRetain(__device_);
|
||||
});
|
||||
# else // ^^^ _CCCL_HOSTED() ^^^ / vvv _CCCL_FREESTANDING() vvv
|
||||
if (!__primary_ctx_)
|
||||
{
|
||||
__primary_ctx_ = ::cuda::__driver::__primaryCtxRetain(__device_);
|
||||
}
|
||||
# endif // _CCCL_FREESTANDING()
|
||||
return __primary_ctx_;
|
||||
}
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_API ::cuda::std::string_view __name()
|
||||
{
|
||||
# if _CCCL_HOSTED()
|
||||
::std::call_once(__name_once_flag_, [this]() {
|
||||
this->__set_name();
|
||||
});
|
||||
# else // ^^^ _CCCL_HOSTED() ^^^ / vvv _CCCL_FREESTANDING() vvv
|
||||
if (__name_length_ != 0)
|
||||
{
|
||||
this->__set_name();
|
||||
}
|
||||
# endif // _CCCL_FREESTANDING()
|
||||
return ::cuda::std::string_view{__name_, __name_length_};
|
||||
}
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_API ::cuda::std::span<const device_ref> __peers()
|
||||
{
|
||||
# if _CCCL_HOSTED()
|
||||
::std::call_once(__peers_once_flag_, [this]() {
|
||||
this->__set_peers();
|
||||
});
|
||||
# else // ^^^ _CCCL_HOSTED() ^^^ / vvv _CCCL_FREESTANDING() vvv
|
||||
if (!__peers_)
|
||||
{
|
||||
this->__set_peers();
|
||||
}
|
||||
# endif // _CCCL_FREESTANDING()
|
||||
return ::cuda::std::span<const device_ref>{__peers_.get(), __num_peers_};
|
||||
}
|
||||
};
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_API inline ::cuda::std::unique_ptr<__physical_device[]>
|
||||
__make_physical_devices(::cuda::std::size_t __device_count)
|
||||
{
|
||||
::cuda::std::unique_ptr<__physical_device[]> __devices{::new __physical_device[__device_count]};
|
||||
for (::cuda::std::size_t __i = 0; __i < __device_count; ++__i)
|
||||
{
|
||||
__devices[__i].__device_ = static_cast<int>(__i);
|
||||
}
|
||||
return __devices;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline ::cuda::std::size_t __physical_devices_count()
|
||||
{
|
||||
static const auto __device_count = static_cast<::cuda::std::size_t>(::cuda::__driver::__deviceGetCount());
|
||||
return __device_count;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline ::cuda::std::span<__physical_device> __physical_devices()
|
||||
{
|
||||
static const auto __device_count = __physical_devices_count();
|
||||
static const auto __devices = ::cuda::__make_physical_devices(__device_count);
|
||||
return ::cuda::std::span<__physical_device>{__devices.get(), __device_count};
|
||||
}
|
||||
|
||||
// device_ref methods dependent on __physical_device
|
||||
|
||||
_CCCL_HOST_API inline void device_ref::init() const
|
||||
{
|
||||
(void) ::cuda::__physical_devices()[__id_].__primary_context();
|
||||
}
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_API inline ::CUcontext device_ref::__primary_context() const
|
||||
{
|
||||
return ::cuda::__physical_devices()[__id_].__primary_context();
|
||||
}
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_API inline ::cuda::std::string_view device_ref::name() const
|
||||
{
|
||||
return ::cuda::__physical_devices()[__id_].__name();
|
||||
}
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_API inline ::cuda::std::span<const device_ref> device_ref::peers() const
|
||||
{
|
||||
return ::cuda::__physical_devices()[__id_].__peers();
|
||||
}
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA
|
||||
|
||||
# include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CCCL_HAS_CTK() && !_CCCL_COMPILER(NVRTC)
|
||||
|
||||
#endif // _CUDA___DEVICE_PHYSICAL_DEVICE_H
|
||||
Reference in New Issue
Block a user