【问题标题】:CUDA to OpenCL : What is the equivalent of (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x in OpenCL?CUDA 到 OpenCL:OpenCL 中 (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x 的等价物是什么?
【发布时间】:2017-12-25 11:39:32
【问题描述】:

我是 OpenCL 的初学者,试图将一个简单的 CUDA 函数转换为 OpenCL。在 CUDA 函数中,他们使用下面的 sn-p 来获取操作索引,

int id = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x;

get_global_id(0) 是否相当于 OpenCL 中的上述内容?

int id = get_global_id(0);

【问题讨论】:

  • 简短的回答是否定的。除了是/否的答案之外,您还有其他想法吗?
  • @talonmies 如果不是,我想找到一种替代方法来实现这一目标。

标签: cuda opencl


【解决方案1】:

我不熟悉 CUDA(仅限 OpenCL),但看起来以下是等价的:

  • get_group_id(uint dimindx)blockIdx.[xyz]
  • get_local_size(uint dimindx)blockDim.[xyz]
  • get_local_id(uint dimindx)threadIdx.[xyz]
  • get_num_groups(uint dimindx)gridDim.[xyz]

其中dimindx 为0、1 或2,分别对应.x.y.z

get_global_id(0)get_group_id(0) * get_local_size(0) + get_local_id(0) 相同,因此假设上述等价确实正确,则与blockIdx.x * blockDim.x + threadIdx.x 相同。 (对于 .y 的索引 1 和 .z 的索引 2 等效)

要获得相同的 ID 值,我想你可能想要这样的东西:

int id = get_group_id(1) * get_global_size(0) + get_global_id(0);

请注意,原始 CUDA 代码明确不考虑 threadIdx.y。我怀疑这可能是因为您的 blockDim.y 为 1,或者因为您真的试图获取块中最顶部的项目(不是与当前线程对应的项目)。

更常见的情况可能是将当前工作项的索引放入包含二维元素数组的缓冲区中的数组中:

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

如果get_local_size(1) 为 1,这当然等价于前面的表达式。(块的高度为 1。)

以上所有内容均假设您已将内核与 CUDA 中的等效工作组(块)和全局维度排入队列。

【讨论】:

  • 我不确定你最后的表达是否正确,get_global_id(1) 应该是get_group_id(1)
  • @talonmies 看起来你对这个问题的深入检查是正确的。我会修复它 - 虽然我怀疑在提问者的情况下块大小在 y 方向上可能是 1,否则获得 ID 似乎是一件奇怪的事情。
  • @talonmies 我怀疑get_global_id(1) * get_global_size(0) + get_global_id(0) 对其他人来说会更有用,所以我添加了一个解释,并更正了原来的那个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
  • 1970-01-01
  • 2014-05-08
  • 2014-06-12
  • 1970-01-01
  • 2022-11-28
  • 2021-06-19
相关资源
最近更新 更多