Solving Fortran Lapack Compilation Issues

  • Context: Fortran 
  • Thread starter Thread starter Takafoo
  • Start date Start date
  • Tags Tags
    Fortran Lapack
Click For Summary

Discussion Overview

The discussion revolves around issues related to compiling a Fortran program that utilizes LAPACK libraries. Participants are seeking assistance with undefined references during compilation, specifically related to the ZGESV function.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant reports an undefined reference error to `zgesv_` when attempting to compile their Fortran program using LAPACK libraries.
  • Another participant suggests that the issue may stem from a missing variable or function declaration in the user's code, indicating that the problem might not be with the library itself.
  • A participant provides a detailed code snippet, highlighting the section where the ZGESV function is called, but expresses uncertainty about the source of the error.
  • One reply indicates that the ZGESV function should be declared in the user's code, proposing the use of the EXTERNAL keyword to reference the function properly.
  • Another participant mentions that simply placing the libraries in the current directory is insufficient and suggests using specific compiler flags to link the libraries correctly.
  • A later reply warns that starting the program name with numbers may lead to compilation errors, although this is noted as a potential issue for gfortran and possibly ifort.

Areas of Agreement / Disagreement

Participants express various views on the source of the compilation issue, with no consensus reached on the exact cause or solution. Multiple suggestions and hypotheses are presented without agreement on a definitive resolution.

Contextual Notes

Participants mention the need for proper linking of libraries and the potential requirement for function declarations, but there are no settled assumptions about the user's code structure or the libraries' configurations.

Takafoo
Messages
2
Reaction score
0
Can you please help me I can't compile using lapack libraries and I can't find anyone who can tell me how to compile.

I have blas_LINUX.a and lapack_LINUX.a and I am trying to use ifort to compile my program but I always get the below error. Please help.

In function `MAIN__':
1001.f90:(.text+0x23f2): undefined reference to `zgesv_'

These are the libraries I have in the same directory

blas_LINUX.a
lapack_LINUX.a
liblapack_LINUX.a
 
Technology news on Phys.org
Takafoo said:
Can you please help me I can't compile using lapack libraries and I can't find anyone who can tell me how to compile.

I have blas_LINUX.a and lapack_LINUX.a and I am trying to use ifort to compile my program but I always get the below error. Please help.



These are the libraries I have in the same directory

blas_LINUX.a
lapack_LINUX.a
liblapack_LINUX.a

I'm not 100% sure, but it looks like you're referencing a variable, possibly a string, and its not defined.

Since I'm not familiar with the library, if I were you, I would find out what that variable corresponds to. Since it is in main, if your library is just a code library, then most likely the MAIN routine is part of another code-base (possibly your own).

If the code entry point is part of the library itself, find a variable/function/interface etc reference and find out what variable it is.

Again, I'm guessing that if you are using an external library and the entry point is in your code, its not a problem with the library, its a problem with your code base.
 
This is my code if it helps. Live 158 is where I call the function from the library... I can't see where I've gone wrong at all unfortunately.

Code:
PROGRAM 1001

   IMPLICIT NONE

! Declare Variables

   COMPLEX(KIND=8), DIMENSION(:,:), ALLOCATABLE :: mat
   COMPLEX(KIND=8), DIMENSION(:), ALLOCATABLE :: vec, vec_2
   REAL(KIND=8), DIMENSION(:,:), ALLOCATABLE :: mat_r, mat_i
   REAL(KIND=8), DIMENSION(:), ALLOCATABLE :: vec_r, vec_i, a, b, x
   REAL(KIND=8) :: n_x, n_0, k, beta, pi, exp, step, x_i, u_i
   REAL(KIND=8) :: start_time, end_time
   INTEGER :: lambda, L, m, numEq, i
   INTEGER :: allocate_status=0, IO_status
   INTEGER :: NRHS, LD_mat, LD_vec, INFO
   INTEGER, DIMENSION(:), ALLOCATABLE :: IPIV
   CHARACTER(LEN=30) :: fmt, int_char, filename

! Load Parameters File

   PRINT *, "Please specify parameter filename: "
   READ (*,*) filename

  OPEN(1, file=filename, status='old', IOSTAT=IO_status)
  IF (IO_status /= 0) THEN
    WRITE(*,*) "Error!"
    WRITE(*,*) "Cannot open file ", filename, " File cannot be located. Please check file and try again."
    GOTO 100
  ENDIF
    READ(1,*) lambda
    READ(1,*) n_x
    READ(1,*) n_0
    READ(1,*) L
    READ(1,*) m
  CLOSE(1)

! Output File Contents

   WRITE(*,*) 'Wavelength = ' , lambda
   WRITE(*,*) 'Refractive Index Function = ' , n_x
   WRITE(*,*) 'Refractive Index = ' , n_0
   WRITE(*,*) 'Length = ' , L
   WRITE(*,*) 'Grid Point Parameter = ',  m

! Set Variables

   pi = 3.14159265
   exp = 2.71828183
   k = 2 * pi / lambda
   beta = n_0 * k
   step = L / m

! Error Checking

   IF (lambda <= 0) THEN
     WRITE(*,*) "ERROR! Wavelength <= 0"
     GOTO 100
   ENDIF

   IF (n_x <= 0) THEN
     WRITE(*,*) "ERROR! Refractive Index Function <= 0"
     GOTO 100
   ENDIF

   IF (n_0 <= 0) THEN
     WRITE(*,*) "ERROR! Refractive Index <= 0"
     GOTO 100
   ENDIF

  IF (L <= 0) THEN
     WRITE(*,*) "ERROR! Length <= 0"
     GOTO 100
   ENDIF

  IF (m <= 2) THEN
     WRITE(*,*) "ERROR! Grid Point Parameter < 2"
     GOTO 100
   ENDIF
! Bulk Coding

   numEq = m + 3
   WRITE(*,*) 'Step Size = ', step

   ALLOCATE(mat(numEq,numEq), vec(numEq), x(m), &
            mat_r(numEq,numEq), vec_r(numEq), a(m-1), &
            mat_i(numEq,numEq), vec_i(numEq), b(m-1), &
            IPIV(numEq), STAT=allocate_status)

   CALL cpu_time(start_time)

! Initialise Matrices and Vectors

   mat = 0.0d0
   mat_r = 0.0d0
   mat_i = 0.0d0
   vec = 0.0d0
   vec_r = 0.0d0
   vec_i = 0.0d0

   DO i=0, m
     x(i) = i * step
   ENDDO

   DO i=1, m-1
     a(i) = -2+(step**2)*(n_x**2)*(k**2)
     b(i) = 1
   ENDDO

   i=1
     mat_r(i,i) = -1
     mat_r(i+1,i) = 1
   DO i=2,m
     mat_r(i-1,i) = b(i-1)
     mat_r(i,i) = a(i-1)
     mat_r(i+1,i) = b(i-1)
   ENDDO
   i=m+1
     mat_r(i-1,i) = -1
     mat_r(i,i) = 1
     mat_r(1,i+1) = 1
     mat_r(i+1,i+1) = -1
     mat_r(i,i+2) = 1

   ! Input value to imaginary mat
   i=1
     mat_i(numEq-1,i) = step * beta
   i=m+1
     mat_i(numEq,i) = -step * beta * (exp**(beta * L))
     mat_i(numEq,i+2) = -exp**(beta * L)

   ! Input value to real and imaginary vec
   vec_r(numEq-1) = 1
   vec_i(1) = step * beta

   ! Combine real and imaginary data to mat and vec
   mat = mat_r+(0.0d0, 1.0d0)*mat_i
   vec = vec_r+(0.0d0, 1.0d0)*vec_i

   ! Formatting fmt
   write(int_char,*) numEq
   FMT = "(" // TRIM(ADJUSTL(int_char)) // "(' (',f10.4,',',f10.4,') '))"

   IF (numEq <= 10) then
     WRITE(*,*) "Matrix (A):"
     WRITE(*,FMT) mat
     WRITE(*,*) "Vector (B):"
     WRITE(*,FMT) vec
   ENDIF

! Solve

   NRHS = 1
   LD_mat = numEq
   LD_vec = numEq
   CALL ZGESV(numEq, NRHS, mat, LD_mat, IPIV, vec, LD_vec, INFO)

   IF (numEq <= 10) then
     WRITE(*,FMT) vec
   ENDIF

   CALL cpu_time(end_time)

   WRITE(*,*) "Run time = ", end_time - start_time

   ! Saving the solution
   OPEN(2, file='solution.txt', status='unknown', IOSTAT=IO_status)
     IF (IO_status /= 0) then
       WRITE(*,*) "Error opening the file solutions.txt"
       GOTO 100
     ELSE
       i=numEq-1
         WRITE(2,'(2(f20.15))') 'r = ', vec(i)
       i=numEq
         WRITE(2,'(2(f20.15))') 't = ', vec(i)
     ENDIF
   CLOSE(2)

   100 CONTINUE

END PROGRAM 1001
 
The ZGESV is a function in your MAIN routine.

I'm not a FORTRAN coder (VB,C,C++,ASM, not FORTRAN), but my guess is that you need to basically declare your function.

I'm guessing that the routine is part of your library. Based on that you will probably have to provide an external reference in your code.

What should happen is with the reference, your code will compile the code into an object file. Then when you use the linker, it will search for all variables, functions and so on, and link everything together into your executable. This is standard procedure for any type of executable code and is independent of the language used (FORTRAN, C, C++ etc).

I just looked up some FORTRAN doc and it said that there is an EXTERNAL keyword. I'm guessing that's what you need to use.
 
Your code looks OK to me.

Just putting the libraries in your current directory is not enough. You have to tell the compiler to search them as well.

You need to do something like
f77 myfile.f -l lapack_LINUX.a -l liblapack_LINUX.a -l blas_LINUX.a

Note, I don't use Linux, so that may not be exactly right, but most compilers have similar options.

There should be an example in the library documentation of what to do, or look at the documentation of your compiler to see how to include routines from libraries.

If you are using "make", you should be able to set a variable in your makefile to the list of libraries you want to search.
 
Ok this thread is old but... At least for gfortran (and I strongly believe that for ifortran too): Never start your first line with "program nameofprogram" where nameofprogram contains numbers. :/ You'll get an error when compiling, so it won't compile.
 

Similar threads

  • · Replies 2 ·
Replies
2
Views
3K
  • · Replies 14 ·
Replies
14
Views
5K
  • · Replies 22 ·
Replies
22
Views
5K
  • · Replies 4 ·
Replies
4
Views
7K
  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 1 ·
Replies
1
Views
6K
  • · Replies 15 ·
Replies
15
Views
2K
  • · Replies 1 ·
Replies
1
Views
8K
  • · Replies 13 ·
Replies
13
Views
2K
  • · Replies 4 ·
Replies
4
Views
2K