Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Program generates NaN with -O3 + intel fortran 14

Guillaume_De_Nayer
1,045 Views

Hi,

I get some troubles with intel fortran 14:

- with -O3 the program we are using generates some NaN.

- with -O2 or -O0 it works.

If I'm using intel fortran 13.1, or 13.0 or 12.1 or older, I don't get any trouble with -O3 or -O2 or -O0.

Any ideas to correct my program ?

Best regards,

Guillaume De Nayer

0 Kudos
14 Replies
Izaak_Beekman
New Contributor II
1,045 Views

It may not be that you’re program has any deficiencies whatsoever. As a first step, I would consult this article on consistency of floating point results using the Intel compilers: https://software.intel.com/en-us/articles/consistency-of-floating-point-results-using-the-intel-compiler It has some information about what compiler options will affect floating point consistency. Just because -O3 started producing NaNs in version 14 doesn’t necessarily mean that there is a compiler defect, or that your program is erroneous. (However, I would search your program for bugs and examine the numerical robustness of your program thoroughly before investigating whether or not there is a compiler bug.)

The first thing to examine (in my mind) is the sensitivity and numerical robustness of your algorithms. Is your problem well conditioned? If not small perturbations to the results caused by changing compiler flags could cause your solution to blow up due to these changes.

If your program is parallel, then there are some additional points to keep in mind:

Compiler optimizations can effect the timings of different sections of code; therefore it is possible that the optimization is unearthing a parallel programming bug like a race condition.

Floating point arithmetic is not associative (consider when rounding happens). (A + B) + C /= A + (B + C) to all decimal places. This has implications in parallel programs when performing unordered reductions like an MPI_Allreduce.

See what you can do on your own, and if you get stuck, be sure to post more information here: All compile flags, 64 vs 32 bit compiler, OS X vs Linux, and most importantly the code causing the problems, or at least a portion of it, where the issue is occurring.

0 Kudos
Greynolds__Alan
Beginner
1,045 Views

I assume the program has passed checks on array bounds and uninitialized variables by compiling with -CB -CU.  If not, I would start there.

Al 

0 Kudos
Guillaume_De_Nayer
1,045 Views

Do the options -CB -CU imply -O2 or -O0 ?

If I'm using -O3 -CB -CU I don't have NaN or any problem...

I these options imply -O2 or -O0, how can I force -O3 and -CB and -CU ?

Regards

0 Kudos
Guillaume_De_Nayer
1,045 Views

@-Zaak

Thx for your reply:

Our program is a fluid solver with a lot of subroutines and codes...It is of course parallel and is using MPI.

For the moment I don't find the beginning of the problem. I'm seeing that some arrays are totally wrong and make no sense with intel compiler 14 + -O3. Using these wrong values NaN are generated: just an example:

f = z^(1/7) with z always positive. With intel compiler 14 + -O3, z is sometimes negative...it make no sense...all z are defined by me. of course with z negative, f is NaN.

Regards

0 Kudos
Izaak_Beekman
New Contributor II
1,045 Views

AlGreynolds wrote:

I assume the program has passed checks on array bounds and uninitialized variables by compiling with -CB -CU.  If not, I would start there.

Al 

Yes, turning on all checks and warnings is probably a good idea (-warn -check) but keep in mind that the checks for uninitialized variables will only find some of them, so there could be some lurking even when turning this check on.

0 Kudos
Guillaume_De_Nayer
1,045 Views

I have a dummy question about -CU:

I compile the following test program with ifort -O3 -CU test_uninit.f.

      program test_uninit


      implicit none
      integer a,b,c                                                                                                                                                                     
      a=1                                         
      c=3

      write(*,*) "Hello World",a,b,c

      end

I get an error that b is not initialized. ok. perfect.

