【发布时间】:2021-07-07 15:30:55
【问题描述】:
我有一个基于 pyopencl 的代码,它在 3 维工作组中运行得非常好,但是当移动到 4 维工作组时,它会因错误而崩溃:
pyopencl._cl.LogicError: clEnqueueNDRangeKernel failed: INVALID_WORK_DIMENSION
四处挖掘,我发现this answer 指向另一个问题,这意味着OpenCl 实际上允许更高维度的工作组。
所以我的问题是是否可以在pyopencl 中更改此设置。从这个other answer 其他地方,我了解到pyopencl 立即输入尺寸,但鉴于我的错误,我认为一定有问题。
这是复制此错误的最小示例代码。 该代码适用于第一个内核函数,但它在第二个内核函数上崩溃了。
import pyopencl as cl
import numpy as np
context = cl.create_some_context()
queue = cl.CommandQueue(context)
kernel_code = """
__kernel void fun3d( __global double *output)
{
size_t i = get_global_id(0);
size_t j = get_global_id(1);
size_t k = get_global_id(2);
size_t I = get_global_size(0);
size_t J = get_global_size(1);
#
size_t idx = k*J*I + j*I + i;
#
output[idx] = idx;
}
__kernel void fun4d( __global double *output)
{
size_t i = get_global_id(0);
size_t j = get_global_id(1);
size_t k = get_global_id(2);
size_t l = get_global_id(3);
size_t I = get_global_size(0);
size_t J = get_global_size(1);
size_t K = get_global_size(2);
#
size_t idx = l*K*J*I + k*J*I + j*I + i;
#
output[idx] = idx;
}
"""
program = cl.Program(context, kernel_code).build()
I = 2
J = 3
K = 4
L = 5
output3d = np.zeros((I*J*K)).astype(np.float64)
cl_output3d = cl.Buffer(context, cl.mem_flags.WRITE_ONLY, output3d.nbytes)
program.fun3d(queue, (I,J,K), None, cl_output3d)
cl.enqueue_copy(queue, output3d, cl_output3d)
queue.finish()
import code; code.interact(local=dict(globals(), **locals()))
# 4d attempt
output4d = np.zeros((I*J*K*L)).astype(np.float64)
cl_output4d = cl.Buffer(context, cl.mem_flags.WRITE_ONLY, output4d.nbytes)
program.fun4d(queue, (I,J,K,L), None, cl_output4d)
cl.enqueue_copy(queue, output4d, cl_output4d)
queue.finish()
【问题讨论】:
-
只需查询您的实现支持的最大维度数是多少,例如:
clinfo | grep dim。但我从未听说过超过 3 个。 -
啊,我明白了,
clinfo | grep dim告诉我,我的两个设备的“最大工作项尺寸 3”;我认为这解决了它。如果您愿意,请发表您的评论作为答案,以关闭此问题。 -
已添加答案。如果您满意,请接受。