1

我几乎完成了将一些 CUDA 代码重写为 OpenCL 的工作。但是我得到了这个可怕的运行时错误。

我调用的内核接受如下参数:

__kernel void kernel_forwardProject(
  __global float *proj_out,
  __gloabl float *proj_in,
  __global float *vol,
  __read_only image3d_t tex_vol,
  __constant float *transformMatrices,
  __constant float *sourcePositions)

我正在使用cl2.hppOpenCL 的包装器,当我调用clSetKernelArg参数 0 的等价物时,即proj_out返回CL_INVALID_MEM_OBJECT

切换参数 0 和 1 时,我也得到相同的结果。我尝试了三种分配设备缓冲区的方法:

// 1)
  auto dev_proj_out = cl::Buffer(queue, h_proj_out, h_proj_out + proj_size,
    /*read_only*/false, /*useHostPtr*/true, &err);
// 2)
  auto dev_proj_out = cl::Buffer(ctx, CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
    proj_size * sizeof(float), (void*)&h_proj_out[0], &err);
// 3)
  auto dev_proj_out = cl::Buffer(ctx, CL_MEM_WRITE_ONLY,
    req_dev_alloc, nullptr, &err);
  queue.enqueueWriteBuffer(dev_proj_out, CL_TRUE, 0, 0, (void *)&h_proj_out[0]);

h_proj_outfloat*proj_size64*64*16在测试用例中。我已经尝试了falseand truefor read_onlyand的所有 4 种组合useHostPtr

err在所有 OpenCL API 调用之后检查,之前没有错误clSetKernelArg

我已经用 gdb 逐步完成了所有组合的代码,它总是在clSetKernelArg第一个参数给出错误。

我已经尝试过NvidiaIntel CPU OpenCL 运行时。(POCL 不支持 nvidia gpus 的图像类型,所以我不能使用它)

主机代码可以在这里找到:https ://gitlab.com/agravgaard/cbctrecon/blob/master/Library/CbctReconLib/rtkExtension/rtkOpenCLForwardProjectionImageFilter.cpp#L130

OpenCL 内核: https ://gitlab.com/agravgaard/cbctrecon/blob/master/Library/CbctReconLib/rtkExtension/forward_proj.cl#L71 内核 使用英特尔 SDK for OpenCL 离线编译器编译,没有任何警告(具有相同的定义在运行时给出)。

错误发生在主机代码的第 247 行。KernelFunctor调用setArgs<>,它调用内核的 setArg,它在cl2.hpp 的第 5398 行调用 clSetKernelArg

4

1 回答 1

1

问题有两个部分来自混合设备、上下文和队列以及内核管理。

cl2.hpp如果没有给出,则使用默认设备、上下文和队列。因为我与上面示例中的默认值不一致,因此不同的队列和上下文“拥有”不同的对象。

CL_INVALID_MEM_OBJECT我最初是通过重写我管理内核的方式来摆脱的,包括添加:

program.createKernels(&kernel_list)

并使用该列表来初始化KernelFunctor.

于 2019-08-22T10:04:04.473 回答