0

I am having some weird errors when trying to use the ifort compilation in Fortran. My code uses the nlopt library and I am writing from a MacOS Big Sur.

Already tried to use gfortran instead of ifort, but also had difficulties to install the nlopt within the GNU compilation.

The code is long, but the module and subroutine that I use the nlopt library is the following:

subroutine nlopt_stat_fcn(ff, nv, x, gradient, need_gradient, param)
    use globvar, only: dp
    use model
    implicit none
    integer :: nv, need_gradient
    real(dp) :: x(nv), FF, gradient(nv)
    real(dp) :: param(2) ! bounds

    ff = statopt(x(1)) ! negative of payoff

    if (need_gradient.ne.0) then 
        print*, 'nlopt algorithm expects gradient, mistake'
    endif
end subroutine nlopt_stat_fcn

subroutine nlopt_stat(n, x0, x1, res, ires, step, tol, algo, param)
    ! n is dimensionality of problem (number of unknowns x)
    ! x0 is guess IN
    ! x1 is solution OUT
    ! res is the minimized function value OUT
    use globvar, only: dp
    implicit none
    include 'nlopt.f'
    external nlopt_stat_fcn
    integer ires, n, algo
    real(dp), intent(in) :: x0(n)
    real(dp), intent(out) :: x1(n), res
    real(dp) :: x(n), abstol(n), reltol(n), step(n), tol
    real(dp) :: param(2), xlo(n), xhi(n)
    integer opt, local_opt

    xlo = param(1)
    xhi = param(2)

    abstol = tol !/2.0_dp
    reltol = tol

    ! algorithm and stopping
    if (algo==1) call nlo_create(opt, nlopt_ld_slsqp, n)
    if (algo==2) call nlo_create(opt, nlopt_ln_cobyla, n)
    if (algo==3) call nlo_create(opt, nlopt_ld_auglag, n)
    if (algo==4) call nlo_create(opt, nlopt_gn_isres, n)
    if (algo==5) call nlo_create(opt, nlopt_ld_lbfgs, n)
    if (algo==6) call nlo_create(opt, nlopt_ln_bobyqa, n)
    if (algo==7) call nlo_create(opt, nlopt_ln_neldermead, n)
    if (algo==8) call nlo_create(opt, nlopt_ln_sbplx, n)
    
    call nlo_set_xtol_rel(ires, opt, reltol)
    call nlo_set_xtol_abs(ires, opt, abstol)
    call nlo_set_ftol_rel(ires, opt, reltol)
    call nlo_set_ftol_abs(ires, opt, abstol)
    call nlo_set_maxeval(ires, opt, 10000)

    ! objective function
    ! parameters must be passed as declared variables
    call nlo_set_min_objective(ires, opt, nlopt_stat_fcn,param)

    ! bounds
    ! *never* violated during optimization (constraints can be)
    call nlo_set_lower_bounds(ires, opt, xlo)
    call nlo_set_upper_bounds(ires, opt, xhi)

    call nlo_set_initial_step(ires, opt, step)

    ! call solver
    x = x0
    call nlo_optimize(ires, opt, x, res)
    x1 = x

    call nlo_destroy(opt)
    if (algo==3) call nlo_destroy(local_opt)

end subroutine nlopt_stat

! ------------------------------------------------------------------
! nlopt dynamic problem
! ------------------------------------------------------------------
subroutine nlopt_fcn(ff, nv, x, gradient, need_gradient, param)
    use globvar, only: dp
    use model
    implicit none
    integer :: nv, need_gradient
    real(dp) :: x(nv), FF, gradient(nv)
    real(dp) :: param(2) ! bounds

    ff = dynopt(x(1)) ! negative of payoff

    if (need_gradient.ne.0) then 
        print*, 'nlopt algorithm expects gradient, mistake'
    endif
end subroutine nlopt_fcn

