Skip to content

Backends

Each backend reads .wbin and emits input for a vendor compiler. The vendor toolchain produces executable GPU code.

BackendOutputTargetToolchain
wave-metalMetal Shading LanguageApple GPUsMetal compiler and runtime
wave-ptxPTX assemblyNVIDIA GPUsCUDA ptxas
wave-hipHIP C++AMD RDNA and CDNA GPUsROCm hipcc
wave-syclSYCL C++Intel Xe and Arc GPUsoneAPI DPC++

The Metal backend emits MSL compute functions.

Kernel metadata determines the number of local uint registers. Floating-point operations reinterpret their bits with as_type<float>.

Local memory uses a threadgroup byte array sized from kernel metadata. Device memory uses one device byte-buffer parameter. Instructions access that allocation through byte offsets.

WAVE instructionMSL operation
wave_shufflesimd_shuffle
wave_shuffle_xorsimd_shuffle_xor
wave_reduce_addsimd_sum
wave_ballotSIMD-group ballot
wave_broadcastsimd_broadcast

A barrier emits threadgroup_barrier with both threadgroup and device memory flags. Fences emit atomic_thread_fence at SIMD-group, threadgroup, or device scope with sequentially consistent ordering. System-scope fences are rejected.

The backend uses 32-lane wave behavior. Other widths require compatible lowering. Metal does not provide the double-precision arithmetic needed by WAVE f64 operations. Calls requiring function extraction are rejected.

The PTX backend emits assembly for the selected shader model. The measurement suite targets SM 75.

WAVE register bits use .b32 registers. Floating-point operations move those bits to .f32 registers. Wide values combine consecutive WAVE registers into 64-bit temporaries.

mov.b32 %f0, %r0;

Separate floating-point addition, subtraction, and multiplication use explicit rounding modifiers to preserve their rounding boundaries. Fused multiply-add remains an explicit operation.

Local memory uses a PTX .shared allocation. Device accesses add WAVE byte offsets to the 64-bit device-memory base pointer and use ld.global or st.global.

Local and device atomics use atom.shared and atom.global. Subtraction negates the operand before atomic addition. Compare-and-swap supplies separate expected and desired operands.

The selected PTX version and shader model constrain the available instructions. The vendor assembler checks whether the generated program is valid for that target.

The HIP backend emits C++ kernels compiled with hipcc.

WAVE registers become local uint32_t values. __uint_as_float and __float_as_uint reinterpret binary32 values.

Local memory uses a dynamically sized shared allocation whose size is supplied at launch. Device memory uses a byte-pointer argument.

WAVE instructionHIP operation
wave_shuffle__shfl
wave_shuffle_xor__shfl_xor
wave_ballot__ballot
wave_reduce_addShuffle-tree reduction
wave_broadcastShuffle from a shared source lane

The backend queries warpSize. A kernel's collective algorithm must still support the resulting 32- or 64-lane grouping.

Workgroup barriers use __syncthreads. Fences use __threadfence_block, __threadfence, or __threadfence_system according to scope.

Reduction lowering uses a sequence of shuffle and arithmetic operations. Register allocation and scheduling depend on the target compiler. RDNA and CDNA wave widths can change the communication pattern and resource cost.

The SYCL backend emits a launch function that submits a kernel through a SYCL queue.

Local uint32_t values hold WAVE registers. sycl::bit_cast reinterprets floating-point bits.

A local_accessor<uint8_t, 1> supplies workgroup-local memory. A USM byte pointer supplies device memory. The generated launch function constructs the command group and dispatch dimensions.

Sub-group operations implement lane selection, shifts, XOR permutation, and reduction. The kernel obtains its sub-group from nd_item::get_sub_group.

The backend uses atomic_ref for memory updates and atomic_fence for scoped ordering.

The generated kernel does not request a fixed subgroup size. The target chooses it, so kernels must use compatible collective algorithms. Local-memory accessors also require host-side command-group construction.

BackendMechanism
Metalas_type<float>
PTXmov.b32
HIP__uint_as_float
SYCLbit_cast<float>
BackendStorage
Metalthreadgroup byte array
PTX.shared byte allocation
HIPDynamic __shared__ byte allocation
SYCLlocal_accessor
BackendOperation
Metalthreadgroup_barrier
PTXbar.sync 0
HIP__syncthreads
SYCLgroup_barrier

See Emulator for CPU execution of the same binary format.