baracuda_runtime/
external.rs1use std::sync::Arc;
14
15use baracuda_cuda_sys::runtime::{cudaExternalMemory_t, cudaExternalSemaphore_t, runtime};
16use baracuda_cuda_sys::types::{
17 CUDA_EXTERNAL_MEMORY_BUFFER_DESC, CUDA_EXTERNAL_MEMORY_HANDLE_DESC,
18 CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC, CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS,
19 CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS,
20};
21
22use crate::error::{Result, check};
23use crate::stream::Stream;
24
25#[derive(Clone)]
28pub struct ExternalMemory {
29 inner: Arc<ExternalMemoryInner>,
30}
31
32struct ExternalMemoryInner {
33 handle: cudaExternalMemory_t,
34}
35
36unsafe impl Send for ExternalMemoryInner {}
37unsafe impl Sync for ExternalMemoryInner {}
38
39impl core::fmt::Debug for ExternalMemoryInner {
40 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
41 f.debug_struct("ExternalMemory")
42 .field("handle", &self.handle)
43 .finish_non_exhaustive()
44 }
45}
46
47impl core::fmt::Debug for ExternalMemory {
48 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
49 self.inner.fmt(f)
50 }
51}
52
53impl ExternalMemory {
54 pub unsafe fn import(desc: &CUDA_EXTERNAL_MEMORY_HANDLE_DESC) -> Result<Self> {
63 unsafe {
64 let r = runtime()?;
65 let cu = r.cuda_import_external_memory()?;
66 let mut handle: cudaExternalMemory_t = core::ptr::null_mut();
67 check(cu(&mut handle, desc))?;
68 Ok(Self {
69 inner: Arc::new(ExternalMemoryInner { handle }),
70 })
71 }
72 }
73
74 pub fn mapped_buffer(
77 &self,
78 offset: u64,
79 size: u64,
80 flags: u32,
81 ) -> Result<*mut core::ffi::c_void> {
82 let r = runtime()?;
83 let cu = r.cuda_external_memory_get_mapped_buffer()?;
84 let desc = CUDA_EXTERNAL_MEMORY_BUFFER_DESC {
85 offset,
86 size,
87 flags,
88 reserved: [0; 16],
89 };
90 let mut ptr: *mut core::ffi::c_void = core::ptr::null_mut();
91 check(unsafe { cu(&mut ptr, self.inner.handle, &desc) })?;
92 Ok(ptr)
93 }
94
95 #[inline]
99 pub fn as_raw(&self) -> cudaExternalMemory_t {
100 self.inner.handle
101 }
102}
103
104impl Drop for ExternalMemoryInner {
105 fn drop(&mut self) {
106 if self.handle.is_null() {
107 return;
108 }
109 if let Ok(r) = runtime() {
110 if let Ok(cu) = r.cuda_destroy_external_memory() {
111 let _ = unsafe { cu(self.handle) };
112 }
113 }
114 }
115}
116
117#[derive(Clone)]
119pub struct ExternalSemaphore {
120 inner: Arc<ExternalSemaphoreInner>,
121}
122
123struct ExternalSemaphoreInner {
124 handle: cudaExternalSemaphore_t,
125}
126
127unsafe impl Send for ExternalSemaphoreInner {}
128unsafe impl Sync for ExternalSemaphoreInner {}
129
130impl core::fmt::Debug for ExternalSemaphoreInner {
131 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
132 f.debug_struct("ExternalSemaphore")
133 .field("handle", &self.handle)
134 .finish_non_exhaustive()
135 }
136}
137
138impl core::fmt::Debug for ExternalSemaphore {
139 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
140 self.inner.fmt(f)
141 }
142}
143
144impl ExternalSemaphore {
145 pub unsafe fn import(desc: &CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC) -> Result<Self> {
151 unsafe {
152 let r = runtime()?;
153 let cu = r.cuda_import_external_semaphore()?;
154 let mut handle: cudaExternalSemaphore_t = core::ptr::null_mut();
155 check(cu(&mut handle, desc))?;
156 Ok(Self {
157 inner: Arc::new(ExternalSemaphoreInner { handle }),
158 })
159 }
160 }
161
162 pub fn signal_fence_async(&self, value: u64, stream: &Stream) -> Result<()> {
164 let r = runtime()?;
165 let cu = r.cuda_signal_external_semaphores_async()?;
166 let params = CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS::fence_value(value);
167 check(unsafe { cu(&self.inner.handle, ¶ms, 1, stream.as_raw()) })
168 }
169
170 pub fn wait_fence_async(&self, value: u64, stream: &Stream) -> Result<()> {
172 let r = runtime()?;
173 let cu = r.cuda_wait_external_semaphores_async()?;
174 let params = CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS::fence_value(value);
175 check(unsafe { cu(&self.inner.handle, ¶ms, 1, stream.as_raw()) })
176 }
177
178 #[inline]
180 pub fn as_raw(&self) -> cudaExternalSemaphore_t {
181 self.inner.handle
182 }
183}
184
185impl Drop for ExternalSemaphoreInner {
186 fn drop(&mut self) {
187 if self.handle.is_null() {
188 return;
189 }
190 if let Ok(r) = runtime() {
191 if let Ok(cu) = r.cuda_destroy_external_semaphore() {
192 let _ = unsafe { cu(self.handle) };
193 }
194 }
195 }
196}