# Real kinds and interoperability?

**URL:** <https://fortran-lang.discourse.group/t/real-kinds-and-interoperability/8095>\
**Category:** Help\
**Created:** [May 27, 2024, 8:29pm UTC](https://fortran-lang.discourse.group/t/real-kinds-and-interoperability/8095 "2024-05-27T20:29:06Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![hraj](https://avatars.discourse-cdn.com/v4/letter/h/bbe5ce/32.png) [@hraj](https://fortran-lang.discourse.group/u/hraj)\
**Post date:** [May 27, 2024, 8:29pm UTC](https://fortran-lang.discourse.group/t/real-kinds-and-interoperability/8095/1 "2024-05-27T20:29:06Z")

</div>

One of our code bases still uses `double precision` to define most floating point variables. We are about to change that to `real(dp)` but as everyone we’re ending up in a discussion on selecting the right definition for the real kind `dp`. Based on various posts and a discussion by Dr Fortran we have arrived at a shortlist of two/three options:

1. `use stdlib, only: dp` … focusing on interoperability with stdlib which internally uses `selected_real_kind(15)` to define `dp`
2. `use iso_c_binding, only: dp => c_double` … focusing on interoperability with C
3. `use ieee_arithmetic, only: ieee_selected_real_kind` and `dp = ieee_selected_real_kind(15)`

Since most hardware seems to be using IEEE arithmetic by default, the benefit of the third option seems to be limited. So, let’s focus on the first two.

For pure Fortran code, following the first option seems most logical: the precision is well defined (well at least concerning the precision, not yet concerning exponent or radix) and the code would be interoperable with all functionality of stdlib.

However, we interoperate at a number of places C code, e.g. for writing netCDF files, solving equations using PetSc, and exchanging many large arrays via API with codes in C and Python. Therefore, I’m thinking that second option would be the safer bet. However, that would add a series of conversions when calling stdlib and that doesn’t feel right.

So, how likely is it that we go wrong by just assuming that the stdlib `dp` kind and the iso\_c\_binding `c_double` kind are in fact equal? Stated differently: how likely is it that a stdlib `real(dp)` array is interpreted incorrectly when being accessed from C code as `double`? Surely there will be platforms where this assumption doesn’t hold, but what are those hardware platforms and how common are they?

---

<div class="post-metadata">

**Author:** ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)\
**Post date:** [May 27, 2024, 9:53pm UTC](https://fortran-lang.discourse.group/t/real-kinds-and-interoperability/8095/2 "2024-05-27T21:53:34Z")

</div>

I’m not sure why you think there would be conversions. (If anything, you should get compile-time errors if there are explicit interfaces for the library routines and the kind doesn’t match.)

Just going on what you wrote here, I’d go for option 2.

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [May 27, 2024, 10:14pm UTC](https://fortran-lang.discourse.group/t/real-kinds-and-interoperability/8095/3 "2024-05-27T22:14:32Z")

</div>

@hraj welcome to the forum!

Yes, unfortunately there is no clear advice yet on this. I once (15 years ago) asked this very question at a Fortran mailinglist, and a long debate ensured where there was no consensus.

I just went with this advice long time ago: [Fortran Best Practices — Fortran90 1.0 documentation](https://www.fortran90.org/src/best-practices.html#floating-point-numbers) that a lot of people agree with, but not all. When we moved the tutorial to fortran-lang, we had to rewrite it to be inclusive of what the Fortran community can agree on, and came up with this advice: [Floating Point Numbers — Fortran Programming Language](https://fortran-lang.org/learn/best_practices/floating_point/), which leaves several options on the table.

As long as you have one module in your project that defines `dp` somehow, then any way is good I think, since you can easily change it as needed.

---

<div class="post-metadata">

**Author:** ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)\
**Post date:** [May 28, 2024, 12:22am UTC](https://fortran-lang.discourse.group/t/real-kinds-and-interoperability/8095/4 "2024-05-28T00:22:04Z")

</div>

> [@hraj](#):
>
> … Surely there will be platforms where this assumption doesn’t hold, but what are those hardware platforms and how common are they?

@hraj,

Have you and your colleagues found any such platform? Or, to think differently, do you know of any platform in use now where the 3 options you list in your original post are **not** the same?

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [May 28, 2024, 2:54am UTC](https://fortran-lang.discourse.group/t/real-kinds-and-interoperability/8095/5 "2024-05-28T02:54:51Z")

</div>

> [@FortranFan](#):
>
> Or, to think differently, do you know of any platform in use now where the 3 options you list in your original post are **not** the same?

For double precision I don’t. But for half precision I know several different kinds: IEEE f16, bf16 and at least two proprietary formats.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [May 28, 2024, 4:27am UTC](https://fortran-lang.discourse.group/t/real-kinds-and-interoperability/8095/6 "2024-05-28T04:27:10Z")

</div>

> [@certik](#):
>
> But for half precision I know several different kinds: […]

Are any of these floating point kinds interoperable with any C floating point types in iso\_c\_binding?

---

<div class="post-metadata">

**Author:** ![hraj](https://avatars.discourse-cdn.com/v4/letter/h/bbe5ce/32.png) [@hraj](https://fortran-lang.discourse.group/u/hraj)\
**Post date:** [May 28, 2024, 4:59am UTC](https://fortran-lang.discourse.group/t/real-kinds-and-interoperability/8095/7 "2024-05-28T04:59:20Z")

</div>

Hi Dr @sblionel,

Thank you for your reaction.

I didn’t mean to suggest that there would be automatic conversion. Obviously, you’re right to state that compilers should notice the real kind mismatch and report an error. So, to avoid that we would have to write some wrapper routines for all stdlib routines that we use to explicitly convert all real precision values/arrays passed across the interface from `c_double` to `dp` and back … even though the kinds may in most cases be effectively the same. … The alternative would be to redefine the stdlib `dp` precision in our local clone of the source code to `c_double` but that feels like a very slippery path since we would deviate from the standard code base and may use the code in ways not intended or tested.

---

<div class="post-metadata">

**Author:** ![hraj](https://avatars.discourse-cdn.com/v4/letter/h/bbe5ce/32.png) [@hraj](https://fortran-lang.discourse.group/u/hraj)\
**Post date:** [May 28, 2024, 5:07am UTC](https://fortran-lang.discourse.group/t/real-kinds-and-interoperability/8095/8 "2024-05-28T05:07:51Z")

</div>

@FortranFan,  
No we don’t have examples yet. My “surely” was more intended to reflect that anything that can go wrong, will go wrong … so, even though if I don’t know of the system, the wider community likely does. Once we know on what kind of platform this assumption does not hold, we can decide how relevant those are for us and either address the issue or ignore it with a statement that we explicitly don’t support those platforms.

---

<div class="post-metadata">

**Author:** ![hraj](https://avatars.discourse-cdn.com/v4/letter/h/bbe5ce/32.png) [@hraj](https://fortran-lang.discourse.group/u/hraj)\
**Post date:** [May 28, 2024, 5:26am UTC](https://fortran-lang.discourse.group/t/real-kinds-and-interoperability/8095/9 "2024-05-28T05:26:21Z")

</div>

Hi @certik,

Thank you for your reply. Yes, it’s my first question on the forum. Usually, I follow the advise of @Arjen, but this time he pointed to the forum.

I agree that if the real kinds are defined in one place, it’s easy to adjust and one of our codes has followed the [Fortran Best Practices — Fortran90 1.0 documentation](https://www.fortran90.org/src/best-practices.html#floating-point-numbers) for a similar period of 15 years. However, with other code catching up and new colleagues joining the team, it’s time to reflect whether that approach is still the best. Indeed the `selected_real_kind` is now preferred, and following stdlib is a pragmatic choice in that context. However, all of that discussion doesn’t address the potential issues with language interoperability which I consider an critical part of our code.

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [May 28, 2024, 1:29pm UTC](https://fortran-lang.discourse.group/t/real-kinds-and-interoperability/8095/10 "2024-05-28T13:29:38Z")

</div>

> [@RonShepard](#):
>
> Are any of these floating point kinds interoperable with any C floating point types in iso\_c\_binding?

I think `iso_c_binding` doesn’t yet have half precision, so none of them are interoperable yet.

---

<div class="post-metadata">

**Author:** ![Jweber](https://avatars.discourse-cdn.com/v4/letter/j/e95f7d/32.png) [@Jweber](https://fortran-lang.discourse.group/u/Jweber)\
**Post date:** [May 28, 2024, 3:24pm UTC](https://fortran-lang.discourse.group/t/real-kinds-and-interoperability/8095/11 "2024-05-28T15:24:04Z")

</div>

According at the change log of GCC, REAL16 is now provided in ISO\_FORTRAN\_ENV.  
(I do not know, to what extent there is support of actual half-precision types).

Edit: With “now” I actually meant GCC15.

---

<div class="post-metadata">

**Author:** ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)\
**Post date:** [May 28, 2024, 4:52pm UTC](https://fortran-lang.discourse.group/t/real-kinds-and-interoperability/8095/12 "2024-05-28T16:52:24Z")

</div>

A named constant in ISO\_FORTRAN\_ENV does not imply support. If an implementation doesn’t support a kind, the value of the constant is -1.

---

<div class="post-metadata">

**Author:** ![wspector](https://avatars.discourse-cdn.com/v4/letter/w/47e85d/32.png) [@wspector](https://fortran-lang.discourse.group/u/wspector)\
**Post date:** [May 28, 2024, 8:09pm UTC](https://fortran-lang.discourse.group/t/real-kinds-and-interoperability/8095/13 "2024-05-28T20:09:56Z")

</div>

I’d suggest using `real64` in `ISO_FORTRAN_ENV`. Though sometimes I’m lazy and just write:

` integer, parameter :: dp = kind (1.0d0)`

(The “best practices” link you posted suggests the same.)

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [May 28, 2024, 8:47pm UTC](https://fortran-lang.discourse.group/t/real-kinds-and-interoperability/8095/14 "2024-05-28T20:47:03Z")

</div>

> [@Jweber](#):
>
> According at the change log of GCC, REAL16 is now provided in ISO\_FORTRAN\_ENV.

Has that name `REAL16` been adopted by the standard committee, or are the GCC people anticipating future support in the stanard? And are there corresponding entries in the GCC version of iso\_c\_binding?

---

<div class="post-metadata">

**Author:** ![GregB](https://avatars.discourse-cdn.com/v4/letter/g/da6949/32.png) [@GregB](https://fortran-lang.discourse.group/u/GregB)\
**Post date:** [May 29, 2024, 1:01am UTC](https://fortran-lang.discourse.group/t/real-kinds-and-interoperability/8095/15 "2024-05-29T01:01:55Z")

</div>

From the draft [2023 standard](https://j3-fortran.org/doc/year/23/23-007r1.pdf) (page 462):

> **16.10.2.27 REAL16, REAL32, REAL64, and REAL128**  
> The values of these default integer scalar named constants shall be those of the kind type parameters that specify a REAL type whose storage size expressed in bits is 16, 32, 64, and 128 respectively. If, for any of these constants, the processor supports more than one kind of that size, it is processor dependent which kind value is provided. If the processor supports no kind of a particular size, that constant shall be equal to −2 if the processor supports kinds of a larger size and −1 otherwise.

---

<div class="post-metadata">

**Author:** ![GregB](https://avatars.discourse-cdn.com/v4/letter/g/da6949/32.png) [@GregB](https://fortran-lang.discourse.group/u/GregB)\
**Post date:** [May 29, 2024, 4:13am UTC](https://fortran-lang.discourse.group/t/real-kinds-and-interoperability/8095/16 "2024-05-29T04:13:06Z")

</div>

> [@Jweber](#):
>
> (I do not know, to what extent there is support of actual half-precision types).

Looks to be a work-in-progress according to one of the [test cases](https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/testsuite/gfortran.dg/iso_fortran_env_8.f90;hb=b644126237a1aa8599f767a5e0bbada1d7286f44):

```Fortran
! We do not support REAL16 for now, but check it can
! still be used in specification expressions
real(kind=max(real16, real32)) :: x

```

```Fortran
! We do not support REAL16 for now
if (real16 /= -2) stop 101

```

---

<div class="post-metadata">

**Author:** ![hraj](https://avatars.discourse-cdn.com/v4/letter/h/bbe5ce/32.png) [@hraj](https://fortran-lang.discourse.group/u/hraj)\
**Post date:** [May 30, 2024, 6:58am UTC](https://fortran-lang.discourse.group/t/real-kinds-and-interoperability/8095/17 "2024-05-30T06:58:35Z")

</div>

That’s the first time I see a `max` operator in a real kind definition. Neat approach to implement a fall back if `real16` is not implemented … but what if `real16` and `real32` are both implemented. Which precision would `x` then be? It seems easy enough to write a program that tells which precision was selected, but does the standard state that `real16` should be less or more than `real32`? If not, it’s compiler specific at best … although common sense bias might suggest that `real32` will typically be larger than `real16` and hence `x` would always be defined as `real32` whether `real16` is defined or not (assuming that the more common type `real32` is defined), which would make the `max` construct utterly useless.

---

<div class="post-metadata">

**Author:** ![PierU](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/pieru/32/1848_2.png) [@PierU](https://fortran-lang.discourse.group/u/PierU)\
**Post date:** [May 30, 2024, 8:02am UTC](https://fortran-lang.discourse.group/t/real-kinds-and-interoperability/8095/18 "2024-05-30T08:02:58Z")

</div>

> [@hraj](#):
>
> That’s the first time I see a `max` operator in a real kind definition.

I think the only point of this test case is to check that the `REAL16` constant is effectively available, nothing else.

---

<div class="post-metadata">

**Author:** ![everythingfunctional](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/everythingfunctional/32/176_2.png) [@everythingfunctional](https://fortran-lang.discourse.group/u/everythingfunctional)\
**Post date:** [May 30, 2024, 2:38pm UTC](https://fortran-lang.discourse.group/t/real-kinds-and-interoperability/8095/19 "2024-05-30T14:38:44Z")

</div>

Some additional discussion:

> **[Which kinds are real?](https://everythingfunctional.wordpress.com/2021/08/23/which-kinds-are-real/)**
>
> A discussion starting on the Fortran Discourse, got me thinking about how Fortran libraries should support multiple kinds of floating point numbers? I immediately recalled Dr. Fortran’s blog …

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [May 30, 2024, 6:16pm UTC](https://fortran-lang.discourse.group/t/real-kinds-and-interoperability/8095/20 "2024-05-30T18:16:57Z")

</div>

> [@everythingfunctional](#):
>
> Some additional discussion:

I would say that a library writer’s task is both simple and complicated. It is simple because “all” that is necessary is to write versions of the code that work with every element of the `real_kinds(:)` array for a given compiler. (I’m ignoring the complementary integer and logical kinds problems, and I’m assuming the complex kinds code will follow the real kinds codes.) Sometimes that will involve only declaring the right kind values in each specific library routine, while other times it might involve more significant changes to the underlying algorithms. However, the complicated part is that the fortran language provides no support at all for a programmer to do that. The `real_kinds(:)` array was introduced in f2003, so it has been some 20 years, and still this is a difficult task. In my opinion, this is something that should have been provided at the time the `real_kinds(:)` array was introduced in the language. It isn’t like this was some unanticipated problem that came out of nowhere, it is really THE central problem with writing library codes in a portable way that can be compiled by every compiler.

[Next page](https://fortran-lang.discourse.group/t/real-kinds-and-interoperability/8095.md?page=2)
