最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++使用cuBLAS加速矩陣乘法運(yùn)算的實(shí)現(xiàn)代碼

 更新時(shí)間:2021年09月07日 10:50:47   作者:白水baishui  
這篇文章主要介紹了C++使用cuBLAS加速矩陣乘法運(yùn)算,將cuBLAS庫(kù)的乘法運(yùn)算進(jìn)行了封裝,方便了算法調(diào)用,具體實(shí)現(xiàn)代碼跟隨小編一起看看吧

本博客主要參考cuBLAS 庫(kù) 詞條實(shí)現(xiàn),與原文不同的是,本博客:

  1. 將cuBLAS庫(kù)的乘法運(yùn)算進(jìn)行了封裝,方便了算法調(diào)用;
  2. 將原文的結(jié)果轉(zhuǎn)置實(shí)現(xiàn)為了不轉(zhuǎn)置,這樣可以直接使用計(jì)算結(jié)果;
  3. 測(cè)試并更改了乘法參數(shù),解決了原文中更改矩陣大小時(shí)報(bào)錯(cuò)的問題。

總的來說,本博客的代碼利用cuBLAS庫(kù)實(shí)現(xiàn)了兩個(gè)矩陣相乘,提高了矩陣乘法的計(jì)算速度。

test.cpp

#include "cuda_runtime.h"
#include "cublas_v2.h"
#include <time.h>
#include <iostream>

using namespace std;


// cuBLAS實(shí)現(xiàn)矩陣乘法
int **matMult_cuBLAS(int **A, int **B, int rowSizeA, int colSizeA, int colSizeB, cublasHandle_t cuHandle){
    // 結(jié)果矩陣
    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;
        }
    }

    // 在內(nèi)存中為將要計(jì)算的矩陣開辟空間
    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));

    // 初始化計(jì)算矩陣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];
        }
    }

    // 在顯存中為將要計(jì)算矩陣與結(jié)果矩陣開辟空間
    float *d_A, *d_B, *d_C;
    cudaMalloc (
        (void**)&d_A,    // 指向開辟的空間的指針
        rowSizeA * colSizeA * sizeof(float)    // 需要開辟空間的字節(jié)數(shù)
    );
    cudaMalloc (
        (void**)&d_B,    
        colSizeA * colSizeB * sizeof(float)    
    );
    cudaMalloc (
        (void**)&d_C,
        rowSizeA * colSizeB * sizeof(float)    
    );

    // 將矩陣數(shù)據(jù)傳遞進(jìn)顯存中已經(jīng)開辟好了的空間
    cublasSetVector (
        rowSizeA * colSizeA,    // 要存入顯存的元素個(gè)數(shù)
        sizeof(float),    // 每個(gè)元素大小
        h_A,    // 主機(jī)端起始地址
        1,    // 連續(xù)元素之間的存儲(chǔ)間隔
        d_A,    // GPU 端起始地址
        1    // 連續(xù)元素之間的存儲(chǔ)間隔
    );
    cublasSetVector (colSizeA * colSizeB, sizeof(float), h_B, 1, d_B, 1);

    // 傳遞進(jìn)矩陣相乘函數(shù)中的參數(shù),具體含義請(qǐng)參考函數(shù)手冊(cè).
    float a=1; float b=0;
    // 矩陣相乘.該函數(shù)必然將數(shù)組解析成列優(yōu)先數(shù)組
    cublasSgemm (
        cuHandle,    // blas 庫(kù)對(duì)象 
        CUBLAS_OP_T,    // 矩陣 A 屬性參數(shù)
        CUBLAS_OP_T,    // 矩陣 B 屬性參數(shù)
        rowSizeA,    // A, C 的行數(shù) 
        colSizeB,    // B, C 的列數(shù)
        colSizeA,    // A 的列數(shù)和 B 的行數(shù)
        &a,    // 運(yùn)算式的 \alpha 值
        d_A,    // A 在顯存中的地址
        colSizeA,    // lda
        d_B,    // B 在顯存中的地址
        colSizeB,    // ldb
        &b,    // 運(yùn)算式的 \beta 值
        d_C,    // C 在顯存中的地址(結(jié)果矩陣)
        rowSizeA    // ldc
    );
    
    // 從 顯存 中取出運(yùn)算結(jié)果至 內(nèi)存中去
    cublasGetVector (
        rowSizeA * colSizeB,    //  要取出元素的個(gè)數(shù)
        sizeof(float),    // 每個(gè)元素大小
        d_C,    // GPU 端起始地址
        1,    // 連續(xù)元素之間的存儲(chǔ)間隔
        h_C,    // 主機(jī)端起始地址
        1    // 連續(xù)元素之間的存儲(chǔ)間隔
    );

    for (int i = 0; i < rowSizeA; i++) {
        for (int j = 0; j < colSizeB; j++) {
            C[i][j] = (int)h_C[j * rowSizeA + i];
        }
    }
    
    // 清理掉使用過的內(nèi)存
    free (h_A); free (h_B); free (h_C); cudaFree (d_A);
    cudaFree (d_B); cudaFree (d_C);

    return C;
}

// 構(gòu)造一個(gè)隨機(jī)二維數(shù)組(矩陣)
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));  //隨機(jī)數(shù)種子采用系統(tǒng)時(shí)鐘
    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) 
{   
    // 創(chuàng)建并初始化 CUBLAS 庫(kù)對(duì)象
    // 若是CUBLAS對(duì)象在主函數(shù)中初始化,cuBLAS方法在其他函數(shù)中調(diào)用,需要將cuHandle傳入該函數(shù),并在該函數(shù)內(nèi)創(chuàng)建status對(duì)象
    cublasHandle_t cuHandle;
    cublasStatus_t status = cublasCreate(&cuHandle);
    if (status != CUBLAS_STATUS_SUCCESS)
    {
        if (status == CUBLAS_STATUS_NOT_INITIALIZED) {
            cout << "CUBLAS 對(duì)象實(shí)例化出錯(cuò)" << endl;
        }
        getchar ();
        return EXIT_FAILURE;
    }

    // 矩陣大小定義
    int rowSizeA = 3; // 矩陣A的行數(shù)
    int colSizeA = 4; // 矩陣A的列數(shù)和矩陣B的行數(shù)
    int colSizeB = 2; // 矩陣B的列數(shù)

    // 構(gòu)造一個(gè)3行4列的矩陣A,矩陣元素在(0,4)內(nèi)隨機(jī)選取
    int **A = uniformMat(rowSizeA, colSizeA, 0, 4);
    // 構(gòu)造一個(gè)4行2列的矩陣B,矩陣元素在(5,9)內(nèi)隨機(jī)選取
    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進(jìn)行矩陣乘法運(yùn)算:C = A * B
    int **C = matMult_cuBLAS(A, B, rowSizeA, colSizeA, colSizeB, cuHandle);

    // 輸出矩陣C,即運(yùn)算結(jié)果
    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 庫(kù)對(duì)象
    cublasDestroy (cuHandle);
    return 0;
}

在終端輸入:

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

運(yùn)算結(jié)果:

矩陣 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

