Intel® oneAPI Math Kernel Library
Ask questions and share information with other developers who use Intel® Math Kernel Library.

using gcc compile this sample program

Ming_L_1
Beginner
925 Views

I am testing a program which diagnalize a hermitian matrix, using LAPACKE_zheev function describe in the MKL manual.

When I try to compile this program, using gcc myprogram.c command. I got an error message saying that:

 /tmp/cc4Xdq1R.o: In function `diag':

zheev_mkl.c:(.text+0x3c): undefined reference to `LAPACKE_zheev'

collect2: ld returned 1 exit status

I don't know how to solve this problem. I have used fortran zheev(F77) and heev(F90) before, and I succeed in compiling the program. In fortran program I use ifort compiler when using F77 interface I just type ifort myprogram.f . Using F90 interface I have a Makefile which is complicated and not written by myself. I will paste that to provide more information to you.

By the way, in my Unbuntu system, I have only installed the intel fortran composer, i didn't install any C compiler other than gcc and g++.

Here is my C program I want to compile:

 

#include    <complex.h>
#include    <math.h>
#include    <stdlib.h>
#include    <stdint.h>
#include    <stdio.h>
#include    <mkl.h>

lapack_int LAPACKE_zheev( int matrix_order, char jobz, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, double* w );
//hermitian matrix, each row in output is an eigenvector, the input matrix is stored in column-major
void    diag(lapack_complex_double *mat, double *e, lapack_int n)
{
    char    jobz='V';   //also eigenvectors
    char    uplo='U';   //upper triangle
    lapack_int  info;

    info=LAPACKE_zheev(n,jobz,uplo,n,mat,n,e);
    if(info!=0){
        printf("matrix diag fail\n");
        exit(1);
    }

}

int main()
{
    lapack_complex_double *mat;
    double  *e;

    mat=(lapack_complex_double *)malloc(sizeof(lapack_complex_double)*16);
    e=(double *)malloc(sizeof(double)*4);

    mat[0].real=1.0;    mat[0].imag=0.0;
    mat[1].real=1.0;    mat[1].imag=-1.0;
    mat[2].real=1.0;    mat[2].imag=-2.0;
    mat[3].real=1.0;    mat[3].imag=-3.0;
    mat[4].real=1.0;    mat[4].imag=1.0;
    mat[5].real=2.0;    mat[5].imag=0.;
    mat[6].real=1.0;    mat[6].imag=-4.0;
    mat[7].real=1.0;    mat[7].imag=-5.0;
    mat[8].real=1.0;    mat[8].imag=2.0;
    mat[9].real=1.0;    mat[9].imag=4.0;
    mat[10].real=3.0;   mat[10].imag=0.;
    mat[11].real=1.0;   mat[11].imag=-6.0;
    mat[12].real=1.0;   mat[12].imag=3.0;
    mat[13].real=1.0;   mat[13].imag=5.0;
    mat[14].real=1.0;   mat[14].imag=6.0;
    mat[15].real=4.0;   mat[15].imag=0.;

    diag(mat,e,4);

    printf("the eigenvalue is %f,%f,%f,%f\n",e[1],e[2],e[3],e[4]);
    printf(" ");

    free(mat);
    free(e);
}

 

And Here is my fortran Makefile which I think may provide some useful information:

NAME=zg
OBJECTS = $(NAME).f90
cc = ifort
MKLPATH=/opt/intel/composer_xe_2013.5.192/mkl/lib/intel64
MKLINCLUDE=/opt/intel/composer_xe_2013.5.192/mkl/include
MODPATH=/opt/intel/composer_xe_2013.5.192/mkl/include/intel64/lp64
FLAGS= -module $(MODPATH) \
 -assume byterecl -L$(MKLPATH) -I$(MKLINCLUDE)  -I$(MODPATH) -lmkl_lapack95_lp64 -lmkl_blas95_lp64  -Wl,--start-group $(MKLPATH)/libmkl_intel_lp64.a $(MKLPATH)/libmkl_intel_thread.a $(MKLPATH)/libmkl_core.a -Wl,--end-group -liomp5 -lpthread

