Can Thrust :: sort / unique句柄NaN,Inf?

时间:2016-12-29 15:13:07

标签: pointers parallel-processing cuda thrust

在我的CUDA内核中:

// declaring data
float * data = new float[size];
[...]
[fill data]
[...]

// sorting
thrust::sort(data, data + size, thrust::greater<float>());

// unique
thrust::unique(thrust::device, data, data + size);

输出:

data =

0.1000
0.1000
0.1000
     0
-0.3000
-0.2000
-0.1000
-Inf
-Inf
-Inf
NaN
Inf
Inf
Inf
-Inf
-Inf  
NaN
Inf
Inf
Inf
Inf

我可以在MATLAB中看到的输出没有排序,并且不会删除重复项。 UNIQUE和SORT根本不工作。 Thrust不支持指向数组的指针吗?

1 个答案:

答案 0 :(得分:2)

基于比较的算法无法正常处理包含NaN值的数据,因为NaNuncomparableInf-Inf具有可比性,可用于执行比较的推力或C ++标准库算法。

这里唯一的解决方案是首先删除NaN值(thrust::remove_if可以使用带有isnan的functor或lambda表达式,然后运行基于比较的算法数据。所以像这样:

#include <iostream>
#include <thrust/remove.h>
#include <thrust/unique.h>
#include <thrust/sort.h>

int main()
{
    const int N=18;
    unsigned int data[N] = { 
         0x3e99999a, 0x7f800000, 0xff800000, 0x7fffffff, 0x3e4ccccd, 0x3dcccccd, 
         0x3e99999a, 0x7f800000, 0xff800000, 0x7fffffff, 0x3e4ccccd, 0x3dcccccd, 
         0x3e99999a, 0x7f800000, 0xff800000, 0x7fffffff, 0x3e4ccccd, 0x3dcccccd };

    float* input = reinterpret_cast<float*>(&data[0]);

    {
        std::cout << "Input" << std::endl;
        auto it = input;
        for(; it != input+N; ++it) { std::cout << *it << std::endl; }
        std::cout << std::endl;
    }

    auto pred = [](const float& v){ return isnan(v); };
    auto input_end = thrust::remove_if(input, input+N, pred);
    thrust::sort(input, input_end);
    input_end = thrust::unique(input, input_end);

    {
        std::cout << "Output" << std::endl;
        auto it = input;
        for(; it != input_end; ++it) {std::cout << *it << std::endl; }
        std::cout << std::endl;
    }

    return 0;
}

执行以下操作:

~/SO$ nvcc --std=c++11 -arch=sm_52 inf_nan.cu 
~/SO$ ./a.out 
Input
0.3
inf
-inf
nan
0.2
0.1
0.3
inf
-inf
nan
0.2
0.1
0.3
inf
-inf
nan
0.2
0.1

Output
-inf
0.1
0.2
0.3
inf

完全能够排序和提取唯一值,在删除Inf条目后,在输入数据中包含-InfNaN