(amdgpu-dma-operations)=
:local:
DMA (or “Direct Memory Access”) operations transfer data between different kinds of memory directly without occupying registers in the invoking wave. They are usually {ref}asynchronous<amdgpu-async-operations> asynchronous, and require the user to explicitly track completion using {ref}asyncmarks<amdgpu-async-operations>.
All DMA operations support the same cache modifiers as ordinary load/store operations from registers. They cannot be performed atomically.
Each GFX9 DMA instruction has a synchronous counterpart (e.g., @llvm.amdgcn.load.to.lds for @llvm.amdgcn.load.async.to.lds). The synchronous variants perform the same operation, but the compiler automatically ensures completion before their side-effects are used.
GFX9 DMA instructions implement volatile (via aux/cpol bit 31) and nontemporal (via metadata) as if they were loads from the global address space.
Flat/Global Addressing
void @llvm.amdgcn.load[.async].to.lds.pN( ptr addrspace(N) %src, ; base pointer to load from (per-lane) ptr addrspace(3) %lds_base, ; LDS base pointer (wave-uniform) i32 immarg %size, ; data byte size: 1/2/4 (12/16 for gfx950) i32 immarg %offset, ; offset applied to both src and LDS address i32 immarg %cpol) ; cache policy
Loads data from global memory to LDS. The data size can be 1, 2, or 4 bytes (gfx950 also allows 12 or 16 bytes). The LDS address is implicitly offset by 4 * lane_id bytes for sizes up to 4 bytes, and by 16 * lane_id bytes for larger sizes.
The %lds_base pointer must be wave-uniform.
The source pointer is overloaded on address space. Supported address spaces are flat (0), global (1), and buffer fat pointer (7).
@llvm.amdgcn.load[.async].to.lds.p7 (buffer pointer) is lowered to @llvm.amdgcn.raw.ptr.buffer.load[.async].lds before instruction selection.
void @llvm.amdgcn.global.load[.async].lds( ptr addrspace(1) %src, ; global base pointer to load from (per-lane) ptr addrspace(3) %lds_base, ; LDS base pointer (wave-uniform) i32 immarg %size, ; data byte size: 1/2/4 (12/16 for gfx950) i32 immarg %offset, ; offset applied to both global and LDS address i32 immarg %cpol) ; cache policy
This is identical to @llvm.amdgcn.load[.async].to.lds.p1.
Buffer Addressing
void @llvm.amdgcn.{raw|struct}[.ptr].buffer.load[.async].lds( %rsrc, ; buffer resource descriptor (SGPR): ; <4 x i32> or ptr addrspace(8) ptr addrspace(3) %lds_base, ; LDS base pointer (wave-uniform) i32 immarg %size, ; data byte size: 1/2/4 (12/16 for gfx950) [i32 %vindex,] ; VGPR buffer index (struct variants only) i32 %voffset, ; VGPR offset (included in bounds checking) i32 %soffset, ; SGPR/imm offset (excluded from bounds checking) i32 immarg %offset, ; imm offset (included in bounds checking) i32 immarg %cpol) ; cache policy
Loads data from a buffer resource to LDS.
The %lds_base pointer must be wave-uniform.
The intrinsics differ in two orthogonal ways:
struct variants add a %vindex argument for indexed buffer addressing.ptr variants use ptr addrspace(8) for the buffer resource descriptor; the non-ptr variants use <4 x i32>.GFX1250 LDS DMA instructions implement nontemporal (via metadata) as if they were loads from the global address space. Tensor DMA instructions do not support volatile or nontemporal.
Global Addressing
void @llvm.amdgcn.{global|cluster}.load.async.to.lds.b<N>( ptr addrspace(1) %src, ; global base pointer to load from (per-lane) ptr addrspace(3) %lds_base, ; LDS base pointer (per-lane) i32 immarg %offset, ; offset applied to both global and LDS address i32 immarg %cpol, ; cache policy [i32 %m0]) ; workgroup broadcast mask, cluster variants only (in M0)
The bit-size encoded in the name can be 8, 32, 64 or 128.
Loads data from global memory to LDS. The %offset is applied to both the global and LDS addresses.
The cluster variants add a %m0 argument for workgroup broadcast. The broadcast mask selects which workgroups within a cluster participate in the load.
void @llvm.amdgcn.global.store.async.from.lds.b<N>( ptr addrspace(1) %dst, ; global base pointer to store to (per-lane) ptr addrspace(3) %lds_base, ; LDS base pointer to load from (per-lane) i32 immarg %offset, ; offset applied to both global and LDS address i32 immarg %cpol) ; cache policy
Stores data from LDS to global memory.
Tensor Addressing
void @llvm.amdgcn.tensor.{load.to|store.from}.lds( <4 x i32> %desc0, ; D# group 0 <8 x i32> %desc1, ; D# group 1 <4 x i32> %desc2, ; D# group 2 (zero-init for D# up to 2D) <4 x i32> %desc3, ; D# group 3 (zero-init for D# up to 2D) <8 x i32> %desc4, ; D# group 4 (reserved, use zeroinitializer) i32 immarg %cpol) ; cache policy
Loads or stores data between global memory and LDS using a tensor descriptor (D#). The descriptor is split across multiple groups. GFX1250 supports up to 4 descriptor groups; %desc4 is reserved for future targets and must be zero-initialized.
Despite the absence of .async in their names, these intrinsics are asynchronous.
All arguments must be wave-uniform.