For eight years Apple has used a single API — Metal — for graphics rendering and for general-purpose GPU compute, with the same shader language in both cases. At today’s WWDC, 6 June 2022, it announced Metal 3 for macOS Ventura and iOS 16. Beneath the name there is a precise technical structure, and what you can actually do on an Apple Silicon Mac used as a compute environment depends on it.

Context

Until 2014, Apple platforms exposed OpenGL and OpenGL ES for graphics, OpenCL for GPU compute. These are APIs designed between the 1990s and the early 2000s around an implicit-state model: the driver keeps a global state machine, infers when to recompile pipelines, and serialises command submission. On mobile hardware the CPU cost of every draw call weighed disproportionately against the GPU’s actual work.

Apple introduced Metal at WWDC on 2 June 2014, for iOS 8 on the A7 and A8 system-on-chips. The stated goal was to cut the CPU overhead of submission and to make state and resource management explicit. The same direction — explicit control, a thinner driver — later returned in Direct3D 12 (2015) and Vulkan (2016).

Architecture

Metal describes work with a small set of explicit objects. MTLDevice is the GPU. MTLCommandQueue and MTLCommandBuffer hold command queues and batches. Three encoders cover the workload types: MTLRenderCommandEncoder for graphics, MTLComputeCommandEncoder for compute, MTLBlitCommandEncoder for memory copies. Pipeline states (MTLRenderPipelineState, MTLComputePipelineState) are compiled ahead of time and stay immutable at runtime.

Submission is explicit: the application builds a command buffer, commits it to the queue, and handles synchronisation itself, with fences, events and shared events. The driver does not try to guess when a state has changed. Resources (MTLBuffer, MTLTexture, MTLHeap) declare an explicit storage mode — shared, managed, private, memoryless — that fixes where they live and how the CPU reaches them.

The model moves complexity from the driver into the application. In return it removes an entire category of hidden costs: implicit validation, pipeline recompilation at the wrong moment, unrequested copies between memory spaces.

One shader language

Shaders are written in Metal Shading Language (MSL), derived from C++14 with GPU extensions. The same language covers the vertex, fragment, tile and compute stages; with Metal 3 it adds object and mesh shaders. The metal compiler, built on LLVM, produces an intermediate binary in AIR (Apple Intermediate Representation) format, packaged into a metallib. Only at runtime does the driver translate AIR into machine code for the concrete GPU. In practice the same compute source runs on integrated iOS GPUs and on desktop Apple Silicon without rewriting anything.

A minimal compute kernel in MSL — a SAXPY, y = a·x + y — shows the structure:

kernel void saxpy(
    device const float* x [[buffer(0)]],
    device float*       y [[buffer(1)]],
    constant float&     a [[buffer(2)]],
    uint                i [[thread_position_in_grid]])
{
    y[i] = a * x[i] + y[i];
}

The double-bracket attributes bind parameters to binding slots and to the thread’s position in the grid. There is no separate language for compute: the same compiler and the same pipeline serve graphics and compute.

Unified memory on Apple Silicon

With the move to Apple Silicon — M1, November 2020 — memory is physically unified: CPU, GPU and Neural Engine draw on the same DRAM pool. In Metal a resource with the shared storage mode lives in this common memory, with no explicit copies between host and device. It is a structural difference from the discrete-GPU model, where a buffer must be transferred over the PCI Express bus before the GPU can read it.

For compute this reduces or zeroes the data-transfer cost, which on pipelines with many intermediate tensors comes to dominate the total time. The limit shifts to memory bandwidth and to the capacity of the unified pool, shared with the rest of the system.

The compute and machine-learning stack

Above Metal, Metal Performance Shaders (MPS) offers kernels tuned for each Apple GPU family: convolutions, matrix products, FFTs, image filters, neural-network primitives. MPSGraph adds a graph-based API aimed at machine learning, with a role close to that of cuDNN paired with a graph compiler.

The higher-level frameworks rest on this stack. Core ML uses MPS as its GPU execution backend. At this week’s WWDC, Apple and Meta showed the mps device for PyTorch as a preview; it maps operations onto MPSGraph and requires macOS 12.3 or later. There is a tensorflow-metal backend with the same role. The Neural Engine, as a unit of its own, splits the work: generic kernels run on the GPU via MPS, while compatible models pass to the Neural Engine through Core ML.

Limits

Metal is tied to Apple platforms. There is no cross-vendor implementation: MSL code does not run on non-Apple GPUs, and porting a kernel written for CUDA means rewriting it, not recompiling it. Projects such as MoltenVK translate Vulkan onto Metal in user space, but the other way round — running Vulkan code on macOS — not this one.

For heavy compute Apple offers no server hardware. There are no data-centre configurations with Apple GPUs, nor node-to-node interconnects comparable to those used for distributed training on discrete GPUs. The unified memory is large by workstation standards, but it stays shared with the CPU and the system, and its bandwidth — wide as it is on M1 Max and Ultra — does not reach that of high-end dedicated VRAM. Apple Silicon therefore holds up as a prototyping and local-inference environment for medium-sized models; for large-scale training the reference stack stays on discrete GPUs.

The metal compiler and the MSL and MPS documentation are public in the Apple Developer Documentation; the language is specified, even if the driver implementation and the low-level AIR are not.


https://developer.apple.com/metal/ https://developer.apple.com/videos/play/wwdc2022/10066/ https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf https://developer.apple.com/documentation/metalperformanceshaders https://developer.apple.com/metal/pytorch/ https://pytorch.org/blog/introducing-accelerated-pytorch-training-on-mac/ https://www.noze.it/en/insights/apple-metal-api/

Cover image: Close-up of the Apple M1 chip with the integrated heat spreader removed, showing the square silicon die at the center of the package… — photo by Sonic8400, CC0 — https://commons.wikimedia.org/wiki/File:Apple_M1_-_APL1102_-_IHS_removed.jpg