Skip to the content.

BLAS (OpenBLAS)

Improvements to OpenBLAS 0.3.30 on RISC-V boards — built via EasyBuild, deployed through EESSI with FlexiBLAS runtime swapping.

Verification microbenchmarks live in opensolvers/benchmarks/OpenBLAS (bench_dgemm, difftest, verify_ctrsm). Alternative BLAS: BLIS RVV vs OpenBLAS DGEMM A/B on X60. Stack probes: NumPy (bench_blas.py). Full repo: opensolvers/benchmarks.

Base stack: GCC 14.3.0, OpenBLAS 0.3.30, EESSI 2025.06-001 (dev.eessi.io/riscv).

OpenBLAS 0.3.34 — end-to-end verify (Orange Pi RV2, 2026-08-25)

EESSI 2025.06-001 still ships 0.3.29 / 0.3.30 only. We built upstream tag v0.3.34 locally with EESSI GCC 14.3.0 (TARGET=RISCV64_ZVL256B; Ubuntu GCC 13 cannot compile ZVL256 SGEMM tuple intrinsics). Harness: run-034-tests.sh in opensolvers/benchmarks/OpenBLAS.

Correctness (difftest, 1 thread)

Backend dgemv NaN dgemm NaN dtrsm NaN dgemv sum
0.3.34 ZVL256B 0 0 0 42.06549
Stock EESSI 0.3.30 768 0 0 0 (broken)
Stock EESSI 0.3.29 0 0 0 42.06549
Patched 0.3.30 (#26444) 0 0 0 42.06549

SYRK PSD (OpenBLAS#5811 repro, N=K=50): max_err=0, min_diag=+12.56, PASS (fixes the 0.3.33 ZVL256 regression).

CTRSM sweep (verify_ctrsm): 2400 cases, 0 fails — new ZVL TRSM RVV kernels in 0.3.34 (OpenBLAS#5895).

Performance — bench_dgemm (N=2048, 8 threads)

Backend GFLOP/s C[0]
0.3.34 15.54 245.24
Stock EESSI 0.3.30 9.81 245.24

~1.6× over stock 0.3.30, bit-identical output. Verdict: 0.3.34 has a working RVV path on X60 — ready for an EESSI package bump when upstream lands in the stack.

HPL end-to-end (same xhpl, FlexiBLAS → 0.3.34)

Config OpenBLAS 0.3.34 Patched 0.3.30 0.3.34 vs patched
HPL.dat (N=8000, 1×8) 11.04 GFLOP/s, PASSED 7.72 GFLOP/s, PASSED 1.43×
HPL-sweep.dat (N=20000, 2×4) 10.97 GFLOP/s, PASSED 10.27 GFLOP/s, PASSED 1.07×

Residuals ~3–4e-03. See HPL and run-hpl-034.sh.

Improvements

Board / CPU Problem (stock 0.3.30) Fix Result
VisionFive 2 — SiFive U74 (scalar) No U74 kernel; falls back to generic RISCV64_GENERIC C 2×2 GEMM New 4×4 DGEMM micro-kernel in RV64 assembly, TARGET=U74 Single-core DGEMM ~1.4 → 1.77 GFLOP/s; 4-core DGEMM 6.31 GFLOP/s; HPL 1.69×
Orange Pi RV2 — SpacemiT X60 (RVV VLEN=256) RVV gemv_n zeroes an uninitialized vector register → dgemv returns NaN Backport upstream gemv_n fix; TARGET=RISCV64_ZVL256B Verification 2.3×; NumPy DGEMM 2.4×; HPL 10.53 GFLOP/s
Banana Pi F3 — same K1 / X60 SoC Same RVV gemv_n bug as RV2 Same easyconfigs#26444 fix Verification 2.35×; NumPy DGEMM 3.6×; HPL 11.52 GFLOP/s

Packages

Target EasyBuild PR Upstream OpenBLAS Walkthrough
SiFive U74 easyconfigs#26436 OpenBLAS#5903 EESSI/docs#818
SpacemiT X60 easyconfigs#26444 OpenBLAS#5408, #5476 EESSI blog · YouTube

Build with eb --from-pr <num> --robot into an EESSI-extend user install, then flexiblas add / flexiblas default — no downstream rebuild.

Verification

Small, self-contained programs in opensolvers/benchmarks/OpenBLAS for BLAS performance and per-routine correctness — used to isolate broken RVV kernels before trusting downstream apps.

File Purpose
bench_dgemm.c Times square C = A×B (3 reps), reports GFLOP/s, prints C[0]
difftest.c dlopens a BLAS .so, runs level-1/2/3 routines, reports sum / NaN counts
verify_ctrsm.c Full-parameter TRSM correctness sweep (localizes OpenBLAS#5928 VLEN bug in _rvv_v1 kernels)
run-034-tests.sh Build + verify OpenBLAS 0.3.34 on RV2 (difftest, SYRK PSD, CTRSM, DGEMM A/B)

Both switch backends at runtime via FlexiBLAS or OPENBLAS_CORETYPE — no recompile.

gcc -O2 bench_dgemm.c -o bench_dgemm -lflexiblas
gcc -O2 difftest.c    -o difftest    -ldl -lm

OPENBLAS_NUM_THREADS=8 ./bench_dgemm 4096
./difftest /path/to/libopenblas.so

Correctness — difftest (X60, RV2 & F3)

Bit-identical on Orange Pi RV2 and Banana Pi F3:

Backend dgemv NaN dgemm NaN dtrsm NaN dgemv sum
Stock EESSI, default RVV 192 0 0 198.94 (wrong)
Forced scalar 0 0 0 42.06549 (reference)
Patched RVV (gemv_n fix) 0 0 0 42.06549 (matches)

Fault is in dgemv only — plain dgemm and dtrsm look fine on the broken gemv_n build, which is why HPL, Quantum ESPRESSO, and PETSc dense/direct paths can fail while a GEMM micro-benchmark passes.

A second bug — RVV _rvv_v1 TRSM kernels not VLEN-agnostic (OpenBLAS#5928) — is caught by verify_ctrsm on ZVL128B builds where GEMM_UNROLL_M ≠ VSETVL_MAX.

Performance — bench_dgemm

Orange Pi RV2 (1 core, N=2048)

Backend GFLOP/s C[0]
Scalar 1.16 245.24
Patched RVV 2.62 245.24

2.3× faster, numerically identical.

Banana Pi F3 (cross-board)

Backend GFLOP/s C[0]
Scalar 1.26 245.24
Patched RVV 2.96 245.24

2.35× at 1 core. Threaded (8 cores, N=4096): 17.71 GFLOP/s on patched RVV.

Notes