Skip to content

Fix OPENBLAS_CORETYPE lookup of SapphireRapids and the MIPS64 core names - #6075

Merged
martin-frbg merged 2 commits into
OpenMathLib:developfrom
Arthur031221:fix-coretype-names
Oct 1, 2026
Merged

martin-frbg merged 2 commits into
OpenMathLib:developfrom
Arthur031221:fix-coretype-names

Conversation

@Arthur031221

Copy link
Copy Markdown
Contributor

force_coretype() in driver/others/dynamic.c only searches corename[1..25], so OPENBLAS_CORETYPE=SapphireRapids (corename[26]) is rejected in x86_64 DYNAMIC_ARCH builds. The bound is a literal that five earlier commits raised by hand, most recently da6e426 ("fix Cooperlake not selectable via environment variable"). SapphireRapids was added in 0b83088 without raising it and without a case 26. This derives the bound from the size of corename[] (the other dynamic_*.c files loop to NUM_CORETYPES rather than a literal) and adds the case.

make DYNAMIC_ARCH=1 on develop (3ea5c8c), Ryzen 5 7500F, with a program that prints openblas_get_corename():

$ OPENBLAS_CORETYPE=SapphireRapids OPENBLAS_VERBOSE=2 ./corename
Core not found: SapphireRapids
Core: Cooperlake
corename: Cooperlake

With this change it prints Core: SapphireRapids.

This matters most on CPUs that get_coretype() does not recognise. Its Intel family 6 switch has no case for extended model 12 (Emerald Rapids, 0xCF), and extended model 10 only handles models 5, 6 and 7 (Granite Rapids is 0xAD), so both get NULL and then Cooperlake from the feature checks when AVX512-BF16 is available. Setting OPENBLAS_CORETYPE=SapphireRapids is the way to get the SapphireRapids tables there. I found this by reading the code. I have no such machine, so I did not touch the detection itself.

driver/others/dynamic_mips64.c is missing a comma after "MIPS64_GENERIC", so corename[] has three entries instead of four. Compiling that table and its two functions on x86_64 with stub tables shows gotoblas_corename() returning "MIPS64_GENERICloongson3r3", "loongson3r4" and "UNKNOWN" for the three cores, and OPENBLAS_CORETYPE=loongson3r4 selecting LOONGSON3R3. With the comma each name maps to its own table. Not run on MIPS hardware.

utest/test_coretype.c (Linux x86_64 DYNAMIC_ARCH only) runs openblas_utest once per core listed for x86_64 DYNAMIC_ARCH in README.md, with OPENBLAS_CORETYPE set. It fails if the child fails, if the name is not found, or, in builds with every core (no DYNAMIC_LIST or NO_AVX*), if another core is selected. Names the host cannot run are skipped: the SkylakeX, Cooperlake and SapphireRapids init code here contains BMI1 andn, and forcing SkylakeX under qemu -cpu SandyBridge dies with SIGILL. So the SapphireRapids check runs on AVX-512 hosts. On develop the test fails for SapphireRapids, and also if only the loop bound is fixed. With the fix it passes in make and CMake DYNAMIC_ARCH builds and with DYNAMIC_LIST="HASWELL SKYLAKEX", and under qemu Nehalem and SandyBridge the remaining names run without error.

The CMake entry has its own CMAKE_SYSTEM_NAME STREQUAL "Linux" block because OS_LINUX is only a #define there, so the existing if (OS_CYGWIN_NT OR OS_LINUX) block (with the fork tests) is not built by CMake. I left that block alone.

force_coretype() in driver/others/dynamic.c only searches corename[1..25],
so OPENBLAS_CORETYPE=SapphireRapids (corename[26]) is rejected in x86_64
DYNAMIC_ARCH builds and silently falls back to Cooperlake. The loop bound
is a literal that five earlier commits raised by hand, most recently
da6e426; SapphireRapids was added in 0b83088 without raising it or
adding a case. This derives the bound from sizeof(corename), matching the
other dynamic_*.c files, and adds the missing case.

driver/others/dynamic_mips64.c is missing a comma after "MIPS64_GENERIC",
so corename[] has three entries instead of four: the reported names are
shifted, and OPENBLAS_CORETYPE=loongson3r4 silently selects LOONGSON3R3.

utest/test_coretype.c runs openblas_utest once per x86_64 DYNAMIC_ARCH
core name listed in README.md, with OPENBLAS_CORETYPE set, and skips
names the host CPU cannot run. It fails on develop for SapphireRapids and
passes with this fix.
@martin-frbg

Copy link
Copy Markdown
Collaborator

Oops. Thanks for the fixes.
Regarding the CI failure on manylinux - I'm not entirely sure if we need the utest, but if we do, the checks pertaining to AVX512 hosts need to be guarded in case the compiler is too old to support AVX512 or BMI (not sure why you're testing the latter anyway ?). Also, __builtin_cpu_supports is likely not supported by all compilers out there.
The "Jenkins" failure is clearly unrelated - it's a transient fault in the docker setup for IBM zarch at OSUOSL

__builtin_cpu_supports is not available with every compiler. Read the
feature bits with cpuid and xgetbv instead, as driver/others/dynamic.c
does.

BMI1 is now required only for SkylakeX, Cooperlake and SapphireRapids.
In a gcc 13 build, those are the only setparam objects that contain
BMI1 instructions (andn), 9 each.
@Arthur031221

Copy link
Copy Markdown
Contributor Author

Thanks. The manylinux failure is what you describe: that image's gcc rejects the arguments, "Parameter to builtin not valid: avx512f" and the same for "bmi", at test_coretype.c:55 and :57.

I pushed a commit that drops __builtin_cpu_supports and __builtin_cpu_init from the test. It reads the feature bits with cpuid and xgetbv, as driver/others/dynamic.c does, so it no longer depends on what the compiler's builtin accepts.

On BMI: the test forces each core by name, and forcing a core runs its setparam object, which is compiled for that core. I disassembled them in a gcc 13 DYNAMIC_ARCH build: setparam_SKYLAKEX, setparam_COOPERLAKE and setparam_SAPPHIRERAPIDS each contain 9 andn instructions (BMI1), while setparam_HASWELL, setparam_ZEN and setparam_SANDYBRIDGE contain none. So BMI1 is now checked for the three AVX512 cores only; the AVX2 and AVX checks for the others are kept as they were.

Results: in a manylinux1 image (gcc 4.8.2), the previous test file fails with the same three errors as in the CI log, and this one compiles; the CI command sequence (make, make -C test, -C ctest, -C utest with BINARY=64 DYNAMIC_ARCH=1 TARGET=NEHALEM NUM_THREADS=32) exits 0 with utest 130/130 including coretype:force_by_name and utest_ext 1539/1539. On a Zen 4 host, make DYNAMIC_ARCH=1 gives the same 130/130 and 1539/1539.

If you would rather not carry the utest at all, I can drop test_coretype.c from the PR and keep only the dynamic.c and dynamic_mips64.c changes.

@martin-frbg martin-frbg added this to the 0.3.35 milestone Oct 1, 2026
@martin-frbg
martin-frbg merged commit 7e68768 into OpenMathLib:develop Oct 1, 2026
106 checks passed
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