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:
ib = -1
logical function isnan(a)
if (a.ne.a) then
isnan = .true.
isnan = .false.
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.
I also need to detect NaNs in a program. Based on your example, I typed this:
print *, b
if (b.ne.b) then
print *, “Its a NaN”
print *, “Its not a NaN”
Compiled like this: pgf90 -o test -Kieee test.f90, it results in:
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,
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,
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:
Its not a NaN or Inf
Is this test only working from version 6.2-3 ?
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
% 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
Thank you very much for your help !
With those functions, it all worked out perfectly.
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]
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.