cuda-api-wrappers
Thin C++-flavored wrappers for the CUDA Runtime API
peer_to_peer.hpp
Go to the documentation of this file.
1 
7 #pragma once
8 #ifndef CUDA_API_WRAPPERS_PEER_TO_PEER_HPP_
9 #define CUDA_API_WRAPPERS_PEER_TO_PEER_HPP_
10 
11 #include "current_context.hpp"
12 
13 namespace cuda {
14 
15 namespace device {
16 
21 namespace peer_to_peer {
22 
25 
27 constexpr const attribute_t link_performance_rank = CU_DEVICE_P2P_ATTRIBUTE_PERFORMANCE_RANK;
28 
30 constexpr const attribute_t access_support = CU_DEVICE_P2P_ATTRIBUTE_ACCESS_SUPPORTED;
31 
33 constexpr const attribute_t native_atomics_support = CU_DEVICE_P2P_ATTRIBUTE_NATIVE_ATOMIC_SUPPORTED;
34 
35 #if CUDA_VERSION >= 10000
36 constexpr const attribute_t array_access_support = CU_DEVICE_P2P_ATTRIBUTE_CUDA_ARRAY_ACCESS_SUPPORTED;
38 #endif
39 
41 namespace detail_ {
53 inline attribute_value_t get_attribute(attribute_t attribute, id_t source, id_t destination)
54 {
55  attribute_value_t value;
56  auto status = cuDeviceGetP2PAttribute(&value, attribute, source, destination);
57  throw_if_error_lazy(status, "Failed obtaining peer-to-peer device attribute for device pair ("
58  + ::std::to_string(source) + ", " + ::std::to_string(destination) + ')');
59  return value;
60 }
61 
70 inline bool can_access(const device::id_t accessor, const device::id_t peer)
71 {
72  int result;
73  auto status = cuDeviceCanAccessPeer(&result, accessor, peer);
74  throw_if_error_lazy(status, "Failed determining whether " + device::detail_::identify(accessor)
75  + " can access " + device::detail_::identify(peer));
76  return (result == 1);
77 }
78 
79 } // namespace detail_
80 
81 } // namespace peer_to_peer
82 
83 } // namespace device
84 
85 namespace context {
86 
87 namespace current {
88 
89 namespace peer_to_peer {
90 
96 void enable_access_to(const context_t &peer_context);
97 
103 void disable_access_to(const context_t &peer_context);
104 
105 } // namespace peer_to_peer
106 
107 } // namespace current
108 
113 namespace peer_to_peer {
114 
115 namespace detail_ {
116 
117 inline void enable_access_to(context::handle_t peer_context)
118 {
119  enum : unsigned {fixed_flags = 0 };
120  // No flags are supported as of CUDA 8.0
121  auto status = cuCtxEnablePeerAccess(peer_context, fixed_flags);
122  throw_if_error_lazy(status, "Failed enabling access to peer " + context::detail_::identify(peer_context));
123 }
124 
125 inline void disable_access_to(context::handle_t peer_context)
126 {
127  auto status = cuCtxDisablePeerAccess(peer_context);
128  throw_if_error_lazy(status, "Failed disabling access to peer " + context::detail_::identify(peer_context));
129 }
130 
131 inline void enable_access(context::handle_t accessor, context::handle_t peer)
132 {
133  context::current::detail_::scoped_override_t set_context_for_this_context(accessor);
134  enable_access_to(peer);
135 }
136 
137 inline void disable_access(context::handle_t accessor, context::handle_t peer)
138 {
139  context::current::detail_::scoped_override_t set_context_for_this_context(accessor);
140  disable_access_to(peer);
141 }
142 
143 } // namespace detail_
144 
148 bool can_access(context_t accessor, context_t peer);
149 
156 void enable_access(context_t accessor, context_t peer);
157 
164 void disable_access(context_t accessor, context_t peer);
165 
170 
175 
176 } // namespace peer_to_peer
177 } // namespace context
178 
179 namespace device {
180 
181 namespace peer_to_peer {
182 
191 inline bool can_access(const device_t& accessor, const device_t& peer);
192 
201 inline void enable_access(const device_t& accessor, const device_t& peer);
202 
211 inline void disable_access(const device_t& accessor, const device_t& peer);
212 
216 inline bool can_access_each_other(const device_t& first, const device_t& second);
217 
221 inline void enable_bidirectional_access(const device_t& first, const device_t& second);
222 
226 inline void disable_bidirectional_access(const device_t& first, const device_t& second);
227 
239 inline attribute_value_t get_attribute(attribute_t attribute, const device_t& first, const device_t& second);
240 
241 } // namespace peer_to_peer
242 } // namespace device
243 } // namespace cuda
244 
245 #endif // CUDA_API_WRAPPERS_PEER_TO_PEER_HPP_
int attribute_value_t
All CUDA device attributes (cuda::device::attribute_t) have a value of this type. ...
Definition: types.hpp:860
Wrapper class for a CUDA context.
Definition: context.hpp:244
bool can_access_each_other(const device_t &first, const device_t &second)
Determine whether two CUDA devices can currently access each other.
Definition: device.hpp:88
Definitions and functionality wrapping CUDA APIs.
Definition: array.hpp:22
bool can_access(const device_t &accessor, const device_t &peer)
Determine whether one CUDA device can access the global memory of another CUDA device.
Definition: device.hpp:68
CUcontext handle_t
Raw CUDA driver handle for a context; see {context_t}.
Definition: types.hpp:878
attribute_value_t get_attribute(attribute_t attribute, const device_t &first, const device_t &second)
Get one of the numeric attributes for a(n ordered) pair of devices, relating to their interaction...
Definition: device.hpp:113
CUdevice id_t
Numeric ID of a CUDA device used by the CUDA Runtime API.
Definition: types.hpp:850
constexpr const attribute_t access_support
1 if access is supported, 0 otherwise
Definition: peer_to_peer.hpp:30
constexpr const attribute_t link_performance_rank
Aliases for CUDA driver GPU attribute codes.
Definition: peer_to_peer.hpp:27
constexpr const attribute_t native_atomics_support
1 if the first device can perform native atomic operations on the second device, 0 otherwise ...
Definition: peer_to_peer.hpp:33
CUdevice_P2PAttribute attribute_t
While Individual CUDA devices have individual "attributes" (attribute_t), there are also attributes c...
Definition: types.hpp:869
#define throw_if_error_lazy(status__,...)
A macro for only throwing an error if we've failed - which also ensures no string is constructed unle...
Definition: error.hpp:316
void disable_access(const device_t &accessor, const device_t &peer)
Disable access by one CUDA device to the global memory of another.
Definition: device.hpp:78
void enable_access(const device_t &accessor, const device_t &peer)
Enable access by one CUDA device to the global memory of another.
Definition: device.hpp:73
void enable_bidirectional_access(const device_t &first, const device_t &second)
Enable access both by the first to the second device and the other way around.
Definition: device.hpp:93
Wrapper class for a CUDA device.
Definition: device.hpp:135
void disable_bidirectional_access(const device_t &first, const device_t &second)
Disable access both by the first to the second device and the other way around.
Definition: device.hpp:103