- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试脱离 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);
G
和 n
不应作为缓冲区传递。相反,以下应该可以解决问题:
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/
我正在尝试脱离 CUDA 并学习 OpenCL。我认为 n 体模拟可能是一个不错的起点。我一直在使用 c++ 包装器,并遵循提供的教程 here了解事情应该如何运作的基本概念。 程序加载 2 个源文件
我是 OpenCL 的新手。我试图将 5 个参数传递给内核:一个输入缓冲区、一个输出缓冲区、一个整数和 2 个输入缓冲区大小的局部数组。 //Create input/output cl_mem ob
我是一名优秀的程序员,十分优秀!