Skip to content

imatrix: read activations through strides, all planes, and F16/BF16 - #31

Merged
danielhanchen merged 1 commit into
masterfrom
imatrix-collector-strides
Oct 16, 2026
Merged

danielhanchen merged 1 commit into
masterfrom
imatrix-collector-strides

Conversation

@danielhanchen

Copy link
Copy Markdown
Member

Summary

IMatrixCollector::collect_imatrix read the activation operand of a dense MUL_MAT as a contiguous F32 matrix and looped over ne[1] only. It ignored the row stride (nb[1]), the batch planes (ne[2], ne[3]), and F16 / BF16 inputs, which were reinterpreted as floats. The device-copy path also sized its host buffer from the element count rather than the byte size.

This change:

  • reads every activation row through byte strides, over all planes;
  • converts F16 and BF16 rows with the ggml helpers, and refuses any other input type loudly (counted and reported at save time instead of silently mixing garbage into the statistics);
  • fixes the host-copy buffer size on the device path;
  • applies the same stride handling to the MUL_MAT_ID (MoE) branch;
  • prints a short summary when the imatrix is saved (calls, rows, skipped tensors by reason).

Results

Synthetic harness driving the unchanged collector method: master fails the strided, batched, permuted and F16 cases (relative error up to 4.5) and aborts on BF16; with this change all 7 cases pass (error at most 2.1e-7).

Real calibration graphs, matmul operand layouts counted during collection:

Run Backend Matmul calls Contiguous F32 2-D Other layouts
FLUX.2-klein, 256x256, 2 steps CPU 367 367 0
FLUX.2-klein, batch 2, CFG 3 CPU 1090 1090 0
FLUX.2-klein, batch 2, CFG 3, repack off CPU 1090 1090 0
MiniMax-H3 Q4_K, 256x160, 9 frames, 2 steps CUDA 878 878 0

The imatrix files are identical before and after the fix on all of these, so existing calibrations for these families are unaffected. The fix matters for graphs that do hand the collector strided, batched or half-precision operands; Wan, LTX, Qwen-Image and Z-Image graphs and the Metal, Vulkan and ROCm backends were not checked.

The dense collector read src1 as packed f32 and walked ne[1] rows only, so
strided row views, batched ne[2]/ne[3] planes and F16/BF16 activations were
summed from the wrong memory or skipped. Rows are now addressed through
nb[1..3], every plane is accumulated into the weight's column vector, and
F16/BF16 rows are converted with the ggml row helpers. Other types, or a
strided nb[0], are refused with an error and counted instead of being read
as floats. The device copy is sized by ggml_nbytes so a strided view no
longer overruns it. The MUL_MAT_ID branch uses the same row reader.

Saving the imatrix logs how many collected matmuls saw each layout.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-14T13:33:03.435893Z 8a1837a PR opened
🔒 Security Review ✅ Completed 2026-10-14T13:34:29.478484Z 8a1837a PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@danielhanchen
danielhanchen merged commit 6c29ce2 into master Oct 16, 2026
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