Skip to content

kernel/riscv64: add an RVV CGEMM oncopy - #6053

Open
6eanut wants to merge 1 commit into
OpenMathLib:developfrom
6eanut:riscv64-cgemm-oncopy-rvv
Open

6eanut wants to merge 1 commit into
OpenMathLib:developfrom
6eanut:riscv64-cgemm-oncopy-rvv

Conversation

@6eanut

@6eanut 6eanut commented Sep 17, 2026

Copy link
Copy Markdown

The CGEMM N packing step was still using the generic C kernel/generic/zgemm_ncopy_8.c, whose address arithmetic is scalar: for every complex element of an 8-column panel it builds one base+offset address per store, which perf annotate shows as eight add/addi per iteration.

Add kernel/riscv64/zgemm_ncopy_8_rvv.c and point CGEMMONCOPY at it. Each of the eight source rows is loaded as one strided segment-2 (real / imaginary) load, both halves are merged with vget/vset, and the panel is written with two strided segment-8 stores whose byte stride is 16*sizeof(FLOAT). The eight per-store addresses collapse into a single stride. The n&4 / n&2 / n&1 tails keep the contiguous segment-8 / segment-4 / segment-2 layout, so the packed byte sequence is unchanged — it was checked against the generic packer over 27200 m x n cases with no mismatch.

The file follows the usual oncopy convention of being written for both precisions behind a single #if !defined(DOUBLE) switch, so it can also serve ZGEMM. Only the CGEMM side is wired up here, matching the C prefix the benchmark covers; the -DDOUBLE build was verified to compile and to match the generic packer, but ZGEMM still uses ../generic/zgemm_ncopy_$(ZGEMM_UNROLL_N).c.

Performance

Measured on a SpaceMiT X100 (2.2 GHz, single thread, ZVL256B), median of three runs: cblas_cgemm -0.5% at 256, +4.0% at 512, +1.1% at 1024.

Testing

make tests returns 0; 125/125 utest and 1473/1473 extension tests pass; the CBLAS L1/L2/L3 suites show no new failures.

The CGEMM N packing step was still using the generic C
kernel/generic/zgemm_ncopy_8.c, whose address arithmetic is scalar: for
every complex element of an 8-column panel it builds one base+offset
address per store, which perf annotate shows as eight add/addi per
iteration.

Add kernel/riscv64/zgemm_ncopy_8_rvv.c and point CGEMMONCOPY at it.  Each
of the eight source rows is loaded as one strided segment-2 (real /
imaginary) load, both halves are merged with vget/vset, and the panel is
written with two strided segment-8 stores whose byte stride is
16*sizeof(FLOAT).  The eight per-store addresses collapse into a single
stride.  The n&4 / n&2 / n&1 tails keep the contiguous segment-8 /
segment-4 / segment-2 layout, so the packed byte sequence is unchanged -
it was checked against the generic packer over 27200 m x n cases with no
mismatch.

The file follows the usual oncopy convention of being written for both
precisions behind a single #if !defined(DOUBLE) switch, so it can also
serve ZGEMM.  Only the CGEMM side is wired up here, matching the C prefix
the benchmark covers; the -DDOUBLE build was verified to compile and to
match the generic packer, but ZGEMM still uses
../generic/zgemm_ncopy_$(ZGEMM_UNROLL_N).c.

Measured on a SpaceMiT X100 (2.2 GHz, single thread, ZVL256B), median of
three runs: cblas_cgemm -0.5% at 256, +4.0% at 512, +1.1% at 1024.
Tests: make tests returns 0; 125/125 utest and 1473/1473 extension tests
pass; the CBLAS L1/L2/L3 suites show no new failures.

Co-authored-by: Yuansheng <yuansheng@isrc.iscas.ac.cn>
Co-authored-by: Ning Tian <tianning24@iscas.ac.cn>
Signed-off-by: jiakai xu <xujiakai2025@iscas.ac.cn>
@martin-frbg martin-frbg added this to the 0.3.35 milestone Sep 18, 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.

2 participants