How to return a value from a Python callback in Fortran using F2Py

爱⌒轻易说出口 提交于 2019-12-24 00:49:47

问题


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:


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.



来源:https://stackoverflow.com/questions/20265697/how-to-return-a-value-from-a-python-callback-in-fortran-using-f2py

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!