到此這篇關(guān)于C++使用cuBLAS加速矩陣乘法運(yùn)算的文章就介紹到這了,更多相關(guān)C++ cuBLAS矩陣加速運(yùn)算內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C,C++中常用的操作字符串的函數(shù)

    C,C++中常用的操作字符串的函數(shù)

    這篇文章主要介紹了C,C++中常用的操作字符串的函數(shù),需要的朋友可以參考下
    2017-09-09
  • C++類重載函數(shù)的function和bind使用示例

    C++類重載函數(shù)的function和bind使用示例

    這篇文章主要介紹了C++類重載函數(shù)的function和bind使用示例,幫助大家更好的理解和使用c++,感興趣的朋友可以了解下
    2021-01-01
  • vs2019 MFC實(shí)現(xiàn)office界面的畫圖小項(xiàng)目

    vs2019 MFC實(shí)現(xiàn)office界面的畫圖小項(xiàng)目

    本文主要介紹了vs2019 MFC實(shí)現(xiàn)office界面的畫圖小項(xiàng)目,對(duì)大家入門有一定的幫助,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-06-06
  • C++&&Opencv實(shí)現(xiàn)控制臺(tái)字符動(dòng)畫的方法

    C++&&Opencv實(shí)現(xiàn)控制臺(tái)字符動(dòng)畫的方法

    這篇文章主要介紹了C++&&Opencv實(shí)現(xiàn)控制臺(tái)字符動(dòng)畫的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • C++中的Reactor原理與實(shí)現(xiàn)

    C++中的Reactor原理與實(shí)現(xiàn)

    reactor設(shè)計(jì)模式是event-driven?architecture的一種實(shí)現(xiàn)方式,處理多個(gè)客戶端并發(fā)的向服務(wù)端請(qǐng)求服務(wù)的場(chǎng)景,每種服務(wù)在服務(wù)端可能由多個(gè)方法組成,這篇文章主要介紹了Reactor原理與實(shí)現(xiàn),需要的朋友可以參考下
    2022-07-07
  • C++實(shí)現(xiàn)CreatThread函數(shù)主線程與工作線程交互的方法

    C++實(shí)現(xiàn)CreatThread函數(shù)主線程與工作線程交互的方法

    這篇文章主要介紹了C++實(shí)現(xiàn)CreatThread函數(shù)主線程與工作線程交互的方法,是Windows應(yīng)用程序設(shè)計(jì)中非常實(shí)用的方法,需要的朋友可以參考下
    2014-10-10
  • C語言多功能動(dòng)態(tài)通訊錄實(shí)現(xiàn)示例

    C語言多功能動(dòng)態(tài)通訊錄實(shí)現(xiàn)示例

    這篇文章主要為大家介紹了C語言多功能動(dòng)態(tài)通訊錄實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • C語言運(yùn)用函數(shù)的遞歸實(shí)現(xiàn)漢諾塔

    C語言運(yùn)用函數(shù)的遞歸實(shí)現(xiàn)漢諾塔

    遞歸(recursive)函數(shù)是“自己調(diào)用自己”的函數(shù),無論是采用直接或間接調(diào)用方式。間接遞歸意味著函數(shù)調(diào)用另一個(gè)函數(shù)(然后可能又調(diào)用第三個(gè)函數(shù)等),最后又調(diào)用第一個(gè)函數(shù)。因?yàn)楹瘮?shù)不可以一直不停地調(diào)用自己,所以遞歸函數(shù)一定具備結(jié)束條件
    2022-07-07
  • 詳解C++中string的用法和例子

    詳解C++中string的用法和例子

    string是C++標(biāo)準(zhǔn)庫(kù)的一個(gè)重要的部分,主要用于字符串處理。這篇文章主要介紹了C++ string的用法和例子,需要的朋友可以參考下
    2018-05-05
  • VC++實(shí)現(xiàn)的OpenGL線性漸變色繪制操作示例

    VC++實(shí)現(xiàn)的OpenGL線性漸變色繪制操作示例

    這篇文章主要介紹了VC++實(shí)現(xiàn)的OpenGL線性漸變色繪制操作,結(jié)合實(shí)例形式分析了VC++基于OpenGL進(jìn)行圖形繪制的相關(guān)操作技巧,需要的朋友可以參考下
    2017-07-07

最新評(píng)論

榆林市| 海门市| 樟树市| 农安县| 泰和县| 西乌珠穆沁旗| 福贡县| 通城县| 双鸭山市| 莱西市| 临沭县| 潍坊市| 浪卡子县| 安庆市| 金沙县| 凤山县| 泗阳县| 新营市| 西昌市| 利辛县| 大方县| 木里| 泉州市| 四会市| 永福县| 大姚县| 乃东县| 广南县| 娱乐| 丰镇市| 邳州市| 鹰潭市| 泰宁县| 肥城市| 乡城县| 田阳县| 金溪县| 德保县| 北辰区| 金湖县| 丹巴县|