pythonfortranfortran90f2py

f2py error: undefined symbol when import the module


I am trying to use f2py to compile a function in fortran90, the function is actually MOPTA08 problem:

function func_and_constr(x,g)  ! x in, g constraints inout, f return value
! replaces subroutine func(nvar,ncon,x,f,g) in func.f90 (easier for f2py)

    implicit      none

    integer, parameter:: nvar = 124
    integer, parameter:: ncon = 68
    real*8        x(nvar)
    real*8        g(ncon)
    real*8        func_and_constr
    real*8        f

    integer       d
    integer       duuuu
    integer       deeee
    integer       dssss
    integer       drrrr
    integer       ny

    parameter     (d=124)
    parameter     (duuuu=91)
    parameter     (deeee=96)
    parameter     (dssss=84)
    parameter     (drrrr=44)
    parameter     (ny=68)

    integer       uuuu2opt(duuuu)
    integer       eeee2opt(deeee)
    integer       ssss2opt(dssss)
    integer       rrrr2opt(drrrr)
    integer       ssss(ny)

    integer       i
    integer       k
    real*8        xuuuu(duuuu)
    real*8        xeeee(deeee)
    real*8        xssss(dssss)
    real*8        xrrrr(drrrr)
    real*8        mmmm(d)
    real*8        aaaa(d)
    real*8        xl(nvar)
    real*8        xu(nvar)
    real*8        gu(ncon)
    real*8        xxxxx(nvar)

    logical       first

    data          first /.true./

    SAVE

    if (first) then

        first = .false.

        call get_uuuu2opt( uuuu2opt )
        call get_eeee2opt( eeee2opt )
        call get_ssss2opt( ssss2opt )
        call get_rrrr2opt( rrrr2opt )
        call get_mmmm( mmmm )
        call get_aaaa( aaaa )
        call get_ssss( ssss )

    endif

    call get_bbbb(xl, xu, gu)

    do i=1,nvar
        xxxxx(i) = xl(i) + x(i) * (xu(i) - xl(i))
    enddo

    do k=1,duuuu
        i = uuuu2opt(k)
        if (i > 0) then
            xuuuu(k) = xxxxx(i)
        else
            xuuuu(k) = aaaa(-i)
        endif
    enddo

    do k=1,deeee
        i = eeee2opt(k)
        if (i > 0) then
            xeeee(k) = xxxxx(i)
        else
            xeeee(k) = aaaa(-i)
        endif
    enddo

    do k=1,dssss
        i = ssss2opt(k)
        if (i > 0) then
            xssss(k) = xxxxx(i)
        else
            xssss(k) = aaaa(-i)
        endif
    enddo

    do k=1,drrrr
        xrrrr(k) = xxxxx( rrrr2opt(k) )
    enddo

    f = 0.0d0
    do i=1,d
        f = f + mmmm(i) * xxxxx(i)
    enddo

    call g1(xuuuu,g(1))
    call g2(xeeee,g(2))
    call g3(xeeee,g(3))
    call g4(xeeee,g(4))
    call g5(xeeee,g(5))
    call g6(xeeee,g(6))
    call g7(xssss,g(7))
    call g8(xssss,g(8))
    call g9(xssss,g(9))
    call g10(xxxxx,g(10))
    call g11(xxxxx,g(11))
    call g12(xxxxx,g(12))
    call g13(xxxxx,g(13))
    call g14(xxxxx,g(14))
    call g15(xxxxx,g(15))
    call g16(xxxxx,g(16))
    call g17(xxxxx,g(17))
    call g18(xxxxx,g(18))
    call g19(xxxxx,g(19))
    call g20(xxxxx,g(20))
    call g21(xxxxx,g(21))
    call g22(xxxxx,g(22))
    call g23(xxxxx,g(23))
    call g24(xxxxx,g(24))
    call g25(xxxxx,g(25))
    call g26(xxxxx,g(26))
    call g27(xxxxx,g(27))
    call g28(xxxxx,g(28))
    call g29(xxxxx,g(29))
    call g30(xxxxx,g(30))
    call g31(xxxxx,g(31))
    call g32(xxxxx,g(32))
    call g33(xxxxx,g(33))
    call g34(xxxxx,g(34))
    call g35(xxxxx,g(35))
    call g36(xxxxx,g(36))
    call g37(xxxxx,g(37))
    call g38(xxxxx,g(38))
    call g39(xxxxx,g(39))
    call g40(xxxxx,g(40))
    call g41(xxxxx,g(41))
    call g42(xxxxx,g(42))
    call g43(xxxxx,g(43))
    call g44(xxxxx,g(44))
    call g45(xxxxx,g(45))
    call g46(xxxxx,g(46))
    call g47(xxxxx,g(47))
    call g48(xxxxx,g(48))
    call g49(xxxxx,g(49))
    call g50(xxxxx,g(50))
    call g51(xxxxx,g(51))
    call g52(xxxxx,g(52))
    call g53(xxxxx,g(53))
    call g54(xxxxx,g(54))
    call g55(xxxxx,g(55))
    call g56(xrrrr,g(56))
    call g57(xrrrr,g(57))
    call g58(xrrrr,g(58))
    call g59(xrrrr,g(59))
    call g60(xrrrr,g(60))
    call g61(xrrrr,g(61))
    call g62(xrrrr,g(62))
    call g63(xrrrr,g(63))
    call g64(xrrrr,g(64))
    call g65(xrrrr,g(65))
    call g66(xrrrr,g(66))
    call g67(xrrrr,g(67))
    call g68(xrrrr,g(68))

    do i=1,ny
        g(i) = ssss(i) * g(i)
        g(i) = ( g(i) - gu(i) ) / abs(gu(i))
    enddo

    func_and_constr = f

end

I use the following command to compile it, and did not receive any error.

f2py -c -m moptafunc  funcpy.f90

However, when I import the module moptafunc I got the following error:

ImportError: /.../moptafunc.cpython-37m-x86_64-linux-gnu.so: undefined symbol: g67_

I spent a lot of time on it but still failed to solve it. Do anyone know how to solve this problem? My python version is 3.7.7.

Thank you so much!


Solution

  • Your Fortran function func_and_constr calls many other subroutines g1(),g2(),...g67(). You need to have these subroutines, either as compiled code or the code for them.