【问题标题】:How do I calculate variance of gpu_array?如何计算 gpu_array 的方差?
【发布时间】:2012-10-30 01:48:53
【问题描述】:

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

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

但是,该文档暗示缩减内核只是将 2 个数组缩减为 1 个数组。如何将单个二维数组缩减为单个值?

【问题讨论】:

    标签: cuda pycuda


    【解决方案1】:

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

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

    1. 计算平均值(这是一种经典的归约方式 - 为数据集生成一个值 - 将所有元素相加,然后除以元素的数量)
    2. 计算所有 i 的值 (x[i]-mean)^2 - 这是一个逐个元素的操作,生成的输出数据集的大小(元素数)与输入数据集相等
    3. 计算步骤 2 中生成的元素的总和 - 这是另一种经典的归约,因为为整个数据集生成了一个值。

    第 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);
        }
    

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

    【讨论】:

    • 以上是两遍算法。您需要传递所有数据以计算平均值,然后再次计算方差。可以使用以下描述的在线算法一次性计算方差:wikipedia
    猜你喜欢
    • 2020-02-05
    • 2014-04-19
    • 1970-01-01
    • 2020-07-25
    • 2017-04-04
    • 1970-01-01
    • 2019-02-15
    • 2011-05-23
    相关资源
    最近更新 更多