2010-12-03 52 views
5

無限遠CUDA程序,近日筆者從測試切換使用測試在CUDA

return x==INFINITY || x==-INFINITY; 

其中INFINITY是math.h中inifinity,以

return !isfinite(x); 

,並很驚訝地獲得不同的結果。 gnu.org暗示他們實際上應該表現得相似。我錯過了什麼嗎?不允許在CUDA內核中使用INFINITY

編輯: 我剛剛發現isinf,發現使用

return isinf(x); 

檢查給出了相同的結果INFINITY檢查。爲什麼不是 isfinite(x)==!isinf(x)

+0

對於結果有什麼不同?結果是什麼?預期的結果是什麼? – 2010-12-03 22:08:33

+0

我還不確定,但似乎是無限的比INFINITY測試更嚴格。 – hannes 2010-12-03 22:14:53

+0

@stephen canon:授予,但Cg文檔沒有提及math.h中的INFINITY宏,這是我所詢問的區別。顯然,INFINITY宏確實像isinf一樣工作(請參閱我的編輯),因此它有一定的相關性。 – hannes 2010-12-03 22:33:55

回答

5

isfinite(a)!isnan(a) && !isinf(a)相同。如果x是NaN,則isfinite(x)isinf(x)都是錯誤的。

1

浮點比較不一定有效。例如,有可能是(1.0f + 3.0f != 2.0f + 2.0f)。非常有可能,isfinite將小於特定常量的值視爲等於INFINITE或-INFINITE,而您寫的是文字相等。

1

許多GPU和SIMD單元並不完全符合IEEE754標準,尤其是對於無窮大和NaN的邊緣情況。就在昨天晚上,我注意到與我合作的特定矢量處理器聲稱∞ +1 ≠ ∞和x == x即使對於x ∈ NaN。

2

isinf()只檢查+INFINITY-INFINITY

!isfinite()檢查+INFINITY,-INFINITYNaN

0

在最近的帖子Checking if a matrix contains nans or infinite values in CUDA中,Robert Crovella建議使用isinf()來檢查CUDA中的無限值。

下面我提供了使用isinf()和利用CUDA Thrust檢查數組中無限值的示例。也許它可以作爲其他用戶的參考。下面的例子相當於Matlab的d_result=isinf(d_data);。這與我上面提到的問題發佈的例子不同,因爲本文檢查每個單獨的元素是無限的,而另一個檢查整個數組是否包含至少一個NaN並且等同於Matlab的sum(isnan(d_data));

#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(); 

}