在我的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不支持指向数组的指针吗?
答案 0 :(得分:2)
基于比较的算法无法正常处理包含NaN
值的数据,因为NaN
为uncomparable。 Inf
和-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
条目后,在输入数据中包含-Inf
和NaN
。