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

differet result when compile with ifort and f95

leo_ma
Principiante
1.192 Visualizações
Today I install the intel fortran compiler for linux into my machine. I try to compile a program as below:

program try

real*8 a, b, c
real a_hi, a_lo
real b_hi, b_lo
real c_hi, c_lo
real t1, t2, e

a=1.1111111111111111111111111d0
b=2.2222222222222222222222222d-2

a_hi=a
b_hi=b
c_hi=c
a_lo=a-a_hi
b_lo=b-b_hi
t1=a_hi+b_hi
e=t1-a_hi
t2=((b_hi-e)+(a_hi-(t1-e)))+a_lo+b_lo

print *, ((b_hi-e)+(a_hi-(t1-e)))
print *, a_lo, b_lo

c_hi=t1+t2

print *, t2, c_hi, t1

c_lo=t2-(c_hi-t1)

c=c_hi+c_lo

print *, a, a_hi, a_lo
print *, b, b_hi, b_lo
print *, c, c_hi, c_lo

print *, a+b

end

However, the answer is different when I compile when f95 and ifort. The result of f95 is correct, but of ifort is ...... Anybody knows what is happening?

0 Kudos
7 Respostas
Steven_L_Intel1
Funcionário
1.192 Visualizações

What results do you think are correct and why? Does adding "-fp_model source" help? Your program is sensitive to low-order precision differences and on IA-32 systems when the X87 floating registers are used, results can seem odd as expressions are maintained in a higher precision "for a while".

What exactly are you testing here?

leo_ma
Principiante
1.192 Visualizações
Dear Steve,

It is a program to calculate double precision addition, by using single precision variable. The formula (not created by me) is as follows:

1) Compute high-order sum and error
t1=a.hi+b.hi
e=t1-a.hi

2) Compute low order term including error and overflows
t2=((b.hi-e)+(a.hi-(t1-e)))+a.lo+b.lo

3)Normalise to get final result
c.hi=t1+t2
c.lo=t2-(c.hi-t1)

By using f95 compile, I got the output is:
-5.7742000E-08
-5.2981907E-08 -5.3809751E-10
-1.1126200E-07 1.133333 1.133333
1.11111111111111 1.111111 -5.2981907E-08
2.222222222222222E-002 2.2222223E-02 -5.3809751E-10
1.13333333333333 1.133333 7.9472855E-09
1.13333333333333

It successfully repoduce the double precision result 1.13333333333333, which is same as the one by simpily adding two double precision.

When I compile it with ifort, the output is:
0.0000000E+00
-5.2981907E-08 -5.3809751E-10
0.0000000E+00 1.133333 1.133333
1.11111111111111 1.111111 -5.2981907E-08
2.222222222222222E-002 2.2222223E-02 -5.3809751E-10
1.13333344459534 1.133333 0.0000000E+00
1.13333333333333

The value of ((b_hi-e)+(a_hi-(t1-e))) is 0.0000000E+00. But its value in -5.7742000E-08 is f95 compile, it should not encounter underflow.

When I compile it with ifort -fp-model strict or -fp-model source, the output is:
-5.7742000E-08
-5.2981907E-08 -5.3809751E-10
-1.1126200E-07 1.133333 1.133333
1.11111111111111 1.111111 -5.2981907E-08
2.222222222222222E-002 2.2222223E-02 -5.3809751E-10
1.13333332538605 1.133333 7.9472926E-09
1.13333333333333

The result is enchanced, but still not the expecting answer as in the f95 compiler.

Do you know what is the problem? Moreover, when do I need to use -fp-model?

Anyway, thanks for your help.

Leo Ma
Steven_L_Intel1
Funcionário
1.192 Visualizações

Whose "f95" are you using and on what system?

This type of calculation can be a problem on IA-32 systems when the X87 extended precision registers are used, as you can get inconsistent results when subtracting two similar values.

-fp-model strict (source means the same in Fortran, it has a different meaning in Intel C++) asks the compiler to round intermediate results to declared precision, but because the extended precision registers are used, you may still get some odd cases. I would have to take a lot of time to analyze your program to see wht the one value is not as expected when -fp-model strict is used.

leo_ma
Principiante
1.192 Visualizações
Dear Steve,

The f95 should be "gcc version 4.0.0 20050519 (Red Hat 4.0.0-8)"

The kernal of the linux is "2.6.11-1.1369_FC4".

Are they those informations that you need?

Moreover, since such problem should be due to the conversion from single to double precision and vice versa, does it mean that if I stick on double precision on other programs, such problem would not occur?

Best Regards,
Leo Ma
TimP
Colaborador honorário III
1.192 Visualizações

gcc-4.0 is not recommended by its own developers, particularly not for Fortran. Calling it f95 certainly doesn't tell us you are using an obsolete version of gfortran. I would like to see more numerical compatibility between gfortran and ifort, and I see some signs of progress, but you won't get it by choosing inappropriate versions.

As you don't care to tell whether you are using 32- or 64-bit compilers, or what compile options you are using, there is little value in commenting. While both gfortran and ifort default to -O0 when you set -g, the default options otherwise are entirely different between those compilers. If you consider a particular set of options to be "correct," you should specify similar options for both compilers.

leo_ma
Principiante
1.192 Visualizações
Dear Tim,

Both compilers should be a 32-bit, and I didn't add any options to the command line. I follow your comment, I add the "-g" to the command line. Surprisingly, it gave me the expecting result. Do you mean that the error is due to the default optimisation?

Best regards,
Leo Ma

TimP
Colaborador honorário III
1.192 Visualizações

Unfortunately, ifort doesn't respect parentheses at default optimization. -fp-model strict should have corrected that. Beyond that, as Steve hinted,your code looks as if it were intended to show differences when run with extra precision,as you appear to be doing when you permit optimization. For example, if you are running on a pentium4, you might use

gfortran -O2 -march=pentium4 -mfpmath=sse

and

ifort -xW -fp-model precise

in an attempt to specify normal usage of SSE and SSE2 code with similar options for both compilers.

You may get similar results for -g with no other options, if results are stored to memory format frequently enough to suppress extra precision effects, even though you use extra precision where the default real is not distinguished from real*8 "for a while."

It still would be advisable to upgrade both compilers to current versions, and study what you areattempting to find out with this code,before trying to draw any conclusions from these tests.

Responder