Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Deepspeedai DeepSpeed Inference Cublas Wrappers

From Leeroopedia
Revision as of 14:46, 16 February 2026 by Admin (talk | contribs) (Auto-imported from implementations/Deepspeedai_DeepSpeed_Inference_Cublas_Wrappers.md)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)


Knowledge Sources
Domains Linear_Algebra, Inference, CUDA_Kernels, Performance_Optimization
Last Updated 2026-02-09 00:00 GMT

Overview

Cross-platform cuBLAS/rocBLAS wrappers providing unified GEMM interfaces for FP32, FP16, and BF16 matrix multiplication with algorithm selection.

Description

This header provides a unified API layer abstracting differences between NVIDIA cuBLAS and AMD rocBLAS libraries, enabling portable GEMM operations across CUDA and ROCm platforms. It implements wrapper functions for standard GEMM (cublas_gemm_ex) and strided batched GEMM (cublas_strided_batched_gemm) with support for mixed-precision computation (FP16/BF16 inputs with FP32 accumulation). The implementation uses conditional compilation to handle API differences between platforms, including version-specific compatibility for PyTorch 2.0 transitions on ROCm. Algorithm selection is exposed as a parameter allowing performance tuning based on problem dimensions, and the wrappers include error checking with detailed diagnostics for matrix dimension debugging.

Usage

Use these wrappers when implementing inference kernels that need to run on both NVIDIA and AMD GPUs, or when you need explicit control over cuBLAS algorithm selection for performance optimization. The strided batched variant is particularly important for transformer attention mechanisms where multiple matrix multiplications with regular stride patterns are computed in parallel.

Code Reference

Source Location

Signature

// FP32 GEMM: C = alpha * op(A) * op(B) + beta * C
int cublas_gemm_ex(cublasHandle_t handle,
                   cublasOperation_t transa, cublasOperation_t transb,
                   int m, int n, int k,
                   const float* alpha, const float* beta,
                   const float* A, const float* B, float* C,
                   cublasGemmAlgo_t algo, int b_stride = -1);

// FP16/BF16 GEMM with FP32 accumulation
template <typename T>
int cublas_gemm_ex(cublasHandle_t handle,
                   cublasOperation_t transa, cublasOperation_t transb,
                   int m, int n, int k,
                   const float* alpha, const float* beta,
                   const T* A, const T* B, T* C,
                   cublasGemmAlgo_t algo, int b_stride = -1);

// Strided batched GEMM for multiple independent matrices
template <typename T>
int cublas_strided_batched_gemm(cublasHandle_t handle,
                                int m, int n, int k,
                                const float* alpha, const float* beta,
                                const T* A, const T* B, T* C,
                                cublasOperation_t op_A, cublasOperation_t op_B,
                                int stride_A, int stride_B, int stride_C,
                                int batch, cublasGemmAlgo_t algo);

Import

#include "inference_cublas_wrappers.h"

I/O Contract

Parameter Type Description
handle cublasHandle_t cuBLAS context handle
transa/transb cublasOperation_t Transpose flags (N/T)
m, n, k int Matrix dimensions (m×k) × (k×n) = (m×n)
alpha, beta const float* Scaling factors
A, B const T* Input matrices (FP32/FP16/BF16)
C T* Output matrix (in-place update)
algo cublasGemmAlgo_t Algorithm ID for cuBLAS
stride_A/B/C int Memory stride between batches
batch int Number of matrix multiplications
Output Type Description
C T* Result matrix C = alpha*op(A)*op(B) + beta*C
return int 0 on success, EXIT_FAILURE on error

Usage Examples

Basic FP16 Matrix Multiplication:

#include "inference_cublas_wrappers.h"

cublasHandle_t handle;
cublasCreate(&handle);

int M = 1024, N = 4096, K = 768;
__half *A, *B, *C;
// ... allocate and initialize ...

float alpha = 1.0f, beta = 0.0f;

int status = cublas_gemm_ex(
    handle,
    CUBLAS_OP_N, CUBLAS_OP_N,  // No transpose
    M, N, K,
    &alpha, &beta,
    A, B, C,
    CUBLAS_GEMM_DEFAULT_TENSOR_OP);

if (status != 0) {
    fprintf(stderr, "GEMM failed\n");
}

Attention Score Computation (Strided Batch):

// Compute attention scores: S = Q * K^T for all heads
// Q: [batch*heads, seq_len, head_dim]
// K: [batch*heads, seq_len, head_dim]
// S: [batch*heads, seq_len, seq_len]

int batch_heads = batch_size * num_heads;
int seq_len = 512;
int head_dim = 64;