Now I'm compiling test_uninit.f with a subroutine sub1.f:

      program test_uninit

      implicit none
      integer a,b,c
                                                         
      c=3

      call sub1(a,b)

      write(*,*) "Hello World",a,b,c

      end
      subroutine sub1(a,b)

      implicit none

      integer a,b

      a=1

      return
      end

And I don't get any error...why ??? b is uninitialized...

0 Kudos
Steven_L_Intel1
Employee
1,045 Views

Because the compiler doesn't know how to check through a subroutine call. It assumes that b may have been stored to in sub1.

0 Kudos
Izaak_Beekman
New Contributor II
1,045 Views

Guillaume De Nayer wrote:

@-Zaak

Thx for your reply:

Our program is a fluid solver with a lot of subroutines and codes...It is of course parallel and is using MPI.

For the moment I don't find the beginning of the problem. I'm seeing that some arrays are totally wrong and make no sense with intel compiler 14 + -O3. Using these wrong values NaN are generated: just an example:

f = z^(1/7) with z always positive. With intel compiler 14 + -O3, z is sometimes negative...it make no sense...all z are defined by me. of course with z negative, f is NaN.

Regards

Right, so you need to figure out why z is becoming negative before you raise it to fractional power, or why a denominator is becoming zero, etc. I *highly* doubt that the compiler is randomly flipping the sign bit due to a compiler bug. If you can find a case were a simple computation produces spectacularly wrong results I’m sure the folks at Intel would want to know about it, but if you *must* run with -O3 then 1) explore the compiler options controlling what optimizations are allowed for floating point optimizations, a good list is in the article I linked to in my first post—certain ones implied by -O3 can individually be turned off—and 2) locate where in your code the computation is running amuck and check that there are no bugs, even subtle ones like race conditions or uninitialized variables.

Otherwise you could just run with -O2

Also, the floating point exception handling features and the intrinsic ieee_exceptions module introduced in F2003 may be useful if you want to hunt down this issue.

0 Kudos
Guillaume_De_Nayer
1,045 Views

Hi,

During the week end I have tested (one more time) my program with:

  •  -g -debug-parameters all -traceback -fpe0 -check all -ftrapuv -debug all -c: I did not find any problem.
  • valgrind: I found some uninitialized variables (which are now set to 0), but I did not solve my problem.

How can I find which optimization options are different between -O2 and -O3 with Intel compiler 14.0 ? I have read the changelog, but it is too complex to understand for me.

Regards,

Guillaume

 

0 Kudos
Greynolds__Alan
Beginner
1,045 Views

I forgot that I also use -ftrapuv option with -CU.  However -ftrapuv causes an internal compiler error with the latest ComposerXE 15.0.0

Al

0 Kudos
Steven_L_Intel1
Employee
1,045 Views

-ftrapuv is useless, but shouldn't trigger an error. Please send us a test case, Al.

We do now have an option "-init snan" but it requires -save as well (at present).

0 Kudos
Greynolds__Alan
Beginner
1,045 Views

If its useless, why is it even available?

Actually it turns out to be the combination of -O0 -xHOST -ftrapuv that causes the ICE in 15.0.0.  Easy to get around.

Al

0 Kudos
Izaak_Beekman
New Contributor II
1,045 Views

Steve, -init snan is going to be a FANTASTIC addition to Fortran developers tools for hunting down un initialized variables, thank you so much for adding this.

0 Kudos
Steven_L_Intel1
Employee
1,045 Views

The initial idea of -ftrapuv was sort of what -init snan is going to end up as - initializing REAL/COMPLEX values to a sNaN. But it wasn't implemented that way - instead variables got initialized to a value that, while "unusual", wasn't a NaN. It also made some subtle changes in the way FP arithmetic was optimized, though I don't know the details.

I've suggested before that -ftrapuv be deprecated, maybe for next year.

While in the 15.0 release, -init snan is for static variables only, we plan to extend that to automatics and allocatables in a future release.

Al, please provide a test case - an ICE is bad no matter what.

0 Kudos
Reply