简体   繁体   中英

f2py fails to compile recursive fortran functions/subroutines

f2py works fine for regular Fortran (free form) subroutines and functions. But fails to compile recursive functions or subroutines

test.f90 :

recursive INTEGER function fib(n) result(a)
    implicit none
    INTEGER::n
    if (n==0)then
        a=0
    elseif (n==1) then
        a=1
    else
        a=fib(n-1)+fib(n-2)
    endif
end function fib

command used: python -m numpy.f2py -c test.f90 -m fibf

ERROR:

getctype: No C-type found in "{'intent': ['out', 'out=a']}", assuming void.
getctype: No C-type found in "{'intent': ['out', 'out=a']}", assuming void.
Traceback (most recent call last):
  File "/usr/lib64/python3.9/runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib64/python3.9/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/home/<user>/.local/lib/python3.9/site-packages/numpy/f2py/__main__.py", line 4, in <module>
    main()
  File "/home/<user>/.local/lib/python3.9/site-packages/numpy/f2py/f2py2e.py", line 690, in main
    run_compile()
  File "/home/<user>/.local/lib/python3.9/site-packages/numpy/f2py/f2py2e.py", line 657, in run_compile
    setup(ext_modules=[ext])
  File "/home/<user>/.local/lib/python3.9/site-packages/numpy/distutils/core.py", line 169, in setup
    return old_setup(**new_attr)
  File "/usr/lib64/python3.9/distutils/core.py", line 148, in setup
    dist.run_commands()
  File "/usr/lib64/python3.9/distutils/dist.py", line 966, in run_commands
    self.run_command(cmd)
  File "/usr/lib64/python3.9/distutils/dist.py", line 985, in run_command
    cmd_obj.run()
  File "/home/<user>/.local/lib/python3.9/site-packages/numpy/distutils/command/build.py", line 61, in run
    old_build.run(self)
  File "/usr/lib64/python3.9/distutils/command/build.py", line 135, in run
    self.run_command(cmd_name)
  File "/usr/lib64/python3.9/distutils/cmd.py", line 313, in run_command
    self.distribution.run_command(command)
  File "/usr/lib64/python3.9/distutils/dist.py", line 985, in run_command
    cmd_obj.run()
  File "/home/<user>/.local/lib/python3.9/site-packages/numpy/distutils/command/build_src.py", line 144, in run
    self.build_sources()
  File "/home/<user>/.local/lib/python3.9/site-packages/numpy/distutils/command/build_src.py", line 161, in build_sources
    self.build_extension_sources(ext)
  File "/home/<user>/.local/lib/python3.9/site-packages/numpy/distutils/command/build_src.py", line 321, in build_extension_sources
    sources = self.f2py_sources(sources, ext)
  File "/home/<user>/.local/lib/python3.9/site-packages/numpy/distutils/command/build_src.py", line 562, in f2py_sources
    numpy.f2py.run_main(f2py_options + ['--lower',
  File "/home/<user>/.local/lib/python3.9/site-packages/numpy/f2py/f2py2e.py", line 462, in run_main
    ret = buildmodules(postlist)
  File "/home/<user>/.local/lib/python3.9/site-packages/numpy/f2py/f2py2e.py", line 388, in buildmodules
    dict_append(ret[mnames[i]], rules.buildmodule(modules[i], um))
  File "/home/<user>/.local/lib/python3.9/site-packages/numpy/f2py/rules.py", line 1190, in buildmodule
    api, wrap = buildapi(nb)
  File "/home/<user>/.local/lib/python3.9/site-packages/numpy/f2py/rules.py", line 1354, in buildapi
    vrd = capi_maps.routsign2map(rout)
  File "/home/<user>/.local/lib/python3.9/site-packages/numpy/f2py/capi_maps.py", line 661, in routsign2map
    ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, rout)
  File "/home/<user>/.local/lib/python3.9/site-packages/numpy/f2py/capi_maps.py", line 387, in getpydocsign
    return getpydocsign(af, var['vars'][af])
  File "/home/<user>/.local/lib/python3.9/site-packages/numpy/f2py/capi_maps.py", line 414, in getpydocsign
    sig = '%s : %s %s%s' % (a, opt, c2py_map[ctype], init)
KeyError: 'void'
make: *** [makefile:2: compile] Error 1

Looks like the compiler is unable to recognize the type of variable an as 'INTEGER'

The same command works fine for non-recursive functions and subroutines.

Is this a bug? since the following program works fine

recursive INTEGER function fib(n) result(a)
    implicit none
    INTEGER::n
    if (n==0)then
        a=0
    elseif (n==1) then
        a=1
    else
        a=fib(n-1)+fib(n-2)
    endif
end function fib

program test
    implicit none
    integer::fib
    print*,"fib 42 = ",fib(42)
end program test

Okay, I figured it out,

modifying it to following will make f2py recognize the type of variable a

recursive function fib(n) result(a)
    implicit none
    INTEGER*8::n,a
    if (n==0)then
        a=0
    elseif (n==1) then
        a=1
    else
        a=fib(n-1)+fib(n-2)
    endif
end function fib

I think it's a bug that f2py can't recognize the other form

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM