Skip to content

riscv: add bf16 gemm with optional zvfbfwma - #7112

Draft
nihui wants to merge 37 commits into
Tencent:masterfrom
nihui:riscv-bf16-gemm
Draft

nihui wants to merge 37 commits into
Tencent:masterfrom
nihui:riscv-bf16-gemm

Conversation

@nihui

@nihui nihui commented Oct 14, 2026 •

Copy link
Copy Markdown
Member

Depends on #7111.

Add BF16 Gemm on top of #7111's compiler/runtime detection, shared conversions and storage-packing support.

  • Reuse the existing 16-bit tile layout, FP32 accumulation and split-K scratch.
  • Support constant/dynamic inputs, transposes, C broadcasting, packed FP32 C and BF16 or FP32 output.
  • Add ordinary RVV/scalar kernels and a separately compiled Zvfbfwma kernel with Gemm-specific runtime dispatch. WMA remains independent of the Zvfbfmin build option.
  • Reuse the shared conversion helpers. XThead packing/compute/output boundaries establish BF16/RNE per worker and restore saved FXCR modes while retaining existing and accrued low-six exception flags. Keep the constant-packer noinline workaround; no XThead WMA kernel is added.
  • Keep output/layout regressions portable through actual layer and packing capabilities. Dynamic FP32 C cases run on backends implementing that mixed-input path; BF16 halfway expectations allow the native RNE and ncnn rounding results.

Both PRs remain drafts targeting Tencent/ncnn:master. This branch includes #7111 and has 21 changed files cumulatively. Review the five-file Gemm-only change. Foundation source: d3cba9fbb0cb38de5af40fe64a305bdf53779639; combined source: d4c13ad79d336942a7b0ea000fe8a5dac98fa692. After the foundation lands, the branch may need synchronization to leave only the Gemm diff.

Validation

  • Historical validation at dce13c11bfd59dd029bae5499275736c621213c4 passed 437 Gemm numerical processes across ordinary RVV, scalar, native-min-only, WMA, min-option-off, fixed and unmodified/corrected vendor XThead configurations. Additional dispatch traces, worker-state/FP16 checks and ISA-isolation audits passed. Affected objects were rebuilt with unchanged support objects reused.
  • The four Gemm production files retain the implementation validated there; the shared helper has only gained its precondition comment. Later portable-test and Net changes were validated separately. These historical results are not fresh execution of the current test sources.
  • Previous-head CI (6f9ac3e9335a7145fb1137f5961f9ac97943e479) passed all 14 audited RISC-V jobs, including linux-riscv64. Cast/Clip/Net/CPU passed throughout the audited non-RISC-V CPU runs. The x64 ASAN job retains the previously observed SDPA/ShuffleChannel failure signatures; T4 jobs encountered Vulkan device-initialization failures.
  • The latest source change is the shared helper comment only. Twelve before/after comparisons across both branches and three ISA paths at O2/Ofast produced identical preprocessed tokens and object bytes; two formatting passes were stable. New-head CI is pending; no all-CI pass is claimed.

XThead BF16 capability and OS FXCR preservation remain experimental assumptions. Unmodified vendor QEMU execution is covered, but FE/DQNaN are not dynamically modeled and no hardware, context-switch or performance result is claimed. See #7111 for the shared conversion and platform boundaries.

nihui added 7 commits October 14, 2026 16:33
Vectorize BF16 conversion with the existing scalar rounding and bit
semantics. Keep the original RNE helper unchanged. Resolve 16-bit input
storage before choosing the destination packing to support mixed
BF16 and FP32 layers.

Add focused conversion boundary and mixed-storage layout regressions.
Reuse the existing 16-bit tile layout for BF16 storage and FP32
accumulation. Provide ordinary RVV widening and FP32 FMA kernels plus
a separately compiled Zvfbfwma kernel, with dispatch outside K loops.
Keep split-K accumulators in FP32 and preserve FP32 output requests.
Support constant and dynamic operands, C broadcasting and packed C.

