Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to expose Python callbacks to Fortran using modules

This scipy documentation page about F2Py states:

[Callback functions] may also be explicitly set in the module. Then it is not necessary to pass the function in the argument list to the Fortran function. This may be desired if the Fortran function calling the python callback function is itself called by another Fortran function.

However, I can't seem to find an example of how this would be done.

Consider the following Fortran / Python combination:

test.f:

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

end subroutine

call_test.py:

import test

def func(x):
    return x * 2

test.test(func)

Compiled with the following command (Intel compiler):

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

What changes would I have to take to expose func to the entire Fortran program in the form of a module, so that I could call the function from inside the subroutine test, or any other subroutine in any other fortran file in the project?

like image 749
JimmidyJoo Avatar asked Nov 02 '22 05:11

JimmidyJoo


1 Answers

The following worked for me. Note the absence of the parameters passed to test. The python file is as stated in the question.

subroutine test()

use iso_fortran_env, only stdout => output_unit

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

integer :: a
integer :: b

a = 12
write(stdout, *) a

end subroutine

As an aside, I then wrapped py_func in a subroutine so that I could call it without having to declare the following in every file / function I use it:

integer y
y = py_func(x)
like image 199
JimmidyJoo Avatar answered Nov 05 '22 10:11

JimmidyJoo