- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 failAs 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page