'f2py compilation error with type(c_ptr) from iso_c_binding

Summary

I am trying to write a model using Fortran and I need to use a function to integrate (closed limits).

I tried working with fgsl and the standalone script (compiled with gfortran) works fine. However, when I try to modify the example and try to re-structure the program as a subroutine under a module, so that I can compile it as an f2py module importable in python, I encounter the following error:

...

getctype: No C-type found in "{'typespec': 'type', 'typename': 'c_ptr'}", assuming void.

... (possibly irrelevant lines later)

File "/home/***/.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'

This is probably directly a result of the declaration line in the code I am trying to compile:

...
use, intrinsic :: iso_c_binding
...
type(c_ptr), value :: params

I must admit, I do not have a good understanding of pointers or even what is exactly happening here, but as mentioned earlier, compilation with gfortran as a program+module works fine.

Even if you can give me alternative methods I can use to internally (in Fortran) integrate a closed function with finite limits (except for trapezoidal/rectangular/simpsons/ functions or callback of scipy.quad functions from python - these methods do not deliver the speed/accuracy that I am looking for).

Full scripts

Standalone integration script (doc/example from fgsl), integration.f90:

module mod_integration
  use fgsl
  use, intrinsic :: iso_c_binding
  implicit none
contains
  function f(x, params) bind(c)
    real(c_double), value :: x
    type(c_ptr), value :: params
    real(c_double) :: f
!
    real(c_double), pointer :: alpha
    call c_f_pointer(params, alpha)
    f = log(alpha * x) / sqrt(x)
  end function f
end module
program integration
  use mod_integration
  implicit none
  integer(fgsl_size_t), parameter :: nmax=1000
  real(fgsl_double), target :: alpha
  real(fgsl_double) :: result, error
  integer(fgsl_int) :: status
  type(c_ptr) :: ptr
  type(fgsl_function) :: f_obj
  type(fgsl_integration_workspace) :: wk
  alpha = 1.0D0
  ptr = c_loc(alpha)
  f_obj = fgsl_function_init(f, ptr)
  wk = fgsl_integration_workspace_alloc(nmax)
  status = fgsl_integration_qags(f_obj, 0.0_fgsl_double, 1.0_fgsl_double, &
       0.0_fgsl_double, 1.0e-7_fgsl_double, nmax, wk, result, error)
  write(6, fmt='(''Integration result        : '',F20.16)') result
  write(6, fmt='(''Integration error estimate: '',F20.16)') error
  write(6, fmt='(''Exact result              : '',F20.16)') -4.0D0
  call fgsl_function_free(f_obj)
  call fgsl_integration_workspace_free(wk)
end program integration

Compiled with: gfortran integration.f90 -L/usr/local/lib/ -lfgsl -I/usr/local/include/fgsl/

Modified example program for module f2py creation intgrt.f90:

module mod_integration
  use fgsl
  use, intrinsic :: iso_c_binding
  implicit none
contains
  function f(x, params) bind(c)
    real(c_double), value :: x
    type(c_ptr), value :: params
    real(c_double) :: f
!
    real(c_double), pointer :: alpha
    call c_f_pointer(params, alpha)
    f = log(alpha * x) / sqrt(x)
  end function f
end module

module integration
  use mod_integration
  implicit none
contains
  subroutine integration(res)
    integer(fgsl_size_t), parameter :: nmax=1000
    real(fgsl_double), target :: alpha
    real(fgsl_double) :: result, error
    real*8, intent(out) :: res
    integer(fgsl_int) :: status
    type(c_ptr) :: ptr
    type(fgsl_function) :: f_obj
    type(fgsl_integration_workspace) :: wk
    alpha = 1.0D0
    ptr = c_loc(alpha)
    f_obj = fgsl_function_init(f, ptr)
    wk = fgsl_integration_workspace_alloc(nmax)
    status = fgsl_integration_qags(f_obj, 0.0_fgsl_double, 1.0_fgsl_double, &
        0.0_fgsl_double, 1.0e-7_fgsl_double, nmax, wk, result, error)
    write(6, fmt='(''Integration result        : '',F20.16)') result
    write(6, fmt='(''Integration error estimate: '',F20.16)') error
    write(6, fmt='(''Exact result              : '',F20.16)') -4.0D0
    call fgsl_function_free(f_obj)
    call fgsl_integration_workspace_free(wk)
    res = result
  end subroutine integration
