gfortran ieee-arithmetic bug or feature?

473 views
Skip to first unread message

John Harper

unread,
Jun 24, 2015, 11:01:23 PM6/24/15
to
I was glad to see that gfortran 5.1 offers ieee-arithmetic but when trying
it I was surprised that the following program gave the output below it on an
x86_64 system: kinds 10 and 16 exist but ieee-arithmetic does not support
them. Bug or feature?

program testIEEE
use ieee_arithmetic
implicit none
integer,parameter:: k1 = selected_real_kind(1),&
k2 = selected_real_kind(precision(1._k1)+1),&
k3 = selected_real_kind(precision(1._k2)+1),&
k4 = selected_real_kind(precision(1._k3)+1)
print *,k1,k2,k3,k4
print *,precision(1._k1),precision(1._k2),&
precision(1._k3),precision(1._k4)
print *,ieee_support_standard(1._k1),ieee_support_standard(1._k2),&
ieee_support_standard(1._k3),ieee_support_standard(1._k4)
end program testIEEE
4 8 10 16
6 15 18 33
T T F F

FX

unread,
Jun 25, 2015, 3:55:21 AM6/25/15
to
> I was glad to see that gfortran 5.1 offers ieee-arithmetic but when
> trying it I was surprised that the following program gave the output
> below it on an x86_64 system: kinds 10 and 16 exist but ieee-arithmetic
> does not support them. Bug or feature?

When I wrote the IEEE support for gfortran, I was unsure on which
platforms we could claim IEEE arithmetic for floating-point types other
than binary32 and binary64 (for which gfortran has kind values 4 and 8).

The idea was that it's better to err on the side of safety, and declare
them unsupported until I was entirely sure that the can claim
conformance. Things are made somewhat complicated in gfortran's case
because we support multiple platforms. For IEEE modules, we support them
on all x86/x86_64 hardware, on AIX, SystemV-derived systems (*BSD), and
all glibc-based systems.

After discussions with x86/x86_64 specialists, I've come to the
conclusion that we do conform with the requirements of the Fortran 2008
standard for both binary128 (kind 16) and the 80-bit "double extended"
extended precision format (kind 10). I intend that these be accessible,
probably starting with gfortran 6.

--
FX

Wolfgang Kilian

unread,
Jun 25, 2015, 4:13:14 AM6/25/15
to
In view of the recent discussion in another thread, would it make sense
to support names "binary32", "binary64" etc. (or "ieee_binary64" etc.)
analogous to ISO_FORTRAN_ENV, as a Gnu extension? The condition would
be that the platform supports those with IEEE conformance.

I understand that this is not in the current or next Fortran standard
(correct?), but regarding applications in numerics, real kinds like that
could be more useful than the memory-oriented kinds "real64" etc.

-- Wolfgang

--
E-mail: firstnameini...@domain.de
Domain: yahoo

Sebastiaan Janssens

unread,
Jun 25, 2015, 4:39:49 AM6/25/15
to
On Thursday, June 25, 2015 at 9:55:21 AM UTC+2, FX wrote:
> > I was glad to see that gfortran 5.1 offers ieee-arithmetic but when
> > trying it I was surprised that the following program gave the output
> > below it on an x86_64 system: kinds 10 and 16 exist but ieee-arithmetic
> > does not support them. Bug or feature?
>
> When I wrote the IEEE support for gfortran,

(snip)

My apologies for the off-topic response, but I'd like to take the opportunity to thank you for the wonderful job you and your co-workers are doing, making a quality free and open Fortran compiler available for everyone.

Best wishes,

Sebastiaan.

robin....@gmail.com

unread,
Jun 25, 2015, 8:01:57 AM6/25/15
to
On Thursday, June 25, 2015 at 6:13:14 PM UTC+10, Wolfgang Kilian wrote:

