Skip to content

flm.GEMM: take M, K, N and the activation as runtime parameters - #200

Draft
hunhoffe wants to merge 10 commits into
develfrom
flm-gemm-rtp-v2
Draft

hunhoffe wants to merge 10 commits into
develfrom
flm-gemm-rtp-v2

Conversation

@hunhoffe

@hunhoffe hunhoffe commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator

Moves flm.GEMM's shape out of the device configuration and into the instruction stream, so one xclbin serves every projection of a model instead of one per shape. All 30 E2B + E4B projection shapes now resolve to a single configuration, asserted by test_one_xclbin_serves_every_shape. M, K, N, the activation and the clamp bounds are runtime parameters.

The parameter buffer is 4 words rather than 10. A word costs ~2.06 µs of dispatch latency across the 32 cores, which is most of a short-prefill dispatch against a ~107 µs floor, so the clamp trio is sent only by a clamp-capable build and n_work/n_drain are derived on-core from a raw N word plus the tile's own column. Separately, split legs (K or N = 10240, where the row-block stride overflows the shim BD's 20-bit iteration step) now retire the oldest transfer as the next is issued instead of draining a whole window and then a whole column-block — worth up to -12.4% on those shapes.

The cost is memtile B residency, which sized the memtile buffer from k_iters and replayed it m_row_blocks times, putting both K and M into the configuration. Against the pre-RTP build, short prefill gets faster (M=256 median -5.5%) and long prefill pays for B's re-reads (M=1024 +13.1%, M=2048 +22.0%). This is a deliberate trade rather than a regression to fix before merge. Recovering it needs a replay count driven from the instruction stream; that is now reachable via aiex.dma_channel_reset_for in the pinned v1.4.3, but the buffer would still be sized from k_iters. Follow-up, not a blocker.

Accuracy is identical to pre-RTP.

PR Merge Checklist

  1. The PR is rebased on the latest devel commit and pointing to devel.
  2. Your PR has been reviewed and approved.
  3. All checks are passing.

andrej and others added 3 commits September 11, 2026 15:59
The FastFlowLM harness registers one mm.xclbin per model and swaps
instruction streams, against a budget of 16 xclbins for the whole model.
This operator baked M, K and N into the core loop bounds, into which columns
it built, and into the memtile's B buffer, so it needed one xclbin per
shape: 11 (K, N, activation) combinations times up to 16 chunk lengths.

Five values move into an L1 buffer the runtime sequence writes and each core
reads once its barrier opens: the column's work and drain counts, M/256,
K/512, and the activation. All columns are now always built, and one with no
work for a shape drains its share of the A broadcast instead. The epilogue
tests its mode once per chunk, outside the vector loop, so each mode keeps a
branch-free inner loop; which modes it can select between stays a build-time
choice, since each costs program memory.

The device body is then a function of the tiling alone, verified byte for
byte across every E2B shape and activation. So the xclbin is built from a
module emitted at a reference shape and the per-shape build produces only
the instruction stream, and the two carry different artifact stems.

The core releases its barrier straight after reading the parameters.
wait_for_value emits LockAction.Acquire, which does not leave the lock
consumed, so without the release a core that runs twice does not wait the
second time and reads the previous dispatch's parameters. Releasing before
the work is safe because the sequence cannot set the barrier again until it
has drained this dispatch's C. The repo's other barrier users never wait
twice -- mha puts its infinite loop inside the wait, softmax writes the same
parameters every dispatch -- so this does not arise there.
test_one_xclbin_serves_every_shape is the regression test; the parametrised
tests cannot catch it, because the aie_context fixture reconfigures the
array between cases.

Dropping B residency is what this costs, and it is not cheap: 12.5% at
M=512, 16.4% at M=1024 and 19.3% at M=2048 on NPU2. Residency sizes the
memtile buffer from K and replays it M/256 times through a buffer
descriptor's repeat count, so it carries both K and M into the
configuration. Restoring it needs a replay mechanism that carries neither.

It does lift a cap: the repeat count expands into the memtile's BD chain at
2 blocks per replay and exceeded its 48-block limit at M=4096, so no shape
with K <= 2048 would build there -- 7 of Gemma4 E2B's 10 projections. All of
them build now.

Verified on this base over all 12 distinct E2B prefill projections at M=256
and M=4096, dispatched back to back on one loaded xclbin with no reset in
between, each checked against a CPU reference; peak 12.2 TFLOP/s at M=4096
K=12288 N=1536. Plus the operator's own suite, 17 non-extensive tests.
The merge of andrej/flm-gemm-rtp was textually clean but left the README
self-contradictory: the new intro says M, K, N and the activation are
runtime parameters, while the FLM-compatibility note I had added in
92080d4 still claimed they were baked in at compile time and called
RTP-selectability "follow-up work" -- which 81e2006 had just done.

- Drop that note entirely; the "Runtime parameters" section it would have
  pointed at now covers the same ground correctly.
- Fix the same stale claim in the shipped-overlay section, and record
  what IS still build-time there: which activations the epilogue can
  select between, since each one compiled in costs program memory.
- design.py: "None of these four" was already stale from 92080d4, which
  added a fifth bullet.

Co-Authored-By: André Rösti <an.roesti@gmail.com>
The RTP work left clamp entirely compile-time, so _config_tag carried the
bound values and every distinct pair forked a whole xclbin -- clamp=(-2,2)
and clamp=(-4,4) built twice over.

Split it the way epilogue_modes already splits activations: the CAPABILITY
stays build-time, the SELECTION and the values go runtime.

- Whether a clamped path exists at all is still -DMM_FUSED_CLAMP, because
  the clamped instantiation costs program memory and a build that never
  clamps should not carry it. That bit stays in _config_tag.
- clamp_enabled and the bounds become RTP words 5-7. Bounds are floats but
  npu_write_rtp writes i32 only, so they travel as raw bit patterns and the
  kernel casts them back with __builtin_bit_cast -- memcpy leaves an
  unresolved external call in the compiled object rather than folding to a
  register move.
- epilogue_body gains a CLAMP template parameter so the clamped and
  unclamped inner loops both stay branch-free; epilogue_dispatch picks
  between them once per chunk, and only compiles the clamped one when the
  capability is on.

Deliberately NOT done: making clamp_enabled a plain runtime branch. That
would double epilogue_body instantiations (mode x clamp), and program
memory is the exact constraint epilogue_modes exists to manage.

Verified on npu2: all four kernel variants (aie2/aie2p x clamp on/off)
compile, 36/36 flm/gemm iter0 tests pass, and the new
test_one_xclbin_serves_every_clamp_bound confirms three different bound
pairs run back to back on one loaded xclbin while an unclamped build
still resolves to a different configuration.

Co-Authored-By: André Rösti <an.roesti@gmail.com>
@github-actions

github-actions Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

CI Test Results

5bbc769 (2026_09_14_23_27_05)

IRON - CI Summary

Examples

iron/applications/llama_3.2_1b
Test Krackan Status Krackan Phoenix Status Phoenix
test_llama_3_2_1b[llama_3.2_1b_prompt_1024_tokens_1] - - -
test_llama_3_2_1b[llama_3.2_1b_prompt_1024_tokens_40] - - -
test_llama_3_2_1b[llama_3.2_1b_prompt_13_tokens_1] - - -
test_llama_3_2_1b[llama_3.2_1b_prompt_13_tokens_40] - - -

Small