end module integration

Tried to compile with: f2py -m fortrapper -h intgrt.pyf intgrt.f90 --overwrite-signature && f2py -c -I/usr/local/integral/include/ intgrt.pyf intgrt.f90 -l/usr/local/lib/fgsl -I/usr/local/include/fgsl/ --verbose

Error

/local/lib/fgsl -I/usr/local/include/fgsl/ --verbose
Reading fortran codes...
        Reading file 'intgrt.f90' (format:free)
{'before': '', 'this': 'use', 'after': ', intrinsic :: iso_c_binding '}
Line #3 in intgrt.f90:"  use, intrinsic :: iso_c_binding "
        analyzeline: Could not crack the use statement.
Post-processing...
        Block: fortrapper
                        Block: mod_integration
In: :fortrapper:intgrt.f90:mod_integration
get_useparameters: no module fgsl info used by mod_integration
                                Block: f
In: :fortrapper:intgrt.f90:mod_integration:f
get_useparameters: no module fgsl info used by f
                        Block: integration
                                Block: integration
Post-processing (stage 2)...
        Block: fortrapper
                Block: unknown_interface
                        Block: mod_integration
                                Block: f
                        Block: integration
                                Block: integration
Saving signatures to file "./intgrt.pyf"
running build
running config_cc
unifing config_cc, config, build_clib, build_ext, build commands --compiler options
running config_fc
unifing config_fc, config, build_clib, build_ext, build commands --fcompiler options
running build_src
build_src
building extension "fortrapper" sources
creating /tmp/tmpwx6qk3c1/src.linux-x86_64-3.9
f2py options: []
f2py: intgrt.pyf
Reading fortran codes...
        Reading file 'intgrt.pyf' (format:free)
Post-processing...
        Block: fortrapper
                        Block: mod_integration
In: intgrt.pyf:fortrapper:unknown_interface:mod_integration
get_useparameters: no module fgsl info used by mod_integration
                                Block: f
In: intgrt.pyf:fortrapper:unknown_interface:mod_integration:f
get_useparameters: no module fgsl info used by f
                        Block: integration
                                Block: integration
Post-processing (stage 2)...
        Block: fortrapper
                Block: unknown_interface
                        Block: mod_integration
                                Block: f
                        Block: integration
                                Block: integration
Building modules...
        Building module "fortrapper"...
                Constructing F90 module support for "mod_integration"...
                Creating wrapper for Fortran function "f"("f")...
                        Constructing wrapper function "mod_integration.f"...
getctype: "real(kind=c_double)" is mapped to C "float" (to override define dict(real = dict(c_double="<C typespec>")) in /home/***/fgsl-1.5.0/doc/examples/integrate/.f2py_f2cmap file).
getctype: "real(kind=c_double)" is mapped to C "float" (to override define dict(real = dict(c_double="<C typespec>")) in /home/***/fgsl-1.5.0/doc/examples/integrate/.f2py_f2cmap file).
getctype: No C-type found in "{'typespec': 'type', 'typename': 'c_ptr', 'attrspec': ['value']}", assuming void.
getctype: "real(kind=c_double)" is mapped to C "float" (to override define dict(real = dict(c_double="<C typespec>")) in /home/***/fgsl-1.5.0/doc/examples/integrate/.f2py_f2cmap file).
getctype: "real(kind=c_double)" is mapped to C "float" (to override define dict(real = dict(c_double="<C typespec>")) in /home/***/fgsl-1.5.0/doc/examples/integrate/.f2py_f2cmap file).
getctype: "real(kind=c_double)" is mapped to C "float" (to override define dict(real = dict(c_double="<C typespec>")) in /home/***/fgsl-1.5.0/doc/examples/integrate/.f2py_f2cmap file).
getctype: "real(kind=c_double)" is mapped to C "float" (to override define dict(real = dict(c_double="<C typespec>")) in /home/***/fgsl-1.5.0/doc/examples/integrate/.f2py_f2cmap file).
getctype: "real(kind=c_double)" is mapped to C "float" (to override define dict(real = dict(c_double="<C typespec>")) in /home/***/fgsl-1.5.0/doc/examples/integrate/.f2py_f2cmap file).
getctype: "real(kind=c_double)" is mapped to C "float" (to override define dict(real = dict(c_double="<C typespec>")) in /home/***/fgsl-1.5.0/doc/examples/integrate/.f2py_f2cmap file).
getctype: No C-type found in "{'typespec': 'type', 'typename': 'c_ptr', 'attrspec': ['value']}", assuming void.
getctype: No C-type found in "{'typespec': 'type', 'typename': 'c_ptr', 'attrspec': ['value']}", assuming void.
Traceback (most recent call last):
  File "/home/***/.local/bin/f2py", line 8, in <module>
    sys.exit(main())
  File "/home/***/.local/lib/python3.9/site-packages/numpy/f2py/f2py2e.py", line 690, in main
    run_compile()
  File "/home/***/.local/lib/python3.9/site-packages/numpy/f2py/f2py2e.py", line 657, in run_compile
    setup(ext_modules=[ext])
  File "/home/***/.local/lib/python3.9/site-packages/numpy/distutils/core.py", line 169, in setup
    return old_setup(**new_attr)
  File "/usr/lib/python3.9/distutils/core.py", line 148, in setup
    dist.run_commands()
  File "/usr/lib/python3.9/distutils/dist.py", line 966, in run_commands
    self.run_command(cmd)
  File "/usr/lib/python3.9/distutils/dist.py", line 985, in run_command
    cmd_obj.run()
  File "/home/***/.local/lib/python3.9/site-packages/numpy/distutils/command/build.py", line 61, in run
    old_build.run(self)
  File "/usr/lib/python3.9/distutils/command/build.py", line 135, in run
    self.run_command(cmd_name)
  File "/usr/lib/python3.9/distutils/cmd.py", line 313, in run_command
    self.distribution.run_command(command)
  File "/usr/lib/python3.9/distutils/dist.py", line 985, in run_command
    cmd_obj.run()
  File "/home/***/.local/lib/python3.9/site-packages/numpy/distutils/command/build_src.py", line 144, in run
    self.build_sources()
  File "/home/***/.local/lib/python3.9/site-packages/numpy/distutils/command/build_src.py", line 161, in build_sources
    self.build_extension_sources(ext)
  File "/home/***/.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/***/.local/lib/python3.9/site-packages/numpy/distutils/command/build_src.py", line 543, in f2py_sources
    numpy.f2py.run_main(f2py_options
  File "/home/***/.local/lib/python3.9/site-packages/numpy/f2py/f2py2e.py", line 462, in run_main
    ret = buildmodules(postlist)
  File "/home/***/.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/***/.local/lib/python3.9/site-packages/numpy/f2py/rules.py", line 1207, in buildmodule
    mr, wrap = f90mod_rules.buildhooks(m)
  File "/home/***/.local/lib/python3.9/site-packages/numpy/f2py/f90mod_rules.py", line 200, in buildhooks
    api, wrap = rules.buildapi(b)
  File "/home/***/.local/lib/python3.9/site-packages/numpy/f2py/rules.py", line 1365, in buildapi
    vrd = capi_maps.sign2map(a, var[a])
  File "/home/***/.local/lib/python3.9/site-packages/numpy/f2py/capi_maps.py", line 604, in sign2map
    ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, var)
  File "/home/***/.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'```


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source