- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have been investigating a problem in a numerical modeling program that gave markedly different results when run in debug mode than when run in release mode. I have finally traced it to a comparison involving a NaN value and produced the following sample code to illustrate the problem:
program NaNandOptimization
implicit none
! Variables
Real sngaValue(1)
Real sngNaN
Real sngSetup
! Body of NaNandOptimization
sngSetup = 0.0
sngNaN = sngSetup/sngSetup
sngaValue = 2.5
If (sngaValue(1) .EQ. sngNaN) Then
Write(*,*) sngNaN, sngaValue, ' are equal'
Else
Write(*,*) sngNaN, sngaValue, ' are not equal'
End If
Pause
end program NaNandOptimization
Depending upon whether it is compiled in debug mode or release mode, this program produces the following results.
Debug mode output:
Release mode output:
NaN 2.500000 are equal
My understanding is that .EQ. applied to NaN and any other number should always result in .False., even if the other number is the same NaN on the other side of the .EQ. If this is so, then the debug results are correct and not the release mode results.
Am I missing something basic here, or is there a problem with the compiler optimization?
For reference, I am using Intel Visual Fortran v9.1.038. The command lines used to produce this result are:
Debug mode:
Fortran command line:
/nologo /Zi /Od /module:"$(INTDIR)/" /object:"$(INTDIR)/" /traceback /check:bounds /libs:static /dbglibs /c
Linker command line:
/OUT:"Debug/NaN and Optimization.exe" /INCREMENTAL:NO /NOLOGO /DEBUG /PDB:"Debug/NaN and Optimization.pdb" /SUBSYSTEM:CONSOLE
Release mode:
Fortran command line:
/nologo /module:"$(INTDIR)/" /object:"$(INTDIR)/" /c
Linker command line:
/OUT:"Release/NaN and Optimization.exe" /INCREMENTAL:NO /NOLOGO /SUBSYSTEM:CONSOLE
Thanks for your comments.
Cheers,
Randy
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
However, if your intention is to detect a NaN, it is better to use an intrinsic provided by the compiler for that purpose. ifort does not yet implement the f2003 intrinsic, but it does have the ISNAN() intrinsic:
if(isnan(x))then
write(*,*)'NaN value'
else
....
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, tim18,
Thanks for your reply. Yes, I'm confident setting /fp:strict will result in correct comparisons. (It was one of the tests I didwhile trying to track down the original problem after I discovered that it was optimization related.) However (as I understand it) this also can have a minorimpact on the accuracy of intermediate calculations, so I am reluctant to use it in this type of program (where iteration can cause minor variations to be amplified).
I have been able to work-around the immediate problem using IsNaN, but I now worry about other places in the code where similar problems might unexpectedly arise. Due to other constraints turning on divide-by-zero exceptions is not an option in this case. So the only indication of a problem is a deviation from the "correct" results, and unfortunately, the "correct" results are generally unknown to the user.
Perhaps the problem is fixed in version 10. Does anyone know?
Cheers,
Randy
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I guess that /fp:precise would more often improve accuracy than degrade it, particularly since it would nearly always force the compiler to observe parentheses when evaluating expressions.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page