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

Floating point model confusion

uha
Novice
1,157 Views

I´m comparing the behaviour using ifort and ifx and floating point models fast, precise and source. I cannot relate the observed behaviour to the documentation. The compiler references both for 2023 and 2024.1 claim that "source" is the same as "precise", and there is no special note on any different behaviour between ifort and ifx. The ifort to ifx porting guide however states: "-fp-model=source (/fp:source) is not supported because it is equivalent to -fp-model=precise [...]"

So I made my own little test (with exception handling /fpe:0):

 

  subroutine test()
    real :: a, b, c
    integer :: i
    a = 1e-10
    b = 1e-11
    i = 0
    do while(.true.)
      i = i + 1
      c = a * b
      if(c .eq. 0.0) exit
      b = b / 1.00001
    enddo

    write (*, '(i8,x,3(g15.8,x))') i, a, b, c
  end subroutine test

 

Now I would have expected that at least with ifort "source" and "precise" give the same result. The table shows the number of iterations until c becomes zero:

uha_0-1715696198340.png

So it looks like both compilers treat "source" as "fast" instead of "precise"? If that is the case, do you know if it has always been like that with ifort, or if not, when it started to do that?

0 Kudos
6 Replies
Ron_Green
Moderator
1,114 Views

I cannot reproduce your numbers.  On my system I get 5554341 for both precise and source.  This was with v2024.1.0, linux, Fedora 40, 

Intel(R) Core(TM) i5-7600.  -O2 and -O2 -xhost

When the Porting Guide was written, it was true that source and precise were the same.  Now there are some differences in the backend compiler options that they invoke. You can examine all compiler defines and backend options by adding this option

-#

 

Doing so and diff'ing the results

precise

-noftz

-fp-model precise

-fp-modbits no_ftz

 

source

-assume protect_parens

 

Note that source does not set ftz but adds assum protect_parens.   precise passes this option to the backend to prevent value unsafe optimizations, source does not.  

 

I will ask the Support team to edit the Porting Guide to remove the old information on precise and source

Ron_Green
Moderator
1,092 Views

I stand corrected.  I spoke to a backend developer for our fp model.  Although the driver does pass different options to the backend, the backend processes source as precise.  You can confirm by saving binaries from both option cases.  You will see that the binaries are identical. 

uha
Novice
1,040 Views

Thanks Ron for looking into this. I´m on v2024.1.0, Windows 10, 11th Gen Intel(R) Core(TM) i7-11850H.

I did some more tests using command line builds - I don´t usually do that so bear with me if something is not optimal. These are my builds:

ifx FpModel.f90 Console1.f90 /O2 /fpe:0 /module:"x64\Release\\" /object:"x64\Release\\" /libs:dll /threads -o "ifx\Console_fpe0_Ftz_fast.exe"
ifx FpModel.f90 Console1.f90 /O2 /fpe:0 /module:"x64\Release\\" /object:"x64\Release\\" /libs:dll /threads /fp:source -o "ifx\Console_fpe0_Ftz_source.exe"
ifx FpModel.f90 Console1.f90 /O2 /fpe:0 /module:"x64\Release\\" /object:"x64\Release\\" /libs:dll /threads /fp:precise -o "ifx\Console_fpe0_Ftz_precise.exe"
ifx FpModel.f90 Console1.f90 /O2 /fpe:0 /module:"x64\Release\\" /object:"x64\Release\\" /libs:dll /threads /Qftz- -o "ifx\Console_fpe0_NoFtz_fast.exe"
ifx FpModel.f90 Console1.f90 /O2 /fpe:0 /module:"x64\Release\\" /object:"x64\Release\\" /libs:dll /threads /fp:source /Qftz- -o "ifx\Console_fpe0_NoFtz_source.exe"
ifx FpModel.f90 Console1.f90 /O2 /fpe:0 /module:"x64\Release\\" /object:"x64\Release\\" /libs:dll /threads /fp:precise /Qftz- -o "ifx\Console_fpe0_NoFtz_precise.exe"

My results:

Console_fpe0_Ftz_fast.exe:     3893013
Console_fpe0_Ftz_source.exe:   3893013
Console_fpe0_Ftz_precise.exe:  5554341
Console_fpe0_NoFtz_fast.exe:   5554341
Console_fpe0_NoFtz_source.exe: 5554341
Console_fpe0_NoFtz_precise.exe:5554341

The only 2 that are binary identical are Console_fpe0_NoFtz_fast.exe and Console_fpe0_NoFtz_source.exe.

This _does_ look like "source" and "precise" differ in the ftz setting? Just on Windows maybe?

0 Kudos
Ron_Green
Moderator
1,034 Views

I see fpe:0 in your options.  That has a dramatic effect on optimizations.  Can you remove that option and try again?

Also, Windows ifx does accept the option

-#

to dump all the defines and backend options used by the compiler.  

I can try this test on my Windows machine as well.

uha
Novice
961 Views

I tried with all combinations of source/precise, fpe0/none, and ftz-/none and using the -# switch. In summary these are the relevant settings and the resulting settings to the backend:

uha_0-1715858395773.png

(+: specified, -: not set)

So the only case where source and precise are the same is when you do _not_ set fpe0 and _do_ set ftz, and in this case the executables indeed are binary identical.

So when the docs (or your developer) say "source" and "precise" are the same, does that just refer to the backend, but the front end setting does more than just setting the backend fp-model?

Interesting you say "fpe0" has "dramatic" effects on optimization. We´ve had it like that probably for decades, I doubt there is still anybody around remembering the exact reasoning behind it. Maybe it´s time for a review.

 

0 Kudos
Ron_Green
Moderator
892 Views

The architect for our FP model is on the C++ team.  So he was unfamiliar with our Fortran driver and was indeed speaking of the backend fpmodel.  What I wonder is if our Fortran drivers should be setting ftz automatically for precise AND source.  I will consult with our Fortran architect and driver developer to see what we should be doing for these 2 fp models with respect to ftz.   The question is from a very high level, should "source" expression evaluation preclude flush to zero, or allow flush to zero?  "Source" means evaluate the expressions according to the rules of Fortran expression evaluation.  Something I will research.

 

fpe0 allows floating point exceptions.  Without going into great detail on compiler optimizations and design, any time you can have an early exit or exception exit will cause the compiler to avoid certain optimizations.  it's complicated to explain all the cases.  If you have some familiarity with compiler terminology, there is an optimization called 'basic block reordering' as an example.  This optimization is disabled in the presence of fpe0.  

That said, if your application does work with very small numbers, very large numbers, or can create NaNs or underflow/overflow then you do want to enable FP exceptions.  And certainly when you are making modifications to the code and want to check for unusual conditions during debug you do want fp exceptions.  For production,for a stable code that is unlikely to generate NaNs, underflow or overflow, etc then you probably don't want or need fpe0.  But if your code is used by humans prone to error and their faulty input for a run can cause bizarre side effects, I'd want fpe0 and -g -traceback in my application build.

0 Kudos
Reply