7 #ifndef CUDA_API_WRAPPERS_DEVICES_HPP_ 8 #define CUDA_API_WRAPPERS_DEVICES_HPP_ 21 using value_type = cuda::device_t;
23 using const_pointer = void;
24 using reference = value_type;
25 using const_reference =
const value_type;
27 using difference_type = typename ::std::make_signed<size_type>::type;
29 class index_based_iterator {
31 using container = all_devices;
32 using difference_type = container::difference_type;
33 using value_type = container::value_type;
34 using pointer = container::pointer;
35 using reference = container::reference;
36 using iterator_category = ::std::random_access_iterator_tag;
42 index_based_iterator(size_type num_devices, size_type index)
43 : num_devices_(num_devices), index_(index)
45 if (index_ > num_devices_) { throw ::std::logic_error(
"Out of range"); }
48 index_based_iterator(
const index_based_iterator& it)
49 : index_based_iterator(it.num_devices_, it.index_) { }
53 reference operator*()
const {
return device::get(index_); }
55 index_based_iterator& operator++()
57 if (index_ == num_devices_) { throw ::std::logic_error(
"Out of range"); }
62 index_based_iterator operator++(
int)
64 if (index_== num_devices_) { throw ::std::logic_error(
"Out of range"); }
65 return index_based_iterator(num_devices_, index_++);
69 index_based_iterator& operator--()
71 if (index_ == 0) { throw ::std::logic_error(
"Out of range"); }
76 index_based_iterator operator--(
int)
78 if (index_ == 0) { throw ::std::logic_error(
"Out of range"); }
79 return index_based_iterator(num_devices_, index_--);
83 reference operator[](difference_type n)
const 88 index_based_iterator& operator+=(difference_type n)
91 if (index_ + n > num_devices_) { throw ::std::logic_error(
"Out of range"); }
97 index_based_iterator operator+(difference_type n)
const 100 if (n + index_ > num_devices_) {
101 throw ::std::logic_error(
"Out of range");
104 return index_based_iterator(num_devices_, index_ + n);
107 index_based_iterator& operator-=(difference_type n)
110 throw ::std::logic_error(
"Out of range");
116 index_based_iterator operator-(difference_type n)
const 119 throw ::std::logic_error(
"Out of range");
121 return index_based_iterator(num_devices_, index_ - n);
124 difference_type operator-(
const index_based_iterator& other)
const 126 return this->index_ - other.index_;
129 size_type index()
const {
return index_; }
130 size_type num_devices()
const {
return num_devices_; }
133 size_type num_devices_;
137 using iterator = index_based_iterator;
138 using const_iterator = index_based_iterator;
139 using reverse_iterator = ::std::reverse_iterator<iterator>;
140 using const_reverse_iterator = ::std::reverse_iterator<const_iterator>;
143 all_devices() : num_devices_(device::
count()) { }
144 ~all_devices() =
default;
145 all_devices(
const all_devices&) =
default;
146 all_devices(all_devices&&) =
default;
147 all_devices& operator=(
const all_devices&) {
return *
this; };
148 all_devices& operator=(all_devices&&) {
return *
this; };
151 void swap(all_devices&) noexcept { }
155 iterator begin() noexcept {
return iterator(num_devices_, 0); }
156 const_iterator begin() const noexcept {
return const_iterator(num_devices_, 0); }
157 iterator end() noexcept {
return iterator(num_devices_, num_devices_); }
158 const_iterator end() const noexcept {
return const_iterator(num_devices_, num_devices_); }
159 reverse_iterator rbegin() noexcept {
return reverse_iterator(end()); }
160 const_reverse_iterator rbegin() const noexcept {
return const_reverse_iterator(end()); }
161 reverse_iterator rend() noexcept {
return reverse_iterator(begin()); }
162 const_reverse_iterator rend() const noexcept {
return const_reverse_iterator(begin()); }
163 const_iterator cbegin() const noexcept {
return const_iterator(num_devices_, 0); }
164 const_iterator cend() const noexcept {
return const_iterator(num_devices_, num_devices_); }
165 const_reverse_iterator crbegin() const noexcept {
return const_reverse_iterator(end()); }
166 const_reverse_iterator crend() const noexcept {
return const_reverse_iterator(begin()); }
170 size_type size() const noexcept {
return num_devices_; }
171 size_type max_size() const noexcept {
return num_devices_; }
172 bool empty() const noexcept {
return size() == 0; }
177 const_reference at(size_type n)
const 180 return device::get(n);
184 const_reference operator[](size_type n)
const {
return at(n); }
188 const_reference front()
const {
return *begin(); }
190 const_reference back() const noexcept {
return num_devices_ ? *(end() - 1) : *end(); }
194 size_type num_devices_;
197 inline bool operator== (
198 const all_devices::index_based_iterator& lhs,
199 const all_devices::index_based_iterator& rhs)
202 return lhs.num_devices() == rhs.num_devices() and lhs.index() == rhs.index();
204 return lhs.index() == rhs.index();
208 inline bool operator!= (
209 const all_devices::index_based_iterator& lhs,
210 const all_devices::index_based_iterator& rhs)
212 return not (lhs == rhs);
217 inline detail_::all_devices devices()
219 return detail_::all_devices();
224 #endif // CUDA_API_WRAPPERS_DEVICES_HPP_ A proxy class for CUDA devices, providing access to all Runtime API calls involving their use and man...
All definitions and functionality wrapping the CUDA Runtime API.
Definition: array.hpp:22
device::id_t count()
Get the number of CUDA devices usable on the system (with the current CUDA library and kernel driver)...
Definition: miscellany.hpp:56
CUdevice id_t
Numeric ID of a CUDA device used by the CUDA Runtime API.
Definition: types.hpp:752
Definition: kernel_launch.hpp:77