在一些代码的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矩阵。
我希望能够在GPU上使用CULA (我不仅仅是做乘法,所以我需要在CULA中使用线性ALgebra操作),例如:
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函数进行函数调用。
从下面答案中的示例中,我得到了以下内容:
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错误
err = cudaMalloc( (void **) &(GlobalFVecs_d[i]), numcoeff*numcoeff*sizeof(double) );然而,这似乎就是另一个示例中的确切内容?
我意识到这是不一样的,所以我现在有了编译的代码,用:
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);
}相反,它在这里出现了故障,这不是获取数据的方法吗?
发布于 2013-05-30 22:20:31
使用cudaMalloc()
cudaMemcpy()
为内核分配内存
最后,您可以在内核中通过您传递的参数使用它!示例:
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字节)。
https://stackoverflow.com/questions/16838487
复制相似问题