iron/operators/axpy
Test Krackan Status Krackan Latency (mean) Phoenix Status Phoenix Latency (mean)
test_axpy[input_length_2048-num_aie_columns_1-tile_size_2048-scalar_factor_3.0] 156.98 350.72
test_axpy[input_length_2048-num_aie_columns_2-tile_size_1024-scalar_factor_3.0] 144.98 354.76
test_axpy[input_length_2048-num_aie_columns_4-tile_size_512-scalar_factor_3.0] 161.18 440.36
test_axpy[input_length_2048-num_aie_columns_8-tile_size_256-scalar_factor_3.0] 191.70 - -
iron/operators/dequant
Test Krackan Status Krackan Latency (mean) Phoenix Status Phoenix Latency (mean)
test_dequant[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048-group_size_32] 178.14 281.34
test_dequant[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024-group_size_32] 173.52 398.54
test_dequant[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024-group_size_32] 182.26 388.72
test_dequant[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512-group_size_32] 158.56 356.00
test_dequant[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512-group_size_32] 188.44 412.76
test_dequant[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256-group_size_32] 178.84 356.06
test_dequant[input_length_2048-num_aie_columns_8-num_channels_1-tile_size_256-group_size_32] 180.16 - -
test_dequant[input_length_2048-num_aie_columns_8-num_channels_2-tile_size_128-group_size_32] 203.86 - -
iron/operators/elementwise_add
Test Krackan Status Krackan Latency (mean) Phoenix Status Phoenix Latency (mean)
test_elementwise_add[input_length_2048-num_aie_columns_1-tile_size_2048] 166.90 479.54
test_elementwise_add[input_length_2048-num_aie_columns_2-tile_size_1024] 163.50 353.16
test_elementwise_add[input_length_2048-num_aie_columns_4-tile_size_512] 215.90 364.32
test_elementwise_add[input_length_2048-num_aie_columns_8-tile_size_256] 225.34 - -
iron/operators/elementwise_mul
Test Krackan Status Krackan Latency (mean) Phoenix Status Phoenix Latency (mean)
test_elementwise_mul[input_length_2048-num_aie_columns_1-tile_size_2048] 174.54 381.00
test_elementwise_mul[input_length_2048-num_aie_columns_2-tile_size_1024] 170.64 350.30
test_elementwise_mul[input_length_2048-num_aie_columns_4-tile_size_512] 185.50 408.20
test_elementwise_mul[input_length_2048-num_aie_columns_8-tile_size_256] 206.26 - -
iron/operators/flm/gemm
Test Krackan Status Krackan Latency (mean) Phoenix Status Phoenix Latency (mean)
test_artifact_stem_differs_from_generic_gemm[M_256-K_512-N_1024] - -
test_artifact_stem_differs_from_generic_gemm[M_512-K_1024-N_2048] - -
test_gemm[M_256-K_512-N_1024-epilogue_gelu-clamp_None-rounding_conv_even] 368.00 - -
test_gemm[M_256-K_512-N_1024-epilogue_none-clamp_(-2.0, 2.0)-rounding_conv_even] 342.80 - -
test_gemm[M_256-K_512-N_1024-epilogue_none-clamp_None-rounding_conv_even] 357.96 - -
test_gemm[M_256-K_512-N_1024-epilogue_none-clamp_None-rounding_floor] 320.28 - -
test_gemm[M_256-K_512-N_1024-epilogue_silu-clamp_None-rounding_conv_even] 445.86 - -
test_gemm[M_256-K_512-N_128-epilogue_none-clamp_None-rounding_conv_even] 345.60 582.52
test_gemm[M_256-K_512-N_1536-epilogue_none-clamp_None-rounding_conv_even] 356.88 - -
test_gemm[M_256-K_512-N_256-epilogue_none-clamp_None-rounding_conv_even] - - 574.32
test_gemm[M_256-K_512-N_320-epilogue_none-clamp_None-rounding_conv_even] - - 598.00
test_gemm[M_256-K_512-N_512-epilogue_gelu-clamp_None-rounding_conv_even] - - 1170.70
test_gemm[M_256-K_512-N_512-epilogue_none-clamp_(-2.0, 2.0)-rounding_conv_even] - - -
test_gemm[M_256-K_512-N_512-epilogue_none-clamp_None-rounding_floor] - - 553.62
test_gemm[M_256-K_512-N_512-epilogue_silu-clamp_None-rounding_conv_even] - - 1340.90
test_gemm[M_256-K_512-N_64-epilogue_none-clamp_None-rounding_conv_even] - - 566.32
test_gemm[M_512-K_1024-N_2048-epilogue_none-clamp_None-rounding_conv_even] 470.92 - -
test_gemm[M_512-K_1024-N_512-epilogue_none-clamp_None-rounding_conv_even] - - 1409.04
test_gemm_split_leg_bounds[iter0] - -
test_gemm_split_leg_bounds[iter1] - -
test_gemm_split_leg_bounds[iter2] - -
test_gemm_split_leg_bounds[iter3] - -
test_gemm_split_leg_bounds[iter4] - -
test_gemm_split_leg_bounds_runs[iter0] - -
test_gemm_split_leg_bounds_runs[iter1] - -
test_gemm_split_leg_bounds_runs[iter2] - -
test_gemm_split_leg_bounds_runs[iter3] - -
test_gemm_split_leg_bounds_runs[iter4] - -
test_gemm_tile_options[tn128-ma64-default] - -
test_gemm_tile_options[tn16-ma64-default] - -
test_gemm_tile_options[tn32-ma64-default] - -
test_gemm_tile_options[tn64-ma16-default] - - -
test_gemm_tile_options[tn64-ma32-default] - - -
test_one_xclbin_serves_every_clamp_bound[iter0] - -
test_one_xclbin_serves_every_clamp_bound[iter1] - -
test_one_xclbin_serves_every_clamp_bound[iter2] - -
test_one_xclbin_serves_every_clamp_bound[iter3] - -
test_one_xclbin_serves_every_clamp_bound[iter4] - -
test_one_xclbin_serves_every_shape[iter0] - -
test_one_xclbin_serves_every_shape[iter1] - -
test_one_xclbin_serves_every_shape[iter2] - -
test_one_xclbin_serves_every_shape[iter3] - -
test_one_xclbin_serves_every_shape[iter4] - -
iron/operators/gelu
Test Krackan Status Krackan Latency (mean) Phoenix Status Phoenix Latency (mean)
test_gelu[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048] 167.46 315.96
test_gelu[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024] 183.92 480.14
test_gelu[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024] 173.56 321.36
test_gelu[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512] 211.28 419.60
test_gelu[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512] 203.40 818.44
test_gelu[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256] 188.78 508.16
test_gelu[input_length_2048-num_aie_columns_8-num_channels_1-tile_size_256] 199.18 - -
test_gelu[input_length_2048-num_aie_columns_8-num_channels_2-tile_size_128] 232.86 - -
iron/operators/gemm
Test Krackan Status Krackan Latency (mean) Phoenix Status Phoenix Latency (mean)
test_gemm[M_1792-K_896-N_1152-num_aie_columns_8-b_col_maj_False-c_col_maj_True-m_64-k_32-n_48-trace_size_0-partition_N_1] 2320.14 - -
test_gemm[M_192-K_384-N_64-num_aie_columns_4-b_col_maj_False-c_col_maj_False-m_48-k_96-n_16-trace_size_0-partition_N_1] 262.08 490.56
test_gemm[M_192-K_384-N_64-num_aie_columns_4-b_col_maj_True-c_col_maj_True-m_48-k_96-n_16-trace_size_0-partition_N_1] 249.70 493.62
test_gemm[M_2048-K_2048-N_2048-num_aie_columns_1-b_col_maj_False-c_col_maj_False-m_64-k_64-n_64-trace_size_0-partition_N_1] 47702.80 82608.80
test_gemm[M_2048-K_2048-N_2048-num_aie_columns_2-b_col_maj_True-c_col_maj_False-m_64-k_64-n_64-trace_size_0-partition_N_1] 27871.70 22223.12
test_gemm[M_2048-K_2048-N_2048-num_aie_columns_8-b_col_maj_True-c_col_maj_True-m_64-k_64-n_64-trace_size_0-partition_N_1] 7866.18 - -
test_gemm[M_384-K_1536-N_1792-num_aie_columns_4-b_col_maj_True-c_col_maj_False-m_32-k_48-n_64-trace_size_0-partition_N_1] 2361.14 3436.42
test_gemm[M_64-K_512-N_256-num_aie_columns_4-b_col_maj_True-c_col_maj_False-m_16-k_64-n_64-trace_size_0-partition_N_4] 3924.70 5396.74
test_gemm[M_896-K_1792-N_640-num_aie_columns_8-b_col_maj_False-c_col_maj_True-m_32-k_64-n_80-trace_size_0-partition_N_1] 1462.28 - -
iron/operators/gemv
Test Krackan Status Krackan Latency (mean) Phoenix Status Phoenix Latency (mean)
test_gemv[M_128-K_128-num_aie_columns_1-tile_size_input_32-tile_size_output_128] 0.20 0.07
test_gemv[M_2048-K_8192-num_aie_columns_1-tile_size_input_1-tile_size_output_2048] 12.44 3.59
test_gemv[M_2048-K_8192-num_aie_columns_2-tile_size_input_1-tile_size_output_1024] 22.54 6.30
test_gemv[M_2048-K_8192-num_aie_columns_4-tile_size_input_1-tile_size_output_512] 40.29 8.77
test_gemv[M_2048-K_8192-num_aie_columns_8-tile_size_input_1-tile_size_output_256] 43.76 - -
test_gemv[M_8192-K_2048-num_aie_columns_1-tile_size_input_4-tile_size_output_1024] 11.87 3.62
test_gemv[M_8192-K_2048-num_aie_columns_2-tile_size_input_4-tile_size_output_1024] 24.14 6.22
test_gemv[M_8192-K_2048-num_aie_columns_4-tile_size_input_4-tile_size_output_1024] 39.21 10.91
test_gemv[M_8192-K_2048-num_aie_columns_8-tile_size_input_4-tile_size_output_1024] 43.90 - -
test_gemv_batched[M_1024-K_1024-num_aie_columns_1-tile_size_input_1-tile_size_output_64-num_batches_2] 9.08 2.48
test_gemv_batched[M_1026-K_64-num_aie_columns_1-tile_size_input_1-tile_size_output_2-num_batches_2] 0.90 0.30
test_gemv_batched[M_256-K_128-num_aie_columns_1-tile_size_input_1-tile_size_output_256-num_batches_4] 1.13 0.46
test_gemv_batched[M_256-K_128-num_aie_columns_8-tile_size_input_1-tile_size_output_32-num_batches_100] 17.60 - -
test_gemv_batched[M_448-K_64-num_aie_columns_8-tile_size_input_1-tile_size_output_56-num_batches_192] 13.78 - -
test_gemv_batched[M_512-K_64-num_aie_columns_8-tile_size_input_4-tile_size_output_64-num_batches_32] 7.61 - -
test_gemv_batched[M_64-K_1536-num_aie_columns_1-tile_size_input_1-tile_size_output_64-num_batches_8] 5.87 2.28
test_gemv_gelu[M_128-K_128-num_aie_columns_1-tile_size_input_32-tile_size_output_128] 0.20 -
test_gemv_gelu[M_2048-K_8192-num_aie_columns_1-tile_size_input_1-tile_size_output_2048] 12.97 -
test_gemv_gelu[M_8192-K_2048-num_aie_columns_1-tile_size_input_4-tile_size_output_1024] 12.77 -
iron/operators/layer_norm
Test Krackan Status Krackan Latency (mean) Phoenix Status Phoenix Latency (mean)
test_layer_norm[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048] 138.20 455.72
test_layer_norm[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024] 164.82 432.12
test_layer_norm[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024] 166.80 662.66
test_layer_norm[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512] 187.94 417.22
test_layer_norm[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512] 173.06 319.28
test_layer_norm[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256] 180.12 862.58
test_layer_norm[input_length_2048-num_aie_columns_8-num_channels_1-tile_size_256] 198.44 - -
test_layer_norm[input_length_2048-num_aie_columns_8-num_channels_2-tile_size_128] 202.30 - -
iron/operators/leaky_relu
Test Krackan Status Krackan Latency (mean) Phoenix Status Phoenix Latency (mean)
test_leaky_relu[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048-alpha_0.01] 167.50 420.72
test_leaky_relu[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048-alpha_0.1] 170.98 377.94
test_leaky_relu[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048-alpha_0.25] 165.98 433.56
test_leaky_relu[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024-alpha_0.01] 201.96 368.82
test_leaky_relu[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024-alpha_0.01] 187.30 340.78
test_leaky_relu[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512-alpha_0.01] 212.98 318.88
test_leaky_relu[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512-alpha_0.01] 178.84 412.18
test_leaky_relu[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256-alpha_0.01] 186.26 568.22
test_leaky_relu[input_length_2048-num_aie_columns_8-num_channels_1-tile_size_256-alpha_0.01] 193.46 - -
test_leaky_relu[input_length_2048-num_aie_columns_8-num_channels_2-tile_size_128-alpha_0.01] 214.60 - -
iron/operators/mem_copy
Test Krackan Status Krackan Latency (mean) Phoenix Status Phoenix Latency (mean)
test_mem_copy[input_length_2048-num_cores_1-num_channels_1-bypass_False-tile_size_2048] 190.56 328.26
test_mem_copy[input_length_2048-num_cores_16-num_channels_2-bypass_False-tile_size_128] 205.34 - -
test_mem_copy[input_length_2048-num_cores_2-num_channels_1-bypass_False-tile_size_1024] 159.94 484.00
test_mem_copy[input_length_2048-num_cores_2-num_channels_2-bypass_False-tile_size_1024] 173.76 351.38
test_mem_copy[input_length_2048-num_cores_4-num_channels_1-bypass_False-tile_size_512] 164.08 374.58
test_mem_copy[input_length_2048-num_cores_4-num_channels_2-bypass_False-tile_size_512] 174.62 365.16
test_mem_copy[input_length_2048-num_cores_8-num_channels_1-bypass_False-tile_size_256] 174.76 - -
test_mem_copy[input_length_2048-num_cores_8-num_channels_2-bypass_False-tile_size_256] 172.04 493.52
iron/operators/mha
Test Krackan Status Krackan Latency (mean) Phoenix Status Phoenix Latency (mean)
test_mha[seq_len_16384-dim_64-num_heads_1-num_pipelines_8-num_kv_heads_0] 47487.20 - -
iron/operators/relu
Test Krackan Status Krackan Latency (mean) Phoenix Status Phoenix Latency (mean)
test_relu[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048] 168.82 345.86
test_relu[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024] 172.24 726.42
test_relu[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024] 189.06 628.40
test_relu[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512] 179.08 355.48
test_relu[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512] 172.30 501.98
test_relu[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256] 195.94 454.72
test_relu[input_length_2048-num_aie_columns_8-num_channels_1-tile_size_256] 201.78 - -
test_relu[input_length_2048-num_aie_columns_8-num_channels_2-tile_size_128] 232.56 - -
iron/operators/repeat
Test Krackan Status Krackan Latency (mean) Phoenix Status Phoenix Latency (mean)
test_cols_without_a_legal_split_is_rejected[cols_1031-why_prime > 1023: the only divisors are 1 and cols, neither legal] - -
test_cols_without_a_legal_split_is_rejected[cols_2062-why_2 x 1031: the only word-aligned chunk leaves a 1031-wide chunk count] - -
test_cols_without_a_legal_split_is_rejected[cols_513-why_odd: every divisor is odd, so no chunk is a whole 32-bit word] - -
test_repeat[rows_4-cols_1024-repeat_2-transfer_size_None] 177.70 417.66
test_repeat[rows_8-cols_512-repeat_4-transfer_size_64] 185.42 472.38
test_repeat[rows_8-cols_64-repeat_4-transfer_size_None] 160.64 468.16
iron/operators/rms_norm
Test Krackan Status Krackan Latency (mean) Phoenix Status Phoenix Latency (mean)
test_rms_norm[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048-weighted_False] 164.28 360.40
test_rms_norm[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048-weighted_True] 207.52 284.74
test_rms_norm[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024-weighted_False] 175.40 363.26
test_rms_norm[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024-weighted_True] 201.12 415.70
test_rms_norm[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024-weighted_False] 152.94 456.28
test_rms_norm[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024-weighted_True] 154.76 359.30
test_rms_norm[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512-weighted_False] 159.12 423.16
test_rms_norm[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512-weighted_True] 186.00 391.74
test_rms_norm[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512-weighted_False] 180.00 384.16
test_rms_norm[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512-weighted_True] 176.78 355.72
test_rms_norm[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256-weighted_False] 184.66 480.92
test_rms_norm[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256-weighted_True] 196.52 - -
test_rms_norm[input_length_2048-num_aie_columns_8-num_channels_1-tile_size_256-weighted_False] 191.90 - -
test_rms_norm[input_length_2048-num_aie_columns_8-num_channels_1-tile_size_256-weighted_True] 195.46 - -
test_rms_norm[input_length_2048-num_aie_columns_8-num_channels_2-tile_size_128-weighted_False] 224.22 - -
iron/operators/rope
Test Krackan Status Krackan Latency (mean) Phoenix Status Phoenix Latency (mean)
test_rope[rows_32-cols_512-angle_rows_32-aie_columns_1-method_type_0] 161.28 401.84
test_rope[rows_32-cols_512-angle_rows_32-aie_columns_2-method_type_0] 161.50 472.16
test_rope[rows_32-cols_512-angle_rows_32-aie_columns_4-method_type_0] 209.28 426.74
test_rope[rows_32-cols_512-angle_rows_32-aie_columns_8-method_type_0] 164.60 - -
test_rope[rows_32-cols_512-angle_rows_8-aie_columns_1-method_type_0] 170.46 384.90
test_rope[rows_32-cols_512-angle_rows_8-aie_columns_2-method_type_0] 190.50 420.66
test_rope[rows_32-cols_512-angle_rows_8-aie_columns_4-method_type_0] 164.58 426.52
test_rope[rows_32-cols_512-angle_rows_8-aie_columns_8-method_type_0] 212.10 - -
iron/operators/sigmoid
Test Krackan Status Krackan Latency (mean) Phoenix Status Phoenix Latency (mean)
test_sigmoid[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048] 179.42 415.74
test_sigmoid[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024] 190.44 403.22
test_sigmoid[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024] 182.18 376.22
test_sigmoid[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512] 189.94 405.88
test_sigmoid[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512] 184.52 372.86
test_sigmoid[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256] 197.38 415.32
test_sigmoid[input_length_2048-num_aie_columns_8-num_channels_1-tile_size_256] 188.68 - -
test_sigmoid[input_length_2048-num_aie_columns_8-num_channels_2-tile_size_128] 230.22 - -
iron/operators/silu
Test Krackan Status Krackan Latency (mean) Phoenix Status Phoenix Latency (mean)
test_silu[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048] 182.40 264.58
test_silu[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024] 182.32 252.04
test_silu[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512] 205.76 360.38
test_silu[input_length_2048-num_aie_columns_8-num_channels_1-tile_size_256] 184.24 - -
iron/operators/softmax
Test Krackan Status Krackan Latency (mean) Phoenix Status Phoenix Latency (mean)
test_softmax[input_length_32768-num_aie_columns_2-num_channels_2-tile_size_1024] 170.10 526.92
test_softmax[input_length_32768-num_aie_columns_2-num_channels_2-tile_size_2048] 201.42 532.64
test_softmax[input_length_32768-num_aie_columns_2-num_channels_2-tile_size_512] 204.62 529.76
iron/operators/strided_copy
Test Krackan Status Krackan Latency (mean) Phoenix Status Phoenix Latency (mean)
test_strided_copy[chunked_transfer] 145.02 274.92
test_strided_copy[contiguous] 162.78 370.48
test_strided_copy[four_channels] 171.24 418.16
test_strided_copy[kv_slot0] 150.92 412.58
test_strided_copy[kv_slot5] 175.20 332.56
test_strided_copy[kv_slot5_four_channels] 174.92 346.10
test_strided_copy[kv_slot5_two_channels] 168.32 409.36
test_strided_copy[kv_slot_last] 180.54 343.50
test_strided_copy[two_channels] 180.22 488.24
test_strided_copy[two_channels_chunked] 162.30 250.24
test_transfer_size_not_dividing_per_channel_share_is_rejected[iter0] - -
test_transfer_size_not_dividing_per_channel_share_is_rejected[iter1] - -
test_transfer_size_not_dividing_per_channel_share_is_rejected[iter2] - -
test_transfer_size_not_dividing_per_channel_share_is_rejected[iter3] - -
test_transfer_size_not_dividing_per_channel_share_is_rejected[iter4] - -
iron/operators/swiglu_decode
Test Krackan Status Krackan Latency (mean) Phoenix Status Phoenix Latency (mean)
test_swiglu_decode[embedding_dim_1024-hidden_dim_3584] 983.50 17100.15
test_swiglu_decode[embedding_dim_2048-hidden_dim_2048] 1041.51 13871.32
iron/operators/swiglu_prefill
Test Krackan Status Krackan Latency (mean) Phoenix Status Phoenix Latency (mean)
test_swiglu_prefill[seq_len_256-embedding_dim_2048-hidden_dim_2048-prio_accuracy_False] 2154.95 20411.27
iron/operators/tanh
Test Krackan Status Krackan Latency (mean) Phoenix Status Phoenix Latency (mean)
test_tanh[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048] 152.68 344.42
test_tanh[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024] 149.96 346.26
test_tanh[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024] 181.24 403.94
test_tanh[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512] 168.38 451.34
test_tanh[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512] 178.74 373.22
test_tanh[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256] 197.74 427.34
test_tanh[input_length_2048-num_aie_columns_8-num_channels_1-tile_size_256] 179.16 - -
test_tanh[input_length_2048-num_aie_columns_8-num_channels_2-tile_size_128] 212.02 - -
iron/operators/transpose
Test Krackan Status Krackan Latency (mean) Phoenix Status Phoenix Latency (mean)
test_transpose[M_2048-N_64-aie_columns_1-channels_1-m_64-n_64-s_8-num_batches_1] 189.98 1179.72
test_transpose[M_2048-N_64-aie_columns_1-channels_1-m_64-n_64-s_8-num_batches_2] 247.66 1782.82
test_transpose[M_2048-N_64-aie_columns_1-channels_2-m_64-n_64-s_8-num_batches_1] 202.88 486.10
Krackan - Small

