当前位置:首页 > 通信资讯 > 正文

cublas 矩阵乘法(cuda加速矩阵乘法)

本博客主要参考cuBLAS 库 词条实现,与原文不同的是,本博客:

  1. 将cuBLAS库的乘法运算进行了封装,方便了算法调用;
  2. 将原文的结果转置实现为了不转置,这样可以直接使用计算结果;
  3. 测试并更改了乘法参数,解决了原文中更改矩阵大小时报错的问题。

总的来说,本博客的代码利用cuBLAS库实现了两个矩阵相乘,提高了矩阵乘法的计算速度。

test.cpp

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 #include "cuda_runtime.h" #include "cublas_v2.h" #include <time.h> #include <iostream> 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矩阵加速运算内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/baishuiniyaonulia/article/details/120119380

如果您对该产品感兴趣,请填写办理(客服微信:xiaoxiongyidong)

为您推荐:

发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。