Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

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

Abierto
#6,103 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
58/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
c
Área
performance

Línea de trabajo

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.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

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).

Lenguaje dominante
C
Estrellas
7.6k
Forks
1.7k
Merge medio
1 d 11 h
PR fusionados (30 d)
55

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de OpenMathLib/OpenBLAS

Todos los issues de OpenMathLib/OpenBLAS

Issues similares

Más issues de C

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.