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

Problems with reference Math kernel Library

felipin85
Beginner
699 Views
Hi, I'm using Ubuntu 10.04, and Intel Fortran ComposerXe 2011.I try using mkl, but I get a reference failure.:

felipe@felipe-desktop:~/Escritorio/Carpeta sin ttulo$ ifort PRUEBARESOLVER.f90 -o PRUEBA
/tmp/ifortGlnEnU.o: In function `MAIN__':
PRUEBARESOLVER.f90:(.text+0x35d): undefined reference to `getrf_'



My code to probe is:

PROGRAM PRUEBARESOLVER
IMPLICIT NONE
INTEGER :: i
REAL,DIMENSION (3,3) :: A
REAL,DIMENSION (3) :: B
REAL,DIMENSION (3) :: X
X=0.0
WRITE(*,*)'ESCRIBIMOS LA MATRIZ A POR FILAS'
DO i=1,3
READ(*,*) A(i,1),A(i,2),A(i,3)
END DO
WRITE(*,*)'ESCRIBIMOS LA MATRIZ LD POR FILAS'
DO i=1,3
READ(*,*) B(i)
END DO
!Resolvemos
CALL getrf(A)
write(*,*) A
END PROGRAM PRUEBARESOLVER


My bash is:
# Variables de entorno para compilador, libreria y debugger de intel
source /opt/intel/composerxe-2011/bin/compilervars.sh ia32

#PATH="/opt/intel/composerxe-2011/bin:$PATH"
#export PATH
#LD_LIBRARY_PATH="/opt/intel/composerxe-2011/lib/ia32:$LD_LIBRARY_PATH"
#export LD_LIBRARY_PATH
PATH="/opt/intel/composerxe-2011/bin:$PATH"
export PATH
LD_LIBRARY_PATH="/opt/intel/composerxe-2011/lib/ia32:$LD_LIBRARY_PATH"
export LD_LIBRARY_PATH
LD_LIBRARY_PATH="/opt/intel/composerxe-2011/mkl/lib/ia32:$LD_LIBRARY_PATH"
export LD_LIBRARY_PATH


PATH=$PATH:/home/felipe/Matlab/bin
export PATH



I think that, my problem is in the bash. How Can I solver it?
Thanks


0 Kudos
1 Solution
John4
Valued Contributor I
699 Views

The fact that the program was not written for Fortran 77 might not be relevant anymore (after all, code written in fixed-source is still Fortran 90+ code).

The error you're having is given by the linker, not the compiler. Your particular code needs three things in order to make it work:

Add the "USE LAPACK95" statement before the implicit none. That way the compiler will know where the GETRF subroutine comes from, and will not defer its resolution to the linker.

[fortran]PROGRAM PRUEBARESOLVER
USE LAPACK95
IMPLICIT NONE
INTEGER :: i
REAL,DIMENSION (3,3) :: A
REAL,DIMENSION (3) :: B
REAL,DIMENSION (3) :: X
X=0.0
WRITE(*,*)'ESCRIBIMOS LA MATRIZ A POR FILAS'
DO i=1,3
READ(*,*) A(i,1),A(i,2),A(i,3)
END DO
WRITE(*,*)'ESCRIBIMOS LA MATRIZ LD  POR FILAS'
DO i=1,3
READ(*,*) B(i)
END DO
!Resolvemos 
CALL getrf(A)
write(*,*) A
END PROGRAM PRUEBARESOLVER
[/fortran]

Your .bashrc file only needs "source /opt/intel/composerxe-2011/bin/compilervars.sh ia32" (try using a . instead of source); the compilervars.sh script takes care of also invoking mklvars.sh if it exists, and it also takes care of exporting the PATH and LD_LIBRARY_PATH, so that you don't have to. The only convenient environment variables you might need are MKLPATH and MKLINCLUDE. The Intel-related portion of your .bashrc should look like:

[bash]#IFC and MKL XE 2011
. /opt/intel/composerxe-2011/bin/compilervars.sh ia32
MKLPATH="$MKLROOT/lib/ia32"; export MKLPATH
MKLINCLUDE="$MKLROOT/include/ia32"; export MKLINCLUDE
[/bash]
To compile your code, you need to instruct the compiler where to find the lapack95.mod (with the -I switch) and tell the linker where to find the libraries (with the -L switch), and which libraries to use (with either the -l switch or using the full path). Since, for reasons unknown, Intel doesn't provide a shared object of the Lapack library, your only option is to use the archive version, which requires listing the libraries in the exact dependency order and/or grouping them so that they can be used multiple times to solve dependencies. Your compile line should look something like:

[bash]~$ ifort -o pruebaresolver -I$MKLINCLUDE -L$MKLPATH pruebaresolver.f90 -lmkl_lapack95  
-Wl,--start-group $MKLPATH/libmkl_intel.a $MKLPATH/libmkl_intel_thread.a $MKLPATH/libmkl_core.a -Wl,--end-group
-liomp5 -lpthread [/bash]
For future reference, you might want to check the MKL documentation (in your"/opt/intel/composerxe/Documentation//mkl" directory).



View solution in original post

0 Kudos
5 Replies
mecej4
Honored Contributor III
699 Views
How Can I solve it?

Read the MKL documentation, look at the example programs, and issue a proper call to GETRF. Use the modules provided with MKL to enable the compiler to compare your usage with the interface to GETRF.

Given that GETRF is an interface name that matches different procedures depending on the argument list, you should not expect a Fortran-77 style implicit interface to work at all.
0 Kudos
felipin85
Beginner
699 Views
Quoting mecej4
How Can I solve it?

