I am having heaps of trouble porting a working project from XE 2013 to XE 2020. My latest problem is calling a LAPACK routine named dlarnv which generates random numbers. I have a version of LAPACK source code compiled as part of the project. In XE 2013 I can step into the dlarnv routine, but I can't in XE 2020 because it says there is are no symbols loaded for it. I verified that it is being built with /debug:full. Anyhow, the vector of random values returned by dlarnv contains some garbage (NaN). What could I be doing wrong? It appears that the dlarnv which is being called is in MKL instead of mine, but why is it returning garbage? The arguments passed to it are nearly trivial.
When you link with two or more libraries that contain the same routine, you have to be careful in controlling which one is put into the resulting EXE. In your case, you must have the linker scan your Lapack library before it uses MKL.
A natural question is: "Why do you want to step into Lapack routines?" Are you trying to debug DLARNV, or are you investigating how it works? Similarly, why use MKL at all?
Please show enough of the source code to enable readers to know if you are passing the correct argument types and meaningful input arguments to DLARNV. I tried the following program with Ifort 19.1, MKL and the Lapack 3.6.0 sources (I used only DLARNV.F and DLARUV.f), and I found that the results were consistent. I repeated with Ifort XE 2013 SP 1, and obtained the same results, too.
program xlarnv implicit none integer :: idist=3, iseed(4) =[1923,2047,1023,4001], n=10 double precision x(10) ! call dlarnv(idist,iseed,n,x) print '(5ES16.8)',x end program
Thanks for the reply, mecej4. When you build the code in quote #2, what is required for dlarnv to be found? In VS2019 I found that specifying /Qmkl:sequential was sufficient to build and run it.
I must be doing something wrong with how the program is put together. The combinations of VS2010/XE2013 and VS2019/XE2020 are behaving differently. For instance, with XE2013 I believe I had to add mkl_pardiso.f90 to the project because it wasn't being found in the Intel include folders. That was nearly 5 years ago.
I also see that in Project Properties/Linker/Input/Additional Dependencies I have mkl_blas95.lib mkl_lapack95.lib mkl_intel_c.lib mkl_intel_thread.lib mkl_core.lib libiomp5md.lib libiode_ia32.lib. I don't know why I had these. If these were not put there automatically, someone would have had to tell me to do it.
I just now tried to run the following example:
/Qmkl:sequential gets it to compile, but not link. error LNK2019: unresolved external symbol _SGESVX_F95 referenced in function _MAIN__
Seems to me /Qmkl ought to be sufficient. After adding mkl_lapack95.lib to Additional Dependencies, it would link and run in XE 2020. Is this the recommended way to do things with visual studio? In XE2013 I had specified additional include directories for MKL, but I'm not doing this for XE 2020.
To try to fix my LAPACK problems with my big project ported from XE2013, I will modify my Use BLAS95 and Use LAPACK95 statements by adding ONLY parameters to designate routines I want to come from MKL, and all others ought to then come from my own compiled versions. Do you think that will work?
You can run into a lot of trouble and waste much time if you do not learn and remember the rules. If you are calling any BLAS of Lapack routines through their Fortran-95 interfaces, you must do three things: 1) use the relevant MKL module that provides an interface to that routine in your source file, 2) compile with the /Qmkl flag, and 3) consult the MKL Link Line Advisor to obtain the list of MKL libraries to specify.
Take the example that you mentioned. If you look at the MKL manual page for ?gesvx, you will see at the top the calling sequences for ?gesvx, where '?' stands for one of 's', 'd', 'c', 'z'. These are for single precision real, double precision real, single precision complex and double precision complex versions. All these are Fortran 77 calls, and can be used without providing interfaces.
The last calling sequence in the MKL manual page for ?gesvx is for GESVX, with no prefix. In contrast to the other calling sequences, this calling sequence contains optional arguments and the the routine name is overloaded, i.e., it stands for a number of specific routine names, the proper one being picked by matching the argument types. If the example code calls GESVX, rather than SGESVX, etc., you must check that the source code has a matching USE statement.
If you use the example gesvxab.f90, it already contains the USE statements. You must, however, check that the corresponding module files already exist in the MKL directory. If not, you have to compile (just once is enough) to generate the module files, which you should place in the appropriate subdirectory in the MKL include directory.
Finally, you use the MKL Link Line Advisor at https://software.intel.com/en-us/articles/intel-mkl-link-line-advisor, and select the options for your purposes. The Advisor will tell you what compiler options to use and what libraries to use for linking. Both those pieces go into the command line used for compiling and linking, or into appropriate entries in the Visual Studio menus. For your example, the command is
ifort /Qmkl gesvxab.f90 mkl_blas95.lib mkl_lapack95.lib
if you are targeting IA32.
If you find all this too complex to follow, you have the option of calling only the Fortran77 entry points in BLAS and Lapack, and using just the /Qmkl option to compile and link. I think that time spent in learning to use Lapack95 and BLAS95 is reasonable for the gains that follow.
Thanks mecej4. I think I understand everything you have said. I vaguely recall using the Link Advisor so that must be where I got my list of LIB files to put in Additional Dependencies. I've certainly been spending a lot of time trying to get the program to work in XE2020 and I'm basically stuck. I've asked in multiple threads about how to properly port a project from VS2010/XE2013 to VS2019/XE2020, but so far nothing. The visual studio Solution has 15 separate projects in it in the form of LIB's, DLL's and EXE's.
In my big code I'm still getting garbage from dlarnv, and my shot at calling this from my library instead of MKL didn't work. I still don't know why XE2013 calls my version and XE2020 calls MKL's. How does one force a program to call a specific version?
My main program uses a library called ARPACK for Arnoldi eigensolving, which consists of four lib's; BLAS.LIB, LAPACK.LIB, SRC.LIB and UTIL.LIB. In visual studio there is for my main program a Project Dependencies dialog box where the main program is specified to be dependent on these four other libraries. The linker command line doesn't actually reveal anything about these selections, so I don't know what is actually happening when the main program is built, but I do know that when I step through it in the XE2013 debugger, it steps into the code in my LAPACK.LIB.
I'm getting closer, maybe. When dlarnv is called, n=140, and only the first element is NaN and all the rest are correct. I don't see any problem with the arguments, so there must be something else fouling things up. I put a call to dlarnv at the very start of the main program with the same arguments and it executed perfectly. I completely removed my BLAS and LAPACK lib components from the visual studio solution and cleaned and rebuilt the main program, and still have exactly the same problem with dlarnv returning NaN in the first element.
SRC and UTIL call routines in LAPACK and BLAS, but these libraries are built without the /Qmkl. XE2013 and XE2020 might be behaving differently with respect to this setting.
Brian Murphy wrote:
... I've asked in multiple threads about how to properly port a project from VS2010/XE2013 to VS2019/XE2020, but so far nothing.
I'm afraid that nobody can answer that question since, in general, the answer is "Do nothing!", as it would be for the similar question, "How to properly port a project from Monday to Friday?" The answer, if anything else, must be related to something specific to your project, but you have not shown us the project features in enough detail to enable us to answer.
If you post the build log from one of the builds, that might provide some clues.
Here is how I built the DLARNV example:
To use the DLARNV in MKL: ifort /Qmkl xlarn.f90
To use the Lapack from Nelib: ifort xlarn.f90 ..\lapack\src\dlarnv.f ..\lapack\src\dlaruv.f