如何使用CUDA Thrust使用下一个非缺失值填充数组中的缺失值?

时间:2013-01-14 00:25:45

标签: cuda gpgpu thrust

通过使用带有max运算符的CUDA Thrust inclusive scan,我可以使用之前的非缺失值(即左边的最后一个非缺失值)填充缺失值。

但是如何使用下一个非缺失值填充(右侧)?因此,例如,使用0作为我的缺失值标记:

                  Input: [0 1 0 0 4 0 6 0]
 Fill missing from left: [0 1 1 1 4 4 6 6]
Fill missing from right: [0 1 4 4 4 6 6 6]   <- want

(请注意,如果缺少最后一个元素,请从左侧恢复为填写最终0。)

我已尝试反向进行包容性扫描,[0 6 6 6 6 6 6 6]产生max,而不是所需。

非常感谢。

2 个答案:

答案 0 :(得分:3)

从左到右扫描时,max()处理升序值的原因是当前最大值始终高于0缺少的元素,因此它将成为填写正确值的正确值缺少元素,即使它从一开始就有一个“记忆”。

如果您只是从右向左扫描,max()不再有效,因为您的范围会下降。

因此,您似乎需要使用rbegin()rend()从右向左扫描,此外,使用MAX_INT作为占位符,min()作为运算符

Input: [MAX_INT 1 MAX_INT MAX_INT 4 MAX_INT 6 MAX_INT]
Fill missing from right: [1 1 4 4 4 6 6 MAX_INT]

然后,您需要在左右两侧为特殊情况捏造物品。

答案 1 :(得分:3)

仿函数FillMissing表示如果element为0,则将其替换为前一个元素,否则保留它。使用反向迭代器时,“previous”表示正确的迭代器。

#include <thrust/device_vector.h>
#include <thrust/scan.h>
#include <iterator>

template<class T>
struct FillMissing
{
    __host__ __device__ T operator()(const T& res, const T& dat)
    {
        return dat == T(0) ? res : dat;
    }
};

int main()
{
    thrust::device_vector<double> vec(8);
    vec[1] = 1;
    vec[4] = 4;
    vec[6] = 6;

    thrust::inclusive_scan(
            vec.rbegin(), vec.rend(),
            vec.rbegin(),
            FillMissing<double>());

    thrust::copy(
            vec.begin(), vec.end(),
            std::ostream_iterator<double>(std::cout, " "));
    std::cout << std::endl;
}

输出。

1 1 4 4 4 6 6 0

您可能需要额外的代码来处理尾随0