spark_storage/
cuda_graph.rs1use anyhow::{Context, Result, bail};
8
9unsafe extern "C" {
10 fn cuStreamBeginCapture_v2(stream: u64, mode: u32) -> i32;
11 fn cuStreamEndCapture(stream: u64, graph_out: *mut u64) -> i32;
12 fn cuGraphInstantiateWithFlags(exec_out: *mut u64, graph: u64, flags: u64) -> i32;
13 fn cuGraphLaunch(exec: u64, stream: u64) -> i32;
14 fn cuGraphExecDestroy(exec: u64) -> i32;
15 fn cuGraphDestroy(graph: u64) -> i32;
16}
17
18const CU_STREAM_CAPTURE_MODE_GLOBAL: u32 = 0;
19
20pub struct CapturedStep {
21 graph: u64,
22 graph_exec: u64,
23}
24
25impl CapturedStep {
26 pub fn capture<F>(stream: u64, body: F) -> Result<Self>
30 where
31 F: FnOnce() -> Result<()>,
32 {
33 let s = unsafe { cuStreamBeginCapture_v2(stream, CU_STREAM_CAPTURE_MODE_GLOBAL) };
34 if s != 0 {
35 bail!("cuStreamBeginCapture_v2 failed: {s}");
36 }
37 let body_result = body();
38 let mut graph = 0u64;
39 let s2 = unsafe { cuStreamEndCapture(stream, &mut graph) };
40 body_result.context("CUDA graph body")?;
43 if s2 != 0 {
44 bail!("cuStreamEndCapture failed: {s2}");
45 }
46 let mut exec = 0u64;
47 let s3 = unsafe { cuGraphInstantiateWithFlags(&mut exec, graph, 0) };
48 if s3 != 0 {
49 unsafe { cuGraphDestroy(graph) };
50 bail!("cuGraphInstantiateWithFlags failed: {s3}");
51 }
52 Ok(Self {
53 graph,
54 graph_exec: exec,
55 })
56 }
57
58 pub fn launch(&self, stream: u64) -> Result<()> {
59 let s = unsafe { cuGraphLaunch(self.graph_exec, stream) };
60 if s != 0 {
61 bail!("cuGraphLaunch failed: {s}");
62 }
63 Ok(())
64 }
65}
66
67impl Drop for CapturedStep {
68 fn drop(&mut self) {
69 unsafe {
70 let _ = cuGraphExecDestroy(self.graph_exec);
71 let _ = cuGraphDestroy(self.graph);
72 }
73 }
74}