CUDA 内核可以调用 cublas 函数吗?

Posted

技术标签:

【中文标题】CUDA 内核可以调用 cublas 函数吗?【英文标题】:Could a CUDA kernel call a cublas function? 【发布时间】:2012-11-02 11:48:46 【问题描述】:

我知道这听起来很奇怪,但这是我的场景:

我需要进行矩阵-矩阵乘法 (A(n*k)*B(k*n)),但我只需要对输出矩阵的对角线元素进行评估。我搜索了 cublas 库,没有找到任何可以做到这一点的 2 级或 3 级函数。 因此,我决定将 A 的每一行和 B 的每一列分配到 CUDA 线程中。对于每个线程(idx),我需要计算点积“A[idx,:]*B[:,idx]”并将其保存为对应的对角线输出。现在由于这个点积也需要一些时间,我想知道我是否可以在这里调用 cublas 函数(比如 cublasSdot)来实现它。

如果我错过了一些可以直接实现目标的 cublas 函数(只计算矩阵-矩阵乘法的对角线元素),这个问题可以被丢弃。

【问题讨论】:

【参考方案1】:

是的,它可以(直到(不包括)CUDA 10 版本)。

“CUDA C/C++ 中可用的语言接口和设备运行时 API 是主机上可用的 CUDA 运行时 API 的子集。CUDA 运行时 API 的语法和语义已保留在设备上以方便使用可以在主机或设备环境中运行的 API 例程的代码重用。内核也可以直接调用 GPU 库,例如 CUBLAS,而无需返回 CPU。” Source

Here 你可以看到矩阵向量乘法使用 cuda 和 CUBLAS 库函数 cublasSgemv。

但请记住,不再有 device CUBLAS capability in CUDA 10.。从 Robert_Crovella 可以引用:

目前的建议是看看CUTLASS 2 是否有帮助(它 主要集中在与 GEMM 相关的活动上)。如果没有,请自己编写 执行该功能的代码,或从主机代码调用 cublas。

尽管如此,目前网上有几种矩阵向量乘法的实现,例如1、2等。

【讨论】:

【参考方案2】:

确保您使用设备库来调用 cublas。您不能使用从主机调用它的同一个库;有关使用 cuda 设备库的详细信息,请参见 cuda 工具包:http://docs.nvidia.com/cuda/cublas/index.html#device-api

查看 7_CUDALibraries/ 下的 cuda 5 示例。

【讨论】:

【参考方案3】:

这里有一个代码示例解决您的问题,我认为this code link 可以帮助您。感谢 Github 的作者。

__global__ void invokeDeviceCublasSgemm(cublasStatus_t *returnValue,
                                    int n,
                                    const float *d_alpha,
                                    const float *d_A,
                                    const float *d_B,
                                    const float *d_beta,
                                    float *d_C)
   
    cublasHandle_t cnpHandle;
    cublasStatus_t status = cublasCreate(&cnpHandle);

    if (status != CUBLAS_STATUS_SUCCESS)
        *returnValue = status;
        return;
    

    /* Perform operation using cublas */
    status = cublasSgemm(cnpHandle,
                CUBLAS_OP_N, CUBLAS_OP_N,
                n, n, n,
                d_alpha,
                d_A, n,
                d_B, n,
                d_beta,
                d_C, n);
    cublasDestroy(cnpHandle);
    *returnValue = status;

【讨论】:

以上是关于CUDA 内核可以调用 cublas 函数吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何针对 cublas_device 编译/链接具有不同计算能力的代码?

是否可以从全局或设备函数调用 CUDA CUBLAS 函数

使用带有 nvcc 的 -G 标志编译为 cubin 后,Cublas 无法在内核中工作

CUDA Nsight - 找出内核/运行时 api 调用之间的 CPU 在做啥

可以在用户创建的 numba CUDA 设备函数中调用 numba.cuda.random 设备函数吗?

CUDA 内核中的中值选择