IRON

Tested on 2026_09_14_23_27_05 at commit 5bbc769.

iron/operators/axpy
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_axpy[input_length_2048-num_aie_columns_1-tile_size_2048-scalar_factor_3.0]✅ 5/5156.980.08n/a
test_axpy[input_length_2048-num_aie_columns_2-tile_size_1024-scalar_factor_3.0]✅ 5/5144.980.09n/a
test_axpy[input_length_2048-num_aie_columns_4-tile_size_512-scalar_factor_3.0]✅ 5/5161.180.08n/a
test_axpy[input_length_2048-num_aie_columns_8-tile_size_256-scalar_factor_3.0]✅ 5/5191.700.07n/a
iron/operators/dequant
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_dequant[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048-group_size_32]✅ 5/5178.140.03n/a
test_dequant[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024-group_size_32]✅ 5/5173.520.03n/a
test_dequant[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024-group_size_32]✅ 5/5182.260.03n/a
test_dequant[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512-group_size_32]✅ 5/5158.560.03n/a
test_dequant[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512-group_size_32]✅ 5/5188.440.03n/a
test_dequant[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256-group_size_32]✅ 5/5178.840.03n/a
test_dequant[input_length_2048-num_aie_columns_8-num_channels_1-tile_size_256-group_size_32]✅ 5/5180.160.03n/a
test_dequant[input_length_2048-num_aie_columns_8-num_channels_2-tile_size_128-group_size_32]✅ 5/5203.860.03n/a
iron/operators/elementwise_add
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_elementwise_add[input_length_2048-num_aie_columns_1-tile_size_2048]✅ 5/5166.900.07n/a
test_elementwise_add[input_length_2048-num_aie_columns_2-tile_size_1024]✅ 5/5163.500.08n/a
test_elementwise_add[input_length_2048-num_aie_columns_4-tile_size_512]✅ 5/5215.900.06n/a
test_elementwise_add[input_length_2048-num_aie_columns_8-tile_size_256]✅ 5/5225.340.06n/a
iron/operators/elementwise_mul
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_elementwise_mul[input_length_2048-num_aie_columns_1-tile_size_2048]✅ 5/5174.540.07n/a
test_elementwise_mul[input_length_2048-num_aie_columns_2-tile_size_1024]✅ 5/5170.640.07n/a
test_elementwise_mul[input_length_2048-num_aie_columns_4-tile_size_512]✅ 5/5185.500.07n/a
test_elementwise_mul[input_length_2048-num_aie_columns_8-tile_size_256]✅ 5/5206.260.06n/a
iron/operators/flm/gemm
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_artifact_stem_differs_from_generic_gemm[M_256-K_512-N_1024]✅ 5/5n/an/an/a
test_artifact_stem_differs_from_generic_gemm[M_512-K_1024-N_2048]✅ 5/5n/an/an/a
test_gemm[M_256-K_512-N_1024-epilogue_gelu-clamp_None-rounding_conv_even]✅ 5/5368.003.90759.87
test_gemm[M_256-K_512-N_1024-epilogue_none-clamp_(-2.0, 2.0)-rounding_conv_even]✅ 5/5342.804.12804.41
test_gemm[M_256-K_512-N_1024-epilogue_none-clamp_None-rounding_conv_even]✅ 5/5357.964.06791.19
test_gemm[M_256-K_512-N_1024-epilogue_none-clamp_None-rounding_floor]✅ 5/5320.284.60896.83
test_gemm[M_256-K_512-N_1024-epilogue_silu-clamp_None-rounding_conv_even]✅ 5/5445.863.09602.75
test_gemm[M_256-K_512-N_128-epilogue_none-clamp_None-rounding_conv_even]✅ 5/5345.601.20100.06
test_gemm[M_256-K_512-N_1536-epilogue_none-clamp_None-rounding_conv_even]✅ 5/5356.885.561157.55
test_gemm[M_512-K_1024-N_2048-epilogue_none-clamp_None-rounding_conv_even]✅ 5/5470.9211.834613.76
test_gemm_split_leg_bounds[iter0]✅ 1/1n/an/an/a
test_gemm_split_leg_bounds[iter1]✅ 1/1n/an/an/a
test_gemm_split_leg_bounds[iter2]✅ 1/1n/an/an/a
test_gemm_split_leg_bounds[iter3]✅ 1/1n/an/an/a
test_gemm_split_leg_bounds[iter4]✅ 1/1n/an/an/a
test_gemm_split_leg_bounds_runs[iter0]✅ 1/1n/an/an/a
test_gemm_split_leg_bounds_runs[iter1]✅ 1/1n/an/an/a
test_gemm_split_leg_bounds_runs[iter2]✅ 1/1n/an/an/a
test_gemm_split_leg_bounds_runs[iter3]✅ 1/1n/an/an/a
test_gemm_split_leg_bounds_runs[iter4]✅ 1/1n/an/an/a
test_gemm_tile_options[tn128-ma64-default]✅ 5/5n/an/an/a
test_gemm_tile_options[tn16-ma64-default]✅ 5/5n/an/an/a
test_gemm_tile_options[tn32-ma64-default]✅ 5/5n/an/an/a
test_gemm_tile_options[tn64-ma32-default]✅ 5/5n/an/an/a
test_one_xclbin_serves_every_clamp_bound[iter0]✅ 1/1n/an/an/a
test_one_xclbin_serves_every_clamp_bound[iter1]✅ 1/1n/an/an/a
test_one_xclbin_serves_every_clamp_bound[iter2]✅ 1/1n/an/an/a
test_one_xclbin_serves_every_clamp_bound[iter3]✅ 1/1n/an/an/a
test_one_xclbin_serves_every_clamp_bound[iter4]✅ 1/1n/an/an/a
test_one_xclbin_serves_every_shape[iter0]✅ 1/1n/an/an/a
test_one_xclbin_serves_every_shape[iter1]✅ 1/1n/an/an/a
test_one_xclbin_serves_every_shape[iter2]✅ 1/1n/an/an/a
test_one_xclbin_serves_every_shape[iter3]✅ 1/1n/an/an/a
test_one_xclbin_serves_every_shape[iter4]✅ 1/1n/an/an/a
iron/operators/gelu
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_gelu[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048]✅ 5/5167.460.05n/a
test_gelu[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024]✅ 5/5183.920.05n/a
test_gelu[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024]✅ 5/5173.560.05n/a
test_gelu[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512]✅ 5/5211.280.04n/a
test_gelu[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512]✅ 5/5203.400.04n/a
test_gelu[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256]✅ 5/5188.780.04n/a
test_gelu[input_length_2048-num_aie_columns_8-num_channels_1-tile_size_256]✅ 5/5199.180.04n/a
test_gelu[input_length_2048-num_aie_columns_8-num_channels_2-tile_size_128]✅ 5/5232.860.04n/a
iron/operators/gemm
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_gemm[M_1792-K_896-N_1152-num_aie_columns_8-b_col_maj_False-c_col_maj_True-m_64-k_32-n_48-trace_size_0-partition_N_1]✅ 5/52320.144.061597.97
test_gemm[M_192-K_384-N_64-num_aie_columns_4-b_col_maj_False-c_col_maj_False-m_48-k_96-n_16-trace_size_0-partition_N_1]✅ 5/5262.080.8937.99
test_gemm[M_192-K_384-N_64-num_aie_columns_4-b_col_maj_True-c_col_maj_True-m_48-k_96-n_16-trace_size_0-partition_N_1]✅ 5/5249.700.9339.49
test_gemm[M_2048-K_2048-N_2048-num_aie_columns_1-b_col_maj_False-c_col_maj_False-m_64-k_64-n_64-trace_size_0-partition_N_1]✅ 5/547702.800.53360.15
test_gemm[M_2048-K_2048-N_2048-num_aie_columns_2-b_col_maj_True-c_col_maj_False-m_64-k_64-n_64-trace_size_0-partition_N_1]✅ 5/527871.700.90616.39
test_gemm[M_2048-K_2048-N_2048-num_aie_columns_8-b_col_maj_True-c_col_maj_True-m_64-k_64-n_64-trace_size_0-partition_N_1]✅ 5/57866.183.202184.49
test_gemm[M_384-K_1536-N_1792-num_aie_columns_4-b_col_maj_True-c_col_maj_False-m_32-k_48-n_64-trace_size_0-partition_N_1]✅ 5/52361.143.44902.13
test_gemm[M_64-K_512-N_256-num_aie_columns_4-b_col_maj_True-c_col_maj_False-m_16-k_64-n_64-trace_size_0-partition_N_4]✅ 5/53924.700.3217.14
test_gemm[M_896-K_1792-N_640-num_aie_columns_8-b_col_maj_False-c_col_maj_True-m_32-k_64-n_80-trace_size_0-partition_N_1]✅ 5/51462.284.751468.95
iron/operators/gemv
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_gemv[M_128-K_128-num_aie_columns_1-tile_size_input_32-tile_size_output_128]✅ 5/5n/a0.200.19
test_gemv[M_2048-K_8192-num_aie_columns_1-tile_size_input_1-tile_size_output_2048]✅ 5/5n/a12.4412.43
test_gemv[M_2048-K_8192-num_aie_columns_2-tile_size_input_1-tile_size_output_1024]✅ 5/5n/a22.5422.52
test_gemv[M_2048-K_8192-num_aie_columns_4-tile_size_input_1-tile_size_output_512]✅ 5/5n/a40.2940.27
test_gemv[M_2048-K_8192-num_aie_columns_8-tile_size_input_1-tile_size_output_256]✅ 5/5n/a43.7643.73
test_gemv[M_8192-K_2048-num_aie_columns_1-tile_size_input_4-tile_size_output_1024]✅ 5/5n/a11.8711.87
test_gemv[M_8192-K_2048-num_aie_columns_2-tile_size_input_4-tile_size_output_1024]✅ 5/5n/a24.1424.13
test_gemv[M_8192-K_2048-num_aie_columns_4-tile_size_input_4-tile_size_output_1024]✅ 5/5n/a39.2139.19
test_gemv[M_8192-K_2048-num_aie_columns_8-tile_size_input_4-tile_size_output_1024]✅ 5/5n/a43.9043.87
test_gemv_batched[M_1024-K_1024-num_aie_columns_1-tile_size_input_1-tile_size_output_64-num_batches_2]✅ 5/5n/a9.089.06
test_gemv_batched[M_1026-K_64-num_aie_columns_1-tile_size_input_1-tile_size_output_2-num_batches_2]✅ 5/5n/a0.900.88
test_gemv_batched[M_256-K_128-num_aie_columns_1-tile_size_input_1-tile_size_output_256-num_batches_4]✅ 5/5n/a1.131.12
test_gemv_batched[M_256-K_128-num_aie_columns_8-tile_size_input_1-tile_size_output_32-num_batches_100]✅ 5/5n/a17.6017.40
test_gemv_batched[M_448-K_64-num_aie_columns_8-tile_size_input_1-tile_size_output_56-num_batches_192]✅ 5/5n/a13.7813.54
test_gemv_batched[M_512-K_64-num_aie_columns_8-tile_size_input_4-tile_size_output_64-num_batches_32]✅ 5/5n/a7.617.48
test_gemv_batched[M_64-K_1536-num_aie_columns_1-tile_size_input_1-tile_size_output_64-num_batches_8]✅ 5/5n/a5.875.77
test_gemv_gelu[M_128-K_128-num_aie_columns_1-tile_size_input_32-tile_size_output_128]✅ 5/5n/a0.200.20
test_gemv_gelu[M_2048-K_8192-num_aie_columns_1-tile_size_input_1-tile_size_output_2048]✅ 5/5n/a12.9712.96
test_gemv_gelu[M_8192-K_2048-num_aie_columns_1-tile_size_input_4-tile_size_output_1024]✅ 5/5n/a12.7712.76
iron/operators/layer_norm
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_layer_norm[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048]✅ 5/5138.200.06n/a
test_layer_norm[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024]✅ 5/5164.820.05n/a
test_layer_norm[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024]✅ 5/5166.800.05n/a
test_layer_norm[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512]✅ 5/5187.940.04n/a
test_layer_norm[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512]✅ 5/5173.060.05n/a
test_layer_norm[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256]✅ 5/5180.120.05n/a
test_layer_norm[input_length_2048-num_aie_columns_8-num_channels_1-tile_size_256]✅ 5/5198.440.04n/a
test_layer_norm[input_length_2048-num_aie_columns_8-num_channels_2-tile_size_128]✅ 5/5202.300.04n/a
iron/operators/leaky_relu
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_leaky_relu[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048-alpha_0.01]✅ 5/5167.500.05n/a
test_leaky_relu[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048-alpha_0.1]✅ 5/5170.980.05n/a
test_leaky_relu[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048-alpha_0.25]✅ 5/5165.980.05n/a
test_leaky_relu[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024-alpha_0.01]✅ 5/5201.960.04n/a
test_leaky_relu[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024-alpha_0.01]✅ 5/5187.300.04n/a
test_leaky_relu[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512-alpha_0.01]✅ 5/5212.980.04n/a
test_leaky_relu[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512-alpha_0.01]✅ 5/5178.840.05n/a
test_leaky_relu[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256-alpha_0.01]✅ 5/5186.260.04n/a
test_leaky_relu[input_length_2048-num_aie_columns_8-num_channels_1-tile_size_256-alpha_0.01]✅ 5/5193.460.04n/a
test_leaky_relu[input_length_2048-num_aie_columns_8-num_channels_2-tile_size_128-alpha_0.01]✅ 5/5214.600.04n/a
iron/operators/mem_copy
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_mem_copy[input_length_2048-num_cores_1-num_channels_1-bypass_False-tile_size_2048]✅ 5/5190.560.05n/a
test_mem_copy[input_length_2048-num_cores_16-num_channels_2-bypass_False-tile_size_128]✅ 5/5205.340.04n/a
test_mem_copy[input_length_2048-num_cores_2-num_channels_1-bypass_False-tile_size_1024]✅ 5/5159.940.05n/a
test_mem_copy[input_length_2048-num_cores_2-num_channels_2-bypass_False-tile_size_1024]✅ 5/5173.760.05n/a
test_mem_copy[input_length_2048-num_cores_4-num_channels_1-bypass_False-tile_size_512]✅ 5/5164.080.05n/a
test_mem_copy[input_length_2048-num_cores_4-num_channels_2-bypass_False-tile_size_512]✅ 5/5174.620.05n/a
test_mem_copy[input_length_2048-num_cores_8-num_channels_1-bypass_False-tile_size_256]✅ 5/5174.760.05n/a
test_mem_copy[input_length_2048-num_cores_8-num_channels_2-bypass_False-tile_size_256]✅ 5/5172.040.05n/a
iron/operators/mha
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_mha[seq_len_16384-dim_64-num_heads_1-num_pipelines_8-num_kv_heads_0]✅ 5/547487.200.18n/a
iron/operators/relu
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_relu[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048]✅ 5/5168.820.05n/a
test_relu[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024]✅ 5/5172.240.05n/a
test_relu[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024]✅ 5/5189.060.04n/a
test_relu[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512]✅ 5/5179.080.05n/a
test_relu[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512]✅ 5/5172.300.05n/a
test_relu[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256]✅ 5/5195.940.04n/a
test_relu[input_length_2048-num_aie_columns_8-num_channels_1-tile_size_256]✅ 5/5201.780.04n/a
test_relu[input_length_2048-num_aie_columns_8-num_channels_2-tile_size_128]✅ 5/5232.560.04n/a
iron/operators/repeat
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_cols_without_a_legal_split_is_rejected[cols_1031-why_prime > 1023: the only divisors are 1 and cols, neither legal]✅ 5/5n/an/an/a
test_cols_without_a_legal_split_is_rejected[cols_2062-why_2 x 1031: the only word-aligned chunk leaves a 1031-wide chunk count]✅ 5/5n/an/an/a
test_cols_without_a_legal_split_is_rejected[cols_513-why_odd: every divisor is odd, so no chunk is a whole 32-bit word]✅ 5/5n/an/an/a
test_repeat[rows_4-cols_1024-repeat_2-transfer_size_None]✅ 5/5177.700.14n/a
test_repeat[rows_8-cols_512-repeat_4-transfer_size_64]✅ 5/5185.420.22n/a
test_repeat[rows_8-cols_64-repeat_4-transfer_size_None]✅ 5/5160.640.03n/a
iron/operators/rms_norm
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_rms_norm[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048-weighted_False]✅ 5/5164.280.05n/a
test_rms_norm[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048-weighted_True]✅ 5/5207.520.06n/a
test_rms_norm[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024-weighted_False]✅ 5/5175.400.05n/a
test_rms_norm[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024-weighted_True]✅ 5/5201.120.05n/a
test_rms_norm[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024-weighted_False]✅ 5/5152.940.05n/a
test_rms_norm[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024-weighted_True]✅ 5/5154.760.07n/a
test_rms_norm[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512-weighted_False]✅ 5/5159.120.05n/a
test_rms_norm[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512-weighted_True]✅ 5/5186.000.05n/a
test_rms_norm[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512-weighted_False]✅ 5/5180.000.05n/a
test_rms_norm[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512-weighted_True]✅ 5/5176.780.05n/a
test_rms_norm[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256-weighted_False]✅ 5/5184.660.04n/a
test_rms_norm[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256-weighted_True]✅ 5/5196.520.05n/a
test_rms_norm[input_length_2048-num_aie_columns_8-num_channels_1-tile_size_256-weighted_False]✅ 5/5191.900.04n/a
test_rms_norm[input_length_2048-num_aie_columns_8-num_channels_1-tile_size_256-weighted_True]✅ 5/5195.460.05n/a
test_rms_norm[input_length_2048-num_aie_columns_8-num_channels_2-tile_size_128-weighted_False]✅ 5/5224.220.04n/a
iron/operators/rope
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_rope[rows_32-cols_512-angle_rows_32-aie_columns_1-method_type_0]✅ 5/5161.280.62n/a
test_rope[rows_32-cols_512-angle_rows_32-aie_columns_2-method_type_0]✅ 5/5161.500.62n/a
test_rope[rows_32-cols_512-angle_rows_32-aie_columns_4-method_type_0]✅ 5/5209.280.50n/a
test_rope[rows_32-cols_512-angle_rows_32-aie_columns_8-method_type_0]✅ 5/5164.600.61n/a
test_rope[rows_32-cols_512-angle_rows_8-aie_columns_1-method_type_0]✅ 5/5170.460.44n/a
test_rope[rows_32-cols_512-angle_rows_8-aie_columns_2-method_type_0]✅ 5/5190.500.39n/a
test_rope[rows_32-cols_512-angle_rows_8-aie_columns_4-method_type_0]✅ 5/5164.580.45n/a
test_rope[rows_32-cols_512-angle_rows_8-aie_columns_8-method_type_0]✅ 5/5212.100.35n/a
iron/operators/sigmoid
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_sigmoid[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048]✅ 5/5179.420.05n/a
test_sigmoid[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024]✅ 5/5190.440.04n/a
test_sigmoid[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024]✅ 5/5182.180.05n/a
test_sigmoid[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512]✅ 5/5189.940.04n/a
test_sigmoid[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512]✅ 5/5184.520.05n/a
test_sigmoid[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256]✅ 5/5197.380.04n/a
test_sigmoid[input_length_2048-num_aie_columns_8-num_channels_1-tile_size_256]✅ 5/5188.680.05n/a
test_sigmoid[input_length_2048-num_aie_columns_8-num_channels_2-tile_size_128]✅ 5/5230.220.04n/a
iron/operators/silu
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_silu[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048]✅ 5/5182.400.05n/a
test_silu[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024]✅ 5/5182.320.05n/a
test_silu[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512]✅ 5/5205.760.04n/a
test_silu[input_length_2048-num_aie_columns_8-num_channels_1-tile_size_256]✅ 5/5184.240.05n/a
iron/operators/softmax
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_softmax[input_length_32768-num_aie_columns_2-num_channels_2-tile_size_1024]✅ 5/5170.100.79n/a
test_softmax[input_length_32768-num_aie_columns_2-num_channels_2-tile_size_2048]✅ 5/5201.420.67n/a
test_softmax[input_length_32768-num_aie_columns_2-num_channels_2-tile_size_512]✅ 5/5204.620.71n/a
iron/operators/strided_copy
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_strided_copy[chunked_transfer]✅ 5/5145.020.03n/a
test_strided_copy[contiguous]✅ 5/5162.780.03n/a
test_strided_copy[four_channels]✅ 5/5171.240.02n/a
test_strided_copy[kv_slot0]✅ 5/5150.920.90n/a
test_strided_copy[kv_slot5]✅ 5/5175.200.76n/a
test_strided_copy[kv_slot5_four_channels]✅ 5/5174.920.77n/a
test_strided_copy[kv_slot5_two_channels]✅ 5/5168.320.79n/a
test_strided_copy[kv_slot_last]✅ 5/5180.540.74n/a
test_strided_copy[two_channels]✅ 5/5180.220.02n/a
test_strided_copy[two_channels_chunked]✅ 5/5162.300.03n/a
test_transfer_size_not_dividing_per_channel_share_is_rejected[iter0]✅ 1/1n/an/an/a
test_transfer_size_not_dividing_per_channel_share_is_rejected[iter1]✅ 1/1n/an/an/a
test_transfer_size_not_dividing_per_channel_share_is_rejected[iter2]✅ 1/1n/an/an/a
test_transfer_size_not_dividing_per_channel_share_is_rejected[iter3]✅ 1/1n/an/an/a
test_transfer_size_not_dividing_per_channel_share_is_rejected[iter4]✅ 1/1n/an/an/a
iron/operators/swiglu_decode
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_swiglu_decode[embedding_dim_1024-hidden_dim_3584]✅ 5/5983.500.00n/a
test_swiglu_decode[embedding_dim_2048-hidden_dim_2048]✅ 5/51041.510.01n/a
iron/operators/swiglu_prefill
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_swiglu_prefill[seq_len_256-embedding_dim_2048-hidden_dim_2048-prio_accuracy_False]✅ 5/52154.950.97n/a
iron/operators/tanh
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_tanh[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048]✅ 5/5152.680.05n/a
test_tanh[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024]✅ 5/5149.960.06n/a
test_tanh[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024]✅ 5/5181.240.05n/a
test_tanh[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512]✅ 5/5168.380.05n/a
test_tanh[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512]✅ 5/5178.740.05n/a
test_tanh[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256]✅ 5/5197.740.04n/a
test_tanh[input_length_2048-num_aie_columns_8-num_channels_1-tile_size_256]✅ 5/5179.160.05n/a
test_tanh[input_length_2048-num_aie_columns_8-num_channels_2-tile_size_128]✅ 5/5212.020.04n/a
iron/operators/transpose
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_transpose[M_2048-N_64-aie_columns_1-channels_1-m_64-n_64-s_8-num_batches_1]✅ 5/5189.982.86n/a
test_transpose[M_2048-N_64-aie_columns_1-channels_1-m_64-n_64-s_8-num_batches_2]✅ 5/5247.664.30n/a
test_transpose[M_2048-N_64-aie_columns_1-channels_2-m_64-n_64-s_8-num_batches_1]✅ 5/5202.882.73n/a
Krackan - Examples

