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

Fortran and Matlab

nabeels
Beginner
6,617 Views
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, ...)
0 Kudos
28 Replies
Steven_L_Intel1
Employee
3,936 Views
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.
0 Kudos
John_B__Walter
Beginner
3,936 Views
Quoting - nabeels
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.
0 Kudos
david_sallngc_com
3,936 Views
Quoting - nabeels
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 onhow 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!

Have fun!

Sincerely,

David
0 Kudos
nabeels
Beginner
3,936 Views
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 releaseif my license is renewed?
knowing: I'm eligible to the Academic Price
Thank you
0 Kudos
Steven_L_Intel1
Employee
3,936 Views
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.
0 Kudos
scrognoid
Beginner
3,936 Views
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.
0 Kudos
eos_pengwern
Beginner
3,936 Views
Quoting - scrognoid
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 recordedhere(ignore the early posts in the thread, but the later ones show what now works well).

Stephen.
0 Kudos
nabeels
Beginner
3,936 Views
Quoting - eos pengwern

I've been working successfully with IVF 11 DLLs called from MATLAB; my experiences are recordedhere(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?
0 Kudos
eos_pengwern
Beginner
3,936 Views
Quoting - nabeels

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-filewhich is sent to TOMLAB viaglcAssign, 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.
0 Kudos
nabeels
Beginner
3,936 Views
Quoting - eos pengwern

Yes, you can do that; assuming that your MATLAB function is inside an m-filewhich is sent to TOMLAB viaglcAssign, 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"??
0 Kudos
eos_pengwern
Beginner
3,936 Views
Quoting - nabeels

That is really interesting. Do you have any documents about the "calling steps"??

I'm afraid Ilet 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.
0 Kudos
nabeels
Beginner
3,936 Views
Quoting - eos pengwern

I'm afraid Ilet 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??!!!
0 Kudos
eos_pengwern
Beginner
3,936 Views
Quoting - nabeels

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, andIntel 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.
0 Kudos
nabeels
Beginner
3,936 Views
Quoting - eos pengwern

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, andIntel 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 FilesMicrosoft Visual StudioMyProjectstest', test)
and the result was the following error message:

??? Error using ==> loadlibrary at 454
There was an error loading the library "C:Program FilesMicrosoft Visual StudioMyProjectstest"
Undefined function or variable 'test'.

Error in ==> nabeeltest at 3
loadlibrary('C:Program FilesMicrosoft Visual StudioMyProjectstest',...

Caused by:
Error using ==> feval
Undefined function or variable 'test'.

Any comments on the above error?!!!
thank you
0 Kudos
IanH
Honored Contributor III
3,936 Views
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:

[cpp]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.2fn', 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.2fn', 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);

methodinfo=fcns;

end[/cpp]


0 Kudos
eos_pengwern
Beginner
3,936 Views
Hi Nabeels,

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.

[cpp]subroutine test (a,b,c) bind(c, name='test')[/cpp]

...make sure that the contents of the 'test.h' file is:

[cpp]void test(float *, float *, float *);
[/cpp]

and load the library using the full name for the header file, i.e.

[cpp]loadlibrary('C:Program FilesMicrosoft Visual StudioMyProjectstest', 'test.h')[/cpp]

(...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:

[cpp]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
[/cpp]

...and you will be able to call it from MATLAB by saying, for example:
[cpp]a=1
b=2
dummy=0
c=calllib('test', 'test', dummy, a, b)
[/cpp]

... and get (in this case) c=0.66667 as the result.

I hope this helps.

Stephen.
0 Kudos
eos_pengwern
Beginner
3,936 Views
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.
0 Kudos
nabeels
Beginner
3,936 Views
Quoting - eos pengwern
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 withextension .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 SettingsHP_AdministratorDesktoptest100Debug';
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 SettingsHP_AdministratorDesktoptest100Debugtest.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??



0 Kudos
nabeels
Beginner
3,936 Views
Quoting - eos pengwern
Hi Nabeels,

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.

[cpp]subroutine test (a,b,c) bind(c, name='test')[/cpp]

...make sure that the contents of the 'test.h' file is:

[cpp]void test(float *, float *, float *);
[/cpp]

and load the library using the full name for the header file, i.e.

[cpp]loadlibrary('C:Program FilesMicrosoft Visual StudioMyProjectstest', 'test.h')[/cpp]

(...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:

[cpp]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
[/cpp]

...and you will be able to call it from MATLAB by saying, for example:
[cpp]a=1
b=2
dummy=0
c=calllib('test', 'test', dummy, a, b)
[/cpp]

... and get (in this case) c=0.66667 as the result.

I hope this helps.

Stephen.

iso_c_binding is not found!
0 Kudos
eos_pengwern
Beginner
3,771 Views
Quoting - nabeels

iso_c_binding is not found!

The '.h' file isn't generated automatically; you need tocreate 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?

Stephen.
0 Kudos
Reply