Skip to content

riscv64: 2 of 4: 16 RVV matmul kernels behind Zvfh - #2600

Open
czoli1976 wants to merge 4 commits into
sonos:mainfrom
czoli1976:riscv64-rvv-f16
Open

riscv64: 2 of 4: 16 RVV matmul kernels behind Zvfh#2600
czoli1976 wants to merge 4 commits into
sonos:mainfrom
czoli1976:riscv64-rvv-f16

Conversation

@czoli1976

Copy link
Copy Markdown
Contributor

Stacked on #2599. GitHub cannot base a pull request on a fork branch, so this
targets main and its diff carries that PR's commits too. The only new commit here
is d24d96d7 — everything else belongs to #2599 and is reviewed there.

Stacked on the f32 tier. Adds four f16 mmm kernels — 16x8 and 32x8 GEMM, 64x1
and 128x1 GEMV — from the same template at SEW=16, where VLMAX doubles and so
does every tile height for a given LMUL and VLEN.

No template change was needed: the f32 PR already parameterised element size,
so this is a kernel table, a probe, and a predicate.

Why this is not speculative

Zvfh is optional in RVA23, so it has to be detected rather than assumed — but
it is not hypothetical hardware. The SpacemiT X60 in the K1 reports zvfh and
zvfhmin in its /proc/cpuinfo isa string, which covers the Banana Pi BPI-F3,
Orange Pi RV2 and Milk-V Jupiter. llama.cpp's RISC-V build enables zvfh
alongside v for exactly this hardware.

The C920v2 in the SG2044 has scalar zfh only, so this is a VLEN=256-class
feature in practice, and the predicates fall back cleanly on parts without it.

Zvfhmin is not sufficient: it provides only f16<->f32 conversion and so cannot
carry an f16 accumulator, which is why the detection looks for Zvfh
specifically.

Testing

No CI change needed — the -cpu max models the f32 PR added already enable
Zvfh, so both existing riscv64 entries exercise this tier. Locally, tract-linalg
passes at VLEN 128 and 256 with Zvfh on and off, and dispatch_matches_vlen
covers the f16 predicates alongside the f32 ones.

Same caveat as the f32 PR: correctness under emulation, no hardware numbers.

🍍

ckristian added 4 commits August 7, 2026 09:26
tract had no RISC-V backend, so rv64gc ran the generic Rust kernels for every
matmul. Add an RVV 1.0 f32 mmm tier, detecting V from the AT_HWCAP bit that
Linux never sets for the incompatible 0.7.1 draft and VLEN from the vlenb CSR.
Because VLEN is a runtime property while MR must be a const generic, each
kernel fixes (MR, NR, LMUL) and pins vl to MR, which is correct wherever
VLMAX >= MR and short below it, so dispatch is gated on the hart's VLMAX
reaching MR and the kernel re-checks the granted vl before running. An
assembler probe keeps toolchains predating RVV 1.0 on the generic fallback.
hwbench's load_a_slice has hand-written versions for x86_64, aarch64 and arm
only, so tract-linalg fails to compile with the hwbench feature on any other
target -- which includes riscv64, and so blocks tract-cli entirely, since it
always enables that feature. Add a portable version reading one volatile word
per cache line, which moves the same traffic; with no wide loads there are
fewer misses in flight, so an out-of-order core may not saturate and the figure
reads low rather than wrong.
The RVV kernels are gated on the hart's vector length, so a single emulated
width would leave half the kernel set untested. Add riscv64gc to the qemu
cross-test platforms twice, at VLEN 256 and 128, which select disjoint halves.
-cpu max rather than a profile model because the generic rv64 model cannot run
Debian's riscv64 glibc at all.
The riscv64 tier covered f32 only, so f16 matmul fell back to the generic
kernels even on parts with native half-precision vectors, which includes the
SpacemiT X60 in the K1. Add an f16 mmm tier from the same template at SEW=16,
where VLMAX doubles and so does every tile height for a given LMUL and VLEN.
Zvfh is read from the /proc/cpuinfo isa line, since RVA23 mandates only
Zvfhmin and that cannot hold an f16 accumulator, and a second assembler probe
keeps toolchains predating Zvfh on the f32 tier alone.
@czoli1976 czoli1976 changed the title riscv64: f16 RVV matmul kernels behind Zvfh riscv64: 2 of 4: 16 RVV matmul kernels behind Zvfh Aug 7, 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