Pointers 是否可以对NaN、Inf进行排序/唯一处理?
在我的CUDA内核中:Pointers 是否可以对NaN、Inf进行排序/唯一处理?,pointers,parallel-processing,cuda,thrust,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); 我的输出,你可以在这里看到在MATLAB中没有排
// 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);
我的输出,你可以在这里看到在MATLAB中没有排序和重复没有被删除。“唯一”和“排序”根本不起作用。推力不支持数组指针吗?基于比较的算法无法正确处理包含
NaN
值的数据,因为NaN
是<代码> INF和NaN
值(推力::删除_,如果
可以与使用isnan
的函子或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;
}
在删除
NaN
条目后,完全能够对输入数据进行排序和提取唯一值,包括Inf
和-Inf
。无法对IEEE754 NaN值进行排序,因为(根据定义)NaN是不可比较的。标准C++比较运算符(及其推力等效)不能将Na与其他数字或本身进行比较。
#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