macuda RTX 5090 · Apple Silicon
AI systems engineering · CUDA on Apple Silicon

CUDA inference on a Mac.
Powered by an RTX 5090.

macuda connects an Apple Silicon Mac to an NVIDIA GPU over Thunderbolt. A custom driver and CUDA compatibility layer run the unmodified CUDA backends of llama.cpp and stable-diffusion.cpp, with dense-model decode throughput at 97–98% of the Windows reference in the published benchmark batch.

97–98%
of Windows reference decode throughput on the three dense models tested
0
NVIDIA driver or runtime binaries executing on the Mac
~15k
lines of C across the driver, CUDA runtime and BLAS compatibility libraries
9
models in the benchmark batch: six language models and three image models

A CUDA stack built for macOS

Running an NVIDIA GPU from an Apple Silicon Mac requires more than a Thunderbolt connection. The applications need a CUDA runtime, a GPU driver and a way to access the hardware. macuda provides those layers for the workloads tested here.

The project combines three C libraries with a split compilation workflow. Together, they initialise the GPU, manage memory and execute CUDA kernels from native macOS applications. The host application is compiled for the Mac; the GPU code is compiled with NVIDIA's toolchain on Linux.

The engineering approach. Keep the applications' CUDA backends intact and implement the interfaces beneath them, from memory allocation and kernel launches to firmware initialisation and hardware queues.

From application to GPU

The application calls a CUDA compatibility layer, which submits work through the userspace driver. tinygrad's DriverKit extension provides hardware access over Thunderbolt.

llama.cpp · stable-diffusion.cpp
Open-source AI applications built for macOS with their unmodified CUDA backends.
▼  calls the CUDA runtime, as any CUDA program does
libtinycudart + libtinycublas
Compatibility libraries for CUDA runtime and matrix operations. They implement the API calls used by these applications to allocate memory, transfer data, load kernels and synchronise execution.
▼  asks the driver for memory, launches, transfers
libtinynv
A C userspace driver that initialises the GPU firmware, manages memory mappings and submits work directly to hardware queues.
▼  reads and writes the card's registers and memory
TinyGPU.app + DriverKit extension
A signed system extension from tinygrad that exposes PCI configuration, memory windows and direct memory access (DMA) to the userspace driver.
▼  Thunderbolt 5 / USB4v2, 80 Gb/s, PCIe ×4
RTX 5090 (GB202) in an AORUS AI BOX
32 GB of GPU memory, connected to the Mac through a Thunderbolt enclosure.

The driver layer is a C port of the userspace NVIDIA driver in tinygrad, using NVIDIA's own published structure definitions from open-gpu-kernel-modules. The GPU runs NVIDIA's signed GSP firmware, downloaded from linux-firmware and hash-checked. NVIDIA's headers, firmware and Linux compiler remain part of the workflow; no NVIDIA driver or runtime binary executes on the Mac.

One application, two compilation targets

A CUDA application contains host code for the CPU and device code for the GPU. macuda compiles those components separately, then combines them into a native macOS executable.

The executable links against macuda's driver and compatibility libraries. Building device code requires the Linux toolchain, locally in a container or over SSH; running an application built with a precompiled kernel archive does not.

Validated workloads

Text generation

Six language models, up to 35B

Dense, hybrid and mixture-of-experts models reach 91–101% of Windows reference decode throughput. Prompt-processing results vary by model and are reported separately.

Model serving

An OpenAI-compatible API

llama-server with speculative decoding reached 124 tok/s on a first single-stream request and approximately 207 tok/s across eight concurrent slots. A 20-minute test completed 440 requests with no errors.

Image generation

Three diffusion models

SDXL Turbo in 2.78 s, Stable Diffusion 1.5 in 3.71 s and Z-Image Turbo at 1024 × 1024 in 10.06 s. PNG outputs matched the project's validation runs byte for byte.

Split inference

GPU prefill, Metal decode

A 49.6 GB model can use the RTX 5090 for prompt processing, then transfer its state to the Mac for generation. A 23,692-token prompt took 15.2 s on the RTX 5090 versus 35.7 s on Metal in the 16 September test.

Scope and limitations

Explore the project