How to use IMSL library in gfortran in Code::Blocks?
I had a problem with my program after the building them.
The message after building was:
undefined reference to `linrg_'
My code is:
Program Fitovanje_krive
Implicit none
integer::i,j,k,n
Integer,parameter::iBrTac=24
Integer,allocatable::vreme(:),potrosnja(:)
Real,allocatable::X(:,:),Y(:,:),P(:,:),Xinv(:,:)
allocate(vreme(iBrTac),potrosnja(iBrTac))
vreme(1:iBrTac)=(/1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24/)
potrosnja(1:iBrTac)=(/20,30,20,30,40,50,50,60,70,80,90,100,80,60,50,30,20,40,40,30,30,20,40,40/)
n=10
allocate(X(n+1,n+1),Y(n+1,1),P(n+1,1),Xinv(n+1,n+1))
do i=1,n+1
do j=1,n+1
X(i,j)=0.
Y(i,j)=0.
do k=1,iBrTac
X(i,j)=X(i,j)+vreme(k)**(i+j-2)
Y(i,1)=Y(i,1)+potrosnja(k)*vreme(k)**(i-1)
end do
end do
end do
Call Linrg(n+1,X,n+1,Xinv,n+1)
P=matmul(Xinv,Y)
Stop
End program Fitovanje_krive
Related
I'm working on a problem for one of my computing courses and I was getting stuck in an error after trying to work through it for some time.
Specifically, I'm working on this Fortran routine:
program linsolve_sgtsv
implicit none
integer, parameter :: lda=10,ldb=lda,nrhs=1
real :: dl(lda-1),d(lda),du(lda-1),b(ldb,nrhs)
integer :: n,info
n = 10
dl(1:n-1) = 1+(1/11); d(1:n) = 2; du(1:n-1) = 1-(1/11)
b(1:n,1) = (/1,1,1,1,1,1,1,1,1,1/)
call sgtsv(n,nrhs,dl,d,du,b,ldb,info)
if (info==0) then
print *, '--- x is ----------------'
print '(g22.16)', b(1:n,1)
else
print *, 'info = ',info
end if
end program linsolve_sgtsv
This routine solves linear systems using gaussian elimination when the matrices are tridiagonal.
However, when I try to create a makefile using:
gfortran linsolve_sgtsv.f90 -o linsolve.f90
I get the following errors:
tmp/ccCiRHve.o: In function `MAIN__':
linsolve_sgtsv.f90:(.text+0x100): undefined reference to `sgtsv_'
collect2: error: ld returned 1 exit status
I can't find any direct duplicate. Many people have similar problems, but they usually know a bit more and your question is more basic.
The tridiagonal solver sgtsv() is not a Fortran built-in subroutine. It is provided in a library called LAPACK and many other implementations (e.g., MKL). That means you must tell the compiler it should include (link) that library.
That is done by adding -llapack (-l means "link" and lapack is the name of the library which is stored in a file called liblapack.so or liblapack.a) at the end of the compile command.
You must have his library installed in your computer for the link flag to work. In many Linux distributions it is included in the repositories.
The correct line would be
gfortran linsolve_sgtsv.f90 -o linsolve -llapack
If the library (liblapack.a or liblapack.so) is installed in some directory the compiler can't see, you must use
gfortran linsolve_sgtsv.f90 -o linsolve -L/path/to/liblapack -llapack
See also gfortran LAPACK "undefined reference" error and your compiler's manual for more.
Notice I did -o linsolve instead of -o linsolve.f90. It is a very bad idea to name your executable file with a .f90 extension. Only Fortran source files should be named .f90.
There will be more problems in your code. They will appear when you start to test it. For example, yoy do
(1/11)
this will not return the mathematical result of 1.0/11.0, it will return 0. Learn about integer division in Fortran. See Why are the elements of an array formatted as zeros when they are multiplied by 1/2 or 1/3? and Simple program, that only produce zeros, bug?
If you will find more problems after you can run your code, you can ask a new question.
I recommend to compile your programs with -g -fcheck=all -Wall to find more bugs and errors more easily.
I am new to using the Math Kernel Library(mkl). I have a program that uses a system-of-linear-equations-solver( gesv routine) of LAPACK (which comes with MKL). I already have MKL (also Intel Parallel Studio XE) installed on my computer. I am having trouble compiling/linking the code. I compile the code using:
ifort -mkl matrixinv.f90
However, it gives the following error
/tmp/ifortjcXZTm.o: In function `MAIN__':
matrixinv.f90:(.text+0xdf): undefined reference to `gesv_'
The code is attached below
PROGRAM matrixinv
IMPLICIT NONE
REAL(8),DIMENSION(3,3)::A,C
INTEGER(4),DIMENSION(3)::IPVT
REAL(8)::RCOND
REAL(8),DIMENSION(3)::V,B
A(1,1)=3.0_8
A(1,2)=2.0_8
A(1,3)=-1.0_8
A(2,1)=2.0_8
A(2,2)=-2.0_8
A(2,3)=4.0_8
A(3,1)=-1.0_8
A(3,2)=0.5_8
A(3,3)=-1.0_8
B(1)=1.0_8
B(2)=-2.0_8
B(3)=0.0_8
call gesv(A,B)
PRINT*,B
END PROGRAM matrixinv
You probably want to declare gesv as external. Add the following statement after the "implicit none":
external gesv
I am using gfortran compiler and ld linker in LINUX ubuntu 16.04.
When I am compiling some program written in Fortran 77, I have the following error message:
libdist.a(setup.F.o): In function `setup_':
setup.F:(.text+0x26c4): undefined reference to `mpi_send_'
setup.F:(.text+0x2b3c): undefined reference to `mpi_recv_'
setup.F:(.text+0x7984): undefined reference to `mpi_send_'
setup.F:(.text+0xb107): undefined reference to `mpi_recv_'
I guess it is about the position of error. However, it is difficult to me the find where is the error.
Can I have a better presentation of the position of error? Such as the c/cxx error: "setup.F:15:12: "
It is an address. And is is NOT a Fortran error. It is a linker error. You can get the very same error from a C or C++ code or any other compiled code linked by the same linker.
Generate debugging symbols (compiler option -g or -ggdb or similar - consult Debugging options in the GCC Fortran manual) to get something more meaningful. But if you do that you will realize that it only points you to some location where you do:
call mpi_send(...)
in some subroutine or function called setup().
So, it is not terribly useful in this case. The important thing is that you should link the appropriate MPI library. Normally that is done by calling mpif90 or mpifort or a similar wrapper which is called instead of gfortran. Consult the documentation of your MPI library implementation.
Background: I am in a situation where I have to make use of an old Fortran95 library in a new C++ project. The F95 library is extensive, has tons of small modules, poorly documented, and it was mostly auto-generated about a decade ago by some obscure computer algebra system (by people on a different continent). So basically heirloom code, but it works and it is currently irreplaceable.
Luckily I have the source code and it can be compiled with current versions of ifort, but I am not too familiar with Fortran, and would rather not touch the old code in any significant way.
So suppose I have this Fortran code (pes_shell.f90):
subroutine pes_init()
use pes,wp=>pes_wp
implicit none
real,parameter::auang=0.5291772083
call pes0_init (dir='coef')
call pes1_init (pes_x3y1z1u1_sysall)
return
end subroutine pes_init
The functions pes0_init(...) and pes1_init(...) lead into the abyssal depths of the Fortran library and they are contained in the pes module.
I can compile this to an object file, if I give ifort the path for the modules:
ifort -r8 -O2 -c pes_shell.f90 -I/home/debianuser/PES/PES_library/lib/mod
My POC C++ code, calling pes_init():
extern "C"{
void pes_init_();
}
int main(){
pes_init_();
return 0;
}
This can also be compiled to an object file, with icpc:
icpc -c PEStest.cpp
However I cannot figure out how to link the two object files, plus the truckload of fortran modules, into a final executable.
I have tried just simply using icpc, but it cannot seem to be able to find the Fortran functions, even if I give it the location of the module files:
icpc -I/home/debianuser/PES/PES_library/lib/mod -o test.x pes_shell.o PEStest.o
pes_shell.o: In function `pes_shell_mp_f_':
pes_shell.f90:(.text+0x595): undefined reference to `pes_x3y1z1u1_mp_pes_x3y1z1u1_pot_'
pes_shell.o: In function `pes_shell_mp_pes_init_':
pes_shell.f90:(.text+0x5f0): undefined reference to `pes0_mp_pes0_init_'
pes_shell.f90:(.text+0x603): undefined reference to `pes1c_mp_pes1_init_'
PEStest.o: In function `main':
PEStest.cpp:(.text+0x2b): undefined reference to `pes_init_'
EDIT:
Pointing the linker to the directory where libpes.a can be found eliminates the problem of locating the function that was referenced in the c++ code, but icpc still cannot find the fortran functions that are being called from fortran codes:
icpc -I/home/debianuser/PES/PES_library/lib/mod -L/home/debianuser/PES/PES_library/lib/pes-xyz -lpes -o test.x PEStest.o pes_shell_new.o
pes_shell_new.o: In function `f_':
pes_shell_new.f90:(.text+0x585): undefined reference to `pes_x3y1z1u1_mp_pes_x3y1z1u1_pot_'
pes_shell_new.o: In function `pes_init_':
pes_shell_new.f90:(.text+0x5e0): undefined reference to `pes0_mp_pes0_init_'
pes_shell_new.f90:(.text+0x5f3): undefined reference to `pes1c_mp_pes1_init_'
I am trying to use FFTW3 with gfortran compiler included in the TDM-GCC-64 suite in Windows 7 platform.
I have downloaded "fftw-3.3.4-dll64.zip" from the following page:
http://www.fftw.org/install/windows.html
I also created a fortran module described in the following tutorial:
http://www.fftw.org/doc/Defining-an-FFTW-module.html
Now, I tried to compile the following fortrans program
program test
use FFTW3
implicit none
integer N
parameter(N=4)
integer*8 plan
double complex in, out
dimension in(N),out(N)
integer i
write(*,*) 'Input array:'
do i = 1,N,1
in(i) = dcmplx(float(i),float(i+1))
write(*,*) ' in(',i,') = ',in(i)
enddo
call dfftw_plan_dft_1d ( plan, N, in, out, FFTW_FORWARD, FFTW_ESTIMATE )
call dfftw_execute ( plan )
write(*,*) 'Output array:'
do i = 1,N,1
write(*,*) ' out(',i,') = ',out(i)
enddo
call dfftw_destroy_plan ( plan )
call dfftw_plan_dft_1d ( plan, N, out, in, FFTW_FORWARD, FFTW_ESTIMATE )
call dfftw_execute ( plan )
write(*,*) 'Output array after inverse FFT:'
do i = 1,N,1
write(*,*) ' ',N,' * in(',i,') = ',in(i)
enddo
call dfftw_destroy_plan ( plan )
end
I tried to compile but the a couple of error messages popped up:
undefined reference to dfftw_plan_dft_1d_'
undefined reference todfftw_execute_'
...
The command used for compiling is:
gfortran test.f90 -ffree-form -o test_fftw.exe
I searched web up and down but have not found solutions to the problem. Could anyone help me out here? Thanks!!!
You need to learn the basics of compiling and linking programs with GCC
This tutorial refers to the GCC C compiler, gcc, and C++ compiler, g++, but the principles are the same for the Fortran compiler, gfortran.
Your program invokes functions, like dfftw_plan_dft_1d that are not defined
in your code but in the fftw3 library. You must therefore tell gfortran
to link that library with your program, after it is compiled, or no definitions will be found for
these functions, and no executable can be built. Instead, the linkage
fails with the undefined reference errors you are seeing.
The command you have used to build the program:
gfortran test.f90 -ffree-form -o test_fftw.exe
attempts to compile and link the program in a single command. You can do this,
if you clearly understand the underlying separate processes of compiling
and linking. If you don't, you should follow the better practice of compiling first,
and if that is successful, then linking. The command you have used fails in
its linkage step because it does not tell the linker that the fftw3 library
is needed (or where to find it) so no attempt is made to find it and link it.
You say you have downloaded fftw-3.3.4-dll64.zip. I presume you have
unzipped it somewhere on your system. Let's say you unzipped it to C:\fftw-3.3.4-dll64.
You also say you have made an FFTW3 module that apparently is being used successfully.
In that case, compile your program first:
gfortran -c -o test.o test.f90
generating an object file test.o. The option -c tells gfortran to compile only,
and not to link. (You do not need to specify --ffree-form: the file-extension .f90
implies it).
Next, link the object file test.o with the fttw3 library, to make an executable
program test_fftw.exe:
gfortran -o test_fftw.exe test.o -LC:\fftw-3.3.4-dll64 -lfftw3-3
The linker option:
-LC:\fftw-3.3.4-dll64
tells the linker to add C:\fftw-3.3.4-dll64 (where you unzipped the package)
to the list of directories that it will search to find libraries. And the linker option -lfftw3-3 tells it to link a library that matches the identifier fftw3-3. On Windows, the GCC linker
will match a library identfier name with any of the filenames:
libname.a (a static library)
libname.dll (a shared library)
name.dll (also a shared library)
name.lib (an import library for a shared library)
So, since C:\fftw-3.3.4-dll64 contains the shared library libfftw3-3.dll,
the linker will identify it in that directory as the one required by -lfftw3-3
Now, unless there are other problems, you program will link and you will have
an executable test_fftw.exe, which will run, provided that libfftw3-3.dll
can be found, at runtime, in one of the places where the Windows
loader will look for it.