I have a rather long experience with scientific fortran programming
the last 20 years.
Recently I noticed the following problem with intel fortran em64t
compilers:
I have access to 3 differtent types of intel-CPU linux computers
running either intel ifort
(versions 9, 10 and 11) or g77:
(a) Pentimum 4 using intel 32-bit compilers
(b) Dual core Itanium 2 (linux ia64) using intel 64 compilers
(c) Intel Xeon 5300 quad core Processor (linux x86_64) using intel
em64t compilers
My fortran code solves over-determined systems using LAPACK DGELS
Least-Squares solver
while mainly I compile my code with ifort and MKL.
Machines (a) and (b) produce results identical to 9 significant digits
(s.d.) but machine (c)
produce results with only 4 s.d. Note that my code uses double-
precision and the systems
are well-conditioned, and thus I expect very limited round-off error,
and in particular,
agreement close to 14 s.d.
To investigate where is the problem with machine (c), I added LAPACK
and BLAS
double-precision subroutines into my code and compiled with ifort
(without MKL) and g77.
I got the same behavior.
Thus on machines (a) and (b), ifort (with or without MKL) and g77
produce results identical to
9 s.d. as does g77 on machine (c).
The problem is with ifort (with or without MKL) on machine (c) which
produces results
identical to 4 s.d. - this is a major issue with me since after
several thousand steps
the low-accuracy/high round-off error results in failure and the
running breaks down.
This problem seems to exist with Least-Squares solver DGELS - for
square systems using LU decomposition DGESV all machines and all
different compilations produce results identical to 9 s.d.
So, has anyone seen this issue/problem? Origin of problem? Any
possible solution?
--------------------------------------------------------------------------------------------------------------------------------------------
I do have an additional question:
Since my code uses double-precision and the systems are well-
conditioned,
I expect agreement close to 14 s.d - not the 9 s.d I get at the very
best.
In the past, on other types of processors (e.g AIX and SGI
workstations)
I was able to get 14 s.d. but not on current INTEL-based computers.
Is this a limit of the recent INTEL processors since this behavior
seems to be independent
of the compilers used (ifort or g77)?
--------------------------------------------------------------------------------------------------------------------------------------------
Many thanks in advance!
/PB
> Machines (a) and (b) produce results identical to 9 significant digits
> (s.d.) but machine (c) produce results with only 4 s.d. Note that my code
> uses double- precision and the systems are well-conditioned, and thus I
> expect very limited round-off error, and in particular, agreement close to
> 14 s.d.
This being a Fortran newsgroup, it is probably a good place to ask
Fortran questions... but you don't show any Fortran. There are *LOTS* of
ways to accidentally lose precision. Some of them relate to
ill-conditioning, which you claim not to be an issue here, but some are
also simple matters of Fortran syntax. Without seeing code, there isn't
much I could offer other than random speculation.
To toss out one such random speculation, literal constants written in
default precision syntax are a reasonably common source of such
problems. Yes, the results of such things do vary from compiler to
compiler.
--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
If you're using g77, then your code should be compatible with
ftnchek. Get a copy of ftnchek and fix all warnings. In particular,
see Richard Maine's post about literal constants.
Try using the compilers options for turning on warnings. With
g77 use -Wall -Wextra -Wsurprizing, among a host of other options
that I currently ron't remember.
LAPACK normally reports a condition number. Are you checking the
returned condition number against your expectations?
--
steve
Richard and Steve:
I realized that I forgot to mentioned some details on my code:
I use f77 fortran and I have double-checked my code with ftnchek;
and yes I always write very carefully using double precision constants
(e.g. 3.5d0) and all my real variables are defined to be real*8.
(The code is quite complicated and long to be included in a message.)
Note that on machine (c) g77 works ok - it is the
intel ifort em64t compiler which produces the low 4 s.d. agreement.
> I have access to 3 differtent types of intel-CPU linux computers
> running either intel ifort
> (versions 9, 10 and 11) or g77:
> (a) Pentimum 4 using intel 32-bit compilers
> (b) Dual core Itanium 2 (linux ia64) using intel 64 compilers
> (c) Intel Xeon 5300 quad core Processor (linux x86_64) using intel
> em64t compilers
> Machines (a) and (b) produce results identical to 9 significant digits
> (s.d.) but machine (c)
> produce results with only 4 s.d. Note that my code uses double-
> precision and the systems
> are well-conditioned, and thus I expect very limited round-off error,
> and in particular,
> agreement close to 14 s.d.
Please post and provide more details in our user forum (link below). In
particular, please tell us which compiler options you are using. If you
can provide a test case, that would be best as otherwise all we can do
is speculate.
It would be interesting for you to take the executable from system a and
run it on system c to see if it gets different answers. For this test,
be sure you are not using the "-ax" option that does automatic CPU type
dispatching.
--
Steve Lionel
Developer Products Division
Intel Corporation
Nashua, NH
For email address, replace "invalid" with "com"
User communities for Intel Software Development Products
http://software.intel.com/en-us/forums/
Intel Software Development Products Support
http://software.intel.com/sites/support/
My Fortran blog
http://www.intel.com/software/drfortran
>
> Note that on machine (c) g77 works ok - it is the
> intel ifort em64t compiler which produces the low 4 s.d. agreement.
Besides, when using ifort, you should be using options such as
-assume protect_parens,minus0,byterecl -prec-div -prec-sqrt
for compatibility with standards and other compilers. Your failure to
discuss this indicates you are likely using inconsistent options.
g77 32-bit defaults to x87 extended 80-bit format for evaluation of
expressions; I never had much luck with g77 64-bit.
Dear Steve and Tim:
Many thanks for your answers.
Using ifort I compiled my code using:
ifort -O2 program.f -o program
or via MKL with:
ifort [-openmp] -O2 program.f -L$MKLPATH \
-Wl,--start-group $MKLPATH/libmkl_intel_lp64.a $MKLPATH/
libmkl_intel_thread.a \
$MKLPATH/libmkl_core.a -Wl,--end-group -liomp5 -
lpthread \
-o program
i.e. w/o any Floating Point options thinking that the same version of
compiler will have the same default FP options on the different
machines.
Compiling again by adding -mp or the faster -fp-model precise before -
O2
in the commands above, I manage to get at least 9 s.d. agreement on
all types of machines.
As Steve suggested, transfering the executable from machine (a) to
machine (c)
I got identical results to the 14 s.d. I print out.
Using -assume protect_parens,minus0,byterecl -prec-div -prec-sqrt
(without -mp or -fp-model precise) it did not improve the results
on machine (c), i.e I still got 4 s.d. agreement.
Tim, may I suppose that the options you suggested need to be combined
with
some -fp-model option?
Based on the above I have the following two questions:
(a) What are the Floating Point options (or any options affecting
precision)
used in compiling MKL by intel?
(b) If somebody wants to receive the maximum combatability or FL
precision
what are all the options he has to use in compiling with ifort?
Many thanks again!
> I realized that I forgot to mentioned some details on my code:
>
> I use f77 fortran and I have double-checked my code with ftnchek;
> and yes I always write very carefully using double precision constants
> (e.g. 3.5d0) and all my real variables are defined to be real*8.
> (The code is quite complicated and long to be included in a message.)
>
> Note that on machine (c) g77 works ok - it is the
> intel ifort em64t compiler which produces the low 4 s.d. agreement.
I wonder if you are specifying a single-precision square root function
in an environement where there are reserved names for the various
levels of desired precision?
| Machines (a) and (b) produce results identical to 9 significant digits
| (s.d.) but machine (c)
| produce results with only 4 s.d. Note that my code uses double-
| precision and the systems
| are well-conditioned, and thus I expect very limited round-off error,
| and in particular,
| agreement close to 14 s.d.
Problems such as you describe are likely to be caused by
real constants having default precision instead of double precision.
If you expect double precision results, constants need to be written
with D0 or Dsomething (except possibly integral constants such as 1. and 2. etc
(but even then, care may be required).
You may also have mis-matched arguments with corresponding dummy arguments.
Then you need to re-check your constants.
Still no code.
This is like "My car won't start. What's wrong with it".
Withourt code, this will go nowhere.
"News user" <ara...@gmail.com> schrieb im Newsbeitrag
news:cfc2b911-5c1f-4513...@j24g2000yqa.googlegroups.com...
> Hi there:
>
> I have a rather long experience with scientific fortran programming
> the last 20 years.
> Recently I noticed the following problem with intel fortran em64t
> compilers:
>
> I have access to 3 differtent types of intel-CPU linux computers
> running either intel ifort
> (versions 9, 10 and 11) or g77:
> (a) Pentimum 4 using intel 32-bit compilers
> (b) Dual core Itanium 2 (linux ia64) using intel 64 compilers
> (c) Intel Xeon 5300 quad core Processor (linux x86_64) using intel
> em64t compilers
>
> My fortran code solves over-determined systems using LAPACK DGELS
> Least-Squares solver
> while mainly I compile my code with ifort and MKL.
Once I wrote a least square program using QR decomposition
in C. I dropped the idea of doing it in Fortran because there's
better control of data types and subsequently
rounding behavior in C.
> Machines (a) and (b) produce results identical to 9 significant digits
> (s.d.) but machine (c)
> produce results with only 4 s.d. Note that my code uses double-
> precision and the systems
> are well-conditioned, and thus I expect very limited round-off error,
> and in particular,
> agreement close to 14 s.d.
> So, has anyone seen this issue/problem? Origin of problem? Any
> possible solution?
I can't help on that.
> --------------------------------------------------------------------------------------------------------------------------------------------
> I do have an additional question:
>
> Since my code uses double-precision and the systems are well-
> conditioned,
> I expect agreement close to 14 s.d - not the 9 s.d I get at the very
> best.
That depends on the number of calulations for example
the system size: the relative rounding error grows
exponential with the number of consecutive calculations.
> In the past, on other types of processors (e.g AIX and SGI
> workstations)
> I was able to get 14 s.d. but not on current INTEL-based computers.
With the same system size or pretty well done examples?
64 bit processors may include the fused multiply add
instruction not found on the x86 or x86-64 platform.
> As Steve suggested, transfering the executable from machine (a) to
> machine (c)
> I got identical results to the 14 s.d. I print out.
Ok, this is a big clue. Machine (a) is 32-bit and machine (c) is
64-bit. The function return and argument passing conventions are
different enough so that type mismatches which may go undetected in
32-bit mode will cause strange problems in 64-bit mode. You ran the
32-bit program on machine (c) and it worked as you wanted.
Try adding the option "-warn interface" to your ifort build and see if
it reports any problems. (If not using version 11.1, add
"-gen_interface" as well.) I'm guessing that you have mismatched types
in arguments or function return values.
> Once I wrote a least square program using QR decomposition
> in C. I dropped the idea of doing it in Fortran because there's
> better control of data types and subsequently
> rounding behavior in C.
Eh? I suppose you must be referring to something other than the C
standard, which I don't recall as saying anything more about about
floating-point data types or rounding issues than Fortran 77.
Traditional C is noted for its distinct lack of user control over even
such basic things as whether a function returns single or double
precision. I also suppose you must be omitting complex data type.
Although standard f77 was severely shortchanged in regards to complex
type, it wasn't as much so as the C standard of the same time frame.
If one moves to time frames a little more recent, I suppose you must
also be referring to some time prior to f90, much less f95+IEEE TR. That
would seem to rule out too recent.
All in all, I find myself at a loss to guess what you might be referring
to. For floating point numerics, I'm much more used to hearing about the
shortcommings of standard C. See NCEG (Numerical C Extensions Group),
which is specifically about addressing those shortcommings.
"Richard Maine" <nos...@see.signature> schrieb im Newsbeitrag
news:1jbff4h.17lx0qbyblyomN%nos...@see.signature...
> Ronald Benedik <rben...@fsmat.htu.tuwien.ac.at> wrote:
>
>> Once I wrote a least square program using QR decomposition
>> in C. I dropped the idea of doing it in Fortran because there's
>> better control of data types and subsequently
>> rounding behavior in C.
>
> Eh? I suppose you must be referring to something other than the C
> standard, which I don't recall as saying anything more about about
> floating-point data types or rounding issues than Fortran 77.
> Traditional C is noted for its distinct lack of user control over even
> such basic things as whether a function returns single or double
> precision.
I refered to gcc. You must refer to the math library of C.
even my sqrt function was done in float, double or long double.
> I also suppose you must be omitting complex data type.
Thats true I programmed only only float, double or long double precision.
> Although standard f77 was severely shortchanged in regards to complex
> type, it wasn't as much so as the C standard of the same time frame.
I never used Fortran 77 but only Fortran 90 or HPF.
> If one moves to time frames a little more recent, I suppose you must
> also be referring to some time prior to f90, much less f95+IEEE TR. That
> would seem to rule out too recent.
Maybe I didn't get something about Fortran but where the
heck is the sizeof() feature in Fortran 90?. I can control
FPU and SSE register rounding mode in C. It is not possible
in Fortran 90.
> All in all, I find myself at a loss to guess what you might be referring
> to. For floating point numerics, I'm much more used to hearing about the
> shortcommings of standard C. See NCEG (Numerical C Extensions Group),
> which is specifically about addressing those shortcommings.
I see newer Fortran compilers more controlled by shell variables
what I consider a mistake.
> "Richard Maine" <nos...@see.signature> schrieb im Newsbeitrag
> news:1jbff4h.17lx0qbyblyomN%nos...@see.signature...
> > Ronald Benedik <rben...@fsmat.htu.tuwien.ac.at> wrote:
> >
> >> ...there's
> >> better control of data types and subsequently
> >> rounding behavior in C.
> >
> > Eh? I suppose you must be referring to something other than the C
> > standard,
> I refered to gcc.
Ah. Ok. Well, that explains most of your comments then. You are talking
about a particular C compiler - not the C language. That's a rather
large difference.
> Maybe I didn't get something about Fortran but where the
> heck is the sizeof() feature in Fortran 90?.
Sizeof is not very directly meaningful in terms of floating point.
That's much more a storage issue. See the numeric inquiry functions
(digits, epsilon, huge, maxexponent, minexponent, precision, radix,
range, and tiny) for things much more pertinent to floating point. Also
see selected_real_kind. For integers, there is bit_size, though again
that isn't directly about storage.
If you do want storage size, its a bit awkward to do with guaranteed
portability in f90, although there are ways that usually work,
particularly if one restricts oneself to a particular compiler, as you
did with gcc. For example, gcc these days stands for the Gnu Compiler
Collection, which incldes Fortran. With that kind of restriction, it is
easy enough. F2003 adds some options, though not the more general
storage_size that I proposed. (I think it is in f2008). But again, if
you are talking floating point, sizeof is just the wrong tool; probably
a case of having a hammer and therefore using it for the screw even
though it doesn't quite match.
> I can control
> FPU and SSE register rounding mode in C. It is not possible
> in Fortran 90.
Per above, that's with a particular C compiler and a particular support
library (not the standard C support library) - not a feature of the C
language. If that's what you are talking about, that probably explains
most of your comments. One can do lots of things with particular Fortran
compilers as well.
In terms of the actual language standards, things are very different.
See the IEEE features of f2003 or F95+TR.
> Ronald Benedik <rben...@fsmat.htu.tuwien.ac.at> wrote:
>
> > Once I wrote a least square program using QR decomposition
> > in C. I dropped the idea of doing it in Fortran because there's
> > better control of data types and subsequently
> > rounding behavior in C.
>
> Eh? I suppose you must be referring to something other than the C
> standard, which I don't recall as saying anything more about about
> floating-point data types or rounding issues than Fortran 77.
Nit: C (since C89) required three nominal types: float=single, double,
and long-double. But they need not be distinct, and in particular
long-double is often the same as double. (And double can be the same
as single if it's big enough e.g. 60-bit hardware.)
But C allowed as much machine-dependence/variation on the exact
details of each of the standard types, which I think was your point.
> Traditional C is noted for its distinct lack of user control over even
> such basic things as whether a function returns single or double
> precision. I also suppose you must be omitting complex data type.
No, C always (even before C89) declared the return type of a function,
except for implicit int -- and that was still fully determined, just
not explicit. Until C99 it promoted _arguments_ from single to double;
and still does for variadic e.g. *printf, or oldstyle (deprecated).
And as noted downthread, until C99 the std-lib math routines (sqrt,
sin, etc., which includes pow) were only double.
> Although standard f77 was severely shortchanged in regards to complex
> type, it wasn't as much so as the C standard of the same time frame.
>
There wasn't _any_ de-jure C standard then. <G> But yes, C both in
standard and usual implementation only recently got complex.