如何计算gpu_array的方差?

时间:2012-11-09 17:42:54

标签: cuda pycuda

我正在尝试计算2D gpu_array的方差。减少内核听起来是个好主意:

http://documen.tician.de/pycuda/array.html

但是,此文档暗示减少内核只将2个数组减少为1个数组。如何将单个2D阵列减少为单个值?

1 个答案:

答案 0 :(得分:3)

我想第一步是为这种情况定义方差。在matlab中,2D数组上的方差函数返回值的向量(1D阵列)。但听起来你想要一个单值方差,正如其他人已经建议的那样,可能首先要做的就是将二维数组视为一维。在C中,我们不需要任何特殊步骤来完成此任务。如果你有一个指向数组的指针,你可以索引它,就像它是一维数组一样。我假设您在how to handle a 2D array with a 1D index上不需要帮助。

现在,如果它是您之后的1D方差,我假设函数如方差(x)= sum((x [i] -mean(x))^ 2)总和超过所有i,是你所追求的(基于我对wikipedia article的阅读)。我们可以将其分解为3个步骤:

  1. 计算均值(这是经典的减少 - 为数据集生成一个值 - 将所有元素相加然后除以元素数量)
  2. 为所有i计算值(x [i] -mean)^ 2 - 这是元素操作的元素,生成与输入数据集大小(元素数量)相等的输出数据集
  3. 计算步骤2中生成的元素之和 - 这是另一个经典缩减,因为为整个数据集生成了一个值。
  4. 步骤1和3都是经典的缩减,它们对数组的所有元素求和。我不会在此处介绍这一点,而是指向Mark Harris' excellent treatment of the topic以及CUDA sample code。对于第2步,我打赌你可以自己找出内核代码,但它看起来像这样:

    #include <math.h>
        __global__ void var(float *input, float *output, unsigned N, float mean){
    
          unsigned idx=threadIdx.x+(blockDim.x*blockIdx.x);
          if (idx < N) output[idx] = __powf(input[idx]-mean, 2);
        }
    

    请注意,您可能希望将缩减和上面的代码组合到一个内核中。