Kernel OpenCL-数组的内核递增索引

Kernel OpenCL-数组的内核递增索引,kernel,opencl,Kernel,Opencl,我想根据一个条件在opencl内核的输出数组中输入一些值。所以我想在数组中输入每个值之后增加数组的索引。由于需要满足条件,因此输出数组索引未知。我使用输出数组索引作为参数: __kernel void match(__global float* input, __global float* output, int pos) { if(condition) { output[pos] = input[get_global_id(0)];

我想根据一个条件在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++时,它起作用了,但这并没有返回数组位置的任何最终值


有人能解释一下我做错了什么吗?

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

input
中的每个元素都分配了一个线程吗?如果是这样,
input
将在内核中使用
index[get\u global\u id(0)]
进行索引,假设(巨大假设)您使用的是1D数组,并调用
clEnqueuNDRangeKernel()
,全局工作大小类似于
size\u global\u work\u size[1]={input\u size}

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

如果内核索引不容易映射,则需要动态计算索引,或者需要输入另一个数组,该数组是映射
input
output
的索引的查找表(LUT)


最后,您可以使用查找错误的确切原因

不能直接使用使用atomic_inc递增的变量的值,否则会有竞争条件。for atomic_inc提到,它返回增量之前的旧值,如果每个线程都以这种方式使用它,那么每个线程都将获得一个唯一的值。因此,正确的使用方法是:

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

“pos”可以是全局的,也可以是本地的,但就您的使用而言,它似乎应该是全局的。

很抱歉,没有包括get_global_id(0)。但是,是的,我只想把那些输入元素放到通过特定条件的输出中。因此,对于某些线程,如果条件通过,则输出数组将递增。这是一个需要转换为并行的顺序问题吗?你能给我一个动态计算位置的想法吗?在顺序版本中,当条件满足时,我使用了向量和push_back()。Hi Shunyo,很抱歉响应延迟。最简单的方法是使输入和输出数组大小相同。如果满足条件,则将值放入输出数组,否则放入0(或-1)。除此之外,不知道算法真的很难。在OpenCL中还没有像C++那样的真正的动态向量。