【问题标题】:OpenCL - Kernel Incrementing index of arrayOpenCL - 数组的内核递增索引
【发布时间】:2013-08-21 19:47:44
【问题描述】:

我想根据条件将一些值输入到 opencl 内核的输出数组中。所以我想在每个值输入到数组后增加数组的索引。由于需要满足条件,所以输出数组索引是未知的。我使用输出数组索引作为参数:

__kernel void match(__global float* input, __global float* output, int pos)
{ 
     if(condition)
     {
          output[pos] = input[get_global_id(0)];
          atomic_inc(&pos); // this is where the problem lies
     }
}

我也尝试将 pos 作为数组给出

__kernel void match(__global float* input, __global float* output, __global int* pos)
{ 
     if(condition)
     {
          output[pos[0]] = input[get_global_id(0)];
          atomic_inc(pos[0]); // this is where the problem lies
     }
}

对于这两种情况,clBuildProgram 返回错误代码 -11。当我增加值 pos++ 但它没有返回数组位置的任何最终值时,它起作用了。

谁能解释我做错了什么?

【问题讨论】:

    标签: kernel opencl


    【解决方案1】:

    不确定我是否理解这个问题,但让我们试一试:

    input 中的每个元素是否都分配了一个线程?如果是这样,input 将在内核中使用index[get_global_id(0)] 进行索引,假设(巨大的假设)您正在使用一维数组并称为clEnqueuNDRangeKernel(),其全局工作大小类似于size_t Global_Work_Size[1] = {input_size}

    当使用int pos 调用类似于第一个示例的内核时,这会在每个线程中放置一个常量pos,因此在我解释您的问题时它不起作用。

    如果内核索引不能以简单的方式映射,则需要动态计算索引,或者需要输入另一个数组,该数组是映射 input 到的索引的查找表 (LUT) output.

    最后,您可以使用clGetProgramBuildInfo 来准确找出错误所在。 See the write-up I did in another thread.

    【讨论】:

    • 很抱歉没有包含 get_global_id(0)。但是,是的,我只想将那些输入元素放入通过特定条件的输出中。因此,对于某些线程,如果条件通过,则输出数组会递增。是顺序问题需要转为并行吗?
    • 你也可以给我一个动态计算位置的想法吗?在顺序版本中,只要满足条件,我就会使用向量和 push_back()。
    • 您好,Shunyo,抱歉延迟回复。最简单的方法是使输入和输出数组大小相同。如果满足条件,则将值放入输出数组,否则放入 0(或 -1)。除此之外,不知道算法真的很难。目前还没有像 C++ 那样在 OpenCL 中实现的真正的动态向量。
    【解决方案2】:

    您不能直接使用您使用 atomic_inc 递增的变量的值,否则您将遇到竞争条件。 atomic_inc 的documentation 提到它返回增量之前的旧值,如果每个线程都以这种方式使用它,它们将各自获得一个唯一值。所以正确的使用方法是:

    int localPos = atomic_inc(&pos);
    output[localPos] = input[get_global_id(0)];
    

    “pos”可以是全局的或本地的,但它似乎应该是全局的以供您使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-17
      • 1970-01-01
      • 2019-06-09
      • 1970-01-01
      • 1970-01-01
      • 2021-09-30
      • 2011-09-13
      相关资源
      最近更新 更多