Summary
Flash SDPA returns an all-zero output instead of attention on any build
configured --no-aocldlp, on any CPU. Three separate defects stack up; the first
is the primary one and the other two are only reachable once it is fixed.
1. The GEMM backend is hardcoded and the status discarded.
zendnn_gemm() in lowoha_sdpa_flash_cpu.cpp pins
params.lowoha_algo = matmul_algo_t::aocl_dlp and is declared void, so
matmul_direct()'s status_t is dropped. Without AOCL-DLP the call is rejected
before dispatch and computes nothing; the kernel proceeds and emits its
zero-initialised accumulator. Both GEMMs are affected — QK^T and PV.
Call path, from gdb:
#0 matmul::matmul_direct(...)
#1 sdpa::zendnn_gemm<float>(...)
#2 sdpa::cpu_flash_attention_sa<simd::avx2_tag, float, ...>(...)
#3 sdpa::sdpa_flash_run_avx2_internal(...)
Not ISA-related. Identical failure on two opposite microarchitectures:
| Host |
ISA |
requires AOCL-DLP errors |
suite |
| AMD PRO A10-8770E |
Excavator, no AVX-512 |
62,772 |
fails |
| Intel Xeon 6767P |
avx512f + bf16 + vnni |
62,402 |
fails |
2. LIBXSMM's implemented BF16→FP32 path is gated off.
matmul_partitioner.cpp rejected every dtype combination whose destination was
not BF16, but run_libxsmm_std() implements BF16 in / FP32 out — the bf16->f32
branch instantiates libxsmm_gemm<libxsmm_bfloat16, libxsmm_bfloat16, float>.
Flash SDPA asks for exactly that (BF16 Q/K/V accumulated in FP32), so the gate
made a working kernel unreachable. Measured at m=32 k=96 n=91: bf16→bf16 computes
at 18.05 GFLOPS, bf16→f32 failed on every backend, 18.31 GFLOPS after the fix.
3. LIBXSMM strided operands are sent to DLP.
select_partition_kernel() rejects any strided layout ("LibXSMM partitioned
kernel does not support strided layouts") though the unpartitioned path passes
lda/ldb/ldc straight to libxsmm_gemm like any BLAS GEMM. Flash SDPA tiles a
[batch, heads, seq, head_dim] tensor, so its operands are always strided
slices — 384 such declines in a single BF16 test.
Cumulative effect (A10-8770E, --no-aocldlp, SDPA suite)
| state |
passing |
"no backend" errors |
| unfixed |
0 (all-zero output) |
— |
| + fix 1 |
146 |
11,250 |
| + fix 2 |
220 |
7,530 |
| + fix 3 |
251, exit 0 |
0 |
Common pattern
All three are a dispatch gate written more narrowly than the kernel behind it,
with AOCL-DLP as the catch-all that hid the narrowness from anyone who had it.
Suggested fixes / reference branches
Summary
Flash SDPA returns an all-zero output instead of attention on any build
configured
--no-aocldlp, on any CPU. Three separate defects stack up; the firstis the primary one and the other two are only reachable once it is fixed.
1. The GEMM backend is hardcoded and the status discarded.
zendnn_gemm()inlowoha_sdpa_flash_cpu.cpppinsparams.lowoha_algo = matmul_algo_t::aocl_dlpand is declaredvoid, somatmul_direct()'sstatus_tis dropped. Without AOCL-DLP the call is rejectedbefore dispatch and computes nothing; the kernel proceeds and emits its
zero-initialised accumulator. Both GEMMs are affected — QK^T and PV.
Call path, from gdb:
Not ISA-related. Identical failure on two opposite microarchitectures:
requires AOCL-DLPerrors2. LIBXSMM's implemented BF16→FP32 path is gated off.
matmul_partitioner.cpprejected every dtype combination whose destination wasnot BF16, but
run_libxsmm_std()implements BF16 in / FP32 out — the bf16->f32branch instantiates
libxsmm_gemm<libxsmm_bfloat16, libxsmm_bfloat16, float>.Flash SDPA asks for exactly that (BF16 Q/K/V accumulated in FP32), so the gate
made a working kernel unreachable. Measured at m=32 k=96 n=91: bf16→bf16 computes
at 18.05 GFLOPS, bf16→f32 failed on every backend, 18.31 GFLOPS after the fix.
3. LIBXSMM strided operands are sent to DLP.
select_partition_kernel()rejects any strided layout ("LibXSMM partitionedkernel does not support strided layouts") though the unpartitioned path passes
lda/ldb/ldcstraight tolibxsmm_gemmlike any BLAS GEMM. Flash SDPA tiles a[batch, heads, seq, head_dim]tensor, so its operands are always stridedslices — 384 such declines in a single BF16 test.
Cumulative effect (A10-8770E,
--no-aocldlp, SDPA suite)Common pattern
All three are a dispatch gate written more narrowly than the kernel behind it,
with AOCL-DLP as the catch-all that hid the narrowness from anyone who had it.
Suggested fixes / reference branches
an error if none do (AOCL-DLP first, so builds that have it are unchanged):
https://github.com/lwandrebeck/BullDNN/tree/upstream/sdpa-zero-output-no-avx512
run_libxsmm_std()handles:https://github.com/lwandrebeck/BullDNN/tree/upstream/libxsmm-bf16-f32-gate
https://github.com/lwandrebeck/BullDNN/tree/upstream/libxsmm-strided-partitioner