C++ CUDA中的无穷大测试
在一个CUDA项目中,我最近从使用C++ CUDA中的无穷大测试,c++,c,cuda,numerical,C++,C,Cuda,Numerical,在一个CUDA项目中,我最近从使用 return x==INFINITY || x==-INFINITY; 其中无穷是从math.h到 return !isfinite(x); 并且很惊讶得到了不同的结果。这表明他们实际上应该表现得类似。我错过什么了吗?不允许在CUDA内核中使用无限 编辑: 我刚刚发现了isinf,并注意到使用 return isinf(x); 给出与无穷大检查相同的结果。为什么不呢 isfinite(x)=!isinf(x)?浮点比较不一定有效。例如,有可能是(1.0f
return x==INFINITY || x==-INFINITY;
其中无穷
是从math.h到
return !isfinite(x);
并且很惊讶得到了不同的结果。这表明他们实际上应该表现得类似。我错过什么了吗?不允许在CUDA内核中使用无限
编辑:
我刚刚发现了isinf
,并注意到使用
return isinf(x);
给出与无穷大检查相同的结果。为什么不呢
isfinite(x)=!isinf(x)
?浮点比较不一定有效。例如,有可能是(1.0f+3.0f!=2.0f+2.0f)
。isfinite很有可能认为小于一个特定常数的值等于无穷大或-INFINITE,而您编写了一个文字等式。许多GPU和SIMD单元并不完全符合IEEE754,特别是对于无穷大和NaN的边情况。就在昨天晚上,我注意到一个与我一起工作的向量处理器声称∞+1.≠ ∞ , x==x,即使对于x∈NaN.是有限的(a)
与相同!伊斯南(a)&!isinf(a)
。如果x
为NaN,则isfinite(x)
和isinf(x)
均为false。isinf()
仅检查+无穷大
或-无穷大
!isfinite()
检查+无穷大
、-无穷大
或NaN
在最近的帖子中,Robert Crovella建议使用isinf()
检查CUDA中的无限值
下面我将提供一个使用isinf()
和利用CUDA推力检查数组中无限值的示例。也许它可以作为其他用户的参考。下面的例子相当于Matlab的d_结果=isinf(d_数据)代码>。它不同于我为上面引用的问题发布的示例,因为当前的一个检查每个元素是无限的,而另一个检查整个数组是否包含至少一个NaN
,并且与Matlab的sum(isnan(d_data))等效代码>
#包括
#包括
#包括
#包括
#包括
#包括
//---用于测试inf值的运算符
结构isinf_测试{
__主机设备布尔运算符()(常量浮点a)常量{
返回isinf(a);
}
};
void main(){
常数int N=10;
推力::主机向量h_数据(N);
对于(int i=0;如果结果有什么不同?结果是什么?预期结果是什么?我还不确定,但似乎有限比无限测试更严格。@stephen canon:是的,但是Cg文档没有提到数学中的无穷宏。h,我要问的差异。显然无穷宏确实如此像isinf一样工作(请参见我的编辑),因此它具有一定的相关性。在任何采用IEEE-754算法的系统上(甚至在某些GPU等不完全符合IEEE-754的系统上,1.0f+3.0f!=2.0f+2.0f
)。浮点不是黑魔法。它的循环和不循环都有明确的规则。我对NaN(x!=x)
的检查通过,因此根据此测试不存在NaN。但是,如果Crashworks是正确的,那么这实际上可能就是解决方案。@hannes:您使用的是什么GPU和CUDA版本?@hannes:确保(x!=x)
没有被编译器优化。@Billy ONeal:手动注入nan时,nan测试工作正常。
#include <thrust/sequence.h>
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust\device_vector.h>
#include <thrust\reduce.h>
#include <float.h>
// --- Operator for testing inf values
struct isinf_test {
__host__ __device__ bool operator()(const float a) const {
return isinf(a);
}
};
void main(){
const int N = 10;
thrust::host_vector<float> h_data(N);
for (int i=0; i<N; i++)
h_data[i] = rand()/RAND_MAX;
h_data[0] = FLT_MAX/FLT_MIN;
thrust::device_vector<float> d_data(h_data);
thrust::device_vector<float> d_result(h_data);
thrust::transform(d_data.begin(), d_data.end(), d_result.begin(), isinf_test());
for (int i=0; i<N; i++) {
float val = d_result[i];
printf("Isinf test for element number %i equal to %f\n",i,val);
}
getchar();
}