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

IVF vs CVF Floating Point Results

Krob__Jeff
Beginner
664 Views

All,

Have a project originally built in CVF 6.6 which worked properly. I now have IVF XE 2016 Update 3 and have discovered some calculations dealing with Floating Point are yielding results which are close...but not good enough for proper operations.

Example:

REAL        YGRDPT,XGRDPT,YTSPNT,XTSPNT

INTEGER IXS,IYS

YTSPNT=YGRDPT-FLOAT(IYS)+1.
XTSPNT=XGRDPT-FLOAT(IXS)+1.

 

CVF shows the following:

 XGRDPT,YGRDPT,IXS,IXE,IYS,IYE =    293.9000       109.2000        290    297   106    113
 TSS: IXS/IYS  =     290    106
 TSS: X/YGRDPT =    293.9000       109.2000    
 TSS: X/YTSPNT =    4.899963       4.199997    <<<< GOOD!!
 

IVF shows the following:

 XGRDPT,YGRDPT,IXS,IXE,IYS,IYE =    293.8999       109.2000        290    297   106    113
 TSS: IXS/IYS  =     290    106
 TSS: X/YGRDPT =    293.8999       109.2000    
 TSS: X/YTSPNT =    4.899902       4.200012    <<<< BAD!!
 

So, I converted them to REAL*8...CVF shows this:

 XGRDPT,YGRDPT,IXS,IXE,IYS,IYE =    293.9000       109.2000        290    297
    106    113
 TSS: IXS/IYS  =     290    106
 TSS: FXS/FYS  =    290.0000       106.0000    
 TSS: DX/YGRDPT =    293.899963378906        109.199996948242     
 TSS: DX/YTSPNT =    4.89996337890625        4.19999694824219     
 TSS: X/YGRDPT =    293.9000       109.2000    
 TSS: X/YTSPNT =    4.899963       4.199997        <<<< GOOD!!
 

And IVF shows this:

 XGRDPT,YGRDPT,IXS,IXE,IYS,IYE =    293.8999       109.2000        290    297 106    113
 TSS: IXS/IYS  =     290    106
 TSS: FXS/FYS  =    290.0000       106.0000    
 TSS: DX/YGRDPT =    293.899902343750        109.200012207031     
 TSS: DX/YTSPNT =    4.89990234375000        4.20001220703125     
 TSS: X/YGRDPT =    293.8999       109.2000    
 TSS: X/YTSPNT =    4.899902       4.200012     <<<< BAD!!

The X/YTSPNT result in IVF need to match the results in CVF. How do I get that to occur?

Thanks in advance,

Jeff

 

0 Kudos
9 Replies
Steve_Lionel
Honored Contributor III
664 Views

I'll first direct you to http://sc13.supercomputing.org/sites/default/files/WorkshopsArchive/pdfs/wp129s1.pdf

Next, I'll comment that CVF used x87 floating point which sometimes carried intermediate results in higher than declared precision. If you fully converted to REAL(8), including constants, I might expect closer correspondence, but I have no idea how many operations your code does and there are many places small differences can creep in and magnify. Current compilers do vectorization and other optimizations that can change the order and thus results.

Last, I'll ask how you know that one set of results is good and another is bad. Since you (it would seem) can still run CVF, it would be useful to log to a file intermediate results using each compiler and see where they start to diverge.

The paper I linked to above gives you some tips you may find useful.

0 Kudos
GVautier
New Contributor II
664 Views

Hi

You must post the exact code you used in both cases. I suspect that you don't initialize values as REAL*8 and the result of function "float" is real*4 ("dble" is the  real*8 function).

Real*4 may be not sufficient to reach the precision you aim. The "good" result with cvf may be only fortuitous.

0 Kudos
jimdempseyatthecove
Honored Contributor III
664 Views

When you follow Steve's suggestion of locating place of divergence it would be better to check the components as opposed to end results.

for example check X and YTSPNT as opposed to X/YTSPNT

Also, converting declared variables to REAL(8) is only half the switchover. You also need to assure literal constants are declared as double precision as well (nnn.nnD+x or nnn.nnD-x or nnn.nnD). The compiler will generate the code as specified.

Gilles may have a good point, the error difference is the same in your REAL(4) as it is in the REAL(8) and is located in the 7th place (limits of precision). You may have code that is reducing the precision to REAL(4) in some place.

Jim Dempsey

0 Kudos
GVautier
New Contributor II
664 Views

Furthermore, I don't understand why you said that CVF result are good

CVF shows the following:

 XGRDPT,YGRDPT,IXS,IXE,IYS,IYE =    293.9000       109.2000        290    297   106    113
 TSS: IXS/IYS  =     290    106
 TSS: X/YGRDPT =    293.9000       109.2000    
 TSS: X/YTSPNT =    4.899963       4.199997    <<<< GOOD!!

For me the 6th digit for XTSPNT must be a 9 and the exact result is 4.9 and 4.2. So even with CVF you had problems of precision.

0 Kudos
Krob__Jeff
Beginner
664 Views

>Last, I'll ask how you know that one set of results is good and another is bad

>The "good" result with cvf may be only fortuitous

>Furthermore, I don't understand why you said that CVF result are good

sigh...understand, this little snippet is part of a much larger gridded data analysis program (that I inherited in it's DOS version) and this specific value is used in a bilinear interpolation routine to collect and display data from a specific point on the earth which may not be exactly on a data point but surrounded by data points. Using the same data set, the DOS version (unknown compiler - MS Powerstation?), the Quickwin version (CVF), the Windows version (CVF) all display the same data result. The Debug Log shows the reference X/Y data point value used in the interpolation to be X= 4.899963, Y=4.199997. They were all consistent. now, when I updated to IVF, & that X/Y data point is now calculated to be: X=4.899902, Y=4.200012 with the same input values to the equation, the resulting data is inconsistent & therefor wrong. If I force that X/Y value to the value calculated by CVF, the data display is consistent with the previous versions. *THAT* is how I know it is good.

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
664 Views

Try adding (individually then together)

/fp:precise
/fp:source
/Qprec
 

You also may want to look at the /Qimf-.... options

Jim Dempsey

0 Kudos
Krob__Jeff
Beginner
664 Views

Jim,

 

I have been switching/comparing all those different fp- options w/ no change. I'm not familiar with the /Q flags...and you can combine those? What file is to be edited to include them all - the 'Properties' dialog is an either/or single selection?

>CVF used x87 floating point...

I presume when CVF & IVF merged, that x87 model was not included as an option for compilation/operational consistency?

If IVF does not use the x87 model, which model does it use - IEEE, something else?

Jeff

0 Kudos
Steve_Lionel
Honored Contributor III
664 Views

The x87 instructions use the floating point stack, which would sometimes carry intermediate results in higher than declared precision, though this mostly affects single-precision. Intel Fortran uses SSE instructions which are vectorized and much faster, but always use declared precision. The floating point format is still IEEE.

The "merge" of CVF and Intel Fortran was to keep the Fortran-specific "front-end" and support library from CVF, and use Intel's code generator, optimizer and math library. You can try using /arch:ia32 if you want to revert to x87, but don't expect you'll get identical results with CVF. Better is for you to understand which computation(s) create differences and which one is more correct.

0 Kudos
andrew_4619
Honored Contributor II
664 Views

x87 is Math co-processor instruction set from first generation PC's from the 80s,......

x87 is a floating-point-related subset of the x86 architecture instruction set. It originated as an extension of the 8086 instruction set in the form of optional floating-point coprocessors that worked in tandem with corresponding x86 CPUs.

0 Kudos
Reply