OpenCL缩减中min()和max()的中性元素

时间:2013-01-23 12:52:52

标签: floating-point opencl

我正在通过OpenCL对GPU上的float[]数组进行缩减(找到最小值和最大值)。

我将global内存中的一些元素加载到每个工作组的local内存中。当全局大小不是工作组大小的倍数时,我填充全局大小,使其成为全局大小的倍数。超过数组末尾的工作项将缩减的中性元素放入local内存中。

但是这个中性元素应该用于max() - 最大函数? The OpenCL documentationMAXFLOATHUGE_VALFINFINITY视为非常大的正(或无符号)float值。 例如,将中性元素设为-INFINITY是否有意义?

现在我使用HUGE_VALF作为min()的中性元素,但文档也说HUGE_VALF用作错误值,所以也许&#39一个坏主意。

还原内核(代码):

#define NEUTRAL_ELEMENT HUGE_VALF
#define REDUCTION_OP min

__kernel void reduce(__global float* weights,
                     __local float* weights_cached
                    )
{
  unsigned int id = get_global_id(0);

  // Load data
  if (id < {{ point_count }}) {
    weights_cached[get_local_id(0)] = weights[id];
  } else {
    weights_cached[get_local_id(0)] = NEUTRAL_ELEMENT;
  }

  barrier(CLK_LOCAL_MEM_FENCE);

  // Reduce
  for(unsigned int stride = get_local_size(0) / 2; stride >= 1; stride /= 2) {
    if (get_local_id(0) < stride) {
      weights_cached[get_local_id(0)] = REDUCTION_OP(weights_cached[get_local_id(0)], weights_cached[get_local_id(0) + stride]);
    barrier(CLK_LOCAL_MEM_FENCE);
  }

  // Save
  weights[get_group_id(0)] = weights_cached[0];
}

修改 我实际上最终使用fmin()fmax()以及NAN作为中性元素 - 这基本上可以保证根据OpenCL documentation工作,因为数值始终是返回(NAN仅在给出两个NAN值时返回。

1 个答案:

答案 0 :(得分:2)

引用OpenCL标准:

  

HUGE_VALF评估为+无穷大。

因此,使用HUGE_VALFINFINITY之间没有真正的区别(隐含意图除外);要么min还原,要么正常工作。在清晰度方面,我略微偏好INFINITY,因为HUGE_VALF在概念上用于边缘案例返回,但事实并非如此。

同样,使用-INFINITY进行max缩减。

如果您的数组包含无穷大,

MAX_FLOAT将无法正常表现为中性元素。