Hello everybody Can I anyone tell me how easy to call Fortran by Matlab? What does intel suppose to send you when you purchase the license? (CDs, manuals, ...)
You can buy Intel Visual Fortran either as a boxed product or as a download. The boxed product provides a DVD with the software, or you can download the software. Manuals are provided in on-disk form only, available after you install the product.
Hello everybody Can I anyone tell me how easy to call Fortran by Matlab? What does intel suppose to send you when you purchase the license? (CDs, manuals, ...)
I haven't used MATLAB (change in job) these last 5 years, so much has changed. The MATLAB documentation addresses this subject. The tricky part is understanding the argument passing -- understanding the MATLAB variable structures. They seem very simple in MATLAB because most of the complexity is hidden. The MATLAB package includes subroutines for copying data between MATLAB variables and more common FORTRAN data structures for some set of FORTRAN compilers. Those compilers are listed on the MATLAB web site. Be sure your compiler is on that list, or get one that is. Basically, read your MATLAB documentation.
Hello everybody Can I anyone tell me how easy to call Fortran by Matlab? What does intel suppose to send you when you purchase the license? (CDs, manuals, ...)
I do it all the time and it works great. You need to learn how to write a mexfunction subroutine. This is the interface between the Matlab and Fortran environment. The mexfunction is written in Fortran. You compile in the Matlab command window using the "mex" command. You first need to setup a mexopts.bat file by invoking the command
> mex -setup
and follow the instructions. If you are using Fortran 90 free-format, you will need to modify the mexopts.bat by removing the /FIXED qualifier (not sure why Mathworks put this in by default).
The most difficult part is writing the mexfunction subroutine using the Matlab MX functions (see the HELP -> MATLAB -> C and Fortran API Reference). After years of writing these files, my advice is to make individual subroutines to perform certain functions. You will use these over and over again.
You can also debug your mexfunction using Microsoft Visual Studio. Mathworks has documentation on how to do this. It is very cool how it all works.
There is a big learning curve here but it is well worth the time. You can turn slow running Matlab code into fast running code. You can also use OpenMP within the Fortran code and it will really fly!
You can buy Intel Visual Fortran either as a boxed product or as a download. The boxed product provides a DVD with the software, or you can download the software. Manuals are provided in on-disk form only, available after you install the product.
Thanks steve I'm planning to purchase Visual intel Fortran Professional Edition (including the two libraries). My concern is: what am I going to receive from renewing the license (although I like mine to be renewed)! Will I have my program upgraded to the new release if my license is renewed? knowing: I'm eligible to the Academic Price Thank you
You will receive a serial number, which when you register it, will give you access to the current version and any released in the next year from the Intel Registration Center.
Matlab does not yet support version 11 of IVF. So in addition to learning to write mex files, you will have to jury rig some things. I think it is just path names that need fixing, but I haven't cracked that nut yet. It's on my to-do list.
(Tip: you can't print from a mex file, say, for debugging. You have to write to a file.)
Mex files are worth the trouble if you have a need for speed.
Matlab does not yet support version 11 of IVF. So in addition to learning to write mex files, you will have to jury rig some things. I think it is just path names that need fixing, but I haven't cracked that nut yet. It's on my to-do list.
(Tip: you can't print from a mex file, say, for debugging. You have to write to a file.)
Mex files are worth the trouble if you have a need for speed.
I've been working successfully with IVF 11 DLLs called from MATLAB; my experiences are recorded here (ignore the early posts in the thread, but the later ones show what now works well).
I've been working successfully with IVF 11 DLLs called from MATLAB; my experiences are recorded here (ignore the early posts in the thread, but the later ones show what now works well).
Stephen.
Thank you all sharing ideas The full picture of my problem is that, I'm a PhD student doing simulation of a novel reactor. The model equations form a set of nonlinear IVP for the case of cocurrent configuration and a set of nonlinear BVP for the case of countercurrent configuration. currently, I'm using those model equations to optimize the performance of my reactor which could be done successfully for the cocurrent but failed for the countercurrent because of the large computational time needed to achieve a single run. All my codes are done in matlab and I purchased solvers from Tomlab to be able to solve the optimization problem, knowing that Tomlab doesn't have the Fortran version for the solvers it sells. My idea: is to call Fortran from Matlab to solve my model equations (most time consuming step) then let the result obtained to be used by the optimization solver, Can I do that? and how easy is it?
Thank you all sharing ideas The full picture of my problem is that, I'm a PhD student doing simulation of a novel reactor. The model equations form a set of nonlinear IVP for the case of cocurrent configuration and a set of nonlinear BVP for the case of countercurrent configuration. currently, I'm using those model equations to optimize the performance of my reactor which could be done successfully for the cocurrent but failed for the countercurrent because of the large computational time needed to achieve a single run. All my codes are done in matlab and I purchased solvers from Tomlab to be able to solve the optimization problem, knowing that Tomlab doesn't have the Fortran version for the solvers it sells. My idea: is to call Fortran from Matlab to solve my model equations (most time consuming step) then let the result obtained to be used by the optimization solver, Can I do that? and how easy is it?
Yes, you can do that; assuming that your MATLAB function is inside an m-file which is sent to TOMLAB via glcAssign, then all you need to do is to place a call to the Fortran code from within the m-file. I still think the easiest way to proceed is by writing a Fortran DLL, loading it (with 'loadlibrary') at the beginning of your program's execution, and calling it (using 'calllib') from within the m-file.
I subsequently found that TOMLAB didn't work all that well on my functions, so went on to write a customised optimisation routine in Fortran as well; but that's another story.
Yes, you can do that; assuming that your MATLAB function is inside an m-file which is sent to TOMLAB via glcAssign, then all you need to do is to place a call to the Fortran code from within the m-file. I still think the easiest way to proceed is by writing a Fortran DLL, loading it (with 'loadlibrary') at the beginning of your program's execution, and calling it (using 'calllib') from within the m-file.
I subsequently found that TOMLAB didn't work all that well on my functions, so went on to write a customised optimisation routine in Fortran as well; but that's another story.
Stephen.
That is really interesting. Do you have any documents about the "calling steps"??
That is really interesting. Do you have any documents about the "calling steps"??
I'm afraid I let my TOMLAB subscription lapse some time ago, so I don't still have the documentation for that. The 'loadlibrary' and 'calllib' functions are pretty clearly described in the MATLAB documentation, and putting these together with the Fortran example in the thread I linked to earlier (in particular the 8/16/2008 post) will probably give you all you need.
I'm afraid I let my TOMLAB subscription lapse some time ago, so I don't still have the documentation for that. The 'loadlibrary' and 'calllib' functions are pretty clearly described in the MATLAB documentation, and putting these together with the Fortran example in the thread I linked to earlier (in particular the 8/16/2008 post) will probably give you all you need.
Stephen.
hello again while I was checking the internet, I found that Matlab doesn't support the communication with compaq Fortran, Any idea about intel Fortran??!!!
hello again while I was checking the internet, I found that Matlab doesn't support the communication with compaq Fortran, Any idea about intel Fortran??!!!
It doesn't support Compaq or Intel Fortran via the 'Mex file' protocol; however, this doesn't affect the use of a DLL, since MATLAB doesn't know or care what language was used to prepare the DLL. The only thing that MATLAB needs is for the DLL to have a standard 'C' interface, and Intel Fortran provides this via the standard 'ISO_C_BINDING' module which is used by the example I cited. MATLAB also needs the 'C' header file (i.e. the .h file), but the comments in the example show how the contents of this should be constructed as well.
It doesn't support Compaq or Intel Fortran via the 'Mex file' protocol; however, this doesn't affect the use of a DLL, since MATLAB doesn't know or care what language was used to prepare the DLL. The only thing that MATLAB needs is for the DLL to have a standard 'C' interface, and Intel Fortran provides this via the standard 'ISO_C_BINDING' module which is used by the example I cited. MATLAB also needs the 'C' header file (i.e. the .h file), but the comments in the example show how the contents of this should be constructed as well.
Stephen.
Hello Stephen I'm currently using Compaq Visual Fortran 6.5. I wrote the following simple Dll to call it in Matlab 2008a
! test.f90 ! ! FUNCTIONS/SUBROUTINES exported from test.dll: ! test - subroutine ! subroutine test (a,b,c)
! Expose subroutine test to users of this DLL ! !DEC$ ATTRIBUTES DLLEXPORT::test
! Variables real a,b,c ! Body of test c=a*b/(a+b) end subroutine test
Then I try to load it in Matlab by using the following command: loadlibrary('C:\Program Files\Microsoft Visual Studio\MyProjects\test', test) and the result was the following error message:
??? Error using ==> loadlibrary at 454 There was an error loading the library "C:\Program Files\Microsoft Visual Studio\MyProjects\test" Undefined function or variable 'test'.
Error in ==> nabeeltest at 3 loadlibrary('C:\Program Files\Microsoft Visual Studio\MyProjects\test',...
Caused by: Error using ==> feval Undefined function or variable 'test'.
CVF didn't have C interoperability. C-interoperability makes life sooooo much easier for this sort of thing. Without this F2003 feature you'll need to be very careful with calling conventions. I have guessed in my example below what they are, but it has been some years since I had CVF installed so these guesses will probably be wrong. Note that compiler options, compiler directives, even changes in compiler versions, can result in changes to calling conventions, default kinds etc.
Your second argument to loadlibrary is the identifier "test", which Matlab thinks is a Matlab variable. That variable does not exist, so you get an error. The second argument to loadlibrary is normally some sort of definition of the procedures exposed by the dll named by the first argument - either a string with the path to a C-style header file, or a function handle that returns the required information - see the documentation within Matlab for loadlibrary for more details.
For the test fortran subroutine as in your previous post, built using CVF, the following is an example of what's required on the Matlab side:
function CVFMatlab
dll_dir = 'C:\path_to_your_dll\'; % ** Edit this ** dll_path = [dll_dir 'name_of_your_DLL.dll']; % ** Edit this ** % Name by which the library will be known internal to Matlab dll_alias = 'CVFMatlab';
% Load the dll, giving it an alias to simplify use loadlibrary(dll_path, @prototypes, 'alias', dll_alias);
% Call the routine with arguments a = 1.0; b = 2.0; c = 0.0; % All arguments are passed by reference, so they can appear on both sides of % the matlab call. [ new_a, new_b, new_c ] = calllib(dll_alias, 'test', a, b, c); fprintf(1, 'c (option one) is: %10.2f\n', new_c);
% Alternative approach p_c = libpointer('singlePtr', c); calllib(dll_alias, 'test', 10, 20, p_c) c = p_c.get('Value'); fprintf(1, 'c (option two) is: %10.2f\n', c);
% Unload the library unloadlibrary(dll_alias);
end
% Mostly boiler-plate code from call loadlibrary with the mfilename option. function [methodinfo,structs,enuminfo,ThunkLibName] = prototypes
ival = { cell(1,1) }; % For pre-allocattion of fcns to the right size. structs = []; enuminfo = []; fcnNum = 1; fcns=struct('name',ival,'calltype',ival,'LHS',ival,'RHS',ival,'alias',ival); ThunkLibName=[];
% Equivalent to a C header declaration of the style: % % void __stdcall TEST(float* a, float* b, float* c);
fcns.name{fcnNum}='TEST'; % Name in DLL, doesn't need decoration. fcns.alias{fcnNum}='test'; % For use within Matlab fcns.calltype{fcnNum}='stdcall'; % CVF default. fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'singlePtr', 'singlePtr', 'singlePtr'}; fcnNum = fcnNum + 1;
% For IVF with BIND(C, Name='MyFunctionName'), change the relevant lines % above to: % fcns.name{fcnNum}='MyFunctionName'; % fcns.calltype{fcnNum}='cdecl'; % % which is equivalent to a C header declaration of: % % void MyFunctionName(float* a, float* b, float* c);
A couple of things, though as I've only ever used Intel Fortran (V10 onwards), I'm not sure if all of this is supported by your version of Compaq Fortran.
At minimum, you need to add "bind(c, name='test')" on the same line as the subroutine declaration, i.e.
subroutine test (a,b,c) bind(c, name='test')
...make sure that the contents of the 'test.h' file is:
void test(float *, float *, float *);
and load the library using the full name for the header file, i.e.
(...assuming that the header file is in your main MATLAB directory).
In addition, I'd strongly recommend two further things:
1) Use the 'iso_c_binding' module, and declare the variables a, b, and c explicitly as the 'c_float' type (in practice this is the same as standard Fortran real on a Win32 platform, but it is good practice to make the type declarations explicit in any case).
2) Change the order of a, b, and c so that the 'output' variable, c, occurs first, and make the intents explicit.
Your code will now look like:
subroutine test (c, a, b) bind(c, name='test')
use iso_c_binding
! Expose subroutine test to users of this DLL
!
!DEC$ ATTRIBUTES DLLEXPORT::test
! Variables
real(c_float), intent(out) :: c
real(c_float), intent(in) :: a, b
! Body of test
c=a*b/(a+b)
end subroutine test
...and you will be able to call it from MATLAB by saying, for example:
a=1
b=2
dummy=0
c=calllib('test', 'test', dummy, a, b)
... and get (in this case) c=0.66667 as the result.
I note that IanH posted his reply while I was composing mine... if he has direct experience of CVF then his advice may well be more applicable to you. As I said, I've only ever used IVF, which has a lot more C interopability 'built in' as part of the Fortran 2003 standard.
I note that IanH posted his reply while I was composing mine... if he has direct experience of CVF then his advice may well be more applicable to you. As I said, I've only ever used IVF, which has a lot more C interopability 'built in' as part of the Fortran 2003 standard.
Stephen.
Hello Stephen and IanH I'm very thankful for your effort! unfortunately, I have no file with extension .h in my project. I changed my Matlab code to the following after removing my test100 project to the disktop to the following:
clear all clc dll_dir = 'C:\Documents and Settings\HP_Administrator\Desktop\test100\Debug\'; dll_path = [dll_dir 'test.dll']; dll_alias = 'CVFMatlab'; loadlibrary(dll_path, @prototypes, 'alias', dll_alias);
and it still give me an error:
??? Error using ==> loadlibrary at 454 There was an error loading the library "C:\Documents and Settings\HP_Administrator\Desktop\test100\Debug\test.dll" Undefined function or variable 'prototypes'.
Error in ==> nabeeltest at 6 loadlibrary(dll_path, @prototypes, 'alias', dll_alias); Caused by: Error using ==> feval Undefined function or variable 'prototypes'.
A couple of things, though as I've only ever used Intel Fortran (V10 onwards), I'm not sure if all of this is supported by your version of Compaq Fortran.
At minimum, you need to add "bind(c, name='test')" on the same line as the subroutine declaration, i.e.
subroutine test (a,b,c) bind(c, name='test')
...make sure that the contents of the 'test.h' file is:
void test(float *, float *, float *);
and load the library using the full name for the header file, i.e.
(...assuming that the header file is in your main MATLAB directory).
In addition, I'd strongly recommend two further things:
1) Use the 'iso_c_binding' module, and declare the variables a, b, and c explicitly as the 'c_float' type (in practice this is the same as standard Fortran real on a Win32 platform, but it is good practice to make the type declarations explicit in any case).
2) Change the order of a, b, and c so that the 'output' variable, c, occurs first, and make the intents explicit.
Your code will now look like:
subroutine test (c, a, b) bind(c, name='test')
use iso_c_binding
! Expose subroutine test to users of this DLL
!
!DEC$ ATTRIBUTES DLLEXPORT::test
! Variables
real(c_float), intent(out) :: c
real(c_float), intent(in) :: a, b
! Body of test
c=a*b/(a+b)
end subroutine test
...and you will be able to call it from MATLAB by saying, for example:
a=1
b=2
dummy=0
c=calllib('test', 'test', dummy, a, b)
... and get (in this case) c=0.66667 as the result.
The '.h' file isn't generated automatically; you need to create it manually, using the MATLAB editor or Notepad, with just the line of text I gave.
I guess iso_c_binding is more recent than your Compaq version. When I experimented, I found I could load the library without using it (and using standard 'real' for the variable kinds), but the "bind(c, name='test')" was essential. Does your compiler support this?
CVF didn't support C-interoperability, a part of which is the ISO_C_BINDING intrinsic module. Hence you see errors associated with that module and probably also the BIND(C,...) syntax. Not having access to C-interoperability is one of the big downsides to using an old Fortran compiler - C-interoperability really makes things easier and much more robust.
We are also assuming here that you have a version of Matlab that has the necessary support for external dll's. I'm using R2008a. Note again that I don't have CVF installed, so I cannot test my suggestions.
unfortunately, I have no file with extension .h in my project.
The idea is that you would create it, should you choose to go down this path.
Matlab needs to know a little bit about the functions in the DLL so that it can call them correctly. You can do this in two ways - you can write a C-style header file (*.h) with the function declarations using C syntax (for CVF, *I THINK* the only difference to eos pengwern's example for IVF is the addition of __stdcall and the capitalisation of TEST), or you can provide it with a function handle that returns the information (as per posted example).
So, for CVF, take your original fortran test routine (no BIND(C, ...) etc), compile to a dll.
Header file approach, adapting eos pengwern's instructions. If you know a little C (and how it relates to Fortran) better than you know Matlab this is probably simpler.
Function handle approach as per example m code. This avoids requiring as much knowledge of C, but on the flipside you'll need to know more about Matlab's "internal" description of "external" interfaces, which in R2008a at least, is only documented by example.
I changed my Matlab code to the following after removing my test100 project to the disktop to the following:
clear all clc dll_dir = 'C:\Documents and Settings\HP_Administrator\Desktop\test100\Debug\'; dll_path = [dll_dir 'test.dll']; dll_alias = 'CVFMatlab'; loadlibrary(dll_path, @prototypes, 'alias', dll_alias);
and it still give me an error:
??? Error using ==> loadlibrary at 454 There was an error loading the library "C:\Documents and Settings\HP_Administrator\Desktop\test100\Debug\test.dll" Undefined function or variable 'prototypes'.
Error in ==> nabeeltest at 6 loadlibrary(dll_path, @prototypes, 'alias', dll_alias); Caused by: Error using ==> feval Undefined function or variable 'prototypes'.
Any idea??
"prototypes" was an subfunction in the example m code (it could also be a separate function in its own m-file). Matlab can't find it. Two options:
To use the example in a self-contained manner take the entire section of matlab code previously posted, copy it into a .m file called CVFMatlab.m and save it in the current Matlab working directory. Then at the matlab prompt type "CVFMatlab". Or
To use loadlibrary from the command line or a script (as I think you've been doing) take the section of code from line 32 (function ... prototypes) through to the end of the file, and copy it into a .m file called prototypes.m. Save it in the current Matlab working directory. Then try your script again.
"prototypes" was an subfunction in the example m code (it could also be a separate function in its own m-file). Matlab can't find it. Two options:
To use the example in a self-contained manner take the entire section of matlab code previously posted, copy it into a .m file called CVFMatlab.m and save it in the current Matlab working directory. Then at the matlab prompt type "CVFMatlab". Or
To use loadlibrary from the command line or a script (as I think you've been doing) take the section of code from line 32 (function ... prototypes) through to the end of the file, and copy it into a .m file called prototypes.m. Save it in the current Matlab working directory. Then try your script again.
IanH
I created the h file manually and still the error is there:
??? Error using ==> loadlibrary>lFullPath at 525 Could not find file test.h.
Error in ==> loadlibrary at 209 header=lFullPath(header);
Error in ==> nabeeltest at 8 loadlibrary('C:\test', 'test.h')
I created the h file manually and still the error is there:
??? Error using ==> loadlibrary>lFullPath at 525 Could not find file test.h.
Check your Matlab path setting; test.h needs to be in a directory that Matlab can find; I usually put it in the same directory as the .m files. If it's in the same directory as your DLL, and you need to give the full path to your DLL, then you'll need to give the full path to the .h file as well.
Check your Matlab path setting; test.h needs to be in a directory that Matlab can find; I usually put it in the same directory as the .m files. If it's in the same directory as your DLL, and you need to give the full path to your DLL, then you'll need to give the full path to the .h file as well.