This is Subhash. I am having problem in linking fortran-matlab mex files.
I am running MATLAB R2010a. I am trying to mex fortran subroutines in MATLAB. I have installed MSYS, MinGW and gfortran. I have also downloaded and extracted gnumex in the c:\documents\MATLAB folder. I entered gnumex to run the installation settings.
At this point, I see a window pop-up and I entered the following:
MinGW's root directory ---> Pointed towards c:\mingw b) Cygwin's
root directory -----> left blank c)
Path to g95.exe ------> c:\mingw\bin
path to gfortran.exe ------> c:\program files\gfortran\bin e)
path to gnumex utilities ------> c:\users.....\matlab\gnumex
environment linking type ------> MinGW
generate mex dll or engine-----> mex
language for compilation -------> fortran 77
add stub ------> no
optimization level -----> -O3
path for libraries and .def files
c:\users...\Roaming\MathWorks\MATLAB\R2010a\gnumex
Mex options file to create:
c\users...\Roaming\MathWorks\MATLAB\R2010a\mexopts.bat
The above is my installation setup for mex with gnumex. When I hit make options file, an warning message pops out which says
" cannot corret mex.pl .....
"cannot open c:...\R2010a\bin\mex.pl for writing"
and when I hit ok, again it pops out saying to confirm overwrite of mexopts.bat .
I hit confirm and the opt file is created.
At this point I should have my mex setup ready. But, when I run the fortran mex examples xtimesy.f, etc.. ( I use mex filename.f at the command prompt) and I get the following error
g77: getValidInputLinkLibraries: No such file or directory
c:\prog~1\MATLAB\R2010A\BIN\MEX.PL: Error: Link of 'xtimesy.mexw32' failed.
Error using ---> mex at 222
unable to complete successfully.
I tried this uninstalling several times, but ended up with the same error.
Could anyone please let me know where am I going wrong. Is this not the correct procedure to link the g77? Please throw some light on this.
I appreciate your time..
Thanks.
I recently tried to mex some fortran routines and failed due to the poor support for fortran compilers by matlab in windows. I got around the problem by using f2c to convert the fortran to C code, then creating a gateway routine in C which calls the automatically generated C code functions and mexing the resul using the visual studio 2008 compiler which integrates nicely with matlab (the free express edition version is sufficient, you will also be able to use it for debugging).
You can get f2c from http://www.netlib.org/f2c/. You must link the produced C code to the f2c library, which you may also have to build from the sources.
I know this all sounds very complicated, but it was easiest solution I found.
Related
I am trying to create mex files for using some C++ code in Matlab, but running into an error with the compilation which, I guess, goes beyond Matlab. I am on Windows.
The example I'm struggling with is the Mex Interface example in the Armadillo library for linear algebra, available: here. The Matlab file is what I'm running and it looks like this:
% Compile the demo as a mex file
mex -lgfortran armaMex_demo.cpp -I/path/to/armadillo
The error I get is:
Error using mex
MEX cannot find library 'gfortran' specified with the -l option.
MEX looks for a file with one of the names:
libgfortran.lib
gfortran.lib
Please specify the path to this library with the -L option.
Trying some things I found online, I installed MinGW and cygwin64 and added the paths to their bin folders to my PATH variable. Before that I also installed MinGW via Matlab.
My question: How do I get it to link with gfortran?
If I search C:for libgfortran I find some files, but none of them have the file ending .lib (but e.g. .dll and .a) and if I search for gfortranI find some .exe files but again, no .lib file. If I run gfortran -dumpversion in the terminal, I get 4.9.3 back, so it is obviously there somewhere. I am obviously missing something, and this is really not my forte, to say the least.
I have a script in matlab that calls other libraries. I use matlab version 2012a on linux . I get below error and I don't know how to fix it.
The error is :
Invalid MEX-file '/home/XXX/nearest_neighbors.mexa64':
libflann.so.1.8: cannot open shared object file: No such file or
directory
Error in flann_search (line 82)
[indices,dists] = nearest_neighbors('find_nn', data, testset, n, params);
Error in MyScript (line 73)
[nresult, ndists] = flann_search(Ntraindata', Ntraindata', resu.KNN, struct('algorithm','composite',...
That library you are referring to - https://github.com/mariusmuja/flann/ - has the nearest_neighbors function written in MEX code. MEX code is C code that is used to interface with MATLAB. People usually write heavily computationally burdening code over in MEX as it is known to handle loops and other things faster. The inputs come from MATLAB and are sent to this MEX function, and the outputs come from the MEX function and are piped back to MATLAB. It's basically a nice black box where you can use it just like any other MATLAB function. In fact, a lot of the functions that come shipped with MATLAB have MEX wrappers written to promote acceleration.
You are getting that error because you need to compile the nearest_neighbors function so that there is a MEX wrapper that can be called in MATLAB. That wrapper is missing because you haven't compiled the code.
First, you need to set up MEX. Make sure you have a compiler that is compatible with your version of MATLAB. You can do that by visiting this link:
http://www.mathworks.com/support/compilers/R20xxy/index.html
xx is the version number that belongs to your MATLAB and y is the character code that comes after it. For example, if you are using R2013a, you would visit:
http://www.mathworks.com/support/compilers/R2013a/index.html
Once you're there, go to your Operating System and ensure you have one of those supported compilers installed. Once you have that installed, go into MATLAB, and in the command prompt, type in:
mex -setup
This will allow you to set up MEX and choose the compiler you want. Given your error, you're using Linux 64-bit, so it should be very easy for you to get GCC. Just make sure that you choose a version of GCC that is compatible with your version of MATLAB. Once you choose the compiler, you can compile the code by doing this in the command prompt:
>> mex -v -O nearest_neighbors.cpp
This should generate the nearest_neighbors MEX file for you. Once that's done, you can now run the code.
For more detailed instructions, check out FLANN's user manual - http://people.cs.ubc.ca/~mariusm/uploads/FLANN/flann_manual-1.8.4.pdf - It tells you how to build and compile it for MATLAB use.
Good luck!
I am trying to compile a CUDA program using MEX within Matlab2014a and can't get it to work.
I installed the newest CUDA toolbox (6.5) and driver (340.62) and the samples work correctly, so I guess it is correctly installed.
I also installed MS Visual Studio 2012 Professional and Matlab 2014a.
I followed the exact description in the Matlab Help in "GPU Computing -> Examples and How To -> Run MEX-Functions Containing CUDA Code".
My CUDA file ends with .cu (so I am trying to compile Matlab's standard example mexGPUExample.cu, but I get the same error with other .cu files), the mex_CUDA_win64.xml is in the same folder, the environment variable MW_NVCC_PATH is set correctly in the user variables and just to be sure I also called "setenv('MW_NVCC_PATH,...)" in Matlab.
If I try to compile a CUDA example with
mex -largeArrayDims mexGPUExample.cu
I get the following error:
cl : Command line warning D9024 : unrecognized source file type 'mexGPUExample.cu', object file assumed
cl : Command line warning D9027 : source file 'mexGPUExample.cu' ignored
cl : Command line warning D9021 : no action performed
D:\PROGRAMS\MATLAB~1\BIN\MEX.PL: Error: Compile of 'mexGPUExample.cu' failed.
Unable to complete successfully.
I also tried to set the compiler correctly using
mex -setup
and chose the MS Visual Studio Compiler.
The code itself works because I tested it on other systems.
I have no idea what I am doing wrong.
Any help is appreciated.
Matlab only supports CUDA 5.5 on R2014a, so your CUDA 6.5 by default cannot compile mex files under Matlab. Matlab R2014a supports VS 2012 now, but you need to verify you have VS 64-bit compiler if your Matlab is 64-bit. You can compile a normal .mex file with .cpp source file, (lots of these files under matlabroot/extern folder) to see whether Matlab works well with your VS.
Note that Matlab has a lag in supporting the latest compilers, both VS/gcc and Cuda. It is always good choice to check the compiler requirement by Matlab, before using the latest compilers.
Also check whether your Cuda kit and graphics drivers are correctly installed and work seamlessly with VS. You can compile and run some .cu files under the VS environment.
If you have finished all above and changed to the correct version of compilers, follow the instructions on matheworks website to compile the mexGPUExample file. If my memory is correct, you need to set environment variables and copy the XML file to the .mex file path. Then it should work.
So, I have a MEX gateway script file that calls my C source code. I've used the -L and -I commands to link my 64-bit compiled GSL libraries (.libs) to my mex executable, which is then compiled under the extension of .mexw64.
I want for this executable to be transferred to another windows machine and run fine, without any GSL libraries installed. That is the the only solution, I don't care what he arguments are regarding the benefits of the dynamic linking/code generation upon compile-time are. I want an executable that has every function not only (of course) pre-declared, but also PRE-DEFINED.
I was lead to believe that this is what 'static' linking is vs. dynamic; but I've read some contradictory definitions all around the interwebs. I need a completely 100% standalone, singular file.
Supposedly you can link the actual .obj file in the mex function, which I can generate, but unfortunately I then get unresolved symbol errors.
Someone else mentioned that I can use the -l (lowercase L) to directly link the actual .lib(s) needed, statically, but that is NOT true.
So is there anyone that can lead me in the right direction, either how to have everything not only linked but to also have the DEFINITIONS linked and ready to load when executable is run--completely standalone, or why I am running into unresolved symbols/linker errors when I include my .obj file? Am I misunderstanding something elementary about the linking process?
Also: To elaborate a bit more, I have the GSL libraries built and linked via Visual Studio for the 64 bit architecture, and I can link it easily with MATLAB, so that is not my problem (any more).
EDIT: I've seen the post here:
Generating standalone MEX file with GNU compilers, including libraries
This doesn't solve my problem, however, although it is the same question. I don't have access to gcc; it's finally compiling on the MSVS12 compiler in MATLAB, I'm not going try to recompile using GCC via MinGW (already tried, couldn't figure it out), so -static and .a options are out.
In your previous post, you mentioned that you decided to compile GSL library with Visual C++, using the VS solution provided by Brian Gladman.
Here is a step-by-step illustration on how to build a MEX-function that links against GSL libraries statically:
Download GNU GSL sources (GSL v1.16)
Download the matching Visual Studio project files (VS2012 for GSL v1.16)
Extract the GSL tarball, say to C:\gsl-1.16
Extract the VS project files on top of the sources, this will overwrite three files as well as add a folder C:\gsl-1.16\build.vc11.
Open Visual Studio 2012, and load the solution: C:\gsl-1.16\build.vc11\gsl.lib.sln
Change the configuration to the desired output: for me I chose platform=x64 and mode=Release
First you must build the gslhdrs project first
Now build the whole solution. This will create two static libraries cblas.lib and gsl.lib stored in C:\gsl-1.16\lib\x64\Release (along with corresponding PDB debugging symbols). It will also create a directory containing the final header files: C:\gsl-1.16\gsl
Next we proceed to build a MEX-function. Take the following simple program (computes some value from a Bessel function, and return it as output):
gsl_test.c
#include "mex.h"
#include <gsl/gsl_sf_bessel.h>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
if (nrhs != 0 || nlhs > 1) mexErrMsgTxt("Wrong number of args.");
plhs[0] = mxCreateDoubleScalar(gsl_sf_bessel_J0(5.0));
}
This is how to compile the above C code in MATLAB:
>> mex -largeArrayDims gsl_test.c -I"C:\gsl-1.16" -L"C:\gsl-1.16\lib\x64\Release" cblas.lib gsl.lib
Finally we test the MEX-file, and compare it against the value reported by MATLAB's own Bessel function:
>> x = gsl_test()
ans =
-0.1776
>> y = besselj(0,5)
y =
-0.1776
>> max(x-y) % this should be less than eps
ans =
8.3267e-17
Note that the built MEX-function has no external DLL dependencies (other than "Visual C Runtime" which is expected, and the usual MATLAB libraries). You can verify that by using Dependency Walker if you want. So you can simply deploy the gsl_test.mexw64 file alone (assuming the users already have the corresponding VC++ runtime installed on their machines).
Update
Thank you Vladimir for the usefull insights in libraries. I took another approach, developping first in ubuntu (which was a lot easier then messing around with Eclipse/Cygwin/... and now I'm trying to port to windows, which goes rather ok, however I have some questions about that too, posted here: Problems with porting a fortran program from ubuntu to windows
Question
I currently have the following setup and can't get the lapack library configured so that my fortran code can compile:
Windows 7
Cygwin installation (for GNU fortran), added to the windows PATH
lapack and liblapack-devel installed with cygwin
resulting in liblapack.a and libblas.a in the folder C:/cygwin/lib
In my program I call the lapack library using the following code
program myProgram
!use lapack (stays commented now)
...
In Eclipse I used the following setup (with the Photran package):
Fortran Project: executable GNU fortran on Windows (GCC toolchain)
GNU fortran compiler: gfortran ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
GNU fortran linker: gfortran ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
I compiled the libraries libblas.a and liblapack.a, to use as a static library, for windows and they are located in the C:/cygwin/lib folder. In the GNU fortran linker properties, the libraries were called lapackand blasin the folder C:/cygwin/lib. This results in a part -L"C:/cygwin/lib" -llapack -lblas in the {$COMMAND} section of the compiler and linker. (thanx to #vladimir-f for the help)
In the output there are no error messages left anymore. Only I got now the following error in Eclipse and no final .exe or bins:
Errors occured during the build.
Errors running builder 'CDT Builder' on project 'Hamfem'
Internal error building project Hamfem configuration
Release
java.lang.NullPointerException
Internal error building project Hamfem configuration
Release
java.lang.NullPointerException
However, the result of the build is still an executable, in this case called Hamfem.exe. Running this file results in the error message (instead of the routine): The program can't start because cyglapack-0.dll is missing from your computer. Try reinstalling the program to fix this problem.
That file is currently located in C:/cygwin/lib/lapack/ but I want that this file isn't needed to run the program, so I can run it on different computers. Can someone collaborate on this?
Second, when copy-pasting the .dll file in the folder where the .exe is located, it runs for a brief second, generating a stackdump file. I can't use the debugger in Eclipse-Photran due to the 'Building Workspace' error. Eclipse gives the message Binary not found when I want to run it in Eclipse as a local Fortran program. Any ideas how to resolve this problem?
The problem is here
L/lib/lapack –llapack
try to change it for
-L/lib/lapack –llapack
probably it is in you Makefile.
i.e.
gfortran -funderscoring -O3 -Wall -c -fmessage-length=0 -L/lib/lapack -llapack -o
And make sure lapack.mod is really in /lib/lapack which is probably C:\cygwin\lib\lapack on Cygwin.