From f0edd9d39358fccd12e415c7f0f80b582afe082b Mon Sep 17 00:00:00 2001 From: booth-algo Date: Wed, 1 Jul 2026 18:33:49 +0000 Subject: [PATCH] fix(projection_asm): correct single-pass matmul emission MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two fixes in the single-pass (num_k_tiles <= MAX_K_TILES) path: - Remove three stray `break`s that truncated the K-loop to a single tile, so the matmul only computed 1 of N K-tiles. - Scale the within-group weight-row offset by MLEN. Matrix SRAM is row-granular (one output feature per row), so the offset must be in rows ((wr % (mlen//blen)) * blen * mlen), not elements — otherwise the BLEN output features in a group aliased to the same weights. Co-Authored-By: Claude Opus 4.8 (1M context) --- asm_templates/projection_asm.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/asm_templates/projection_asm.py b/asm_templates/projection_asm.py index 0e43582..6d7113e 100644 --- a/asm_templates/projection_asm.py +++ b/asm_templates/projection_asm.py @@ -198,7 +198,9 @@ def projection_asm( ) lines.append(f"S_ADDI_INT gp{w_actual_register}, gp0, 0 ") else: - lines.append(f"S_ADDI_INT gp{w_actual_register}, gp0, {(weight_row % (mlen // blen)) * blen} ") + # weight rows are 1 output-feature each in matrix SRAM (row-granular), so the + # within-group offset must be in rows: (wr % (mlen//blen)) * blen * mlen. + lines.append(f"S_ADDI_INT gp{w_actual_register}, gp0, {(weight_row % (mlen // blen)) * blen * mlen} ") lines.append( f"S_ADDI_INT gp{intermediate_register}, gp{result_reg}, {(weight_row % (mlen // blen)) * blen} " ) @@ -210,13 +212,10 @@ def projection_asm( lines.append(f"M_MM 0, gp{w_temp_register}, gp{act_reg} ") lines.append(f"S_ADDI_INT gp{w_temp_register}, gp{w_temp_register}, {mlen * mlen} ") lines.append(f"S_ADDI_INT gp{act_reg}, gp{act_reg}, {mlen * batch} ") - break lines.append(f"M_MM_WO gp{intermediate_register}, gp0, 0 ") lines.append(f"S_ADDI_INT gp{intermediate_register}, gp{intermediate_register}, {blen * mlen} ") - break if (weight_row + 1) % (mlen // blen) == 0 and weight_row != out_features // blen - 1: lines.append(f"S_ADDI_INT gp{result_reg}, gp{result_reg}, {mlen * batch} ") - break else: # K-split path chunks = _proj_k_chunks(num_k_tiles, MAX_K_TILES)