Skip to main content

baracuda_driver/
ipc.rs

1//! Inter-Process Communication for CUDA events and allocations.
2//!
3//! Two producers / two consumers of cross-process state:
4//!
5//! - Device memory: [`mem_get_handle`] → transmit bytes to another process
6//!   → [`mem_open_handle`] gives you a device pointer aliasing the same
7//!   physical memory. Close with [`mem_close_handle`].
8//! - Events: [`event_get_handle`] / [`event_open_handle`] for cross-process
9//!   synchronization.
10//!
11//! Availability: Linux only in practice. Windows drivers return
12//! `CUDA_ERROR_NOT_SUPPORTED`. Use external-memory / semaphore interop
13//! for Windows IPC.
14
15use baracuda_cuda_sys::types::{CUipcEventHandle, CUipcMemHandle};
16use baracuda_cuda_sys::{driver, CUdeviceptr, CUevent};
17
18use crate::error::{check, Result};
19use crate::event::Event;
20
21/// Export a CUDA event for sharing with another process.
22pub fn event_get_handle(event: &Event) -> Result<CUipcEventHandle> {
23    let d = driver()?;
24    let cu = d.cu_ipc_get_event_handle()?;
25    let mut h = CUipcEventHandle::default();
26    check(unsafe { cu(&mut h, event.as_raw()) })?;
27    Ok(h)
28}
29
30/// Open a peer-exported event handle. Returns a raw `CUevent`; wrap it
31/// with [`Event::from_raw`] if needed.
32///
33/// Note the handle is passed by value (CUDA's ABI), not by pointer.
34pub fn event_open_handle(handle: CUipcEventHandle) -> Result<CUevent> {
35    let d = driver()?;
36    let cu = d.cu_ipc_open_event_handle()?;
37    let mut event: CUevent = core::ptr::null_mut();
38    check(unsafe { cu(&mut event, handle) })?;
39    Ok(event)
40}
41
42/// Export a device allocation for sharing with another process.
43pub fn mem_get_handle(dptr: CUdeviceptr) -> Result<CUipcMemHandle> {
44    let d = driver()?;
45    let cu = d.cu_ipc_get_mem_handle()?;
46    let mut h = CUipcMemHandle::default();
47    check(unsafe { cu(&mut h, dptr) })?;
48    Ok(h)
49}
50
51/// Open a peer-exported device-memory handle. Returns a device pointer
52/// valid in the *current* context.
53pub fn mem_open_handle(handle: CUipcMemHandle, flags: u32) -> Result<CUdeviceptr> {
54    let d = driver()?;
55    let cu = d.cu_ipc_open_mem_handle()?;
56    let mut dptr = CUdeviceptr(0);
57    check(unsafe { cu(&mut dptr, handle, flags) })?;
58    Ok(dptr)
59}
60
61/// Release an imported device pointer previously opened via
62/// [`mem_open_handle`].
63pub fn mem_close_handle(dptr: CUdeviceptr) -> Result<()> {
64    let d = driver()?;
65    let cu = d.cu_ipc_close_mem_handle()?;
66    check(unsafe { cu(dptr) })
67}