是否可以在 pyopencl 中 运行 一个 4 维工作项?
Is it possible to run a 4 dimensional work item in pyopencl?
我有一个基于 pyopencl
的代码,它在 3 维工作组中运行得非常好,但是当移动到 4 维工作组时,它出现错误:
pyopencl._cl.LogicError: clEnqueueNDRangeKernel failed: INVALID_WORK_DIMENSION
四处挖掘,我发现 另一个问题,这意味着 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()
尝试指定比实现所支持的更多的维度是行不通的。
支持的最大维度数可以通过CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS
或终端查询,例如:
$ clinfo | grep dim
Max work item dimensions 3
我有一个基于 pyopencl
的代码,它在 3 维工作组中运行得非常好,但是当移动到 4 维工作组时,它出现错误:
pyopencl._cl.LogicError: clEnqueueNDRangeKernel failed: INVALID_WORK_DIMENSION
四处挖掘,我发现 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()
尝试指定比实现所支持的更多的维度是行不通的。
支持的最大维度数可以通过CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS
或终端查询,例如:
$ clinfo | grep dim
Max work item dimensions 3