Avatar for the OpenMathLib user
OpenMathLib
OpenBLAS
BlogDocsChangelog

Performance History

Latest Results

Pass CR and RC as -DCR=CR / -DRC=RC when building GEMMT objects with make A bare -DCR expands every CR token in the MinGW system headers to 1 and breaks the complex ?gemmt_?CR objects ("expected identifier or '(' before numeric constant"). The GEMM rules and cmake/utils.cmake already use the self-referencing form for exactly this reason. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jgillis:gemmt-level3
1 day ago
Fix compiler warnings
martin-frbg:f2c-lapack-c
1 day ago
Implement GEMMT with a blocked level-3 driver instead of a GEMV loop ?GEMMT / ?GEMMTR has been a loop over the columns of the triangle with one ?GEMV per column since it was added in 0.3.22. Besides being much slower than GEMM (issue #4921), every column above the GEMV multithreading threshold becomes its own thread dispatch, so the routine gains almost nothing from more cores. Add a real level-3 driver. No new microkernels are needed: the blocks that cross the diagonal are handled by the existing SYRK kernel, which already clips a block against the diagonal at register-block granularity. - driver/level3/level3_gemmt.c is derived from level3_syrk.c. The blocking, the diagonal handling and the loop structure are the same; the packed B buffer is filled from a second matrix, so the buffer sharing SYRK can do is not available, and op(A) / op(B) are selected by the NN/NT/.../CC defines that level3.c uses. - driver/level3/gemmt_k.c holds the triangular beta scaling and the choice of kernel, and is built once per uplo x op(A) x op(B) just as syrk_k.c is built per uplo x trans. - For complex, syrk_kernel.c is also built with CONJA / CONJB; the file already supported those defines but nothing instantiated them. interface/gemmt.c dispatches through a [uplo][op(B)][op(A)] table like interface/gemm.c, and above the existing SMP threshold splits the triangle into column ranges of equal area with syrk_thread(), so every thread writes a disjoint set of columns of C. Only the blocks that intersect the requested triangle are packed and computed, and only the triangle is scaled by beta. This also stops complex GEMMT from writing to the caller's B: conjugation used to be done by conjugating B in place and undoing it afterwards, which is unsafe for a shared or read-only B. dgemmt on an 8-core/16-thread i7-11800H, SKYLAKEX kernels, time for one call, with dsyrk on the same data for reference: n=1600 k=128, 1 thread: 18.7 ms -> 5.14 ms (dsyrk 5.12 ms) n=1600 k=128, 4 threads: 6.92 ms -> 1.54 ms (dsyrk 1.53 ms) n=1600 k=128, 16 threads: 11.7 ms -> 1.01 ms (dsyrk 1.01 ms) n=400 k=128, 16 threads: 1.31 ms -> 0.10 ms (dsyrk 0.11 ms) One deliberate deviation from level3_syrk.c: for a row band that lies entirely below the column block, level3_syrk.c bounds its column loop with `jjs < min_j`, which mixes an absolute index with a length and packs nothing when js > 0. The GEMMT driver uses `jjs < js + min_j`. Neither interface passes a row range, so the branch is only reachable by calling the driver directly; level3_syrk.c is left alone here. Add a utest case per precision at a size that is neither a multiple of the register blocking nor small enough to stay single-threaded, which is where the packing and the diagonal clipping have to agree. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
jgillis:gemmt-level3
1 day ago

Latest Branches

CodSpeed Performance Gauge
0%
Replace the GEMV-loop ?GEMMT with a blocked level-3 driver#6060
1 day ago
49f817a
jgillis:gemmt-level3
CodSpeed Performance Gauge
0%
CodSpeed Performance Gauge
0%
3 days ago
d005d50
almayne:sgemm_interleave
© 2026 CodSpeed Technology
Home Terms Privacy Docs