OUTNAME=zg.out

$(NAME): $(OBJECTS)
    $(cc) -o $(OUTNAME) $(OBJECTS) $(FLAGS)
clean:
    rm -f $(OUTNAME)

 

Thanks for you help in advance.

0 Kudos
1 Solution
Ying_H_Intel
Employee
925 Views

Hi Ming L. 

The latest version of the tool is available at http://software.intel.com/en-us/articles/intel-mkl-link-line-advisor.

The link command of gcc is almost same as ifort in mkl useguide link example.  just repace the ifort with gcc. 

for example, you may try to 

$ gcc le_zheev.c -ole_zheev -Iopt/intel/composer_xe_2013.5.192/mkl/include -L/opt/intel/composer_xe_2013.5.192/mkl/lib/intel64 -L/opt/intel/composer_xe_2013.5.192/compiler/lib/intel64 -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -liomp5 -lm -lpthread
$ ./le_zheev
Wrong parameter 1 in LAPACKE_zheev
matrix diag fail

As mecej4 mentioned, the parameter in the function is wrong, you may refer to MKL manual for the details. 

Best Regards,

Ying 

 

View solution in original post

0 Kudos
10 Replies
TimP
Honored Contributor III
925 Views

For gcc linking, you would need to add all the -L and -l specifications (equivalent to what you used with ifort), as well as the -I ones which you may have got right, although you don't show it.  Adding -v option might be helpful to verify the order of library searching. Environment variables like MKLPATH and having libiomp5 on path would not be available in gcc unless you had set them up, e.g. by the commands by which you set up for ifort.

It's unusual to set up a Makefile which over-rides the normal cc (presumably pointing to gcc) with a Fortran compiler. Environment variable name choices such as $(FC) or $(F90) are more usual.   You would need to make sure such a move doesn't interfere with use of gcc.

0 Kudos
mecej4
Honored Contributor III
925 Views

The first argument to LAPACKE_zheev should be an integer with value LAPACK_ROW_MAJOR or LAPACK_COL_MAJOR, not n.

Secondly, there is no point in using any of the libraries containing "95" in their name -- those are libraries intended for calling from Fortran 90 and later, using generic routine names. It is very doubtful that you will have any need to call those generic names from C code.

0 Kudos
TimP
Honored Contributor III
925 Views

The MKL link advisor covers gcc on linux with either libgomp or libiomp5.   The environment variable MKLROOT could be set by sourceing mklvars script in the MKL installation.

0 Kudos
Ying_H_Intel
Employee
926 Views

Hi Ming L. 

The latest version of the tool is available at http://software.intel.com/en-us/articles/intel-mkl-link-line-advisor.

The link command of gcc is almost same as ifort in mkl useguide link example.  just repace the ifort with gcc. 

for example, you may try to 

$ gcc le_zheev.c -ole_zheev -Iopt/intel/composer_xe_2013.5.192/mkl/include -L/opt/intel/composer_xe_2013.5.192/mkl/lib/intel64 -L/opt/intel/composer_xe_2013.5.192/compiler/lib/intel64 -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -liomp5 -lm -lpthread
$ ./le_zheev
Wrong parameter 1 in LAPACKE_zheev
matrix diag fail

As mecej4 mentioned, the parameter in the function is wrong, you may refer to MKL manual for the details. 

Best Regards,

Ying 

 

0 Kudos
Ming_L_1
Beginner
925 Views

Ying H (Intel) wrote:

Hi Ming L. 

The latest version of the tool is available at http://software.intel.com/en-us/articles/intel-mkl-link-line-advisor.

The link command of gcc is almost same as ifort in mkl useguide link example.  just repace the ifort with gcc. 

for example, you may try to 

$ gcc le_zheev.c -ole_zheev -Iopt/intel/composer_xe_2013.5.192/mkl/include -L/opt/intel/composer_xe_2013.5.192/mkl/lib/intel64 -L/opt/intel/composer_xe_2013.5.192/compiler/lib/intel64 -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -liomp5 -lm -lpthread

$ ./le_zheev

Wrong parameter 1 in LAPACKE_zheev

matrix diag fail

As mecej4 mentioned, the parameter in the function is wrong, you may refer to MKL manual for the details. 

Best Regards,

Ying 

 

 

Hi Ying H:

Copying your code, I succeed in passing the compilation. Thank you very much! Also thanks other guys, they may at the right point, but a little bit abstract for me. 

Cheers.

0 Kudos
Ming_L_1
Beginner
925 Views

mecej4 wrote:

The first argument to LAPACKE_zheev should be an integer with value LAPACK_ROW_MAJOR or LAPACK_COL_MAJOR, not n.

Secondly, there is no point in using any of the libraries containing "95" in their name -- those are libraries intended for calling from Fortran 90 and later, using generic routine names. It is very doubtful that you will have any need to call those generic names from C code.

Thank you very much for pointing out the wrong use of the first argument! I have correct that and my sample program passed the compiling! 

Cheers.

0 Kudos
mecej4
Honored Contributor III
925 Views

Ming L. wrote:

Quote:

Thank you very much for pointing out the wrong use of the first argument! I have correct that and my sample program passed the compiling! 

Argument value checks are made at run time; therefore, being able to compile and link is not enough to establish that correct arguments are being provided. You need a test case for which you can find the correct solution (by hand calculation or other means) and then you should compare that solution with the output of the program in question.

0 Kudos
Ming_L_1
Beginner
925 Views

mecej4 wrote:

Quote:

Ming L. wrote:

Quote:

Thank you very much for pointing out the wrong use of the first argument! I have correct that and my sample program passed the compiling! 

 

Argument value checks are made at run time; therefore, being able to compile and link is not enough to establish that correct arguments are being provided. You need a test case for which you can find the correct solution (by hand calculation or other means) and then you should compare that solution with the output of the program in question.

Thanks for reminding me, I correct another mistake in my program, that is: eigenvalue starts form e[0] not e[1].

May I ask you a little question: if I choose my matrix_order to be LAPACK_ROW_MAJOR, do this mean the output eigenvectors also put in the row order. In my example, is that mean that mat[0],mat[1],mat[2],mat[3] form the eigenvector of the first eigenvalue?

And, if I choose my matrix_order to be LAPACK_COL_MAJOR, is the output eigenvectors also put in the column major. In my example, then , mat[0], mat[4], mat[8], mat[12] form the eigenvector of the first eigenvalue?

0 Kudos
Ying_H_Intel
Employee
925 Views

Hi Ming L, 

If you choose LAPACK_ROW_MAJOR, you can take the mat as  the matrix in Math concept,  as you know,  in math concept, the eigenvector is the column of output matrix.  So in your example, mat[0], mat[1], mat[2], mat[3] is the first row of matrix.  They are not the eigenvector of the first eigenvalues. 

Based on the same rule, if LAPACK_COL_MAJOR, the mat[0], mat[1], mat[2], mat[3] is the first column of matrix. So they are the eignevector of the first eigenvalues. 

There are exact cheev 4x4 matrix example code in MKL install directory, for example, 

<MKL example>\lapacke\source\lapacke_cheev_col.c and lapacke_cheev_row.c

You may refer to them. 

Best Regards,

Ying 

0 Kudos
Ming_L_1
Beginner
925 Views

Ying H (Intel) wrote:

Hi Ming L, 

If you choose LAPACK_ROW_MAJOR, you can take the mat as  the matrix in Math concept,  as you know,  in math concept, the eigenvector is the column of output matrix.  So in your example, mat[0], mat[1], mat[2], mat[3] is the first row of matrix.  They are not the eigenvector of the first eigenvalues. 

Based on the same rule, if LAPACK_COL_MAJOR, the mat[0], mat[1], mat[2], mat[3] is the first column of matrix. So they are the eignevector of the first eigenvalues. 

There are exact cheev 4x4 matrix example code in MKL install directory, for example, 

<MKL example>\lapacke\source\lapacke_cheev_col.c and lapacke_cheev_row.c

You may refer to them. 

Best Regards,

Ying 

Thanks for your explanation and the reference provided. I think I got this rule.  

0 Kudos
Reply