Loading...
Searching...
No Matches
device_uvector.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: Copyright (c) 2020-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6#pragma once
7
8#include <rmm/detail/cuda_memcpy.hpp>
9#include <rmm/detail/error.hpp>
10#include <rmm/detail/exec_check_disable.hpp>
11#include <rmm/detail/export.hpp>
12#include <rmm/device_buffer.hpp>
14#include <rmm/resource_ref.hpp>
15
16#include <cuda/std/iterator>
17#include <cuda/std/span>
18#include <cuda/stream>
19
20#include <cstddef>
21#include <limits>
22#include <type_traits>
23#include <utility>
24
25RMM_NAMESPACE_BEGIN
31
69template <typename T>
71 static_assert(std::is_trivially_copyable_v<T>,
72 "device_uvector only supports types that are trivially copyable.");
73
74 public:
75 using value_type = T;
76 using size_type = std::size_t;
79 value_type const&;
81 using const_pointer = value_type const*;
82 using iterator = pointer;
85 cuda::std::reverse_iterator<iterator>;
87 cuda::std::reverse_iterator<const_iterator>;
89
90 RMM_EXEC_CHECK_DISABLE
91 ~device_uvector() = default;
92
93 RMM_EXEC_CHECK_DISABLE
94 device_uvector(device_uvector&&) noexcept = default;
95
96 RMM_EXEC_CHECK_DISABLE
97 device_uvector& operator=(device_uvector&&) noexcept =
98 default;
99
104
108 device_uvector& operator=(device_uvector const&) = delete;
109
113 device_uvector() = delete;
114
132 cuda::stream_ref stream,
133 cuda::mr::any_resource<cuda::mr::device_accessible> mr = mr::get_current_device_resource_ref())
134 : _storage{elements_to_bytes(size), std::alignment_of_v<T>, stream, std::move(mr)}
135 {
136 }
137
148 device_uvector const& other,
149 cuda::stream_ref stream,
150 cuda::mr::any_resource<cuda::mr::device_accessible> mr = mr::get_current_device_resource_ref())
151 : _storage{other._storage, stream, std::move(mr)}
152 {
153 }
154
163 [[nodiscard]] pointer element_ptr(size_type element_index) noexcept
164 {
165 assert(element_index < size());
166 return data() + element_index;
167 }
168
177 [[nodiscard]] const_pointer element_ptr(size_type element_index) const noexcept
178 {
179 assert(element_index < size());
180 return data() + element_index;
181 }
182
216 void set_element_async(size_type element_index, value_type const& value, cuda::stream_ref stream)
217 {
218 RMM_EXPECTS(
219 element_index < size(), "Attempt to access out of bounds element.", rmm::out_of_range);
220 RMM_CUDA_TRY(
221 rmm::detail::memcpy_async(element_ptr(element_index), &value, sizeof(value), stream));
222 }
223
224 // We delete the r-value reference overload to prevent asynchronously copying from a literal or
225 // implicit temporary value after it is deleted or goes out of scope.
226 void set_element_async(size_type, value_type const&&, cuda::stream_ref) = delete;
227
250 void set_element_to_zero_async(size_type element_index, cuda::stream_ref stream)
251 {
252 RMM_EXPECTS(
253 element_index < size(), "Attempt to access out of bounds element.", rmm::out_of_range);
254 RMM_CUDA_TRY(cudaMemsetAsync(element_ptr(element_index), 0, sizeof(value_type), stream.get()));
255 }
256
286 void set_element(size_type element_index, T const& value, cuda::stream_ref stream)
287 {
288 set_element_async(element_index, value, stream);
289 stream.sync();
290 }
291
304 [[nodiscard]] value_type element(size_type element_index, cuda::stream_ref stream) const
305 {
306 RMM_EXPECTS(
307 element_index < size(), "Attempt to access out of bounds element.", rmm::out_of_range);
308 value_type value;
309 RMM_CUDA_TRY(
310 rmm::detail::memcpy_async(&value, element_ptr(element_index), sizeof(value), stream));
311 stream.sync();
312 return value;
313 }
314
326 [[nodiscard]] value_type front_element(cuda::stream_ref stream) const
327 {
328 return element(0, stream);
329 }
330
342 [[nodiscard]] value_type back_element(cuda::stream_ref stream) const
343 {
344 return element(size() - 1, stream);
345 }
346
361 void reserve(size_type new_capacity, cuda::stream_ref stream)
362 {
363 _storage.reserve(elements_to_bytes(new_capacity), stream);
364 }
365
384 void resize(size_type new_size, cuda::stream_ref stream)
385 {
386 _storage.resize(elements_to_bytes(new_size), stream);
387 }
388
396 void shrink_to_fit(cuda::stream_ref stream) { _storage.shrink_to_fit(stream); }
397
403 device_buffer release() noexcept { return std::move(_storage); }
404
411 [[nodiscard]] size_type capacity() const noexcept
412 {
413 return bytes_to_elements(_storage.capacity());
414 }
415
424 [[nodiscard]] pointer data() noexcept { return static_cast<pointer>(_storage.data()); }
425
434 [[nodiscard]] const_pointer data() const noexcept
435 {
436 return static_cast<const_pointer>(_storage.data());
437 }
438
446 [[nodiscard]] iterator begin() noexcept { return data(); }
447
455 [[nodiscard]] const_iterator cbegin() const noexcept { return data(); }
456
464 [[nodiscard]] const_iterator begin() const noexcept { return cbegin(); }
465
474 [[nodiscard]] iterator end() noexcept { return data() + size(); }
475
484 [[nodiscard]] const_iterator cend() const noexcept { return data() + size(); }
485
494 [[nodiscard]] const_iterator end() const noexcept { return cend(); }
495
503 [[nodiscard]] reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
504
512 [[nodiscard]] const_reverse_iterator crbegin() const noexcept
513 {
515 }
516
524 [[nodiscard]] const_reverse_iterator rbegin() const noexcept { return crbegin(); }
525
534 [[nodiscard]] reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
535
545 [[nodiscard]] const_reverse_iterator crend() const noexcept
546 {
548 }
549
558 [[nodiscard]] const_reverse_iterator rend() const noexcept { return crend(); }
559
563 [[nodiscard]] size_type size() const noexcept { return bytes_to_elements(_storage.size()); }
564
568 [[nodiscard]] std::int64_t ssize() const noexcept
569 {
570 assert(size() < static_cast<size_type>(std::numeric_limits<int64_t>::max()) &&
571 "Size overflows signed integer");
572 return static_cast<int64_t>(size());
573 }
574
578 [[nodiscard]] bool is_empty() const noexcept { return size() == 0; }
579
583 [[nodiscard]] operator cuda::std::span<T const>() const noexcept
584 {
585 return cuda::std::span<T const>(data(), size());
586 }
587
591 [[nodiscard]] operator cuda::std::span<T>() noexcept
592 {
593 return cuda::std::span<T>(data(), size());
594 }
595
600 [[nodiscard]] rmm::device_async_resource_ref memory_resource() noexcept
602 return _storage.memory_resource();
603 }
604
605
608 [[nodiscard]] cuda::stream_ref stream() const noexcept { return _storage.stream(); }
621 void set_stream(cuda::stream_ref stream) noexcept { _storage.set_stream(stream); }
623 private:
624 device_buffer _storage{};
625
626 [[nodiscard]] size_type elements_to_bytes(size_type num_elements) const
627 {
628 RMM_EXPECTS(num_elements <= std::numeric_limits<size_type>::max() / sizeof(value_type),
629 "Requested size overflows device_uvector storage.",
631 return num_elements * sizeof(value_type);
632 }
633
634 [[nodiscard]] size_type constexpr bytes_to_elements(size_type num_bytes) const noexcept
635 {
636 return num_bytes / sizeof(value_type);
637 }
638};
639
640 // end of group
641RMM_NAMESPACE_END
RAII construct for device memory allocation.
Definition device_buffer.hpp:72
reverse_iterator rend() noexcept
Returns reverse_iterator to the element preceding the first element of the vector.
Definition device_uvector.hpp:534
const_iterator cend() const noexcept
Returns a const_iterator to the element following the last element of the vector.
Definition device_uvector.hpp:484
cuda::stream_ref stream() const noexcept
Stream most recently specified for allocation/deallocation.
Definition device_uvector.hpp:609
void reserve(size_type new_capacity, cuda::stream_ref stream)
Increases the capacity of the vector to new_capacity elements.
Definition device_uvector.hpp:361
void resize(size_type new_size, cuda::stream_ref stream)
Resizes the vector to contain new_size elements.
Definition device_uvector.hpp:384
const_reverse_iterator crend() const noexcept
Returns a const_reverse_iterator to the element preceding the first element of the vector.
Definition device_uvector.hpp:545
value_type back_element(cuda::stream_ref stream) const
Returns the last element.
Definition device_uvector.hpp:342
void set_stream(cuda::stream_ref stream) noexcept
Sets the stream to be used for deallocation.
Definition device_uvector.hpp:622
value_type * pointer
The type of the pointer returned by data().
Definition device_uvector.hpp:80
bool is_empty() const noexcept
true if the vector contains no elements, i.e. size() == 0
Definition device_uvector.hpp:578
size_type size() const noexcept
The number of elements in the vector.
Definition device_uvector.hpp:563
const_pointer data() const noexcept
Returns const pointer to underlying device storage.
Definition device_uvector.hpp:434
reverse_iterator rbegin() noexcept
Returns a reverse_iterator to the last element.
Definition device_uvector.hpp:503
pointer data() noexcept
Returns pointer to underlying device storage.
Definition device_uvector.hpp:424
void set_element(size_type element_index, T const &value, cuda::stream_ref stream)
Performs a synchronous copy of v to the specified element in device memory.
Definition device_uvector.hpp:286
iterator end() noexcept
Returns an iterator to the element following the last element of the vector.
Definition device_uvector.hpp:474
void set_element_async(size_type element_index, value_type const &value, cuda::stream_ref stream)
Performs an asynchronous copy of v to the specified element in device memory.
Definition device_uvector.hpp:216
std::size_t size_type
The type used for the size of the vector.
Definition device_uvector.hpp:76
value_type front_element(cuda::stream_ref stream) const
Returns the first element.
Definition device_uvector.hpp:326
const_reverse_iterator crbegin() const noexcept
Returns a const_reverse_iterator to the last element.
Definition device_uvector.hpp:512
size_type capacity() const noexcept
Returns the number of elements that can be held in currently allocated storage.
Definition device_uvector.hpp:411
cuda::std::reverse_iterator< iterator > reverse_iterator
The type of the iterator returned by rbegin().
Definition device_uvector.hpp:84
value_type const & const_reference
Constant reference type returned by operator[](size_type) const.
Definition device_uvector.hpp:78
std::int64_t ssize() const noexcept
The signed number of elements in the vector.
Definition device_uvector.hpp:568
T value_type
Stored value type.
Definition device_uvector.hpp:75
const_iterator cbegin() const noexcept
Returns a const_iterator to the first element.
Definition device_uvector.hpp:455
void set_element_to_zero_async(size_type element_index, cuda::stream_ref stream)
Asynchronously sets the specified element to zero in device memory.
Definition device_uvector.hpp:250
const_pointer const_iterator
The type of the const iterator returned by cbegin().
Definition device_uvector.hpp:83
void shrink_to_fit(cuda::stream_ref stream)
Forces deallocation of unused device memory.
Definition device_uvector.hpp:396
device_buffer release() noexcept
Release ownership of device memory storage.
Definition device_uvector.hpp:403
device_uvector(device_uvector &&) noexcept=default
Default move constructor.
device_uvector(device_uvector const &other, cuda::stream_ref stream, cuda::mr::any_resource< cuda::mr::device_accessible > mr=mr::get_current_device_resource_ref())
Construct a new device_uvector by deep copying the contents of another device_uvector.
Definition device_uvector.hpp:147
pointer iterator
The type of the iterator returned by begin().
Definition device_uvector.hpp:82
value_type & reference
Reference type returned by operator[](size_type).
Definition device_uvector.hpp:77
const_reverse_iterator rend() const noexcept
Returns const_reverse_iterator to the element preceding the first element of the vector.
Definition device_uvector.hpp:558
const_iterator end() const noexcept
Returns an iterator to the element following the last element of the vector.
Definition device_uvector.hpp:494
value_type element(size_type element_index, cuda::stream_ref stream) const
Returns the specified element from device memory.
Definition device_uvector.hpp:304
cuda::std::reverse_iterator< const_iterator > const_reverse_iterator
Definition device_uvector.hpp:86
pointer element_ptr(size_type element_index) noexcept
Returns pointer to the specified element.
Definition device_uvector.hpp:163
value_type const * const_pointer
The type of the pointer returned by data() const.
Definition device_uvector.hpp:81
const_reverse_iterator rbegin() const noexcept
Returns a const_reverse_iterator to the last element.
Definition device_uvector.hpp:524
const_pointer element_ptr(size_type element_index) const noexcept
Returns pointer to the specified element.
Definition device_uvector.hpp:177
const_iterator begin() const noexcept
Returns a const_iterator to the first element.
Definition device_uvector.hpp:464
iterator begin() noexcept
Returns an iterator to the first element.
Definition device_uvector.hpp:446
Exception thrown when an argument to a function is invalid.
Definition error.hpp:108
Exception thrown when attempting to access outside of a defined range.
Definition error.hpp:99
device_async_resource_ref get_current_device_resource_ref()
Get the device_async_resource_ref for the current device.
Definition per_device_resource.hpp:187
cuda::mr::resource_ref< cuda::mr::device_accessible > device_async_resource_ref
Alias for a cuda::mr::resource_ref with the property cuda::mr::device_accessible.
Definition resource_ref.hpp:30
Memory Resource classes and adaptors.
Management of per-device memory resources.