Use lapack's dgemm (linker error) - fortran

How can I multiply two matrices by Lapack package for Fortran? I use gfortran compiler in ubuntu.
My code which doesn't work is:
program main
integer, parameter :: n = 10
double precision :: alpha = 1.0, beta = 0.0
real, dimension(10,10) :: a
do i1 = 1,n
do j1 = 1,n
a(i1,j1) = j1 + (i1-1)*n
end do
end do
call cpu_time(start)
call DGEMM('N', 'N', n, n, n, alpha, a, n, a, n, beta, a, n)
call cpu_time(end)
print *, end - start
end program main
I used:
gfortran 0.f90 -llapack
It returned:
/tmp/ccPy78g5.o: In function `MAIN__':
0.f90:(.text+0x110): undefined reference to `dgemm_'
collect2: ld returned 1 exit status

The error message means, that your compiler (gfortran) cannot find lapack or rather dgemm. Please make sure, that lapack is in your path. Alternatively (I assume you are using Ubuntu Linux) you could try -lblas instead (after installing it, of course - afaik ubuntu follows a different naming convention):
gfortran 0.f90 -lblas -llapack
Edit
Alternatively, you may pass the path to the library directly as an argument. By default, gfortran will look in `/usr/local/lib/``for the specified libraries. If the library is located somewhere else, you may instead use something like
gfortran 0.f90 /path/to/my/library.a

Related

Using FFTW3 Fortran library in MacOS

I am getting the following error while trying to compile a Fortran program with gfortran and FFTW3 library. The program however compiles successfully with the Intel compiler ifort.
Error
Undefined symbols for architecture x86_64:
"__gfortran_os_error_at", referenced from:
_MAIN__ in ccAVlghr.o
ld: symbol(s) not found for architecture x86_64
Compile Command
gfortran -I/usr/local/include -L/usr/local/lib pois.f90 -lfftw3 -lm
pois.f90 is the program which contains FFTW3 commands to solve a Poisson equation through Fourier transform.
The equivalent C program also compiles and executes successfully. The FFTW3 statements are inserted in Poisson.f90 as per FFTW3 documents. The routine which uses FFTW3 commands is given below
subroutine fft_forward(j,f,Fr,Fi)
use, intrinsic :: iso_c_binding
implicit none
include 'fftw3.f03'
double precision :: f(j),Fr(j),Fi(j)
integer :: i,j
type(C_PTR) :: plan
complex(C_DOUBLE_COMPLEX) :: FF(j)
plan = fftw_plan_dft_r2c_1d(j,f,FF,FFTW_ESTIMATE)
call fftw_execute_dft_r2c(plan,f,FF)
call fftw_destroy_plan(plan)
do i = 1,j
Fr(i) = real(FF(i))/j
Fi(i) = aimag(FF(i))/j
enddo
Fr = Fr/j; Fi = Fi/j
end
I also tried using a compiler flag -lgfortran but got the same error. Any suggestion will be of great help.
It probably depends on what you did while installing GNU Fortran, FFTW, et al.
In my case, it works as expected.
I have GNU Fortran installed from sources: gcc-9-2-0
Then, I have built FFTW using my own installation of GNU Fortran
./configure --prefix=$HOME/opt/usr/local/fftw/fftw-3.3.10 CC=gcc-9.2.0 MPICC=mpicc F77=gfortran-9.2.0
make
make install
and then, I have compiled your sample using
gfortran-9.2.0 -I$HOME/opt/usr/local/fftw/fftw-3.3.10/include -L$HOME/opt/usr/local/fftw/fftw-3.3.10/lib -lfftw3 -lm -c simple.f90
I have also added short _main stuff like so to double check it links with the stuff
program main
print *, 'Hello'
end program main
after building, it runs as expected
gfortran-9.2.0 -I$HOME/opt/usr/local/fftw/fftw-3.3.10/include -L$HOME/opt/usr/local/fftw/fftw-3.3.10/lib -lfftw3 -lm simple.f90 -o main
./main
Hello
I guess you have sort of a messy GNU Fortran + FFTW installation.

Fortran undefined reference, collect2.exe: error: ld returned 1 exit status [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it in Fortran?
(5 answers)
Fortran 90 compiling issue: undefined reference to <modulename>
(1 answer)
Closed 1 year ago.
I am trying to write two simple functions, one which contains the definition of a real function and the other one uses the previous function to find its derivative. However i keep getting the undefined reference error.
my module:
module module_name
contains
function f(x)
implicit none
real(8) :: x
real(8) :: f
f= 2.71**x
endfunction
function f_p_def(x)
implicit none
real(8) :: x, dx, f
real(8) :: f_p_def
dx= 0.1
f_p_def= (f(x+dx)-f(x))/dx
endfunction
endmodule
then in my main program I have this:
program test
use module_name
real(8) :: f1, x
x=0
f1= f_p_def(x)
write(*,*) f1
endprogram
and this is the error:
.\principal.o:principal.f95:(.text+0x27): undefined reference to `__module_name_MOD_f_p_def'
collect2.exe: error: ld returned 1 exit status
Seems like you have your module defined in a separate file. This means that when producing the final executable you must add the object file as well.
EDIT To clarify, you need to compile each source file, producing an object file. Then at the end you link them together. The compiler driver program (gfortran in this case) can run the linker for you automatically.
Separating out all these steps, you need to do something like:
gfortran -O2 -g -fcheck=all -c principal.f95
gfortran -O2 -g -fcheck=all -c module_name.f95
gfortran -O2 -g -fcheck=all principal.o module_name.o -o myprogram
./myprogram
where module_name.f95 is the name of the file where module_name is defined. If not, modify appropriately. In the above, the first two commands compile the source files, producing object files. The third command doesn't actually compile anything, but rather links together your two object files, producing the executable. Then the final command executes the executable.

