On Strix Halo the CPU and iGPU share one physical memory pool (unified memory). That is great for fitting big models — and confusing, because every tool in the stack reports a different size for “GPU memory”. This page maps each number to what it actually is, using real captures from the tested machine: a Corsair AI Workstation 300 with Ryzen AI Max+ 395, Radeon 8060S and 128 GiB of memory.
The unified-memory architecture, as observed
Ryzen AI Max+ has no discrete GPU memory. The Radeon 8060S reads and writes
the same LPDDR5 channels as the CPU (vendor specs market this as LPDDR5X;
dmidecode on this machine reports Type LPDDR5), through a GTT (Graphics
Translation Table) that maps an aperture into system RAM. From this machine’s
capture:
- Memory is one pool:
free -hreports 124 GiB total (the modules are 8 × 16 GB — 16 GiB each, which dmidecode prints as “16 GB”; the sysfs GTT total of exactly 137,438,953,472 bytes = 128 GiB confirms the binary reading). Type is reportedLPDDR5, 8000 MT/s configured, 8532 MT/s measured. - Inference competes with the OS for the same memory controller — one pool, shared bandwidth. There is no “GPU memory” to be starved separately.
- The BIOS “dedicated” iGPU memory setting on this machine is 1 GiB —
the minimum the Corsair AI Workstation 300’s BIOS offers. It maps 1:1 to
what dmesg reports: the
VRAM: 1024Mvisible aperture is that dedicated slice. - The large GTT is a separate mechanism from that split: it is sized by the
kernel command line (
amdgpu.gttsize=131072/ttm.pages_limit, see above), not by BIOS. Minimal dedicated slice + a full-pool GTT is what makes the whole box behave as one unified pool for GPU workloads.
What the kernel says at boot
Trimmed from dmesg on the tested machine — this is the ground truth for the
aperture layout:
[ 4.023700] amdgpu 0000:c5:00.0: amdgpu: VRAM: 1024M 0x0000008000000000 - 0x000000803FFFFFFF (1024M used)
[ 4.023804] amdgpu 0000:c5:00.0: amdgpu: amdgpu: 1024M of VRAM memory ready
[ 4.023805] amdgpu 0000:c5:00.0: amdgpu: [drm] Configuring gttsize via module parameter is deprecated, please use ttm.pages_limit
[ 4.023806] amdgpu 0000:c5:00.0: amdgpu: amdgpu: 131072M of GTT memory ready.
Two things to notice:
- The “VRAM” aperture is only 1 GiB. On a discrete GPU that line would be the card’s onboard memory; here it is a small visible window. The number that matters is the next one: 131072 MiB (128 GiB) of GTT memory ready — the full physical pool, addressable by the GPU.
- The kernel deprecates
amdgpu.gttsize. This machine’s command line passes bothamdgpu.gttsize=131072andttm.pages_limit=33554432(× 4 KiB pages = the same 128 GiB), plusttm.page_pool_size=33554432andiommu=pt. Newer setups should rely onttm.pages_limit; the value is already in/proc/cmdlineif you want to audit it.
What each tool reports (measured)
| Tool / source | Shows (measured on this machine) | What it actually is |
|---|---|---|
free -h | 124 GiB total | physical pool available to everything |
dmesg (amdgpu) | 1024 MiB “VRAM”, 131072 MiB GTT | visible aperture / full GTT, set at boot |
/sys/class/drm/card0/device/mem_info_* | gtt_total = 137,438,953,472 B (128 GiB), gtt_used ≈ 34 GiB*; vram_total = 1 GiB, vram_used ≈ 155 MiB* | kernel’s live accounting of both apertures |
ROCm/HIP — llama-cli --list-devices | ROCm0: AMD Radeon 8060S Graphics (131072 MiB, 83680 MiB free) | the GTT aperture as seen by the runtime; “free” varies with what is loaded |
rocminfo (7.14) | gfx1151 agent listed, but no Memory (MB) line in this capture | version quirk — use --list-devices for the number |
vulkaninfo memoryHeaps (RADV) | two heaps: 43.00 GiB + 86.00 GiB, with live budget (94.91 GiB total at capture time) and usage fields | the driver’s view of the same pool, split into two heaps and reported dynamically (below) |
vulkaninfo memoryHeaps (llvmpipe) | one heap, size = budget = 124.45 GiB, usage 45.73 GiB at capture time | the whole physical pool as seen by the software rasterizer |
*used/budget/usage figures are point-in-time (captures ran around
benchmark sessions); expect them to move with system load.
Vulkan’s view: two heaps and a live budget
Where the kernel, sysfs and ROCm all report one static number (128 GiB GTT), RADV reports two heaps plus dynamic accounting fields:
memoryHeaps: count = 2
memoryHeaps[0]:
size = 46170898432 (0xac0000000) (43.00 GiB)
budget = 33967968256 (0x7e8a61000) (31.64 GiB)
usage = 0 (0x00000000) (0.00 B)
flags:
None
memoryHeaps[1]:
size = 92341796864 (0x1580000000) (86.00 GiB)
budget = 67935936512 (0xfd14c2000) (63.27 GiB)
usage = 0 (0x00000000) (0.00 B)
flags: count = 1
MEMORY_HEAP_DEVICE_LOCAL_BIT
sizeis the heap’s total;budgetis what the driver/OS currently says is available to the application;usageis what this device has taken. Re-runvulkaninfounder load and the budget numbers move — unlike the kernel/sysfs values, these are not static hardware facts.- The two heap sizes (43 + 86 = 129 GiB) reconcile exactly with **128 GiB GTT
- the 1 GiB visible VRAM aperture** from dmesg — same memory, re-sliced by the driver.
- Heap 0 carries no flags; heap 1 carries
MEMORY_HEAP_DEVICE_LOCAL_BIT— i.e. the larger 86 GiB heap is the one RADV marks as “device local” (the smaller 43 GiB heap is shared). On a unified-memory APU both are still system RAM; the bit only steers allocation preference. - llvmpipe, for comparison, exposes the whole pool as a single 124.45 GiB heap and reports live system usage in it — a reminder that “usage” on an iGPU is just system RAM usage wearing a GPU costume.
- Running
vulkaninfoover SSH (no display) also prints loader noise that the block above omits: on this machine anERRORabout a non-functional NVIDIA ICD (libGLX_nvidia.so.0, from a straylibnvidia-gl-595package — there is no NVIDIA GPU in the box), a skippedlibvulkan_dzn.so, and'DISPLAY' not set... skipping surface info. None of it affects RADV’s output.
Reading the full table: kernel boot message, sysfs and the ROCm runtime all agree on 128 GiB static, Vulkan re-slices it into dynamic heaps that sum to the same memory, and the kernel’s small 1 GiB “VRAM” window never shows up in any user-facing tool. No single number is “the GPU memory” — but on this machine every one resolves to the same physical pool.
Practical allocation limits
- Reserve headroom for OS + desktop + services; a 128 GiB box is not a 128 GiB
model box. On this machine, a 29.1 GB model fully offloaded still left ~49
GiB free per
free -h. - Weights + KV cache + activations must fit inside the remainder with margin:
model file size + ctx × per-token-KV + peak activation < usable RAM. - Watch the system, not the GPU: OOM on Strix Halo is a system-level event — the desktop freezes before anything prints an error.
- Swap is your canary: any swap activity during generation means you are over the practical limit, regardless of what the runtime reported as free. This machine carries an 8 GiB swap file, which will absorb small overruns at a huge speed cost rather than hard-failing.
Examples from measured runs
- Qwen3.8-27B Q8_0 (29.1 GB file), fully offloaded (
-ngl 999, ctx from the benchmark matrix): ran without issue on ROCm and Vulkan — full numbers on the ROCm vs Vulkan page. Observed amdgpu GTT usage after model load: 34,724 MiB / 131,054 on ROCm, 35,544 MiB / 131,054 on Vulkan — a few GiB above the weight file (context + activation working set). - Qwen3.6-35B-A3B-MTP Q8_0 (37.8 GB file), fully offloaded, server idle (observed amdgpu GTT usage after model load): 37,615 MiB / 131,054 MiB on ROCm, 37,382 MiB / 131,054 MiB on Vulkan — same weights in the same pool, no material difference between backends; ~90 GiB of headroom left over.
- Over-limit behavior: not measured on this machine. The largest tested load used ~37.5 GiB of a ~128 GiB pool and no memory pressure was observed in normal use, so no deliberately over-sized run was done. If you do hit the limit, expect a system-level OOM — the desktop freezes before anything prints an error, and this machine’s 8 GiB swap file absorbs small overruns at a huge speed cost rather than hard-failing.
Sources and upstream documentation
- amdgpu kernel driver documentation — the GTT sizing parameters set on this machine’s kernel command line.
- Vulkan specification, memory management — memory-heap concepts behind the
vulkaninforeadouts. - AMD ROCm documentation — the HSA/ROCm side of device reporting.