您好,登錄后才能下訂單哦!
這篇文章主要講解了“C++如何使用cuBLAS加速矩陣乘法運算”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“C++如何使用cuBLAS加速矩陣乘法運算”吧!
test.cpp
#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加速矩陣乘法運算這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。