Fortran and Matlab

Fortran and Matlab

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, ...)

29 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

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.

Retired 12/31/2016

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.

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

Quoting - Steve Lionel (Intel)
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

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.

Retired 12/31/2016

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.

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.

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?

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.

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"??

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.

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??!!!

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.

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

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

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.

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.

loadlibrary('C:Program FilesMicrosoft Visual StudioMyProjectstest', 'test.h')

(...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 hope this helps.

Stephen.

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.

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??

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.

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.

loadlibrary('C:Program FilesMicrosoft Visual StudioMyProjectstest', 'test.h')

(...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 hope this helps.

Stephen.

iso_c_binding is not found!

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.

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.

Quoting - nabeels

unfortunately, I have no file withextension .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.

Create a file named test.h and put in it:

void __stdcall TEST(float *a, float *b, float *c);

Then at the Matlab prompt:

loadlibrary('C:path_to_your_dllyour_dll_name.dll', 'test.h')

[new_a, new_b, new_c] = calllib('your_dll_name', 'test', 1.0, 2.0, 3.0)

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 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??

"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

Quoting - IanH

"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')

Quoting - nabeels

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.

Stephen.

Quoting - eos pengwern

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.

Stephen.

It is there, it looks like matlab can't see it

Quoting - nabeels

It is there, it looks like matlab can't see it

What happens if you type 'dir test.h' from the MATLAB command prompt?

Quoting - eos pengwern

What happens if you type 'dir test.h' from the MATLAB command prompt?

>> dir test.h
test.h not found.
>>

Is there another way to call CVF from matlab?

Quoting - nabeels

>> dir test.h
test.h not found.
>>

Is there another way to call CVF from matlab?

If test.h isn't found then the problem must be with the Matlab path setting; have you put test.h in the same directory as your .m files? What filesdo you see if you just type 'dir'?

I really don't know of any other ways to call Fortran from MATLAB, unless you want to try building a COM server (which was supported on some versions of CVF, but I'm not sure which ones). This is a huge subject however, and much more complicated than loading a DLL.

Stephen.

Quoting - eos pengwern

If test.h isn't found then the problem must be with the Matlab path setting; have you put test.h in the same directory as your .m files? What filesdo you see if you just type 'dir'?

I really don't know of any other ways to call Fortran from MATLAB, unless you want to try building a COM server (which was supported on some versions of CVF, but I'm not sure which ones). This is a huge subject however, and much more complicated than loading a DLL.

Stephen.

Hello Stephen
Thank you very much for the help
This is what I got when I ran the command "dir"
>> dir

. Ficks_law_DEHYm.asv Text1.dsp catDYiso.m nabeel.dsw test.h.txt
.. Ficks_law_DEHYm.m Text1.dsw catHYiso.asv nabeel.for testBVP.asv
Catalyst_Pellet.asv Ficks_law_HY.asv Text1.f catHYiso.m nabeel.opt testBVP.m
Catalyst_Pellet.m Ficks_law_HY.m Text1.opt cheb.m nabeel.plg timestwo.f
Catalyst_Pelletm.asv IRCO.asv Text1.plg funCount.asv nabeeltest.asv
Catalyst_Pelletm.m IRCO.m bvp4cfsinghouseqr.m funCount.m nabeeltest.m
Debug IRCOFD.asv bvp5c2.m hs_err_pid1524.log reactor_par.asv
Ficks_law.asv IRCOFD.m catDY.asv main2.asv reactor_par.m
Ficks_law_DEHY.asv MassDYiso.asv catDY.m main2.m sparse2.mexw32
Ficks_law_DEHY.m MassDYiso.m catDYiso.asv nabeel.dsp test.f

I can see the text file I created as test.h.txt, can I discuss it through e-mail?
My e-mail is: naboghander@gmail.com , if you like

Leave a Comment

Please sign in to add a comment. Not a member? Join today