Тестирование на бесконечность в CUDA
В программе CUDA я недавно переключился с тестирования на inifinity с помощью
return x==INFINITY || x==-INFINITY;
Где INFINITY
- из математики.h, to
return !isfinite(x);
И был весьма удивлен, получив разные результаты. gnu.org предполагает, что они действительно должны вести себя подобным образом. Я что-то упустил? Разве нельзя использовать INFINITY
в ядре CUDA?
Редактировать:
Я только что обнаружил isinf
и заметил, что проверка с помощью
return isinf(x);
Дает тот же результат, что и проверка бесконечности. Почему? не
isfinite(x)==!isinf(x)
?
5 ответов:
isfinite(a)
это то же самое, что!isnan(a) && !isinf(a)
. Еслиx
- NaN, то иisfinite(x)
, иisinf(x)
ложны.
isinf()
проверяет только для+INFINITY
или-INFINITY
.
!isfinite()
чеки для+INFINITY
,-INFINITY
илиNaN
.
Сравнения с плавающей точкой не обязательно корректны. Например, возможно, что
(1.0f + 3.0f != 2.0f + 2.0f)
. вполне возможно, что isfinite считает значения, меньшие, чем определенная константа, равными бесконечности или-бесконечности, тогда как вы написали буквальное равенство.
Многие графические процессоры и SIMD-модули не полностью совместимы с IEEE754, особенно для граничных случаев вокруг бесконечностей и NaN. Только вчера вечером я заметил, что конкретный векторный процессор , с которым я работал, утверждал, что ∞+1≠ ∞, а x == x даже для X ∈ NaN.
В недавнем посте проверить, если матрица содержит значения NaN или бесконечность значений в CUDA, Роберт Crovella и предложил использовать
isinf()
чтобы проверить наличие бесконечного значения в CUDA.Ниже я привожу пример проверки бесконечных значений в массиве с помощью
isinf()
и с использованием тяги CUDA. Возможно, это может быть полезно в качестве ссылки для других пользователей. Приведенный ниже пример эквивалентен Матлабовскомуd_result=isinf(d_data);
. Это отличается от примера, который я опубликовал для вопроса, приведенного выше, в том, что настоящий проверяет, что каждый отдельный элемент бесконечен, в то время как другой проверяет, содержит ли весь массив хотя бы одинNaN
и эквивалентенsum(isnan(d_data));
Matlab.#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(); }