cuBLAS#

Defined in code/simulator.h.

This page documents 20 symbols: 4 macros, 16 functions.

Macros#

Signature

Description

Availability

Location

Example

SIM_CUBLAS_AXPY(NAME, T)

Expands to inline cublasStatus_t NAME(cublasHandle_t h, int n, const T* alpha, const T* x, int incx, T* y, int incy) { const T a = *alpha; ::simdetail::streamEnqueue(h ? h->stream : nullptr,

sim only

simulator.h:2650

SIM_CUBLAS_GEMM(NAME, T)

Expands to inline cublasStatus_t NAME(cublasHandle_t h, cublasOperation_t opA, cublasOperation_t opB, int m, int n, int k, const T* alpha, const T* A, int lda, const T* B, int ldb, const T* b

sim only

simulator.h:2615

SIM_CUBLAS_GEMM_SB(NAME, T)

Strided-batched gemm: batchCount independent gemms over uniformly strided slices of A, B and C.

sim only

simulator.h:2632

SIM_CUBLAS_GEMV(NAME, T)

The public entry points read *alpha/*beta at call time (host pointer mode) and queue the work on the handle’s stream, so cuBLAS obeys stream ordering too.

sim only

simulator.h:2600

Functions#

Signature

Description

Availability

Location

Example

inline void blasGemm(cublasOperation_t opA, cublasOperation_t opB, int m, int n, int k, T alpha, const T* A, int lda, const T* B, int ldb, T beta, T* C, int ldc)

C = alpha*op(A)*op(B) + beta*C, all column-major; C is m-by-n, inner dim k.

sim only

simulator.h:2584

inline void blasGemv(cublasOperation_t op, int m, int n, T alpha, const T* A, int lda, const T* x, int incx, T beta, T* y, int incy)

y = alpha*op(A)*x + beta*y, with A an m-by-n column-major matrix.

sim only

simulator.h:2570

inline cublasStatus_t cublasCreate(cublasHandle_t* h)

sim only

simulator.h:2510

View

inline cublasStatus_t cublasCreate_v2(cublasHandle_t* h)

_v2 spellings (what <cublas_v2.h> #defines the classic names to)

sim only

simulator.h:2558

inline cublasStatus_t cublasDestroy(cublasHandle_t h)

sim only

simulator.h:2513

View

inline cublasStatus_t cublasDestroy_v2(cublasHandle_t h)

sim only

simulator.h:2559

inline cublasStatus_t cublasGetMatrix(int rows, int cols, int elemSize, const void* A, int lda, void* B, int ldb)

sim only

simulator.h:2553

inline cublasStatus_t cublasGetStream(cublasHandle_t h, cudaStream_t* s)

sim only

simulator.h:2517

inline cublasStatus_t cublasGetVector(int n, int elemSize, const void* x, int incx, void* y, int incy)

sim only

simulator.h:2536

View

inline cublasStatus_t cublasGetVector_v2(int n, int e, const void* x, int ix, void* y, int iy)

sim only

simulator.h:2542

inline cublasStatus_t cublasSetMatrix(int rows, int cols, int elemSize, const void* A, int lda, void* B, int ldb)

Column-major sub-matrix transfer: rows x cols elements, source ld lda, dest ld ldb.

sim only

simulator.h:2544

inline cublasStatus_t cublasSetPointerMode(cublasHandle_t, cublasPointerMode_t)

sim only

simulator.h:2520

inline cublasStatus_t cublasSetStream(cublasHandle_t h, cudaStream_t s)

sim only

simulator.h:2514

View

inline cublasStatus_t cublasSetStream_v2(cublasHandle_t h, cudaStream_t s)

sim only

simulator.h:2560

inline cublasStatus_t cublasSetVector(int n, int elemSize, const void* x, int incx, void* y, int incy)

sim only

simulator.h:2531

View

inline cublasStatus_t cublasSetVector_v2(int n, int e, const void* x, int ix, void* y, int iy)

sim only

simulator.h:2541

Examples#

Code from the repository’s example corpus (code\*.cu); the highlighted line is the call site. These blocks are what the View links above open.

cublasCreate (test_web_bf_cublas_gemm.cu:81)
71    check(cudaMalloc((void**)&g_A, sizeof(double) * MK), "cudaMalloc(g_A)");
72    check(cudaMalloc((void**)&g_B, sizeof(double) * KN), "cudaMalloc(g_B)");
73    check(cudaMalloc((void**)&g_C, sizeof(double) * MN), "cudaMalloc(g_C)");
74
75    // [SIM] was cublasSetVector(MK, sizeof(double), h_A, 1, g_A, 1) etc.
76    check(cudaMemcpy(g_A, h_A.data(), sizeof(double) * MK, cudaMemcpyHostToDevice), "H2D A");
77    check(cudaMemcpy(g_B, h_B.data(), sizeof(double) * KN, cudaMemcpyHostToDevice), "H2D B");
78    check(cudaMemcpy(g_C, h_C.data(), sizeof(double) * MN, cudaMemcpyHostToDevice), "H2D C");
79
80    cublasHandle_t handle;
81    cublasCreate(&handle);
82    const double alpha = 1.0, beta = 0.0;
83    cublasDgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N,
84                M, N, K, &alpha, g_A, M, g_B, K, &beta, g_C, M);
85    cublasDestroy(handle);
86    check(cudaDeviceSynchronize(), "cudaDeviceSynchronize");
87
88    // [SIM] was cublasGetVector(MN, sizeof(double), g_C, 1, h_C, 1)
89    check(cudaMemcpy(h_C.data(), g_C, sizeof(double) * MN, cudaMemcpyDeviceToHost), "D2H C");
90    print_matrix(M, N, h_C.data(), "C = A x B");
91
92    // CPU reference, column-major: C[i + j*M] = sum_p A[i + p*M] * B[p + j*K].
cublasDestroy (test_web_bf_cublas_gemm.cu:85)
75    // [SIM] was cublasSetVector(MK, sizeof(double), h_A, 1, g_A, 1) etc.
76    check(cudaMemcpy(g_A, h_A.data(), sizeof(double) * MK, cudaMemcpyHostToDevice), "H2D A");
77    check(cudaMemcpy(g_B, h_B.data(), sizeof(double) * KN, cudaMemcpyHostToDevice), "H2D B");
78    check(cudaMemcpy(g_C, h_C.data(), sizeof(double) * MN, cudaMemcpyHostToDevice), "H2D C");
79
80    cublasHandle_t handle;
81    cublasCreate(&handle);
82    const double alpha = 1.0, beta = 0.0;
83    cublasDgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N,
84                M, N, K, &alpha, g_A, M, g_B, K, &beta, g_C, M);
85    cublasDestroy(handle);
86    check(cudaDeviceSynchronize(), "cudaDeviceSynchronize");
87
88    // [SIM] was cublasGetVector(MN, sizeof(double), g_C, 1, h_C, 1)
89    check(cudaMemcpy(h_C.data(), g_C, sizeof(double) * MN, cudaMemcpyDeviceToHost), "D2H C");
90    print_matrix(M, N, h_C.data(), "C = A x B");
91
92    // CPU reference, column-major: C[i + j*M] = sum_p A[i + p*M] * B[p + j*K].
93    for (int j = 0; j < N && g_ok; ++j)
94        for (int i = 0; i < M && g_ok; ++i) {
95            double acc = 0.0;
96            for (int p = 0; p < K; ++p) acc += h_A[i + p * M] * h_B[p + j * K];
cublasGetVector (test_web_cs_simplecublas.cu:114)
104    simple_sgemm(N, alpha, h_A.data(), h_B.data(), beta, h_C_ref.data());
105
106    /* Performs operation using cublas: column-major, no operand swap */
107    if (cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N, N, N, N,
108                    &alpha, d_A, N, d_B, N, &beta, d_C, N) != CUBLAS_STATUS_SUCCESS) {
109        std::fprintf(stderr, "!!!! kernel execution error.\n");
110        return 1;
111    }
112
113    /* Read the result back */
114    if (cublasGetVector(n2, sizeof(float), d_C, 1, h_C.data(), 1) != CUBLAS_STATUS_SUCCESS) {
115        std::fprintf(stderr, "!!!! device access error (read C)\n");
116        return 1;
117    }
118
119    /* Check result against reference */
120    float error_norm = 0, ref_norm = 0;
121    for (int i = 0; i < n2; ++i) {
122        const float diff = h_C_ref[i] - h_C[i];
123        error_norm += diff * diff;
124        ref_norm   += h_C_ref[i] * h_C_ref[i];
125    }
cublasSetStream (test_web_cs_um_streams.cu:92)
 82    if (t.size < 100) {
 83        std::printf("Task [%u], thread [%d] executing on host (%u)\n", t.id, tid, t.size);
 84        check(cudaStreamAttachMemAsync(stream[0], t.data,   0, cudaMemAttachHost), "attach data");
 85        check(cudaStreamAttachMemAsync(stream[0], t.vector, 0, cudaMemAttachHost), "attach vector");
 86        check(cudaStreamAttachMemAsync(stream[0], t.result, 0, cudaMemAttachHost), "attach result");
 87        check(cudaStreamSynchronize(stream[0]), "cudaStreamSynchronize");
 88        gemv(int(t.size), int(t.size), T(1), t.data, t.vector, T(0), t.result);
 89    } else {
 90        std::printf("Task [%u], thread [%d] executing on device (%u)\n", t.id, tid, t.size);
 91        const double one = 1.0, zero = 0.0;
 92        cublasSetStream(handle[tid + 1], stream[tid + 1]);
 93        check(cudaStreamAttachMemAsync(stream[tid + 1], t.data,   0, cudaMemAttachSingle), "attach data");
 94        check(cudaStreamAttachMemAsync(stream[tid + 1], t.vector, 0, cudaMemAttachSingle), "attach vector");
 95        check(cudaStreamAttachMemAsync(stream[tid + 1], t.result, 0, cudaMemAttachSingle), "attach result");
 96        cublasDgemv(handle[tid + 1], CUBLAS_OP_N, int(t.size), int(t.size), &one,
 97                    t.data, int(t.size), t.vector, 1, &zero, t.result, 1);
 98    }
 99}
100
101int main() {
102    int deviceCount = 0;
103    cudaError_t e = cudaGetDeviceCount(&deviceCount);
cublasSetVector (test_web_cs_simplecublas.cu:95)
 85    /* Allocate device memory for the matrices */
 86    float *d_A = nullptr, *d_B = nullptr, *d_C = nullptr;
 87    if (cudaMalloc(reinterpret_cast<void**>(&d_A), n2 * sizeof(float)) != cudaSuccess ||
 88        cudaMalloc(reinterpret_cast<void**>(&d_B), n2 * sizeof(float)) != cudaSuccess ||
 89        cudaMalloc(reinterpret_cast<void**>(&d_C), n2 * sizeof(float)) != cudaSuccess) {
 90        std::fprintf(stderr, "!!!! device memory allocation error\n");
 91        return 1;
 92    }
 93
 94    /* Initialize the device matrices with the host matrices */
 95    if (cublasSetVector(n2, sizeof(float), h_A.data(), 1, d_A, 1) != CUBLAS_STATUS_SUCCESS ||
 96        cublasSetVector(n2, sizeof(float), h_B.data(), 1, d_B, 1) != CUBLAS_STATUS_SUCCESS ||
 97        cublasSetVector(n2, sizeof(float), h_C.data(), 1, d_C, 1) != CUBLAS_STATUS_SUCCESS) {
 98        std::fprintf(stderr, "!!!! device access error (write)\n");
 99        return 1;
100    }
101
102    /* Performs operation using plain C code */
103    std::vector<float> h_C_ref = h_C;               // [SIM] was the h_C pointer shuffle
104    simple_sgemm(N, alpha, h_A.data(), h_B.data(), beta, h_C_ref.data());
105
106    /* Performs operation using cublas: column-major, no operand swap */