subroutine nlopt(n, x0, x1, res, ires, step, tol, algo, param)
    ! n is dimensionality of problem (number of unknowns x)
    ! x0 is guess IN
    ! x1 is solution OUT
    ! res is the minimized function value OUT
    use globvar, only: dp
    implicit none
    include 'nlopt.f'
    external nlopt_fcn
    integer ires, n, algo
    real(dp), intent(in) :: x0(n)
    real(dp), intent(out) :: x1(n), res
    real(dp) :: x(n), abstol(n), reltol(n), step(n), tol
    real(dp) :: param(2), xlo(n), xhi(n)
    integer opt, local_opt

    xlo = param(1)
    xhi = param(2)

    abstol = tol !/2.0_dp
    reltol = tol

    ! algorithm and stopping
    if (algo==1) call nlo_create(opt, nlopt_ld_slsqp, n)
    if (algo==2) call nlo_create(opt, nlopt_ln_cobyla, n)
    if (algo==3) call nlo_create(opt, nlopt_ld_auglag, n)
    if (algo==4) call nlo_create(opt, nlopt_gn_isres, n)
    if (algo==5) call nlo_create(opt, nlopt_ld_lbfgs, n)
    if (algo==6) call nlo_create(opt, nlopt_ln_bobyqa, n)
    if (algo==7) call nlo_create(opt, nlopt_ln_neldermead, n)
    if (algo==8) call nlo_create(opt, nlopt_ln_sbplx, n)
    
    call nlo_set_xtol_rel(ires, opt, reltol)
    call nlo_set_xtol_abs(ires, opt, abstol)
    call nlo_set_ftol_rel(ires, opt, reltol)
    call nlo_set_ftol_abs(ires, opt, abstol)
    call nlo_set_maxeval(ires, opt, 10000)

    ! objective function
    ! parameters must be passed as declared variables
    call nlo_set_min_objective(ires, opt, nlopt_fcn,param)

    ! bounds
    ! *never* violated during optimization (constraints can be)
    call nlo_set_lower_bounds(ires, opt, xlo)
    call nlo_set_upper_bounds(ires, opt, xhi)

    call nlo_set_initial_step(ires, opt, step)

    ! call solver
    x = x0
    call nlo_optimize(ires, opt, x, res)
    x1 = x

    call nlo_destroy(opt)
    if (algo==3) call nlo_destroy(local_opt)

end subroutine nlopt

Which gives me the following error:

victoralexandrino@MacBook-Pro-de-Victor-3:~/Google Drive/PhD Insper/Thesis/Paper 1 - Sovereign Default Holdings/Read/Sunder-Plassmann (2020) - Paper, Codes and Data/research_data$ ifort *.f90  -L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib
Undefined symbols for architecture x86_64:
  "_nlo_create_", referenced from:
      _model_mp_solve_dynamic_problem_ in ifortTeFs8c.o
      _model_mp_solve_static_problem_ in ifortTeFs8c.o
      _nlopt_stat_ in ifortTeFs8c.o
      _nlopt_ in ifortTeFs8c.o
  "_nlo_destroy_", referenced from:
      _model_mp_solve_dynamic_problem_ in ifortTeFs8c.o
      _model_mp_solve_static_problem_ in ifortTeFs8c.o
      _nlopt_stat_ in ifortTeFs8c.o
      _nlopt_ in ifortTeFs8c.o
  "_nlo_optimize_", referenced from:
      _model_mp_solve_dynamic_problem_ in ifortTeFs8c.o
      _model_mp_solve_static_problem_ in ifortTeFs8c.o
      _nlopt_stat_ in ifortTeFs8c.o
      _nlopt_ in ifortTeFs8c.o
  "_nlo_set_ftol_abs_", referenced from:
      _model_mp_solve_dynamic_problem_ in ifortTeFs8c.o
      _model_mp_solve_static_problem_ in ifortTeFs8c.o
      _nlopt_stat_ in ifortTeFs8c.o
      _nlopt_ in ifortTeFs8c.o
  "_nlo_set_ftol_rel_", referenced from:
      _model_mp_solve_dynamic_problem_ in ifortTeFs8c.o
      _model_mp_solve_static_problem_ in ifortTeFs8c.o
      _nlopt_stat_ in ifortTeFs8c.o
      _nlopt_ in ifortTeFs8c.o
  "_nlo_set_initial_step_", referenced from:
      _model_mp_solve_dynamic_problem_ in ifortTeFs8c.o
      _model_mp_solve_static_problem_ in ifortTeFs8c.o
      _nlopt_stat_ in ifortTeFs8c.o
      _nlopt_ in ifortTeFs8c.o
  "_nlo_set_lower_bounds_", referenced from:
      _model_mp_solve_dynamic_problem_ in ifortTeFs8c.o
      _model_mp_solve_static_problem_ in ifortTeFs8c.o
      _nlopt_stat_ in ifortTeFs8c.o
      _nlopt_ in ifortTeFs8c.o
  "_nlo_set_maxeval_", referenced from:
      _model_mp_solve_dynamic_problem_ in ifortTeFs8c.o
      _model_mp_solve_static_problem_ in ifortTeFs8c.o
      _nlopt_stat_ in ifortTeFs8c.o
      _nlopt_ in ifortTeFs8c.o
  "_nlo_set_min_objective_", referenced from:
      _model_mp_solve_dynamic_problem_ in ifortTeFs8c.o
      _model_mp_solve_static_problem_ in ifortTeFs8c.o
      _nlopt_stat_ in ifortTeFs8c.o
      _nlopt_ in ifortTeFs8c.o
  "_nlo_set_upper_bounds_", referenced from:
      _model_mp_solve_dynamic_problem_ in ifortTeFs8c.o
      _model_mp_solve_static_problem_ in ifortTeFs8c.o
      _nlopt_stat_ in ifortTeFs8c.o
      _nlopt_ in ifortTeFs8c.o
  "_nlo_set_xtol_abs_", referenced from:
      _model_mp_solve_dynamic_problem_ in ifortTeFs8c.o
      _model_mp_solve_static_problem_ in ifortTeFs8c.o
      _nlopt_stat_ in ifortTeFs8c.o
      _nlopt_ in ifortTeFs8c.o
  "_nlo_set_xtol_rel_", referenced from:
      _model_mp_solve_dynamic_problem_ in ifortTeFs8c.o
      _model_mp_solve_static_problem_ in ifortTeFs8c.o
      _nlopt_stat_ in ifortTeFs8c.o
      _nlopt_ in ifortTeFs8c.o
ld: symbol(s) not found for architecture x86_64

Many thanks in advance for any help :)

  • 1
    Welcome, please take the [tour]. You don't seem to be linking the library. – Vladimir F Героям слава Mar 01 '21 at 22:33
  • You really have to link it, I do not know what is the name of your library file, but it will be something as `-lnlopt` if it is `libnlopt.so` or `libnlopt.a`. – Vladimir F Героям слава Mar 02 '21 at 10:43
  • What do you mean to link it? the library is `nlopt` ([here](https://nlopt.readthedocs.io/en/latest/)). In call it in other module using the `include 'nlopt.f'` statement. It is already installed from `$ brew install nlopt`. – Victor Hugo Alexandrino Mar 03 '21 at 13:08
  • Please see https://stackoverflow.com/a/12574400/721644 It is for C++ but most concepts work for other languages too. Compilation produces object files from your code. But at the final stage those object files need to be linked with the library. In a simple command it all happens one by one. You must tell the compiler which libraries it should link. Therefore, you need something like `-lnlopt`. – Vladimir F Героям слава Mar 03 '21 at 13:27
  • Please note that `include 'nlopt.f'` only enables your compiler to generate code that calls that library. It does NOT include any compiled code for the functions from that library. – Vladimir F Героям слава Mar 03 '21 at 13:31

0 Answers0