IRON

Tested on 2026_09_14_23_34_35 at commit 5bbc769.

iron/applications/llama_3.2_1b
TestChecksTTFT (mean)TPS (mean)
test_llama_3_2_1b[llama_3.2_1b_prompt_1024_tokens_1]✅ 5/52.07n/a
test_llama_3_2_1b[llama_3.2_1b_prompt_1024_tokens_40]✅ 5/52.097.81
test_llama_3_2_1b[llama_3.2_1b_prompt_13_tokens_1]✅ 5/52.03n/a
test_llama_3_2_1b[llama_3.2_1b_prompt_13_tokens_40]✅ 5/52.027.61
Phoenix - Small

IRON

Tested on 2026_09_14_23_24_00 at commit 5bbc769.

iron/operators/axpy
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_axpy[input_length_2048-num_aie_columns_1-tile_size_2048-scalar_factor_3.0]✅ 5/5350.720.04n/a
test_axpy[input_length_2048-num_aie_columns_2-tile_size_1024-scalar_factor_3.0]✅ 5/5354.760.04n/a
test_axpy[input_length_2048-num_aie_columns_4-tile_size_512-scalar_factor_3.0]✅ 5/5440.360.03n/a
iron/operators/dequant
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_dequant[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048-group_size_32]✅ 5/5281.340.02n/a
test_dequant[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024-group_size_32]✅ 5/5398.540.02n/a
test_dequant[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024-group_size_32]✅ 5/5388.720.01n/a
test_dequant[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512-group_size_32]✅ 5/5356.000.02n/a
test_dequant[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512-group_size_32]✅ 5/5412.760.01n/a
test_dequant[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256-group_size_32]✅ 5/5356.060.02n/a
iron/operators/elementwise_add
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_elementwise_add[input_length_2048-num_aie_columns_1-tile_size_2048]✅ 5/5479.540.03n/a
test_elementwise_add[input_length_2048-num_aie_columns_2-tile_size_1024]✅ 5/5353.160.04n/a
test_elementwise_add[input_length_2048-num_aie_columns_4-tile_size_512]✅ 5/5364.320.04n/a
iron/operators/elementwise_mul
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_elementwise_mul[input_length_2048-num_aie_columns_1-tile_size_2048]✅ 5/5381.000.04n/a
test_elementwise_mul[input_length_2048-num_aie_columns_2-tile_size_1024]✅ 5/5350.300.04n/a
test_elementwise_mul[input_length_2048-num_aie_columns_4-tile_size_512]✅ 5/5408.200.03n/a
iron/operators/flm/gemm
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_artifact_stem_differs_from_generic_gemm[M_256-K_512-N_1024]✅ 5/5n/an/an/a
test_artifact_stem_differs_from_generic_gemm[M_512-K_1024-N_2048]✅ 5/5n/an/an/a
test_gemm[M_256-K_512-N_128-epilogue_none-clamp_None-rounding_conv_even]✅ 5/5582.520.8662.57
test_gemm[M_256-K_512-N_256-epilogue_none-clamp_None-rounding_conv_even]✅ 5/5574.321.16118.66
test_gemm[M_256-K_512-N_320-epilogue_none-clamp_None-rounding_conv_even]✅ 5/5598.001.37152.28
test_gemm[M_256-K_512-N_512-epilogue_gelu-clamp_None-rounding_conv_even]✅ 5/51170.701.06135.76
test_gemm[M_256-K_512-N_512-epilogue_none-clamp_(-2.0, 2.0)-rounding_conv_even]❌ 0/5n/an/an/a
test_gemm[M_256-K_512-N_512-epilogue_none-clamp_None-rounding_floor]✅ 5/5553.621.91244.92
test_gemm[M_256-K_512-N_512-epilogue_silu-clamp_None-rounding_conv_even]✅ 5/51340.901.11141.62
test_gemm[M_256-K_512-N_64-epilogue_none-clamp_None-rounding_conv_even]✅ 5/5566.320.6630.91
test_gemm[M_512-K_1024-N_512-epilogue_none-clamp_None-rounding_conv_even]✅ 5/51409.042.04418.28
test_gemm_split_leg_bounds[iter0]✅ 1/1n/an/an/a
test_gemm_split_leg_bounds[iter1]✅ 1/1n/an/an/a
test_gemm_split_leg_bounds[iter2]✅ 1/1n/an/an/a
test_gemm_split_leg_bounds[iter3]✅ 1/1n/an/an/a
test_gemm_split_leg_bounds[iter4]✅ 1/1n/an/an/a
test_gemm_split_leg_bounds_runs[iter0]✅ 1/1n/an/an/a
test_gemm_split_leg_bounds_runs[iter1]✅ 1/1n/an/an/a
test_gemm_split_leg_bounds_runs[iter2]✅ 1/1n/an/an/a
test_gemm_split_leg_bounds_runs[iter3]✅ 1/1n/an/an/a
test_gemm_split_leg_bounds_runs[iter4]✅ 1/1n/an/an/a
test_gemm_tile_options[tn128-ma64-default]✅ 5/5n/an/an/a
test_gemm_tile_options[tn16-ma64-default]✅ 5/5n/an/an/a
test_gemm_tile_options[tn32-ma64-default]✅ 5/5n/an/an/a
test_gemm_tile_options[tn64-ma16-default]✅ 5/5n/an/an/a
test_one_xclbin_serves_every_clamp_bound[iter0]❌ 0/1n/an/an/a
test_one_xclbin_serves_every_clamp_bound[iter1]❌ 0/1n/an/an/a
test_one_xclbin_serves_every_clamp_bound[iter2]❌ 0/1n/an/an/a
test_one_xclbin_serves_every_clamp_bound[iter3]❌ 0/1n/an/an/a
test_one_xclbin_serves_every_clamp_bound[iter4]❌ 0/1n/an/an/a
test_one_xclbin_serves_every_shape[iter0]✅ 1/1n/an/an/a
test_one_xclbin_serves_every_shape[iter1]✅ 1/1n/an/an/a
test_one_xclbin_serves_every_shape[iter2]✅ 1/1n/an/an/a
test_one_xclbin_serves_every_shape[iter3]✅ 1/1n/an/an/a
test_one_xclbin_serves_every_shape[iter4]✅ 1/1n/an/an/a
iron/operators/gelu
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_gelu[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048]✅ 5/5315.960.03n/a
test_gelu[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024]✅ 5/5480.140.02n/a
test_gelu[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024]✅ 5/5321.360.03n/a
test_gelu[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512]✅ 5/5419.600.02n/a
test_gelu[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512]✅ 5/5818.440.02n/a
test_gelu[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256]✅ 5/5508.160.02n/a
iron/operators/gemm
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_gemm[M_192-K_384-N_64-num_aie_columns_4-b_col_maj_False-c_col_maj_False-m_48-k_96-n_16-trace_size_0-partition_N_1]✅ 5/5490.560.4820.35
test_gemm[M_192-K_384-N_64-num_aie_columns_4-b_col_maj_True-c_col_maj_True-m_48-k_96-n_16-trace_size_0-partition_N_1]✅ 5/5493.620.4720.11
test_gemm[M_2048-K_2048-N_2048-num_aie_columns_1-b_col_maj_False-c_col_maj_False-m_64-k_64-n_64-trace_size_0-partition_N_1]✅ 5/582608.800.30207.99
test_gemm[M_2048-K_2048-N_2048-num_aie_columns_2-b_col_maj_True-c_col_maj_False-m_64-k_64-n_64-trace_size_0-partition_N_1]✅ 5/522223.121.13773.26
test_gemm[M_384-K_1536-N_1792-num_aie_columns_4-b_col_maj_True-c_col_maj_False-m_32-k_48-n_64-trace_size_0-partition_N_1]✅ 5/53436.422.76724.55
test_gemm[M_64-K_512-N_256-num_aie_columns_4-b_col_maj_True-c_col_maj_False-m_16-k_64-n_64-trace_size_0-partition_N_4]✅ 5/55396.740.2413.12
iron/operators/gemv
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_gemv[M_128-K_128-num_aie_columns_1-tile_size_input_32-tile_size_output_128]✅ 5/5n/a0.070.07
test_gemv[M_2048-K_8192-num_aie_columns_1-tile_size_input_1-tile_size_output_2048]✅ 5/5n/a3.593.59
test_gemv[M_2048-K_8192-num_aie_columns_2-tile_size_input_1-tile_size_output_1024]✅ 5/5n/a6.306.29
test_gemv[M_2048-K_8192-num_aie_columns_4-tile_size_input_1-tile_size_output_512]✅ 5/5n/a8.778.76
test_gemv[M_8192-K_2048-num_aie_columns_1-tile_size_input_4-tile_size_output_1024]✅ 5/5n/a3.623.62
test_gemv[M_8192-K_2048-num_aie_columns_2-tile_size_input_4-tile_size_output_1024]✅ 5/5n/a6.226.21
test_gemv[M_8192-K_2048-num_aie_columns_4-tile_size_input_4-tile_size_output_1024]✅ 5/5n/a10.9110.90
test_gemv_batched[M_1024-K_1024-num_aie_columns_1-tile_size_input_1-tile_size_output_64-num_batches_2]✅ 5/5n/a2.482.47
test_gemv_batched[M_1026-K_64-num_aie_columns_1-tile_size_input_1-tile_size_output_2-num_batches_2]✅ 5/5n/a0.300.30
test_gemv_batched[M_256-K_128-num_aie_columns_1-tile_size_input_1-tile_size_output_256-num_batches_4]✅ 5/5n/a0.460.45
test_gemv_batched[M_64-K_1536-num_aie_columns_1-tile_size_input_1-tile_size_output_64-num_batches_8]✅ 5/5n/a2.282.24
test_gemv_gelu[M_128-K_128-num_aie_columns_1-tile_size_input_32-tile_size_output_128]❌ 0/5n/an/an/a
test_gemv_gelu[M_2048-K_8192-num_aie_columns_1-tile_size_input_1-tile_size_output_2048]❌ 0/5n/an/an/a
test_gemv_gelu[M_8192-K_2048-num_aie_columns_1-tile_size_input_4-tile_size_output_1024]❌ 0/5n/an/an/a
iron/operators/layer_norm
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_layer_norm[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048]✅ 5/5455.720.02n/a
test_layer_norm[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024]✅ 5/5432.120.02n/a
test_layer_norm[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024]✅ 5/5662.660.02n/a
test_layer_norm[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512]✅ 5/5417.220.02n/a
test_layer_norm[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512]✅ 5/5319.280.03n/a
test_layer_norm[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256]✅ 5/5862.580.01n/a
iron/operators/leaky_relu
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_leaky_relu[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048-alpha_0.01]✅ 5/5420.720.02n/a
test_leaky_relu[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048-alpha_0.1]✅ 5/5377.940.02n/a
test_leaky_relu[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048-alpha_0.25]✅ 5/5433.560.03n/a
test_leaky_relu[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024-alpha_0.01]✅ 5/5368.820.03n/a
test_leaky_relu[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024-alpha_0.01]✅ 5/5340.780.03n/a
test_leaky_relu[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512-alpha_0.01]✅ 5/5318.880.03n/a
test_leaky_relu[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512-alpha_0.01]✅ 5/5412.180.02n/a
test_leaky_relu[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256-alpha_0.01]✅ 5/5568.220.02n/a
iron/operators/mem_copy
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_mem_copy[input_length_2048-num_cores_1-num_channels_1-bypass_False-tile_size_2048]✅ 5/5328.260.03n/a
test_mem_copy[input_length_2048-num_cores_2-num_channels_1-bypass_False-tile_size_1024]✅ 5/5484.000.02n/a
test_mem_copy[input_length_2048-num_cores_2-num_channels_2-bypass_False-tile_size_1024]✅ 5/5351.380.03n/a
test_mem_copy[input_length_2048-num_cores_4-num_channels_1-bypass_False-tile_size_512]✅ 5/5374.580.02n/a
test_mem_copy[input_length_2048-num_cores_4-num_channels_2-bypass_False-tile_size_512]✅ 5/5365.160.02n/a
test_mem_copy[input_length_2048-num_cores_8-num_channels_2-bypass_False-tile_size_256]✅ 5/5493.520.02n/a
iron/operators/relu
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_relu[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048]✅ 5/5345.860.02n/a
test_relu[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024]✅ 5/5726.420.02n/a
test_relu[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024]✅ 5/5628.400.02n/a
test_relu[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512]✅ 5/5355.480.03n/a
test_relu[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512]✅ 5/5501.980.02n/a
test_relu[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256]✅ 5/5454.720.02n/a
iron/operators/repeat
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_cols_without_a_legal_split_is_rejected[cols_1031-why_prime > 1023: the only divisors are 1 and cols, neither legal]✅ 5/5n/an/an/a
test_cols_without_a_legal_split_is_rejected[cols_2062-why_2 x 1031: the only word-aligned chunk leaves a 1031-wide chunk count]✅ 5/5n/an/an/a
test_cols_without_a_legal_split_is_rejected[cols_513-why_odd: every divisor is odd, so no chunk is a whole 32-bit word]✅ 5/5n/an/an/a
test_repeat[rows_4-cols_1024-repeat_2-transfer_size_None]✅ 5/5417.660.07n/a
test_repeat[rows_8-cols_512-repeat_4-transfer_size_64]✅ 5/5472.380.10n/a
test_repeat[rows_8-cols_64-repeat_4-transfer_size_None]✅ 5/5468.160.01n/a
iron/operators/rms_norm
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_rms_norm[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048-weighted_False]✅ 5/5360.400.03n/a
test_rms_norm[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048-weighted_True]✅ 5/5284.740.04n/a
test_rms_norm[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024-weighted_False]✅ 5/5363.260.02n/a
test_rms_norm[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024-weighted_True]✅ 5/5415.700.03n/a
test_rms_norm[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024-weighted_False]✅ 5/5456.280.02n/a
test_rms_norm[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024-weighted_True]✅ 5/5359.300.03n/a
test_rms_norm[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512-weighted_False]✅ 5/5423.160.02n/a
test_rms_norm[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512-weighted_True]✅ 5/5391.740.02n/a
test_rms_norm[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512-weighted_False]✅ 5/5384.160.02n/a
test_rms_norm[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512-weighted_True]✅ 5/5355.720.03n/a
test_rms_norm[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256-weighted_False]✅ 5/5480.920.02n/a
iron/operators/rope
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_rope[rows_32-cols_512-angle_rows_32-aie_columns_1-method_type_0]✅ 5/5401.840.26n/a
test_rope[rows_32-cols_512-angle_rows_32-aie_columns_2-method_type_0]✅ 5/5472.160.22n/a
test_rope[rows_32-cols_512-angle_rows_32-aie_columns_4-method_type_0]✅ 5/5426.740.27n/a
test_rope[rows_32-cols_512-angle_rows_8-aie_columns_1-method_type_0]✅ 5/5384.900.20n/a
test_rope[rows_32-cols_512-angle_rows_8-aie_columns_2-method_type_0]✅ 5/5420.660.20n/a
test_rope[rows_32-cols_512-angle_rows_8-aie_columns_4-method_type_0]✅ 5/5426.520.21n/a
iron/operators/sigmoid
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_sigmoid[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048]✅ 5/5415.740.02n/a
test_sigmoid[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024]✅ 5/5403.220.02n/a
test_sigmoid[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024]✅ 5/5376.220.02n/a
test_sigmoid[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512]✅ 5/5405.880.02n/a
test_sigmoid[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512]✅ 5/5372.860.03n/a
test_sigmoid[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256]✅ 5/5415.320.02n/a
iron/operators/silu
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_silu[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048]✅ 5/5264.580.03n/a
test_silu[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024]✅ 5/5252.040.03n/a
test_silu[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512]✅ 5/5360.380.02n/a
iron/operators/softmax
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_softmax[input_length_32768-num_aie_columns_2-num_channels_2-tile_size_1024]✅ 5/5526.920.28n/a
test_softmax[input_length_32768-num_aie_columns_2-num_channels_2-tile_size_2048]✅ 5/5532.640.27n/a
test_softmax[input_length_32768-num_aie_columns_2-num_channels_2-tile_size_512]✅ 5/5529.760.27n/a
iron/operators/strided_copy
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_strided_copy[chunked_transfer]✅ 5/5274.920.02n/a
test_strided_copy[contiguous]✅ 5/5370.480.01n/a
test_strided_copy[four_channels]✅ 5/5418.160.01n/a
test_strided_copy[kv_slot0]✅ 5/5412.580.39n/a
test_strided_copy[kv_slot5]✅ 5/5332.560.44n/a
test_strided_copy[kv_slot5_four_channels]✅ 5/5346.100.41n/a
test_strided_copy[kv_slot5_two_channels]✅ 5/5409.360.34n/a
test_strided_copy[kv_slot_last]✅ 5/5343.500.43n/a
test_strided_copy[two_channels]✅ 5/5488.240.01n/a
test_strided_copy[two_channels_chunked]✅ 5/5250.240.02n/a
test_transfer_size_not_dividing_per_channel_share_is_rejected[iter0]✅ 1/1n/an/an/a
test_transfer_size_not_dividing_per_channel_share_is_rejected[iter1]✅ 1/1n/an/an/a
test_transfer_size_not_dividing_per_channel_share_is_rejected[iter2]✅ 1/1n/an/an/a
test_transfer_size_not_dividing_per_channel_share_is_rejected[iter3]✅ 1/1n/an/an/a
test_transfer_size_not_dividing_per_channel_share_is_rejected[iter4]✅ 1/1n/an/an/a
iron/operators/swiglu_decode
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_swiglu_decode[embedding_dim_1024-hidden_dim_3584]✅ 5/517100.150.00n/a
test_swiglu_decode[embedding_dim_2048-hidden_dim_2048]✅ 5/513871.320.00n/a
iron/operators/swiglu_prefill
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_swiglu_prefill[seq_len_256-embedding_dim_2048-hidden_dim_2048-prio_accuracy_False]✅ 5/520411.270.11n/a
iron/operators/tanh
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_tanh[input_length_2048-num_aie_columns_1-num_channels_1-tile_size_2048]✅ 5/5344.420.03n/a
test_tanh[input_length_2048-num_aie_columns_1-num_channels_2-tile_size_1024]✅ 5/5346.260.03n/a
test_tanh[input_length_2048-num_aie_columns_2-num_channels_1-tile_size_1024]✅ 5/5403.940.02n/a
test_tanh[input_length_2048-num_aie_columns_2-num_channels_2-tile_size_512]✅ 5/5451.340.02n/a
test_tanh[input_length_2048-num_aie_columns_4-num_channels_1-tile_size_512]✅ 5/5373.220.02n/a
test_tanh[input_length_2048-num_aie_columns_4-num_channels_2-tile_size_256]✅ 5/5427.340.02n/a
iron/operators/transpose
TestChecksLatency (mean)Bandwidth (mean)Throughput (mean)
test_transpose[M_2048-N_64-aie_columns_1-channels_1-m_64-n_64-s_8-num_batches_1]✅ 5/51179.720.84n/a
test_transpose[M_2048-N_64-aie_columns_1-channels_1-m_64-n_64-s_8-num_batches_2]✅ 5/51782.821.18n/a
test_transpose[M_2048-N_64-aie_columns_1-channels_2-m_64-n_64-s_8-num_batches_1]✅ 5/5486.101.17n/a
Phoenix - Examples

