Skip to content
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

f2py builds successfully direct from .f90 but fails if I generate .pyf first #13553

Open
tloredo opened this issue May 14, 2019 · 2 comments
Open
Assignees
Projects

Comments

@tloredo
Copy link

tloredo commented May 14, 2019

I'm trying to use f2py to generate a module from the following snippet of Fortran code, from the Fortran Wiki, lightly edited (I took out the associate which caused other problems, and switched to real*8):

function trapz(x, y) result(r)
  real*8, dimension(:), intent(in)  :: x         ! Nodes
  real*8, dimension(size(x)), intent(in)  :: y   ! Function values
  real*8              :: r                       ! Integral of y(x)
  integer :: n

  ! Integrate using the trapezoidal rule
  n = size(x)
  r = sum((y(1+1:n-0) + y(1+0:n-1))*(x(1+1:n-0) - x(1+0:n-1)))/2
end function trapz

I have that in a file _trapz.f90. If I use f2py to generate the module directly:

python -m numpy.f2py -c _trapz.f90 -m _trapz

It appears to work fine; it generates the .so. But if I instead generate a .pyf:

python -m numpy.f2py _trapz.f90 -m _trapz -h _trapz.pyf

(which runs without warnings or errors), and then generate the module from it (without editing the .pyf):

python -m numpy.f2py -c _trapz.pyf _trapz.f90

then I get errors from the module build:

Error message:

...
compiling Fortran sources
Fortran f77 compiler: /usr/local/bin/gfortran -Wall -g -ffixed-form -fno-second-underscore -m64 -fPIC -O3 -funroll-loops
Fortran f90 compiler: /usr/local/bin/gfortran -Wall -g -fno-second-underscore -m64 -fPIC -O3 -funroll-loops
Fortran fix compiler: /usr/local/bin/gfortran -Wall -g -ffixed-form -fno-second-underscore -Wall -g -fno-second-underscore -m64 -fPIC -O3 -funroll-loops
compile options: '-I/var/folders/9y/zmj12xx97jv4m19jg0ywpsg00000gn/T/tmplv7hp3b_/src.macosx-10.7-x86_64-3.6 -I/Users/loredo/anaconda/envs/py36/lib/python3.6/site-packages/numpy/core/include -I/Users/loredo/anaconda/envs/py36/include/python3.6m -c'
gfortran:f90: _trapz.f90
gfortran:f77: /var/folders/9y/zmj12xx97jv4m19jg0ywpsg00000gn/T/tmplv7hp3b_/src.macosx-10.7-x86_64-3.6/_trapz-f2pywrappers.f
/var/folders/9y/zmj12xx97jv4m19jg0ywpsg00000gn/T/tmplv7hp3b_/src.macosx-10.7-x86_64-3.6/_trapz-f2pywrappers.f:13:17:
           real*8, dimension(size(x)),intent(in),depend(x) :: y
                 1
Error: Invalid character in name at (1)
/var/folders/9y/zmj12xx97jv4m19jg0ywpsg00000gn/T/tmplv7hp3b_/src.macosx-10.7-x86_64-3.6/_trapz-f2pywrappers.f:17:22:

       trapzf2pywrap = trapz(x, y)
                      1
Error: Type mismatch in argument ‘y’ at (1); passed REAL(8) to REAL(4)
error: Command "/usr/local/bin/gfortran -Wall -g -ffixed-form -fno-second-underscore -m64 -fPIC -O3 -funroll-loops -I/var/folders/9y/zmj12xx97jv4m19jg0ywpsg00000gn/T/tmplv7hp3b_/src.macosx-10.7-x86_64-3.6 -I/Users/loredo/anaconda/envs/py36/lib/python3.6/site-packages/numpy/core/include -I/Users/loredo/anaconda/envs/py36/include/python3.6m -c -c /var/folders/9y/zmj12xx97jv4m19jg0ywpsg00000gn/T/tmplv7hp3b_/src.macosx-10.7-x86_64-3.6/_trapz-f2pywrappers.f -o /var/folders/9y/zmj12xx97jv4m19jg0ywpsg00000gn/T/tmplv7hp3b_/var/folders/9y/zmj12xx97jv4m19jg0ywpsg00000gn/T/tmplv7hp3b_/src.macosx-10.7-x86_64-3.6/_trapz-f2pywrappers.o" failed with exit status 1

I have no trouble building a module from another simple function this way. Am I overlooking a problem in the Fortran code? I don't see any invalid names (might this be treating free-form code as fixed-form?), and I don't see the origin of the type mismatch. And neither problem arose going straight to the module.

Numpy/Python version information:

macOS 10.13.6, gfortran-6.3.0 (latest from GCC for this OS)

import sys, numpy; print(numpy.version, sys.version)
1.16.2 3.6.8 |Anaconda, Inc.| (default, Dec 29 2018, 19:04:46)
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)]

@pearu
Copy link
Contributor

pearu commented Nov 25, 2019

In the generated _trapz-f2pywrappers.f file, the line

real*8, dimension(size(x)),intent(in),depend(x) :: y

should read

real*8, dimension(size(x)),intent(in) :: y

As a workaround, try removing depend(x) from the corresponding line in the .pyf file.

@HaoZeke
Copy link
Member

HaoZeke commented Dec 18, 2023

This is now very close, the .pyf file is the same (with the meson backend). The generated file difference between the broken and the working code is just:

12,14c12,13
<           real*8, required,dimension(:),intent(in) :: x
<           real*8, dimension(size(x)),intent(in),check(shape(y, 0) == siz&
<      &e(x)),depend(x) :: y
---
>           real*8, dimension(:),intent(in) :: x
>           real*8, dimension(size(x)),intent(in) :: y

Corresponding to the error:

../_trapz-f2pywrappers2.f90:12:18:

   12 |           real*8, required,dimension(:),intent(in) :: x
      |                  1
Error: Invalid character in name at (1)
../_trapz-f2pywrappers2.f90:13:18:

   13 |           real*8, dimension(size(x)),intent(in),check(shape(y, 0) == siz&
      |                  1
Error: Invalid character in name at (1)
../_trapz-f2pywrappers2.f90:18:22:

   18 |       trapzf2pywrap = trapz(x, y)
      |                      1
Error: Type mismatch in argument 'x' at (1); passed REAL(8) to REAL(4)
../_trapz-f2pywrappers2.f90:18:22:

   18 |       trapzf2pywrap = trapz(x, y)
      |                      1
Error: Type mismatch in argument 'y' at (1); passed REAL(8) to REAL(4)

Note that the checks shouldn't have made it into f2pywrappers2 in the first place, they belong (correctly) in the .pyf file which also has them. As expected it is because of different handling in the front-end (#25179).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

No branches or pull requests

4 participants