Fortran 90 kind parameter

65,770

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.

Share:
65,770

Related videos on Youtube

nbro
Author by

nbro

don't believe the hype

Updated on August 30, 2021

Comments

  • nbro
    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
      a_h almost 15 years
      are you referring to Kind notation?
  • Tim Whitcomb
    Tim Whitcomb almost 15 years
    Thanks 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
    bikerider almost 15 years
    A 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.
    M. S. B. over 10 years
    If 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
    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, say int(kind=1)? [This latter would be bad practice regardless.] Perhaps you could clarify?
  • Zeus
    Zeus almost 9 years
    I concur with your comment @francescalus
  • Vladimir F Героям слава
    Vladimir F Героям слава almost 7 years
    Nope, this is not portable. Don't recommend it to beginners please.
  • kvantour
    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
    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 Героям слава
    Vladimir F Героям слава almost 5 years
    Recommended by whom? This is the archaic way, not the modern way. It is also not just about "precision".
  • Rodrigo Rodrigues
    Rodrigo Rodrigues almost 5 years
    Wait, 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
    Youjun Hu almost 5 years
    Recommented 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
    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
    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, use iso_fortran_env kind constants. Refer to this answer for more details.
  • Youjun Hu
    Youjun Hu almost 5 years
    We 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
    Rodrigo Rodrigues almost 5 years
    I 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 means double double precision... ¬¬
  • lucky
    lucky about 3 years
    -1. software.intel.com/content/www/us/en/develop/blogs/… -- TLDR: use SELECTED_REAL_KIND()
  • Eular
    Eular about 3 years
    REAL(n) and REAL(kind=n) they are always the same thing, right?
  • Vladimir F Героям слава
    Vladimir F Героям слава almost 3 years
    The 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
    francescalus over 2 years
    Why is a guaranteed to be an 8-byte real for every processor?
  • Vladimir F Героям слава
    Vladimir F Героям слава over 2 years
    This 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
    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
    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
    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 Героям слава
    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 have real64 defined in iso_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 Героям слава
    Vladimir F Героям слава over 2 years
    I 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
    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
    francescalus over 2 years
    Using 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 Героям слава
    Vladimir F Героям слава over 2 years
    The 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
    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
    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 Героям слава
    Vladimir F Героям слава over 2 years
    It 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
    francescalus over 2 years
    I 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 program print '(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
    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
    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
    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
    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
    francescalus over 2 years
    The 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
    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
    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) and real(dp) respectively, and it appears they both mean the same thing.