繁体   English   中英

CUDA矩阵加法段故障

[英]CUDA Matrix Addition Seg faults

我只是有一个关于我编写的cuda程序的问题。 它允许我输入矩阵,列和行的大小。 假设我输入了〜1124,它计算得很好。 但是说我输入1149,它会在设备中的计算后出现段故障(我认为这是在回写期间出现段故障)。 但是说我输入2000会在设备中进行计算之前发生段错误(我认为复制期间会出现段错误)。 我认为我的问题全部与内存管理有关。 如果你们能指出正确的方向,我将不胜感激。

我在代码中加上了如何调用它。 在新的编辑中(在底部),它包含:sumMatrix(具有eleCount1的大小的空白矩阵,它是整个矩阵的大小),matrixOne(第一个矩阵),matrixTwo(第二个矩阵,以与matrix1相同的方式分配) ,eleCount1(整个矩阵的大小)。 从文件中读取了matrixOne和两个。

不确定是否有人需要查看有关我的GPU的这些信息:

  • 恒定内存总量:65536字节
  • 每个块的共享内存总数:49152字节
  • 每个块可用的寄存器总数:32768
  • 经纱尺寸:32
  • 每个块的最大线程数:1024
  • 块的每个尺寸的最大大小:1024 x 1024 x 64
  • 网格每个尺寸的最大大小:65535 x 65535 x 65535

代码是:

void addKernel(float *c, float *a, float *b)
{
    int i = threadIdx.x;
    int idx = blockDim.x * blockIdx.x + threadIdx.x;
    c[idx] = a[idx] + b[idx];
}
cudaError_t addWithCuda(float *c, float *a, float *b, size_t size)
{
  float *dev_a = 0;
  float *dev_b = 0;
  float *dev_c = 0;
  cudaError_t cudaStatus;
  blocksNeeded=(size/MAXTHREADS)+1;
  int threadsPerBlock = MAXTHREADS/blocksNeeded+1;
  cudaStatus = cudaMalloc((void**)&dev_c, size * sizeof(float));
  if (cudaStatus != cudaSuccess) {
      fprintf(stderr, "cudaMalloc failed!");
      goto Error;
  }

  cudaStatus = cudaMalloc((void**)&dev_a, size * sizeof(float));
  if (cudaStatus != cudaSuccess) {
      fprintf(stderr, "cudaMalloc failed!");
      goto Error;
  }

  cudaStatus = cudaMalloc((void**)&dev_b, size * sizeof(float));
  if (cudaStatus != cudaSuccess) {
      fprintf(stderr, "cudaMalloc failed!");
      goto Error;
  }

  cudaStatus = cudaMemcpy(dev_a, a, size * sizeof(float), cudaMemcpyHostToDevice);
  if (cudaStatus != cudaSuccess) {
      fprintf(stderr, "cudaMemcpy failed!");
      goto Error;
  }

  cudaStatus = cudaMemcpy(dev_b, b, size * sizeof(float), cudaMemcpyHostToDevice);
  if (cudaStatus != cudaSuccess) {
      fprintf(stderr, "cudaMemcpy failed!");
      goto Error;
  }

  addKernel<<<blocksNeeded, size>>>(dev_c, dev_a, dev_b);
  cudaStatus = cudaDeviceSynchronize();

  if (cudaStatus != cudaSuccess) {
      fprintf(stderr, "cudaDeviceSynchronize returned error code %d after launching addKernel!\n", cudaStatus);
      goto Error;
  }
  cudaStatus = cudaMemcpy(c, dev_c, size * sizeof(float), cudaMemcpyDeviceToHost);
  if (cudaStatus != cudaSuccess) {
      fprintf(stderr, "cudaMemcpy failed!");
      goto Error;
  }

Error:
  cudaFree(dev_c);
  cudaFree(dev_a);
  cudaFree(dev_b);

  return cudaStatus;
}
//edit: added how the matrix are allocated
    float* matrixOne = (float*)malloc(sizeof(float)*file1size);
int matrixIndex = 0;
readFromFile(fd,byte, matrixOneWidth, matrixOneHeight,  matrixOne);

//matrixOneHeight--;
eleCount1 = matrixOneHeight*matrixOneWidth;
matrixOne= (float*)realloc(matrixOne,eleCount1*sizeof(float));
//Edit: Added how the addWithCuda is called.
cudaStatus = addWithCuda(sumMatrix, matrixOne,matrixTwo,eleCount1);
//sumMatrix is created after we know how large the matrices are. 
float sumMatrix[eleCount1];

您没有在内核中测试计算的界限。 如果总工作量未平均分配到块的大小,则某些线程将尝试写入输出数组之外的索引。 我建议您还将大小作为参数传递给内核,并引入检查:

__global__ void addKernel(float *c, float *a, float *b, int size)
{
    int i = threadIdx.x;
    int idx = blockDim.x * blockIdx.x + threadIdx.x;
    if(idx < size) c[idx] = a[idx] + b[idx];
}

我看到您正在索引内核中的数组a,b和c,但是您没有检查以确保索引在数组范围内。 因此,您正在写入您不拥有的内存,从而在随机位置导致段错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM