Skip to content

Flash SDPA silently returns zeros on any --no-aocldlp build (hardcoded GEMM backend + two LIBXSMM gates) #31

Description

@lwandrebeck

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions