8000 BUG: `bind(c)` on functions is broken · Issue #24558 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content
BUG: bind(c) on functions is broken #24558
Closed
@HaoZeke

Description

@HaoZeke

Describe the issue:

Consider the following toy example:

! gh9693
  module coddity
    use, intrinsic :: iso_c_binding
    implicit none
    contains
      function c_add(a, b) result(c) bind(c, name="c_add")
        real(c_double) :: a, b
        real(c_double) :: c
        c = a + b
      end function c_add
  end module coddity

This, with python -m numpy.f2py -m buggy isoCfunc.f90 will produce the following wrapper:

!     -*- f90 -*-
!     This file is autogenerated with f2py (version:1.24.4)
!     It contains Fortran 90 wrappers to fortran functions.

      subroutine f2pywrap_coddity_c_add (c_addf2pywrap, a, e_b____result&
     &___c____bind___c_er, e_name__c_add_er)
      use coddity, only : c_add
      real(kind=c_double) a
      real e_b____result___c____bind___c_er
      real e_name__c_add_er
      real c_addf2pywrap
      c_addf2pywrap = c_add(a, e_b____result___c____bind___c_er, e_name_&
     &_c_add_er)
      end subroutine f2pywrap_coddity_c_add
      
      subroutine f2pyinitcoddity(f2pysetupfunc)
      interface 
      subroutine f2pywrap_coddity_c_add (c_addf2pywrap, c_add, a, e_b___&
     &_result___c____bind___c_er, e_name__c_add_er)
      real c_add
      real(kind=c_double) a
      real e_b____result___c____bind___c_er
      real e_name__c_add_er
      real c_addf2pywrap
      end subroutine f2pywrap_coddity_c_add
      end interface
      external f2pysetupfunc
      call f2pysetupfunc(f2pywrap_coddity_c_add)
      end subroutine f2pyinitcoddity

There is of course no end of problems with the generated wrapper as seen in the compiler errors below but also OTOH, kind is not propagated, super mangled variable names..

For reference, note that without bind(c) the wrapper is short and sweet:

!     -*- f90 -*-
!     This file is autogenerated with f2py (version:1.24.4)
!     It contains Fortran 90 wrappers to fortran functions.

      subroutine f2pywrap_coddity_c_add (c_addf2pywrap, a, b)
      use coddity, only : c_add
      real(kind=c_double) a
      real(kind=c_double) b
      real(kind=c_double) c_addf2pywrap
      c_addf2pywrap = c_add(a, b)
      end subroutine f2pywrap_coddity_c_add
      
      subroutine f2pyinitcoddity(f2pysetupfunc)
      interface 
      subroutine f2pywrap_coddity_c_add (c_addf2pywrap, c_add, a, b)
      real(kind=c_double) c_add
      real(kind=c_double) a
      real(kind=c_double) b
      real(kind=c_double) c_addf2pywrap
      end subroutine f2pywrap_coddity_c_add
      end interface
      external f2pysetupfunc
      call f2pysetupfunc(f2pywrap_coddity_c_add)
      end subroutine f2pyinitcoddity

Note that the same function rewritten as a subroutine correctly, that is for:

  module coddity
    use, intrinsic :: iso_c_binding, only: c_double
    implicit none
    contains
      subroutine c_add(a, b, c) bind(c, name="c_add")
        real(c_double), intent(in) :: a, b
        real(c_double), intent(out) :: c
        print*, "a is", a
        print*, "b is", b
        c = a + b
      end subroutine c_add
  end module coddity

With python -m numpy.f2py -m buggy isoCsub.f90 we have:

      subroutine f2pyinitcoddity(f2pysetupfunc)
      use coddity, only : c_add
      external f2pysetupfunc
      call f2pysetupfunc(c_add)
      end subroutine f2pyinitcoddity

Though it won't compile correctly without an f2cmap file, which is noted in #24555.

Reproduce the code example:

#NA

Error message:

INFO: gfortran:f90: /tmp/tmpm7m0gs7h/src.linux-x86_64-3.8/buggy-f2pywrappers2.f90
/tmp/tmpm7m0gs7h/src.linux-x86_64-3.8/buggy-f2pywrappers2.f90:8:16:

    8 |       real(kind=c_double) a
      |                1
Error: Parameter ‘c_double’ at (1) has not been declared or is a variable, which does not reduce to a constant expression
/tmp/tmpm7m0gs7h/src.linux-x86_64-3.8/buggy-f2pywrappers2.f90:21:16:

   21 |       real(kind=c_double) a
      |                1
Error: Parameter ‘c_double’ at (1) has not been declared or is a variable, which does not reduce to a constant expression
/tmp/tmpm7m0gs7h/src.linux-x86_64-3.8/buggy-f2pywrappers2.f90:12:22:

   12 |       c_addf2pywrap = c_add(a, e_b____result___c____bind___c_er, e_name_&
      |                      1
Error: Type mismatch in argument ‘a’ at (1); passed REAL(4) to REAL(8)
/tmp/tmpm7m0gs7h/src.linux-x86_64-3.8/buggy-f2pywrappers2.f90:12:22:

   12 |       c_addf2pywrap = c_add(a, e_b____result___c____bind___c_er, e_name_&
      |                      1
Error: Type mismatch in argument ‘b’ at (1); passed REAL(4) to REAL(8)
/tmp/tmpm7m0gs7h/src.linux-x86_64-3.8/buggy-f2pywrappers2.f90:12:22:

   12 |       c_addf2pywrap = c_add(a, e_b____result___c____bind___c_er, e_name_&
      |                      1
Error: More actual than formal arguments in procedure call at (1)
/tmp/tmpm7m0gs7h/src.linux-x86_64-3.8/buggy-f2pywrappers2.f90:12:22: Warning: Possible change of value in conversion from REAL(8) to REAL(4) at (1) [-Wconversion]
/tmp/tmpm7m0gs7h/src.linux-x86_64-3.8/buggy-f2pywrappers2.f90:5:39:

    5 |       subroutine f2pywrap_coddity_c_add (c_addf2pywrap, a, e_b____result&
      |                                       1
......
   18 |       subroutine f2pywrap_coddity_c_add (c_addf2pywrap, c_add, a, e_b___&
      |                                       2
Warning: 'f2pywrap_coddity_c_add' has the wrong number of arguments between (1) and (2)

Runtime information:

1.24.4
3.8.0 | packaged by conda-forge | (default, Nov 22 2019, 19:11:38)
[GCC 7.3.0]

Context for the issue:

This is likely to be broken right from the initial work on bind(c) since it essentially is adding it to the name mangling process. Should be fixed and backported.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0