Fortran 90 kind parameter
Solution 1
The KIND of a variable is an integer label which tells the compiler which of its supported kinds it should use.
Beware that although it is common for the KIND parameter to be the same as the number of bytes stored in a variable of that KIND, it is not required by the Fortran standard.
That is, on a lot of systems,
REAl(KIND=4) :: xs ! 4 byte ieee float
REAl(KIND=8) :: xd ! 8 byte ieee float
REAl(KIND=16) :: xq ! 16 byte ieee float
but there may be compilers for example with:
REAL(KIND=1) :: XS ! 4 BYTE FLOAT
REAL(KIND=2) :: XD ! 8 BYTE FLOAT
REAL(KIND=3) :: XQ ! 16 BYTE FLOAT
Similarly for integer and logical types.
(If I went digging, I could probably find examples. Search the usenet group comp.lang.fortran for kind
to find examples. The most informed discussion of Fortran occurs there, with some highly experienced people contributing.)
So, if you can't count on a particular kind value giving you the same data representation on different platforms, what do you do? That's what the intrinsic functions SELECTED_REAL_KIND
and SELECTED_INT_KIND
are for. Basically, you tell the function what sort of numbers you need to be able to represent, and it will return the kind you need to use.
I usually use these kinds, as they usually give me 4 byte and 8 byte reals:
!--! specific precisions, usually same as real and double precision
integer, parameter :: r6 = selected_real_kind(6)
integer, parameter :: r15 = selected_real_kind(15)
So I might subsequently declare a variable as:
real(kind=r15) :: xd
Note that this may cause problems where you use mixed language programs, and you need to absolutely specify the number of bytes that variables occupy. If you need to make sure, there are enquiry intrinsics that will tell you about each kind, from which you can deduce the memory footprint of a variable, its precision, exponent range and so on. Or, you can revert to the non-standard but commonplace real*4
, real*8
etc declaration style.
When you start with a new compiler, it's worth looking at the compiler specific kind values so you know what you're dealing with. Search the net for kindfinder.f90
for a handy program that will tell you about the kinds available for a compiler.
Solution 2
I suggest using the Fortran 2008 and later; INT8, INT16, INT32, INT64, REAL32, REAL64, REAL128
. This is done by calling ISO_FORTRAN_ENV
in Fortran 2003 and later. Kind parameters provides inconsistent way to ensure you always get the appropriate number of bit representation
Solution 3
Just expanding the other (very good) answers, specially Andrej Panjkov's answer:
The KIND of a variable is an integer label which tells the compiler which of its supported kinds it should use.
Exactly. Even though, for all the numeric intrinsic types, the KIND parameter is used to specify the "model for the representation and behavior of numbers on a processor" (words from the Section 16.5 of the standard), that in practice means their bit model, that's not the only thing a KIND parameter may represent.
A KIND parameter for a type is any variation in its nature, model or behavior that is avaliable for the programmer to choose at compile time. For example, for the intrinsic character type, the kind parameter represents the character sets avaliable on the processor (ASCII, UCS-4,...).
You can even define your own model/behaviour variations on you defined Derived Types (from Fortran 2003 afterwards). You can create a Transform Matrix type and have a version with KIND=2 for 2D space (in which the underlying array would be 3x3) and KIND=3 for 3D space (with a 4x4 underlying array). Just remember that there is no automatic kind conversion for non-intrinsic types.
Solution 4
From the Portland Group Fortran Reference, the KIND
parameter "specifies a precision for intrinsic data types." Thus, in the declaration
real(kind=4) :: float32
real(kind=8) :: float64
the variable float64
declared as an 8-byte real (the old Fortran DOUBLE PRECISION
) and the variable float32
is declared as a 4-byte real (the old Fortran REAL
).
This is nice because it allows you to fix the precision for your variables independent of the compiler and machine you are running on. If you are running a computation that requires more precision that the traditional IEEE-single-precision real (which, if you're taking a numerical analysis class, is very probable), but declare your variable as real :: myVar
, you'll be fine if the compiler is set to default all real
values to double-precision, but changing the compiler options or moving your code to a different machine with different default sizes for real
and integer
variables will lead to some possibly nasty surprises (e.g. your iterative matrix solver blows up).
Fortran also includes some functions that will help pick a KIND
parameter to be what you need - SELECTED_INT_KIND
and SELECTED_REAL_KIND
- but if you are just learning I wouldn't worry about those at this point.
Since you mentioned that you're learning Fortran as part of a class, you should also see this question on Fortran resources and maybe look at the reference manuals from the compiler suite that you are using (e.g. Portland Group or Intel) - these are usually freely available.
Related videos on Youtube
Comments
-
nbro over 2 years
I am having trouble understanding Fortran 90's
kind
parameter. As far as I can tell, it does not determine the precision (i.e., float or double) of a variable, nor does it determine the type of a variable.So, what does it determine and what exactly is it for?
-
a_h almost 15 yearsare you referring to Kind notation?
-
-
Tim Whitcomb almost 15 yearsThanks for pointing out that KIND is not KIND=<number of bytes I want> - have you seen a modern compiler where this is the case? That kindfinder.f90 program is very cool.
-
bikerider almost 15 yearsA search of usenet turns up: salford f95 compiler uses kinds 1,2, and 3 to stand for 2- 4- and 8-byte variables; I saw a claim that g77 did the same before g95 and gfortran came along; and a report that the NAG fortran compiler had a compiler switch that allowed the selection between the (1,2,3,4) scheme and the (1,2,4,8) scheme. No doubt there are others. Yes, kindfinder is handy. You can use it to set up a site-specific module file that contains named parameters for the different kinds, so that your real programs aren't littered with nonportable magic numbers.
-
M. S. B. over 10 yearsIf you really want to specify types by their bytes of storage, Fortran 2003 has the ISO_C_Binding, which provides kind values corresponding to C types, some of which specify storage size. Fortran 2008 provides types in the ISO_FORTRAN_ENV module, such as the
real32
kind value for 32 bits,real64
for 64 bits, etc. These have the advantage of being portable, at least as long as you have a Fortran 2003 or 2008 compiler. See the gfortran manual for the list of kinds in these two modules. -
francescalus almost 9 years
int8
does (if an appropriate kind is available) specify a kind parameter. I suspect you mean that one should prefer this to an explicit number like, sayint(kind=1)
? [This latter would be bad practice regardless.] Perhaps you could clarify? -
Zeus almost 9 yearsI concur with your comment @francescalus
-
Vladimir F Героям слава almost 7 yearsNope, this is not portable. Don't recommend it to beginners please.
-
kvantour about 6 years@francescalus, would it not be useful to make this question a canonical question and have a single "community answer" which sums up all the entire story for various versions of fortran? Often I see code where I would like to refer to such a complete canonical answer. This is the best place here, but the information is completely spread out over different answers and various comments. (sorry this is the best way I figured out to reach you)
-
francescalus about 6 years@kvantour, discussions of canonical questions (scope, desire, etc.) fit well on Meta SO. You'll likely get more than just my opinion there. That's if you think the question itself needs work: if you think an answer here solves the problem then there's little harm pulling everything together into a complete form.
-
Vladimir F Героям слава almost 5 yearsRecommended by whom? This is the archaic way, not the modern way. It is also not just about "precision".
-
Rodrigo Rodrigues almost 5 yearsWait, what? Recommended by whom [2]? 1) Explicit is better than implicit, 2) Kind specifiers is the most portable alternative, 3) 8 byte float is about data storage not about precision.
-
Youjun Hu almost 5 yearsRecommented by tokamak fusion scientists from General Atomics. They gave a list of FORTRAN coding conventions used in the GACODE build system. All latest General Atomics modeling codes follow these conventions. What's nice about them is that, when porting the code to any new platform (cori, titan, summit ...), all that's needed is to set up the correct platform environment variable in the makefile. The GACODE build system has been set up on many computer systems in the world.
-
Youjun Hu almost 5 years@Rodrigo , It seems to me that a real number stored by 8 bytes is more accurate than that stored by 4 bytes, so storage and precision are related. Is this right?
-
Rodrigo Rodrigues almost 5 years@YoujunHu a real number stored in 8 bytes can be (and probably will, obviously) more acurate than a 4 bytes, but does this say anything about how much precise it is? how many decimal places? maximum exponent? If you care about a specific requirement in precision, use
selected_real_kind
. If you care about a specific storage size, useiso_fortran_env
kind constants. Refer to this answer for more details. -
Youjun Hu almost 5 yearsWe specify storage by using compiling options. Then suitable decimal digits and maximum exponent are automatically determined by the compiler or by programmers using compiling options (if they exist). In summary, it seems more natural to specify storage and precision via compiling options, rather than via source codes.
-
Rodrigo Rodrigues almost 5 yearsI am not saying
-fdefault-real-8
is evil, I am saying that this is not the most recommended approach by Fortran community, because it changes implictly the behaviour you expect when you look at the code. Help forums are full of: "why my calls to libraries (Lapack, mkl...) fail or give wrong result when the signature of the function seems to match the passed arguments?". Oh, it's because there is a line in the makefile (totally away from the source code) that says that, in this project,double precision
actually meansdouble double precision
... ¬¬ -
lucky about 3 years-1. software.intel.com/content/www/us/en/develop/blogs/… -- TLDR: use
SELECTED_REAL_KIND()
-
Eular about 3 years
REAL(n)
andREAL(kind=n)
they are always the same thing, right? -
Vladimir F Героям слава almost 3 yearsThe main issue with this answer is that despite getting many upvotes it simply does not even attempt to answer the question. It just gives some opinion about what choice of kind parameters might be the best.
-
francescalus over 2 yearsWhy is
a
guaranteed to be an 8-byte real for every processor? -
Vladimir F Героям слава over 2 yearsThis is just wrong. The different machine might use some non IEEE floating point types. Alas, the 8-byte float may not even exist on such a machine and still the machine could have a conforming Fortran 90 compiler.
-
CRquantum over 2 years@VladimirF defining r8 type by doing selected_real_kind, is exactly what we do in HPC computing, to ensure the results on a laptop or on the supercomputer, on windows or linux are the same. It is just not wrong. I actually would like to see how you define true real 8 for all the machine.
-
CRquantum over 2 years@francescalus Because we defined the type at the beginning of the code, r8=selected_real_kind(15,9), it means that then as real(kind=r8) :: a , a will be a r8 type which uses 8 Byte. This is a typical thing we define in all of our massively parallelized quantum Monte Carlo codes which sometimes requires tens of millions of core hours. If this is wrong then I do not know what.
-
CRquantum over 2 years@VladimirF r8=selected_real_kind(15,9) , It just means uses 8 Byte memory to store a true real 8 number, how can it be impossible? I am very confused. I am talking about true real 8, not real 800000.
-
Vladimir F Героям слава over 2 years
selected_real_kind
is simply not about storage size at all. It does not really matter what you do in your HPC. It is about numerical precision. It says how big and precise numbers can be. I repeat, a conforming Fortran processor can exist on a machine that does not even have to have any 8-byte type. Those that do have it will havereal64
defined iniso_fortran_env
and that is the true way to define a true 8-byte real. And if an IEEE conforming 8-type is available, you can use the ieee_selected_real_kind, where the correspondende between numerical precision and storage size more certain. -
Vladimir F Героям слава over 2 yearsI am not saying that what you do will not work for you on a typical IEEE conforming machine in this day and age. I am saying that the claim "which is real 8 (means uses 8 Bytes) type no matter what machine/OS it is running on." is incorrect from a language lawyer point of view. It also does not guarantee that the results will be the same.
-
CRquantum over 2 years@VladimirF Nowadays, a modern and well written Fortran code, gives the same results (up to machine precision) no matter it is on windows/linux/mac, this is guaranteed. If your code gives different results on different OS, it is a sign that something in your code may not be well written. On the other hand, of course, it depends on the person who wrote the code, not the Fortran language itself. Therefore in this sense, you can say it is not guaranteed.
-
francescalus over 2 yearsUsing
selected_real_kind
in this answer you have asked for a minimal decimal precision and range. You haven't asked for a storage size, radix, IEEE conformance or exact range and precision. There is nothing in the Fortran language that says you will get an 8-byte real with this kind parameter. -
Vladimir F Героям слава over 2 yearsThe point is in "nowadays". This is not about my code or your code. It is not about windows/mac/linux. It is about what the standard allows. It is about possible CPUs that existed throughout the 20th century and could exist in the future. It is about various compilers that might exist on these systems. Their numbers do not even have to be binary, for example. They might not even have numbers as small as 8 bytes.
-
CRquantum over 2 years@francescalus Do you agree all electronic computers use 10101010101....? If so, selected_real_kind(15,9) returns 8, 8 means it requires 8 Byte, this means exactly in Fortran you can get a real 8 byte number, period. What you are saying is like, "because fortran does not have internal spherical harmonic functions, therefore there is no way fortran can calculate spherical harmonics." It does not make sense.
-
CRquantum over 2 years@VladimirF selected_real_kind(15,9) returns 8, 8 means it requires 8 Byte, this means exactly in Fortran you can get a real 8 byte number. I repeat, selected_real_kind, is a generic, valid, and good way of defining true real 4, 8 , or anything kind you want. The highest voted answer already explains it well.
-
Vladimir F Героям слава over 2 yearsIt does not matter what it returns on your compiler at all. BTW, it wil return 2 for some other xompilers ecxactly as the highest-voted answer shows.
selected_real_kind()
does NOT return number of bytes.storage_size()
retirns number of bits instead. I repeat,selected_real_kind()
is NOT for sepectimg any bytes, it is for selecting numerical precision, radix,... And that is what the highest-voted answer, which I upvoted explains very well. Please read it again, because you have not understood it yet. -
francescalus over 2 yearsI don't know what using "10101010101" means, but I certainly don't agree that
selected_real_kind(15,9)
must have value 8 or that even if it had value 8 a real with kind parameter 8 must have 8-byte storage. Let's say I asked you what output you think I'd get running the Fortran programprint '(L1)', 1.>0.; end
. And then I ask "how many bytes did you use for those real constants when calculating?", would I make sense? -
CRquantum over 2 years@VladimirF selected_real_kind() is the way, and the generic way to go. As stated clearly by the highest voted answer. The reason Fortran has this selected_real_kind() is really to make sure that even on different machine or OS, eg. by doing selected_real_kind(15,9), a variable can indeed be the same true real 8 type which means 8 bytes so occupy 64 bits in the memory. if you have chance to look at how people's code for true HPC on supercomputer like Summit, Sierra, etc. I really did not find people use things like iso c binding stuff as you did in your github repos.
-
CRquantum over 2 years@francescalus In order to represent the precision of selected_real_kind(15,9), you need 8 bytes so 64 bits on any electronic computer. Please name one example, such that selected_real_kind(15,9) does not return 8 and please explain why, if possible. 10101.... simply means electronic computer uses 0 or 1 to represent anything. At the end of the day, any variable with selected_real_kind(15,9) does require 8 Bytes of memory. It is really just math, without 8 Bytes you simply cannot reach that precision.
-
CRquantum over 2 years@VladimirF if for example, selected_real_kind(15,9) return 8, then may I ask, what does this 8 mean? I mean selected_real_kind() will return a number, right? The number has a meaning, right? We know if it returns a negative number then it means something is wrong. But if it returns a positive number, like 4, 8, 16, 32, then what does those number 4, 8, 16, 32 mean?
-
CRquantum over 2 years@VladimirF I read many stackoverflow questions and answers, I have impression about your name because you answered many questions. Many of them are useful. But here about selected_real_kind(), it is just a good and generic way to make the code portable. Nothing wrong with it. A true real 8 does require 64 bits of memory.
-
francescalus over 2 yearsThe NAG compiler will return 2 by default, and there is an option to have it return 202 (or some other large number, I don't recall which, but that's because the exact number is completely irrelevant). Either way, a Fortran compiler isn't required to provide a real decimal precision larger than 10 and isn't required to provide a real with 8-byte storage. If you disagree with those points then further discussion will be fruitless.
-
CRquantum over 2 years@francescalus I am not going to continuing the argument. All what I wanted to say is that defining r8 = selected_real_kind(15,9) works very well. That is all.
-
ZeroTwo over 2 years@Eular Late to this, but am currently getting acquainted to these, and I found this : fortranwiki.org/fortran/show/Real+precision Here in first block, a and b are declared using
real(kind=dp)
andreal(dp)
respectively, and it appears they both mean the same thing.