Тестирование на бесконечность в 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(); }