2

Consider the following Fortran subroutine, defined in test.f:

subroutine test(py_func)

use iso_fortran_env, only stdout => output_unit

external py_func

integer :: a
integer :: b

a = 12
write(stdout, *) a

b = py_func(a)
write(stdout, *) b

end subroutine

Also the following Python code, defined in call_test.py:

import test

def func(x):
    return x * 2

test.test(func)

Compiled with the following (Intel compiler):

python f2py.py -c test.f --fcompiler=intelvem -m test

I expect this as output when I run test:

      12
      24

But I actually get this:

      12
       0

It seems as if b is being initialised with a default value instead of the result of test. I have tried using the following in the Fortran:

!f2py intent(callback) py_func
      external py_func
!f2py integer y,x
!f2py y = py_func(x)

But my program crashes after the printout of 12 to the console.

Any ideas what could be going on here? The reason for the crash would be a bonus, but I'm really just interested in getting a simple callback working at this point.

1 Answer 1

0

I don't claim to understand it, I found the answer on an F2Py forum thread. Adding integer py_func (not prefixed by !f2py) does the trick for me:

subroutine test(py_func)

use iso_fortran_env, only stdout => output_unit

!f2py intent(callback) py_func
external py_func
integer py_func
!f2py integer y,x
!f2py y = py_func(x)

integer :: a
integer :: b

a = 12
write(stdout, *) a

b = py_func(a)
write(stdout, *) b

end subroutine

Perhaps this is to do with space being needed for a temporary value used to store the result before being assigned to b? In any case, it is apparently compiler-dependent, which explains why it is not in various F2Py callback examples you can find elsewhere online.

Sign up to request clarification or add additional context in comments.

1 Comment

You do not have implicit none in your file, therefore py_func is considered real due to the implicit typing rules.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.