2

I want to specify as type of a subroutine a floating point value (real) of 8 bytes precision.

I have read here that the modern way to do it would be:

real(real64), intent(out)       :: price_open(length)

However, iso_fortran_env is not supported by f2py (same as it does not support iso_c_bindings either).

I get errors of this type:

   94 |       real(kind=real64) price_open(length)
      |                1
Error: Parameter 'real64' at (1) has not been declared or is a variable, which does not reduce to a constant expression

The link referenced before states that using kind would be the proper way if iso_fortran_env is not available and that real*8 shall be avoided.

  • I have been using real(8) is that equivalent to using kinds? If not, what shall I use?
  • What is wrong with real*8 if I want to always enforce 8 bytes floating point values?
M.E.
  • 4,955
  • 4
  • 49
  • 128
  • 1
    Is it specifically the 8-bytes container that is of interest, or 64-bit precision? If it is the latter, you could use [`selected_real_kind()`](https://gcc.gnu.org/onlinedocs/gfortran/SELECTED_005fREAL_005fKIND.html) intrinsic. – Scientist Jul 21 '21 at 23:38
  • Could you elaborate on differences? I thought it was the same. – M.E. Jul 21 '21 at 23:43
  • 3
    You might be interested in my thoughts on the subject: https://stevelionel.com/drfortran/2017/03/27/doctor-fortran-in-it-takes-all-kinds/ – Steve Lionel Jul 22 '21 at 00:24
  • Thanks Steve, I read it twice. Still some practical doubts that I will share here just in case somebody wants to comment. King states about the difference between an 8 bytes container and 64 bit precision. First doubt I have is that I thought precision for floating point numbers was specified in terms of decimal places and not in terms of bits. – M.E. Jul 22 '21 at 06:02
  • The second doubt I have is that, I am specifically looking for interoperability with C, specifically I am looking for having a `double` and while the C standard does not define its size (or format IIRC) in the practical real world of 2021 that always defaults to `8 bytes` in today's 64 bits servers. That suffices me and I do not need further portability. In that case, and given that `f2py` does not support `iso_c_bindings` or `iso_fortran_env`, I am still wondering what shall I be using. I am still unclear on that even after reading Steve's article (which it is worth reading for sure). – M.E. Jul 22 '21 at 06:04
  • 1
    Regarding f2py, by manually specifying a mapping, it is possible to write standard conforming Fortran code with e.g. iso-c-binding (or other kind specifiers), that can be interpreted by f2py. See e.g: https://stackoverflow.com/a/61869003 – jbdv Jul 22 '21 at 06:22
  • 1
    @M.E. I do not mean in any way to discourage the use of f2py by the following statement, only to report a personal experience. With the `iso_c_binding` of F2003 and `ctypes` module of Python, I don't see the need for `f2py` in almost any use case. I personally frequently find the former easier to implement, maintain, and use than the latter. – Scientist Jul 23 '21 at 18:42
  • Does `ctypes` return numpy arrays from C arrays and the opposite (you pass a numpy array to a C function expecting a C array)? I am interested in exploring alternatives to f2py – M.E. Jul 24 '21 at 00:00
  • 1
    @M.E. C takes a pointer to the array and returns a pointer to the array. So as long as you use the returned array with appropriate bounds, numpy has not problems dealing with it. – Scientist Jul 24 '21 at 18:48
  • @King, I am trying to get it converted into a numpy array in case yo want to contribute also to that question: https://stackoverflow.com/questions/68513850/how-do-i-convert-a-pointer-returned-by-a-c-function-invoked-using-ctypes-into-a – M.E. Jul 24 '21 at 21:57

1 Answers1

3

You say you are specifically interested in interoperability with C. However, iso_c_binding, nor iso_fortran_env are supported. These modules have constants that help you to set the right kind constant for a given purpose. The one from iso_fortran_env would NOT be the right one to choose anyway, it would be c_double.

If these constants meant to help you in your choice are not available, you are on your own. Now you can choose any other method freely.

It is completely legitimate to use just kind(1.d0) and just check that the connection to C works. Automake had been doing that for ages.

Or use selected_real_kind(), it does not matter, it is really up to you. Just check that double in C ended up being the same numeric type.

The traditional thing in automatic build processes was to do many tests about which (mainly C) constant ended up having which value. You just need to check that double precision in Fortran does indeed correspond to double in C. It is very likely, but just check it. You can have a macro that changes the choice if not, but probably it is a needless work untill you actually meet such a system.