
forums.silverfrost.com Welcome to the Silverfrost forums

View previous topic :: View next topic 
Author 
Message 
mecej4
Joined: 31 Oct 2006 Posts: 874

Posted: Sat Mar 03, 2018 3:33 pm Post subject: Inconsistent treatment of Kind Numbers if /alt_kinds is used 


The /alt_kinds option is convenient to use when compiling large existing Fortran codes in which the kind numbers 4 and 8 for single and doubleprecison reals are hardwired into the source code. Because other widelyused compilers use these kind numbers, /alt_kinds enables one to reuse codes from, for example, www.netlib.org, without having to modify the code to use the FTN95 native kind numbers (1 and 2), or to make the code fully portable using SELECTED_REAL_KIND.
The implementation of /alt_kinds is, unfortunately, incomplete/inconsistent. I found at least three previous posts in which this question was debated:
http://forums.silverfrost.com/viewtopic.php?t=742
http://forums.silverfrost.com/viewtopic.php?t=1453
http://forums.silverfrost.com/viewtopic.php?t=3313
Today, I ran into problems when I was working with code in which expressions of the type real(<integer_expression>, KIND=<symbolic_kind_number>). Here is a short program to illustrate the problem.
Code:  program tst
implicit none
integer, parameter :: sp = selected_real_kind(7,30), &
dp = selected_real_kind(15,300)
integer :: ij
real(sp) :: x(2)
real(dp) :: xd(2)
!
ij = 15729
x(1) = real(ij, sp)
x(2) = acos(1.0_sp)
xd(1) = real(ij,dp)
xd(2) = acos(1.0_dp)
print *, 'sp, dp = ', sp, dp
print *, 'x, xd = ', x, xd
end program tst 
Note that the code makes no assumptions regarding kind numbers (beyond assuming that single and double precision are available, which are required by the standards). The program runs fine with FTN95 (as long as you do not use /alt_kinds), Gfortran, Intel, etc. It also works fine with NAG, with or without the kind=byte option, which has the same purpose as /alt_kinds. With FTN95 /alt_kinds, the compilation fails:
Code:  [FTN95/Win32 Ver. 8.10.0 Copyright (c) Silverfrost Ltd 19932017]
0010) x(1) = real(ij, sp)
*** KIND parameter out of range, permitted KINDs are 1, 2, or 3
0012) xd(1) = real(ij,dp)
*** KIND parameter out of range, permitted KINDs are 1, 2, or 3
2 ERRORS [<TST> FTN95 v8.20.0]
*** Compilation failed 
Thus, the kind number(s) returned by SELECTED_REAL_KIND is not accepted as valid for use as the optional argument KIND of the intrinsic function REAL, which is inconsistent.
One could object that the example code does not need /alt_kinds at all. That is true, but imagine a large source file containing many declarations and lots of code spread over many files, the compiling of which requires the use of /alt_kinds.
P.S., added on March 7: It turns out (see responses below) that SELECTED_REAL_KIND(7,30) means double precision, rather than single precision. The program should have contained SELECTED_REAL_KIND(6,30) instead.
Last edited by mecej4 on Wed Mar 07, 2018 11:51 am; edited 2 times in total 

Back to top 


JohnCampbell
Joined: 16 Feb 2006 Posts: 1930 Location: Sydney

Posted: Mon Mar 05, 2018 3:43 am Post subject: 


Given this history of problems with kind and FTN95, I find REAL*8 to be a very useful extension.
With 64bit, the problem of using integer*8 constants is more realistic.
One question that I am wondering is : What should be the Fortran 90 standard "type default integer" kind for a 64bit OS. I would think it should be a 64 bit integer.
I can't find what are the requirements of a type default integer, but I would expect that it should be able to address array sizes that can be defined for the OS being used. 

Back to top 


LitusSaxonicum
Joined: 23 Aug 2005 Posts: 1773 Location: Yateley, Hants, UK

Posted: Mon Mar 05, 2018 11:15 am Post subject: 


