0

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

1 Answer 1

0

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

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

Comments

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.