Expand description
Metal backend: device discovery, kernel library and pipelines, shared buffers, and command encoding with minimal barriers.
use nuvec_gpu::{Arg, Device};
let Some(device) = Device::system_default() else { return Ok(()) }; // no Metal here
let add = device.pipeline("nuvec_add_f32")?;
let a = device.buffer_from(&1.0f32.to_le_bytes().repeat(4))?;
let b = device.buffer_from(&2.0f32.to_le_bytes().repeat(4))?;
let mut out = device.new_buffer(16)?;
let mut cmd = device.command_buffer()?;
let n = 4u32.to_le_bytes();
let args = [Arg::read(&a), Arg::read(&b), Arg::write(&mut out), Arg::bytes(&n)];
// SAFETY: `nuvec_add_f32` touches element `i < n` of each buffer; all hold 4 floats.
unsafe { cmd.dispatch(&add, &args, 4)? };
cmd.commit().wait()?;
assert_eq!(&out.contents()?[..4], &3.0f32.to_le_bytes());Buffers live in shared (unified) memory: the CPU reads GPU results in place. CPU access
is refused while submitted work uses a buffer, and GPU writes need &mut Buffer, so
CPU and GPU never race on the same memory. Dispatching is unsafe: nuvec validates the
arguments and orders the work, but cannot check that a kernel stays within its buffers.
Requires macOS 15 or later (Metal 3.2, as the kernel library is built).
Arrays evaluated on the GPU (nuvec-core) use the process-wide Device::shared; its
allocator’s limits and statistics are set and read there.
Stability: no promise when this crate is depended on directly; depend on nuvec,
whose re-exports are semver-tracked.
Modules§
- profile
- Per-kernel GPU time, for finding where time goes (
NUVEC_PROFILE=1).
Structs§
- Buffer
- GPU memory in unified (shared) storage: the CPU reads and writes it in place.
- Command
Buffer - Work being recorded for the GPU: one concurrent compute encoder, with memory barriers inserted only where a dispatch depends on an earlier one.
- Deferred
- The commit of a command buffer queued with
CommandBuffer::enqueue_then: callcommit, from any thread, to hand the work to the GPU. Dropping it commits as well. - Device
- A Metal GPU with its command queue, kernel library and pipeline cache. Cheap to clone.
- Device
Info - What the GPU is and what it can do.
- Event
- A counter command buffers wait on
(
CommandBuffer::wait_event) and the CPU raises (signal). Waiters for a value run once the counter reaches it. - Memory
Stats - Memory use and limits of a device’s allocator, in bytes.
- Pending
- A command buffer committed with
CommandBuffer::commit_then. Dropping it does not wait;waitblocks until the GPU has finished and the completion has run (on this thread, if Metal’s handler has not started it yet). - Pipeline
- A compiled compute kernel. Cheap to clone.
- Submitted
- Submitted GPU work.
waitfor it to finish; dropping it also waits (and discards a GPU error). - Timeline
- Orders command buffers that are committed without waiting: each command buffer created
on a timeline starts its work only after the previous one’s work has finished. Buffers
are untracked, so consecutive command buffers would otherwise overlap on the GPU (as
Device::ordered_command_buffers do when they are independent).
Enums§
- Arg
- A kernel argument, bound to the slot of its position in the argument list.
- Constant
- A function constant value for
Device::pipeline_with_constants. - GpuError
- Why a GPU operation failed.
- NaxReason
- Why the Neural Accelerator (NAX) kernels are not used (
NaxStatus::Off). - NaxStatus
- Whether products run on the Neural Accelerator kernels (
crate::Device::nax).
Constants§
- VERSION
- The version of this crate.
Functions§
- allocation_
size - The bytes the allocator charges (in
active) for a buffer oflenbytes: its size class (256-byte steps up to one page, whole pages beyond);Noneif that overflows. - mapping_
size - The bytes mapping a file of
lenbytes counts inmapped: the whole file, rounded up to the system’s pages. - page_
size - The system’s page size: the granularity of file mappings (
map_file_rangeoffsets). - physical_
memory - The machine’s physical memory in bytes, with or without a GPU:
NSProcessInfoon macOS,MemTotalof/proc/meminfoon Linux, 0 where neither is available.