cudaMalloc全局数组导致seg错误

时间:2013-06-05 01:07:57

标签: cuda

当我尝试从设备执行的函数访问全局数组时发现了一些困难:

float globTemp[3][3] = "some value in here";
__device__ float* globTemp_d;

__global__ void compute(int *a, int w)
{
  int x = threadIdx.x + blockDim.x * blockIdx.x;
  int y = threadIdx.y + blockDim.y * blockIdx.y;
  int i = y*w+x;
  if(x<3 && y<3)
    a[i] = 1+globTemp_d[i];
}

int hostFunc(){
   float *a_d;
   cudaMalloc((void**)&a_d, 3*3*sizeof(int));
   cudaMalloc((void**)&globTemp_d, 3*3*sizeof(int));
   cudaMemcpy(globTemp_d,globTemp, 3*3*sizeof(float), cudaMemcpyHostToDevice);
   compute<<<1,1>>>(a_d,3);
   cudaMemcpy(a,a_d, 3*3*sizeof(float), cudaMemcpyDeviceToHost);
}

但是,当我尝试访问globTemp_d [i]时,我遇到了seg错误。我在这里做错了吗?

1 个答案:

答案 0 :(得分:1)

您的代码存在各种问题:

  1. 您的网格是1D线程块的1D网格(实际上您正在启动单个1个线程的块)但是您的内核被编写为好像它期望2D线程块结构(使用.x和{{1内置变量)。单个线程肯定无法完成工作,并且一维线程块将无法与您的内核代码一起使用。
  2. .y变量为not accessed __device__cudaMalloc。我们使用了一组不同的API调用,例如cudaMemcpy
  3. 你没有做任何cuda error checking,当你遇到困难时,总会被推荐。你应该对API调用内核调用进行cuda错误检查。
  4. 您在内核参数(cudaMemcpyToSymbol)中混合了float个变量(a_d)和int个变量,所以我不认为这个代码会在没有编译的情况下编译至少是警告。如果忽略它,那当然会导致奇怪的行为。
  5. 这是我在修复所有错误时最接近您的代码的地方:

    int *a

    通过省略#include <stdio.h> __device__ float* globTemp_d; __global__ void compute(float *a, int w) { int x = threadIdx.x + blockDim.x * blockIdx.x; int y = threadIdx.y + blockDim.y * blockIdx.y; int i = (y*w)+x; if((x<3) && (y<3)) a[i] = 1.0f+globTemp_d[i]; } int main(){ float *a_d, *d_globTemp; float globTemp[3][3] = {0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f}; float a[(3*3)]; dim3 threads(3,3); dim3 blocks(1); cudaMalloc((void**)&a_d, 3*3*sizeof(float)); cudaMalloc((void**)&d_globTemp, 3*3*sizeof(float)); cudaMemcpy(d_globTemp,globTemp, 3*3*sizeof(float), cudaMemcpyHostToDevice); cudaMemcpyToSymbol(globTemp_d, &d_globTemp, sizeof(float *)); compute<<<blocks,threads>>>(a_d,3); cudaMemcpy(a,a_d, 3*3*sizeof(float), cudaMemcpyDeviceToHost); printf("results:\n"); for (int i = 0; i<(3*3); i++) printf("a[%d] = %f\n", i, a[i]); return 0; } 变量并将__device__作为参数传递给内核,并使用它代替对d_globTemp的引用,可以简化此代码。但是我并没有简化这一点。