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

the yprime example under windows : error LNK2001: unresolved external symbol _MEXFUNCTION@16

pascal_M_
Beginner
828 Views

Under unix I was writing fortran code and compiling mex (with ifort) libraries to use with matlab. The debug sessions were quite awful compared to a debug session in windows with visual studio, so that now that I moved to windows, I intend to write mex libraries with visual studio and ifort.

(My setup is last win10 update, last visual studio 2017 upate, matlab 2018b 64bits, intel visual fortran compiler for windows, 2018.)

I came across the following matlab forum thread :

https://fr.mathworks.com/matlabcentral/answers/100208-how-can-i-compile-fortran-mex-files-in-microsoft-visual-studio?s_tid=mwa_osa_a

and followed the advice of the accepted answer with the following modifications :

  • Something missing in then answer was to add in "properties > Linker > General > Additional Libraries Directories" the path "C:\Program Files\MATLAB\R2018b\extern\lib\win64\microsoft" as without this libmx.lib and libmex.lib cannot be found
  • The answer is for 32bits and I target 64bits, so that I added a new configuration etc, and replaced mexw32 by mexw64.

After compiling, I get the following visual studio output :

1>Compiling with Intel(R) Visual Fortran Compiler 18.0.0.124 [Intel(R) 64]...
1>yprimef.F
1>yprimefg.F
1>Linking...
1>Creating library C:\path\to\project\folder\yprime_fortran\yprime_fortran\x64\Debug\yprime_fortran.lib and object C:\path\to\project\folder\yprime_fortran\yprime_fortran\x64\Debug\yprime_fortran.exp
1>yprime_fortran.exp : error LNK2001: unresolved external symbol _MEXFUNCTION@16
1>x64\Debug\yprime_fortran.mexw64 : fatal error LNK1120: 1 unresolved externals

What am I doing wrong ?

One point though : the output of a "mex -setup" is :

MEX configured to use 'Microsoft Visual C++ 2017 (C)' for C language compilation.
Warning: The MATLAB C and Fortran API has changed to support MATLAB
         variables with more than 2^32-1 elements. You will be required
         to update your code to utilize the new API.
         You can find more information about this at:
         https://www.mathworks.com/help/matlab/matlab_external/upgrading-mex-files-to-use-64-bit-api.html.

To choose a different C compiler, execute one from the following:
For Intel Parallel Studio XE 2018 with Microsoft Visual Studio 2015 (C):  mex -setup:"C:\Program Files\MATLAB\R2018b\bin\win64\mexopts\intel_c_18_vs2015.xml" C
For Intel Parallel Studio XE 2018 with Microsoft Visual Studio 2017 (C):  mex -setup:"C:\Program Files\MATLAB\R2018b\bin\win64\mexopts\intel_c_18_vs2017.xml" C
For Microsoft Visual C++ 2015 (C):  mex -setup:"C:\Program Files\MATLAB\R2018b\bin\win64\mexopts\msvc2015.xml" C
For Microsoft Visual C++ 2017 (C):  mex -setup:C:\Users\Me\AppData\Roaming\MathWorks\MATLAB\R2018b\mex_C_win64.xml C

To choose a different language, execute one from the following:
 mex -setup C++
 mex -setup FORTRAN

Should I maybe setup matlab for mex as follows :

https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/286108

?

0 Kudos
9 Replies
Steve_Lionel
Honored Contributor III
828 Views

Did you do step 4d in that first linked article?

d. Under Fortran -> External Procedures -> Calling Convention, choose 'STDCALL, REFERENCE'

I have never used MATLAB so don't know the details. I do note that the article's suggestion for the @16 implies 32-bit, as 64-bit doesn't have STDCALL.

0 Kudos
mecej4
Honored Contributor III
828 Views

The MEX script is rather complex and works only for a limited number of combinations of Matlab and Parallel Studio versions. I was able to build the Mex file using IFort 19.0.3 and Matlab 2013b as follows, directly from the command line:

  1. Open an Ifort-x64 command window.
  2. Add the Matlab paths to %INCLUDE% and %LIB%.
  3. Build the Mex file using the command ifort /fpp /LD yprimef.F yprimefg.F libmx.lib libmex.lib /link /export:MEXFUNCTION /out:yprime.mexw64
  4. Test the Mex file in Matlab: yprime(0.2,[1 2 3 4]) .

Note that the exported entry name expected by 64-bit Matlab is MEXFUNCTION, not _MEXFUNCTION@16 .

0 Kudos
pascal_M_
Beginner
828 Views