Fortran and FFTW3

I am learning how to call fftw from fortran. My test program is the following:
Program Single_Thread_FFTW
use, intrinsic :: iso_c_binding
implicit none
integer, parameter :: N=16
type (c_ptr) :: plan_forward
integer :: k
complex (kind=8) :: in(N), out(N)
include 'fftw3.f03'
in=(/(sin(3.14159d0*k),k=1,N)/)
print *,in
plan_forward=fftw_plan_dft_1d(N,in,out,FFTW_FORWARD,FFTW_ESTIMATE)
call fftw_execute_dft(plan_forward,in,out)
print *,out
call fftw_destroy_plan(plan_forward)
End Program Single_Thread_FFTW
The first confusion came about because the fftw website suggests all the fftw call should be prefaced with the letter d, as in 'dfftw_plan_dft_1d'. However none of the functions/subroutines in fftw3.f03 (located in /usr/include) have the d prefix. When I try to compile/link with either
gfortran -I/usr/include -o example1 example1.f90 or
gfortran -I/usr/include -L/usr/lib/x86_64-linux-gnu -o example1 example1.f90
the linker throws the errors:
example1.f90:(.text+0xf3): undefined reference to `fftw_plan_dft_1d'
example1.f90:(.text+0x114): undefined reference to `fftw_execute_dft'
example1.f90:(.text+0x1cc): undefined reference to `fftw_destroy_plan'
even though the libraries are in /usr/lib/x86_64-linux-gnu. A separate point is that I would like to lear how to declare double precision complex variables without using the (kind=8) modifier. My compiler (gfortran) doesnt know about double complex.

Undefined reference to LAPACK and BLAS subroutines

I'm trying to understand how BLAS and LAPACK in Fortran work and so on, so I made a code that generates a matrix and inverts it.
Here's the code
program test
Implicit none
external ZGETRF
external ZGETRI
integer ::M
complex*16,allocatable,dimension(:,:)::A
complex*16,allocatable,dimension(:)::WORK
integer,allocatable,dimension(:)::IPIV
integer i,j,info,error
Print*, 'Enter size of the matrix'
Read*, M
Print*, 'Enter file of the matrix'
READ(*,*), A
OPEN(UNIT=10,FILE = '(/A/)' ,STATUS='OLD',ACTION='READ')
allocate(A(M,M),WORK(M),IPIV(M),stat=error)
if (error.ne.0)then
print *,"error:not enough memory"
stop
end if
!definition of the test matrix A
do i=1,M
do j=1,M
if(j.eq.i)then
A(i,j)=(1,0)
else
A(i,j)=0
end if
end do
end do
call ZGETRF(M,M,A,M,IPIV,info)
if(info .eq. 0) then
write(*,*)"succeded"
else
write(*,*)"failed"
end if
call ZGETRI(M,A,M,IPIV,WORK,M,info)
if(info .eq. 0) then
write(*,*)"succeded"
else
write(*,*)"failed"
end if
deallocate(A,IPIV,WORK,stat=error)
if (error.ne.0)then
print *,"error:fail to release"
stop
end if
close (10)
end program test
The matrix A is in a file, which I'm calling, and also I say the size of the matrix (M ). When I copile them with gfortran I get these message
/tmp/ccVkb1zY.o: In function MAIN__':
test.f03:(.text+0x751): undefined reference tozgetrf_'
test.f03:(.text+0x85d): undefined reference to `zgetri_'
collect2: error: ld returned 1 exit status
I have installed BLAS and LAPACK installed so I don't know if I'm calling in a right way the library.
Any suggestion?
It looks like you might not have linked to the libraries. Try:
gfortran -o test test.f03 -llapack -lblas
This causes the linker (the program which joins all the program parts together; usually called "ld" on UNIX) to include the library code for the LAPACK call (or a dynamic link to it) in your program.
If the result of the above line is "cannot find -llapack" or similar, there are two common problems:
Libraries can be "shared" (names ending ".so") or "static" (names ending ".a"); the linker will look for the shared one, so if you only have the static one you should add "-static" before the library link:
gfortran -o test test.f03 -static -llapack -lblas
This will also make it look for the static version of BLAS; if you need the shared version, add "-shared" in front of the "-lblas":
gfortran -o test test.f03 -static -llapack -shared -lblas
You might find this page helpful.
The linker isn't looking in the right directory for the libraries. You need to locate the actual library (called something like "liblapack.so" or "liblapack.a") and make sure the directory it's in is included in the directories the linker looks in, e.g. to get it to look in "/mylibs/maths" as well:
gfortran -o test test.f03 -L/mylibs/maths -llapack -lblas

