- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have a project where /fpconstant is specified for both Debug and Release builds. However the Debug version is still interpreting a single real constant oddly. I have:
double precision, parameter :: KToFShift = -459.67
Yet when I print it out in the code:
write(78,*) KToFShift
I get:
-459.670013427734
In Release it shows up correctly. Why does Debug show it incorrectly?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you didn't mean to expose how -459.67 differs from -459.67_real64, you could use the latter.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I know I can solve the problem by adding d0 (or _real64) to all constants however that is not the point: /fpconstant should do this for me. Why does it do it in Release but not Debug?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Do you, by any chance, have /standard-semantics turned on for your Debug configuration? If yes, there is a possibility this might be overriding /fpconsant.
The evaluation of single-precision constants in double precision during assignment to double precision variables, as offered by /fpconstant option, is inconsistent with Fortran 2003 standard, as you may know.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Nope didn't know that. But here is my command line:
Debug:
/nologo /debug:full /Od /extend_source:132 /fp:source /fpconstant /module:"Debug\\" /object:"Debug\\" /Fd"Debug\vc100.pdb" /traceback /check:bounds /libs:static /threads /libdir:noauto /c
Release:
/nologo /O2 /extend_source:132 /real_size:64 /fp:source /fpconstant /module:"Release\\" /object:"Release\\" /Fd"Release\vc100.pdb" /libs:static /threads /c
I see the REAL_SIZE:64 is different however I understood this only to determine how REAL :: realvar is interpreted, ie. as REAL*4 or REAL*8
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I also feel the same: /real_size specification shouldn't play a role. Hmm... this looks like a compiler bug in terms of /fpconstant being ignored in the Debug configuration. Best to wait one of the Intel gurus, esp. Steve, to take a look.
Separately, you really have a mixed bag of real kinds specification with the use of non-standard Fortran (at least, Fortran 2003 onward), use of "double precision" in declarations, compiler specification of real kind size, etc. - if you plan to support this code for any length of time and have a situation where other users besides you will be running the code, you should consider cleaning it up, using standard Fortran almost exclusively, and not make use of compiler-specific options to define the data and methods in your code in any fashion. The compiler options should be limited to compile and run-time checks for any errors and warnings, library specifications, path pointers for modules, output, libraries, etc.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes agreed, as with all old Fortran code, it would be nice to clean it all up, and that would be done in time. However in the meantime I need to sort out the differences between Debug and Release so at least we can Debug what the user is seeing...
Let's wait for Steve's view on this.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
BTW adding /REAL_SIZE:64 fixed the problem too. No idea why though.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Adrian F. wrote:This changes the default kind for REAL to be 8 (the same kind as specified by DOUBLE PRECISION with ifort and the kind which gives you a 64 bit representation). That changes both the kind of a variable declared without a kind specification (REAL :: real_var) and the kind of real constants written without a kind specification - for example the thing on the right hand side of the '=' side in the initialization of the constant in your source.
BTW adding /REAL_SIZE:64 fixed the problem too. No idea why though.
I've no real idea what /fpconstant should or should not do here, but the absence of that /real_size flag in the debug build can explain the difference that you see.
The documentation for /fpconstant talks about assignment, but there's no assignment in your example, or in the example in the documentation for /fpconstant, for that matter. That said, when I compiled and ran a simple program with 14.0.2 on x86 I see /fpconstant appears to do what the non-example part of the document says.
IMPLICIT NONE INTEGER, PARAMETER :: dk = KIND(1.0D0) DOUBLE PRECISION, PARAMETER :: DefaultConstant = -459.67 DOUBLE PRECISION, PARAMETER :: SpecificConstant = -459.67_dk DOUBLE PRECISION :: DefaultAssign DOUBLE PRECISION :: SpecificAssign DOUBLE PRECISION :: DefaultInit = -459.67 DOUBLE PRECISION :: SpecificInit = -459.67_dk DOUBLE PRECISION :: DefaultData = -459.67 DOUBLE PRECISION :: SpecificData = -459.67_dk DATA DefaultData/-459.67/ DATA SpecificData/-459.67_dk/ DefaultAssign = -459.67 SpecificAssign = -459.67_dk WRITE (*, *) 'DefaultConstant:', DefaultConstant WRITE (*, *) 'SpecificConstant:', SpecificConstant WRITE (*, *) 'DefaultVar:', DefaultAssign WRITE (*, *) 'SpecificVar:', SpecificAssign WRITE (*, *) 'DefaultInit:', DefaultInit WRITE (*, *) 'SpecificInit:', SpecificInit WRITE (*, *) 'DefaultData:', DefaultData WRITE (*, *) 'SpecificData:', SpecificData END
Note in the following output how the only "precise" variable set via a default kind constant is the one that was assigned to.
>ifort /Od /check:all /warn:all /fpconstant "2014-04-21 fpconstant.f90" && "2014-04-21 fpconstant.exe" Intel(R) Visual Fortran Compiler XE for applications running on IA-32, Version 14.0.2.176 Build 20140130 Copyright (C) 1985-2014 Intel Corporation. All rights reserved. Microsoft (R) Incremental Linker Version 10.00.40219.01 Copyright (C) Microsoft Corporation. All rights reserved. "-out:2014-04-21 fpconstant.exe" -subsystem:console "2014-04-21 fpconstant.obj" DefaultConstant: -459.670013427734 SpecificConstant: -459.670000000000 DefaultVar: -459.670000000000 SpecificVar: -459.670000000000 DefaultInit: -459.670013427734 SpecificInit: -459.670000000000 DefaultData: -459.670013427734 SpecificData: -459.670000000000
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, very interesting. So /fpconstant does not work with data initialization through declaration, only assignment. That's news to me. And a bit strange too.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ian has the correct answer, as usual.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve Lionel (Intel) wrote:
Ian has the correct answer, as usual.
Steve,
Not sure I still understand why /fpconstant won't work with the PARAMETER statement.
As you know, the Intel help for /fpconstant says, "Tells the compiler that single-precision constants assigned to double-precision variables should be evaluated in double precision."
And per the explanation for PARAMETER statements in many sources including Modern Fortran Explained by Metcalf et al., "Each named constant in the list is defined with the value of the corresponding expression according to the rules of intrinsic assignment."
/fpconstant as explained, therefore, seems to change the rules of the intrinsic assignment and if so, why does it not extend to PARAMETER statements.
In addition, the example given in Intel help doesn't seem to work as expected either. Hence doesn't it appear that
- there is a gap in /fpconstant implementation
- And at the very least, Intel help documentation for /fpconstant can be updated.
Not that I am advocating the use of this option, but if it is there, it'll be good to have consistency and clarity.
Thanks much,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'll suggest this to the developers, but putting on my Dr. Fortran hat and stethoscope, I would very strongly advise against using compiler options to compensate for writing incorrect code. I have a strong dislike for /real_size, /fpconstant and the like. Write correct, standard-conforming code, and you won't have to deal with such issues.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes Steve I agree, all my new code is written this way, but there are tons of legacy applications out there for which we don't have the luxury of being able to rewrite.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page