Read the MKL documentation, look at the example programs, and issue a proper call to GETRF. Use the modules provided with MKL to enable the compiler to compare your usage with the interface to GETRF.

Given that GETRF is an interface name that matches different procedures depending on the argument list, you should not expect a Fortran-77 style implicit interface to work at all.

Hi mecej4! In first place, I'm new in Linux, this is a big problem; but I read the documentation, and I change a bashrc, and I still have the same problem. The function GETRF was using for test, but my idea is using sparse subrutines, but I have a problems with call. My programas was wrote in fortran 95,not in 77.

Tha bash modified is:


# Variables de entorno para compilador, libreria y debugger de intel
source /opt/intel/composerxe-2011/bin/compilervars.sh ia32
source /opt/intel/mkl/bin/mklvars.sh ia32

#PATH="/opt/intel/composerxe-2011/bin:$PATH"
#export PATH
#LD_LIBRARY_PATH="/opt/intel/composerxe-2011/lib/ia32:$LD_LIBRARY_PATH"
#export LD_LIBRARY_PATH
PATH="/opt/intel/composerxe-2011/bin:$PATH"
export PATH
LD_LIBRARY_PATH="/opt/intel/composerxe-2011/lib/ia32:$LD_LIBRARY_PATH"
export LD_LIBRARY_PATH
LD_LIBRARY_PATH="/opt/intel/composerxe-2011/mkl/lib/ia32:$LD_LIBRARY_PATH"
export LD_LIBRARY_PATH


PATH=$PATH:/home/felipe/Matlab/bin
export PATH
0 Kudos
mecej4
Honored Contributor III
699 Views
Again, I suggest that you try one of the example problems included with the MKL distribution. Once you succeed in compiling, linking and running a few of these examples, you can proceed to writing your own MKL calls.

You cannot, as a rule, call a library subroutine without giving it the proper type and number of arguments.

I don't know why you are changing the ifortvars.sh script. Once it is working after installation, it is intended to be modified infrequently, if at all.

Here are the steps to get started.

1. Create a working direcory, and copy one of the MKL example source files into it, for example, ddotx.f. If the example needs data, copy the data file as well: ddotx.d.

2. Set up the IFORT environment: (note the dot and space before the name of the shell script)

. /opt/intel/compiler/11/067/bin/ifortvars.sh

3. Compile and link the example:

ifort -mkl ddotx.f

4. Run the example

./a.out < ddotx.d
0 Kudos
John4
Valued Contributor I
700 Views

The fact that the program was not written for Fortran 77 might not be relevant anymore (after all, code written in fixed-source is still Fortran 90+ code).

The error you're having is given by the linker, not the compiler. Your particular code needs three things in order to make it work:

Add the "USE LAPACK95" statement before the implicit none. That way the compiler will know where the GETRF subroutine comes from, and will not defer its resolution to the linker.

[fortran]PROGRAM PRUEBARESOLVER
USE LAPACK95
IMPLICIT NONE
INTEGER :: i
REAL,DIMENSION (3,3) :: A
REAL,DIMENSION (3) :: B
REAL,DIMENSION (3) :: X
X=0.0
WRITE(*,*)'ESCRIBIMOS LA MATRIZ A POR FILAS'
DO i=1,3
READ(*,*) A(i,1),A(i,2),A(i,3)
END DO
WRITE(*,*)'ESCRIBIMOS LA MATRIZ LD  POR FILAS'
DO i=1,3
READ(*,*) B(i)
END DO
!Resolvemos 
CALL getrf(A)
write(*,*) A
END PROGRAM PRUEBARESOLVER
[/fortran]

Your .bashrc file only needs "source /opt/intel/composerxe-2011/bin/compilervars.sh ia32" (try using a . instead of source); the compilervars.sh script takes care of also invoking mklvars.sh if it exists, and it also takes care of exporting the PATH and LD_LIBRARY_PATH, so that you don't have to. The only convenient environment variables you might need are MKLPATH and MKLINCLUDE. The Intel-related portion of your .bashrc should look like:

[bash]#IFC and MKL XE 2011
. /opt/intel/composerxe-2011/bin/compilervars.sh ia32
MKLPATH="$MKLROOT/lib/ia32"; export MKLPATH
MKLINCLUDE="$MKLROOT/include/ia32"; export MKLINCLUDE
[/bash]
To compile your code, you need to instruct the compiler where to find the lapack95.mod (with the -I switch) and tell the linker where to find the libraries (with the -L switch), and which libraries to use (with either the -l switch or using the full path). Since, for reasons unknown, Intel doesn't provide a shared object of the Lapack library, your only option is to use the archive version, which requires listing the libraries in the exact dependency order and/or grouping them so that they can be used multiple times to solve dependencies. Your compile line should look something like:

[bash]~$ ifort -o pruebaresolver -I$MKLINCLUDE -L$MKLPATH pruebaresolver.f90 -lmkl_lapack95  
-Wl,--start-group $MKLPATH/libmkl_intel.a $MKLPATH/libmkl_intel_thread.a $MKLPATH/libmkl_core.a -Wl,--end-group
-liomp5 -lpthread [/bash]
For future reference, you might want to check the MKL documentation (in your"/opt/intel/composerxe/Documentation//mkl" directory).



0 Kudos
felipin85
Beginner
699 Views
Everybody, THANKS. I try automating the process of setting Enviroment Variables with Getting Start 2, page 19, but, all time I get errors. Also, my English is very bad, this is reason I can't understand this manual 100 percent.
But, with people with you, all we can programmer with the best software, Intel Fortran. Thanks.

Note: With John's explication the program run. I don't know because with mecej4 explication don't run, but THANKS.

Regards,

Felipe Rodrguez Fonte
0 Kudos
Reply