Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ CUDA矩阵加法Seg故障_C++_C_Nvidia_Cuda - Fatal编程技术网

C++ CUDA矩阵加法Seg故障

C++ CUDA矩阵加法Seg故障,c++,c,nvidia,cuda,C++,C,Nvidia,Cuda,我只是对我写的cuda程序有个问题。它允许我输入矩阵、列和行的大小。假设我输入~1124,它计算为罚款。但是,假设我在设备中计算后输入1149 it Seg faults(我认为是在复制过程中出现Seg故障)。但假设我在设备中计算之前输入2000个it seg故障(我认为在复制过程中it seg故障)。我想我的问题是内存管理。如果你们能给我指出正确的方向,我会很感激的 我对代码的调用方式进行了分析。在新编辑中(在底部),它包含:sumMatrix(大小为eleCount1的空白矩阵,即整个矩阵的

我只是对我写的cuda程序有个问题。它允许我输入矩阵、列和行的大小。假设我输入~1124,它计算为罚款。但是,假设我在设备中计算后输入1149 it Seg faults(我认为是在复制过程中出现Seg故障)。但假设我在设备中计算之前输入2000个it seg故障(我认为在复制过程中it seg故障)。我想我的问题是内存管理。如果你们能给我指出正确的方向,我会很感激的

我对代码的调用方式进行了分析。在新编辑中(在底部),它包含:sumMatrix(大小为eleCount1的空白矩阵,即整个矩阵的大小)、matrixOne(第一个矩阵)、matrixTwo(第二个矩阵,分配方式与matrix1相同)、eleCount1(矩阵的整个大小)。matrixOne和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];
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];
}
CUDA错误添加CUDA(浮点*c、浮点*a、浮点*b、大小)
{
浮动*dev_a=0;
浮动*dev_b=0;
浮点数*dev_c=0;
cudaError\u t cudaStatus;
BlocksNeed=(大小/最大线程数)+1;
int threadsPerBlock=MAXTHREADS/BlocksNeed+1;
cudaStatus=cudaMalloc((无效**)和dev_c,尺寸*尺寸(浮动));
if(cudaStatus!=cudaSuccess){
fprintf(stderr,“cudamaloc失败!”);
转到错误;
}
cudaStatus=cudaMalloc((无效**)和dev_a,尺寸*尺寸(浮动));
if(cudaStatus!=cudaSuccess){
fprintf(stderr,“cudamaloc失败!”);
转到错误;
}
cudaStatus=cudaMalloc((无效**)和dev_b,尺寸*尺寸(浮动));
if(cudaStatus!=cudaSuccess){
fprintf(stderr,“cudamaloc失败!”);
转到错误;
}
cudaStatus=cudaMemcpy(dev_a,a,size*sizeof(float),cudaMemcpyHostToDevice);
if(cudaStatus!=cudaSuccess){
fprintf(stderr,“cudaMemcpy失败!”);
转到错误;
}
cudaStatus=cudaMemcpy(dev_b,b,size*sizeof(float),cudaMemcpyHostToDevice);
if(cudaStatus!=cudaSuccess){
fprintf(stderr,“cudaMemcpy失败!”);
转到错误;
}
addKernel(dev_c、dev_a、dev_b);
cudaStatus=cudaDeviceSynchronize();
if(cudaStatus!=cudaSuccess){
fprintf(stderr,“cudaDeviceSynchronize在启动addKernel!\n后返回错误代码%d”,cudaStatus);
转到错误;
}
cudaStatus=cudaMemcpy(c,dev_c,size*sizeof(float),cudaMemcpyDeviceToHost);
if(cudaStatus!=cudaSuccess){
fprintf(stderr,“cudaMemcpy失败!”);
转到错误;
}
错误:
cudaFree(开发中心);
cudaFree(dev_a);
cudaFree(dev_b);
返回CUDA状态;
}
//编辑:添加了矩阵的分配方式
float*matrixOne=(float*)malloc(sizeof(float)*file1size);
int-matrixIndex=0;
readFromFile(fd,byte,matrixOneWidth,matrixonehh,matrixOne);
//母性体重--;
eleCount1=矩阵高度*矩阵宽度;
matrixOne=(浮动*)realloc(matrixOne,eleCount1*浮动大小);
//编辑:添加了addWithCuda的调用方式。
CUDA状态=添加CUDA(sumMatrix、matrixOne、matrixTwo、eleCount1);
//求和矩阵是在我们知道矩阵有多大之后创建的。
浮点求和矩阵[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];
}
\uuuu全局\uuuu无效添加内核(float*c、float*a、float*b、int-size)
{
int i=threadIdx.x;
int idx=blockDim.x*blockIdx.x+threadIdx.x;
如果(idx
您没有在内核中测试计算的边界。如果总工作量不能平均分配到块的大小,则某些线程将尝试写入输出数组之外的索引。我建议您也将大小作为参数传递给内核,并引入检查:

__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];
}
\uuuu全局\uuuu无效添加内核(float*c、float*a、float*b、int-size)
{
int i=threadIdx.x;
int idx=blockDim.x*blockIdx.x+threadIdx.x;
如果(idx
我看到您正在为内核中的数组a、b和c编制索引,但您没有检查以确保索引在数组边界内。因此,您正在写入您不拥有的内存,导致随机位置出现seg错误。

我看到您正在为内核中的数组a、b和c编制索引,但您没有检查以确保索引在数组边界内。因此,您正在向内存中写入您不拥有的数据,导致随机位置出现seg故障。

这不会导致主机segfault,这就是报告的情况。他说segfault发生在随机位置。无论如何,这是值得一试的,因为这通常是cuda程序中出现SEGFULT的原因。对不起,但事实并非如此。GPU中的内存冲突会生成CUDA运行时错误(通常是未指定的启动错误),但不会生成主机内存保护错误。如果他得到一个SEGFULT,这意味着在主机内存中做了一些非法的事情。Talonmes是对的。CUDA有一个宽松的内存组织,在这里你几乎可以在GPU内存上做你想做的事情。最糟糕的情况是,如前所述,出现了一个未指定的启动错误。女巫可以