John,
What is 32 bit, what is 64 bit, in terms of a compiler or OS? Mecej4 once pointed out that you run out of addressing space with a multidimensioned array with each dimension smaller than a maximum INTEGER*4 (which impressed me mightily, because I'd never thought of it). This limitation must apply (eventually) however big you make your INTEGERs.
For some reason, Windows32 appears to be INTEGER*4 and REAL*8. Whether this means that Windows64 is INTEGER*8 I don't know  probably. That reverts us to Fortran 66 where the size of INTEGER and REAL was the same. There are things to be said for and against this, like using an integer to store option codes. Unless you have more than 250 of these, even INTEGER*1 is wasteful!
INTEGER*8 and REAL*8 can't be 'standard' Fortran, because then there is no DOUBLE PRECISION type (and probably other reasons as well).
The KINDs business always seemed to me to be rather flawed, as it has the potential to be different for different machines and compilers, and if you ask for the KIND by specifying range and precision, again, you might get something different. Not that it matters, because once you use Clearwin+ you are effectively locked into FTN95, which is fine by me but not to a purist.
Eddie 

Back to top 


mecej4
Joined: 31 Oct 2006 Posts: 874

Posted: Mon Mar 05, 2018 1:46 pm Post subject: 


Kind numbers seem to have been a solution to a problem that existed in the mainframe era. However, by the time the solution was presented, microprocessors and personal computers/workstations became widespread; the problem faded in importance, but we were burdened with the solution.
Some sarcastic remarks about SELECTED_REAL_KIND:
The customer can have any KIND, as long as it is implemented in our CPU.
The customer can ask for the moon with SELECTED_REAL_KIND, but will have to settle for a piece of cheese.
It would be useful if someone with ties to J3 undertook and published an assessment of KIND, now that we have lived with this feature for a couple of decades and computer architectures have converged. 

Back to top 


DanRRight
Joined: 10 Mar 2008 Posts: 1781 Location: South Pole, Antarctica

Posted: Mon Mar 05, 2018 7:02 pm Post subject: 


I'd consider the KIND kind of confusing and even almost dead (possibly asking Silvertfrost to offer in diagnostics of errors to mention both suggestions, older real*4/real*8 and new with KINDs for Fortran language Nazis. Currently older one is not mentioned), but developers saved KIND from extinction by introducing KIND=7 for window handles.
Last edited by DanRRight on Tue Mar 06, 2018 5:19 pm; edited 1 time in total 

Back to top 


PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 5294 Location: Salford, UK

Posted: Tue Mar 06, 2018 3:18 pm Post subject: 


Many thanks for the bug report. This has now been fixed for the next release. 

Back to top 


JohnCampbell
Joined: 16 Feb 2006 Posts: 1930 Location: Sydney

Posted: Wed Mar 07, 2018 12:05 am Post subject: 


What should be the response for :
integer, parameter :: sp = selected_real_kind (7,30)
Running Program tst surprised me !
Perhaps I should adopt the following approach to standard conforming code. It shows my thoughts on the suitability of kind !
Code:  module precisions
implicit none
integer, parameter :: sp = selected_real_kind(6,30)
integer, parameter :: dp = selected_real_kind(7,30)
end module precisions
program tst
use precisions
integer :: ij
real(sp) :: x(2)
real(dp) :: xd(2)
!
ij = 15729
x(1) = real(ij, sp)
x(2) = acos(1.0_sp)
xd(1) = real(ij,dp)
xd(2) = acos(1.0_dp)
print *, 'sp, dp = ', sp, dp
print *, 'x, xd = ', x, xd
end program tst 


Back to top 


mecej4
Joined: 31 Oct 2006 Posts: 874

Posted: Wed Mar 07, 2018 5:01 am Post subject: 


John, you are right, the "sp" and "dp" given by the test program in the original post are the same, as I would have found out if the compiler could compile and let me run the program! Your suggestion of using a precision of 6 digits for single precision and 7 digits for double precision in the invocation of SELECTED_REAL_KIND is provocative, and prompts the question, "If you ask for only 7 digits, couldn't you get by with just 6, which is almost the same?"
The Fortran 2003 standard says this about PRECISION:
Quote:  The result has the value INT ((p − 1) * LOG10 (b)) + k, where b and p are as defined in 13.4 for the model representing real numbers with the same value for the kind type parameter as X, and where k is 1 if b is an integral power of 10 and 0 otherwise. 
For IEEE32, p = 24, b = 2, k = 0, so we get INT(23*0.3010) = INT(6.9..) = 6. For numbers in the neighborhood of 1.0, we have INT(24*0.3010) = 7, but consideration of edge values and binarydecimal conversion robs us of one digit, leaving 6.
The two precisions that you requested straddle 6.9, so you get different kind numbers for P = 6 and P = 7 from SELECTED_REAL_KIND(P,30).
Last edited by mecej4 on Wed Mar 07, 2018 12:19 pm; edited 1 time in total 

Back to top 


JohnCampbell
Joined: 16 Feb 2006 Posts: 1930 Location: Sydney

Posted: Wed Mar 07, 2018 5:56 am Post subject: 


This variability of precision interpretation can also be seen with different compiler implementation of "write (*,*) x" where a different number of significant digits are reported. I think FTN95 reports 6 while others report 7.
This just further reinforces my dislike for the KIND structure in Fortran.
Reading the code where "integer, parameter :: sp = selected_real_kind (7,30) " is used does not clearly indicate there is a problem.
You have to run the code and check the value to see the problem.
selected_real_kind is not a user friendly routine, with required values having little relevance to what is being requested. I am sure most users are thinking of supported real types and how many bytes do we need for this real calculation, rather than what precision should be specified. Even a very experienced user like yourself can get this wrong. This approach is a nonsense.
REAL*4 is supported by all Fortran 90+ compilers on platforms that support the IEEE 754 Standard for Floating Point. That excludes very few compiler/hardware options.
Although REAL*4 does not conform to the Fortran standard, only a few would claim that the Fortran standard is divinely inspired. It can be ok to not conform.
KIND should go the way of the dodo.
John 

Back to top 


LitusSaxonicum
Joined: 23 Aug 2005 Posts: 1773 Location: Yateley, Hants, UK

Posted: Wed Mar 07, 2018 11:59 am Post subject: 


John,
I dislike KIND and everything that flows from it, just as I dislike a lot of constructs that appeared in and since Fortran 90 and attempt to supplant what was there before. I saw a quote from 3 decades ago: 'Nice language, but it's not Fortran'. I also dislike a lot about earlier Fortran versions, never having used ENTRY ever, and assigned and computed GO TOs once only (each) when I couldn't see another way (and removed when I did). I disliked ENCODE and DECODE  and lots of other things.
But, when you remove something, you make someone's source code stop working, and if a lot of years pass by since it was removed, knowledge of what it was for evaporates. Surely someone somewhere likes KIND, uses it in their program(s), and therefore needs it? Just like someone somewhere used a REAL variable as a DO loop index, has code with Holleriths straying over into a continuation line, or wants to program in capitals  or in fixed format. The greatest strengths of Fortran have been its ubiquity, longevity and to a large extent its portability, and amputation of parts means what used to work may now not.
So none of the rush to the tumbrils brandishing pitchforks and demanding 'off with its head', eh?
Eddie
PS Maybe I'll make an exception this time! 

Back to top 


mecej4
Joined: 31 Oct 2006 Posts: 874

Posted: Wed Mar 07, 2018 12:34 pm Post subject: Re: 


LitusSaxonicum wrote:  ... That reverts us to Fortran 66 where the size of INTEGER and REAL was the same. 
That is still true for default integers and default reals. I found this in the Fortran 2003 Handbook (Adams et al.):
Quote:  A processor must provide at least two kinds for the real type. One of the kinds is for the default real type and the other is for the double precision real type, which must have more precision than the default real type. The default real type must occupy the same amount of storage as default integer; double precision real type must occupy twice as much. 
The Fortran95 standard says in Section 14.6.3.1:
Quote:  In a storage association context : A nonpointer scalar object of type default integer, default real, or default logical occupies a single numeric storage unit... 
A large number of old Fortran programs rely on this sameness of storage size. They declare a single work array (often in COMMON) and mark out parts of it to hold variables of various types, and avoid having to allocate and pass one work array for each type. Those programs would stop working if default REAL and default INTEGER were to become different in size.
Last edited by mecej4 on Wed Mar 07, 2018 1:35 pm; edited 2 times in total 

Back to top 


LitusSaxonicum
Joined: 23 Aug 2005 Posts: 1773 Location: Yateley, Hants, UK

Posted: Wed Mar 07, 2018 1:15 pm Post subject: 


Yes, I came across this multiple times. Often it was associated with declaring an array of length 1 in blank common (still in FTN95 with /OLD_ARRAYS) and relying on the location of blank common in the memory map to be somewhere where it could be of variable length.
E 

Back to top 


JohnSilver
Joined: 30 Jul 2013 Posts: 758

Posted: Thu Mar 08, 2018 9:09 pm Post subject: 


All this talk of rebellion over the KIND statement is for one reason only ... it's confusing and hence not well understood !
As a mere amateur who has difficulty even following the discussion above my feet have trembled several times faced with all the various explanations encountered when googling the subject.
The main fundamental thing I don't understand is why the standard didn't standardise the KIND values !!!
By definition, if different compilers have different values for the same thing then any program written which includes KIND is not portable ! Which sort of negates the intention of having a standard imo.
And another thing ....
Fortran 2003/2008 is mentioned in the above discussions.
Is there actually any F2003/F2008 compilers out there in the wild (and if so which), or has each compiler just adopted one or two, or dozens of it's new capabilities ?
It seems to me that F95 now being widely adopted and maybe the 2003/2008 'standards' are, generally speaking, superfluous to needs.
This 'partial adoption' being the same kind of shortcut which no doubt led to KIND being implemented differently on fìdifferent compilers.
Isn't there a 'Compilers Club' where they get together say once a year to discuss anomalies like this and iron them out between themselves ? _________________ "This is the triumph of folly.
The machine, which knows no rest, ought to remain a tool,
... but instead becomes our master and will swallow up our life and soul" 

Back to top 




You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum

Powered by phpBB © 2001, 2005 phpBB Group