IRON

Tested on 2026_09_14_23_26_05 at commit 5bbc769.

Trend tables omitted, the comment hit GitHub's size limit. Full report in the workflow run.

hunhoffe and others added 6 commits September 11, 2026 17:05
A core can HOLD a B chunk across m_chunk accumulators instead of releasing
it after one, so DDR reads B m_row_blocks/m_chunk times. That recovers the
traffic the removed B residency used to save, without residency's cost:
residency sized the memtile buffer from k_iters and replayed it
m_row_blocks times, putting both K and M in the device configuration,
whereas m_chunk is a configuration constant.

Defaults to 1 (off). It is a tested knob, not a default, because
interleaved A/B at K=1024 N=4096 does not show a consistent win:

    M      m_chunk=1 min/med    m_chunk=2 min/med     min      med
     512    525.4 /  622.7       502.1 /  566.3      -4.4%    -9.1%
    1024    959.0 / 1081.6      1092.4 / 1162.9     +13.9%    +7.5%
    2048   1902.8 / 1986.0      1837.1 / 1940.0      -3.5%    -2.3%

B's traffic does fall, but the per-unit A descriptors m_chunk forces
(a_split) appear to eat it. The M=1024 regression is not monotonic in
n_units and is unexplained -- that is the open question, and the reason
this is off by default.

How the interleave works, since it is the non-obvious part: the core
consumes A as (k, b_iter, mc, band), with mc INSIDE b_iter. A second A
fifo would express that directly but needs a third core input DMA channel
against a hardware limit of two. So the memtile A object holds m_chunk
stacked tiles and the forward's dims_to_stream emits them interleaved,
which fits the memtile BD's four dimensions only because mc's stride
(M_TILE*K_TILE) exactly equals the row-group dimension's size*stride and
the two merge.

A partial group is inexpressible -- stride 0 inner is rejected, stride 0
outermost is the BD repeat count (one object per repetition, not one in
total), and sub-object fills do not coalesce, all three confirmed on
hardware -- so op.py resolves m_chunk to 1 when it would not divide
m_row_blocks, or when the group's ROWS*M_TILE*K stride would overflow the
shim BD's 20-bit step.

Also stops forcing OVERLAP=1 on every split block: only a block spanning
more than one window awaits inside itself. Worth -3.5% at M=2048 alone.

37/37 iter0 tests pass on npu2.

Co-Authored-By: André Rösti <an.roesti@gmail.com>
Moves off the 1.4.3.dev85 snapshot onto the tagged release. llvm-aie is
unchanged at 22.0.0.2026090701+3e93bf7b, which is the pin mlir-aie v1.4.3
itself names in utils/peano-requirements.txt, so the two stay in step.

Tagged wheels live under their own tag's asset page rather than
latest-wheels-4 (which carries only the .dev builds), hence the extra
find-links.

Co-Authored-By: Claude <noreply@anthropic.com>
CT_MAX_K_FOR_N is carried to the kernel as -DMM_FUSED_CT_K but appeared in
neither artifact name. This repo's build cache keys on filename and mtime
rather than on source or flags, so an object or xclbin built at one ct_max_k
silently satisfied a request for another.

Naming it in _kernel_object alone is not enough, and the reasoning that let
that hole stand is worth recording: tile_ma usually moves with ct_max_k, but
tile_ma is caller-overridable, so tn128/ma16 is reachable at two different
ct_max_k values. An xclbin built by an experiment at ck=128 was then served
to test_gemm_tile_options[tn128-ma16], which wants ck=32, and it returned
NaN rather than an error.

An artifact name must cover every input to THAT artifact; do not argue one
field is implied by another unless the implication holds for every reachable
configuration, overrides included.

Co-Authored-By: Claude <noreply@anthropic.com>
A parameter word is not free. Each costs ~66 ns per core and the sequence
writes ROWS*COLS = 32 of them, so every word is ~2.06 us of dispatch latency
-- measured by padding the buffer at a fixed core count (12 words 108.6 us,
24 words 135.2, 48 words 182.7). Against a ~107 us floor that is most of a
short-prefill dispatch.

Five of the ten were dead or duplicated:

  * the clamp trio is now sent only by a clamp-capable build. Where no
    clamped path is compiled in -- the default, and every real projection --
    those three words were written on every dispatch and never read.
  * n_chunks / n_units are sent only when m_chunk > 1. They are
    m_row_blocks // M_CHUNK and each other, so at the shipped M_CHUNK = 1 the
    core reads m_row_blocks instead. No on-core arithmetic.

and n_work / n_drain are now derived rather than sent, from a raw N word plus
the tile's own column. Branch-free, and both divisors are powers of two, so
it lowers to sdiv-by-constant and leaves no __divsi3 (verified in the .elf,
not just the .ll). Note ScalarValue overloads add/sub/mul/floordiv/mod but
NOT the shift operators, so this uses // rather than >>.

The column index is per-tile static data, deliberately not a constant folded
into the program: the 32 core programs differ today only in symbol names, and
baking it into code would make them differ in instructions, foreclosing a
future one-program xclbin.

rtp_layout() sizes the buffer from (clamp_capable, m_chunk), both of which are
already in _config_tag, so the word count cannot vary within a configuration
and ship-once-use-many is preserved -- verified by loading one xclbin and
dispatching shapes that disagree on M, K, N, on which columns sit a block
out, and on the activation.

Also guards CT_MAX_K_FOR_N: it reads like a tuning table but is load-bearing
for correctness, and a wrong value fails silently (err/mass 3.45e-02 at
tile_n=64/ct_k=64, NaN at tile_n=128). Root cause not found; pack_b is ruled
out by test, its permutation round-trips at ct_k 128, 64 and 32. Unverified
pairs now raise rather than miscompute.

30-shape suite: -3.5% median at M=256 (best -11.3%, E2B/kv), within noise at
M >= 1024 -- the saving is a constant ~12 us. Accuracy bit-identical on all
30 shapes; frozen-reference control drifted +0.11%.

Co-Authored-By: Claude <noreply@anthropic.com>
--no-short is not a real pytest option. What the harness actually wants is
--iterations 1: each test already averages ITERS dispatches over ROUNDS
interleaved rounds, so conftest's default of 5 repeats the whole matrix five
times for nothing.

Also records that -s must not be passed when the CSV is wanted -- the reporter
parses captured stdout, so disabling capture yields a CSV with no metric
columns.

Co-Authored-By: Claude <noreply@anthropic.com>
Where K or N is 10240 the row-block stride overflows the shim BD's 20-bit
iteration step, so that leg is issued as one transfer per row-block. Two shim
resources bound how many may be outstanding and neither is modelled by the
toolchain: BD ids (16/tile, freed without a completion check) and the channel
task queue (4 deep, pushed unconditionally).

That bound was enforced by windowing -- issue four, await the whole window,
issue the next four, then the same again per column-block. It is correct, but
TaskGroup.finish() emits dma_await_task, so each of those is a real barrier and
the channel drains to EMPTY at every window and column-block boundary. On a
DDR-rate-bound design those bubbles are the entire cost of the split path. The
OVERLAP value computed for this path was never read by it.

Retire the oldest transfer as the next is issued instead: the same number stay
in flight, the queue bound is enforced directly rather than by draining, and
the channel stays full across both kinds of boundary. Interleaved 8 rounds x 30
iters, bit-exact against the previous sequence on every shape:

    E4B/gateup M1024  4119.4 -> 3617.7  -12.2%
    E4B/gateup M2048  7664.8 -> 7182.4   -6.3%
    E4B/down   M1024  3649.2 -> 3553.4   -2.6%
    E4B/down   M2048  7196.6 -> 6978.7   -3.0%

The 24 shapes that do not split are untouched, measured at -0.1% median over
the full suite. One xclbin still serves every shape.

A unit is weighted by the C descriptors it drains (M_CHUNK under c_split), not
counted as one: counting units would overrun the 4-deep queue by exactly
M_CHUNK, and overrunning it hangs rather than diagnoses.

Also drops three knobs that no longer have a consumer -- the overlap parameter
(never passed), col_work/col_drain (superseded by the core deriving its own
trip counts) and the mt_*_bytes sizes (orphaned when B residency went) -- and
the prose describing mechanisms this design no longer has.

Co-Authored-By: Claude <noreply@anthropic.com>
@hunhoffe hunhoffe changed the title FLM GEMM w/ RTPs flm.GEMM: take M, K, N and the activation as runtime parameters Sep 14, 2026

@hunhoffe hunhoffe left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More fine-tuning needed.

Comment thread aie_kernels/generic/mm_fused.cc Outdated
#ifndef MM_FUSED_EPILOGUE_MODE_MASK
#define MM_FUSED_EPILOGUE_MODE_MASK 0xF
#endif
// Whether a clamp is compiled in at all. Like the mode mask above this is a

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to imply there are multiple builds per clamp. But doesn't this build include all the epilogue options? Isn't the logic to clamp or not static (and could be included in program memory?)

Comment thread aie_kernels/generic/mm_fused.cc Outdated
@@ -144,47 +197,64 @@ void mm_fused_k_step(bfloat16 *a_buf, mm_fused_b_elem_t *b_buf, float *y_acc, in
// Fusing the activation here is the point: the values are already in registers

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These few comment paragraphs seem excessive. Can you be more concise?

Comment thread iron/operators/flm/gemm/design.py Outdated
# (M_TILE * 256 * 4 = 65536 bytes) already fills the whole of L1, before A, B
# or C are even counted, so no ct_max_k could ever make it fit.
CT_MAX_K_FOR_N = {16: 16, 32: 32, 64: 128, 128: 32}
# (tile_n, ct_max_k) pairs KNOWN TO COMPUTE CORRECTLY on hardware. The table

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: can we dive deep? I don't like leaving artifacts from unsolved bugs in designs.

)

@property
def config_name(self) -> str:

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the onfig_tag actually reused? if not, can we combine functions instead of having mulitple helpers?


def get_mlir_artifact(self):
@property
def _reference_shape(self) -> tuple[int, int, int]:

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This... doesn't seem great. Can we use the runtime sequence generation via https://github.com/Xilinx/mlir-aie/blob/main/test/npu-xrt/matmul_whole_array_dynamic/whole_array_dynamic.py

Comment thread requirements.txt
--extra-index-url https://pypi.org/simple

mlir_aie==1.4.3.dev85+gdf48abc
# Tagged release wheels live under their own tag's asset page, not under

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need a release comment here.

This operator had accumulated about one line of prose per line of code, and
the RTP work made it worse rather than better -- design.py went from 429
comment and docstring lines to 633 while the code grew by 120.

Most of that was not explaining the code. It was measurement tables that
belong in README.md, rationale for alternatives that were tried and rejected,
and restatements of the line underneath. Several facts were stated two or
three times over: that the build cache keys on filename, that a second A fifo
would want a third input DMA channel, that C drains in row-block order even
under M_CHUNK.

What is kept is the class of comment that is expensive to lose, because the
failure it describes is silent: the BD-id recycle hazard that corrupts rather
than faulting, the shim task-queue depth that hangs rather than diagnosing,
_VERIFIED_CT_K where a wrong entry computes the wrong answer, and the memtile
placement pin. Those are stated once, at the code they constrain.

    design.py     42% -> 33% prose      op.py         45% -> 35%
    test.py       41% -> 33%            benchmark.py  42% -> 35%
    mm_fused.cc   46% -> 36%

Also corrects documentation that had gone stale. test.py still described the
split legs as retired in windows, which they have not been since the rolling
retire landed, so its docstring, an inline comment and two entries in the
shape table were all describing a mechanism that no longer exists.
test_gemm_split_leg_windowing is renamed to test_gemm_split_leg_bounds for the
same reason. Drops an unused `import os`.

No functional change: the AST with docstrings stripped is identical except for
that import and the two renames. 185/185 pass.

Co-Authored-By: Claude <noreply@anthropic.com>
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.

2 participants