为什么我从 `clSetKernelArg` 得到 `CL_INVALID_MEM_OBJECT`?
Why do I get `CL_INVALID_MEM_OBJECT` from `clSetKernelArg`?
我即将完成将一些 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)
我正在使用 OpenCL 的 cl2.hpp
包装器,当我为参数 0 调用 clSetKernelArg
的等价物时,即 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_out
在测试用例中是float*
,proj_size
是64*64*16
。
我已经为 read_only
和 useHostPtr
.
尝试了 false
和 true
的所有 4 种组合
我在所有 OpenCL API 调用之后检查 err
,在 clSetKernelArg
之前没有错误。
我已经使用 gdb 逐步完成所有组合的代码,第一个参数总是在 clSetKernelArg
处给出错误。
我已经尝试了两种 Nvidia and Intel CPU OpenCL 运行时。 (POCL 不支持 nvidia gpus 的图像类型,所以我不能使用它)
OpenCL 内核:
https://gitlab.com/agravgaard/cbctrecon/blob/master/Library/CbctReconLib/rtkExtension/forward_proj.cl#L71
内核使用面向 OpenCL 离线编译器的英特尔 SDK 进行编译,没有任何警告(与运行时给出的定义相同)。
错误发生在line 247 of the host code. The KernelFunctor calls setArgs<> which calls setArg of the kernel, which calls clSetKernelArg at line 5398 of cl2.hpp
问题有两个部分来自混合设备、上下文和队列以及内核管理。
如果给定 none,cl2.hpp
使用默认设备、上下文和队列。由于我与上面示例中的默认值不一致,因此不同的队列和上下文 "owned" 不同的对象。
我最初通过重写我管理内核的方式摆脱了 CL_INVALID_MEM_OBJECT
,包括添加:
program.createKernels(&kernel_list)
并使用该列表初始化 KernelFunctor
。
我即将完成将一些 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)
我正在使用 OpenCL 的 cl2.hpp
包装器,当我为参数 0 调用 clSetKernelArg
的等价物时,即 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_out
在测试用例中是float*
,proj_size
是64*64*16
。
我已经为 read_only
和 useHostPtr
.
false
和 true
的所有 4 种组合
我在所有 OpenCL API 调用之后检查 err
,在 clSetKernelArg
之前没有错误。
我已经使用 gdb 逐步完成所有组合的代码,第一个参数总是在 clSetKernelArg
处给出错误。
我已经尝试了两种 Nvidia and Intel CPU OpenCL 运行时。 (POCL 不支持 nvidia gpus 的图像类型,所以我不能使用它)
OpenCL 内核: https://gitlab.com/agravgaard/cbctrecon/blob/master/Library/CbctReconLib/rtkExtension/forward_proj.cl#L71 内核使用面向 OpenCL 离线编译器的英特尔 SDK 进行编译,没有任何警告(与运行时给出的定义相同)。
错误发生在line 247 of the host code. The KernelFunctor calls setArgs<> which calls setArg of the kernel, which calls clSetKernelArg at line 5398 of cl2.hpp
问题有两个部分来自混合设备、上下文和队列以及内核管理。
如果给定 none,cl2.hpp
使用默认设备、上下文和队列。由于我与上面示例中的默认值不一致,因此不同的队列和上下文 "owned" 不同的对象。
我最初通过重写我管理内核的方式摆脱了 CL_INVALID_MEM_OBJECT
,包括添加:
program.createKernels(&kernel_list)
并使用该列表初始化 KernelFunctor
。