Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Problem linked some library.

Felipe_Marchant
Beginner
783 Views

Hi to everyone,

I need your help with a problem when that appears when I try to compile some program using Ifort 13. I create some library called libmaxent.a and in the program that I want to use I put ifort -o shape -check bound -g -traceback -C maxent_shape.f90 -L /home/felipe/Maxent/Intel_version -lmaxent to compile the code, considering that the library is located on the path describe, but I obtain the next error:

/tmp/ifortuplYii.o: In function `maxent_shape':
/home/felipe/Programs/Programs/FP1D/maxent_shape.f90:67: undefined reference to `drivermaxent_'

I review the called to the subroutine, and I don't see any problem with that. Please, someone can help me with this, and say me where is my error.

Thanks.

0 Kudos
5 Replies
mecej4
Honored Contributor III
783 Views

The linker is telling you that the subroutine/function "drivermaxent", which is invoked on line 67 of source file maxent_shape.f90 was not found in the libraries that you listed. The matter now rests between you and your code, which you have not shown us. 

0 Kudos
Felipe_Marchant
Beginner
783 Views

Thanks for your reply, well I understand the same thing, but when I create the library I'm sure that this subroutine is contained in the module that I use to form them.  With respect to the code, the code where I use the library is:

[       PROGRAM maxent_shape

        IMPLICIT NONE

        INTEGER(KIND=4),PARAMETER :: ipr = 4
        INTEGER(KIND=4),PARAMETER :: pr = 8

        INTEGER(KIND=ipr) :: i,j,k
        INTEGER(KIND=ipr) :: intervals
        INTEGER(KIND=ipr) :: nodes
        INTEGER(KIND=ipr) :: errorflag

        REAL(KIND=pr) :: step
        REAL(KIND=pr) :: lengthscale

        REAL(KIND=pr),DIMENSION(:),ALLOCATABLE :: p
        REAL(KIND=pr),DIMENSION(:),ALLOCATABLE :: rmax
        REAL(KIND=pr),DIMENSION(:),ALLOCATABLE :: phi
        REAL(KIND=pr),DIMENSION(:,:),ALLOCATABLE :: sphi
        REAL(KIND=pr),DIMENSION(:,:),ALLOCATABLE :: dphi
        REAL(KIND=pr),DIMENSION(:,:,:),ALLOCATABLE :: ddphi
        REAL(KIND=pr),DIMENSION(:,:),ALLOCATABLE :: xyz
        REAL(KIND=pr),DIMENSION(:,:,:),ALLOCATABLE :: d

        LOGICAL :: printflag


        WRITE(*,*) '**************************************'
        WRITE(*,*) '*** SHAPE FUNCTION CALCULATE (1D). ***'
        WRITE(*,*) '**************************************'
        WRITE(*,*)

        WRITE(*,*) 'How many intervals do you want to probe?'
        READ(*,*) intervals

        WRITE(*,*)

        WRITE(*,*) 'Starting calculate of points ...'
        nodes = intervals + 1
        ALLOCATE(xyz(nodes,1),p(1),phi(nodes),sphi(nodes,nodes))
        ALLOCATE(rmax(nodes),dphi(1,nodes),ddphi(1,1,nodes),d(1,1,nodes))

        step = (1.0d0 - 0.0d0)/dble(intervals)

        DO i = 1,nodes
                xyz(i,1) = step*(dble(i-1))
                rmax(i) = 1.0d0
        END DO

        WRITE(*,*) '************ The intervals is then ...'
        WRITE(*,*) (xyz(i,1), i = 1,nodes)
        WRITE(*,*)
        WRITE(*,*) 'Calculate of intervals finished.'
        WRITE(*,*) '**************************************'

        DO i = 1,nodes
                p(1) = xyz(i,1)
                d = 0.0d0
                DO j = 1,1
                        DO k = 1,nodes
                                d(k,k,j) = 1.0d0
                        END DO
                END DO
                lengthscale = 1.0d0
                printflag = .TRUE.
                CALL drivermaxent(nodes,1,'newton','uniform',xyz,p,rmax,d,100, &
                1.0d-10,printflag,errorflag,lengthscale,1.d-15,phi,dphi,ddphi)
                DO j = 1,nodes
                        sphi(j,i) = phi(j)
                END DO
        END DO

        OPEN(UNIT=10,FILE='Maxent_function.dat')

        DO i = 1,nodes
                DO j = 1,nodes
                        WRITE(10,*) xyz(j,1),sphi(j,i)
                END DO
                WRITE(10,*)
                WRITE(10,*)
        END DO

        CLOSE(UNIT=10)

END PROGRAM maxent_shape
]

****************************************

And the subroutine contained in the library is:

[

!*************************************************************************
! SUBROUTINE drivermaxent(ndim,nsddim,scheme,priorwt,xyz,p,dmax,dmetric,&
!                         maxit,eps,maxentprint,ierror,charlengthscale,&
!                         idet_tol,phi,dphi,ddphi)
! Purpose
! =======
! Driver subroutine for maxent basis functions, which serves as a general
! purpose interface to the MAXENT library
!
!*************************************************************************
!
SUBROUTINE drivermaxent(ndim,nsddim,scheme,priorwt,xyz,p,dmax,dmetric,&
                        maxit,eps,maxentprint,ierror,charlengthscale,&
                        dettol,phi,dphi,ddphi)

USE priorweightfunction

integer, intent(in) :: ndim, nsddim
integer :: ierror
character(80), intent(in) :: scheme, priorwt
real(dp), intent(in) :: xyz(ndim,nsddim), p(nsddim)
real(dp), intent(in) :: dmax(ndim)
real(dp), intent(in) :: dmetric(nsddim,nsddim,ndim)
integer, intent(in) :: maxit
real(dp), intent(in) :: eps
logical, intent(in) :: maxentprint
real(dp), optional, intent(in)    :: charlengthscale, dettol
real(dp), optional, intent(out) :: phi(ndim)
real(dp), optional, intent(out) :: dphi(nsddim,ndim)
real(dp), optional, intent(out) :: ddphi(nsddim,nsddim,ndim)

integer :: i, j

!
! set `rmax', 'metric', and `prior' in the priorweightfunction module
!
call setrmaxandpriorweight(dmax,dmetric,priorwt)

n = ndim
nsd = nsddim
method = scheme
maxiter = maxit
epsilon = eps
ierror = 0
!
! set point, coord and allocate A matrix
!
call allocateandsetarrays(p,xyz,dmetric,dmax)

!
! determine characteristic length, which is needed to establish convergence criterion that is
! independent of specimen dimensions
!
if (present(charlengthscale)) then
  charlen = charlengthscale
else
  charlen = sum(getrmax())/ndim ! use average of the support sizes to make
                                ! results independent of units
endif
if (present(dettol)) det_tol = dettol

if (maxentprint) then
  if (nsd == 1) write(*,'("POINT = ",(1pe13.6),/)')point
  if (nsd == 2) write(*,'("POINT = ",2(1pe13.6),/)')point
  if (nsd == 3) write(*,'("POINT = ",3(1pe13.6),/)')point
  if (nsd > 3) write(*,*)"POINT = ",point
  do i = 1,n
    if (nsd == 1) then
      write(*,'("NODE ",i5," : COORD = ",1(1pe13.6)," RMAX ",1pe13.6)')i,coord(i,:),dmax(i)
    else if (nsd == 2) then
      write(*,'("NODE ",i5," : COORD = ",2(1pe13.6)," RMAX ",1pe13.6)')i,coord(i,:),dmax(i)
    else if (nsd == 3) then
      write(*,'("NODE ",i5," : COORD = ",3(1pe13.6)," RMAX ",1pe13.6)')i,coord(i,:),dmax(i)
    else
      write(*,'("NODE ",i5," : COORD = ",4(1pe13.6)," RMAX ",1pe13.6)')i,coord(i,:),dmax(i)
    endif
  enddo
  write(*,'(/,"PRIOR WEIGHTFUNCTION TYPE = ",a20,/)')getpriortype()
endif

select case (method)
  case ('descent')
    call drivermaxent_descent(maxentprint,phi)
  case ('lbfgs')
    call drivermaxent_lbfgs(maxentprint,phi)
  case ('newton')
    call drivermaxent_newton(maxentprint,phi)
  case default
    write(*,*)"Solution scheme not yet coded for scheme = ", method
    stop
end select

!
! determinant in inv hessian is too small or nonconvergence in `maxiter' iterations
!
if (error_flag .ne. 0) then
  ierror = error_flag
  call deallocatemaxentarrays
  return
endif

if (present(dphi)) then
  if (.not. present(phi)) then
    write(6,*)'Error: Must include phi in the calling subroutine too'
    stop
  endif
  dphi = dphimaxent()
  if (maxentprint) then
    call checkdconsistency()
    write(*,*)"D-BASISFUNCTIONS"
    do i = 1,n
      if (nsd == 1) write(*,'(i5,1x,1(1pe20.13,1x))')i,dphi(1:nsd,i)
      if (nsd == 2) write(*,'(i5,1x,2(1pe20.13,1x))')i,dphi(1:nsd,i)
      if (nsd == 3) write(*,'(i5,1x,3(1pe20.13,1x))')i,dphi(1:nsd,i)
      if (nsd > 3) write(*,'(i5,1x,4(1pe20.13,1x))')i,dphi(1:nsd,i)
    enddo
  endif
endif

if (present(ddphi)) then
  if (.not. present(phi)) then
    write(6,*)'Error: Must include phi in the calling subroutine too'
    stop
  endif
  ddphi = ddphimaxent()
  if (maxentprint) then
    call checkddconsistency()
    write(*,*)"DD-BASISFUNCTIONS"
    do i = 1,n
      if (nsd == 1) then
        write(*,'(i5,1x,1(1pe20.13))')i,ddphi(1,1:nsd,i)
      elseif (nsd == 2) then
        write(*,'(i5,1x,2(1pe20.13,1x))')i,ddphi(1,1:nsd,i)
        write(*,'(6x,2(1pe20.13,1x))')ddphi(2,1:nsd,i)
      elseif (nsd == 3) then
        write(*,'(i5,1x,3(1pe20.13,1x))')i,ddphi(1,1:nsd,i)
        write(*,'(6x,3(1pe20.13,1x))')ddphi(2,1:nsd,i)
        write(*,'(6x,3(1pe20.13,1x))')ddphi(3,1:nsd,i)
      else
        write(*,'(i5,1x,4(1pe20.13,1x))')i,ddphi(1,1:nsd,i)
        write(*,'(6x,4(1pe20.13,1x))')ddphi(2,1:nsd,i)
        write(*,'(6x,4(1pe20.13,1x))')ddphi(3,1:nsd,i)
        write(*,'(6x,4(1pe20.13,1x))')ddphi(4,1:nsd,i)
      endif
    enddo
  endif
endif

call deallocatemaxentarrays

END SUBROUTINE drivermaxent

]

Thanks for your help.

0 Kudos
Felipe_Marchant
Beginner
783 Views

Ok, I have reviewing and I think that my problem is with the library. For the library, I have two file that each contains a module and my first action was compile this, and obtain the *.o. After this I create the library writing::

ar cr libmaxent.a priorweightfunction.o maxent.o

The problem that I think is that I don't consider the *.mod or in my program, I don't call the module using USE; but really I don't have clear this. Can any help me with that and explain me this? Thanks in advance.

0 Kudos
mecej4
Honored Contributor III
783 Views

When you compile a source containing a module and the module contains a procedure, the object file gets the subroutine name decorated by the module name. If you call the subroutine from your main program or elsewhere, but do not have a USE statement for the module, the call in the object file is to the undecorated subroutine name, and therfore an unsatisfied external symbol is flagged by the linker. In other words, an attempt to call a module procedure as if it were a simple external procedure will cause a link-time error. Solution: use a USE statement in the routine containing the call to the module procedure.

0 Kudos
Felipe_Marchant
Beginner
783 Views
Thanks for your help, the problem, that I had, was that I wasn't using USE and neither was indicating the location of the *.mod. To fix this then I wrote the call to module using USE and I compiled according to: ifort -o shape -check bound -g -traceback -C maxent_shape.f90 -module /home/felipe/Maxent/src -L /home/felipe/Maxent/Intel_version -lmaxent Thank you very much. Regards.
0 Kudos
Reply