gpt4 book ai didi

c++ - 设置内核 arg 时的 CL_INVALID_ARG_SIZE

转载 作者:行者123 更新时间:2023-11-30 04:42:05 25 4
gpt4 key购买 nike

我正在尝试脱离 CUDA 并学习 OpenCL。我认为 n 体模拟可能是一个不错的起点。我一直在使用 c++ 包装器,并遵循提供的教程 here了解事情应该如何运作的基本概念。

程序加载 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 here 上找到。 .

最佳答案

您的内核预期参数不匹配:

__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);

Gn 不应作为缓冲区传递。相反,以下应该可以解决问题:

const float gravity = …;
const int32_t size = …;

fKernel->setArg(1, gravity);
fKernel->setArg(2, size);

关于c++ - 设置内核 arg 时的 CL_INVALID_ARG_SIZE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58915361/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com