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++ 但它没有返回数组位置的任何最终值时,它起作用了。

谁能解释我做错了什么?

4

2 回答 2

2

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

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

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

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

最后,您可以使用clGetProgramBuildInfo准确找出错误所在。 请参阅我在另一个线程中所做的文章

于 2013-08-21T21:23:58.210 回答
0

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

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

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

于 2013-08-23T00:24:53.830 回答