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

"unresolved external symbol" errors when building python project with Fortran and C

Evgeny_F_
Beginner
822 Views

Dear all,

I'm trying to follow basic instructions, published at
https://software.intel.com/en-us/articles/building-numpyscipy-with-intel-mkl-and-intel-fortran-on-windows
to build another python project (originally written for Linux OS). My current understanding is that it should be pretty much the same as building Scipy on Windows.

My current setup includes both Intel and Fortran Compilers from Parallel Studio XE Cluster edition (academic license). I had to make a few modifications to the steps, provided in the guide. More specifically, I modified

def get_flags(self):
    opt = ['/nologo', '/MD', '/nbs', '/names:lowercase', '/assume:underscore']

in the numpy/distutil/fcompiler/intel.py file to

def get_flags(self):
    opt = ['/nologo', '/MD', '/assume:underscore', '/fpp', '/llapack', '/lblas'] 

as without '/fpp' flag and with '/nbs', '/names:lowercase' flags I was getting various warnings and errors. Linking to LAPACK and BLAS is required by the project. Building everything with

python setup.py config --compiler=intelemw --fcompiler=intelvem build_clib --compiler=intelemw --fcompiler=intelvem build_ext --compiler=intelemw --fcompiler=intelvem build

There seem to be no problems with compiling both C and Fortran code, however at a linking step (with xilink.exe) I get a bunch of similar errors like the following:

mytt.lib(tt.o) : error LNK2019: unresolved external symbol DNRM2_ referenced in function TT_LIB_mp_DTT_SVD0_


What should be the steps to debug this? Could it be related to the LAPACK and BLAS not being linked properly with xilink (the command starts with xilink /DLL /nologo /INCREMENTAL:NO and doesn't have any mentions of the LAPACK and BLAS)?

Thanks in advance!

Kind regards,
Evgeny

0 Kudos
1 Solution
TimP
Honored Contributor III
822 Views

$ dumpbin /symbols mkl_intel_lp64.lib|grep -i dnrm2
002 00000000 SECT1  notype ()    External     | dnrm2
006 00000000 UNDEF  notype ()    External     | mkl_blas_dnrm2
018 00000000 SECT6  notype ()    External     | dnrm2_
01B 00000000 SECT7  notype ()    External     | DNRM2
01E 00000000 SECT8  notype       External     | ??_C@_0BA@A@DNRM2?$CI?$CFd?0?$CF
p?0?$CFd?$CJ?$AA@ (`string')
002 00000000 SECT1  notype ()    External     | cblas_dnrm2
003 00000000 UNDEF  notype ()    External     | dnrm2

So you can see that the Windows MKL may support the linux default convention of the combination of -assume:underscore -names:lowercase as well as the Windows default of uppercase without underscore, but does not support the combination of underscore and uppercase.

As Steve hinted, the basic options like /Qmkl or /Qmkl:sequential are provided for convenience, so you don't need to read up on MKL link advisor for the simple cases.

You might be able to use the ISO C interoperability features to alias the BLAS function names to one of the supported conventions, but that does seem too complicated and probably in conflict with the provided .mod files.

Library names like liblapack and libblas usually refer to libraries which have been compiled from netlib source using a compiler such as gfortran, without much architecture specific optimization.

View solution in original post

0 Kudos
3 Replies
Steven_L_Intel1
Employee
822 Views

The /assume:underscore is a Linux/UNIX convention and not compatible with standard libraries on Windows. Also, /llapack and /lblas have no meaning here - again, those are Linux/UNIX things (with - instead of /)

See the MKL documentation for how to link with MKL BLAS, or you could just use /Qmkl. You will have to lose the /assume:underscore though.

0 Kudos
TimP
Honored Contributor III
823 Views

$ dumpbin /symbols mkl_intel_lp64.lib|grep -i dnrm2
002 00000000 SECT1  notype ()    External     | dnrm2
006 00000000 UNDEF  notype ()    External     | mkl_blas_dnrm2
018 00000000 SECT6  notype ()    External     | dnrm2_
01B 00000000 SECT7  notype ()    External     | DNRM2
01E 00000000 SECT8  notype       External     | ??_C@_0BA@A@DNRM2?$CI?$CFd?0?$CF
p?0?$CFd?$CJ?$AA@ (`string')
002 00000000 SECT1  notype ()    External     | cblas_dnrm2
003 00000000 UNDEF  notype ()    External     | dnrm2

So you can see that the Windows MKL may support the linux default convention of the combination of -assume:underscore -names:lowercase as well as the Windows default of uppercase without underscore, but does not support the combination of underscore and uppercase.

As Steve hinted, the basic options like /Qmkl or /Qmkl:sequential are provided for convenience, so you don't need to read up on MKL link advisor for the simple cases.

You might be able to use the ISO C interoperability features to alias the BLAS function names to one of the supported conventions, but that does seem too complicated and probably in conflict with the provided .mod files.

Library names like liblapack and libblas usually refer to libraries which have been compiled from netlib source using a compiler such as gfortran, without much architecture specific optimization.

0 Kudos
Evgeny_F_
Beginner
822 Views

Thanks for so quick responses!

Steve Lionel (Intel) wrote:

...See the MKL documentation for how to link with MKL BLAS, or you could just use /Qmkl. You will have to lose the /assume:underscore though.

That was it! Thank you, Steve! I have played with /Qmkl option previously but didn't realize that the main problem was with unsupported underscore and lowercase arguments. Now these errors are gone.

Tim P. wrote:

$ dumpbin /symbols mkl_intel_lp64.lib|grep -i dnrm2

That is very good way to understand the root of the problem! Thanks for detailed explanation, Tim!


P.S. Now I have only one unresolved problem. I get

tt_f90module.obj : warning LNK4197: export 'inittt_f90' specified multiple times; using first specification

Looking into tt_f90module.c module I see

#if PY_VERSION_HEX >= 0x03000000
#define RETVAL m
PyMODINIT_FUNC PyInit_tt_f90(void) {
#else
#define RETVAL
PyMODINIT_FUNC inittt_f90(void) {
#endif

And no other occurrences of "inittt_f90". So it's not really clear, why it's flagged with multiple export flag, but it seems like it's not related to compilers themselves, so probably I'd open another question (not sure yet where this problem comes from).

0 Kudos
Reply