Repository navigation
Ampere HMMA through Metal 4 tensor operations on Apple10 GPUs: Donkey Kong Bananza's own upscaler goes from 3.82 to 3.00 ms a frame on an M5 - #1334
Conversation
…onkey Kong Bananza's own upscaler goes from 3.82 to 3.00 ms a frame on an M5 dmsh_build.py builds a second library for each shader with HMMA.16816, <key>_bt (hmma_tensor_msl): the same scratch block as the simdgroup_matrix body, with the product as one MetalPerformancePrimitives matmul2d (16x8x16, one SIMD-group) over threadgroup tensors. The reflection names it (hmma_tensor). shader_load takes it on a GPU of the Apple10 family, whose cores have neural accelerators; other GPUs and iOS keep <key>_b, and DM_NVN_HMMA_TENSOR=0 turns it off. A tensor library that fails to build or load leaves <key>_b. On a MacBook M5 (16 GB, macOS 27): the helper's block round trip 1.57 ns a SIMD-group per HMMA against 1.84; in game (DM_UPSCALER=game, DM_NVN_GPUPROF, the same five frames of one docked route) the upscaler encoder 3.00 ms against 3.82, its share of the frame's GPU time 25 % against 29 %. test_dmsh_hmma.py checks the tensor body on the GPU against the CPU reference of mma.m16n8k16. Chain change (26dc2fa9477c -> ce59435185e4). regress.py chain: Donkey Kong Bananza 23638/23638 shaders, 24 changed (reflection and variants only, no MSL); Mario Kart World 11561/11561, 30 changed (its NDSR upscaler, likewise). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # dm/games/040074A01BF12000/README.md # dm/gfx/nvn/dmsh_chain.h # dm/gfx/tools/dmsh_build.py
…st_dmsh_abi ratchet) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…OR=1 and Apple10 runtime selection with DM_NVN_HMMA_TENSOR=1.
# Conflicts: # dm/gfx/nvn/dmsh_chain.h
# Conflicts: # dm/gfx/nvn/dmsh_chain.h
# Conflicts: # dm/gfx/nvn/dmsh_chain.h
# Conflicts: # dm/gfx/nvn/dmsh_chain.h
|
Thanks for this! I checked it against fxd0h's Jetson Orin HMMA recordings (gist) on an M5 Max (Apple10, Metal 4), and it rounds differently from the Orin. This branch merged main before #1897, which made the f16 accumulator sum each block of 8 products in f32 and round once to f16, as Ampere does.
The last row is what I'd suggest. Since The branch also conflicts with main: main's To rerun, use the gist's |
What and why
On an M5, Donkey Kong Bananza's own upscaler (agl's NDSR,
DM_UPSCALER=game) still takes about a quarter of the GPU frame docked (3.1-4.7 ms of 12-14 ms), with its HMMAs already throughsimdgroup_matrix(Ampere HMMA through simdgroup_matrix). Apple10 GPUs (M5) have neural accelerators in each core, which Metal 4 reaches only through tensor operations (MetalPerformancePrimitives).dmsh_build.pynow builds a second library for each shader with HMMA.16816,<key>_bt(hmma_tensor_msl): the same scratch block, with the product as onematmul2d16x8x16 of one SIMD-group over threadgroup tensors. The reflection names it (hmma_tensor), andshader_loadtakes it on an Apple10 GPU only; other GPUs and iOS keep<key>_b, andDM_NVN_HMMA_TENSOR=0turns it off. A tensor library that fails to build or load leaves<key>_b.Reference entry: Ampere HMMA through Metal 4 tensor operations on Apple10 GPUs.
Checked
dm/gfx/tests/test_dmsh_hmma.py(6 tests, including the tensor body on the GPU against the CPU reference ofmma.m16n8k16),dm/tools/tests/test_docs.py,dm/tools/tests/test_nsp_chain.py: pass.microbenchmark of the helper's block round trip: 1.57 ns a SIMD-group per HMMA through
matmul2dagainst 1.84 throughsimdgroup_matrix, identical results;Donkey Kong Bananza (
040074A01BF12000, v458752), docked,DM_UPSCALER=game,DM_NVN_GPUPROF=every:300, two runs of about 2 minutes on one route, the 24 NDSR libraries swapped by hand on chain7a8a6262ad3a:simdgroup_matrixFive comparable frames only; macOS clocks the GPU to the frame, so the share of the frame's GPU time is the comparison that clock changes do not move.
this branch's host and chain
ce59435185e4on the same game:HMMA: Metal 4 tensor operations (<key>_bt libraries, Apple10 GPU), about 2 minutes at 60 fps (p50 16.6 ms), no new[RED]line.regress.py chain): Donkey Kong Bananza 23638/23638 → 23638/23638, 24 changed (reflection and variants only, no MSL); Mario Kart World (0400C3F00006E000, v0) 11561/11561 → 11561/11561, 30 changed (its NDSR upscaler, likewise). These are the only two games on this Mac, so no other game was run._btfor iOS yet), Mario Kart World in game, and whether the pipeline prebuild / prewarm build the_btfunctions or leave them to first use.Docs
docs/reference/<subsystem>.mdentry, andpython3 dm/tools/docs_symptoms.pywas run (the symptom index)dmsh_chain.py --headerwas run anddm/gfx/nvn/dmsh_chain.his part of the change🤖 Generated with Claude Code