nuvec_gpu/lib.rs
1//! Metal backend: device discovery, kernel library and pipelines, shared buffers, and
2//! command encoding with minimal barriers.
3//!
4//! ```no_run
5//! use nuvec_gpu::{Arg, Device};
6//!
7//! # fn main() -> nuvec_gpu::Result<()> {
8//! let Some(device) = Device::system_default() else { return Ok(()) }; // no Metal here
9//! let add = device.pipeline("nuvec_add_f32")?;
10//! let a = device.buffer_from(&1.0f32.to_le_bytes().repeat(4))?;
11//! let b = device.buffer_from(&2.0f32.to_le_bytes().repeat(4))?;
12//! let mut out = device.new_buffer(16)?;
13//! let mut cmd = device.command_buffer()?;
14//! cmd.dispatch(&add, &[Arg::read(&a), Arg::read(&b), Arg::write(&mut out), Arg::bytes(&4u32.to_le_bytes())], 4)?;
15//! cmd.commit().wait()?;
16//! assert_eq!(&out.contents()?[..4], &3.0f32.to_le_bytes());
17//! # Ok(())
18//! # }
19//! ```
20//!
21//! Buffers live in shared (unified) memory: the CPU reads GPU results in place. CPU access
22//! is refused while submitted work uses a buffer, and GPU writes need `&mut Buffer`, so
23//! CPU and GPU never race on the same memory.
24//!
25//! **Status:** pre-alpha. Not yet wired into array evaluation.
26
27mod error;
28mod info;
29
30pub use error::{GpuError, Result};
31pub use info::DeviceInfo;
32
33#[cfg(target_os = "macos")]
34mod metal;
35#[cfg(target_os = "macos")]
36pub use metal::{Arg, Buffer, CommandBuffer, Device, MemoryStats, Pipeline, Submitted};
37
38#[cfg(not(target_os = "macos"))]
39mod stub;
40#[cfg(not(target_os = "macos"))]
41pub use stub::Device;
42
43/// The version of this crate.
44pub const VERSION: &str = env!("CARGO_PKG_VERSION");
45
46#[cfg(test)]
47mod tests {
48 #[test]
49 fn version_is_set() {
50 assert!(!super::VERSION.is_empty());
51 let _ = nuvec_kernels::MODE;
52 }
53}