Essentials
Query the system, select a GPU and wait for GPU work. See Tasks and synchronization for execution ordering.
Metal — Module
MetalProgram Apple GPUs from Julia: GPU arrays (MtlArray), kernels written in Julia (@metal), and wrappers of Apple's Metal (Metal.MTL), Metal Performance Shaders (Metal.MPS) and Metal Performance Shaders Graph (Metal.MPSGraphs) frameworks.
Versions and support
Metal.jl generates code for the newest Metal Shading Language (MSL), AIR and metallib versions the host macOS supports. See Apple's Detecting GPU features and Metal software versions.
Metal.functional — Function
Metal.functional()Report whether Metal.jl can be loaded and used.
Metal.versioninfo — Function
Metal.versioninfo(io::IO=stdout)Print the versions of macOS, the toolchain and the Metal shading language, AIR and metallib versions Metal.jl generates code for, the relevant Julia packages, Metal-related environment variables and preferences, and the available GPUs. Include this when reporting issues.
Metal.macos_version — Function
Metal.darwin_version — Function
Metal.metal_support — Function
Metal.metal_support(macos=macos_version())::VersionNumberReturns the highest Metal Shading Language version supported by macos (defaulting to the host macOS version).
See also Metal.metallib_support and Metal.air_support.
Metal.air_support — Function
Metal.air_support(macos=macos_version())::VersionNumberReturns the highest embedded-AIR-bitcode version supported by macos (defaulting to the host macOS version).
See also Metal.metallib_support and Metal.metal_support.
Metal.metallib_support — Function
Metal.metallib_support(macos=macos_version())::VersionNumberReturns the highest metallib file-format version supported by macos (defaulting to the host macOS version).
See also Metal.air_support and Metal.metal_support.
Metal.metal_target — Function
Metal.metal_target(macos=macos_version())::VersionNumberReturns the Metal Shading Language version Metal.jl emits by default, which tracks the host-supported version (see Metal.metal_support) to expose the newest intrinsics.
Metal.air_target — Function
Metal.air_target(macos=macos_version())::VersionNumberReturns the embedded-AIR-bitcode version Metal.jl emits by default, which tracks the host-supported version (see Metal.air_support).
Metal.metallib_target — Function
Metal.metallib_target(macos=macos_version())::VersionNumberReturns the metallib file-format version Metal.jl emits by default, which tracks the host-supported version (see Metal.metallib_support).
Devices and global state
Every Julia task has a current device and, per device, a command queue that its GPU work is submitted to.
Metal.device — Function
device()::MTLDeviceReturn the Metal GPU device associated with the current Julia task.
Since all M-series systems currently only externally show a single GPU, this function effectively returns the only system GPU.
device(<:MtlArray)Get the Metal device for an MtlArray.
Metal.device! — Function
device!(dev::MTLDevice)Sets the Metal GPU device associated with the current Julia task.
Metal.MTL.devices — Function
devices()Return the Metal GPUs of the system, as a vector of MTLDevices.
Metal.MTL.MTLDevice — Type
MTLDeviceA Metal GPU (MTLDevice), as returned by Metal.device() and Metal.devices(). Its properties are those of Apple's MTLDevice, e.g.:
dev.name: the name of the GPU, e.g.,"Apple M1".dev.maxThreadsPerThreadgroup: the maximum threadgroup size, per dimension.dev.maxThreadgroupMemoryLength: the maximum amount of threadgroup memory, in bytes.dev.recommendedMaxWorkingSetSize: the memory the GPU can use without affecting its performance, in bytes (seeMetal.total_memory).dev.currentAllocatedSize: the memory currently allocated on the GPU, in bytes.
MTL.supports_family(dev, MTL.MTLGPUFamilyApple9) checks whether the GPU belongs to a GPU family.
Metal.global_queue — Function
global_queue(dev::MTLDevice)::BatchedCommandQueueReturn the BatchedCommandQueue associated with the current Julia task.
This is a batched queue: kernel launches and blit operations accumulate into a single command buffer and are submitted lazily, rather than one command buffer per operation. It is a drop-in for a raw MTLCommandQueue — using it as one (e.g. to derive a command buffer, or for MPS) preserves program order by draining pending batches when command buffers are enqueued or committed. Call synchronize to wait for submitted work to finish. See BatchedCommandQueue for the full draining semantics.
Metal.BatchedCommandQueue — Type
BatchedCommandQueueA command queue that batches GPU work to amortize Metal's per-command-buffer submission latency. Kernel launches (@metal) and GPU-side blit operations (copyto!, fill!) are encoded into a single open command buffer and committed lazily, instead of one command buffer per operation.
It wraps, and is a drop-in for, the MTLCommandQueue it batches: properties that aren't its own (e.g. label) forward to the underlying queue.
How the work is encoded and submitted is up to its CommandBackend type parameter: Metal3Backend using the Metal 3 command API, or Metal4Backend using the Metal 4 one, as selected by the command_api preference.
The open batch is committed ("flushed") when any of the following happens:
synchronizeis called on the queue (or on one of its command buffers);- a command buffer derived from the queue is enqueued or committed;
- command batching is disabled with the
command_batching = falsepreference; - the batch reaches
command_batching_ops()operations orcommand_batching_bytes()of blit traffic; - a GPU profiler is attached, in which case batching is disabled (each operation gets its own command buffer) so per-operation GPU timing is preserved;
- an immediate submission is requested via
@metal ... submit=true, orMetal.flush!is called explicitly.
Program order is preserved across flushes: command buffers execute in commit order and dispatches within an encoder run serially. At most command_batching_inflight() command buffers are kept in flight; further submissions block until the GPU drains one. Obtain the current task's batched queue with global_queue.
BatchedCommandQueues are task-local, but are only mutated while holding a global lock, so that other tasks can flush them too. Sharing a raw MTLCommandQueue across tasks is unsupported. Once the owning task has finished, any task's synchronize flushes and waits for the work it left behind, so results of a task are visible after waiting for it. device_synchronize flushes the batches of all tasks, which supports @async work and the REPL synchronization hook.
Synchronization
GPU work executes asynchronously. These functions wait for it to finish, and throw the errors it reported.
Metal.synchronize — Function
synchronize(queue=global_queue(device()))Wait for currently committed GPU work on queue to finish. This includes work left behind by tasks that have finished, so that their results are visible after waiting for them.
synchronize(cmdbuf::MTLCommandBufferLike)Wait for cmdbuf (which must already have been committed) and all preceding work on the same queue to complete.
Metal.device_synchronize — Function
device_synchronize()Synchronize all committed GPU work across all global queues.
Metal.@sync — Macro
Metal.@sync exEvaluate ex, then wait for the GPU work of the current task to finish, with synchronize, and return the value of ex. Use it, e.g., to time GPU work with @time or @btime.
Metal.KernelException — Type
KernelExceptionAn exception thrown by a kernel, e.g., a BoundsError from an out-of-bounds access. Kernels cannot throw to the host while executing, so the first exception is recorded, and thrown by the next synchronize or device_synchronize after the kernel finished.
How much is reported depends on the kernel's debug_level (see @metal): at level 1, the default, the type of exception and its reason; at level 2, also the position of the thread that threw and a device-side backtrace.
Metal.MTL.CommandBufferError — Type
CommandBufferErrorAn error reported by one or more Metal command buffers at a synchronization boundary. The errors field contains the original NSError domain, code, and description, plus the command-buffer and queue labels when available.
KernelAbstractions
Metal.MetalKernels.MetalBackend — Type
MetalBackend()The KernelInterface back end for running on Metal GPUs, which KernelAbstractions uses to launch @kernel kernels.