Error in linking gfortran to LAPACK and BLAS

I have installed LAPACK and BLAS from Synaptic package manager in Ubuntu.
whereis libblas
libblas: /usr/lib/libblas.so /usr/lib/libblas.a /usr/lib/libblas
whereis liblapack
liblapack: /usr/lib/liblapack.a /usr/lib/liblapack.so
When I try to compile the randomsys1 example with gfortran I get the following error messages.
gfortran randomsys1.f90 -L/usr/lib/lapack -llapack -L/usr/lib/libblas -lblas
/tmp/cclwtifh.o: In function `MAIN__':
randomsys1.f90:(.text+0x12): undefined reference to `init_random_seed_'
collect2: error: ld returned 1 exit status
or
gfortran randomsys1.f90 -llapack -lblas
/tmp/ccB1isEC.o: In function `MAIN__':
randomsys1.f90:(.text+0x12): undefined reference to `init_random_seed_'
collect2: error: ld returned 1 exit status
As per my understanding, it is the recommended way to link gfortran with lapack and blas (kindly refer to gfortran LAPACK “undefined reference” error). Thanks in advance for pointing out the correct way to compile the fortran code using gfortran.
Give this a try
gfortran randomsys1.f90 -L/usr/lib -llapack -L/usr/lib -lblas
I think you went one directory too far
I wrote a program using the LAPACK eigensolver and here is how I successfully compiled it on my own computer. It was used to calculate modes of a spring-mass system.
gfortran eigen.f90 -L/usr/local/lib -lblas -L/usr/local/lib -llapack
This also works on my computer
gfortran eigen.f90 -lblas -llapack
I just tried both to verify.
PS, now that you know how to compile, I think you need the subroutine init_random_seed in your program (goes after "contains" but before "end program"). This one is from google. No idea if it is what you need, your professor should be able to steer you correctly here.
! Initialize the random number generator using current time,
! so a new sequence of random numbers is generated each
! execution time.
! Taken from http://gcc.gnu.org/onlinedocs/gfortran/RANDOM_005fSEED.html
SUBROUTINE init_random_seed()
INTEGER :: i, n, clock
INTEGER, DIMENSION(:), ALLOCATABLE :: seed
CALL RANDOM_SEED(size = n)
ALLOCATE(seed(n))
CALL SYSTEM_CLOCK(COUNT=clock)
seed = clock + 37 * (/ (i - 1, i = 1, n) /)
CALL RANDOM_SEED(PUT = seed)
print *, "Using random seed = ", seed
print *, " "
DEALLOCATE(seed)
END SUBROUTINE
I had the same problem. I followed the recommendation above and
it worked. Here's my working example batch file (it has to be executed
in the cmd window):
gfortran -c for\kurs_evd.f90
gfortran -o kurs_evd.exe kurs_evd.o charint.o -L/usr/lib -llapack -L/usr/lib -lblas
kurs_evd.exe