Skip to content

gemm: software-pipelined k-loop + INT8 dtype support - #177

Closed
bong-water-water-bong wants to merge 3 commits into
amd:develfrom
1bit-MONSTER:feat/gemm-int8-pipelined
Closed

gemm: software-pipelined k-loop + INT8 dtype support#177
bong-water-water-bong wants to merge 3 commits into
amd:develfrom
1bit-MONSTER:feat/gemm-int8-pipelined

Conversation

@bong-water-water-bong

Copy link
Copy Markdown

Summary

Software-pipeline the k-loop in matmul_vectorized_2x2_mmul and add validated INT8/INT16 dtype support to the GEMM operator.

Kernel (aie_kernels/aie2p/mm.cc)

  • Software-pipelined k-loop: prologue loads k-step 0, loop body consumes the previous step's A/B tiles while prefetching the next, epilogue MACs the final step — hides load→vmac latency on AIE2P.
  • Pipelining hint clamped to the real compile-time trip count (colA−1, in [1,4]) so small K tiles are not mis-scheduled.

Operator (op.py, design.py)

  • Per-dtype tile-multiple validation matching kernel static_asserts.
  • _kernel_dtype_flag selects the correct {combo}_ONLY define; bf16_f32_ONLY under prio_accuracy.
  • Integer outputs narrower than the 32-bit accumulator rejected (i8→i8/i8→i16/i16→i16 truncate).
  • design.py: duplicate npu1 entry merged; i8/i16 MAC dims.

Validation (NPU Strix Halo, XDNA2)

  • i8→i32 bit-exact vs numpy int32 reference at 1024×512×1024, 2048×512×2048, 2048×2048×2048, 2048×2048×8192 (N-partition).
  • ~8.4 TOPS best at 2048³.

bong-water-water-bong added 2 commits August 31, 2026 17:11
- aie_kernels/aie2p/mm.cc: software-pipeline the k-loop in
  matmul_vectorized_2x2_mmul — prologue loads k-step 0, the loop body
  consumes the previous step's A/B tiles while prefetching the next, and
  an epilogue MACs the final step. Hides load->vmac latency (verified
  bit-exact vs numpy int32 on NPU Strix Halo; ~7.8 TOPS at 2048^3 i8->i32).
- iron/operators/gemm/op.py: per-dtype tile-multiple validation matching
  the kernel static_asserts; _kernel_dtype_flag selects the {combo}_ONLY
  define (bf16_f32_ONLY under prio_accuracy since design.py resolves
  matmul_bf16_f32); reject integer outputs narrower than the 32-bit
  accumulator (i8->i8/i8->i16/i16->i16 truncate).
- iron/operators/gemm/design.py: merge duplicate npu1 entry; add i8/i16
  MAC dims for npu1/npu2.
- bench_int8.py / int8_bench.py / run_int8_gemm.py: NPU INT8 GEMM
  benchmarks (bit-exactness + TOPS, 2048^3 and shape sweeps).

Known limits (upstream design, not this kernel): first dispatch after an
xclbin reload in a multi-shape process can race the zero kernel (retry
exact); N=8192 with 8 columns exceeds the aie.dma_bd stride range
(per-column C slice 2^21 > 2^20) — use partition_N for very wide outputs.
- aie_kernels/aie2p/mm.cc: software-pipeline the k-loop in
  matmul_vectorized_2x2_mmul — prologue loads k-step 0, the loop body
  consumes the previous step's A/B tiles while prefetching the next, and
  an epilogue MACs the final step. Hides load->vmac latency on AIE2P;
  the pipelining hint is clamped to the real compile-time trip count
  (colA-1, [1,4]) so small K tiles are not mis-scheduled. Verified
  bit-exact vs numpy int32 on NPU Strix Halo (~8.4 TOPS at 2048^3 i8->i32).
- iron/operators/gemm/op.py: per-dtype tile-multiple validation matching
  the kernel static_asserts; _kernel_dtype_flag selects the {combo}_ONLY
  define (bf16_f32_ONLY under prio_accuracy, matching design.py's
  matmul_bf16_f32 resolution); integer outputs narrower than the 32-bit
  accumulator are rejected (i8->i8/i8->i16/i16->i16 truncate).
- iron/operators/gemm/design.py: merge duplicate npu1 entry; add i8/i16
  MAC dims for npu1/npu2.
NPU2 (Strix Halo): a dispatch can rarely (~5% per process) return a wrong
result after several distinct xclbins compile in one process — the
zero/accumulate write races the first submit on a fresh context and
self-heals on the next dispatch. Document the warm-up + verify + retry
guidance in the GEMM docstring.
@bong-water-water-bong

Copy link
Copy Markdown
Author

Closing — superseded. The INT8 + software-pipelined-k-loop work landed on devel in refined form (64105500f5cc485582ca1), plus the llama prefill fusion (76eee2a) and real-prompt-length sizing (764e7ef) that build on it. The feature branch's older iterations (e670793/84c276a) are fully contained in those devel commits; keeping this PR open would conflict with the same files. Work is verified on Strix Halo XDNA2 (bit-exact INT8, deterministic prefill).

@bong-water-water-bong
bong-water-water-bong deleted the feat/gemm-int8-pipelined branch August 31, 2026 23:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant