如何用cublas計算逆矩陣?

2021-07-09 16:20:33 字數 2817 閱讀 7313

cublas的文件中提供了乙個用lu分解求逆矩陣的方法,需要用到兩個函式:

第乙個函式用於做lu分解,第二個函式把lu分解的結果變為逆矩陣。

但官方文件對這兩個函式的用法語焉不詳,我花了幾個小時才把這個問題搞定。主要遇到兩個問題:

函式有乙個引數是 const float * 型別,直接把 float **指標傳進去的話編譯通不過,以前沒接觸過這個型別的指標,費了不少功夫,上網查了些資料才搞定。

unspecified launch failure

這是視訊記憶體變數越界造成的。但仔細檢查**,也沒找到問題。後來翻牆到看看有沒有人遇到過類似問題,不得不說國外的社群就是強大,果然有人遇到過類似問題,別且找到了癥結所在。

原來,cuda 的指標的指標(例如 float **)就像普通資料一樣,也分為 host和 device, host上的,例如:

float ** hostprt = (float **)malloc(sizeof(float *));//這是host上的定義方法

float ** deviceprt ;

cudamalloc((void **) & deviceprt, sizeof(float *));//這是device上的定義方法。

而這兩個函式引數中,接受的

float *  

引數都是 device指標, 傳入host指標就出出錯。

解決了這個問題後,用cublas求逆矩陣就順利通過了。

但最後又遇到乙個問題:

我測試了用cublas計算逆矩陣的時間,和cpu上用eigen計算用的時間,(我的顯示卡是gtx980ti 算是不錯的顯示卡了),計算矩陣大小是1000 x 1000。結果cublas用的時間是cpu的5倍!!!看來用cublas計算逆矩陣,毫無速度優勢。我又想是不是矩陣不夠大?就改為2000 x 2000的矩陣試試看,結果是顯示卡直接罷工了(cublas的文件上就說求逆的矩陣不宜過大),而eigen也只是用了0.6秒左右的時間。究其原因,應該是求逆矩陣並不是乙個可以通過並行方法解決的問題(求特徵矩陣也是如此)。

那麼為何cublas為何還要提供乙個求逆矩陣的函式呢?

因為cublas提供的這兩個函式,並非計算單個逆矩陣,而是可以計算逆矩陣組,比如你有幾十個相同大小的矩陣需要求逆,就可以發揮並行運算的威力,可能計算幾十個的時間比計算乙個的時間多不了太多,這樣gpu的優勢就顯示出來了。畢竟在實際應用中,求一系列矩陣的逆矩陣的情況還是常見的,比如做嶺回歸分析的時候。

cublashandle_t handle;

cublascreate(&cublashandle);

int size = 50; //矩陣的行和列

int num = 100;//矩陣組的矩陣個數

int * info ;//用於記錄lu分解是否成功

int * pivo;//用於記錄lu分解的資訊

cudamalloc((void **) & info, sizeof(int) * num);

cudamalloc((void **) & pivo, sizeof(int) * size * num);

float ** mat = new float *[num];//待求逆的矩陣組

float ** invmat = new float *[num];//存放逆矩陣的矩陣組

for(int i = 0; i< num; i++)

float ** gpumat;

cudamalloc((void **) & gpumat, sizeof(float *) * num);

cudamemcpy(gpumat, mat, sizeof(float *) * num, cudamemcpyhosttodevice);

//以上三步的目的是把host上的float ** 指標轉變為 device上的 float ** 指標

cublassgetrfbatched(handle, size, gpumat, size , pivo, info, num);//第四個引數是矩陣的主導維,由於這裡假設資料在記憶體中的存放是連續的,所以是size

const float ** constmat;

cudamalloc((void **) & constmat, sizeof(float *) * num);

cudamemcpy(constmat, gpumat, sizeof(float *) * num, cudamemcpydevicetodevice);

//以上三步的目的是把 float ** 指標轉變為 float *指標

float ** gpuinvmat;

cudamalloc((void **) & gpuinvmat, sizeof(float *) * num);

cudamemcpy(gpuinvmat, invmat, sizeof(float *) * num, cudamemcpyhosttodevice);

//以上三步的目的是把host上的float ** 指標轉變為 device上的 float ** 指標

cublassgetribatched(handle, size, constmat, size, pivo, gpuinvmat, size, info, num);

cudafree(info);

cudafree(pivo);

cudafree(mat);

cudafree(gpumat);

cudafree(gpuinvmat);

cudafree(constmat);

C語言計算逆矩陣

花了4天寫的,不過三天在重學線代。1 include2 include 操作記憶體 3 include pow 函式,計算 1的n次方,可以不用這個函式,偷懶使用現成的45 6顯示矩陣 7matrix 矩陣 8order 階數9 10void showmatrix float matrix,int ...

如何用Python計算Softmax?

softmax函式,或稱歸一化指數函式,它能將乙個含任意實數的k維向量z 壓縮 到另乙個k維實向量 sigma 中,使得每乙個元素的範圍都在 0,1 之間,並且所有元素的和為1。該函式的形式通常按下面的式子給出 sigma frac e quad for j 1,k 輸入向量 1,2,3,4,1,2...

C 計算矩陣的逆矩陣方法例項分析

1.思路 1 對矩陣進行合法性檢查 矩陣必須為方陣 2 計算矩陣行列式的值 determinant函式 3 只有滿秩矩陣才有逆矩陣,因此如果行列式的值為0 在 中以絕對值小於1e 6做判斷 則終止函式,報出異常 4 求出伴隨矩陣 adjointmatrix函式 5 逆矩陣各元素即其伴隨矩陣各元素除以...