Repository navigation
honeykrisp: expose VK_AMD_shader_core_properties2 - #36
joshuaswarren wants to merge 1 commit into
Conversation
Report the active GPU core count through activeComputeUnitCount, taken from agx_get_num_cores(). llama.cpp reads this property to decide how many workgroups a decode flash attention dispatch needs. Without a core count it assumes 16, so 32-head decode runs as 32 workgroups on a 32-core M1 Max, and each workgroup walks the whole KV cache serially. Measured on an M1 Max with llama-2-7B Q4_0, FA decode op, 32 heads, head size 128, f16 KV, at KV 4096: 942 us with the placeholder, 578 us when the core count is 32. A consumer that also scales the count (a 4096-KV run with an effective 64) reaches 411 us.
[Medium impact] The change affects Vulkan capability queries on Honeykrisp devices. The required parent extension must be implemented and advertised before this is safe to merge. Findings
SummaryHoneykrisp now advertises
Reviews (1) · Last reviewed commit: "honeykrisp: expose VK_AMD_shader_core_pr..." · Reviewed by Greptile |
| .KHR_vulkan_memory_model = true, | ||
| .KHR_workgroup_memory_explicit_layout = true, | ||
| .KHR_zero_initialize_workgroup_memory = true, | ||
| .AMD_shader_core_properties2 = true, |
There was a problem hiding this comment.
Required parent extension is missing
VK_AMD_shader_core_properties2 requires VK_AMD_shader_core_properties, but Honeykrisp advertises only the former. An app that enables both extensions to meet that requirement gets VK_ERROR_EXTENSION_NOT_PRESENT from vk_device_init. Apps that check dependencies first must skip the new extension instead.
Implement and advertise the required parent extension, including its properties, before exposing this one.
|
Hardware check on a 16-inch M1 Max MacBook Pro (Linux, honeykrisp built from the installed lab base 69bde15 plus this one change, private build, system driver untouched). llama.cpp Vulkan, llama-2-7B Q4_0, flash attention on, tg64, 3 repetitions per cell, order system / patched / patched / system, same unmodified llama-bench binary:
Depth 0 is unchanged. At depth 4096 decode is 30% faster (15.8 to 20.6 tok/s). The device loads and runs normally with the extension exposed. Without the extension, llama.cpp assumes 16 compute units and splits the flash-attention decode into too few workgroups for a 32-core GPU (measured in an earlier op-level test); I did not log the split chosen in this run. Earlier on the stock lab Mesa, with llama.cpp patched to pass the real core count, the same model went from 18.3 to 26.3 tok/s at depth 4096. Absolute numbers in the table are lower than in that run; I did not isolate why. The A/B pairs agree within 1%. Not covered: other Vulkan applications that query this extension, and a CTS run. |
|
Follow-up with the core count and the four-way comparison, same 16-inch M1 Max MacBook Pro, llama-2-7B Q4_0, flash attention on, tg64, 3 repetitions per cell, run order S M B F F B M S (means of the two runs per arm). With this change the driver reports
B and F agree within 1% at every depth. So the honest core count and the placeholder-64 path land on the same split; the extra gain over M comes from the multiplier in llama.cpp, not from a different core count. This change alone gives the +31% at depth 4096; a correct multiplier on the llama.cpp side adds the rest. Absolute tok/s are lower than in my first run on the same machine (the system-driver depth 4096 cell was 18.3 then, 15.8 now); I did not isolate why, and each comparison above is within one run. |
|
GREEN at 8092feb — opencode-go/glm-5.3-flash as routed by Main (model id unverifiable); implementer model unverified. The plumbing is complete: enabling AMD_shader_core_properties2 in hk_get_device_extensions plus filling .activeComputeUnitCount in the flat struct vk_properties is all that is needed — vk_physical_device_properties_gen.py generates both the flattened properties struct and the GetPhysicalDeviceProperties2 emitter from vk.xml (which contains VkPhysicalDeviceShaderCoreProperties2AMD), so the struct is emitted with the core count once the extension flag is set; agx_get_num_cores (sum of per-cluster core_masks) is pre-existing and is the same count the driver uses elsewhere. No behavior change for apps that do not query it, as stated. CI 6x SUCCESS + 1 SKIP at this head. Caveat carried from the description: the measured table came from overriding the count in llama.cpp, so the owed boot-check on an M1 Max (activeComputeUnitCount reads 32) is still the device-side proof. |
agx_lower_agx3_g18g_half_icmpsel was ported without its call, so the rewrite never ran. A signed half compare-select refused in the first compile attempt and compiled only in the second one (float constants in registers). Call it after mixed-width unary lowering, as mesa-aurora omacom#36 does. test-agx3-compile-fail-closed compiles signed less-than and greater-or-equal half compare-selects (register and immediate arms) as G18G in a child with AGX_MESA_DEBUG=shaders and requires a first-attempt binary. Before the call the six cases fail with retried=1; after it they pass. meson test --suite asahi: 40 of 40 OK. Signed-off-by: Joshua Warren <816217+joshuaswarren@users.noreply.github.com>
Honeykrisp reports no GPU core count, so consumers guess. llama.cpp reads
VK_AMD_shader_core_properties2(activeComputeUnitCount) to size its flash attentionsplit_k; without it, it assumes 16 cores. With 32 heads and one query row that gives 32 workgroups on a 32-core M1 Max, each walking the whole KV cache serially.This exposes
VK_AMD_shader_core_properties2and fillsactiveComputeUnitCountfromagx_get_num_cores(). No behavior change for apps that do not query it.Measured on a 16-inch M1 Max (32 cores), llama-2-7B Q4_0, FA decode op, 32 heads, head size 128, f16 KV, KV 4096:
End to end, token generation at 4096 context goes from 18.3 to 26.3 tok/s once the app also scales the count 2x (llama.cpp side patch is carried in our fork; upstream llama.cpp does not accept agent-authored PRs). Not tested yet on a build of this branch: the numbers above come from overriding the count in llama.cpp, so the driver change needs a boot-check that
activeComputeUnitCountreads 32 on an M1 Max.