2013-05-31 77 views
0

所以這是一個後續的問題,我有,在一些代碼的CPU版本的那一刻,我有一個類似如下的東西:訪問向量

for(int i =0;i<N;i++){ 

    dgemm(A[i], B[i],C[i], Size[i][0], Size[i][1], Size[i][2], Size[i][3], 'N','T'); 

} 

其中A [i]將是一些尺寸的二維矩陣。

我希望能夠做到這一點,使用CULA一個GPU(我不只是在做乘法,所以我需要在CULA線性代數操作),因此,例如:

for(int i =0;i<N;i++){ 
     status = culaDeviceDgemm('T', 'N', Size[i][0], Size[i][0], Size[i][0], alpha, GlobalMat_d[i], Size[i][0], NG_d[i], Size[i][0], beta, GG_d[i], Size[i][0]); 
} 

但我希望在程序開始時將我的B存儲在GPU上,因爲它們不會改變,所以我需要一個包含指向組成我的B的向量集的指針的向量。

目前,我有以下代碼編譯:

double **GlobalFVecs_d; 
double **GlobalFPVecs_d; 

extern "C" void copyFNFVecs_(double **FNFVecs, int numpulsars, int numcoeff){ 


    cudaError_t err; 
    GlobalFPVecs_d = (double **)malloc(numpulsars * sizeof(double*)); 
err = cudaMalloc((void ***)&GlobalFVecs_d, numpulsars*sizeof(double*)); 
checkCudaError(err); 

    for(int i =0; i < numpulsars;i++){ 
     err = cudaMalloc((void **) &(GlobalFPVecs_d[i]), numcoeff*numcoeff*sizeof(double)); 
     checkCudaError(err);  
     err = cudaMemcpy(GlobalFPVecs_d[i], FNFVecs[i], sizeof(double)*numcoeff*numcoeff, cudaMemcpyHostToDevice); 
     checkCudaError(err); 
     } 

     err = cudaMemcpy(GlobalFVecs_d, GlobalFPVecs_d, sizeof(double*)*numpulsars, cudaMemcpyHostToDevice); 
     checkCudaError(err); 

} 

,但如果我現在試着和訪問它:

dim3 dimBlock(BLOCK_SIZE, BLOCK_SIZE); 
dim3 dimGrid;//((G + dimBlock.x - 1)/dimBlock.x,(N + dimBlock.y - 1)/dimBlock.y); 
dimGrid.x=(numcoeff + dimBlock.x - 1)/dimBlock.x; 
dimGrid.y = (numcoeff + dimBlock.y - 1)/dimBlock.y; 

for(int i =0; i < numpulsars; i++){ 
    CopyPPFNF<<<dimGrid, dimBlock>>>(PPFMVec_d, GlobalFVecs_d[i], numpulsars, numcoeff, i); 
} 

在這裏賽格故障,這是不如何在獲得數據?

那我打電話籽粒功能就是:

__global__ void CopyPPFNF(double *FNF_d, double *PPFNF_d, int numpulsars, int numcoeff, int thispulsar) { 

    // Each thread computes one element of C 
    // by accumulating results into Cvalue 




    int row = blockIdx.y * blockDim.y + threadIdx.y; 
    int col = blockIdx.x * blockDim.x + threadIdx.x; 

    int subrow=row-thispulsar*numcoeff; 
    int subcol=row-thispulsar*numcoeff; 

    __syncthreads(); 
    if(row >= (thispulsar+1)*numcoeff || col >= (thispulsar+1)*numcoeff) return; 
    if(row < thispulsar*numcoeff || col < thispulsar*numcoeff) return; 


    FNF_d[row * numpulsars*numcoeff + col] += PPFNF_d[subrow*numcoeff+subcol]; 

} 

什麼我不這樣做對嗎?注意,最後我還想做第一個例子,在每個GlobalFVecs_d [i]上調用cula函數,但現在甚至都不行。

您認爲這是做這件事的最好方法嗎?如果可以通過CULA函數,我可以做到這一點,但我不知道它是否支持。

乾杯 林德利

回答

0

改變這一點:

CopyPPFNF<<<dimGrid, dimBlock>>>(PPFMVec_d, GlobalFVecs_d[i], numpulsars, numcoeff, i); 

這樣:

CopyPPFNF<<<dimGrid, dimBlock>>>(PPFMVec_d, GlobalFPVecs_d[i], numpulsars, numcoeff, i); 

,我相信它會工作。

您的處理指針的方法大多是正確的。但是,如果將GlobalFVecs_d[i]放入參數列表中,則強制內核設置代碼(在主機上運行)執行GlobalFVecs_d(設備指針,使用cudaMalloc創建),將適當縮放的i添加到指針值,然後取消引用結果指針以檢索要作爲參數傳遞給內核的值。但我們不允許取消引用主機代碼中的設備指針。

但是,因爲你的方法主要是正確的,你可以很方便並行陣列駐留在主機上的同一指針。這個數組(GlobalFPVecs_d)是我們被允許在主機代碼中取消引用來檢索最終設備指針並傳遞給內核的東西。

這是一個有趣的錯誤,因爲通常內核不會分段錯誤(儘管它們可能會引發錯誤),所以內核調用行上的seg錯誤是不尋常的。但在這種情況下,Seg錯誤發生在內核設置代碼中,而不是內核本身。

+0

感謝你的工作,並沒有比我一直在做的事情快得多,它將一個大矩陣複製過來,然後爲循環的每次迭代創建單個矩陣,但代碼更清晰一些。 – LindleyLentati