__half *Q, *K, *scores;
// ... allocate memory ...

float scale = 1.0f / sqrtf((float)head_dim);
float beta = 0.0f;

cublasSetStream(handle, stream);
cublas_strided_batched_gemm(
    handle,
    seq_len,        // M: output rows
    seq_len,        // N: output cols
    head_dim,       // K: reduction dimension
    &scale, &beta,
    K,              // A: keys
    Q,              // B: queries
    scores,         // C: output scores
    CUBLAS_OP_T,    // Transpose keys
    CUBLAS_OP_N,    // Don't transpose queries
    seq_len * head_dim,    // stride_A
    seq_len * head_dim,    // stride_B
    seq_len * seq_len,     // stride_C
    batch_heads,           // batch count
    CUBLAS_GEMM_DEFAULT_TENSOR_OP);

Attention Context Computation:

// Compute context: C = softmax(S) * V
// attn_probs: [batch*heads, seq_len, seq_len]
// V: [batch*heads, seq_len, head_dim]
// context: [batch*heads, seq_len, head_dim]

__half *attn_probs, *V, *context;

float alpha = 1.0f, beta = 0.0f;

cublas_strided_batched_gemm(
    handle,
    head_dim,       // M: head dimension
    seq_len,        // N: sequence length
    seq_len,        // K: attention dimension
    &alpha, &beta,
    V,              // A: values
    attn_probs,     // B: attention probabilities
    context,        // C: output context
    CUBLAS_OP_N,    // Don't transpose V
    CUBLAS_OP_N,    // Don't transpose attn_probs
    seq_len * head_dim,    // stride_A
    seq_len * seq_len,     // stride_B
    seq_len * head_dim,    // stride_C
    batch_heads,
    CUBLAS_GEMM_DEFAULT_TENSOR_OP);

Linear Layer with Algorithm Selection:

// Optimized linear layer with tuned algorithm
class OptimizedLinear {
    cublasHandle_t handle;
    cublasGemmAlgo_t best_algo;
    __half *weight;  // [out_features, in_features]
    int in_features, out_features;

public:
    OptimizedLinear(cublasHandle_t h, int in_f, int out_f,
                   cublasGemmAlgo_t algo)
        : handle(h), in_features(in_f), out_features(out_f),
          best_algo(algo) {
        cudaMalloc(&weight, sizeof(__half) * in_f * out_f);
    }

    void forward(__half* input, __half* output, int batch_size) {
        // Y = X * W^T
        float alpha = 1.0f, beta = 0.0f;

        cublas_gemm_ex(
            handle,
            CUBLAS_OP_T,    // Transpose weight
            CUBLAS_OP_N,    // Don't transpose input
            out_features,   // M
            batch_size,     // N
            in_features,    // K
            &alpha, &beta,
            weight, input, output,
            best_algo);
    }
};

Cross-Platform Inference:

// Platform-agnostic GEMM wrapper
template <typename T>
void inference_matmul(cublasHandle_t handle,
                     const T* A, const T* B, T* C,
                     int m, int n, int k,
                     bool transpose_a, bool transpose_b) {
    float alpha = 1.0f, beta = 0.0f;

    auto op_a = transpose_a ? CUBLAS_OP_T : CUBLAS_OP_N;
    auto op_b = transpose_b ? CUBLAS_OP_T : CUBLAS_OP_N;

    #if defined(__HIP_PLATFORM_AMD__)
    // ROCm-specific algorithm
    auto algo = rocblas_gemm_algo_standard;
    #else
    // NVIDIA-specific algorithm
    auto algo = CUBLAS_GEMM_DEFAULT_TENSOR_OP;
    #endif

    int status = cublas_gemm_ex(
        handle, op_a, op_b, m, n, k,
        &alpha, &beta, A, B, C, algo);

    if (status != 0) {
        throw std::runtime_error("GEMM failed");
    }
}

BFloat16 Support:

#ifdef BF16_AVAILABLE
// Mixed precision: BF16 input/output, FP32 accumulation
void bf16_linear_layer(cublasHandle_t handle,
                      const __nv_bfloat16* input,
                      const __nv_bfloat16* weight,
                      __nv_bfloat16* output,
                      int batch, int in_dim, int out_dim) {
    float alpha = 1.0f, beta = 0.0f;

    cublas_gemm_ex(
        handle,
        CUBLAS_OP_T, CUBLAS_OP_N,
        out_dim, batch, in_dim,
        &alpha, &beta,
        weight, input, output,
        CUBLAS_GEMM_DEFAULT_TENSOR_OP);
}
#endif

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment