如何在OpenCL的工作组中添加工作项的结果?

如何在OpenCL的工作组中添加工作项的结果?,opencl,gpgpu,Opencl,Gpgpu,我使用GlobalWorkSize64 4 1和WorkGroupSize1 4 1调用下面的内核,参数output初始化为零 __kernel void kernelB(__global unsigned int * output) { uint gid0 = get_global_id(0); uint gid1 = get_global_id(1); output[gid0] += gid1; } 我期望6…作为gid1的总和(0+1+2+3)。相反,我得到的是3…有没有

我使用GlobalWorkSize
64 4 1
和WorkGroupSize
1 4 1
调用下面的内核,参数
output
初始化为零

__kernel void kernelB(__global unsigned int * output) 
{
  uint gid0 = get_global_id(0);
  uint gid1 = get_global_id(1);

  output[gid0] += gid1;
}
我期望
6…
作为
gid1
的总和(0+1+2+3)。相反,我得到的是
3…
有没有办法获得此功能?通常,我需要工作组中每个工作项的结果的总和


编辑:似乎必须说,我想在没有原子的情况下解决这个问题。

多个工作项同时访问
global
的元素,结果未定义。您需要使用原子操作或为每个工作项写入唯一位置。

多个工作项同时访问
global
的元素,并且结果未定义。您需要使用原子操作或为每个工作项写入唯一位置。

您需要使用本地内存来存储所有工作项的输出。在完成工作项的计算后,使用累加步骤对结果求和

__kernel void kernelB(__global unsigned int * output) 
{
  uint item_id = get_local_id(0);
  uint group_id = get_group_id(0);

  //memory size is hard-coded to the expected work group size for this example
  local unsigned int result[4];

  //the computation
  result[item_id] = item_id % 3;

  //wait for all items to write to result
  barrier(CLK_LOCAL_MEM_FENCE);

  //simple O(n) reduction using the first work item in the group
  if(local_id == 0){
    for(int i=1;i<4;i++){
      result[0] += result[i];
    }
    output[group_id] = result[0];
  }
}
\uuuu内核void kernelB(\uuu全局无符号int*输出)
{
uint item_id=get_local_id(0);
uint group\u id=get\u group\u id(0);
//对于本例,内存大小硬编码为预期的工作组大小
局部无符号整数结果[4];
//计算
结果[项目id]=项目id%3;
//等待所有项目写入结果
屏障(CLK_本地_MEM_围栏);
//使用组中的第一个工作项进行简单O(n)缩减
如果(本地_id==0){

对于(int i=1;i您需要使用本地内存来存储所有工作项的输出。在工作项完成计算后,您可以使用累加步骤对结果求和

__kernel void kernelB(__global unsigned int * output) 
{
  uint item_id = get_local_id(0);
  uint group_id = get_group_id(0);

  //memory size is hard-coded to the expected work group size for this example
  local unsigned int result[4];

  //the computation
  result[item_id] = item_id % 3;

  //wait for all items to write to result
  barrier(CLK_LOCAL_MEM_FENCE);

  //simple O(n) reduction using the first work item in the group
  if(local_id == 0){
    for(int i=1;i<4;i++){
      result[0] += result[i];
    }
    output[group_id] = result[0];
  }
}
\uuuu内核void kernelB(\uuu全局无符号int*输出)
{
uint item_id=get_local_id(0);
uint group\u id=get\u group\u id(0);
//对于本例,内存大小硬编码为预期的工作组大小
局部无符号整数结果[4];
//计算
结果[项目id]=项目id%3;
//等待所有项目写入结果
屏障(CLK_本地_MEM_围栏);
//使用组中的第一个工作项进行简单O(n)缩减
如果(本地_id==0){

例如(int i=1;这似乎解释了示例代码无法按预期工作的原因。但是,原子学不是一个选项,写入到唯一位置是必要的(似乎)但这还不足以解决这个问题,即如何获得总和?请重新编写内核,使每个工作项负责单个输出,并收集所需的任何输入数据。在本例中,编写一个全局大小为64的1D内核。这似乎解释了示例代码无法按预期工作的原因。但是,原子s不是一个选项,写入一个唯一的位置是必要的(似乎)但这还不足以解决这个问题,即如何获得总和?请重新编写内核,使每个工作项负责一个输出,并收集所需的任何输入数据。在本例中,请编写一个全局大小为64的1D内核。供将来参考,当在本地workgr中处理大量超过4个线程时OP,OP应该考虑使用并行约化来积累所有的结果。我使用了一个类似于被接受的答案的方法,即有一个工作项和,并且写工作组的结果。OP在本地工作组中有4多个线程,OP应该考虑使用并行还原来累积所有的结果。我使用了一个类似于被接受的答案的方法,即有一个工作项和,并且写工作组的结果。