The v1 deliverable is a correct, stream-aware, column-major SGEMM implementation with a fast NN specialization. It is intentionally not a complete BLAS library and not a portable claim of cuBLAS parity.
The design separates three concerns:
- a stable C API and BLAS-compatible validation rules;
- a general correctness kernel that covers the full v1 contract;
- guarded, GPU-specific optimized kernels selected only when their preconditions hold.
CUTLASS is used as a readable reference for hierarchical decomposition, pipelines, epilogues, and schedulers, but sgBLAS does not link to or include CUTLASS. NVIDIA documents the same threadblock/warp/thread hierarchy in Efficient GEMM in CUDA.
The operation is
C(m,n) = alpha * op(A)(m,k) * op(B)(k,n) + beta * C(m,n)
with these rules:
A,B, andCcontain IEEE binary32 values.- The selected v1 math mode performs FP32 multiplication and FP32 accumulation. Fused FP32 FMA is permitted; reduced-precision TF32 inputs are not. “Strict FP32” is project shorthand for this precision contract and does not imply bitwise-identical results or an identical reduction order.
- Matrices use column-major storage.
transaandtransbindependently acceptNorT, coveringNN,NT,TN, andTT.m,n, andkmay be any non-negativeintvalues.lda >= max(1, transa == N ? m : k).ldb >= max(1, transb == N ? k : n).ldc >= max(1, m).alphaandbetaare valid host pointers for the duration of the call.- Matrix pointers identify device memory accessible from the handle's current device. A, B, and C storage must not overlap.
- The operation is enqueued on the handle's stream and does not introduce a device- or stream-wide synchronization.
- If
m == 0orn == 0, the call succeeds without launching work. - If
k == 0oralpha == 0, A and B are not read and the result isbeta * C. - If
beta == 0, the prior values, including NaNs, in C are not read.
The public definitions live in include/sgblas/sgblas.h. Invalid enums, dimensions, leading dimensions, handles, or required pointers return a status code rather than terminating the process.
The general kernel is the semantic backstop. It handles all transpose modes, legal tails, and legal leading dimensions. Optimized kernels may make stronger assumptions, but those assumptions belong in an explicit dispatch predicate; they must never leak into the public contract.
The initial dispatch order is:
validated request
-> optimized FP32 NN kernel when its GPU/layout/alignment/shape guard passes
-> general FP32 kernel otherwise
Future kernels should be keyed by at least compute capability, math mode, transpose pair, alignment class, and coarse M/N/K shape bucket. Tile dimensions, stage count, or vector width are implementation details, not ABI.
Each rung must preserve correctness and demonstrate a benchmark improvement before becoming the new baseline.
- Map adjacent lanes to adjacent elements of C and coalesce A/B/C global accesses.
- Tile M, N, and K at CTA scope; load each A/B tile once into shared memory.
- Pad or swizzle shared layouts to avoid bank conflicts. NVIDIA explains coalescing, redundant-load elimination, shared-memory banks, and padding in the CUDA Best Practices Guide.
- Use naturally aligned 8- or 16-byte memory operations where the dispatch guard proves alignment. Keep a predicated/scalar tail. NVIDIA's vectorized memory-access guidance emphasizes both the instruction-count benefit and alignment requirement.
- Give each thread a 2D register accumulator tile and reuse loaded A/B values across an outer product. Unroll the inner K fragment.
- Double-buffer shared tiles and register fragments so data movement overlaps useful FMA work.
- Make the epilogue coalesce stores and handle
alpha/betawithout a second global-memory pass. - Tune CTA, warp, and thread tiles together. Do not maximize occupancy blindly: NVIDIA notes that extra registers and instruction-level parallelism can outperform higher occupancy in the occupancy guidance.
| Target | Strict-FP32 path | Architecture-specific next step |
|---|---|---|
Volta/Turing (sm_70-sm_75) |
Shared-memory multibuffering and FP32 CUDA-core FMA | Tune synchronous global-to-shared staging and register reuse. CUDA 13 removed offline compilation and library support for Volta, so sm_70 requires a CUDA 12.x toolchain. |
Ampere/Ada (compute capability 8.x; sm_80-sm_89) |
FP32 CUDA-core FMA remains the scored v1 path | On sm_80 and later, use aligned 16-byte PTX cp.async/LDGSTS or CUDA pipeline APIs to overlap global-to-shared copies. Published tuning is A100 compute capability 8.0 only. See Asynchronous Data Copies. |
Hopper (sm90a) |
Preserve a true-FP32 CUDA-core lane | Explore TMA, warp specialization, and persistent scheduling; WGMMA belongs to a separately scored Tensor Core mode. See the Hopper Tuning Guide |
Blackwell datacenter (sm100a/sm103a) |
Preserve a true-FP32 lane | Explore TMA, TMEM, CLC scheduling, and tcgen05 only in a declared Tensor Core or emulation mode. See NVIDIA's tcgen05 guide |
Blackwell GeForce (sm120) |
Preserve a true-FP32 lane | Treat it as a separate backend: SM120 uses extended mma.sync for narrow types and lacks SM100-style multicast. See CUTLASS Blackwell functionality |
Architecture specialization must be compiled for the matching feature target. An sm90a or sm100a kernel is not a generic fallback for all devices carrying the same marketing family name.
SGBLAS_MATH_FP32 means FP32 inputs reach FP32 arithmetic without TF32 truncation. A future SGBLAS_MATH_TF32 mode may use Tensor Cores, but it must have its own dispatch table, error tolerance, cuBLAS compute mode, and scorecard.
The benchmark must never divide an FP32 kernel's throughput by a TF32 cuBLAS result, or vice versa. NVIDIA's cuBLAS compute-type documentation distinguishes CUBLAS_COMPUTE_32F_PEDANTIC, CUBLAS_COMPUTE_32F, and CUBLAS_COMPUTE_32F_FAST_TF32, and notes that NVIDIA_TF32_OVERRIDE=0 disables TF32 acceleration across NVIDIA libraries.
- Use a higher-precision host reference for small matrices and strict-FP32 cuBLAS as a large-case cross-check.
- Compare with a magnitude- and K-aware tolerance; floating-point reductions are not expected to be bitwise identical when their legal evaluation orders differ.
- Include zero dimensions, K tails, non-tile M/N tails, padded leading dimensions, every transpose pair,
alphain{0, 1, nontrivial}, andbetain{0, 1, nontrivial}. - Seed random cases and print the seed on failure.
- Test a non-default, nonblocking CUDA stream and verify that the API does not synchronize unrelated work.
- Run NVIDIA Compute Sanitizer during development in addition to numerical tests.
NVIDIA recommends reference comparison after every optimization and explains why epsilon-based comparison is often required in Getting the Right Answer.
- batched, grouped, distributed, sparse, complex, FP64, FP16, BF16, FP8, or FP4 GEMM;
- row-major public storage;
- fused bias or activation epilogues;
- universal parity with cuBLAS on every size;
- Tensor Core performance reported as strict FP32;
- hidden JIT compilation or runtime autotuning in a timed region.