> In view of the recent discussion in another thread, would it make sense
> to support names "binary32", "binary64" etc. (or "ieee_binary64" etc.)
> analogous to ISO_FORTRAN_ENV, as a Gnu extension? The condition would
> be that the platform supports those with IEEE conformance.
>
> I understand that this is not in the current or next Fortran standard
> (correct?), but regarding applications in numerics, real kinds like that
> could be more useful than the memory-oriented kinds "real64" etc.

Why would binary64 be any different from real64?

Wolfgang Kilian

unread,
Jun 25, 2015, 8:22:30 AM6/25/15
to
gfortran on i86_64:

real64 = binary64
real128 /= binary128

All of these kinds are supported and in accordance with the Fortran
standard (LHS) or IEEE standard (RHS), respectively.

Paul van Delst

unread,
Jun 25, 2015, 9:58:05 AM6/25/15
to
Yeah!

+1 (times a million)


cheers,

paulv

Stansfield Temmelmeier

unread,
Jun 25, 2015, 1:03:20 PM6/25/15
to
That's better than results I get from my copies of latest Linux Solaris
Studio and a little bit old ifort. Blindly trying to compile your program
without understanding since I didn't use IEEE yet.

stan@home:/tmp$ f95 -V
f90: Sun Fortran 95 8.7 Linux_i386 2014/10/20
stan@home:/tmp$ f95 -c test.f90

precision(1._k3),precision(1._k4)
^
"test.f90", Line = 10, Column = 35: ERROR: The kind type parameter value -1 is not valid for type REAL.

ieee_support_standard(1._k3),ieee_support_standard(1._k4)
^
"test.f90", Line = 12, Column = 59: ERROR: The kind type parameter value -1 is not valid for type REAL.

f90comp: 19 SOURCE LINES
f90comp: 2 ERRORS, 0 WARNINGS, 0 OTHER MESSAGES, 0 ANSI
stan@home:/tmp$ ifort -V
Intel(R) Fortran Compiler XE for applications running on IA-32, Version 13.1.1.163 Build 20130313
Copyright (C) 1985-2013 Intel Corporation. All rights reserved.
FOR NON-COMMERCIAL USE ONLY

stan@home:/tmp$ ifort -c test.f90
test.f90(10): error #6684: This is an incorrect value for a kind type parameter in this context.
precision(1._k3),precision(1._k4)
------------------------------------^
test.f90(12): error #6684: This is an incorrect value for a kind type parameter in this context.
ieee_support_standard(1._k3),ieee_support_standard(1._k4)
------------------------------------------------------------^
compilation aborted for test.f90 (code 1)
stan@home:/tmp$

James Van Buskirk

unread,
Jun 25, 2015, 4:01:37 PM6/25/15
to
"Stansfield Temmelmeier" wrote in message
news:mmhc8j$tka$1...@speranza.aioe.org...

> precision(1._k3),precision(1._k4)
^
> "test.f90", Line = 10, Column = 35: ERROR: The kind type parameter
> value -1 is not valid for type REAL.

The error occurs because the programmer requires 4
kinds of real. I posted once again how to fix this sort of error
just a week or so ago:

> integer,parameter:: k1 = selected_real_kind(1),&
> k2 = selected_real_kind(precision(1._k1)+1),&
> k3 = selected_real_kind(precision(1._k2)+1),&
! k4 = selected_real_kind(precision(1._k3)+1)
k4_we_hope = selected_real_kind(precision(1._k3)+1), &
k4 = merge(k4_we_hope,k3,k4_we_hope >= 0)

An alternative is to use the REAL_KINDS array from the
ISO_FORTRAN_ENV intrinsic module and express the outputs
as array constructors:

D:\gfortran\clf\test_IEEE>type test_IEEE.f90
program test_IEEE
use, intrinsic :: ieee_arithmetic
use ISO_FORTRAN_ENV
implicit none
integer i
print *,REAL_KINDS
print *,[(precision(REAL(1,REAL_KINDS(i))),i=1,size(REAL_KINDS))]
print
*,[(ieee_support_standard(REAL(1,REAL_KINDS(i))),i=1,size(REAL_KINDS))]
end program test_IEEE

