Summary
Since 0.3.34, SGEMM results under a pinned OPENBLAS_CORETYPE (SkylakeX, Haswell) differ between a Zen 4 host and an Intel host for some K, while they are byte-identical with the same pin on every release from 0.3.23 through 0.3.33 (bisected with the conda-forge builds).
The cause is the block added by #5868 at the end of init_parameter() in kernel/setparam-ref.c (v0.3.34 lines 2087–2115): when the host CPUID reports AuthenticAMD, l3_kb % 32768 == 0, l2_kb == 1024 and CPUID.7:EBX bit 16 (AVX512F), it sets sgemm_p=384, sgemm_q=512 (and the d/c/z equivalents). driver/others/dynamic.c reads OPENBLAS_CORETYPE (line 1145), applies force_coretype() (1148) and then calls gotoblas->init() (1180), so the override rewrites the blocking of the forced table on Zen 4/5 hosts only. GEMM_Q is the K-chunk of the reduction, so partial sums are accumulated in a different order than on any other host running the same pinned kernel, and the bits differ. openblas_get_corename() still reports the pinned core, so nothing indicates that the pin no longer means the same thing everywhere.
Reproduction
conda-forge libopenblas 0.3.34 (openmp build), NumPy A @ B in float32, M = N = 64, K varied, OPENBLAS_NUM_THREADS=1. Hosts: AMD EPYC 9V44 (Genoa, Zen 4: L2 1 MiB, L3 32 MiB, AVX-512) vs Intel Xeon Platinum 8573C (Emerald Rapids). Digests of the result matrix compared across the two hosts:
| pin |
identical K |
different K |
OPENBLAS_CORETYPE=SkylakeX (table Q = 448) |
256, 384, 448, 513, 640, 768, 895, 896 |
449, 480, 512, 1024, 1536 |
OPENBLAS_CORETYPE=Haswell (table Q = 320) |
256, 320, 513, 600, 639, 640 |
321, 400, 512, 768, 1024 |
This is exactly the pattern of the K-chunking rule in driver/level3/level3.c with Q = 512 on the Zen 4 host against the table's Q elsewhere: identical wherever both Q values produce the same chunk sequence (including K = 2Q, where the halving rule coincides), different elsewhere. Predicted from the source before measuring; every K landed as predicted.
Controls, all consistent with the mechanism:
OPENBLAS_L2_SIZE=2048 on the Zen 4 host (the block requires l2_kb == 1024) restores byte-identity with the Intel host at every K under both pins, with no rebuild. OPENBLAS_L2_SIZE=1024 changes nothing. OPENBLAS_L2_SIZE is inert on the Intel host.
- A Zen 3 host (EPYC 7V13 Milan: L2 512 KiB, no AVX-512) on 0.3.34 is byte-identical to Intel with no workaround, and remains so with
OPENBLAS_L2_SIZE=1024 forced (the AVX512F term fails there).
- Every release 0.3.23 … 0.3.33 with the same pins: byte-identical at all K on the same hosts.
Why it matters
OPENBLAS_CORETYPE is documented as a kernel-selection override, but it is the route that has been suggested here for identical results across Intel and AMD (#4510), and up to 0.3.33 it delivered them for GEMM. #6013 found the same block as a crash on Windows; the fix on develop (a59a5c7) only wraps it in #ifndef NO_AVX512, so normal AVX-512 builds of 0.3.35 will keep the host-dependent override under a forced coretype.
Suggestion
Any of: skip the Zen 4 P/Q override when a coretype was forced via OPENBLAS_CORETYPE (so a pin means the same blocking on every host); apply it inside the Zen table's init rather than after force_coretype; or document that OPENBLAS_L2_SIZE=2048 is needed for cross-host identity on Zen 4/5 under a pin. Happy to test a patch on the same hosts.
Summary
Since 0.3.34, SGEMM results under a pinned
OPENBLAS_CORETYPE(SkylakeX,Haswell) differ between a Zen 4 host and an Intel host for some K, while they are byte-identical with the same pin on every release from 0.3.23 through 0.3.33 (bisected with the conda-forge builds).The cause is the block added by #5868 at the end of
init_parameter()inkernel/setparam-ref.c(v0.3.34 lines 2087–2115): when the host CPUID reports AuthenticAMD,l3_kb % 32768 == 0,l2_kb == 1024and CPUID.7:EBX bit 16 (AVX512F), it setssgemm_p=384, sgemm_q=512(and the d/c/z equivalents).driver/others/dynamic.creadsOPENBLAS_CORETYPE(line 1145), appliesforce_coretype()(1148) and then callsgotoblas->init()(1180), so the override rewrites the blocking of the forced table on Zen 4/5 hosts only.GEMM_Qis the K-chunk of the reduction, so partial sums are accumulated in a different order than on any other host running the same pinned kernel, and the bits differ.openblas_get_corename()still reports the pinned core, so nothing indicates that the pin no longer means the same thing everywhere.Reproduction
conda-forge
libopenblas 0.3.34(openmp build), NumPyA @ Bin float32,M = N = 64, K varied,OPENBLAS_NUM_THREADS=1. Hosts: AMD EPYC 9V44 (Genoa, Zen 4: L2 1 MiB, L3 32 MiB, AVX-512) vs Intel Xeon Platinum 8573C (Emerald Rapids). Digests of the result matrix compared across the two hosts:OPENBLAS_CORETYPE=SkylakeX(table Q = 448)OPENBLAS_CORETYPE=Haswell(table Q = 320)This is exactly the pattern of the K-chunking rule in
driver/level3/level3.cwith Q = 512 on the Zen 4 host against the table's Q elsewhere: identical wherever both Q values produce the same chunk sequence (including K = 2Q, where the halving rule coincides), different elsewhere. Predicted from the source before measuring; every K landed as predicted.Controls, all consistent with the mechanism:
OPENBLAS_L2_SIZE=2048on the Zen 4 host (the block requiresl2_kb == 1024) restores byte-identity with the Intel host at every K under both pins, with no rebuild.OPENBLAS_L2_SIZE=1024changes nothing.OPENBLAS_L2_SIZEis inert on the Intel host.OPENBLAS_L2_SIZE=1024forced (the AVX512F term fails there).Why it matters
OPENBLAS_CORETYPEis documented as a kernel-selection override, but it is the route that has been suggested here for identical results across Intel and AMD (#4510), and up to 0.3.33 it delivered them for GEMM. #6013 found the same block as a crash on Windows; the fix ondevelop(a59a5c7) only wraps it in#ifndef NO_AVX512, so normal AVX-512 builds of 0.3.35 will keep the host-dependent override under a forced coretype.Suggestion
Any of: skip the Zen 4 P/Q override when a coretype was forced via
OPENBLAS_CORETYPE(so a pin means the same blocking on every host); apply it inside the Zen table's init rather than afterforce_coretype; or document thatOPENBLAS_L2_SIZE=2048is needed for cross-host identity on Zen 4/5 under a pin. Happy to test a patch on the same hosts.