C语言 为什么 malloc() 和 calloc() 在使用 CUDA 时似乎不起作用



在 CUDA 中使用时,使用 malloc()/calloc() 的动态内存分配似乎无法正常工作。

至于检查,我使用 calloc() 编写了以下代码。数组似乎分配了所需的内存,我也可以分配一些值。但是当我从内核打印矩阵元素时,我只能看到垃圾值。我认为这可能是cudaMemcpy()的问题,但是,而不是**A,如果我说,A[5][5],代码工作完美。

memset()使用会导致"核心转储"错误。

任何人都可以帮助与malloc()/calloc()相处而没有错误吗?

#include<stdio.h>
__global__ void threads(int* dA)
{
 int gi=threadIdx.x+(blockIdx.x*blockDim.x);
 int gj=threadIdx.y+(blockIdx.y*blockDim.y);
 printf("global Id in X= %d, in Y =%d, E= %dn", gi,gj,dA[gi*5+gj]);
}
int main(int argc, char** argv)
{
 int **A, *dA;
 int R=5, C=4;
 int size=R*C*sizeof(int);
 A=(int **)calloc(R, sizeof(int*));
 for(int i=0; i<R; i++)
    A[i]=(int *)calloc(C, sizeof(int));
// memset(A, 0, size);
 for(int i=0; i<R; i++)
   {
   for(int j=0; j<C; j++)
      A[i][j]=i*C+j;
   }
printf(" n Before n");
for(int i=0; i<R; i++)
   {
    for(int j=0; j<C; j++)
        printf("%d ",A[i][j]);
    printf("n");
   }
cudaMalloc((int**) &dA, size);
cudaMemcpy(dA, A, size, cudaMemcpyHostToDevice);
dim3 nblocks(R,C);
dim3 nthreads(1);
threads<<<nblocks, nthreads>>>(dA);
cudaDeviceSynchronize();
cudaFree(dA);
free(A);
return 0;
}

代码的问题与主机函数malloccalloc的使用无关。问题是您没有正确处理双指针以及它们如何传递给 CUDA 内核。正如Robert Crovella所指出的,适当的错误检查可以让您更好地了解实现中缺少的内容。

下面是您的程序的工作版本。它只不过是 cuda 2D 阵列问题中 talonmies 提供的答案的应用。

#include<stdio.h>
#include<conio.h>
inline void GPUassert(cudaError_t code, char * file, int line, bool Abort=true)
{
    if (code != 0) {
        fprintf(stderr, "GPUassert: %s %s %dn", cudaGetErrorString(code),file,line);
        if (Abort) exit(code);
    }       
}
#define GPUerrchk(ans) { GPUassert((ans), __FILE__, __LINE__); }
__global__ void threads(int* dA[]) {
    int gi=blockIdx.x;
    int gj=blockIdx.y;
    printf("global Id in X= %i, in Y =%i, E= %in", gi, gj, dA[gi][gj]);
}
int main(int argc, char** argv)
{
    int **A, *dA;
    int R=5, C=4;
    int size=R*C*sizeof(int);
    A=(int**)calloc(R,sizeof(int*));
    for(int i=0; i<R; i++) A[i]=(int*)calloc(C,sizeof(int));
    for(int i=0; i<R; i++) for(int j=0; j<C; j++) A[i][j]=i*C+j;
    printf("Before transfer n");
    for(int i=0; i<R; i++) { for(int j=0; j<C; j++) { printf("%d ",A[i][j]); } printf("n"); }
    printf("n");
    // --- Create an array of R pointers on the host
    int** h_A = (int**)malloc(R*sizeof(int*));
    for(int i=0; i<R;i++){
        // --- For each array pointer, allocate space for C ints on the device
        GPUerrchk(cudaMalloc((void**)&h_A[i], C*sizeof(int)));
        // --- Copy the rows of A from host to device at the address determined by h_A[i]
        GPUerrchk(cudaMemcpy(h_A[i], &A[i][0], C*sizeof(int), cudaMemcpyHostToDevice));
    }
    // --- Create an array of R pointers on the device
    int **d_A; GPUerrchk(cudaMalloc((void***)&d_A, R*sizeof(int*)));
    // --- Copy the addresses of the rows of the device matrix from host to device
    GPUerrchk(cudaMemcpy(d_A, h_A, R*sizeof(int*), cudaMemcpyHostToDevice));
    dim3 nblocks(R,C);
    dim3 nthreads(1);
    printf("After transfer n");
    threads<<<nblocks, nthreads>>>(d_A);
    GPUerrchk(cudaPeekAtLastError());
    cudaDeviceSynchronize();
    getch();
    return 0;
}

正如 cuda 2D 数组问题中也强调的那样,最好将 2D 数组展平为 1D 以避免这种繁琐的数组处理。

相关内容

  • 没有找到相关文章

最新更新