RISC-V Development

FP8 Lands in XiangShan's Reference Model: Inside the Verification Stack for RISC-V Matrix Extensions

📅 2026-10-29 ⏱ 12 min read 🔗 Source: OpenXiangShan/NEMU + OpenXiangShan/difftest commit history, 24–27 Oct 2026

Every RISC-V matrix extension argument eventually collapses into the same question, and it is never the peak-throughput one. It is this: when two implementations disagree by one unit in the last place, which one is wrong? A matrix unit is a reduction tree with an accumulator, a rounding mode, a saturation flag and a signedness decision per operand pair, and any of those can differ between a vendor's RTL and a software model without either side being obviously broken. Peak TOPS is a marketing number. Agreement on the edge cases is the thing that lets a design tape out.

That is why the more interesting RISC-V news of the past week is not a chip launch. It is seventeen commits landed across OpenXiangShan/NEMU and OpenXiangShan/difftest between 24 and 27 October 2026, which together move the XiangShan project's matrix-extension support from "the instruction semantics are implemented" to "the numerical semantics are verifiable". FP8 arrives in the reference model with FP32 accumulation. MMA event types stop being inferred from storage width and start being decoded from the mcfg register. INT32 saturation becomes real on both the software and the GPU differencing backends. And synchronous verification becomes a build flag.

Honesty note. Everything below is read from the actual patches and the public source tree — commit SHAs, timestamps, authors, per-file diffstats and code fragments are quoted as retrieved from the GitHub API on 29 October 2026. The matrix extension implemented here is NEMU's implementation of an AME draft; it is not a ratified RISC-V specification, and this article does not claim any performance number. Where the source is silent, the text says so rather than filling the gap.

What the Matrix Extension Actually Looks Like in Code

NEMU gates the whole feature behind CONFIG_RV_AME. The register file is modelled as matrix tile registers plus a set of configuration registers, and the instruction set is small enough to enumerate. Reading src/isa/riscv64/instr/ame/ on 29 October 2026 gives this:

InstructionFunction
minitInitialise matrix state; sets mstatus.MS
msettilem / msettilemiSet tile row count (register / immediate form)
msettilek / msettilekiSet reduction depth
msettilen / msettileniSet tile column count
msetcfg / mgetcfgWrite / read one of 8 mcfg registers (index ≥ 8 is an illegal-instruction exception)
mmaccMatrix multiply-accumulate over the configured tile
msyncreset / mreleaseToken-based synchronisation; token index bounded by MSYNC (default 16)
mldst familyMatrix load / store, including a transpose fast path

The geometry is compile-time configured. Defaults in src/isa/riscv64/Kconfig are RV_AME_TLEN = 65536 bits (8 KiB per tile register) and RV_AME_TRLEN = 512 bits (64 bytes per row), which yields ROWNUM = TLEN / TRLEN = 128 rows. RV_AME_MLEN = 32 bits drives the accumulator sizing: ALEN = ROWNUM × ROWNUM × MELEN = 64 KiB, and ARLEN = ROWNUM × MELEN = 512 bytes. Tile bounds follow directly: TMMAX = TNMAX = ROWNUM, while TKMAX(sew) = TRLEN / sew — so with a 512-bit row the reduction depth a single mmacc may request is 64 elements at 8-bit, 32 at 16-bit and 16 at 32-bit. Widening the data type costs reduction depth, which is why tile shape and type have to be decided together.

The type encoding is a 15-entry table in mreg.h. It is worth reproducing because three of its entries are the reason a naive verification harness silently passes:

enum MTYPECODE_TAB0 {
  MTYPECODE_INT4 = 0,  MTYPECODE_UINT4,   MTYPECODE_INT8,
  MTYPECODE_UINT8,     MTYPECODE_INT32,   MTYPECODE_NVFP4,
  MTYPECODE_MXFP4,     MTYPECODE_FP8E5M2, MTYPECODE_FP8E4M3,
  MTYPECODE_FP16,      MTYPECODE_BF16,    MTYPECODE_TF32,
  MTYPECODE_FP32,      MTYPECODE_FP2PACK4, MTYPECODE_FP2PACK5
};

INT8 and UINT8 are one byte wide with different arithmetic meaning. FP8E5M2 and FP8E4M3 are one byte wide with different exponent and mantissa splits (5/2 versus 4/3), and INT8 is also one byte wide. Three distinct semantics, one storage width. Any code path that carries only "how many bytes" is already wrong, which is exactly what commit #1269 was written to fix.

The Type Matrix, Before and After #1266

mcompute_impl.h enumerates the multiply-accumulate combinations the model accepts. Comparing 24 October against 27 October gives a clean before/after:

Operand pairAccumulatorState
INT4 × INT4INT32Pre-existing
INT8 × INT8INT32Pre-existing
FP16 × FP16FP16Pre-existing
FP16 × FP16FP32Pre-existing
BF16 × BF16FP32Pre-existing
FP32 × FP32FP32Pre-existing
FP8 E4M3 × FP8 E4M3FP32Added 27 Oct 2026, #1266
FP8 E5M2 × FP8 E5M2FP32Added 27 Oct 2026, #1266

The E4M3/E5M2 split is not cosmetic. E4M3 gives four exponent bits and three mantissa bits — more precision, narrower dynamic range, no infinity encoding. E5M2 gives five and two — range at the cost of mantissa. Training pipelines reach for one and inference stacks for the other, and a reference model that implements "FP8" as a single type will disagree with hardware on exactly the overflow-heavy inputs that matter.

FP4 is conspicuously not in the accepted list, and the reason is in mmacc itself:

#ifdef CONFIG_RV_AME_FP4
  if (is_raw_fp4_type_code(s1mcfg) || is_raw_fp4_type_code(s2mcfg) ||
      is_raw_fp4_type_code(dmcfg)) {
    longjmp_exception(EX_II);
  }
#endif

NVFP4 and MXFP4 exist in the type table but mmacc raises an illegal-instruction exception when it sees them. The encoding knows about FP4; the execute path does not yet implement it. That distinction is the difference between a roadmap and a claim.

Seventeen Commits in Ninety-Six Hours

Querying both repositories for the window 2026-10-24T00:00Z to 2026-10-28T00:00Z returns 7 commits in NEMU and 10 in difftest. Reproduced verbatim, newest first:

RepoSHATimestamp (UTC)AuthorSubject
NEMUa683e0bb10-27 09:45:31Haoyuan Fengfeat(configs): add layered BOOM reference profiles (#1262)
NEMU50a9a8e910-27 09:00:34Kunlin Youperf(memory): reuse HostTLB for shared FAST references (#1270)
NEMUe581cb7a10-27 08:23:37Jiru Sunfeat(ame): support FP8 MMA with FP32 accumulation (#1266)
NEMUfcdceb0110-27 02:33:14Kamimiaoci: give diff-spike NEMU 32 GiB of guest memory (#1267)
NEMU337bed5f10-26 15:04:12Kunlin Yourefactor(config): reduce duplication with shared config layers (#1259)
NEMU4465965810-26 15:00:29Jiru Sunfix(ame): encode MMA event types from mcfg semantics (#1269)
NEMU783babde10-26 12:26:33Jiru Sunfix(ame): preserve host FMA exception flags (#1268)
difftest1fa7d81710-27 05:47:48Kunlin Youfeat(fpga): separate DiffTest link and REF checking (#1006)
difftest0308e14510-27 05:39:37Jiru Sunfeat(mma): add synchronous verification build option (#1009)
difftesta527248910-27 04:31:39Jiru Sunfix(mma): honor integer saturation in CPU and CUDA (#1008)
difftest2abc9f6610-26 14:11:32Haoyuan Fengfeat(difftest): add BOOM DiffTest support (#998)
difftestc1f6e34710-26 06:18:46Kunlin Youfix(difftest): preserve C++11 build compatibility (#1003)
difftestb548dc0e10-26 01:42:11Kunlin Youfeat(reftrace): record and replay REF-driving traces (#981)
difftest2691d2b410-25 12:36:30Jiru Sunperf(mma): use native-width operand loads (#1002)
difftest4406565110-25 05:32:46Jiru Sunperf(mma): use Tensor Cores for INT8 CUDA verification (#1001)
difftest15debf2c10-25 05:32:30Jiru Sunperf(mma): specialize CUDA floating-point kernels by format (#1000)
difftest9027f0bf10-25 03:51:06Jiru Sunperf(mma): avoid redundant operand and DUT result copies (#999)

Note the shape of it. The 25th is throughput work — Tensor Cores, per-format kernel specialisation, fewer copies. The 26th is correctness work — semantics, flags, trace replay. The 27th is completeness and determinism — a new data type and a switch that trades parallelism for reproducibility. That is a team working through a verification stack in the order you would want them to.

Deep Dive 1: FP8 by Unifying, Not Bolting On

The interesting part of #1266 is the diffstat. mcompute_impl.c goes +104 / −153 — the file shrinks by 49 lines while gaining a data type. The commit message states the mechanism plainly: "Unify floating-point MMA vectorization and extend it to FP8."

The per-file breakdown:

FileDiffWhy
configs/riscv64-matrix-xs-lite_defconfig+10 / −0New config for standalone matrix execution
include/rtl/fp.h+3 / −1FP type plumbing
src/engine/interpreter/fp.c+17 / −0Interpreter entry for 8-bit floats
src/engine/interpreter/softfloat-fp.h+33 / −0E4M3 / E5M2 conversion helpers
src/isa/riscv64/instr/ame/mcompute.h+6 / −0Type dispatch
src/isa/riscv64/instr/ame/mcompute_impl.c+104 / −153Unified vectorised float path
src/isa/riscv64/instr/ame/mcompute_impl.h+2 / −0Enumeration of new MMACC types

The type-matching logic that results is deliberately boring, which is the point — one branch per accepted combination, and everything else falls through to FLOAT_MMACC_UNSUPPORTED:

if (d_type == MTYPECODE_FP16 &&
    s1_type == MTYPECODE_FP16 && s2_type == MTYPECODE_FP16) {
  return FLOAT_MMACC_FP16_FP16_FP16;
} else if (d_type == MTYPECODE_FP32 &&
    s1_type == MTYPECODE_FP16 && s2_type == MTYPECODE_FP16) {
  return FLOAT_MMACC_FP16_FP16_FP32;
} else if (d_type == MTYPECODE_FP32 &&
    s1_type == MTYPECODE_BF16 && s2_type == MTYPECODE_BF16) {
  return FLOAT_MMACC_BF16_BF16_FP32;
/* ... FP32, then the two new entries ... */
} else if (d_type == MTYPECODE_FP32 &&
    s1_type == MTYPECODE_FP8E4M3 && s2_type == MTYPECODE_FP8E4M3) {
  return FLOAT_MMACC_FP8E4M3_FP8E4M3_FP32;
} else if (d_type == MTYPECODE_FP32 &&
    s1_type == MTYPECODE_FP8E5M2 && s2_type == MTYPECODE_FP8E5M2) {
  return FLOAT_MMACC_FP8E5M2_FP8E5M2_FP32;
}

Mixed FP8 inputs — E4M3 on one side, E5M2 on the other — are not in the accepted set. Neither is FP8 into an FP16 accumulator. Whether hardware should support either is a spec question, not an implementation one; right now the model's answer is no, and a differential test that feeds such a pair should expect an exception rather than a result.

Deep Dive 2: Why mcfg Semantics Beat Storage Width

#1269 is the commit that will save somebody a very bad week. Its message: "Separate AMU type payloads from byte-storage widths and integer arithmetic signedness. Use the semantic encoding for both MMA sources and the destination in REF, CTRL and diagnostic events." Three files, +41 / −7.

The failure mode it closes is subtle. Differencing does not compare operands — it compares events: a compact record saying "an MMA happened at this PC, with these operands, this type, this shape". If that record encodes the operand type as a storage width, then E5M2, E4M3 and INT8 all become "1 byte", and a model that computes E4M3 against RTL that computed INT8 will not be caught — the event descriptor matched. You get a green test and a wrong chip.

The fix moves the encoding to the mcfg register's semantics rather than its size, which means the event now carries the actual type code out of the 15-entry table. It is a one-line concept and an unavoidable one: the differencing ABI must be as typed as the ISA.

Why this pattern repeats. RISC-V's extensibility means new types arrive by adding encodings, not by widening registers. Every verification tool that inferred semantics from width — because width was once sufficient — breaks the moment a same-width type with different semantics appears. FP8 is that moment for matrix extensions.

Deep Dive 3: Saturation, the Case the Docstring Admitted

Before #1008, the difftest documentation said this of the INT8 CUDA backend:

Integer MMA uses INT8 Tensor Core instructions on SM80 and newer targets,
retaining the software kernel on older targets. Accumulation wraps at 32
bits without saturation.

After #1008 the same paragraph reads:

Integer MMA uses INT8 Tensor Core instructions on SM80 and newer targets,
retaining the software kernel on older targets. Both paths support wrapping
and saturating INT32 accumulation.

One sentence changed; the consequences run through eight files. In the CUDA kernel the previous comment above the PTX was explicit about the choice:

// Before:
// No .satfinite: the accumulator wraps modulo 2^32, as in the integer reference model.

// After:
// Half dots start from zero; the caller applies the selected INT32 overflow mode.

The instruction itself is mma.sync.aligned.m16n8k32.row.col.s32.s8.s8.s32 — an M16 × N8 × K32 INT8 tile with an S32 accumulator, which is the shape most 8-bit inference kernels are built around. What changed is that the sat field now travels with the request instead of being assumed:

FileDiffWhat it now carries
mma/backend/cuda/int8.cuh+24 / −10Both overflow modes on the device
mma/backend/mma_backend_cute_model.h+18 / −4add_int32(lhs, rhs, saturate) with explicit clamp
mma/backend/mma_backend_cpu.cpp+4 / −3Same ReducePE chunk boundaries for both modes
mma/backend/mma_backend_cuda.cpp+1 / −0Copies amu_event.sat
mma/backend/mma_backend_cuda_impl.{h,cpp}+3 / −0sat in the batch descriptor
mma/backend/mma_backend_cuda_kernel.cu+5 / −4Threads the flag into the element kernel
docs/sw-check.md+1 / −1The honest sentence

The new helper is about as small as code gets and about as easy to get wrong:

CUTE_MMA_HOST_DEVICE static inline int64_t add_int32(int64_t lhs, int64_t rhs, bool saturate) {
  const int64_t result = lhs + rhs;
  if (saturate) {
    if (result > INT32_MAX) return INT32_MAX;
    if (result < INT32_MIN) return INT32_MIN;
    return result;
  }
  return wrap_signed(result, 32);
}

The comment above the calling loop is the tell that this was a real correctness fix and not a feature: "Follow the same ReducePE chunk boundaries for wrapping and saturation." A reduction tree that clamps at the end and one that clamps per chunk produce different answers, and the model has to clamp where the hardware clamps. That is the level at which matrix extensions are actually specified — or, today, not yet specified, which is why the model has to choose and the choice has to be recorded.

Deep Dive 4: Determinism as a Build Flag

Asynchronous differencing is how you get throughput: submit a buffer, let a worker thread verify it while the DUT keeps running, compare later. It is also how you lose error attribution, because by the time a mismatch surfaces the core has moved on and the reported PC may belong to a different instruction.

#1009 adds the escape hatch in cuda.mk, five lines including the comment:

MMA_ASYNC ?= 1
ifeq ($(MMA_ASYNC),0)
SIM_CXXFLAGS += -DCONFIG_DIFFTEST_MMA_SYNC
endif

With MMA_ASYNC=0 the verifier stops owning a thread. The header documents the contract change directly: "With CONFIG_DIFFTEST_MMA_SYNC, submission verifies synchronously on the caller; start()/stop() are no-ops and flush() reports the retained error." The checker change in matrix.cpp is the part that matters for debugging:

+#ifdef CONFIG_DIFFTEST_MMA_SYNC
+          // Do not consume the next ready event after a synchronous failure.
+          if (mma_verifier->has_mma_verification_error()) {
+            set_error_pc(state->coreid, amu_event.pc);
+            return STATE_ERROR;
+          }
+#endif

That is the whole value of the flag: on failure, stop, and attribute the error to the PC that caused it. The default stays asynchronous (MMA_ASYNC ?= 1), with MMA_BATCH_SIZE ?= 256 and MMA_BACKPRESSURE_FACTOR ?= 4. So the same codebase gives you a fast mode for regression runs and a deterministic mode for the afternoon you are chasing a one-in-ten-thousand mismatch.

The Supporting Cast

Three commits outside the MMA path are worth knowing because they change what the harness can do:

And two smaller ones that are quietly important: #1268 preserves host FMA exception flags across model execution — without it, floating-point status bits leak between the model and its host and a differencing run can fail for reasons that have nothing to do with the DUT; #1270 reuses the HostTLB for shared FAST references, which is the kind of change that makes a 64-core run finish before lunch.

How to Read This

Three observations, offered as reading rather than conclusion.

First, the bottleneck has moved. A matrix unit with 128-row tiles and a 64 KiB accumulator is not something you can step through cycle by cycle in software any more. The 25 October commits moved INT8 comparison onto Tensor Cores precisely because the software kernel could not keep up with the DUT. Verification infrastructure is becoming hardware-accelerated in its own right, and that is a permanent change in how these projects are staffed.

Second, the unspecifiable parts are being specified by code. Saturation on overflow, the chunking of a reduction tree, whether mixed FP8 inputs are legal, what happens to NaN in E4M3 (which has no infinity encoding at all) — none of these are settled in a ratified document for matrix extensions today. They are being settled by whichever implementation ships first and by whether the reference model matches it. That is a normal phase for an ISA extension and a genuinely risky one for anyone building a second implementation against a document that does not yet say.

Third, the honest gaps are visible in the source. FP4 is encoded and rejected. Mixed FP8 pairs are rejected. There is no ratified spec to cite. A reader who wants to know what RISC-V matrix extensions actually do in October 2026 is better served by mcompute_impl.h than by any slide deck, because the code has to answer the questions the slides defer.

For the ecosystem, that is the useful signal in a week with no chip launch: the open-source RISC-V matrix stack is being hardened at the numerical-semantics layer, in public, with commit messages that explain the trade-off. When the specification does land, the projects that have been differencing against a typed reference model will be the ones that can claim compliance without an asterisk.

摘要(中文)

2026 年 10 月 24–27 日,香山团队在 OpenXiangShan/NEMU 与 OpenXiangShan/difftest 两个仓库共合入 17 笔提交(NEMU 7 笔、difftest 10 笔),把 RISC-V 矩阵扩展的支持从「指令语义已实现」 推进到「数值语义可验证」。

核心四点:

结构事实:默认配置 TLEN=65536 bit(8 KiB 每 tile 寄存器)、 TRLEN=512 bit(64 B 每行)→ ROWNUM=128;MELEN=32 → 累加器 ALEN 64 KiB;8 个 mcfg 寄存器、16 个 msync 令牌。NVFP4/MXFP4 在类型表中存在, 但 mmacc 会对其抛非法指令异常——编码已知、执行未实现。

一句话:这周没有芯片发布,但开源 RISC-V 矩阵栈正在公开地把「溢出、饱和、NaN、混合精度」这些 规范尚未定论的问题,一行一行地钉进参考模型里。

Кратко (RU)

С 24 по 27 октября 2026 года команда XiangShan внесла 17 коммитов в OpenXiangShan/NEMU (7) и OpenXiangShan/difftest (10), переведя поддержку матричного расширения RISC-V из состояния «семантика инструкций реализована» в состояние «числовая семантика проверяема».

Четыре ключевых изменения: #1266 — FP8 MMA с накоплением FP32 (E4M3×E4M3→FP32, E5M2×E5M2→FP32), реализовано через унификацию векторизованного пути; файл mcompute_impl.c при этом сократился на 49 строк (+104/−153). Смешанные пары FP8 не поддерживаются. #1269 — типы событий MMA теперь кодируются из семантики регистра mcfg, а не из ширины хранения: E5M2, E4M3 и INT8 все однобайтовые, и старая схема пропускала ошибочные сравнения. #1008 — целочисленное насыщение INT32 теперь реально поддерживается и на CPU-, и на CUDA-бэкенде; флаг sat доходит до ядра устройства. #1009 — сборка с MMA_ASYNC=0 включает синхронную проверку (CONFIG_DIFFTEST_MMA_SYNC), при сбое следующее готовое событие не потребляется, поэтому PC ошибки указывается верно.

Геометрия по умолчанию: TLEN=65536 бит на tile-регистр, TRLEN=512 бит на строку → ROWNUM=128; MELEN=32 → аккумулятор 64 КиБ; 8 регистров mcfg и 16 токенов msync. NVFP4/MXFP4 присутствуют в таблице типов, но mmacc вызывает для них исключение недопустимой инструкции: кодирование есть, исполнения нет.

Resumen (ES)

Entre el 24 y el 27 de octubre de 2026 el equipo XiangShan integró 17 commits en OpenXiangShan/NEMU (7) y OpenXiangShan/difftest (10), llevando el soporte de la extensión matricial de RISC-V de «la semántica de instrucciones está implementada» a «la semántica numérica es verificable».

Cuatro cambios clave: #1266 añade FP8 MMA con acumulación FP32 (E4M3×E4M3→FP32, E5M2×E5M2→FP32) unificando la ruta vectorizada: mcompute_impl.c se reduce en 49 líneas (+104/−153). Las parejas FP8 mixtas no están soportadas. #1269 codifica los tipos de evento MMA desde la semántica del registro mcfg y no desde el ancho de almacenamiento — E5M2, E4M3 e INT8 ocupan un byte, y el esquema anterior dejaba pasar comparaciones erróneas. #1008 implementa de verdad la saturación INT32 en los backends CPU y CUDA; el campo sat llega hasta el kernel del dispositivo. #1009 permite compilar con MMA_ASYNC=0 para verificación síncrona (CONFIG_DIFFTEST_MMA_SYNC); tras un fallo no se consume el siguiente evento, de modo que el PC del error es correcto.

Geometría por defecto: TLEN=65536 bits por registro de tile y TRLEN=512 bits por fila → ROWNUM=128; MELEN=32 → acumulador de 64 KiB; 8 registros mcfg y 16 tokens msync. NVFP4/MXFP4 figuran en la tabla de tipos, pero mmacc lanza una excepción de instrucción ilegal: codificados pero no ejecutables.

Résumé (FR)

Entre le 24 et le 27 octobre 2026, l'équipe XiangShan a fusionné 17 commits dans OpenXiangShan/NEMU (7) et OpenXiangShan/difftest (10), faisant passer le support de l'extension matricielle RISC-V de « la sémantique des instructions est implémentée » à « la sémantique numérique est vérifiable ».

Quatre changements clés : #1266 ajoute le MMA FP8 avec accumulation FP32 (E4M3×E4M3→FP32, E5M2×E5M2→FP32) en unifiant le chemin vectorisé flottant : mcompute_impl.c perd 49 lignes (+104/−153). Les paires FP8 mixtes ne sont pas prises en charge. #1269 encode les types d'événement MMA à partir de la sémantique du registre mcfg et non de la largeur de stockage — E5M2, E4M3 et INT8 font un octet, et l'ancien schéma laissait passer des comparaisons fausses. #1008 implémente vraiment la saturation INT32 côté CPU et CUDA ; le drapeau sat parvient jusqu'au noyau GPU. #1009 permet de compiler avec MMA_ASYNC=0 pour une vérification synchrone (CONFIG_DIFFTEST_MMA_SYNC) ; après un échec, l'événement suivant n'est pas consommé, donc le PC de l'erreur est correct.

Géométrie par défaut : TLEN=65536 bits par registre de tile, TRLEN=512 bits par ligne → ROWNUM=128 ; MELEN=32 → accumulateur de 64 Kio ; 8 registres mcfg et 16 jetons msync. NVFP4/MXFP4 figurent dans la table des types, mais mmacc lève une exception d'instruction illégale : encodés mais non exécutables.

Zusammenfassung (DE)

Zwischen dem 24. und 27. Oktober 2026 hat das XiangShan-Team 17 Commits in OpenXiangShan/NEMU (7) und OpenXiangShan/difftest (10) zusammengeführt und damit die Unterstützung der RISC-V-Matrixerweiterung von „die Instruktionssemantik ist implementiert“ auf „die numerische Semantik ist verifizierbar“ gehoben.

Vier Kernänderungen: #1266 ergänzt FP8-MMA mit FP32-Akkumulation (E4M3×E4M3→FP32, E5M2×E5M2→FP32) durch Vereinheitlichung des vektorisierten Gleitkommapfads; mcompute_impl.c schrumpft um 49 Zeilen (+104/−153). Gemischte FP8-Paare werden nicht unterstützt. #1269 kodiert MMA-Ereignistypen aus der Semantik des mcfg-Registers statt aus der Speicherbreite — E5M2, E4M3 und INT8 sind je ein Byte, und das alte Schema ließ falsche Vergleiche durch. #1008 setzt INT32-Sättigung sowohl im CPU- als auch im CUDA-Backend tatsächlich um; das sat-Flag reicht bis in den Device-Kernel. #1009 erlaubt MMA_ASYNC=0 für synchrone Verifikation (CONFIG_DIFFTEST_MMA_SYNC); nach einem Fehlschlag wird das nächste Ereignis nicht mehr konsumiert, sodass der Fehler-PC stimmt.

Standardgeometrie: TLEN=65536 Bit pro Tile-Register, TRLEN=512 Bit pro Zeile → ROWNUM=128; MELEN=32 → 64 KiB Akkumulator; 8 mcfg-Register und 16 msync-Token. NVFP4/MXFP4 stehen in der Typtabelle, aber mmacc löst dafür eine Illegal-Instruction-Exception aus: kodiert, aber nicht ausführbar.

خلاصه (FA)

در بازهٔ ۲۴ تا ۲۷ اکتبر ۲۰۲۶ تیم شیانگ‌شان ۱۷ کامیت در OpenXiangShan/NEMU (۷) و OpenXiangShan/difftest (۱۰) ادغام کرد و پشتیبانی از افزونهٔ ماتریسی RISC-V را از «معناشناسی دستور پیاده‌سازی شده» به «معناشناسی عددی قابل‌راستی‌آزمایی» رساند.

چهار تغییر کلیدی: #1266 ضرب‌جمع ماتریسی FP8 با انباشت FP32 را اضافه می‌کند (E4M3×E4M3→FP32 و E5M2×E5M2→FP32) و این کار را با یکسان‌سازی مسیر برداری‌شدهٔ اعشاری انجام می‌دهد؛ فایل mcompute_impl.c ۴۹ خط کوچک‌تر می‌شود (+۱۰۴/−۱۵۳). جفت‌های ترکیبی FP8 پشتیبانی نمی‌شوند. #1269 نوع رویداد MMA را از معناشناسی ثبت mcfg رمزگذاری می‌کند نه از عرض ذخیره‌سازی — E5M2 و E4M3 و INT8 هر سه یک بایتی‌اند و طرح قبلی مقایسه‌های نادرست را رد نمی‌کرد. #1008 اشباع INT32 را در هر دو بک‌اند CPU و CUDA واقعاً پیاده می‌کند و پرچم sat تا هستهٔ دستگاه منتقل می‌شود. #1009 با MMA_ASYNC=0 راستی‌آزمایی همگام (CONFIG_DIFFTEST_MMA_SYNC) را فعال می‌کند؛ پس از خطا رویداد بعدی مصرف نمی‌شود، بنابراین PC خطا درست گزارش می‌شود.

هندسهٔ پیش‌فرض: TLEN=65536 بیت برای هر ثبات کاشی و TRLEN=512 بیت برای هر سطر → ROWNUM=128؛ MELEN=32 → انباشتگر ۶۴ کیلوبایت؛ ۸ ثبات mcfg و ۱۶ توکن msync. NVFP4 و MXFP4 در جدول نوع وجود دارند، اما mmacc برای آن‌ها استثنای دستور نامعتبر تولید می‌کند: رمزگذاری‌شده ولی اجرانشده.

Sources / 参考来源

← Back to Tech Blog