I indeed did the step 4d and I am trying, without success, to adapt it to 64bits. What does your experience tell you about the right calling convention under 64bits ? (One remark : working exclusively with command line, I don't remember having to bother with exports etc)

0 Kudos
Steve_Lionel
Honored Contributor III
828 Views

There is only one calling convention for 64-bit. So I would NOT do step 4d for 64-bit and would change the exports name to just MEXFUNCTION (no underscore, no @16.)

0 Kudos
pascal_M_
Beginner
828 Views

Steve, your last comment just crossed mine, I indeed tried that and "succeed". Now the output is :

1>------ Rebuild All started: Project: yprime_fortran, Configuration: Debug x64 ------
1>Deleting intermediate files and output files for project 'yprime_fortran', configuration 'Debug|x64'.
1>yprime_fortran: warning: TargetPath(C:\path\to\project\folder\yprime_fortran\yprime_fortran\x64\Debug\yprime_fortran.dll) does not match the Linker's OutputFile property value (C:\Users\Me\Desktop\DEMO_FRED\yprime_fortran\yprime_fortran\x64\Debug\yprime_fortran.mexw64). This may cause your project to build incorrectly. To correct this, please make sure that $(OutDir), $(TargetName) and $(TargetExt) property values match the value specified in %(Link.OutputFile).
1>Compiling with Intel(R) Visual Fortran Compiler 18.0.0.124 [Intel(R) 64]...
1>yprimef.F
1>yprimefg.F
1>Linking...
1>Creating library C:\Users\Me\Desktop\DEMO_FRED\yprime_fortran\yprime_fortran\x64\Debug\yprime_fortran.lib and object C:\Users\Me\Desktop\DEMO_FRED\yprime_fortran\yprime_fortran\x64\Debug\yprime_fortran.exp
1>Embedding manifest...
1>mt.exe : general error c101008d: Failed to write the updated manifest to the resource of file "C:\path\to\project\folder\yprime_fortran\yprime_fortran\x64\Debug\yprime_fortran.dll". The system cannot find the file specified.
1>
1>Build log written to  "file://C:\Users\Me\Desktop\DEMO_FRED\yprime_fortran\yprime_fortran\x64\Debug\BuildLog.htm"
1>yprime_fortran - 1 error(s), 1 warning(s)
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

Which will be easily solved. (I hope so.)

Thx Steve !

Thx to mecej4 also !

0 Kudos
Steve_Lionel
Honored Contributor III
828 Views

The important part is this:

1>yprime_fortran: warning: TargetPath(C:\path\to\project\folder\yprime_fortran\yprime_fortran\x64\Debug\yprime_fortran.dll) does not match the Linker's OutputFile property value (C:\Users\Me\Desktop\DEMO_FRED\yprime_fortran\yprime_fortran\x64\Debug\yprime_fortran.mexw64). This may cause your project to build incorrectly. To correct this, please make sure that $(OutDir), $(TargetName) and $(TargetExt) property values match the value specified in %(Link.OutputFile).

0 Kudos
pascal_M_
Beginner
828 Views

Thx Steve.

$(OutDir), $(TargetName) and $(TargetExt) property values cannot match the value specified in %(Link.OutputFile) for the following reason : I need to produce mexw64 files instead of .dll so that iI replaced everywhere $(TargetExt) by ".mew64" ... except in "configuration properties -> General -> Target Extension" where I simply cannot override the target extension as its field (as well as the "Configuration Type" field) is greyed and not modifiable. (See attached window-shot.) Is this an intended behavior of intel fortran for visual studio or some bug, or am I doing something wrong ?

I nevertheless confirm that if I keep $(TargetExt) everywhere (frozen to ".dll", remember) instead of ".mew64", module.def included, then the project builds without a warning. Then changing (by hand or in a post build command in the properties of the project) the dll extension to mexw64 give a mex-file perfectly usable in MATLAB as intended, debugable as well with stepping inside fortran in visual studio as well.

0 Kudos
mecej4
Honored Contributor III
828 Views

pascal M. wrote:

... replaced everywhere $(TargetExt) by ".mew64"

This may only be a typographical error; nevertheless, please check your VS settings to make sure that you have mexw64 rather than mew64 (is that a 9-lives 64-bit cat?).

0 Kudos
pascal_M_
Beginner
828 Views

mecej4 wrote:

Quote:

pascal M. wrote:

 

... replaced everywhere $(TargetExt) by ".mew64"

 

This may only be a typographical error; nevertheless, please check your VS settings to make sure that you have mexw64 rather than mew64 (is that a 9-lives 64-bit cat?).

It was only a typo, as the problem may be caused, as I have explained in my previous message, by the fact that I am apparently not allowed to override $(TargetExt) which is frozen to ".dll". Good pun on mew btw :)

0 Kudos
Reply