46 template <
class OtherElement>
47 requires(std::is_const_v<element_type> && !std::is_const_v<OtherElement> &&
48 std::same_as<std::remove_const_t<OtherElement>,
value_type>)
50 : buffer_(other.buffer_), offset_(other.offset_)
54 [[nodiscard]]
explicit constexpr operator bool() const noexcept {
return buffer_ !=
nullptr; }
59 CHECK(buffer_ !=
nullptr,
"cannot resolve an empty CUDA buffer view");
64 [[nodiscard]]
constexpr std::size_t
element_offset() const noexcept {
return offset_; }
71 result.offset_ += offset;
78 using buffer_pointer = std::add_pointer_t<std::remove_reference_t<buffer_reference>>;
80 buffer_pointer buffer_ =
nullptr;
81 std::size_t offset_ = 0;
97inline constexpr bool has_zero_object_representation_v = [] {
99 if constexpr (std::same_as<T, uni20::float128>)
return true;
101 return std::is_arithmetic_v<T>;
105inline constexpr bool has_zero_object_representation_v<uni20::detail::standard_complex<Real>> =
106 has_zero_object_representation_v<Real>;
108template <
class Descriptor>
struct IsCudaBufferView : std::false_type
111template <
class ElementType>
struct IsCudaBufferView<CudaBufferView<ElementType>> : std::true_type
119 typename std::remove_cvref_t<Span>::data_descriptor_type;
120} && detail::IsCudaBufferView<typename std::remove_cvref_t<Span>::data_descriptor_type>
::value;
128struct CudaAccessorFactory
130 template <
class ElementType>
using accessor_t = CudaPointerAccessor<ElementType>;
131 template <
class ElementType>
using device_accessor_t = CudaPointerAccessor<ElementType>;
133 template <
class ElementType,
class Storage>
134 [[nodiscard]]
constexpr auto make_accessor(Storage
const&)
const noexcept -> accessor_t<ElementType>
136 return accessor_t<ElementType>{};
139 template <
class ElementType,
class Storage>
140 [[nodiscard]]
constexpr auto make_device_accessor(Storage
const&)
const noexcept -> device_accessor_t<ElementType>
142 return device_accessor_t<ElementType>{};
170#if UNI20_BACKEND_CUSOLVER && UNI20_BACKEND_CUBLAS
173#elif UNI20_BACKEND_CUSOLVER
175#elif UNI20_BACKEND_CUBLAS
184 template <
class ElementType>
185 [[nodiscard]]
static auto
192 template <
class ElementType>
193 [[nodiscard]]
static auto
198 initialize_storage(result, initialization);
202 template <
class ElementType>
203 [[nodiscard]]
static auto
210 template <
class ElementType>
215 return make_storage<ElementType>(storage.resources(), size, initialization);
218 template <
class ElementType>
220 std::size_t size, std::span<std::size_t const> offsets,
226 template <
class ElementType>
228 cuda::Device device, std::size_t size, std::span<std::size_t const> offsets,
231 return make_packed_storage<ElementType>(
cuda::device_resources(device.ordinal()), size, offsets, initialization);
234 template <
class ElementType>
236 context_type& context, std::size_t size, std::span<std::size_t const> offsets,
239 std::vector<cuda::CudaBufferRange> ranges;
240 if (!offsets.empty())
243 ranges.reserve(offsets.size() - 1);
244 for (std::size_t ordinal = 0; ordinal + 1 < offsets.size(); ++ordinal)
249 initialize_storage(result, initialization);
253 template <
class ElementType>
258 return make_packed_storage<ElementType>(storage.resources(), size, offsets, initialization);
262 template <
class ElementType>
265 return storage.resources();
271 template <RealOrComplex ElementType>
273 std::span<std::size_t const> block_ends)
275 CHECK_EQUAL(offsets.size(), block_ends.size() + 1);
276 bool has_padding =
false;
277 for (std::size_t ordinal = 0; ordinal < block_ends.size(); ++ordinal)
279 CHECK(block_ends[ordinal] <= offsets[ordinal + 1], block_ends[ordinal], offsets[ordinal + 1]);
280 has_padding = has_padding || block_ends[ordinal] != offsets[ordinal + 1];
282 if (!has_padding)
return;
287 for (std::size_t ordinal = 0; ordinal < block_ends.size(); ++ordinal)
289 auto const padding_size = offsets[ordinal + 1] - block_ends[ordinal];
290 if (padding_size == 0)
continue;
291 cuda::check(cudaMemsetAsync(access.data() + block_ends[ordinal], 0, padding_size *
sizeof(ElementType),
292 stream.native_handle()),
293 "zero packed CUDA BlockTensor padding", stream.device());
297 template <
class ElementType>
300 return storage.
device() == device;
303 template <
class ElementType>
304 [[nodiscard]]
static auto
310 template <
class ElementType>
311 [[nodiscard]]
static auto
317 template <
class ElementType>
318 [[nodiscard]]
static auto
325 template <
class ElementType>
326 [[nodiscard]]
static auto
336#if UNI20_BACKEND_CUSOLVER && UNI20_BACKEND_CUBLAS
338#elif UNI20_BACKEND_CUSOLVER
340#elif UNI20_BACKEND_CUBLAS
348 template <
class Buffer>
static void initialize_storage(Buffer& storage,
StorageInitialization initialization)
350 using element_type =
typename Buffer::element_type;
351 if (storage.size() == 0)
return;
355 if constexpr (cuda::detail::has_zero_object_representation_v<element_type>)
357 auto stream = storage.resources().streams().acquire();
358 auto access = storage.write_synchronized_with(stream);
360 cuda::check(cudaMemsetAsync(access.data(), 0, storage.size() *
sizeof(element_type), stream.native_handle()),
361 "zero CUDA tensor storage", stream.device());
365 throw std::invalid_argument(
"CUDA zero initialization requires a supported numerical scalar representation");
370#if UNI20_FILL_UNINITIALIZED_SNAN
371 if constexpr (RealOrComplex<element_type>)
373 using real_type = make_real_t<element_type>;
376 if constexpr (std::same_as<real_type, float> || std::same_as<real_type, double>)
378 using word_type = std::conditional_t<
sizeof(real_type) == 4, std::uint32_t, std::uint64_t>;
379 auto const pattern = std::bit_cast<word_type>(detail::signaling_nan_value<real_type>());
380 auto stream = storage.resources().streams().acquire();
381 auto access = storage.write_synchronized_with(stream);
382 cuda::ScopedDevice guard(storage.device().ordinal());
383 cuda::detail::enqueue_initialization_pattern(access.data(), storage.size() *
sizeof(element_type), pattern,
384 sizeof(real_type),
stream.native_handle(),
stream.device());
Stream-ordered diagnostic initialization of CUDA scalar storage.
Ordered backend selector values shared by tensor storage and linalg dispatch.
Typed CUDA device buffers and scoped stream access guards.
Non-owning opaque view into one logical CUDA buffer.
Definition cuda_storage.hpp:33
constexpr CudaBufferView offset_by(std::size_t offset) const noexcept
Return a view advanced by an element offset.
Definition cuda_storage.hpp:68
std::conditional_t< std::is_const_v< element_type >, buffer_type const &, buffer_type & > buffer_reference
Definition cuda_storage.hpp:38
constexpr CudaBufferView(CudaBufferView< OtherElement > other) noexcept
Convert a mutable view into a read-only view.
Definition cuda_storage.hpp:49
std::remove_const_t< element_type > value_type
Definition cuda_storage.hpp:36
constexpr std::size_t element_offset() const noexcept
Return this view's element offset from the logical buffer start.
Definition cuda_storage.hpp:64
friend constexpr bool operator==(CudaBufferView const &, CudaBufferView const &)=default
constexpr CudaBufferView() noexcept=default
auto buffer() const -> buffer_reference
Return the CUDA buffer whose completion ledger governs access.
Definition cuda_storage.hpp:57
ElementType element_type
Definition cuda_storage.hpp:35
Move-only logical CUDA buffer and completion state.
Definition buffer.hpp:222
Device device() const
Return the allocation's CUDA device.
Definition buffer.hpp:276
Mutable stream and provider resources associated with one CUDA device.
Definition runtime.hpp:222
StreamPool & streams() noexcept
Return the device's actually-idle stream pool.
Definition runtime.hpp:244
Validated CUDA device identity with cached immutable capabilities.
Definition device.hpp:105
constexpr int ordinal() const noexcept
Return this device's CUDA runtime ordinal.
Definition device.hpp:123
One CUDA allocation partitioned into independent logical buffers.
Definition buffer.hpp:709
Device device() const
Return the CUDA device containing the physical allocation.
Definition buffer.hpp:755
DeviceResources & resources() const
Return the device resources shared by every child buffer.
Definition buffer.hpp:748
auto write_synchronized_with(Stream const &stream) -> PartitionedWriteAccess< T >
Acquire write access to the complete contiguous allocation.
Definition buffer.hpp:1202
Temporarily select one CUDA device and restore the previous device on destruction.
Definition runtime.hpp:44
Stream acquire()
Block until one actually idle stream can be leased.
Definition runtime.cpp:594
Immediate or descriptor-backed mdspan metadata targeting CUDA access.
Definition mdspan/concepts.hpp:329
CUDA-accessible mdspec backed by a CudaBufferView descriptor.
Definition cuda_storage.hpp:118
CUDA-device-callable accessors for leased Tensor storage.
locale_t value
Definition data_table.cpp:49
Mdspan concept and accessor extensions for Uni20.
Definition cublas/execution.hpp:18
void check(cudaError_t status, std::string_view operation, std::optional< int > device, std::source_location where)
Raise when a CUDA runtime operation did not return cudaSuccess.
Definition cuda_error.cpp:44
DeviceResources & device_resources()
Return canonical resources for the installed runtime's default device.
Definition runtime.cpp:820
stream
Selects the ordinary display stream for a message.
Definition display.hpp:25
Definition async/async.hpp:26
StorageInitialization
Numerical initialization requested from a storage implementation.
Definition common/initialization.hpp:26
Tensor storage policy for device-resident CUDA values.
Definition cuda_storage.hpp:164
cuda::CudaAccessorFactory accessor_factory_type
Definition cuda_storage.hpp:169
static auto make_storage(cuda::Device device, std::size_t size, StorageInitialization initialization=StorageInitialization::Uninitialized) -> storage_t< ElementType >
Definition cuda_storage.hpp:204
static auto make_packed_storage(std::size_t size, std::span< std::size_t const > offsets, StorageInitialization initialization=StorageInitialization::Uninitialized) -> packed_storage_t< ElementType >
Definition cuda_storage.hpp:219
static auto make_packed_data_descriptor(packed_storage_t< ElementType > &storage, std::size_t ordinal) noexcept -> cuda::CudaBufferView< ElementType >
Definition cuda_storage.hpp:319
static constexpr std::size_t allocation_alignment
Byte alignment guaranteed by CUDA runtime device allocations.
Definition cuda_storage.hpp:166
static auto make_packed_storage(context_type &context, std::size_t size, std::span< std::size_t const > offsets, StorageInitialization initialization=StorageInitialization::Uninitialized) -> packed_storage_t< ElementType >
Definition cuda_storage.hpp:235
static auto make_packed_storage_like(packed_storage_t< ElementType > const &storage, std::size_t size, std::span< std::size_t const > offsets, StorageInitialization initialization=StorageInitialization::Uninitialized) -> packed_storage_t< ElementType >
Definition cuda_storage.hpp:254
static bool storage_is_compatible(storage_t< ElementType > const &storage, cuda::Device device)
Definition cuda_storage.hpp:298
static auto make_packed_storage(cuda::Device device, std::size_t size, std::span< std::size_t const > offsets, StorageInitialization initialization=StorageInitialization::Uninitialized) -> packed_storage_t< ElementType >
Definition cuda_storage.hpp:227
static auto make_storage(std::size_t size, StorageInitialization initialization=StorageInitialization::Uninitialized) -> storage_t< ElementType >
Definition cuda_storage.hpp:186
static constexpr auto backend_selector() noexcept -> backend_selector_type
Return the ordered backend list for CUDA device storage.
Definition cuda_storage.hpp:334
static auto make_packed_data_descriptor(packed_storage_t< ElementType > const &storage, std::size_t ordinal) noexcept -> cuda::CudaBufferView< ElementType const >
Definition cuda_storage.hpp:327
static auto make_data_descriptor(storage_t< ElementType > const &storage) noexcept -> cuda::CudaBufferView< ElementType const >
Definition cuda_storage.hpp:312
static auto make_data_descriptor(storage_t< ElementType > &storage) noexcept -> cuda::CudaBufferView< ElementType >
Definition cuda_storage.hpp:305
static auto allocation_context(packed_storage_t< ElementType > const &storage) noexcept -> context_type &
Return the allocation context retained by a packed CUDA buffer.
Definition cuda_storage.hpp:263
static void initialize_packed_padding(packed_storage_t< ElementType > &storage, std::span< std::size_t const > offsets, std::span< std::size_t const > block_ends)
Initialize only the alignment gaps in a packed CUDA allocation.
Definition cuda_storage.hpp:272
static auto make_storage_like(storage_t< ElementType > const &storage, std::size_t size, StorageInitialization initialization=StorageInitialization::Uninitialized) -> storage_t< ElementType >
Definition cuda_storage.hpp:211
static auto make_storage(context_type &context, std::size_t size, StorageInitialization initialization=StorageInitialization::Uninitialized) -> storage_t< ElementType >
Definition cuda_storage.hpp:194
One logical range used to partition a CUDA allocation.
Definition buffer.hpp:42
Backend value for cuBLAS dense linalg kernels.
Definition backend_selector.hpp:34
Backend value for generic CUDA runtime kernels and transfers.
Definition backend_selector.hpp:48
Backend value for cuSOLVER dense factorization kernels.
Definition backend_selector.hpp:41
Ordered list of backend values tried by the dispatch walk.
Definition backend_selector.hpp:62
#define CHECK(cond,...)
Definition trace.hpp:299
#define CHECK_EQUAL(a, b,...)
Definition trace.hpp:309