Skip to content

DOC: callback example from f2py docs does not work #14919

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

Closed
melissawm opened this issue Nov 15, 2019 · 2 comments
Closed

DOC: callback example from f2py docs does not work #14919

melissawm opened this issue Nov 15, 2019 · 2 comments

Comments

@melissawm
Copy link
Member

The Callback Arguments section of the f2py docs here contains a non-working example.

If we follow the docs and compile the callback.f file using f2py -c -m callback callback.f, the following happens when we try to reproduce the python session:

>>> import callback
>>> def f(i): return i*i
... 
>>> print(callback.foo(f))
0.0
>>> 

The expected result was 110. Changing the Fortran file to declare FUN as a REAL*8 argument does the trick (but I don't understand exactly why this is needed and it's not mentioned in the docs)

C FILE: CALLBACK.F
      SUBROUTINE FOO(FUN,R)
      EXTERNAL FUN
      INTEGER I
      REAL*8 R
      REAL*8 FUN
Cf2py intent(out) r
      R = 0D0
      DO I=-5,5
         R = R + FUN(I)
      ENDDO
      END
C END OF FILE CALLBACK.F

Compile again using f2py -c -m callback callback.f and we get

>>> import callback
>>> def f(i): return i*i
... 
>>> print(callback.foo(f))   
110.0

I'm guessing an explanation of this should be added in the docs. I'm working on updating them but I need help to explain this behaviour. Any input is appreciated!

>>> import sys, numpy; print(numpy.__version__, sys.version)
1.17.3 3.6.7 | packaged by conda-forge | (default, Jul  2 2019, 02:18:42) 
[GCC 7.3.0]
>>> 
@WarrenWeckesser
Copy link
Member

WarrenWeckesser commented Nov 20, 2019

This looks like a bug in the example. With no explicit declaration of the type for FUN, and no IMPLICIT NONE statement to turn off the old Fortran type conventions, the type of FUN will be REAL (i.e. single precision floating point, also often written REAL*4). f2py, however, apparently assumes FUN will return a double precision value (REAL*8). So your change looks correct.

@pearu
Copy link
Contributor

pearu commented Jan 14, 2020

The example used to work in the past when using g77. Since nowadays nobody uses g77, the example should be fixed for gfortran, that is, declare FUN to be REAL*8. Warren explained the 0.0 result.
For the docs, to avoid this kinds of bugs, recommend using IMPLICIT NONE.

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

No branches or pull requests

3 participants