baracuda_runtime/driver_entry.rs
1//! Runtime-to-Driver entry-point bridge — `cudaGetDriverEntryPoint`.
2//!
3//! Most code using this crate goes through the typed Driver loader in
4//! `baracuda-driver`. The runtime's `cudaGetDriverEntryPoint` is useful
5//! for one narrow case: asking the installed runtime which driver
6//! symbol name / fptr it would resolve for a given API, without
7//! touching `libcuda` directly. Handy for diagnostic tools and for
8//! picking up versioned symbol variants (`_ptsz`, `_v2`, …).
9
10use core::ffi::{c_int, c_void};
11use std::ffi::CString;
12
13use baracuda_cuda_sys::runtime::runtime;
14
15use crate::error::{Error, Result, check};
16
17/// Typed outcome of [`driver_entry_point`]. `status` mirrors the
18/// `cudaDriverEntryPointQueryResult` enum reported by the runtime:
19/// 0 = Success, 1 = SymbolNotFound, 2 = VersionNotSufficient.
20#[derive(Copy, Clone, Debug)]
21pub struct DriverEntryPoint {
22 /// Resolved Driver-API function pointer, or null on lookup failure.
23 pub fn_ptr: *mut c_void,
24 /// Raw `cudaDriverEntryPointQueryResult` code (0 = success).
25 pub status: i32,
26}
27
28impl DriverEntryPoint {
29 /// `true` iff the runtime resolved the symbol and the function
30 /// pointer is non-null.
31 #[inline]
32 pub fn is_success(&self) -> bool {
33 self.status == 0 && !self.fn_ptr.is_null()
34 }
35}
36
37/// Resolve a Driver-API symbol by name through the Runtime API
38/// (`cudaGetDriverEntryPoint`). `flags = 0` = default; bit 0 = legacy
39/// stream, bit 1 = per-thread stream (mirrors `cuGetProcAddress`).
40pub fn driver_entry_point(symbol: &str, flags: u64) -> Result<DriverEntryPoint> {
41 let c_sym = CString::new(symbol).map_err(|_| {
42 Error::Loader(baracuda_core::LoaderError::SymbolNotFound {
43 library: "cuda-runtime",
44 symbol: "cudaGetDriverEntryPoint(symbol contained a NUL byte)",
45 })
46 })?;
47 let r = runtime()?;
48 let cu = r.cuda_get_driver_entry_point()?;
49 let mut fn_ptr: *mut c_void = core::ptr::null_mut();
50 let mut driver_status: c_int = 0;
51 check(unsafe { cu(c_sym.as_ptr(), &mut fn_ptr, flags, &mut driver_status) })?;
52 Ok(DriverEntryPoint {
53 fn_ptr,
54 status: driver_status,
55 })
56}