设置内核参数时使用CL_INVALID_ARG_SIZE

CL_INVALID_ARG_SIZE when setting kernel arg

本文关键字:INVALID ARG SIZE CL 内核 参数 设置      更新时间:2023-10-16

我正在尝试脱离CUDA,学习OpenCL。我认为n体模拟可能是一个很好的开始。我一直在使用c++包装器,并遵循这里提供的教程来了解应该如何工作。

该程序加载2个源文件,每个内核函数一个。每一个都经过编译,并构建到一个单独的内核中。在我第一次尝试时,它们在同一个内核中。这是试图通过采取不同的措施来解决问题。

nbs_forces.cl

typedef struct body_t {
...
};
__kernel void execute(__global struct body_t* bodies, const float G, const int n){
...
}

nbs_positions.cl

typedef struct body_t {
...
};
__kernel void execute(__global struct body_t* bodies, const float dt, const int n){
...
}

缓冲区分配如下:

// create memory buffers
bGravity = new cl::Buffer(*context, CL_MEM_READ_ONLY, sizeof(float));
bBodies = new cl::Buffer(*context, CL_MEM_READ_WRITE,
capacity * sizeof(body_t));
bTimestep = new cl::Buffer(*context, CL_MEM_READ_ONLY, sizeof(float));
bSize = new cl::Buffer(*context, CL_MEM_READ_ONLY, sizeof(int));

在数据被复制到缓冲区后,到了运行模拟的时候,我将内核参数设置为:

fKernel->setArg(0, *bBodies);
fKernel->setArg(1, *bGravity);
fKernel->setArg(2, *bSize);
pKernel->setArg(0, *bBodies);
pKernel->setArg(1, *bTimestep);
pKernel->setArg(2, *bSize);
cl::NDRange global(capacity);
cl::NDRange local(1);
for (int step = 0; step < steps; step++) {
queue->enqueueNDRangeKernel(*fKernel, cl::NullRange, global, local);
queue->enqueueNDRangeKernel(*pKernel, cl::NullRange, global, local);
}

但在执行模拟函数的第二行(setKernelArg(1,*bGravity((时,程序以CL_INVALID_ARG_SIZE终止。这似乎应该是一个微不足道的错误来解决,但尽管我尽了最大努力,我似乎找不到任何会导致它的原因

我尝试过传递不同的数据类型,包括opencl提供的类型(cl_float等(,但问题仍然存在。我确信我只是做了一些愚蠢的事,但在过去的几天里,我一直在用头撞墙,但无济于事。

在我试图保持这篇文章简短的过程中,如果有任何我忽略了包含的关键代码,所有内容都可以在这里的git repo上找到。

内核的预期参数之间不匹配:

__kernel void execute(__global struct body_t* bodies, const float G, const int n)

(包含struct body_t和2个标量值的数组的缓冲器(

以及你实际传递给它的信息:

bGravity = new cl::Buffer(*context, CL_MEM_READ_ONLY, sizeof(float));
bBodies = new cl::Buffer(*context, CL_MEM_READ_WRITE,
capacity * sizeof(body_t));
…
bSize = new cl::Buffer(*context, CL_MEM_READ_ONLY, sizeof(int));
…
fKernel->setArg(0, *bBodies);
fKernel->setArg(1, *bGravity);
fKernel->setArg(2, *bSize);

CCD_ 2和CCD_。相反,以下方法应该起作用:

const float gravity = …;
const int32_t size = …;
fKernel->setArg(1, gravity);
fKernel->setArg(2, size);