首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在GPU上使用3D矩阵和CULA?

如何在GPU上使用3D矩阵和CULA?
EN

Stack Overflow用户
提问于 2013-05-30 22:10:31
回答 1查看 181关注 0票数 1

在一些代码的CPU版本中,我有许多类似于以下内容的东西:

代码语言:javascript
复制
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矩阵。

我希望能够在GPU上使用CULA (我不仅仅是做乘法,所以我需要在CULA中使用线性ALgebra操作),例如:

代码语言:javascript
复制
 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上,因为它们不会改变,但我不知道如何去做。或者我如何存储我的数组,以便这是可能的。

关于在CUDA中使用3D矩阵,我在网上看到了各种各样的东西,但它们似乎不太适用于能够对CULA函数进行函数调用。

从下面答案中的示例中,我得到了以下内容:

代码语言:javascript
复制
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); 
        }

}

其中我已经声明了double **GlobalFVecs_d是全局的。但是当它命中线路时,我得到了一个seg错误

代码语言:javascript
复制
 err = cudaMalloc( (void **) &(GlobalFVecs_d[i]), numcoeff*numcoeff*sizeof(double) );

然而,这似乎就是另一个示例中的确切内容?

我意识到这是不一样的,所以我现在有了编译的代码,用:

代码语言:javascript
复制
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);

}

但是,如果我现在尝试使用以下命令访问它:

代码语言:javascript
复制
 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);
 }

相反,它在这里出现了故障,这不是获取数据的方法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-05-30 22:20:31

使用cudaMalloc()

  • Copy it从主机到设备使用cudaMemcpy()

  • Pass内核参数列表中的设备指针

为内核分配内存

最后,您可以在内核中通过您传递的参数使用它!示例:

代码语言:javascript
复制
  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的问题。

EDIT#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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16838487

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档