OpenCL global_work_size不反映返回的实际 ID
OpenCL global_work_size does not reflect actual ids returned
我对OpenCL很陌生,我似乎对我在OpenCL C++中使用enqueueNDRangeKernel设置的global_work_size的含义感到困惑。
我的问题如下:
我必须使用内核文件中的以下代码初始化矩阵:
kernel void init(global const int *n, global const int *m, global float *matrix, global int *all_positions)
{
size_t position = get_global_id(0);
all_positions[position] = position;
int i = position / m[position];
int j = position % m[position];
matrix[position] = i * (n[position] - i - 1) * (2.f*i / n[position]) * j * (m[position] - j - 1) * (1.f*j / m[position]);
}
还有我主机的这段代码
cl::Kernel init(program, "init");
// Prepare input data.
std::vector<int> all_positions(n*m, 0);
std::vector<int> input_n(n*m, n);
std::vector<int> input_m(n*m, m);
cl::Buffer N(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, input_n.size(), input_n.data());
cl::Buffer M(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, input_m.size(), input_m.data());
cl::Buffer MATRIX(context, CL_MEM_READ_WRITE, matrix.size(), matrix.data());
cl::Buffer ALLPOSITIONS(context, CL_MEM_WRITE_ONLY, all_positions.size(), all_positions.data());
// Set kernel parameters.
init.setArg(0, N);
init.setArg(1, M);
init.setArg(2, MATRIX);
init.setArg(3, ALLPOSITIONS);
// Launch kernel on the compute device.
queue.enqueueNDRangeKernel(init, cl::NullRange, N_SIZE);
// Get result back to host.
queue.enqueueReadBuffer(MATRIX, CL_TRUE, 0, matrix.size(), matrix.data());
queue.enqueueReadBuffer(ALLPOSITIONS, CL_TRUE, 0, all_positions.size(), all_positions.data());
在此代码示例中,n
和m
是确定矩阵大小的命令行参数。matrix
是浮点数的一维向量,大小为n * m
。
据我了解,当我调用queue.enqueueNDRangeKernel(init, cl::NullRange, N_SIZE)
时,N_SIZE
也等于n * m
,我将global_work_size
设置为相同的数量(n * m
)。
问题是,当我启动程序时,我打印了 int 的结果all_positions向量,我相信它的值应该从 0 到n*m-1
开始,但它的结局是这样的:
0 1 2 3 4 5 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
(使用n=5
和m=5
)
矩阵值也最多只能计算matrix[6]
。
您在 GPU 上创建的缓冲区的大小太小。 例如,all_positions.size()
返回 25。这是向量中元素的数量。 以字节为单位的实际大小是25 * sizeof(int)
. 所以写:
cl::Buffer ALLPOSITIONS(context, CL_MEM_WRITE_ONLY, all_positions.size()*sizeof(int), all_positions.data());
对N
、M
和MATRIX
缓冲区创建执行相同的更改。 对于 queue.enqueueReadBuffer 也必须这样做。 例如:
queue.enqueueReadBuffer(MATRIX, CL_TRUE, 0, matrix.size()*sizeof(float), matrix.data());
大多数情况下sizeof(int)
是 4 个字节,您创建的缓冲区是 25 个字节长。所以只有 6 个元素而不是 25 个元素。
相关文章:
- 我不断收到 [错误] ID 返回 1 退出状态错误,但看不到问题所在
- 在返回 0 之前应为非限定 ID
- OpenCL global_work_size不反映返回的实际 ID
- 为什么if(fork()==0){getpid()}和popen()进程返回相同的进程id
- OpenGl,glUseProgram() 返回GL_INVALID_VALUE甚至着色器的 ID 是正确的
- "Extern"对象问题:错误:Id 返回 1 个退出状态
- 其他人的代码似乎返回了不同的处理器 ID
- 更新返回 0,即使表中没有此 ID
- 错误 (Id) 返回 1 个退出状态
- 开发人员在Dev C 中编译代码时,我会收到此错误:[错误] ID返回1退出状态
- Id 返回 1 个退出状态
- 简单c++程序Id的问题返回1退出状态
- 未定义的引用EVP_sha1、HMAC、Id 返回 1 个退出状态
- 作为宏参数的安装类型返回错误:字符串常量之前的预期非限定 id
- 从函数 C++ 返回文件 ID
- 错误:在 C++ 中返回之前应为非限定 ID
- MAKEINTRESOURCE 返回资源 ID 的错误指针
- glCreateProgram在LG7上返回奇怪的id
- 流权限被拒绝,id返回1退出状态
- Boost::this_thread::get_id在exit()调用期间不返回id