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

Single precision real constants

Adrian_F_1
Beginner
1,310 Views

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?

 

0 Kudos
13 Replies
TimP
Honored Contributor III
1,310 Views

If you didn't mean to expose how -459.67 differs from -459.67_real64, you could use the latter.

0 Kudos
Adrian_F_1
Beginner
1,310 Views

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?

0 Kudos
FortranFan
Honored Contributor III
1,310 Views

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.

 

0 Kudos
Adrian_F_1
Beginner
1,310 Views

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

0 Kudos
FortranFan
Honored Contributor III
1,310 Views

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.

0 Kudos
Adrian_F_1
Beginner
1,310 Views

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.

0 Kudos
Adrian_F_1
Beginner
1,310 Views

BTW adding /REAL_SIZE:64 fixed the problem too.  No idea why though.

0 Kudos
IanH
Honored Contributor III
1,310 Views

Adrian F. wrote:

BTW adding /REAL_SIZE:64 fixed the problem too.  No idea why though.

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.

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

 

0 Kudos
Adrian_F_1
Beginner
1,310 Views

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.

0 Kudos
Steven_L_Intel1
Employee
1,310 Views

Ian has the correct answer, as usual.

0 Kudos
FortranFan
Honored Contributor III
1,310 Views

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

  1. there is a gap in /fpconstant implementation
  2. 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,

0 Kudos
Steven_L_Intel1
Employee
1,310 Views

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.

0 Kudos
Adrian_F_1
Beginner
1,310 Views

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.

0 Kudos
Reply