2013-05-30 25 views
0

所以在一些代码的CPU版本的那一刻,我有一个类似如下的东西:如何在GPU上使用CULA 3D矩阵?

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上,因为它们不会改变,但我不知道该怎么做。或者我可以如何在一般情况下存储数组,以便这是可能的..

我已经在网上看到有关使用3D矩阵与CUDA的各种事情,但他们似乎不太适用于能够然后进行CULA函数的函数调用秒。

无论如何..我真的不知道最好的方式去做这件事,任何人有任何想法?

好,在回答下面的例子中,我有这样的:

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


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

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

} 

我在那里宣布双** GlobalFVecs_d是一个全球性的..但我得到一个赛格故障,当它击中行

err = cudaMalloc((void **) &(GlobalFVecs_d[i]), numcoeff*numcoeff*sizeof(double)); 

但它似乎正是在另一个例子中是什么?

EDIT2:

好吧,我意识到这是不一样的,所以我现在已经编译,用代码:

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); 
} 

它在这里seg错误,而不是如何获取数据?

+0

你解决了吗? – KiaMorot

回答

0
  1. 分配内存BcudaMalloc()
  2. 从主机复制到设备与cudaMemcpy()
  3. 传递设备指针在内核参数列表

最后,你用用它从内核你已经通过的论点! 例如:

1  // Kernel definition, see also section 4.2.3 of Nvidia Cuda Programming Guide 
    2  __global__ void vecAdd(float* A, float* B, float* C) 
    3  { 
    4  // threadIdx.x is a built-in variable provided by CUDA at runtime 
    5  int i = threadIdx.x; 
    6  A[i]=0; 
    7  B[i]=i; 
    8  C[i] = A[i] + B[i]; 
    9  } 
    10  
    11  #include <stdio.h> 
    12  #define SIZE 10 
    13  int main() 
    14  { 
    15   int N=SIZE; 
    16   float A[SIZE], B[SIZE], C[SIZE]; 
    17   float *devPtrA; 
    18   float *devPtrB; 
    19   float *devPtrC; 
    20   int memsize= SIZE * sizeof(float); 
    21  
    22   **cudaMalloc((void**)&devPtrA, memsize);** 
    23   cudaMalloc((void**)&devPtrB, memsize); 
    24   cudaMalloc((void**)&devPtrC, memsize); 
    25   **cudaMemcpy(devPtrA, A, memsize, cudaMemcpyHostToDevice);** 
    26   cudaMemcpy(devPtrB, B, memsize, cudaMemcpyHostToDevice); 
    27   // __global__ functions are called: Func<<< Dg, Db, Ns >>>(parameter); 
    28   **vecAdd<<<1, N>>>(devPtrA, devPtrB, devPtrC);** 
    29   cudaMemcpy(C, devPtrC, memsize, cudaMemcpyDeviceToHost); 
    30  
    31   for (int i=0; i<SIZE; i++) 
    32   printf("C[%d]=%f\n",i,C[i]); 
    33  
    34   cudaFree(devPtrA); 
    35   cudaFree(devPtrA); 
    36   cudaFree(devPtrA); 
    37  } 

**区域是您的重要部分。取自here的示例。你可能想看看this的问题。

编辑#1: 首先声明一个内核函数,您需要在返回类型之前放置关键字__global__

__global__ void copyFNFVecs_(double **FNFVecs, int numpulsars, int numcoeff)

此外,我只用一个指针指向矩阵的第一个元素。

double *devPtr

cudaMalloc((void*)&devPtr, size)

分配,然后复制

cudaMemcpy(devPtr, hostPtr, size, hostToDevice)

请注意,要计算结构的大小,您需要尺寸(例如X和Y)以及基础元素类型(例如double)的大小。

size_t size = X*Y*sizeof(double)

sizeof(double *)意味着指针的大小为双这是不正确(在32位机器上的指针的大小是4个字节,但两倍的大小是8个字节)。

+0

嗨,感谢您的回复,我将不得不在后续答案中发帖,一会儿 – LindleyLentati