D:\gfortran\clf\test_IEEE>gfortran test_IEEE.f90 -otest_IEEE
test_IEEE.f90:2.19:

use, intrinsic :: ieee_arithmetic
1
Fatal Error: Can't find an intrinsic module named 'ieee_arithmetic' at (1)

Is this because my gfortran is too old gcc version 4.9.2
(x86_64-win32-seh-rev0,
Built by MinGW-W64 project) or because my environmental variables
are messed up?

ifort doesn’t work on this either:

D:\gfortran\clf\test_IEEE>ifort /nologo test_IEEE.f90
test_IEEE.f90(7): error #6683: A kind type parameter must be a compile-time
cons
tant. [REAL_KINDS]
print *,[(precision(REAL(1,REAL_KINDS(i))),i=1,size(REAL_KINDS))]
-----------------------------^
test_IEEE.f90(8): error #6683: A kind type parameter must be a compile-time
cons
tant. [REAL_KINDS]
print
*,[(ieee_support_standard(REAL(1,REAL_KINDS(i))),i=1,size(REAL_KINDS))]
-----------------------------------------^
compilation aborted for test_IEEE.f90 (code 1)

Well, the code was good even if no compiler on the planet admits it yet.

Steve Lionel

unread,
Jun 25, 2015, 5:02:28 PM6/25/15
to
On 6/25/2015 4:01 PM, James Van Buskirk wrote:
> ifort doesn’t work on this either:
>
> D:\gfortran\clf\test_IEEE>ifort /nologo test_IEEE.f90
> test_IEEE.f90(7): error #6683: A kind type parameter must be a
> compile-time cons
> tant. [REAL_KINDS]
> print *,[(precision(REAL(1,REAL_KINDS(i))),i=1,size(REAL_KINDS))]
> -----------------------------^
> test_IEEE.f90(8): error #6683: A kind type parameter must be a
> compile-time cons
> tant. [REAL_KINDS]
> print
> *,[(ieee_support_standard(REAL(1,REAL_KINDS(i))),i=1,size(REAL_KINDS))]
> -----------------------------------------^
> compilation aborted for test_IEEE.f90 (code 1)
>
> Well, the code was good even if no compiler on the planet admits it yet.

Initially, I was going to disagree, but I should have known better. One
of the rules for primaries in initialization/constant expressions is:

(10) An ac-do-variable within an array constructor where each
scalar-int-expr of the corresponding ac-implied-do-control is an
initialization expression,

The (i) qualifies here. I'll file an ifort bug report.

--
Steve Lionel
Developer Products Division
Intel Corporation
Merrimack, 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

Refer to http://software.intel.com/en-us/articles/optimization-notice
for more informati

kargl

unread,
Jun 25, 2015, 5:15:45 PM6/25/15
to
Steve Lionel wrote:

> On 6/25/2015 4:01 PM, James Van Buskirk wrote:
>> ifort doesn?t work on this either:
>>
>> D:\gfortran\clf\test_IEEE>ifort /nologo test_IEEE.f90
>> test_IEEE.f90(7): error #6683: A kind type parameter must be a
>> compile-time cons
>> tant. [REAL_KINDS]
>> print *,[(precision(REAL(1,REAL_KINDS(i))),i=1,size(REAL_KINDS))]
>> -----------------------------^
>> test_IEEE.f90(8): error #6683: A kind type parameter must be a
>> compile-time cons
>> tant. [REAL_KINDS]
>> print
>> *,[(ieee_support_standard(REAL(1,REAL_KINDS(i))),i=1,size(REAL_KINDS))]
>> -----------------------------------------^
>> compilation aborted for test_IEEE.f90 (code 1)
>>
>> Well, the code was good even if no compiler on the planet admits it yet.
>
> Initially, I was going to disagree, but I should have known better.

Me too. :-)

>One of the rules for primaries in initialization/constant expressions is:
>
> (10) An ac-do-variable within an array constructor where each
> scalar-int-expr of the corresponding ac-implied-do-control is an
> initialization expression,
>
> The (i) qualifies here. I'll file an ifort bug report.
>

Yep, gfortran has the same issue.

--
steve

James Van Buskirk

unread,
Jun 25, 2015, 6:32:55 PM6/25/15
to
"kargl" wrote in message news:mmhqvd$j8u$1...@dont-email.me...

> Steve Lionel wrote:

> >One of the rules for primaries in initialization/constant expressions is:

> > (10) An ac-do-variable within an array constructor where each
> > scalar-int-expr of the corresponding ac-implied-do-control is an
> > initialization expression,

> > The (i) qualifies here. I'll file an ifort bug report.

> Yep, gfortran has the same issue.

This possibility goes back at least to f95, so I composed an example
that should be at least close to f95-compliant. It has always seemed
to me that adding generic resolution to the mix might also make
life more difficult for the compiler:

D:\gfortran\clf\test_IEEE>type test_f95.f90
module mykinds
implicit none
integer, parameter :: k1 = selected_real_kind(6)
integer, parameter :: k2 = selected_real_kind(15)
integer, parameter :: k3 = selected_real_kind(33)
integer, parameter :: rk(3) = (/k1,k2,k3/)
end module mykinds

module BCE
implicit none
interface real2string
module procedure real2string1,real2string2,real2string3
end interface
contains
function real2string1(x)
use mykinds, only: wp => k1
implicit none
real(wp), intent(in) :: x
character(len=real2stringlen1(x)) real2string1
character(len=100) temp

write(temp,*) x
real2string1 = adjustl(temp)
end function real2string1
pure function real2stringlen1(x)
use mykinds, only: wp => k1
implicit none
integer real2stringlen1
character(len=100) temp

real(wp), intent(in) :: x
write(temp,*) x
real2stringlen1 = len_trim(adjustl(temp))
end function real2stringlen1
function real2string2(x)
use mykinds, only: wp => k2
implicit none
real(wp), intent(in) :: x
character(len=real2stringlen2(x)) real2string2
character(len=100) temp

write(temp,*) x
real2string2 = adjustl(temp)
end function real2string2
pure function real2stringlen2(x)
use mykinds, only: wp => k2
implicit none
integer real2stringlen2
character(len=100) temp
real(wp), intent(in) :: x

write(temp,*) x
real2stringlen2 = len_trim(adjustl(temp))
end function real2stringlen2
function real2string3(x)
use mykinds, only: wp => k3
implicit none
real(wp), intent(in) :: x
character(len=real2stringlen3(x)) real2string3
character(len=100) temp

write(temp,*) x
real2string3 = adjustl(temp)
end function real2string3
pure function real2stringlen3(x)
use mykinds, only: wp => k3
implicit none
integer real2stringlen3
character(len=100) temp
real(wp), intent(in) :: x

write(temp,*) x
real2stringlen3 = len_trim(adjustl(temp))
end function real2stringlen3
end module BCE

program test
use mykinds
use BCE
implicit none
type t
character(len=100) string
end type t
type(t) capture(size(rk))
integer i

! capture(1) = t(real2string(4*atan(real(1,rk(1)))))
! capture(2) = t(real2string(4*atan(real(1,rk(2)))))
! capture(3) = t(real2string(4*atan(real(1,rk(3)))))
capture = (/(t(real2string(4*atan(real(1,rk(i))))),i=1,size(rk))/)
write(*,'(a)') (trim(capture(i)%string),i=1,size(rk))
end program test

D:\gfortran\clf\test_IEEE>gfortran test_f95.f90 -otest_f95
test_f95.f90:90.44:

capture = (/(t(real2string(4*atan(real(1,rk(i))))),i=1,size(rk))/)
1
Error: Invalid kind for REAL at (1)

D:\gfortran\clf\test_IEEE>ifort /nologo test_f95.f90
test_f95.f90(90): error #6683: A kind type parameter must be a compile-time
cons
tant. [RK]
capture = (/(t(real2string(4*atan(real(1,rk(i))))),i=1,size(rk))/)
--------------------------------------------^
compilation aborted for test_f95.f90 (code 1)

kargl

unread,
Jun 25, 2015, 6:47:43 PM6/25/15
to
James Van Buskirk wrote:

> "kargl" wrote in message news:mmhqvd$j8u$1...@dont-email.me...
>
>> Steve Lionel wrote:
>
>> >One of the rules for primaries in initialization/constant expressions is:
>
>> > (10) An ac-do-variable within an array constructor where each
>> > scalar-int-expr of the corresponding ac-implied-do-control is an
>> > initialization expression,
>
>> > The (i) qualifies here. I'll file an ifort bug report.
>
>> Yep, gfortran has the same issue.
>
> This possibility goes back at least to f95, so I composed an example
> that should be at least close to f95-compliant.

Yep. I never did figure out how to deal with implied-do-loops in F95
constant expressions, which now has moved forward to initialization
expressions.

(code elided for brevity)

> D:\gfortran\clf\test_IEEE>gfortran test_f95.f90 -otest_f95
> test_f95.f90:90.44:
>
> capture = (/(t(real2string(4*atan(real(1,rk(i))))),i=1,size(rk))/)
> 1
> Error: Invalid kind for REAL at (1)

This is the error I see with my reworked version of your original
post.

program foo
implicit none
integer i
integer, parameter :: n = 4
integer, parameter :: k(n) = [4, 8, 10, 16]
print *, (real(1,k(i)), i=1, n)
end program foo

% gfc6 -o z g.f90 && ./z
g.f90:6:19:

print *, (real(1,k(i)), i=1, n)
1
Error: Invalid kind (0) for REAL at (1)

I made gfortran output the value it got. Here, it is zero.

If I change k(i) to k(2), the ouput is as expected. So, what
appears to be happen is that gfortran is trying to evaluate
real(1,k(i)) before the implied-do-loop is expanded not
during the expansion.

--
steve





themos...@gmail.com

unread,
Jun 26, 2015, 2:16:34 PM6/26/15
to
Hello,

The NAG compiler thinks the code is Fortran.

>cat test_IEEE.f90
program test_IEEE
use, intrinsic :: ieee_arithmetic
use ISO_FORTRAN_ENV
implicit none
integer i
print *,REAL_KINDS
print *,[(precision(REAL(1,REAL_KINDS(i))),i=1,size(REAL_KINDS))]
print *,[(ieee_support_standard(REAL(1,REAL_KINDS(i))),i=1,size(REAL_KINDS))]
end program test_IEEE

>nagfor test_IEEE.f90
NAG Fortran Compiler Release 6.0(Hibiya) Build 1053
[NAG Fortran Compiler normal termination]

>./a.out
1 2 3
6 15 31
T T T

>nagfor -kind=byte test_IEEE.f90
NAG Fortran Compiler Release 6.0(Hibiya) Build 1053
[NAG Fortran Compiler normal termination]

>./a.out
4 8 16
6 15 31
T T T


Themos Tsikas
NAG Ltd.

James Van Buskirk

unread,
Jun 26, 2015, 10:36:33 PM6/26/15
to
"Themos...@googlemail.com" wrote in message
news:d7fffd8e-fe92-4884...@googlegroups.com...

> >cat test_IEEE.f90
> program test_IEEE
> use, intrinsic :: ieee_arithmetic
> use ISO_FORTRAN_ENV
> implicit none
> integer i
> print *,REAL_KINDS
> print *,[(precision(REAL(1,REAL_KINDS(i))),i=1,size(REAL_KINDS))]
> print
> *,[(ieee_support_standard(REAL(1,REAL_KINDS(i))),i=1,size(REAL_KINDS))]
> end program test_IEEE

> >nagfor test_IEEE.f90
> NAG Fortran Compiler Release 6.0(Hibiya) Build 1053
> [NAG Fortran Compiler normal termination]

> >./a.out
> 1 2 3
> 6 15 31
> T T T

Very impressive! Thanks for trying out my example on your compiler.

Reply all
Reply to author
Forward
0 new messages