How to detect NaN during runtime?

Hi everyone,
I am running a parallel program compiled with pgf90. I am constantly checking for a floating point exception at a certain data point as my program runs. I am interested in stopping the program as soon as an “NaN” is detected. To check whether a variable is “NaN”, I simply divide the variable by itself and check to see if the result is equal to one. The result should always be equal to one as long as the variable is not NaN. This approach works on other Fortran compilers such as the one on AIX, but it does not work with pgf90. Even though NaN divided by itself is not equal to one, the if statement that checks this fails to function correctly in pgf90. Any ideas on how I can detect NaN during runtime? I want to stay away from using compiler flags for detecting floating point exceptions because I am worried some of those flags may slow down my program. Thanks for any input on this matter.

Here is one way that works. You don’t need to compile your whole program with flags. Just this one subroutine:

program is
real b
integer ib
logical isnan
equivalence(b,ib)
c
ib = -1
print *,b
print *,isnan(b)
end
c
logical function isnan(a)
real a
if (a.ne.a) then
isnan = .true.
else
isnan = .false.
end if
return
end

If you compile isnan with the -Kieee flag, it will do the correct conditionals to check the case you want. You don’t need to compile anything else with -Kieee if you don’t want to.

Thanks! This procedure works well.

Hello,
I also need to detect NaNs in a program. Based on your example, I typed this:

program test
real a,b

b=3
a=0
b=b/a

print *, b

if (b.ne.b) then
print *, “Its a NaN”
else
print *, “Its not a NaN”
end if

end

Compiled like this: pgf90 -o test -Kieee test.f90, it results in:
$ ./test
Inf
Its not a NaN


My pfg90 version is:
$ pgf90 -V
pgf90 6.0-5 64-bit target on x86-64 Linux
Copyright 1989-2000, The Portland Group, Inc. All Rights Reserved.
Copyright 2000-2005, STMicroelectronics, Inc. All Rights Reserved.

What I am doing wrong ?
Thank you in advance,
Luc

Hi Luc,

I believe this will work. Note that Inf is a number, just a very large one!

cat inf.f90
program test
real a,b
logical isnan
logical isinf

b=3
a=0
b=b/a

print *, b
if (isnan(b)) then
print *, "Its a NaN"
else if (isinf(b)) then
print *, "Its a Inf"
else
print *, "Its not a NaN or Inf"
end if

end

logical function isnan(a)
real a
if (a.ne.a) then
isnan = .true.
else
isnan = .false.
end if
return
end

logical function isinf(a)
real a

if ((a*0).ne.0) then
isinf = .true.
else
isinf = .false.
end if
return
end
% pgf90 -V6.2-3 -Kieee inf.f90
% a.out
             Inf
 Its a Inf

Hope this helps,
Mat

Hello,
Thanks for your answer.
I couldn’t use the -V6.2-3 flag, as my compiler is only version 6.0-5.
Without that flag, it compiles fine, but the output is:
$ ./a.out
Inf
Its not a NaN or Inf

Is this test only working from version 6.2-3 ?

Hi Luc,

This is a bit embasssing, but I just found out that as of the 5.0 compilers we added intrinsics to detect NaNs and INF so please disregard both mine and Brent’s examples. Instead please use the following intrinsics which do not need “-Kieee”:

logical function isnand(xx)
double precision xx

logical function isnanf(xx)
real xx

logical function isinfd(xx)
double precision xx

logical function isinff(xx)
real xx

Example:

% cat inf2.f90
program test
real a,b
logical isnanf
logical isinff

b=3
a=0
b=b/a

print *, b
if (isnanf(b)) then
print *, "Its a NaN"
else if (isinff(b)) then
print *, "Its a Inf"
else
print *, "Its not a NaN or Inf"
end if

end
% pgf90 inf2.f90
% a.out
             inf
 Its a Inf

Thanks,
Mat

Hello,
Thank you very much for your help !
With those functions, it all worked out perfectly.
Bye,
Luc

Is the latest info in this thread still valid? When I try to use isnand/isnanf, I’m getting

PGF90-S-0038-Symbol, isnand, has not been explicitly declared
PGF90-S-0038-Symbol, isnanf, has not been explicitly declared

.

This is on OSX, I haven’t tested yet on Linux. Is there any cross-platform way to do this?[/quote]

Hi MuellerM,

This error occurs when you have “implicit none” set and the compiler finds symbols used that have not been explicitly declared. Declaring theses symbols as logical like I show in the earlier example will allow you to call them.

One thing you might consider since we now support F2003, is to use the “ieee_arithmetic” module instead of these extensions.

  • Mat