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

Floating Point Consistency

Kantor__Baruch
Beginner
1,050 Views

Hi

I'm upgrading a CVF application that relies heavily on single precision floating point calculations.

I'm using the "Enable Floating Point Consistency" and "Extend Precision of Single Precision Constants".

Currently I create IA-32 Fortran DLL on XE.

 

From comparing the results of the CVF and XE versions I see that the CVF application is more precise.

It looks like in CVF there are more significant digits (or half digits).

I've read previous posts regarding Floating Point Consistency, including referred documents and presentations.

I've tried all possible combinations of the Fortran Floating Point Settings and still can not recreate precisely CVF results.

Will be grateful for any insight on this.

Baruch

 

0 Kudos
11 Replies
Steve_Lionel
Honored Contributor III
1,050 Views

First, read http://sc13.supercomputing.org/sites/default/files/WorkshopsArchive/pdfs/wp129s1.pdf

CVF did not use SSE instructions for floating point - it used the X87 registers and instructions. Sometimes this would keep intermediate results in "higher than declared" precision, leading to the effect you noticed. It was not something you had any control over, though.

If you need better precision then you should do key computations (if not all of them) in a higher precision data type/

0 Kudos
mecej4
Honored Contributor III
1,050 Views

It does not make sense to me that you program using  single-precision and then complain when the results are not sufficiently precise. With x87 arithmetic, you might have obtained better precision in intermediate results, and perhaps better precision even in some final results, than with single-precision SSE2 arithmetic. The more important question: do you get sufficiently accurate results using double-precision SSE2 (or more recent) FPU arithmetic?

0 Kudos
Kantor__Baruch
Beginner
1,050 Views

Steve,

I've read this presentation but it does not include the point you've raised ragerding the X87 instructions.

Your explanation seems to perfectly support my findings. I guess I cannot make XE use X87 (?)

 

mecej

Tho code I use was written 30 to 40 years ago with tens of thousands of lines.

To change it to double precision will not be a straightforward task.

Thank you!

0 Kudos
mecej4
Honored Contributor III
1,050 Views

Kantor, Baruch wrote:
 Tho code I use was written 30 to 40 years ago with tens of thousands of lines.

To change it to double precision will not be a straightforward task. 

In that case, see how far the compiler's /real-size:64 will help you. From the documentation for the Intel Fortran compiler:

Makes default real and complex declarations, constants, functions, and intrinsics 8 bytes long. REAL declarations are treated as DOUBLE PRECISION (REAL(KIND=8)) and COMPLEX declarations are treated as DOUBLE COMPLEX (COMPLEX(KIND=8)). Real and complex constants of unspecified KIND are evaluated in double precision (KIND=8).

 

 

0 Kudos
Kantor__Baruch
Beginner
1,050 Views

mecej4

I wish I could use this option but I'm limited with structures of existing binary data files and communication ICD's and API with other programs that I can not change.

0 Kudos
Steve_Lionel
Honored Contributor III
1,048 Views

The paper doesn't specifically address X87 - the initial audience for the paper wouldn't be caught dead using X87 floating - but it does fall under instruction set differences (not to mention compiler differences.) Your situation is one I have seen before where a particular result is "accepted as correct" and then no deviation is allowed. In the end, especially given the distance in time and hardware, you may have little choice but to either accept the newer results or put in the effort to update the application so that it declares the precision it requires.

0 Kudos
Kantor__Baruch
Beginner
1,048 Views

Steve,

My problem is to justify buying new compiler licenses and then spend hundreds of working hours just to get the same (correct) result.

I've tested some specific calculations and no doubt: CVF was much more precise in single precision arithmetic.

We are commercial company and the managers are not ready spend time and money just to use 2018 software and not 1998...

CVF worked for 20 years and will continue to work for another 20 years.

Thank you

Baruch

0 Kudos
Steve_Lionel
Honored Contributor III
1,048 Views

CVF was also inconsistent - you had no control over when an expression was kept in extended precision and when it was rounded to single. I disagree that the results were "correct". How exactly did you determine that they were correct - did you do extensive numerical and computational analysis on each calculation? Or did you look at the results from CVF, say they "looked right", and called it a day?

If CVF continues to work for you, that's fine, but the development environment is completely unsupported on modern Windows versions.

0 Kudos
Kantor__Baruch
Beginner
1,050 Views

You are right of course that when the computation are complex the precision on the X87 single is not consistent - depends of the usage of the X87 registers.

My software is made of large number of quite simple formulas so it is less relevant to me.

I took some atmospheric formulas, integration and linearization routines and converted them to double precision.

The CVF results (single) were much closer to double. In system linearization the differences were rather large.

Looking on state variables like altitude it is obvious that the the granularity of the smallest changes in CVF are much smaller than in XE.

Thank you

 

0 Kudos
TimP
Honored Contributor III
1,050 Views

The use of extended precision in CVF should be mostly matched by 32-bit ifort with setting of IA32 instruction set.  As these applications are normally run with x87 precision set (by default with CVF and ifort) to 53 bits, it is equivalent to promoting intermediate calculations with REAL(x,REAL64) or, in F77, dble().  As Steve pointed out, you have no control over where CVF or ifort do this automatically for the "IA32" target,and ifort may not exactly match CVF. 

If you wish to take the trouble, you may insert explicit promotions in your code for each expression involving 3 or more operands.  Due to the mixed data type promotion rules of Fortran,  one insertion of dble() will take care of a 3 operand expression in some cases (like A*REAL(X,REAL64)+B). Of course, this REAL64 (if you don't define it yourself) depends on USE ISO_FORTRAN_ENV, which ifort has supported in recent years.  You could make up your own named module or internal function to abbreviate the verbose REAL intrinsic while improving future portabiity compared with DBLE(). Then you could expect portability to Intel64 targets.  It may be necessary, or at least helpful, to declare all local scalar variables as REAL(REAL64).  REAL(8) would work with ifort compatible compilers, but it is poor style.

When using simd instruction sets, which you probably are doing, as ifort defaults to /arch:SSE2, mixed single and double precision are likely to reduce performance, hence the preference of previous replies to suggest full doube precision.

0 Kudos
Kantor__Baruch
Beginner
1,050 Views

Altitude.png

Tim,

I've considered such options but if I'll get the budget I will go all the way to double precision calculations while keeping ICD's and API intact.

Above you can see the diffrence between the two compilers. The XE results were with arch:IA32 settings.

0 Kudos
Reply