Skip to content

Instantly share code, notes, and snippets.

@benvanik
benvanik / quake-on-xdna.md
Last active September 21, 2026 15:14
Quake across CPU, NPU, and GPU with Loom: shared memory, incremental publication, spatial page preparation and rasterization, and a resident GPU consumer. Video, diagrams, C++, and native IR.

Quake across CPU, NPU, and GPU with Loom

Quake renders through a streaming CPU → NPU → GPU pipeline on a single Ryzen AI Max+ 395. The CPU produces work, sixteen XDNA tiles prepare texture pages and rasterize it, and a Radeon shader consumes the pixels as they arrive. Vulkan samples the resulting shared image to compose the game, its interface, and a CRT effect.

Each stage can make progress when its own input is ready. There is no device-wide barrier between the streaming stages, no CPU relay for each completed batch, and no staging copy at the NPU → GPU or compute → Vulkan handoffs. CPU preparation, NPU execution, and GPU consumption overlap within a frame; a bounded frame ring also permits work on successive frames to overlap.

Loom compiles both the NPU workers and the GPU consumer. libamdf supplies native XDNA memory and queue access, and explicit ownership connects that work to the AMDGPU execution path and Vulkan. The result is a program whose processors cooperate across the chip instead of meet

@benvanik
benvanik / doom-on-the-npu.md
Last active September 24, 2026 18:49
Doom rasterized on XDNA: an intrusive thought, a composable compiler stack, and ten resident NPU workers. Video, spatial diagrams, C++, Loom IR, native Low, and measurements.

Next: Quake on XDNA — sixteen cooperating NPU tiles, texture paging, vector rasterization, and the path to CPU→NPU→GPU streaming.

Doom on the NPU: an intrusive thought meets a compiler stack

Three weeks ago, Loom had no XDNA backend. On September 17, native XDNA compilation and experimental execution landed in main. On September 18, we were playing Doom with its world rasterized by ten NPU tiles, using a C++ pixel worker imported through Loom.

The idea began as a joke. The speed came from being able to compose substantial pieces we had already built: a compiler with reusable analyses and explicit hardware models, a native device-access library, and now a C/C++ frontend. An unexpected application gave those pieces a chance to meet.

loom-npu-doom.mp4
@benvanik
benvanik / README.md
Created August 22, 2026 01:36
Loom report: AMDGPU rejects a result fragment store into a dynamic strided view

AMDGPU rejects a result fragment store into a dynamic strided view

Summary and impact

Compiling a wave64 F32-accumulating WMMA contraction that stores its result fragment directly into a row-major output view fails during AMDGPU source-to-low lowering. The same contraction compiles when its epilogue first stores the result fragment into a statically shaped LDS view and then copies ordinary vectors to the dynamic output view.

This blocks direct result-fragment publication for dynamically shaped matrix outputs. The available LDS publication path adds storage, barriers, and copy instructions to a performance-critical contraction epilogue.

Observed behavior

@benvanik
benvanik / README.md
Last active August 22, 2026 00:46
Loom report: dynamic AMDGPU fragment-store failure

AMDGPU rejects a result fragment store into a dynamic strided view

Summary and impact

Compiling a wave64 F32-accumulating WMMA contraction that stores its result fragment directly into a row-major output view fails during AMDGPU source-to-low lowering. The same contraction compiles when its epilogue first stores the result fragment into a statically shaped LDS view and then copies ordinary vectors to the dynamic output view.

This blocks direct result-fragment publication for dynamically shaped matrix outputs. The available LDS publication path adds storage, barriers, and copy instructions to a performance-critical contraction epilogue.

Observed behavior

@benvanik
benvanik / loom-template-family-migration.md
Created August 21, 2026 15:25
Migrating Loom code to symbol-backed template families

Migrating Loom code to symbol-backed template families

This is a mechanical source migration for Loom code using the former func.template, func.ukernel, and func.apply operations. The algorithm and provider-selection policy should not change.

1. Inventory the old vocabulary

Search source, tests, expected output, build metadata, and documentation:

rg -n 'func\.(template|ukernel|apply|provider\.decl)' path/to/migration/scope
@benvanik
benvanik / ISSUE.md
Last active July 31, 2026 01:39
rocJITsu gfx1250 four-word WMMA decoder truncation reproducer and fix

rocJITsu waitcheck truncates four-word gfx1250 scaled WMMA instructions

BasicBlock::build_reachable copies decoder input into a three-dword local window, but gfx1250 scaled WMMA instructions occupy four dwords. The decoder reads the second VOP3P word out of bounds, so identical code-object analyses produce zero or varying matrix source registers. Waitcheck consumes those corrupted operands during dependency analysis.

The direct decoder and LLVM both consistently decode:

@benvanik
benvanik / loom_kernel_optimization_workflow.md
Last active July 30, 2026 15:19
From reference graph to hero kernel: a Loom optimization workflow

From Reference Graph to Hero Kernel: A Loom Optimization Workflow

This is a repeatable workflow for turning a hot operation sequence from an existing inference stack into a correct, shape-specialized Loom kernel family. It is aimed at humans and agents doing model-porting work, especially when the reference uses packed or otherwise non-native data types.

The central discipline is simple:

Preserve the numerical contract, improve the semantic cut, prove the

@benvanik
benvanik / README.md
Last active July 19, 2026 18:43
rocJITsu #8831 positive gfx1250 cluster dogfood: Loom FP8/BF16 WMMA kernel, HSACO, disassembly, and validation

rocJITsu #8831: real ID4 gfx1250 cluster dogfood

This is a positive interoperability report for ROCm/rocm-systems#8831. Against the exact PR head, source-built rocJITsu successfully executed Loom's production clustered linear kernel at an actual ID4 short-QKV model shape:

BF16[128,4608] x scaled-FP8-E4M3[4608,13824] -> BF16[128,13824]
@benvanik
benvanik / ISSUE.md
Last active July 19, 2026 16:48
rocJITsu waitcheck: disjoint gfx1250 LDS ASYNCCNT false positive

rocJITsu waitcheck reports disjoint gfx1250 LDS ranges as an ASYNCCNT hazard

rj_waitcheck reports the same missing-s_wait_asynccnt diagnostic for a provably disjoint LDS store and an actually overlapping control.

Standalone reproducer: https://gist.github.com/benvanik/26f51dfc83a608dc271a596fbc279a3d.

The standalone reproducer builds two eight-instruction gfx1250 code objects with the public ROCm SDK. Both set the LDS base to constant zero, issue

@benvanik
benvanik / gfx1250-cluster-identity-review-followup.patch
Created July 19, 2026 15:22
Prototype review follow-up for ROCm/rocm-systems#8826; architectural and test handoff for upstream generator ownership
diff --git a/emulation/rocjitsu/lib/python/amdisa/codegen/_generator.py b/emulation/rocjitsu/lib/python/amdisa/codegen/_generator.py
index e32a7d219b..54c19529a0 100644
--- a/emulation/rocjitsu/lib/python/amdisa/codegen/_generator.py
+++ b/emulation/rocjitsu/lib/python/amdisa/codegen/_generator.py
@@ -2774,6 +2774,8 @@ class CodeGenerator:
constexprs.append(f'constexpr uint32_t HW_REG_IB_STS2 = {ib_sts2_id};')
constexprs.extend(
[
+ 'constexpr uint32_t HW_REG_IB_STS2_CLUSTER_ID_SHIFT = 6;',
+ 'constexpr uint32_t HW_REG_IB_STS2_CLUSTER_ID_MASK = 0xFu;',