Python OpenCL最大工作项目尺寸

Python OpenCL最大工作项目尺寸,python,arrays,numpy,opencl,pyopencl,Python,Arrays,Numpy,Opencl,Pyopencl,我很难理解工作项约束的含义。我正在使用pyopencl,查看它给出的最大工作项大小,我假设每个维度的最大全局工作线程数 将pyopencl作为cl导入 将numpy作为np导入 ctx=cl.创建一些上下文 queue=cl.CommandQueuectx queue.device.max_work_item_大小[1024、1024、64] 我可以通过以下方式模拟np.arange函数: prg = cl.Program(ctx, """ __kernel voi

我很难理解工作项约束的含义。我正在使用pyopencl,查看它给出的最大工作项大小,我假设每个维度的最大全局工作线程数

将pyopencl作为cl导入 将numpy作为np导入 ctx=cl.创建一些上下文 queue=cl.CommandQueuectx queue.device.max_work_item_大小[1024、1024、64] 我可以通过以下方式模拟np.arange函数:

prg = cl.Program(ctx, """
__kernel void arange(__global int *res_g)
{
  int gid = get_global_id(0);
  res_g[gid] = gid;
}
""").build()

res_g = cl.Buffer(ctx, cl.mem_flags.READ_WRITE, 4 * 4096)
prg.arange(queue, [4096], None, res_g)

# transfer back to cpu
res_np = np.empty(4096).astype(np.int32)
cl.enqueue_copy(queue, res_np, res_g)

assert (res_np == np.arange(4096)).all() # this is true
prg = cl.Program(ctx, """
__kernel void arange(__global int *res_g)
{
  int gid = get_global_id(0) * get_global_id(1);
  barrier(CLK_GLOBAL_MEM_FENCE);
  res_g[gid] = gid;
}
""").build()

res_g = cl.Buffer(ctx, cl.mem_flags.READ_WRITE, 4 * 4096)
prg.arange(queue, [64, 64], [1,1], res_g)

# transfer back to cpu
res_np = np.empty(4096).astype(np.int32)
cl.enqueue_copy(queue, res_np, res_g)

assert (res_np == np.arange(4096)).all()
如何为第一个维度指定1024个以上的工作项?最大工作项尺寸是什么意思

与此相关的另一个问题是,使用尽可能多的工作维度是否有益?据我所知,最多可以使用3维。使用2个工作项维度模拟np.arange的方法可以通过以下方式完成:

prg = cl.Program(ctx, """
__kernel void arange(__global int *res_g)
{
  int gid = get_global_id(0);
  res_g[gid] = gid;
}
""").build()

res_g = cl.Buffer(ctx, cl.mem_flags.READ_WRITE, 4 * 4096)
prg.arange(queue, [4096], None, res_g)

# transfer back to cpu
res_np = np.empty(4096).astype(np.int32)
cl.enqueue_copy(queue, res_np, res_g)

assert (res_np == np.arange(4096)).all() # this is true
prg = cl.Program(ctx, """
__kernel void arange(__global int *res_g)
{
  int gid = get_global_id(0) * get_global_id(1);
  barrier(CLK_GLOBAL_MEM_FENCE);
  res_g[gid] = gid;
}
""").build()

res_g = cl.Buffer(ctx, cl.mem_flags.READ_WRITE, 4 * 4096)
prg.arange(queue, [64, 64], [1,1], res_g)

# transfer back to cpu
res_np = np.empty(4096).astype(np.int32)
cl.enqueue_copy(queue, res_np, res_g)

assert (res_np == np.arange(4096)).all()
由于某些原因,这个断言并不总是正确的

但我的问题是,在处理大型数组时,是否最好使用所有3个work\u item\u维度?还是将数组视为1d连续数组并仅使用get\u global\u id0更好

如何为第一个项目指定1024个以上的工作项 维最大工作项尺寸是什么意思

max_work_item_size返回每个维度中每个工作组的最大工作项数

通过将None作为第三个参数传递:

prg.arange(queue, [4096], None, res_g)
                          ^^^^
正在要求实施部门选择最佳工作组规模。可以通过以下方式检查工作组大小,例如:

res_g[gid] = get_local_size(0);
在我的系统中,max_work_item_size=[4096,4096,4096],get_local_size0返回的值为1024,这意味着实现决定工作组大小为1024个项目,4096/1024为我们安排了4个工作组

指定工作组大小,例如256个工作项:

prg.arange(queue, [4096], [256], res_g)
将安排4倍多的工作组

与此相关的另一个问题是,使用尽可能多的数据是否有益 工作尺寸是否尽可能大?据我所知,使用3是可能的 最多是尺寸

但我的问题是,在处理大型数组时 使用所有3个工作项尺寸?还是治疗癌症更好 数组作为1d连续数组,并且仅使用get_global_id0

根据我的经验,使用一个或多个维度没有区别。所以你可以做你更方便的事

由于某些原因,这个断言并不总是正确的

那是因为你的代码中有一个bug。计算指标应为:

int gid = get_global_id(0) * get_global_size(0) + get_global_id(1);

谢谢那么,看看最大工作项大小是否为每个对应维度指定了最大本地大小或工作组大小?如果我设置local\u size=None,那么全局\u size是否有任何限制?是max\u work\u item\u size是工作组中的最大工作项数,可以通过get\u local\u sizedimension在内核内部查询;指定本地大小与否对全局大小值没有任何影响。唯一的限制是全局大小必须是可被局部大小整除的数字。我没有听说过全局_大小有任何限制,但它可能受到所使用的数据类型或处理如此大的内核所需的资源的限制,例如,需要将更多的数据传递到内核,这受到全局内存大小的限制。我还有一个问题:当在gpu上执行简单的操作(如乘法和加法)时,如果有意义的话,将本地_大小指定为1并且不启动任何不必要的线程会更好吗?由于执行加法,如果两个数组操作数的大小相同,我们只需要使用get_global_id0。指定local_size=1可能会影响性能。对于大于或等于2维的2D乘法,1D的最小局部_大小应为32或64。但是,如果算法只使用全局_id/大小,那么通常最好让实现决定最佳的局部大小。