我是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
的{{1}}时,我将n * m
设置为相同的金额({{1} }。
问题是,当我启动程序时,我将打印出结果所得的int的all_positions向量,我认为其值应从0到global_work_size
,但最终会像这样:>
n * m
(使用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
。
答案 0 :(得分:3)
您在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个元素的地方。