簡體   English   中英

訪問指向GPU上其他向量的指針的向量

[英]Access vector of pointers to other vectors on a GPU

因此,這是對我所提出問題的跟進,目前在某些代碼的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]將是某個大小的2D矩陣。

我希望能夠在使用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預先存儲,因為B不變,所以我需要一個向量,該向量包含指向構成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函數,則可以對大型連續向量進行切片,但是我不知道它是否支持。

干杯林德利

改變這個:

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錯誤發生在內核設置代碼中,而不是內核本身。

暫無
暫無

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

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