Hacktoberfest 2026: die Issues, die Maintainer für den Oktober markiert haben – offen und einsteigerfreundlich. Hacktoberfest-Issues durchsuchen

SVE small SGEMM/DGEMM writes output padding at VL384 (QEMU)

Offen
#6,103 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Maintainer antworten meist innerhalb von 1 Tag

Dieses Issue hat noch niemand übernommen.

Bewertung

Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Anfängerfreundlichkeit
58/100
Issue-Typ
Bug
Klarheit
Klar beschrieben
Aktivitätsstatus
Aktiv
Tech-Stack
c
Bereich
performance

Rechercherichtung

Start with the two named files, kernel/arm64/sgemm_small_kernel_nn_sve.c near lines 250–251 and kernel/arm64/dgemm_small_kernel_nn_sve.c near lines 222–223, and inspect how their row-count bounds behave at VL384. Build OpenBLAS with the supplied AArch64/QEMU setup and run the repro.c SGEMM and DGEMM cases. Done means both calls produce nine zeros while preserving every allocated padding value of 17; verify other vector lengths remain unaffected.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

SVE small SGEMM/DGEMM writes output padding at VL384 (QEMU)

On OpenBLAS develop 277ef7801416412ee970873701fdf14d603d2c3f and release
v0.3.34, a public row-major 1-by-9 SGEMM or DGEMM with K=0 and beta=0
writes into padding beyond the nine output elements at SVE VL384 with
forced ARMV8SVE dispatch under QEMU. The one-call reproducer below
initializes the nine outputs to NaN and all remaining allocated elements
to 17. Correct output is nine zeros with every other element still 17.
The first padding element instead becomes zero.

QEMU 8.2.2 and 10.2.1 agree with ARMV8SVE, A64FX and NEOVERSEV1
dispatch. ARMV8 and NEOVERSEV2 preserve padding at VL384; the affected
tables pass these vectors at VL128, 256, 512, 1024 and 2048. Original
Reference BLAS v3.12.1 SGEMM/DGEMM, with equivalent column-major
dimensions, preserves the padding on both emulators at all six lengths.
All accesses demonstrated by this reproducer remain within its allocated
128-element arrays; the incorrect writes are outside the logical output.

Suspected cause

Row-major dimensions 1-by-9 become internal M=9, N=1. K=0 bypasses
GEMM-to-GEMV forwarding, while the small-matrix permit accepts the call.
Beta=0 selects sgemm_small_kernel_b0_nn or dgemm_small_kernel_b0_nn,
so this does not depend on the regular GEMM packers.

kernel/arm64/sgemm_small_kernel_nn_sve.c
near lines 250-251 and
kernel/arm64/dgemm_small_kernel_nn_sve.c
near lines 222-223 compute row counts as M & -(2*v_size) and
M & -v_size. At VL384, the respective lane counts are 12 and 6;
these masks do not compute floor-to-multiple counts. For example,
the float two-vector bound is 9 & -24 = 8, which enters a full
24-row store even though there are only nine output rows. The double
one-vector bound is 9 & -6 = 8, which permits two six-row stores.
Both explain the change to the first padding element without reading A
or B. Arithmetic count calculation is a candidate direction; no source
fix has been tested here.

Hardware scope

The names above select OpenBLAS dispatch tables on QEMU's max CPU.
Documented maximum SVE lengths for the named processors are 128 bits for
Neoverse N2/V2, 256 bits for Neoverse V1, and 512 bits for A64FX
(Arm, NVIDIA).
SVE permits non-power-of-two multiples of 128 bits;
VL384 is an architectural conformance case supported by QEMU. These forced
table/VL combinations do not establish a failure on the named native
processors. Native confirmation is unavailable.

Reproduce

On Linux, use Git, GNU Make, host GCC, an AArch64 GCC cross toolchain
with its glibc sysroot, and QEMU user mode. GCC 15.2 was used for the
reported builds. Save the C block below as repro.c in a clean
working directory, then run these commands from that directory:

git init openblas-src
git -C openblas-src fetch --depth=1 https://github.com/OpenMathLib/OpenBLAS.git 277ef7801416412ee970873701fdf14d603d2c3f
git -C openblas-src checkout --detach FETCH_HEAD
cd openblas-src
make -j4 ARCH=arm64 BINARY=64 TARGET=ARMV8 DYNAMIC_ARCH=1 \
  'DYNAMIC_LIST=ARMV8SVE A64FX NEOVERSEV1 NEOVERSEN2' \
  NOFORTRAN=1 NO_LAPACK=1 USE_THREAD=0 NUM_THREADS=1 HOSTCC=gcc \
  CC=aarch64-linux-gnu-gcc AR=aarch64-linux-gnu-ar RANLIB=aarch64-linux-gnu-ranlib
make ARCH=arm64 BINARY=64 TARGET=ARMV8 DYNAMIC_ARCH=1 \
  'DYNAMIC_LIST=ARMV8SVE A64FX NEOVERSEV1 NEOVERSEN2' \
  NOFORTRAN=1 NO_LAPACK=1 USE_THREAD=0 NUM_THREADS=1 HOSTCC=gcc \
  CC=aarch64-linux-gnu-gcc AR=aarch64-linux-gnu-ar RANLIB=aarch64-linux-gnu-ranlib \
  PREFIX="$PWD/install" install
aarch64-linux-gnu-gcc -O2 -Wall -Wextra -Iinstall/include ../repro.c \
  install/lib/libopenblas.a -lm -lpthread -o small-repro
OPENBLAS_CORETYPE=ARMV8SVE OPENBLAS_NUM_THREADS=1 \
  qemu-aarch64 -L /usr/aarch64-linux-gnu \
  -cpu max,sve-default-vector-length=48 ./small-repro 384 s
OPENBLAS_CORETYPE=ARMV8SVE OPENBLAS_NUM_THREADS=1 \
  qemu-aarch64 -L /usr/aarch64-linux-gnu \
  -cpu max,sve-default-vector-length=48 ./small-repro 384 d

The QEMU property is in bytes: 48 requests VL384.
Replace qemu-aarch64 with QEMU 8.2.2's qemu-aarch64-static to
repeat with the second emulator.
The program checks the actual vector length with PR_SVE_GET_VL and
prints the selected OpenBLAS core; confirm that the printed core matches
the requested dispatch table. Exit 0 means the checked values are right,
1 means a numerical or padding mismatch, and 2 means a setup/argument
failure rather than a valid numerical result. Each mode makes one public
BLAS call.

repro.c
/* Public beta-only SGEMM/DGEMM: SVE small-kernel VL384 count witness. */
#include <cblas.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/prctl.h>
int main(int argc,char **argv) {
    int requested=argc>1?atoi(argv[1]):384;
    int vl=prctl(51,0,0,0,0);
    if(vl<0 || (vl&65535)*8!=requested)return 2;
    int isdouble=argc>2&&!strcmp(argv[2],"d");
    float af[128]={0},bf[128]={0},cf[128];
    double ad[128]={0},bd[128]={0},cd[128];
    for(int i=0;i<128;i++){cf[i]=cd[i]=i<9?NAN:17;}
    if(isdouble)cblas_dgemm(CblasRowMajor,CblasNoTrans,CblasNoTrans,1,9,0,1,ad,1,bd,9,0,cd,12);
    else cblas_sgemm(CblasRowMajor,CblasNoTrans,CblasNoTrans,1,9,0,1,af,1,bf,9,0,cf,12);
    int wrong=0;
    for(int i=0;i<128;i++)wrong+=(isdouble?cd[i]:cf[i])!=(i<9?0:17);
    printf("SMALL-VL: %s precision=%c core=%s VL=%d m=1 n=9 k=0 padding=%g want=17 wrong=%d first_surfaced_by=differential\n",
           wrong?"WRONG":"RIGHT",isdouble?'d':'s',openblas_get_corename(),requested,
           isdouble?cd[9]:cf[9],wrong);
    return wrong?1:0;
}

First surfaced by differential testing (first_surfaced_by: differential).

Vorherrschende Sprache
C
Sterne
7.6k
Forks
1.7k
Ø Merge
1 T. 11 Std.
Gemergte PRs (30 T.)
53

Entwicklungsumgebung

Dieses Projekt bietet weder Dev-Container noch Dockerfile noch Beitragsleitfaden – die Einrichtung liegt bei Ihnen. Beginnen Sie mit der README; die allgemeinen Schritte stehen in unserem Leitfaden für den ersten Beitrag.

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus OpenMathLib/OpenBLAS

Alle Issues in OpenMathLib/OpenBLAS

Ähnliche Issues

Weitere Issues zu C

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.