Add compiler checks, ruapu CPU wrappers and fixed-ISA build support
without a Zfh or Zvfh requirement. Keep narrowing conversions in the
software path to preserve ncnn rounding and NaN bit semantics.

Validate 19 Gemm tests plus CPU/Cast/Packing/Net for VLEN 128/256/512
with native BF16 disabled and enabled in QEMU. Add small output-contract
and packed FP32 C regressions. Hardware performance remains unmeasured.
Add scalar and RVV BF16 storage paths using FP32 clamp arithmetic and
existing roundaway conversion helpers. Gate FP16 dispatch on runtime
support so BF16 remains usable without Zfh/Zvfh.

Add exact BF16 midpoint, packing, tail and channel-stride tests that
require storage support rather than silently skipping the new path.
Keep Zvfbfwma opt-in for fixed CPU builds while preserving its default
runtime dispatch. Reuse the existing XThead noinline workaround for
the four FP32-to-BF16 constant packers.
Keep compiler/runtime detection and dispatch infrastructure, BF16 Cast
and Clip, shared conversion helpers and storage-before-packing support
in the foundation change. Move the Gemm implementation and regression
tests to a dependent pull request without rewriting the tested history.
Build on the BF16 foundation with ordinary RVV and scalar kernels,
FP32 accumulation and split-K scratch, constant/dynamic operands,
transposes, broadcasting, packed FP32 C and BF16 or FP32 output.
Add the separately compiled native Zvfbfwma kernel and dispatch.
Preserve the existing XThead noinline workaround for constant packers.

This five-file change restores the exact combined source tree already
tested at e7864d1.
@tencent-adm

Copy link
Copy Markdown
Member

CLA assistant check
Thank you for your submission, we really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@codecov-commenter

codecov-commenter commented Oct 14, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.50173% with 36 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.02%. Comparing base (fcde729) to head (d4c13ad).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
src/layer/riscv/gemm_bf16s.h 97.72% 20 Missing ⚠️
src/cpu.cpp 27.27% 8 Missing ⚠️
src/layer/riscv/gemm_riscv.cpp 98.87% 5 Missing ⚠️
src/layer/riscv/cast_bf16.h 96.00% 2 Missing ⚠️
src/net.cpp 95.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #7112      +/-   ##
==========================================
- Coverage   95.29%   95.02%   -0.28%     
==========================================
  Files        1477     1461      -16     
  Lines      504532   496943    -7589     
==========================================
- Hits       480804   472216    -8588     
- Misses      23728    24727     +999     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

nihui and others added 6 commits October 15, 2026 07:36
Probe Zvfbfmin independently and compile native Cast and Clip conversion
sources without a Zvfbfwma, Zfbfmin, Zfh or Zvfh requirement. Dispatch
from ordinary RVV only, preserve XThead and scalar fallbacks, and keep
fixed-target native ISA opt-in.

Use explicit ISA round-to-even conversion and canonical NaNs. Exercise
native and fallback bit contracts, floating-point rounding-mode
preservation, and vector Clip Inf/NaN behavior in existing tests.
Synchronize the dependent foundation from PR Tencent#7111 while preserving
the five-file Gemm-only delta and existing branch history.
Follow the x86 layout with shared BF16 kernel headers and thin native
translation-unit wrappers. Keep scalar, ordinary RVV and Zvfbfmin
selection in the headers without changing conversion semantics.
Respect the min option even when fixed WMA enables its compiler macro.
Keep the dependent Gemm branch synchronized with PR Tencent#7111 while
preserving its five-file Gemm-only delta and automatic format commits.
@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Binary size comparison

The binary size change of libncnn.so (bytes)

architecture base size pr size difference
x86_64 27751048 27751176 +128 ⚠️
armhf 7710292 7710528 +236 ⚠️
aarch64 11849384 11849824 +440 ⚠️

Commit: d4c13ad79d336942a7b0ea000fe8a5dac98fa692 · Workflow run

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants