Since compilers treat the non-standard but very common
real*4, real*8, integer*4, integer*8
as
use iso_fortran_env
real(kind=real32), real(kind=real64), integer(kind=int32), integer(kind=int64)
would it make sense to standardize the former set of declarations, which is concise and clear, to mean the same as the latter?
On Saturday, April 9, 2022 at 10:05:29 AM UTC-4, Beliavsky wrote:.
Since compilers treat the non-standard but very common
real*4, real*8, integer*4, integer*8
as
use iso_fortran_env
real(kind=real32), real(kind=real64), integer(kind=int32), integer(kind=int64)
would it make sense to standardize the former set of declarations, which is concise and clear, to mean the same as the latter?Currently, if someone inherits a code with real*8 and decides to make it standard-conforming, they may replace it with
real(kind=8),
which is not guaranteed to work (failing with the NAG compiler for example). By standardizing real*8 appropriately this error is avoided..
..
would it make sense to standardize the former set of declarations, which is concise and clear, to mean the same as the latter?
would it make sense to standardize the former set of declarations,
which is concise and clear, to mean the same as the latter?
Currently, if someone inherits a code with real*8 and decides to make it standard-conforming, they may replace it with real(kind=8), which is not guaranteed to work (failing with the NAG compiler for example).
By standardizing real*8 appropriately this error is avoided.
As far as I know, REAL(8) is more popular, and equally standard and non-portable.
I even knew of a MOOC, meant for introducing Fortran to physicists,
that taught REAL(8).
REAL(KIND(1D0))
would be standard, and reliably give a double precision type, though takes more characters to type.
It is nice to have something that can be replaced, line by line, without the need for any other lines to be included. (Well, assuming appropriate continuation rules.)
Since compilers treat the non-standard but very common
real*4, real*8, integer*4, integer*8
as
use iso_fortran_env
real(kind=real32), real(kind=real64), integer(kind=int32), integer(kind=int64)
would it make sense to standardize the former set of declarations, which is concise and clear, to mean the same as the latter?
On Saturday, April 9, 2022 at 10:05:29 AM UTC-4, Beliavsky wrote:
Since compilers treat the non-standard but very common
real*4, real*8, integer*4, integer*8
as
use iso_fortran_env
real(kind=real32), real(kind=real64), integer(kind=int32), integer(kind=int64)
would it make sense to standardize the former set of declarations, which is concise and clear, to mean the same as the latter?Currently, if someone inherits a code with real*8 and decides to make it standard-conforming, they may replace it with
real(kind=8), which is not guaranteed to work (failing with the NAG compiler for example). By standardizing real*8 appropriately this error is avoided.
There are many deprecated features that it would be very easy to write
a program to convert to non-deprecated form. As far as I know, that hasn't been done. (And in both free and fixed form.)
I do find it interesting that the Fortran II PRINT statement, after not making
it into Fortran 66, later was included in the standard. Including REAL*8 makes
about as much sense.
..
I am in favour of making this standard ..
The KIND specifications are clear and unambiguous, but in small test programs they can take up a significant proportion of the entire text.
Since compilers treat the non-standard but very common
real*4, real*8, integer*4, integer*8
as
use iso_fortran_env
real(kind=real32), real(kind=real64), integer(kind=int32), integer(kind=int64)
would it make sense to standardize the former set of declarations, which is concise and clear, to mean the same as the latter?
On Saturday, April 9, 2022 at 7:05:29 AM UTC-7, Beliavsky wrote:
(snip)
would it make sense to standardize the former set of declarations,
which is concise and clear, to mean the same as the latter?
One thing that I have long thought, is that it would be nice to include in the
standard some things that aren't required of implementations, but indicate how to do something if it is included.
(And more generally than this question.)
In the past, this was complicated by machines with 60 or 64 bit words,
that had a type of that length as default REAL, and then (as required by
the standard) a longer type of DOUBLE PRECISION. Those machines are
now out of favor.
Since compilers treat the non-standard but very commonreal*8 and real(kind=real64) both provide a clear documentation of precision. real(8) unfortunately, is not portable.
real*4, real*8, integer*4, integer*8
as
use iso_fortran_env
real(kind=real32), real(kind=real64), integer(kind=int32), integer(kind=int64)
would it make sense to standardize the former set of declarations, which is concise and clear, to mean the same as the latter?
On Saturday, April 9, 2022 at 2:29:37 PM UTC-7, Thomas Koenig wrote:
gah4 <ga...@u.washington.edu> schrieb:
On Saturday, April 9, 2022 at 7:05:29 AM UTC-7, Beliavsky wrote:
(snip)
In the past, this was complicated by machines with 60 or 64 bit words,
that had a type of that length as default REAL, and then (as required by >> > the standard) a longer type of DOUBLE PRECISION. Those machines are
now out of favor.
POWER has rather recently acquired IEEE quad precision, and
gfortran will have aquired support for it in the upcoming
release.
It was the word addressed 60 and 64 bit machines that didn't have
a smaller floating point type. IBM had REAL*16 and COMPLEX*32
since the 360/85 and standard on all S/370 and later models.
I am surprised it took this long to get to POWER.
VAX Fortran also supports REAL*16 and COMPLEX*32, though
software emulated on many machines. That was from close
to the beginning of VAX. (A microcode option on most,
it was standard on the low end 11/730.)
gah4 <ga...@u.washington.edu> schrieb:
On Saturday, April 9, 2022 at 7:05:29 AM UTC-7, Beliavsky wrote:
In the past, this was complicated by machines with 60 or 64 bit words,
that had a type of that length as default REAL, and then (as required by the standard) a longer type of DOUBLE PRECISION. Those machines are
now out of favor.
POWER has rather recently acquired IEEE quad precision, and
gfortran will have aquired support for it in the upcoming
release.
Not as double precision, but as REAL(KIND=16).
On Saturday, April 9, 2022 at 12:16:46 PM UTC-4, gah4 wrote:
As far as I know, REAL(8) is more popular, and equally standard and non-portable.
REAL(KIND(1D0))
would be standard, and reliably give a double precision type, though takes more characters to type.
It is nice to have something that can be replaced, line by line, without the
need for any other lines to be included. (Well, assuming appropriate continuation rules.)
If someone declares variables as real*8 they are saying that 8-byte reals are sufficient.
You could have a platform where singe precision is real(kind=real64) and double
precision is real(kind=real128). In that case the natural equivalent of real*8 would be
real(kind=real128) and not real(kind=kind(1.0d0)).
real(dp) or real(kind=dp) is not clear, as you need to search for the definition of dp, often in a "remote" module.
sp, dp, qp, wp, r4 or r8 are not standard abbreviations. They are not uncommon real variables in legacy codes.
I use multiple compilers, which have different kind values. Real*8 works easily for me on all compilers I use, while real(kind=dp) has the problem of which compiler last compiled the module where DP was defined.
One compiler has real_kinds of [ 1,2 ] and integer_kinds of [ 1,2,3,4 ]. Try using integers such as 123_4 and see what you get for the different compilers I use.
When using real*8, there is always the danger of using a compiler
that does not support this non-standard syntax. I think there
are greater dangers out there at the moment! I have used new
Fortran compilers that did not support the real*byte syntax. It
has happened a few times and I always successfully lobbied for
the compiler to be enhanced. Most new OS and compilers tend to
want to help established users.
On Saturday, April 9, 2022 at 9:46:13 AM UTC-7, Beliavsky wrote:
On Saturday, April 9, 2022 at 12:16:46 PM UTC-4, gah4 wrote:
As far as I know, REAL(8) is more popular, and equally standard and
non-portable.
(snip)
REAL(KIND(1D0))
would be standard, and reliably give a double precision type, though takes >>> more characters to type.
It is nice to have something that can be replaced, line by line, without the
need for any other lines to be included. (Well, assuming appropriate
continuation rules.)
If someone declares variables as real*8 they are saying that 8-byte reals are sufficient.
You could have a platform where singe precision is real(kind=real64) and double
precision is real(kind=real128). In that case the natural equivalent of real*8 would be
real(kind=real128) and not real(kind=kind(1.0d0)).
The Cray-1 series are word addressed 64 bit machines, with a 64 bit
floating point type. I believe Fortran supports a software emulated 128
bit type, as required by the standard. But all the Cray machines are, as far as I know, in museums. (There used to be a machine that would one on
one day a week, as that was how much power they could afford.)
I don't know about Cray support for REAL*8 syntax.
I do remember Fortran programs with a series of declarations and
DATA statements at the beginning, where you uncomment the ones
for the system you are using. That was for the different word size,
and also other constants that varied between machines.
gah4 <ga...@u.washington.edu> schrieb:
It was the word addressed 60 and 64 bit machines that didn't have
a smaller floating point type. IBM had REAL*16 and COMPLEX*32
since the 360/85 and standard on all S/370 and later models.
I am surprised it took this long to get to POWER.
IIRC, the REAL*16 types were implemented as two doubles. POWER also
had that (but as a pair of IEEE doubles), and a true headache it
is proving to get rid of that in compiler support.
real(dp) or real(kind=dp) is not clear, as you need to search for the definition of dp, often in a "remote" module.They are what I usually use. In most of my projects, I have a small
sp, dp, qp, wp, r4 or r8 are not standard abbreviations. They are not uncommon real variables in legacy codes.
module
module prec
implicit none
integer, parameter :: sp = selected_real_kind(6)
integer, parameter :: dp = selected_real_kind(15)
integer, parameter :: qp = selected_real_kind(30)
end module prec
Note, though, that the DEC compilers for the 36 bit PDP-10
recognize REAL*8 for the 72 bit double precision. I am not sure
about the CDC and Cray compilers. It isn't required that the *8
represent 8 bytes of any specific size. (The PDP-10 byte
instructions work on bytes from 1 to 36 bits. C compilers
tend to use 9 bits for char. C requires char to be an integer
fraction of the word (int) size.)
JCampbell <campbel...@gmail.com> schrieb:
real(dp) or real(kind=dp) is not clear, as you need to search for the definition of dp, often in a "remote" module.They are what I usually use. In most of my projects, I have a small
sp, dp, qp, wp, r4 or r8 are not standard abbreviations. They are not uncommon real variables in legacy codes.
module
module prec
implicit none
integer, parameter :: sp = selected_real_kind(6)
integer, parameter :: dp = selected_real_kind(15)
integer, parameter :: qp = selected_real_kind(30)
end module prec
I use multiple compilers, which have different kind values. Real*8 works easily for me on all compilers I use, while real(kind=dp) has the problem of which compiler last compiled the module where DP was defined.
On Sunday, April 10, 2022 at 7:44:59 PM UTC+12, Thomas Koenig wrote:I am not sure I would agree that real*10 works well with gfortran, especially considering the memory storage approach.
JCampbell <campbel...@gmail.com> schrieb:
real(dp) or real(kind=dp) is not clear, as you need to search for the definition of dp, often in a "remote" module.They are what I usually use. In most of my projects, I have a small
sp, dp, qp, wp, r4 or r8 are not standard abbreviations. They are not uncommon real variables in legacy codes.
module
module precIn one of my projects where I test programs with lower precision to save run time but finish up using the highest I use a little module like this:
implicit none
integer, parameter :: sp = selected_real_kind(6)
integer, parameter :: dp = selected_real_kind(15)
integer, parameter :: qp = selected_real_kind(30)
end module prec
I use multiple compilers, which have different kind values. Real*8 works easily for me on all compilers I use, while real(kind=dp) has the problem of which compiler last compiled the module where DP was defined.
module myprec
integer, parameter :: prec(4) = [6,15,18,33]
integer, parameter :: wp = selected_real_kind(prec(2))
end module myprec
when I want what gfortran and ifort call double precision. Changing the desired precision requires changing only the 2 into 1, 3 or 4, and no change is needed in a program that uses that module.
That works well with gfortran but when compiling with ifort I must remember that asking for prec(3) is the same as asking for prec(4).
On 4/10/22 2:44 AM, Thomas Koenig wrote:.
real(dp) or real(kind=dp) is not clear, as you need to search for the definition of dp, often in a "remote" module.They are what I usually use. In most of my projects, I have a small
sp, dp, qp, wp, r4 or r8 are not standard abbreviations. They are not uncommon real variables in legacy codes.
module
module precJust to include this possibility into the mix, there is also
implicit none
integer, parameter :: sp = selected_real_kind(6)
integer, parameter :: dp = selected_real_kind(15)
integer, parameter :: qp = selected_real_kind(30)
end module prec
real*8, private :: temp
integer, parameter :: wp=kind(temp)
The rest of the code should use the "wp" parameter of course, in
declarations and in literal constants, but in that one module, it isn't
so bad to use real*8 in that one place. Once it is localized like this,
it isn't even so bad to hardwire the kind number.
integer, parameter :: wp=8
The big porting problems arise when the "8" is scattered throughout the source code.
On Saturday, April 9, 2022 at 2:19:23 PM UTC-4, john.c...@simconglobal.com wrote:.
..Should the standard do anything now, a better option will be to simply provide built-in i.e., ALIASes toward type-and-kind equivalent to certain standard floating point formats, say IEEE binary (and perhaps decimal) formats.
I am in favour of making this standard ..
The KIND specifications are clear and unambiguous, but in small test programs they can take up a significant proportion of the entire text.
For the foreseeable future, the powers-that-be in the industry and research and engineering areas I know only expect to use IEEE binary 64-bit floating point in >99% of computing.
So what will be really useful is to have, say, IEEE_FPB64 as an alias for real(KIND=xx) where xx is IEEE_SELECTED_REAL_KIND( p=, r=, radix=..) corresponding to 64-bit IEEE binary floating point format.
One should then be able to do the following in any processor that provides support for IEEE_xxx features from Fortran 2003+ which is several of the modern Fortran compilers:
ieee_fpb64 :: x
One can combine that with proposal for kinds for literal constants.
On Saturday, April 9, 2022 at 3:05:29 PM UTC+1, Beliavsky wrote:users.
Since compilers treat the non-standard but very common
real*4, real*8, integer*4, integer*8
as
use iso_fortran_env
real(kind=real32), real(kind=real64), integer(kind=int32), integer(kind=int64)
would it make sense to standardize the former set of declarations, which is concise and clear, to mean the same as the latter?I am in favour of making this standard, but I think it is academic. I know of no compilers in common use which do not support declarations in this format, and I doubt if any compiler writers would remove them for the sake of annoying some of their
The KIND specifications are clear and unambiguous, but in small test programs they can take up a significant proportion of the entire text..
On 4/9/22 9:05 AM, Beliavsky wrote:.
Since compilers treat the non-standard but very common
real*4, real*8, integer*4, integer*8
as
use iso_fortran_env
real(kind=real32), real(kind=real64), integer(kind=int32), integer(kind=int64)
would it make sense to standardize the former set of declarations, which is concise and clear, to mean the same as the latter?In my opinion, this would be a step backward for the language.
There are many reasons why this should not be done, but one of them is
that REAL*4 etc. were always just defined by the local compiler to map
to its supported floating point formats. For byte addressable machines,
that meant that your suggested mapping would be correct. But there are
also 36-bit, 60-bit, and 64-bit machines that cannot conform to those mappings, so they must do something different. In the f77 time in the
1980s, I used those declarations extensively for exactly that reason, it
was a way, with some care, to write portable (but nonstandard) code. I
used REAL*8 declarations to run on machines with all of those word
lengths. It wasn't pretty, but it served its purpose at the time.
But now we have the fortran KIND system, which handles all of that much better. Yes, when you incorporate old f66 and f77 code into your current project, you need to edit in those changes, but that is not a big deal.
Your minimal efforts are rewarded with clarity and portability. I have programs with hundreds of thousands of lines where I can change the
precision globally by modifying a single line of code in a module. From
the programmer's perspective, that is hard to beat.
On Sunday, April 10, 2022 at 12:05:29 AM UTC+10, Beliavsky wrote:.
Since compilers treat the non-standard but very common
real*4, real*8, integer*4, integer*8
as
use iso_fortran_env
real(kind=real32), real(kind=real64), integer(kind=int32), integer(kind=int64)
would it make sense to standardize the former set of declarations, which is concise and clear, to mean the same as the latter?real*8 and real(kind=real64) both provide a clear documentation of precision. real(8) unfortunately, is not portable.
..
real(dp) or real(kind=dp) is not clear,
as you need to search for the definition of dp,.
often in a "remote" module..
sp, dp, qp, wp, r4 or r8 are not standard abbreviations. They are not uncommon real variables in legacy codes.
I use multiple compilers, which have different kind values. Real*8 works easily for me on all compilers I use,.
while real(kind=dp) has the problem of which compiler last compiled the module where DP was defined..
One compiler has real_kinds of [ 1,2 ] and integer_kinds of [ 1,2,3,4 ]. Try using integers such as 123_4 and see what you get for the different compilers I use.
When using real*8, there is always the danger of using a compiler that does not support this non-standard syntax. I think there are greater dangers out there at the moment!.
I have used new Fortran compilers that did not support the real*byte syntax. It has happened a few times and I always successfully lobbied for the compiler to be enhanced.
Most new OS and compilers tend to want to help established users..
IEEE documents also use REAL*8 syntax.
I am not sure I would agree that real*10 works well with gfortran, especially considering the memory storage approach.
JCampbell wrote:
I am not sure I would agree that real*10 works well with gfortran, especially considering the memory storage approach.
Can you elaborate?
gfortran's real(10) on x86_64 class hardware is Intel 80-bit
extended double precision.
On 4/11/22 11:05 AM, steve kargl wrote:
JCampbell wrote:
I am not sure I would agree that real*10 works well with gfortran, especially considering the memory storage approach.
Can you elaborate?
gfortran's real(10) on x86_64 class hardware is Intel 80-bit
extended double precision.
I think the problem people have is that it is stored in 16 bytes, so
there is a lot of wasted memory and/or file space.
I'm glad the option is there, for example for accumulating sums with
extended precision, but its overall usefulness is limited because of
those wasted 48-bits per value. Programmers instead are likely just to
use the 128-bit floating point kind which takes up the same memory/file space. And it is nice to have the 128-bit kind supported too.
So does DOUBLE PRECISION, which is STANDARD.
.
I agree that standardising REAL*8 would inject a fossil into the language. Perhaps a way forward is to define a new class of PARAMETER for types and kinds, e.g.
PARAMETER,KIND :: REAL_8 = REAL,KIND=KIND(1.0D0)
Then REAL_8 could only be used in a kind specification and would always mean the same thing.
This would avoid an error which we found recently in an important code where the user had written an expression of the form:
REAL(dp),PARAMETER :: kappa = 68431_dp
dp was (as a result of SELECTED_REAL_KIND) equal to 8 so the integer
was defined as 64-bits and no error occurred on the original ifort compiler.
What NAG or FTN95 would have done with it I don't want to know.
We don't (yet) know how many more of these are likely to turn up.
The compiler could issue an error if a parameterised KIND were used as a tag for an integer literal.
On Monday, April 11, 2022 at 10:21:33 AM UTC+1, Robin Vowels wrote:
<snip>> .
So does DOUBLE PRECISION, which is STANDARD.
.
I'm not sure that it is, or at least, not in a helpful way. A system with a default 64-bit real number might interpret DOUBLE PRECISION as 128-bit.
John Collins wrote:
On Monday, April 11, 2022 at 10:21:33 AM UTC+1, Robin Vowels wrote:
<snip>> .
So does DOUBLE PRECISION, which is STANDARD.
.
I'm not sure that it is, or at least, not in a helpful way. A system with a default 64-bit real number might interpret DOUBLE PRECISION as 128-bit.
DOUBLE PRECISION is defined by the standard. An entity with
default REAL kind type occupies one numeric storage unit.
An entity with DOUBLE PRECISION type occupies two numeric
storage units. If one numeric storage unit is 64 bits, then
two would use 128 bits.
DOUBLE PRECISION is defined by the standard. An entity with
default REAL kind type occupies one numeric storage unit.
An entity with DOUBLE PRECISION type occupies two numeric
storage units. If one numeric storage unit is 64 bits, then
two would use 128 bits.
Right. DOUBLE is really double the size, since the actual precision,
however it is measured, can vary, and is usually not double.
The original subject here is the non-standard REAL*8, but there is the standard, non-portable, and way too common REAL(8).
On Monday, April 11, 2022 at 10:21:33 AM UTC+1, Robin Vowels wrote:.
<snip>> .
So does DOUBLE PRECISION, which is STANDARD.I'm not sure that it is, or at least, not in a helpful way. A system with a default 64-bit real number might interpret DOUBLE PRECISION as 128-bit.
.
I agree that standardising REAL*8 would inject a fossil into the language. Perhaps a way forward is to define a new class of PARAMETER for types and kinds, e.g..
PARAMETER,KIND :: REAL_8 = REAL,KIND=KIND(1.0D0)
Then REAL_8 could only be used in a kind specification and would always mean the same thing. This would avoid an error which we found recently in an important code where the user had written an expression of the form:
REAL(dp),PARAMETER :: kappa = 68431_dp
dp was (as a result of SELECTED_REAL_KIND) equal to 8 so the integer was defined as 64-bits and no error occurred on the original ifort compiler. What NAG or FTN95 would have done with it I don't want to know.
We don't (yet) know how many more of these are likely to turn up..
The compiler could issue an error if a parameterised KIND were used as a tag for an integer literal.
John Collins wrote:.
On Monday, April 11, 2022 at 10:21:33 AM UTC+1, Robin Vowels wrote:
<snip>> .
So does DOUBLE PRECISION, which is STANDARD.
.
I'm not sure that it is, or at least, not in a helpful way. A system with a default 64-bit real number might interpret DOUBLE PRECISION as 128-bit.
DOUBLE PRECISION is defined by the standard. An entity with
default REAL kind type occupies one numeric storage unit.
An entity with DOUBLE PRECISION type occupies two numeric
storage units. If one numeric storage unit is 64 bits, then
two would use 128 bits.
On 4/12/22 1:23 PM, gah4 wrote:.
The original subject here is the non-standard REAL*8, but there is the standard, non-portable, and way too common REAL(8).There are thousands of lines of compiler documentation that use REAL(8) because that is a concise way to describe how the compiler does things.
When new programmers see that documentation, they will mimic it in their codes. This problem is not going away any time soon.
John Collins wrote:.
On Monday, April 11, 2022 at 10:21:33 AM UTC+1, Robin Vowels wrote:
<snip>> .
So does DOUBLE PRECISION, which is STANDARD.
.
I'm not sure that it is, or at least, not in a helpful way. A system with a default 64-bit real number might interpret DOUBLE PRECISION as 128-bit.
DOUBLE PRECISION is defined by the standard. An entity with
default REAL kind type occupies one numeric storage unit.
An entity with DOUBLE PRECISION type occupies two numeric
storage units. If one numeric storage unit is 64 bits, then
two would use 128 bits.
How many machines are using that offer only 64 bit reals?
On Tuesday, April 12, 2022 at 11:06:52 PM UTC-7, Robin Vowels wrote:.
(snip)
How many machines are using that offer only 64 bit reals?
Cray-1, Cray-1A, Cray-1S, Cray-1M, Cray-X-MP, Cray-Y-MP, Cray-2.
Cray-C90 Cray-EL90.
How many of each did they make, so we can add them all up?
On Tuesday, April 12, 2022 at 11:06:52 PM UTC-7, Robin Vowels wrote:
(snip)
How many machines are using that offer only 64 bit reals?
Cray-1, Cray-1A, Cray-1S, Cray-1M, Cray-X-MP, Cray-Y-MP, Cray-2
Cray-C90 Cray-EL90.
How many of each did they make, so we can add them all up?
On Wednesday, April 13, 2022 at 5:52:47 AM UTC+10, steve kargl wrote:
John Collins wrote:.
On Monday, April 11, 2022 at 10:21:33 AM UTC+1, Robin Vowels wrote:DOUBLE PRECISION is defined by the standard. An entity with
<snip>> .
So does DOUBLE PRECISION, which is STANDARD.
.
I'm not sure that it is, or at least, not in a helpful way. A system with a default 64-bit real number might interpret DOUBLE PRECISION as 128-bit.
default REAL kind type occupies one numeric storage unit.
An entity with DOUBLE PRECISION type occupies two numeric
storage units. If one numeric storage unit is 64 bits, then
two would use 128 bits.
How many machines are you using that offer 64 bit words for single precision?
.
How long would it take to write a program to read in a Fortran
program and change REAL(8) to REAL(dp) ?
Cray-1, Cray-1A, Cray-1S, Cray-1M, Cray-X-MP, Cray-Y-MP, Cray-2
Cray-C90 Cray-EL90.
I'm not sure exactly what this discussion is about, but fortran
compilers on those computers also supported 128-bit reals. Double
precision on those machines was slow, but it was there if you absolutely needed it.
However, the FPS series of machines, which were also popular in the
1980s, did not support 128-bit arithmetic at all. They only supported
64-bit single precision floating point.
On Wednesday, April 13, 2022 at 7:09:17 AM UTC+1, Robin Vowels wrote:
How long would it take to write a program to read in a Fortran
program and change REAL(8) to REAL(dp) ?
If the original code didn't have odd space characters, continuation lines
and comments in silly places very little time at all.
But I think that an issue here is that dp must be defined somewhere,
and the definition added to every routine. Inserting an INCLUDE file or
USE statement into every Fortran sub-program is much more work
than a 1-line sed script.
.. I think a simple, unambiguous declaration which didn't have any associated complexities would be useful. To that end REAL*8 is the best we have got, it works everywhere (at least that I know of) and doesn't need to be in the standard if everyoneunderstands it.
A "simple, unambiguous declaration" can be as suggested upthread i.e., IEEE_FPB64 where
IEEE_FPB64 is an intrinsic (built-in) alias for REAL(KIND=K) where
K = IEEE_SELECTED_REAL_KIND( P=15, R=307, RADIX=2 )
Here IEEE_FPB64 is something a Fortran processor supporting
IEEE_ARITHMETIC introduced Fortran 2003 must support intrinsically,
meaning there will be no need for any USE statements.
The introduction of IEEE_FPB64 can meet almost all the needs given
the >9X.Y% (X, Y likely >8) of computing that is now done using IEEE floating-point arithmetic toward the binary64 format in the
IEEE 60559:2011 standard.
Note: the Fortran standard can also introduce IEEE_FPB32, IEEE_FPB128, IEEE_FPB256 for completeness to introduce intrinsic support for binart32, binary128, and binary256 formats from the IEEE 60559:2011 i.e.,
those that are colloquially understood to be single, quadruple, and octuple
precision formats respectively. Additionally the standard can also introduce IEEE_FPD32, IEEE_FPD64, IEEE_FPD128 for the decimal formats since the IEEE_SELECTED_REAL_KIND also permits RADIX argument.
The latter may not be supported by any real processor for a long,
long time but it will be there for comprehensiveness.
Refactoring, when needed, of "REAL*8" codes would be a simple string replacement to "IEEE_FPB64".
On Wednesday, April 13, 2022 at 7:09:17 AM UTC+1, Robin Vowels wrote:.
.If the original code didn't have odd space characters, continuation lines and comments
How long would it take to write a program to read in a Fortran
program and change REAL(8) to REAL(dp) ?
in silly places very little time at all. But I think that an issue here is that dp must be defined
somewhere, and the definition added to every routine.
Inserting an INCLUDE file or USE statement into every Fortran sub-program is much more work than a 1-line sed script..
We have done all this. But I think a simple, unambiguous declaration which didn't have any associated complexities would be useful. To that end REAL*8 is the best we have got, it works everywhere (at least that I know of) and doesn't need to be in thestandard if everyone understands it.
On Wednesday, April 13, 2022 at 2:41:22 PM UTC-4, john.c...@simconglobal.com wrote:understands it.
.. I think a simple, unambiguous declaration which didn't have any associated complexities would be useful. To that end REAL*8 is the best we have got, it works everywhere (at least that I know of) and doesn't need to be in the standard if everyone
REAL*8 comes with considerable confusion given the current state of nonstandard compiler implementations and it is not going to make it into the ISO IEC standard for Fortran.be single, quadruple, and octuple precision formats respectively. Additionally the standard can also introduce IEEE_FPD32, IEEE_FPD64, IEEE_FPD128 for the decimal formats since the IEEE_SELECTED_REAL_KIND also permits RADIX argument. The latter may not
A "simple, unambiguous declaration" can be as suggested upthread i.e., IEEE_FPB64 where
IEEE_FPB64 is an intrinsic (built-in) alias for REAL(KIND=K) where K = IEEE_SELECTED_REAL_KIND( P=15, R=307, RADIX=2 )
Here IEEE_FPB64 is something a Fortran processor supporting IEEE_ARITHMETIC introduced Fortran 2003 must support intrinsically, meaning there will be no need for any USE statements.
The introduction of IEEE_FPB64 can meet almost all the needs given the >9X.Y% (X, Y likely >8) of computing that is now done using IEEE floating-point arithmetic toward the binary64 format in the IEEE 60559:2011 standard.
Note: the Fortran standard can also introduce IEEE_FPB32, IEEE_FPB128, IEEE_FPB256 for completeness to introduce intrinsic support for binart32, binary128, and binary256 formats from the IEEE 60559:2011 i.e., those that are colloquially understood to
Refactoring, when needed, of "REAL*8" codes would be a simple string replacement to "IEEE_FPB64"..
On Thursday, April 14, 2022 at 11:16:51 AM UTC+10, FortranFan wrote:
On Wednesday, April 13, 2022 at 2:41:22 PM UTC-4, john.c...@simconglobal.com wrote:
.. I think a simple, unambiguous declaration..
Refactoring, when needed, of "REAL*8" codes would be a simple string replacement to "IEEE_FPB64"..
That's gobbledegook.
English words are better, such as REAL, etc.
Since compilers treat the non-standard but very common
real*4, real*8, integer*4, integer*8
as
use iso_fortran_env
real(kind=real32), real(kind=real64), integer(kind=int32), integer(kind=int64)
would it make sense to standardize the former set of declarations, which is concise and clear, to mean the same as the latter?
On Sunday, April 10, 2022 at 12:37:41 AM UTC+10, Beliavsky wrote:
On Saturday, April 9, 2022 at 10:05:29 AM UTC-4, Beliavsky wrote:.
Since compilers treat the non-standard but very commonCurrently, if someone inherits a code with real*8 and decides to make it standard-conforming, they may replace it with
real*4, real*8, integer*4, integer*8
as
use iso_fortran_env
real(kind=real32), real(kind=real64), integer(kind=int32), integer(kind=int64)
would it make sense to standardize the former set of declarations, which is concise and clear, to mean the same as the latter?
real(kind=8),
An appropriate replacement is real (kind=dp)
(where dp is defined as kind(1.0d0)...)
On 4/13/22 2:44 AM, gah4 wrote:
On Tuesday, April 12, 2022 at 11:06:52 PM UTC-7, Robin Vowels wrote:
(snip)
How many machines are using that offer only 64 bit reals?
Cray-1, Cray-1A, Cray-1S, Cray-1M, Cray-X-MP, Cray-Y-MP, Cray-2
Cray-C90 Cray-EL90.
I'm not sure exactly what this discussion is about, but fortran
compilers on those computers also supported 128-bit reals. Double
precision on those machines was slow, but it was there if you absolutely needed it.
However, the FPS series of machines, which were also popular in the
1980s, did not support 128-bit arithmetic at all. They only supported
64-bit single precision floating point.
How many of each did they make, so we can add them all up?
These were not personal computers, so the measure is not how many of the computers were made, but rather how many programmers and users had
access to them. In my field of computational chemistry, that would be essentially every active programmer. In the 1980s, one could gain access
in a variety of ways, through government agencies like NSF, NIH, DoD, or
DOE, through state computer access programs, through universities, or
through private employers. Those machines cast a huge shadow in their time.
On 4/9/22 9:05 AM, Beliavsky wrote:
Since compilers treat the non-standard but very common
real*4, real*8, integer*4, integer*8
as
use iso_fortran_env
real(kind=real32), real(kind=real64), integer(kind=int32),
integer(kind=int64)
would it make sense to standardize the former set of declarations,
which is concise and clear, to mean the same as the latter?
In my opinion, this would be a step backward for the language.
There are many reasons why this should not be done, but one of them is
that REAL*4 etc. were always just defined by the local compiler to map
to its supported floating point formats. For byte addressable machines,
that meant that your suggested mapping would be correct. But there are
also 36-bit, 60-bit, and 64-bit machines that cannot conform to those mappings, so they must do something different. In the f77 time in the
1980s, I used those declarations extensively for exactly that reason, it
was a way, with some care, to write portable (but nonstandard) code. I
used REAL*8 declarations to run on machines with all of those word
lengths. It wasn't pretty, but it served its purpose at the time.
But now we have the fortran KIND system, which handles all of that much better. Yes, when you incorporate old f66 and f77 code into your current project, you need to edit in those changes, but that is not a big deal.
Your minimal efforts are rewarded with clarity and portability. I have programs with hundreds of thousands of lines where I can change the
precision globally by modifying a single line of code in a module. From
the programmer's perspective, that is hard to beat.
Numerical analysts are now experimenting with 16-bit real arithmetic to
speed up critical parts of algorithms. If/when they get that working,
the fortran KIND system is already set up to handle that. IEEE decimal arithmetic is another feature raising its head on the horizon. Again,
the fortran KIND system is already there and waiting. 10-byte arithmetic
is another example (although some compilers are currently doing this the wrong way, I think). 128-bit arithmetic and beyond, both reals and
integers, are all handled perfectly well with the fortran KIND system.
If a compiler supports real types with those numbers of bits (real32,
real64, etc.), then the kind values are set appropriately. If there is
more than one kind with that many bits, then the processor chooses which
one to return. If the processor does not support a kind with exactly
those bits, then the processor sets the value to either -1 or -2. The -2 value means that some kind is available with higher precision. This
might not be the best way to write portable code, but if you want to
write code targeted to specific floating point formats, that is a
reasonable way to do it. The IEEE intrinsic module goes even further if
code is intended to target that floating point format, rounding modes,
NaN, subnormals, etc., all available within the fortran KIND system.
This is all in contrast to REAL*4, REAL*8, etc, which are mapped in a
very loose manner to the underlying supported floating point formats.
I think the fortran KIND system is well thought out and it works well in practice.
Yep. And REAL*8 was by far the simplest way to have code running
efficiently on both these supercomputers and the unix workstations, when ~64bits precision was needed
Le 09/04/2022 à 16:05, Beliavsky a écrit :
Since compilers treat the non-standard but very common
real*4, real*8, integer*4, integer*8
as
use iso_fortran_env
real(kind=real32), real(kind=real64), integer(kind=int32),
integer(kind=int64)
would it make sense to standardize the former set of declarations,
which is concise and clear, to mean the same as the latter?
It could make sense, except that xxxx*n notations have never been standardized
As noted by other contributors :
- both REAL*4 and REAL*8 were mapped to the 64 bits floating point type
on old CRAY computers
- REAL*4 was mapped to the 36 bits floating point on CDC, and REAL*8 to
72 bits.
So mapping REAL*4 to kind=real32 could break some legacy codes, as it
seems to me that kind=real32 is *required* to be stored on exactly 32 bits.
I have to admit that 36 bits machines are unlikely to show up again (but
how knows...), but compilers that would completely drop 32 flating point support are not that unlikely in the future.
The CDC 7600 that I programmed on back in the 1970s was 60 bit words.
REAL*4 was mapped to the 60 bit word.
The UNIVAC 1108 was 36 bit words back in the 1970s. REAL*4 was mapped
to the 36 bit word.
Le 13/04/2022 à 17:10, Ron Shepard a écrit :.
On 4/13/22 2:44 AM, gah4 wrote:
On Tuesday, April 12, 2022 at 11:06:52 PM UTC-7, Robin Vowels wrote:
(snip)
How many machines are using that offer only 64 bit reals?
Cray-1, Cray-1A, Cray-1S, Cray-1M, Cray-X-MP, Cray-Y-MP, Cray-2
Cray-C90 Cray-EL90.
I'm not sure exactly what this discussion is about, but fortran
compilers on those computers also supported 128-bit reals. Double precision on those machines was slow, but it was there if you absolutely needed it.
However, the FPS series of machines, which were also popular in the
1980s, did not support 128-bit arithmetic at all. They only supported 64-bit single precision floating point.
How many of each did they make, so we can add them all up?
These were not personal computers, so the measure is not how many of the computers were made, but rather how many programmers and users hadYep. And REAL*8 was by far the simplest way to have code running
access to them. In my field of computational chemistry, that would be essentially every active programmer. In the 1980s, one could gain access in a variety of ways, through government agencies like NSF, NIH, DoD, or DOE, through state computer access programs, through universities, or through private employers. Those machines cast a huge shadow in their time.
efficiently on both these supercomputers and the unix workstations, when ~64bits precision was needed
Le 09/04/2022 à 19:15, Ron Shepard a écrit :.
On 4/9/22 9:05 AM, Beliavsky wrote:
Since compilers treat the non-standard but very common
real*4, real*8, integer*4, integer*8
as
use iso_fortran_env
real(kind=real32), real(kind=real64), integer(kind=int32),
integer(kind=int64)
would it make sense to standardize the former set of declarations,
which is concise and clear, to mean the same as the latter?
In my opinion, this would be a step backward for the language.
There are many reasons why this should not be done, but one of them is that REAL*4 etc. were always just defined by the local compiler to map
to its supported floating point formats. For byte addressable machines, that meant that your suggested mapping would be correct. But there are also 36-bit, 60-bit, and 64-bit machines that cannot conform to those mappings, so they must do something different. In the f77 time in the 1980s, I used those declarations extensively for exactly that reason, it was a way, with some care, to write portable (but nonstandard) code. I used REAL*8 declarations to run on machines with all of those word lengths. It wasn't pretty, but it served its purpose at the time.
But now we have the fortran KIND system, which handles all of that much better. Yes, when you incorporate old f66 and f77 code into your current project, you need to edit in those changes, but that is not a big deal. Your minimal efforts are rewarded with clarity and portability. I have programs with hundreds of thousands of lines where I can change the precision globally by modifying a single line of code in a module. From the programmer's perspective, that is hard to beat.
Numerical analysts are now experimenting with 16-bit real arithmetic to speed up critical parts of algorithms. If/when they get that working,
the fortran KIND system is already set up to handle that. IEEE decimal arithmetic is another feature raising its head on the horizon. Again,
the fortran KIND system is already there and waiting. 10-byte arithmetic is another example (although some compilers are currently doing this the wrong way, I think). 128-bit arithmetic and beyond, both reals and integers, are all handled perfectly well with the fortran KIND system.
If a compiler supports real types with those numbers of bits (real32, real64, etc.), then the kind values are set appropriately. If there is more than one kind with that many bits, then the processor chooses which one to return. If the processor does not support a kind with exactly
those bits, then the processor sets the value to either -1 or -2. The -2 value means that some kind is available with higher precision. This
might not be the best way to write portable code, but if you want to
write code targeted to specific floating point formats, that is a reasonable way to do it. The IEEE intrinsic module goes even further if code is intended to target that floating point format, rounding modes, NaN, subnormals, etc., all available within the fortran KIND system.
This is all in contrast to REAL*4, REAL*8, etc, which are mapped in a
very loose manner to the underlying supported floating point formats.
I think the fortran KIND system is well thought out and it works well in practice.
And yet, it still lacks something as simple as REAL*8, which would
select either the default REAL or the DOUBLE PRECISION, and nothing else.
kind=real64 is almost that, except that:.
- it may not exist
- nothing garantees that real64 is kind(1.0) or kind(1.0d0)
OK, as of today there's probably no compiler where real64 does not exist
(or does exist but is inefficient). Nevertheless it can happen one day
or another...
I used to write:
integer, parameter :: sp = kind(1.0)
integer, parameter :: dp = kind(1.0d0)
integer, parameter :: sp_is_enough = min(max(precision(sp)-9,1),0)
integer, parameter :: double = sp*sp_is_enough + dp*(1-sp_is_enough)
so REAL(kind=double) is similar to the C "double", which is only
required to have at least 10 digits precision, and which can be
identical to "float". And most importantly it is always, and will always
be, defined.
kind=sp, kind=dp, and kind=double, cover 99.99% of the needs.
.
These were not personal computers, so the measure is not how many of the >>> computers were made, but rather how many programmers and users had
access to them. In my field of computational chemistry, that would be
essentially every active programmer. In the 1980s, one could gain access >>> in a variety of ways, through government agencies like NSF, NIH, DoD, or >>> DOE, through state computer access programs, through universities, or
through private employers. Those machines cast a huge shadow in their time.
Yep. And REAL*8 was by far the simplest way to have code running
efficiently on both these supercomputers and the unix workstations, when
~64bits precision was needed
DOUBLE PRECISION was clear and unequivocal (and STANDARD).
.
I used to write:
integer, parameter :: sp = kind(1.0)
integer, parameter :: dp = kind(1.0d0)
integer, parameter :: sp_is_enough = min(max(precision(sp)-9,1),0)
integer, parameter :: double = sp*sp_is_enough + dp*(1-sp_is_enough)
This last line won't work in some compilers.
.
Le 18/06/2022 à 04:10, Robin Vowels a écrit :.
And a full waste of resources (both CPU time and memory) on a Cray, as.
These were not personal computers, so the measure is not how many of the >>> computers were made, but rather how many programmers and users had
access to them. In my field of computational chemistry, that would be >>> essentially every active programmer. In the 1980s, one could gain access >>> in a variety of ways, through government agencies like NSF, NIH, DoD, or >>> DOE, through state computer access programs, through universities, or >>> through private employers. Those machines cast a huge shadow in their time.
Yep. And REAL*8 was by far the simplest way to have code running
efficiently on both these supercomputers and the unix workstations, when >> ~64bits precision was needed
DOUBLE PRECISION was clear and unequivocal (and STANDARD).
it was 128 bits software emulated.
When you were lucky enough to have access to such machines back then, it
was a crime to use DOUBLE PRECISION where REAL was enough.
..And a full waste of resources (both CPU time and memory) on a Cray, as
DOUBLE PRECISION was clear and unequivocal (and STANDARD).
it was 128 bits software emulated.
When you were lucky enough to have access to such machines back then, it
was a crime to use DOUBLE PRECISION where REAL was enough.
In that case, you used REAL.
Le 18/06/2022 à 00:55, pehache a écrit :
And yet, it still lacks something as simple as REAL*8, which would
select either the default REAL or the DOUBLE PRECISION, and nothing else.
kind=real64 is almost that, except that:
- it may not exist
- nothing garantees that real64 is kind(1.0) or kind(1.0d0)
OK, as of today there's probably no compiler where real64 does not
exist (or does exist but is inefficient). Nevertheless it can happen
one day or another...
I used to write:
integer, parameter :: sp = kind(1.0)
integer, parameter :: dp = kind(1.0d0)
integer, parameter :: sp_is_enough = min(max(precision(sp)-9,1),0)
integer, parameter :: double = sp*sp_is_enough + dp*(1-sp_is_enough)
so REAL(kind=double) is similar to the C "double", which is only
required to have at least 10 digits precision, and which can be
identical to "float". And most importantly it is always, and will
always be, defined.
kind=sp, kind=dp, and kind=double, cover 99.99% of the needs.
I am just discovering the stdlib kinds module... REAL(kind=dp) might be
the quasi-standard substitute for REAL*8. If I understand correctly "dp"
is just an alias to "c_double" in ISO_BIND_C. Good point : it is always defined.
integer, parameter :: sp = kind(1.0)
integer, parameter :: dp = kind(1.0d0)
In such cases, why not just write REAL and DOUBLE PRECISION? The
results will be exactly the same.
If you are going to use KIND, then don't call it something like sp or dp which is confusing if you change the definition (sort of the point of
KIND); if you won't ever change it, just use REAL and DOUBLE PRECISION: completely clear, completely standard.
integer, parameter :: sp = kind(1.0)
integer, parameter :: dp = kind(1.0d0)
Well, some then define wp, working precision, which is either sp or dp.
So you only have to change one place.
.. I sometimes use selected_real(kind(prec)) where prec is any of 6,15,18,33 ..
On Friday, June 17, 2022 at 4:58:32 PM UTC-7, Lynn McGuire wrote:
(snip)
The CDC 7600 that I programmed on back in the 1970s was 60 bit words.
REAL*4 was mapped to the 60 bit word.
The UNIVAC 1108 was 36 bit words back in the 1970s. REAL*4 was mapped
to the 36 bit word.
I am not sure about REAL*4 and the PDP-10's 36 bit word, but I do
remember that REAL*8 got the double precision 72 bit word.
(Actually, there are two PDP-10 double precisions, one for the machines without double precision hardware that do it in software, the other
for ones with the hardware.
On Saturday, June 18, 2022 at 5:05:54 PM UTC-4, jfh wrote:Yes. Sorry. I usually check anything I say in Fortran by compiling it but I was in a hurry this morning.
.. I sometimes use selected_real(kind(prec)) where prec is any of 6,15,18,33 ..
You meant selected_real_kind(prec)?
On Saturday, June 18, 2022 at 12:45:40 PM UTC-7, Phillip Helbig (undress to reply) wrote:
integer, parameter :: sp = kind(1.0)
integer, parameter :: dp = kind(1.0d0)
In such cases, why not just write REAL and DOUBLE PRECISION? The
results will be exactly the same.
If you are going to use KIND, then don't call it something like sp or dp which is confusing if you change the definition (sort of the point of KIND); if you won't ever change it, just use REAL and DOUBLE PRECISION: completely clear, completely standard.
Well, some then define wp, working precision, which is either sp or dp.
So you only have to change one place.
One trick from the card days was a C in column 80. You then reverse
the card, and to end, so the C is in column 1. Just for the ones
you don't want to use.
integer, parameter :: sp = kind(1.0)
integer, parameter :: dp = kind(1.0d0)
In such cases, why not just write REAL and DOUBLE PRECISION?
It seems, though, that REAL(8) is now very popular, and even taught in
some scientific computing courses. However, KIND values are not
standardized at all, and so that is less reasonable than REAL*8.
I think the fortran KIND system is well thought out and it works well
in practice.
And yet, it still lacks something as simple as REAL*8, which would
select either the default REAL or the DOUBLE PRECISION, and nothing else.
People who had access to a Cray at the times also had classical unix workstations, with compilers defaulting REAL to 32 bits as usual. Many
codes had to run on both machines.
On Saturday, June 18, 2022 at 8:02:31 AM UTC+10, pehache wrote:
Le 13/04/2022 à 17:10, Ron Shepard a écrit :.
On 4/13/22 2:44 AM, gah4 wrote:efficiently on both these supercomputers and the unix workstations, when
On Tuesday, April 12, 2022 at 11:06:52 PM UTC-7, Robin Vowels wrote:
(snip)
How many machines are using that offer only 64 bit reals?
Cray-1, Cray-1A, Cray-1S, Cray-1M, Cray-X-MP, Cray-Y-MP, Cray-2
Cray-C90 Cray-EL90.
I'm not sure exactly what this discussion is about, but fortran
compilers on those computers also supported 128-bit reals. Double
precision on those machines was slow, but it was there if you absolutely >>> needed it.
However, the FPS series of machines, which were also popular in the
1980s, did not support 128-bit arithmetic at all. They only supported
64-bit single precision floating point.
How many of each did they make, so we can add them all up?
These were not personal computers, so the measure is not how many of the >>> computers were made, but rather how many programmers and users had
access to them. In my field of computational chemistry, that would be
essentially every active programmer. In the 1980s, one could gain access >>> in a variety of ways, through government agencies like NSF, NIH, DoD, or >>> DOE, through state computer access programs, through universities, or
through private employers. Those machines cast a huge shadow in their time. >> Yep. And REAL*8 was by far the simplest way to have code running
~64bits precision was needed
DOUBLE PRECISION was clear and unequivocal (and STANDARD).
On 6/18/22 11:26 AM, pehache wrote:
[...]
People who had access to a Cray at the times also had classical unix
workstations, with compilers defaulting REAL to 32 bits as usual. Many
codes had to run on both machines.
I think this is why CRAY computers weren't more popular than they were.
Seymore Cray focused on high-end supercomputing, and he was not
interested in the full programming infrastructure to support that supercomputing. There were several things that would have saved the
company and that computing environment, none of which happened:
1) PC-level, workstation-level, or department-level minicomputers that supported the CRAY instruction set.
2) Development of interactive debuggers to facilitate code development.
3) Support for cross compilers that would allow code development on
PC-level computers. It would have been great if code could have run in simulation mode on these computers, but even having the ability to
compile the code on a local PC or workstation to see compile-time
diagnostics would have been a huge step forward.
4) Support for fortran 8x, with array operations and more or less direct support for vector hardware. Instead, it was not until the late 1980s
and 1990s that CRAY computers even supported f77.
Le 18/06/2022 à 21:45, Phillip Helbig (undress to reply) a écrit :
integer, parameter :: sp = kind(1.0)
integer, parameter :: dp = kind(1.0d0)
In such cases, why not just write REAL and DOUBLE PRECISION?
Just to simplify the two lines that come ater and that you have cut ;)
On 6/18/22 11:26 AM, pehache wrote:
[...]
People who had access to a Cray at the times also had classical unix
workstations, with compilers defaulting REAL to 32 bits as usual. Many
codes had to run on both machines.
I think this is why CRAY computers weren't more popular than they were.
Seymore Cray focused on high-end supercomputing, and he was not
interested in the full programming infrastructure to support that supercomputing. There were several things that would have saved the
company and that computing environment, none of which happened:
1) PC-level, workstation-level, or department-level minicomputers that supported the CRAY instruction set.
2) Development of interactive debuggers to facilitate code development.
3) Support for cross compilers that would allow code development on
PC-level computers. It would have been great if code could have run in simulation mode on these computers, but even having the ability to
compile the code on a local PC or workstation to see compile-time
diagnostics would have been a huge step forward.
4) Support for fortran 8x, with array operations and more or less direct support for vector hardware. Instead, it was not until the late 1980s
and 1990s that CRAY computers even supported f77.
On 6/17/22 5:55 PM, pehache wrote:
I think the fortran KIND system is well thought out and it works well
in practice.
And yet, it still lacks something as simple as REAL*8, which would
select either the default REAL or the DOUBLE PRECISION, and nothing else.
The common real(wp) convention is only one character more, and it avoids
all of the problems with the literal kind value. You can write millions
of lines of code with that declaration, and the wp parameter can be
defined in a single line of code. To change precision throughout, only
that single line of code needs to be changed.
You can't make things easier than that.
Further, if for some reason there is a conflict of kinds between some
legacy code and the modern code, then you find out these problems at
compile time where they can be easily addressed. It does not require
some extensive testing and debugging at run time to find the kind
mismatches.
I do think it would be better if it were easier to incorporate legacy
code into modules. But it is hard to think of an improvement over the
fortran KIND system, for either mixed- or nonmixed precision arithmetic.
Also in theory the result of selected_real_kind() could be a kind that
is neither REAL nor DOUBLE PRECISION. But if your code is calling
libraries such as BLAS/LAPACK, you really want only one of these two...
What I mean here is that in practice, the usage of all the kind system
rely on some assumptions about the hardware. It's OK because we have
nowadays quite standardized machines, but we tend to forget that we are making assumptions.
Since compilers treat the non-standard but very common
real*4, real*8, integer*4, integer*8
On 6/20/22 11:06 AM, pehache wrote:
Also in theory the result of selected_real_kind() could be a kind that
is neither REAL nor DOUBLE PRECISION. But if your code is calling
libraries such as BLAS/LAPACK, you really want only one of these two...
This is a shortcoming of the implementation of the BLAS and LAPACK
libraries. They were designed to support the real and double precision provided by fortran in the 1970s and 1980s, and nothing else.
I don't know what the answer is for this. Maybe the
language should have two types of support, one just a subset for simple operations, and the other level being the full support as it is now.
I think the fortran kind system is quite open ended and well designed.
When combined with explicit interfaces, which prevent mistakes
associated with mismatched arguments, it seems hard to beat the design.
Le 18/06/2022 à 04:21, Robin Vowels a écrit :.
Isn't it a constant expression ?.
I used to write:
integer, parameter :: sp = kind(1.0)
integer, parameter :: dp = kind(1.0d0)
integer, parameter :: sp_is_enough = min(max(precision(sp)-9,1),0)
integer, parameter :: double = sp*sp_is_enough + dp*(1-sp_is_enough)
This last line won't work in some compilers.
.
On Saturday, June 18, 2022 at 3:36:34 PM UTC+10, pehache wrote:
Le 18/06/2022 à 04:21, Robin Vowels a écrit :.
Isn't it a constant expression ?.
I used to write:
integer, parameter :: sp = kind(1.0)
integer, parameter :: dp = kind(1.0d0)
integer, parameter :: sp_is_enough = min(max(precision(sp)-9,1),0)
integer, parameter :: double = sp*sp_is_enough + dp*(1-sp_is_enough)
This last line won't work in some compilers.
.
0004) integer, parameter :: sp_is_enough = min(max(precision(sp)-9,1),0)
*** The first argument (X) to the intrinsic PRECISION must be of REAL or
COMPLEX type, not INTEGER(KIND=3)
On Monday, June 20, 2022 at 10:39:10 AM UTC-7, Ron Shepard wrote:
(snip)
I think the fortran kind system is quite open ended and well designed.
When combined with explicit interfaces, which prevent mistakes
associated with mismatched arguments, it seems hard to beat the design.
I suppose, but it leaves out that you often don't know the kind needed.
Maybe it is more obvious for integers. They need to be big enough
for whatever you might want to count. And you might know now how
big is enough, but maybe not forever, when your program might be
used by someone else. 32 bit integers are big enough for the
size (one dimension) of a square matrix, but maybe not for the
number of elements. 16 bit integers are not big enough for
storing a US (five digit) zip code.
For floating point, very little is built to better than single
precision. (About 1mm per km, or 1s per day, or one gram
per ton.) But very often double precision intermediates
are needed to get single precision results. That is true
for many matrix algorithms, and often for numerical
derivatives.
Sometimes we know that four or five digits is good
enough, but that isn't enough reason to rewrite the
program to use that precision. (Assuming that there
is hardware to supply it.)
Most often, algorithms are written to "good enough"
precision.
You could write REAL(SELECTED_REAL_KIND(8)) when you knew
that 8 digits was enough, and that you didn't need 12 or 14.
But since 8 digit hardware is rare, might as well just use the
usual hardware precision of about 52 significant bits.
Le 20/06/2022 à 19:39, Ron Shepard a écrit :
On 6/20/22 11:06 AM, pehache wrote:
Also in theory the result of selected_real_kind() could be a kind
that is neither REAL nor DOUBLE PRECISION. But if your code is
calling libraries such as BLAS/LAPACK, you really want only one of
these two...
This is a shortcoming of the implementation of the BLAS and LAPACK
libraries. They were designed to support the real and double precision
provided by fortran in the 1970s and 1980s, and nothing else.
Whatever, this is something that should be addressed, as legacy has
always been something to care about in Fortran.
For instance :
selected_real_kind(p,r,list) where list would be an optional array of
kinds we want to chose from
or a "double" kind value provided by ISO_FORTRAN_ENV (or stdlib_kind at
the moment), which would have at leasts 10 digits precison and that
would be either kind(1.0) or kind(1.0d0)
By the way, as long as there's no full generic programming in Fortran, writing libraries for all possible kinds that can be encountered is not
easy.
I don't know what the answer is for this. Maybe the language should
have two types of support, one just a subset for simple operations,
and the other level being the full support as it is now.
Let's say that REAL and DOUBLE PRECISION must have full support, and the
rest don't have to... :)
On Saturday, April 9, 2022 at 7:05:29 AM UTC-7, Beliavsky wrote:
Since compilers treat the non-standard but very common
real*4, real*8, integer*4, integer*8
I just notice that there is no mention of COMPLEX*8, COMPLEX*16, and even COMPLEX*32.
Should we have those, too?
On 6/21/22 6:04 AM, pehache wrote:
Le 20/06/2022 à 19:39, Ron Shepard a écrit :
On 6/20/22 11:06 AM, pehache wrote:
Also in theory the result of selected_real_kind() could be a kind
that is neither REAL nor DOUBLE PRECISION. But if your code is
calling libraries such as BLAS/LAPACK, you really want only one of
these two...
This is a shortcoming of the implementation of the BLAS and LAPACK
libraries. They were designed to support the real and double precision
provided by fortran in the 1970s and 1980s, and nothing else.
Whatever, this is something that should be addressed, as legacy has
always been something to care about in Fortran.
Note that some vendors supported 128-bit floating point arithmetic even
in the 1970s and early 1980s when these libraries were first developed.
They did extend the use to double precision complex, a common extension
that was not part of standard fortran, but they did not account for any
other real or complex kinds. Now that the kind facility is available,
this could be done in a straightforward way, but that hasn't occurred in
the 30+ years since f90 has been available. I'm just guessing about
this, but I think the reason is that the source code is available, so if
some individual wanted a 128-bit floating point version of some linear algebra code, he could do the work himself.
For instance :
selected_real_kind(p,r,list) where list would be an optional array of
kinds we want to chose from
or a "double" kind value provided by ISO_FORTRAN_ENV (or stdlib_kind at
the moment), which would have at leasts 10 digits precison and that
would be either kind(1.0) or kind(1.0d0)
This is already what selected_real_kind(10) does.
If there are more than
one choice, then maybe it doesn't return the one the programmer might
want, but then the other exponent and base arguments can be added to
refine the selection.
No, it does not ensure that the result is necessarily kind(1.0) or kind(1.0d0)
Le 21/06/2022 à 17:24, Ron Shepard a écrit :
On 6/21/22 6:04 AM, pehache wrote:
Le 20/06/2022 à 19:39, Ron Shepard a écrit :
On 6/20/22 11:06 AM, pehache wrote:
Also in theory the result of selected_real_kind() could be a kind
that is neither REAL nor DOUBLE PRECISION. But if your code is
calling libraries such as BLAS/LAPACK, you really want only one of
these two...
This is a shortcoming of the implementation of the BLAS and LAPACK
libraries. They were designed to support the real and double precision >>> provided by fortran in the 1970s and 1980s, and nothing else.
Whatever, this is something that should be addressed, as legacy has
always been something to care about in Fortran.
Note that some vendors supported 128-bit floating point arithmetic evenThe main reason is that there is not something like a unified hardware support for quadruple precision. If one writes a library and wants to provide binaries for a platform that has no hardware support for quadruple precision, what should one do? One can compile the library with a compiler that has a real128 kind, but without any guarantee that it will work if
in the 1970s and early 1980s when these libraries were first developed. They did extend the use to double precision complex, a common extension that was not part of standard fortran, but they did not account for any other real or complex kinds. Now that the kind facility is available,
this could be done in a straightforward way, but that hasn't occurred in the 30+ years since f90 has been available. I'm just guessing about
this, but I think the reason is that the source code is available, so if some individual wanted a 128-bit floating point version of some linear algebra code, he could do the work himself.
the compiled library is called from a code compiled with another compiler, as different compilers may use different interpretation of real128
(ieee-754 compliant, or as "double double", or as the x86 10 bytes
floating point padded to 16 bytes, ...).
For instance :
selected_real_kind(p,r,list) where list would be an optional array of
kinds we want to chose from
or a "double" kind value provided by ISO_FORTRAN_ENV (or stdlib_kind at >> the moment), which would have at leasts 10 digits precison and that
would be either kind(1.0) or kind(1.0d0)
This is already what selected_real_kind(10) does.No, it does not ensure that the result is necessarily kind(1.0) or kind(1.0d0)
If there are more thanIf the programmer knows what specific kind he wants beforehand, there's simply no reason at all to use selected_real_kind()
one choice, then maybe it doesn't return the one the programmer might want, but then the other exponent and base arguments can be added to refine the selection.
Ron Shepard wrote:
I think the problem people have is that it is stored in 16 bytes, so
there is a lot of wasted memory and/or file space.
Then those people are blaming the wrong thing. Intel choose 4, 8, and 16-byte alignment in their ABIs. gfortran (and gcc) are just a tool sitting above the cpu.
On Sunday, April 10, 2022 at 3:35:25 PM UTC+10, JCampbell wrote:
real(dp) or real(kind=dp) is not clear,.
in what way? "dp" is used often enough that it is immediately clear
that it signifies double precision.
To that end REAL*8 is the best we have got, it works everywhere (at least that I know of)
and doesn't need to be in the standard if everyone understands it.
Early support for f90, maybe... But even in the 1990s f90 was not that popular in high performance computing (for sometimes good, sometimes bad reasons). The recommandation where I was working (as a PhD student) was
to stick to f77. So the lack of f90 features on the Cray was not a big problem I guess.
The problem I see with fortran isn't the kind system, which allows the programmer to mix kinds within expressions with complete control, rather
it is the complications that come from the library support of those
kinds. If a compiler has, say 10 different real kinds, then it is
required to support all of the intrinsics for each of those kinds, all
the exp and log functions, all the trig functions, all the Bessel
functions, and so on, for both real and complex types. That seems like a
high hurdle. I don't know what the answer is for this. Maybe the
language should have two types of support, one just a subset for simple operations, and the other level being the full support as it is now.
The kind system deals with another problem: since some machines
might have 32-bit single precision, and 64-bit double precision, and others might have 64-bit single precision and 128-bit double precision, a way is provided to use the 64-bit reals on both kinds of machine by specifying that one wants at least 15 (or even 12) decimal digits of precision.
On Monday, April 11, 2022 at 3:21:33 AM UTC-6, Robin Vowels wrote:
On Sunday, April 10, 2022 at 3:35:25 PM UTC+10, JCampbell wrote:
real(dp) or real(kind=dp) is not clear,.
in what way? "dp" is used often enough that it is immediately clear
that it signifies double precision.
My quarrel with it is that it is redundant. DOUBLE PRECISION is already
in existence in the language; the syntax real(...) is for when you want to specify by length instead.
On Wednesday, April 13, 2022 at 12:41:22 PM UTC-6, john.c...@simconglobal.com wrote:
To that end REAL*8 is the best we have got, it works everywhere (at least that I know of)
and doesn't need to be in the standard if everyone understands it.
On the FORTRAN compiler for the IBM System/360, IBM added length specifications as
an extension to the standard. It allowed them to define COMPLEX*16, since DOUBLE
COMPLEX was not yet part of the standard at the time. And it allowed them to define
LOGICAL*1 in addition to LOGICAL*4 (the default), and INTEGER*2 in addition to
INTEGER*4.
This extension served a purpose in its day. But it was not intended to be _portable_.
So on a machine with addressable 6-bit characters, REAL might be REAL*6 or REAL*8,
and DOUBLE PRECISION might be REAL*12 or REAL*16. Or even REAL*10.
Of course, these days, byte addressing and power-of-two word sizes are nigh universal.
John Savard
The point of using the kind system is that you don't need to know in advance what kinds are available. SELECTED_REAL_KIND helps to do that.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 157 |
Nodes: | 16 (0 / 16) |
Uptime: | 16:20:14 |
Calls: | 3,193 |
Files: | 10,512 |
Messages: | 2,978,769 |