千家信息网

C++如何使用cuBLAS加速矩阵乘法运算

发表于:2025-01-22 作者:千家信息网编辑
千家信息网最后更新 2025年01月22日,这篇文章主要讲解了"C++如何使用cuBLAS加速矩阵乘法运算",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"C++如何使用cuBLAS加速矩阵乘法运算
千家信息网最后更新 2025年01月22日C++如何使用cuBLAS加速矩阵乘法运算

这篇文章主要讲解了"C++如何使用cuBLAS加速矩阵乘法运算",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"C++如何使用cuBLAS加速矩阵乘法运算"吧!

test.cpp

#include "cuda_runtime.h"#include "cublas_v2.h"#include #include using namespace std;// cuBLAS实现矩阵乘法int **matMult_cuBLAS(int **A, int **B, int rowSizeA, int colSizeA, int colSizeB, cublasHandle_t cuHandle){    // 结果矩阵    int** C = new int*[rowSizeA];    for(int i = 0; i < rowSizeA; i++){        C[i] = new int[colSizeB];    }    for (int i = 0; i < rowSizeA; i++){        for (int j = 0; j < colSizeB; j++){            C[i][j] = 0;        }    }    // 在内存中为将要计算的矩阵开辟空间    float *h_A = (float*)malloc (rowSizeA * colSizeA * sizeof(float));    float *h_B = (float*)malloc (colSizeA * colSizeB * sizeof(float));    float *h_C = (float*)malloc (rowSizeA * colSizeB * sizeof(float));    // 初始化计算矩阵h_A和h_B    for (int i = 0; i < rowSizeA; i++) {        for (int j = 0; j < colSizeA; j++) {            h_A[i * colSizeA + j] = (float)A[i][j];        }    }    for (int i = 0; i < colSizeA; i++) {        for (int j = 0; j < colSizeB; j++) {            h_B[i * colSizeB + j] = (float)B[i][j];        }    }    // 在显存中为将要计算矩阵与结果矩阵开辟空间    float *d_A, *d_B, *d_C;    cudaMalloc (        (void**)&d_A,    // 指向开辟的空间的指针        rowSizeA * colSizeA * sizeof(float)    // 需要开辟空间的字节数    );    cudaMalloc (        (void**)&d_B,            colSizeA * colSizeB * sizeof(float)        );    cudaMalloc (        (void**)&d_C,        rowSizeA * colSizeB * sizeof(float)        );    // 将矩阵数据传递进显存中已经开辟好了的空间    cublasSetVector (        rowSizeA * colSizeA,    // 要存入显存的元素个数        sizeof(float),    // 每个元素大小        h_A,    // 主机端起始地址        1,    // 连续元素之间的存储间隔        d_A,    // GPU 端起始地址        1    // 连续元素之间的存储间隔    );    cublasSetVector (colSizeA * colSizeB, sizeof(float), h_B, 1, d_B, 1);    // 传递进矩阵相乘函数中的参数,具体含义请参考函数手册.    float a=1; float b=0;    // 矩阵相乘.该函数必然将数组解析成列优先数组    cublasSgemm (        cuHandle,    // blas 库对象         CUBLAS_OP_T,    // 矩阵 A 属性参数        CUBLAS_OP_T,    // 矩阵 B 属性参数        rowSizeA,    // A, C 的行数         colSizeB,    // B, C 的列数        colSizeA,    // A 的列数和 B 的行数        &a,    // 运算式的 \alpha 值        d_A,    // A 在显存中的地址        colSizeA,    // lda        d_B,    // B 在显存中的地址        colSizeB,    // ldb        &b,    // 运算式的 \beta 值        d_C,    // C 在显存中的地址(结果矩阵)        rowSizeA    // ldc    );        // 从 显存 中取出运算结果至 内存中去    cublasGetVector (        rowSizeA * colSizeB,    //  要取出元素的个数        sizeof(float),    // 每个元素大小        d_C,    // GPU 端起始地址        1,    // 连续元素之间的存储间隔        h_C,    // 主机端起始地址        1    // 连续元素之间的存储间隔    );    for (int i = 0; i < rowSizeA; i++) {        for (int j = 0; j < colSizeB; j++) {            C[i][j] = (int)h_C[j * rowSizeA + i];        }    }        // 清理掉使用过的内存    free (h_A); free (h_B); free (h_C); cudaFree (d_A);    cudaFree (d_B); cudaFree (d_C);    return C;}// 构造一个随机二维数组(矩阵)int** uniformMat(int rowSize, int colSize, int minValue, int maxValue) {    int** mat = new int* [rowSize];    for (int i = 0; i < rowSize; i++)        mat[i] = new int[colSize];    // srand(1024);    srand((unsigned)time(NULL));  //随机数种子采用系统时钟    for (int i = 0; i < rowSize; i++) {        for (int j = 0; j < colSize; j++) {            mat[i][j] = (int)(rand() % (maxValue - minValue + 1)) + minValue;        }    }    return mat;}int main(void) {       // 创建并初始化 CUBLAS 库对象    // 若是CUBLAS对象在主函数中初始化,cuBLAS方法在其他函数中调用,需要将cuHandle传入该函数,并在该函数内创建status对象    cublasHandle_t cuHandle;    cublasStatus_t status = cublasCreate(&cuHandle);    if (status != CUBLAS_STATUS_SUCCESS)    {        if (status == CUBLAS_STATUS_NOT_INITIALIZED) {            cout << "CUBLAS 对象实例化出错" << endl;        }        getchar ();        return EXIT_FAILURE;    }    // 矩阵大小定义    int rowSizeA = 3; // 矩阵A的行数    int colSizeA = 4; // 矩阵A的列数和矩阵B的行数    int colSizeB = 2; // 矩阵B的列数    // 构造一个3行4列的矩阵A,矩阵元素在(0,4)内随机选取    int **A = uniformMat(rowSizeA, colSizeA, 0, 4);    // 构造一个4行2列的矩阵B,矩阵元素在(5,9)内随机选取    int **B = uniformMat(colSizeA, colSizeB, 5, 9);    // 输出矩阵A和B    cout << "矩阵 A :" << endl;    for (int i = 0; i < rowSizeA; i++) {        for (int j = 0; j < colSizeA; j++) {            cout << A[i][j] << " ";        }        cout << endl;    }    cout << endl;    cout << "矩阵 B :" << endl;    for (int i = 0; i < colSizeA; i++) {        for (int j = 0; j < colSizeB; j++) {            cout << B[i][j] << " ";        }        cout << endl;    }    cout << endl;    // 使用cuBLAS进行矩阵乘法运算:C = A * B    int **C = matMult_cuBLAS(A, B, rowSizeA, colSizeA, colSizeB, cuHandle);    // 输出矩阵C,即运算结果    cout << "矩阵 C :" << endl;    for (int i = 0; i < rowSizeA; i++) {        for (int j = 0; j < colSizeB; j++) {            cout << C[i][j] << " ";        }        cout << endl;    }    cout << endl;    // 释放 CUBLAS 库对象    cublasDestroy (cuHandle);    return 0;}

在终端输入:

nvcc -lcublas test.cpp -o t
./t

运算结果:

矩阵 A :
1 3 2 0
2 1 2 1
4 3 2 4

矩阵 B :
6 8
7 5
7 6
7 6

矩阵 C :
41 35
40 39
87 83

感谢各位的阅读,以上就是"C++如何使用cuBLAS加速矩阵乘法运算"的内容了,经过本文的学习后,相信大家对C++如何使用cuBLAS加速矩阵乘法运算这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

矩阵 元素 运算 j++ 函数 地址 显存 乘法 对象 结果 空间 C++ 之间 存储 起始 内存 参数 大小 数组 学习 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 信息化软件开发具体地址 苹果4id注册服务器错误 网络安全靠人民内容初中 渝中区综合软件开发服务公司 不属于数据库管理系统的是 查看服务器的raid信息 服务器怎么知道是二级域名 江丰电子 互联网科技 腾讯节省服务器资源分布式存储 学生对网络安全的看法 北京软件开发服务单位 做erp软件开发的企业 徐汇区什么是软件开发服务至上 为什么用虚拟机学习网络安全 天天十三水软件开发 福建会计软件开发服务优化 农业银行软件开发中心位置 网络技术专科大一要学的科目 正在更新服务器列表 通过服务器保存微信图片 数据库sql默认用户删除 网络安全秘钥不正确笔记本电脑 分期付款服务器 选购网络服务器遵循哪些原则 服务器连接失败怎么办 无忧隐藏软件开发 怎么用服务器做自己的网店 科来网络技术股份有限公司 网络安全从我做起演讲稿300字 福建会计软件开发服务优化
0