Skip to content

Encode result block scales as OCP E8M0 - #1

Closed
DanielKellerM wants to merge 2 commits into
pulp-platform:gwaihirfrom
DanielKellerM:e8m0-result-scale
Closed

DanielKellerM wants to merge 2 commits into
pulp-platform:gwaihirfrom
DanielKellerM:e8m0-result-scale

Conversation

@DanielKellerM

@DanielKellerM DanielKellerM commented Oct 7, 2026 •

Copy link
Copy Markdown

MXCore writes its result scales as signed numbers, while its inputs, the OCP MX spec and iDMA use E8M0 (unsigned, offset 127). So MXCore cannot read its own results back, and iDMA decodes them wrong.
This switches the result scale to E8M0 in the RTL and PyGolden; the data bytes do not change.
MXCore's tests pass (the vector-size 8/16 failures exist without this change too), and the gwaihir iDMA to MXCore to iDMA test is now exact.
Fixes pulp-platform/gwaihir#119

The result quantizer emitted signed two's complement block scales while
MXCore operands, OCP MX and iDMA use unsigned E8M0 (bias 127), so MXCore
could not consume its own MXFP8 results. Emit E8M0 scales, clamped at 0,
and an E8M0 NaN scale (0xFF) for poisoned blocks. Update PyGolden to match.
@DanielKellerM
DanielKellerM requested review from Jayanth2209 and gamzeisl and a balanced review from Copilot October 7, 2026 03:53

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@DanielKellerM

Copy link
Copy Markdown
Author

Suggested change, please feel free to modify or force-push the branch

DanielKellerM added a commit to pulp-platform/gwaihir that referenced this pull request Oct 7, 2026
Temporary pin to pulp-platform/MXCore#1 (DanielKellerM/MXCore e8m0-result-scale); repin to pulp-platform/MXCore gwaihir once it merges.
DanielKellerM added a commit to pulp-platform/gwaihir that referenced this pull request Oct 7, 2026
MXCore now writes E8M0 result scales (pulp-platform/MXCore#1), so the c_scale, c_mx and c_deq checks are bit-exact and gating.
@Jayanth2209

Copy link
Copy Markdown
Collaborator

Thanks Daniel! I applied these changes on the gwaihir branch as it was already done on experiment branch. Result scales are now unsigned/biased OCP E8M0.

@Jayanth2209 Jayanth2209 closed this Oct 7, 2026
hopang-0221 pushed a commit to pulp-platform/gwaihir that referenced this pull request Oct 9, 2026
MXCore now writes E8M0 result scales (pulp-platform/MXCore#1), so the c_scale, c_mx and c_deq checks are bit-exact and gating.
Lore0599 added a commit to pulp-platform/gwaihir that referenced this pull request Oct 11, 2026
* [Bender][hw][sw][CI] MXCore Feature and Kernel Updates

MXCore now supports accumulator preload for C += AxB

MXCore now supports BF16 output quantization

MXCore now supports multi-context configuration

[hw] MXCore interrupt on job(s) done only

[sw] Extended mxcore.c with PRELOAD/MULTI_JOB modes, disabled by default

[sw] Added mxcore_multi.c (with PRELOAD/MULTI_JOB) for work-splitting a large GEMM across 16 clusters

[CI] Extend CI with new MXCore kernels

* [Bender] Bump MXCore with Quantizer Fixes

Result scales are now unsigned/biased like the input scales, in line with OCP spec

* deps: Bump iDMA to devel for the planar MX layout

iDMA devel drops the inline 33 B MX block for separate data and E8M0
scale planes. Move l2_dma_mx_roundtrip to the planes, with a 2D quant and
dequant that step the scale plane by the scale stride. Pinned by commit
until iDMA 0.7.4 is tagged.

* hw: Wire the mx4 iDMA timing cuts (103) and frontend parameters

TimingCuts 103 (mx_beat_push, dfe_ready_ahead, dfe_reg_flags, wdp_head_spill,
outst_cnt_reg) and BufferDepth 3 to the backend; DataWidth and ComputeOps to
the reg64 frontends.

* deps: Bump iDMA to devel 6d64058 and axi_obi to the comb-loop fix

iDMA devel deploy 378fa46 (#267 on #271), pinned by commit until 0.7.4 is
tagged. axi_obi points at pulp-platform/axi_obi#7 until it merges.

* deps: Bump iDMA to v0.7.4

* sw: Add an iDMA to MXCore MX end-to-end test

The cluster DMA gathers FP32 A and B ([N][K]) from L2 and quantizes them
into MXCore's operand planes, MXCore runs the GEMM in FP32 and MXFP8, and
the DMA dequantizes the MXFP8 result. verify.py checks the operand planes
and the FP32 result bit-exactly; the result scale and dequant checks are
reported but not gating until #119, since MXCore writes signed result scales.

* sw: Gate the mx_e2e result scale, MXFP8 result and dequant checks

MXCore now writes E8M0 result scales (pulp-platform/MXCore#1), so the c_scale, c_mx and c_deq checks are bit-exact and gating.

* sw: Port mx_e2e to the MXCore preload register map

MXCore d45847f (#126) inserts the preload pointer and tile size registers; without the port the job never completes.

* sw: Add an FP16 variant of the MX end-to-end test

mx_e2e_fp16 runs the same flow from FP16 sources with the FP16 MX quant
and dequant ops. verify.py now takes its goldens from iDMA's
test/idma_mx_golden.h (quant/dequant) and MXCore's PyGolden (layout, GEMM,
result quantization) instead of local math, also checks the iDMA dequant of
the planes MXCore wrote, and checks canaries around every L2 output.

* sw: Preload the mx_e2e canaries and fix the golden pointer types

Core byte stores to the L2 canaries before the run made MXCore's result
port hang (HCI RQ-3 on the result mux) in both variants, so the canaries
are now part of the preloaded image. The ctypes goldens passed 64-bit
pointers as int, which truncated them and crashed verify.py.

* [hw] Minor mem tile rtl changes for timing improvement

* Fix lint issue

* Bump AXI obi

---------

Co-authored-by: Jayanth Jonnalagadda <jjonnalagadd@iis.ee.ethz.ch>
Co-authored-by: Hong Pang <hopang@iis.ee.ethz.ch>
Co-authored-by: Lorenzo Leone <lleone@iis.ee.ethz.ch>
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.

3 participants