-
-
Notifications
You must be signed in to change notification settings - Fork 9.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DOC: clarification about the interaction of numpy / f2py with Fortran procedures #23633
Comments
Hi, sorry for getting to this belatedly. At the moment the intrinsic |
Ah, right so we currently 'support' the ! file: fib2a.f90
subroutine fib(a, n)
! calculate first Fibonacci numbers
use iso_fortran_env, only: dp => real64
implicit none
integer :: i, n
real(kind=dp) :: a(n)
do i = 1, n
if (i .eq. 1) then
a(i) = 0.0_dp
elseif (i .eq. 2) then
a(i) = 1.0_dp
else
a(i) = a(i - 1) + a(i - 2)
end if
end do
end subroutine fib
! end file fib2a.f90 We can write a type specification file
Note that this is kind of a hack, but it does work: f2py -c fib2a.f90 -m fib2 --f2cmap .f2py_f2cmap
python -c "import numpy as np; import fib2; a = np.zeros(8, 'd'); fib2.fib(a); print(a)"
[ 0. 1. 1. 2. 3. 5. 8. 13.] Other type specifications can be written out similarly Let me know if there are more questions about this, @nbehrnd . |
@HaoZeke Thank you for getting back in touch. I equally had to revisit the suggestion. Not knowing well enough the inner working of numpy your description of "kind of a hack, but it does work" is understood as you / as other maintainers of numpy would prefer to have some additional time to adjust how numpy internally works and the approach is a preliminary one. This is why I returned to the other approach seen to explicitly define the numerical precision in Fortran independent to integer, parameter :: dp = selected_real_kind(15, 50) as in Both the original snippet of FORTRAN as well as the slightly modernized one however seem to interact with current numpy differently, than in the showcase of getting started/the quick way. The instructions in the info box successfully create a an array of eight zeros, to fill only the first six fields however fail. Because |
Issue with current documentation:
Prior to filing a PR about the presentation of f2py here, I would like to reach out for the maintainers of numpy for some discussion.
Limiting to the first example "the quick way",
fib1.f
currently presented is written in FORTRAN77 equally known as fixed style. Modern Fortran (everything since and including Fortran 90, with a last revision 2018, and standard 2023 in preparation) follows set of modernized rules, the statementimplicit none
might be one known equally by those outside Fortran. I rewrote the procedure as in snippetfib1a.f90
whichf2py
byaccepts to wrap into an extension module. Python can use it to replicate replicate the computation
a = np.zeros(8, 'd')
to yield[0. 1. 1. 2. 3. 5. 8. 13.]
.Observation 1: Line 6 defines double precision as suitable for the gfortran compiler which is applied on the elements of array
a(n)
. With the advent of Fortran 2003,iso_fortran_env
(ref) offers a compiler independent definition of precision which can be used instead. While fine for gfortran, and apparently fine forf2py
, the subsequent use of the .so extension module by Python did not follow through with either versionfib2a.f90
(which loads fromiso_fortran_env
only what is relevant to for "double precision" of a floating number), orfib2b.f90
(which does not impose such a constrain what other procedure definitions this Fortran intrinsic module might contain). For either one of the two, their use in the minimal Python example terminates with the reportQuestion: Does the use of
iso_fortran_env
in the Fortran procedure require a different syntax in the Python script to use the wrapper module? Doesd
ina = np.zeros(8, 'd')
relate to double precision of reals (Fortran) / floating numbers (numpy)?Observation 2: Especially Fortran subroutines are safer in use with an explicit definition if processed data shall
intent(in)
)intent(out)
), orintent(in out)
, or functional equivalent,intent(inout)
). Hence I derivedfib3a.f90
fromfib1a.f90
which compiles well and yields the anticipated result[ 0. 1. 1. 2. 3. 5. 8. 13.]
. However the use of these keywords and the double precision provided by Fortran's intrinsiciso_fortran_env
module now yields the result[0. 0. 0. 0. 0. 0. 0. 0.]
Question: Here, I do not know how to interpret the result for the second case. Do you recommend a different input syntax on level of numpy?
The observations refer to an instance of Linux Debian 12/bookworm with Python (3.11.2) with numpy (1.24.2), gcc and gfortran (12.2.0-14) as provided by this Linux distributions. The Fortran modules were considered as "good enough" because their compilation to yield object files in a pattern of
did not yield an error. The two warnings e.g.
were noted, though not considered as relevant for the discussion. All relevant source code is in the zip archive below.
2023-04-21_f2py_discussion.zip
Idea or request for content:
No response
The text was updated successfully, but these errors were encountered: