【问题标题】:cuda "invalid argument" error on second kernel第二个内核上的cuda“无效参数”错误
【发布时间】:2012-12-22 22:02:43
【问题描述】:

我遇到了内核启动问题。我有一个使用一个大内核的程序。由于同步问题,现在我需要将其分成两部分。第一个内核做了一些初始化工作,并获得了传递给第二个内核的参数子集。只运行第一个内核工作正常。由于缺少初始化,仅运行第二个内核在执行时失败,但内核本身已启动。连续运行这两个内核会使第二个内核因“无效参数”错误而失败。如有必要,我将提供代码,但现在无法弄清楚它可能有什么帮助。提前致谢。

编辑: 这里是请求的启动代码:

void DeviceManager::integrate(){
  assert(hostArgs->neighborhoodsSize > 0);
  size_t maxBlockSize;
  size_t blocks;
  size_t threadsPerBlock;
  // init patch kernel
  maxBlockSize = 64;
  blocks = (hostArgs->patchesSize /maxBlockSize);
  if(0 != hostArgs->patchesSize % maxBlockSize){
    blocks++;
  }
  threadsPerBlock = maxBlockSize;
  std::cout << "blocks: " << blocks << ", threadsPerBlock: " << threadsPerBlock << std::endl;
  initPatchKernel<CUDA_MAX_SPACE_DIMENSION><<<blocks,threadsPerBlock>>>(devicePatches, hostArgs->patchesSize);
  cudaDeviceSynchronize();

  //calc kernel
  maxBlockSize = 64;
  blocks = (hostArgs->neighborhoodsSize /maxBlockSize);
  if(0 != hostArgs->neighborhoodsSize % maxBlockSize){
    blocks++;
  }
  threadsPerBlock = maxBlockSize;
  size_t maxHeapSize = hostArgs->patchesSize * (sizeof(LegendreSpace) + sizeof(LinearSpline)) + hostArgs->neighborhoodsSize * (sizeof(ReactionDiffusionCCLinearForm) + sizeof(ReactionDiffusionCCBiLinearForm));
  std::cout << "maxHeapSize: " << maxHeapSize << std::endl;
  cudaDeviceSetLimit(cudaLimitMallocHeapSize, maxHeapSize);
  std::cout << "blocks: " << blocks << ", threadsPerBlock: " << threadsPerBlock << std::endl;
  integrateKernel<CUDA_MAX_SPACE_DIMENSION><<<blocks,threadsPerBlock>>>(deviceNeighborhoods, hostArgs->neighborhoodsSize, devicePatches, hostArgs->patchesSize, hostArgs->biLinearForms, hostArgs->linearForms, deviceRes);
  cudaDeviceSynchronize();
}

内存传输和分配应该不是问题,因为它在只使用一个内核时工作。

编辑 2: 通过包装函数在调试模式下构建时,我会在每次内核调用后检查错误。所以在每次内核调用之后都会执行以下操作:

cudaError_t cuda_result_code = cudaGetLastError();                        
if (cuda_result_code!=cudaSuccess) {                                      
   fprintf("message: %s\n",cudaGetErrorString(cuda_result_code));
}

很抱歉没有提到这一点,包装器不是我的,很抱歉没有粘贴这个技巧。 失败前的输出如下:

blocks: 1, threadsPerBlock: 64
maxHeapSize: 4480
blocks: 1, threadsPerBlock: 64
message: invalid argument

【问题讨论】:

  • 我确信提供您的代码会有所帮助。特别是我对您的第二次内核调用的启动参数以及它们是如何派生的感兴趣。
  • 至少给我们看看你的内存初始化和内核调用代码..
  • 我没有看到任何错误检查。你怎么知道你的内核因“无效参数错误”而失败?此外,在两个内核启动之前,您正在输出 blocks 和 threadsPerBlock 变量。在失败之前你得到了什么输出?
  • 请不要在启动后向所有 cuda* 函数添加错误处理。我已经提交了一个我认为可以解决您的问题的答案。

标签: cuda


【解决方案1】:

cudaDeviceSetLimit

cudaLimitMallocHeapSize 控制 malloc() 和 free() 设备系统调用使用的堆的大小(以字节为单位)。必须在启动任何使用 malloc() 或 free() 设备系统调用的内核之前执行设置 cudaLimitMallocHeapSize,否则将返回 cudaErrorInvalidValue。此限制仅适用于计算能力 2.0 及更高版本的设备。尝试在计算能力小于 2.0 的设备上设置此限制将导致返回错误 cudaErrorUnsupportedLimit。

【讨论】:

  • 非常感谢您的回答。当我有时间可能会持续几天时,我会尝试你的建议,对此感到抱歉。
  • 现在我有时间检查我的代码并牢记您的答案。我的内存分配设计中有不同的错误。我现在首先调用 cudaDeviceSetLimit(得到一张计算能力为 2.0 的卡)而不是内核来初始化一些内存。比主内核(integrateKernel)自行分配和释放一些内存。最后是一个新内核来释放由 init 内核初始化的内存(我忘了这样做)。现在一切正常。再次非常感谢您的回答,您真的让我摆脱了困境。
猜你喜欢
  • 2016-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多