metal
Typed Apple Metal compute bindings, generated over Apple's Metal framework on top of the objc runtime bridge. Wrap an MTLDevice handle with metal::Device::from_raw(ptr), then chain into new_command_queue(), new_buffer_with_length(len, options), new_library_with_source(src, opts, err) (or new_library_with_data(...)), new_function_with_name(name), and new_compute_pipeline_state_with_function(fn, err). Each of those is fallible: it returns an option::Option[T] — Some on success, None when Metal hands back nil — instead of trapping. Objects the package allocates itself (descriptors and similar alloc/init values) carry a drop(ref this) that rt::releases the +1 reference; the borrowed MTLDevice / MTLBuffer / MTLLibrary protocol handles are non-owning and have no drop.
Because every step returns an Option, guard let reads the happy path straight through and bails on the first None:
import "metal/metal" as metal;
import "stdlib/option" as option;
let dev = metal::Device::from_raw(device_ptr); // an MTLDevice you already hold
let opts = metal::CompileOptions::from_raw(0 as *u8); // nil options = compiler defaults
guard let option::Option[metal::CommandQueue]::Some(queue) =
dev.new_command_queue() else { return 1; };
guard let option::Option[metal::Library]::Some(lib) =
dev.new_library_with_source(msl_source, opts, 0 as *u8) else { return 1; };
guard let option::Option[metal::Function]::Some(kernel) =
lib.new_function_with_name("add") else { return 1; };
guard let option::Option[metal::ComputePipelineState]::Some(pso) =
dev.new_compute_pipeline_state_with_function(kernel, 0 as *u8) else { return 1; };
For pre-tuned CPU numerics that ship in every macOS binary — the "no GPU" fallback and result-checking reference — see accelerate.