簡體   English   中英

改進CUDA GPU上A * x = B的Matlab + CUSP MEX解決方案

[英]Improving Matlab + CUSP MEX solution for A*x=B on CUDA GPU

Matlab仍然無法在CUDA GPU上計算稀疏矩陣。 也沒有這樣的工具箱(Jacket已停產)。 這就是為什么我使用通過MEX文件集成到Matlab的CUSP。 但是,我開發的工具有兩個問題:

  • 對於大型方程組(實際上僅從100個元素開始),它非常不穩定,
  • 它比替代Matlab CPU慢幾十倍或幾百倍。

我正在求解A * x = b,其中A是一個稀疏的對稱矩陣,b是一個向量。

硬件規格:英特爾i7 3630QM,GT640M 2G,8 GB DDR3。 軟件:Windows 8 64位,Matlab R2012b 64位,CUDA 5.0 64位,CUSP 0.3.1,Windows SDK v7.0,VS2010編譯器。

MEX代碼:

#include<cusp/csr_matrix.h>
#include <cusp/krylov/bicgstab.h>
#include <matrix.h>
#include <mex.h> 
#include <time.h>

void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
        double t1 =  clock();
          // data from Matlab       
        double *b = mxGetPr(prhs[1]);
        double *A = mxGetPr(prhs[0]);
        int n = mxGetM(prhs[0]);
        mwIndex *ir = mxGetIr(prhs[0]);
        mwIndex *jc = mxGetJc(prhs[0]);
        int N = jc[n];
        t1 = clock() - t1;

        double t2 =  clock();
          // initialization of matrix A in CSR format (jc and ir are exchanged, because Matlab uses CSC format
        cusp::csr_matrix<int,float,cusp::device_memory> Ag(n,n,3*n-2);
        thrust::copy(jc, jc + n + 1, Ag.row_offsets.begin());
        thrust::copy(ir, ir + N,     Ag.column_indices.begin());
        thrust::copy(A,  A  + N,     Ag.values.begin()); 
          // initialization of vector b
        cusp::array1d<float, cusp::device_memory> bg (b, b+n);
        cusp::array1d<float, cusp::device_memory> xg (n, 0);
        t2 = clock() - t2;

        double t3 =  clock();
          // bicgstab algorithm solution for vector x, when using 0.001 accuracy and precondition M
          // this is the slowest part, much slower than others
        cusp::verbose_monitor<float> monitor(bg, 5000, 1e-3);
        cusp::identity_operator<float, cusp::device_memory> M(n, n);
        cusp::krylov::bicgstab(Ag, xg, bg, monitor, M);        
        t3 = clock() - t3;

        double t4 =  clock();     
          // gathering solution vector bact on host to Matlab array T
        mxArray *T = mxCreateDoubleMatrix(n, 1, mxREAL);
        double *x  = mxGetPr(T);
        thrust::copy(xg.begin(), xg.end(), x);
        t4 = clock() - t4;

          // gathering execution times to Matlab array times
        mxArray *times=mxCreateDoubleMatrix(5, 1, mxREAL);
        double *timesb=mxGetPr(times);
        timesb[0]=t1; timesb[1]=t2; timesb[2]=t3; timesb[3]=t4; timesb[4]=monitor.iteration_count();

          // sending data back to Matlab
        plhs[0] = times; 
        plhs[1] = T;
} 

使用以下命令在Matlab的MEX文件(ex.cu)中編譯此代碼(如有必要,將第二個命令更改為32位):

>> !nvcc -c -arch sm_20 ex.cu -Xcompiler -fPIC -I "C:\Program Files\MATLAB\R2012b\extern\include" -I "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include
>> mex ex.obj -L"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.0\lib\x64" -lcudart

樣本矩陣,向量和已編譯的64位MEX函數: http : //www.failai.lt/3fqkhvoslxyt/sampleData.7z.htm

采用:

tic; [times,x]=ex(K',F); toc;   %K has to be transposed for CSR

其中,時間-單獨的執行時間,最后一個元素-用於解決方案的迭代次數(bicgstab監視器),結果-K * x = F的解決方案。

結果( http://www.failai.lt/rupaliln7kfb/results.7z.htm ):

  • K_int_6,F_int_6-好
  • K_11,F_11-x(1)錯誤,其他還可以
  • K_100000,F_100000-x(1)錯誤,其他開頭都可以,但后來與正確結果相比有所減少。
  • K_100000,F_100000-GPU(MEX)上的執行持續0.6 s,而CPU( tic; xcpu = K \\ F; toc; )上的執行持續0.014 s。

您能否看一下這些代碼,或者嘗試使用MEX函數,報告您的結果,並提出如何改進該函數的建議? 也許您知道可以在GPU上進行稀疏計算的任何替代方法? 我希望,這對每個人都將有用,直到Matlab在GPU上發布對稀疏矩陣的兼容性為止:)

看看Matlab文件交換,適用於gpus的cusp稀疏類,對單精度,實/復雜的支持: http : //www.mathworks.com/matlabcentral/fileexchange/44423-gpu-sparse-accumarray-non-uniform-grid

稀疏矩陣向量乘法因CUSP而過載。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM