Code covered by the BSD License  

Highlights from
Fortran 95 Interface to MATLAB API with extras!

5.0

5.0 | 5 ratings Rate this file 35 Downloads (last 30 days) File Size: 157 KB File ID: #25934
image thumbnail

Fortran 95 Interface to MATLAB API with extras!

by

 

23 Nov 2009 (Updated )

This is the one you have been waiting for, a clean interface using assumed shape Fortran pointers.

| Watch this File

File Information
Description

Finally, a clean Fortran 95 interface to the MATLAB API routines, with extras! A complete interface to existing MATLAB API functions (eng, mat, mex, mx), as well as dozens of powerful new routines that work with assumed shape Fortran Pointers. Functions are available to, in one line:

- Get shaped pointers into the data area of an mxArray
- Get shaped pointers that point to a copy of the data area of an mxArray
- Reshape a pointer or an array *without* copying
- Allocate Fortran pointers using MATLAB’s allocation functions
- Get lists of workspace variable names or mat file variable names

You will never call mxGetPr, mxGetPi, mxGetDimensions, etc. again once you see the Fortran pointer routines I have included in this package! See the enclosed pdf file for a description of all the available functions in this package.

There are four module routines, five mex test routines, and one engine test routine. The files in the MatlabAPI suite are (should be compiled in the order shown):

Module Code:
MatlabAPImx.f
MatlabAPImex.f
MatlabAPIeng.f
MatlabAPImat.f

Mex Test routines:
MatlabAPI_real.f
MatlabAPI_complex.f
MatlabAPI_getset.f
MatlabAPI_matfile.f
MatlabAPI_implicit.f

Engine Test routine:
MatlabAPI_engine.f

The test routines do not take any inputs. Some give no outputs and some give one output. They can be compiled with the build scripts included on a 32-bit WinXp system with Intel or Compaq Fortran:

Build Scripts:
MatlabAPI_build_cfv61.m
MatlabAPI_build_cfv66.m
MatlabAPI_build_intelf90.m
MatlabAPI_build_intelf90msvs2003.m
MatlabAPI_build_intelf90msvs2005.m
MatlabAPI_build_intelf91msvs2005.m
MatlabAPI_build_intelf10msvs2005.m

Before you run the build scripts, you must select a Fortran compiler:

> mex –setup
(then select a Fortran 95 compiler)

Running the test programs:

MatlabAPI_real, MatlabAPI_complex, MatlabAPI_matfile, and MatlabAPI_implicit are one-line runs with no inputs:

> MatlabAPI_real
> MatlabAPI_complex
> MatlabAPI_matfile
> MatlabAPI_implicit

MatlabAPI_getset also has no inputs, but is designed to be called multiple times (be sure to have the figure uncovered to see the results … you may need to shrink the MATLAB window):

> MatlabAPI_getset
> MatlabAPI_getset
> MatlabAPI_getset
> MatlabAPI_getset
        :
       Etc

MatlabAPI_engine is the engine version of MatlabAPI_getset. It can be run with the bang operator:

> !MatlabAPI_engine

Again, be sure to have the figure uncovered to see the results.

Testing:

I have only tested this suite on 32-bit Windows XP with Intel Fortran 9.1 and 10, and Compaq Fortran 6.1, using various MATLAB versions R2006b – R2009b. I would appreciate it if others with different OS/Machine/Compiler setups can try these out and report back on the results, or maybe send me modified build scripts that worked for their setup. Ultimately I would like this suite to evolve into a package that will work across multiple platforms with multiple compilers.

Future upgrades planned:

- Bug fixes, of course.
- Additional Fortran pointer routines for various functions.
- More extensive test routines.
- Expanded documentation and examples.
- Support for linux and mac machines. But this will depend on other users willing to supply this code to me, since I do not have access to these machines for development or testing.
- Support for 64-bit machines. But this will depend on other users willing to supply this code to me, since I do not have access to these machines for development or testing.

Future upgrades that I *may* consider depending on my time availability and the popularity of MatlabAPI:

- Support for other classes (e.g., single, int8, int16, int32, int64, logical). The current set of routines only work with double class variables.
- More Fortran Pointer routines if I can think of some more ideas on how to use them effectively.
- Support for older versions of MATLAB, particularly versions prior to 7. My guess is that some of the API functions I used might not be compatible. Again, this will depend on other users willing to help modify the code, since I do not have access to these older versions of MATLAB for development or testing.

Feel free to post items of general interest to other users (bug reports, performance data, questions about usage or optimizations, etc) directly on the FEX of course. But if you have modified the code for your version of MATLAB (older version, non-PC machine, non-supported Fortran compiler, etc.) please feel free to contact me directly and I will try to incorporate them into future MatlabAPI upgrades. You can reach me at

    a#lassyguy%ho$mail_com (replace # with k, % with @, $ with t, _ with .)

James Tursa

MATLAB release MATLAB 7.4 (R2007a)
Other requirements Any Fortran 95 compiler that supports the %VAL( ) and LOC( ) or %LOC( ) constructs.
Tags for This File   Please login to tag files.
Please login to add a comment or rating.
Comments and Ratings (35)
18 Feb 2014 Laurent

I tried to use this with gfortran 4.4.5 on Debian and failed. Any instructions on how to get it to run with gfortran and Linux in general? Somebody before mentioned that minor modifications were necessary but didn't give any details.

25 Jan 2014 James Tursa

@ageage Juan: When you compile the modules, the compiler will typically generate both .obj and .mod files (the .mod file maybe with a machine specific extension). When you mex routines that USE these modules, include the .obj file name at the end of your mex command line (you don't need to include the .mod file name in the mex command line because the compiler/linker will automatically look for that)

19 Jan 2014 ageage Juan

May I ask how to use the interface in a Visual Studio FORTRAN project? I am confused that there is no .LIB file generated after I run the set of commands that starts with "Mex -setup" in MATLAB. In this case, I am wondering where I should tell MATLAB to look for files that are applicable to the USE of the interface?

02 Nov 2013 ANDREY

Intel Fortran 14.0 (XE2013 SP1) VS2012 SP1 Matlab 2013b. Naturally to make mex -setup work I had to make special versions of the stp, bat and xml files in changing 13 to 14 everywhere in these text files. For default options compiling this API was easy but for -largeArrayDims one MUST
add /integer_size:64 to the end of set COMPFLAGS= in mexopt.bat (User/.../) if and only if one wants to compile your API with -largeArrayDims. Without this flag one gets a rahter cryptic error MatlabAPImx.f(3436): error #6415: This name cannot be assigned this data type because it conflicts with prior uses of the name. [N]
integer*8, intent(in) :: n

12 Apr 2012 Nik F

This is hugely useful, and -- with some very minor modifications -- works with gfortran under Linux, too. I must confess that I only need a very small subset of this, mostly fpGetPr and mexprint, so I can only comment on that, but it works perfectly.

28 Jul 2011 James Tursa

@Thomas: Thanks for the info. Your post reminds me that I need to upload new files. I think I have fixed all of the size etc type mismatch issues with the new files ... we'll see.

28 Jul 2011 Thomas Clark

(apologies if multiple posting - website form not behaving itself)

I really love this. Thanks, James, for such a comprehensive effort to fix the outdated mess that TMW have made of the FORTRAN interface.

In response to your call for support on platforms other than Windows, I have a few problems and fixes/workarounds:

On a linux box (openSUSE 11.3) with Intel(R) Fortran Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 12.0.1.107 Build 20101116...

Line 3321 of MatlabAPImx.f declares variable n after it is used on the line above. Move that up two lines and problem solved.

After that, I get a long string of errors:

./MatlabAPImx.f(3825): error #6284: There is no matching specific function for this generic function reference. [FPALLOCATE]
fp => fpAllocate(size(mp))
------------^
./MatlabAPImx.f(3825): error #6678: When the target is an expression it must deliver a pointer result. [FPALLOCATE]
fp => fpAllocate(size(mp))
------------^

So there are two issues. The first pertains to the type of the integer used to pass the size variable. Thanks to this website for showing me the way...
http://software.intel.com/en-us/forums/showthread.php?t=44834

The next appears to be a compiler problem (incorrectly diagnosing an error where the % construct is used). Weirdly, Intel say they've fixed the problem but I think the fix hasn't alleviated the issue where generic interfaces are used. Here's the bug report site:
http://software.intel.com/en-us/articles/error-6678-compiler-defect-with-pointer-assignment-to-a-type-bound-procedure-returning-a-pointer/

The workaround for the first issue is to explicitly declare the type of output from size. This is annoying as it has to be redone for each call functions.

The workaround for the second issue is a direct call to the specific function without using the generic function interface.

As a demonstration of working around those problems, here are lines 3812-3833 of MatlabAPImx.f including the workaround:

______

function fpGetPrCopy1Double( mx ) result(fp)

implicit none

real(8), pointer :: fp(:)

!-ARG

mwPointer, intent(in) :: mx

!-LOC
real(8), pointer :: mp(:)
mwSize :: sz

!-----

mp => fpGetPr1(mx)

if( .not.associated(mp) ) then

nullify(fp)

return

endif
sz = size(mp)

fp => fpAllocate1Double(sz)

if( .not.associated(fp) ) then

return

endif

fp = mp

return

end function fpGetPrCopy1Double
_____

It isn't ideal - kind of removes the point of generic interfaces, and it's hassle to go through and fix all of them! Be far better if Intel fixed their compiler!!

24 May 2011 ANDREY

Compilation on Intel Visual Fortran 12.0 (ComposerXE-2011) integrated into VS 2008 SP1 WinXP SP3 32bit

After evident changes in the following files (everywhere '11' was replaced with '12'):
MatlabAPI_build_intelf10msvs2005.m
intelf11msvs2008engmatopts.bat (in MATLAB/bin/Win32/mexopts/)
intelf11msvs2008opts.bat(in MATLAB/bin/Win32/mexopts/)
intelf11msvs2008opts.stp(in MATLAB/bin/Win32/mexopts/)

Then I chose Intel Fortran (mex -setup)

and run MatlabAPI_build_intelf12msvs2008 (made from MatlabAPI_build_intelf10msvs2005.m)

and after several seconds of very optimistically looking reports I ran into the following error:

>> MatlabAPI_build_intelf12msvs2008
MatlabAPI build script for Intel Fortran 12 with MSVS 2008 Linker

... Compiling module MatlabAPImx with large model
... Compiling module MatlabAPImex
... Compiling module MatlabAPIeng
... Compiling module MatlabAPImat
... Compiling MatlabAPI_real.f example
LINK : fatal error LNK1104: cannot open file 'ifconsol.lib'

E:\MATLAB~2\BIN\MEX.PL: Error: Link of 'MatlabAPI_real.mexw32' failed.

I had to copy ifconsol.lib and sevaral other lib files from Intel Fortran/compiler/lib/ia32
to MATLAB/extern/lib/win32/microsoft

and finally all compiled and linked and MatlabAPI_real ran sucessfully.
At the first glance this library is a little gem and its a pity that Mathworks has not incorporated such functions into Matlab MEX interface yet.

07 Apr 2011 Bastian

According to the documentation it is INTEGER*4 for both 32 and 64 bit

30 Mar 2011 James Tursa

@ Bastian: What is the default integer kind on 64-bit Linux ifort? 4 or 8?

29 Mar 2011 Bastian

with gfortran I get (first lines):

In file MatlabAPImx.F90:5953

call MatlabAPI_COM_Apx2( %VAL(ipaddress), stride, &
1
In file MatlabAPImx.F90:10341

subroutine MatlabAPI_COM_Apx2( A, stride, DIMS )
2
Warning (155): Inconsistent types (INTEGER(8)/REAL(8)) in actual argument lists at (1) and (2)
In file MatlabAPImx.F90:5922

call MatlabAPI_COM_Apx2( %VAL(ipaddress), stride, &
1
In file MatlabAPImx.F90:10341

subroutine MatlabAPI_COM_Apx2( A, stride, DIMS )
2
Warning (155): Inconsistent types (INTEGER(8)/REAL(8)) in actual argument lists at (1) and (2)
In file MatlabAPImx.F90:5891

call MatlabAPI_COM_Apx2( %VAL(ipaddress), stride, &

29 Mar 2011 Bastian

On 64-bit, Linux, ifort I get:

MatlabAPI_getset.F90(125): error #6633: The type of the actual argument differs from the type of the dummy argument. [LHS]
k = mexCallMATLAB(0,lhs,0,rhs,"figure")
-------------------------------^
MatlabAPI_getset.F90(125): error #6633: The type of the actual argument differs from the type of the dummy argument. [RHS]
k = mexCallMATLAB(0,lhs,0,rhs,"figure")
-------------------------------------^
MatlabAPI_getset.F90(126): error #6633: The type of the actual argument differs from the type of the dummy argument. [LHS]
k = mexCallMATLAB(0,lhs,3,rhs,"plot")
-------------------------------^
MatlabAPI_getset.F90(126): error #6633: The type of the actual argument differs from the type of the dummy argument. [RHS]
k = mexCallMATLAB(0,lhs,3,rhs,"plot")
-------------------------------------^
MatlabAPI_getset.F90(130): error #6633: The type of the actual argument differs from the type of the dummy argument. [LHS]
k = mexCallMATLAB(1,lhs,0,rhs,"gca")
-------------------------------^
MatlabAPI_getset.F90(130): error #6633: The type of the actual argument differs from the type of the dummy argument. [RHS]
k = mexCallMATLAB(1,lhs,0,rhs,"gca")
-------------------------------------^
MatlabAPI_getset.F90(175): error #6633: The type of the actual argument differs from the type of the dummy argument. [LHS]
k = mexCallMATLAB(0,lhs,2,rhs,"title")
--------------------------^
MatlabAPI_getset.F90(175): error #6633: The type of the actual argument differs from the type of the dummy argument. [RHS]
k = mexCallMATLAB(0,lhs,2,rhs,"title")
--------------------------------^
compilation aborted for MatlabAPI_getset.F90 (code 1)

mex: compile of ' "MatlabAPI_getset.F90"' failed.

And yes, I made the two suggested changes.

27 Jan 2011 Robin  
05 Jan 2011 Mark Shore

Still no luck. I've emailed you the verbose command window output to avoid cluttering this comment section further.

05 Jan 2011 James Tursa

@ Mark Shore: When compiling the modules and all of the examples except the engine example, the build script invokes mex using the default options, which is (I am assuming) the intelf11msvs2008opts.bat file you made. The engine example, however, uses a different options file. Did you make an intelf11msvs2008engmatopts.bat file that the engine example can use? Offhand, I don't know of a reason why the link would work for all of the normal mex options files but not the engine option file.

02 Jan 2011 Mark Shore

Hi James.

I made the suggested change and got the following error:

>> MatlabAPI_build_intelf11msvs2008
MatlabAPI build script for Intel Fortran 11 with MSVS 2008 Linker

... Compiling module MatlabAPImx with large model
... Compiling module MatlabAPImex
... Compiling module MatlabAPIeng
... Compiling module MatlabAPImat
... Compiling MatlabAPI_real.f example
... Compiling MatlabAPI_complex.f example
... Compiling MatlabAPI_getset.f example
... Compiling MatlabAPI_implicit.f example
... Compiling MatlabAPI_matfile.f example
... Compiling MatlabAPI_engine.f example
'link' is not recognized as an internal or external command,
operable program or batch file.

C:\PROGRA~1\MATLAB\R2010B\BIN\MEX.PL: Error: Link of 'MatlabAPI_engine.exe' failed.

??? Error using ==> mex at 208
Unable to complete successfully.

Error in ==> MatlabAPI_build_intelf11msvs2008 at 64
mex('-f', options, 'MatlabAPI_engine.f', 'MatlabAPIeng.obj', 'MatlabAPImx.obj')

Sorry I can't be of more help but I am trying to get my dated Fortran skills up to par with my limited MATLAB ones.

02 Jan 2011 James Tursa

@ Yu Cheong Kim: Intel has confirmed that the "class" issue is a compiler bug. I will be changing my variable names to avoid this and uploading new files sometime this week.

02 Jan 2011 James Tursa

@ prashant: Can you post or e-mail me with the specific error message including the offending lines of code? Which version of Intel compiler are you using? The code has worked for 9.1 and 10.0 for me.

02 Jan 2011 prashant

when I tried compiling "MatlabAPImx.f" file in INTEL compiler. I get following error message
"Error 19 Error: Syntax error, found ',' when expecting one of: => = .(:"

somehow it does not recognize mwPointer command

01 Jan 2011 James Tursa

@ Yu Cheong Kim: Another thing you can try is to replace these lines:

integer*4 classid

with these lines:

integer*4 :: classid

01 Jan 2011 James Tursa

@ Mark Shore: The following files are missing an important include file:

MatlabAPImat.f
MatlabAPImex.f

Change the front end macro section to include the fintrf.h file, e.g., make the front end macro section start like this:

#include "fintrf.h"

#ifndef mwPointer
#define mwPointer integer(4)
#endif

etc.

Sorry about that! I will upload corrected versions next week.

01 Jan 2011 James Tursa

@ Yu Cheong Kim: Intel ifort 11 now includes CLASS as a special identifier, and apparently the compiler is getting confused with the token classid and interpreting it as two tokens class/id. Try renaming the classid variable to something else that does not begin with the letters class, e.g. myclass.

01 Jan 2011 Yu Cheong Kim

@ James Tursa

here is missed my environment at previous my comment

VS2008 ver9. , .net FrameWork 3.5 SP1

01 Jan 2011 Yu Cheong Kim

@James Tursa

1.here is my environment
MATLAB Version 7.11.0.584 (R2010b)
Operating System: Microsoft Windows XP Version 5.1 (Build 2600: Service Pack 3)
Java VM Version: Java 1.6.0_17-b04 with Sun Microsystems Inc. Java HotSpot(TM) Client VM mixed mode
ifort 11.1 048

//and also, the same file run with windows7 and the same error messages are shown at command window

2.run "MatlabAPI_build_intelf10msvs2005.m"
and error messages are...

MatlabAPI build script for Intel Fortran 10 with MSVS 2005 Linker

... Compiling module MatlabAPImx with large model
MatlabAPImx.f(2466): error #5082: Syntax error, found IDENTIFIER 'ID' when expecting one of: ( % : . = =>
classid = mxClassIDFromClassName("logical")
-----------^
MatlabAPImx.f(2517): error #5082: Syntax error, found IDENTIFIER 'ID' when expecting one of: ( % : . = =>
classid = mxClassIDFromClassName("logical")
-----------^
MatlabAPImx.f(2466): error #6404: This name does not have a type, and must have an explicit type. [CLASS]
classid = mxClassIDFromClassName("logical")
------^
MatlabAPImx.f(2466): error #6460: This is not a field name that is defined in the encompassing structure. [ID]
classid = mxClassIDFromClassName("logical")
-----------^
compilation aborted for MatlabAPImx.f (code 1)

C:\PROGRA~1\MATLAB\R2010B\BIN\MEX.PL: Error: Compile of 'MatlabAPImx.f' failed.

??? Error using ==> mex at 208
Unable to complete successfully.

Error in ==> MatlabAPI_build_intelf10msvs2005 at 45
mex -c MatlabAPImx.f

i hope this reply is useful for you :)

31 Dec 2010 James Tursa

@ Yu Cheong Kim: Can you post or e-mail me the specific details of your error messages?

31 Dec 2010 Yu Cheong Kim

@ Mark Shore: Thanks for reply.
in case of me, however, there are errors with "mxClassIDFromClassName" when i put the command >>mex -c MatlabAPImx.f. Is it the problem of path of ifort 11? it may not...

30 Dec 2010 Mark Shore

@ Yu Cheong Kim - that was me. The only change I made was to edit the path to the compiler directory and save it the amended m-file with a new name.

30 Dec 2010 Yu Cheong Kim

@James

can i get "MatlabAPI_build_intelf11msvs2008" freely ?

27 Dec 2010 James Tursa

@ Mark Shore: Thanks for the bug report. I don't have a 64-bit system to test with, but I will look into it. Probably a mismatch in the types somewhere between integer*4 and integer*8 for the pointer or size types.

26 Dec 2010 Mark Shore

Apologies if the following error messages are too long for this format. 64-bit 2010b, Windows 7 64-bit, Intel Fortran 11.1.070. Obvious changes made to the build m-file.

>> MatlabAPI_build_intelf11msvs2008
MatlabAPI build script for Intel Fortran 11 with MSVS 2008 Linker

... Compiling module MatlabAPImx with large model
... Compiling module MatlabAPImex
... Compiling module MatlabAPIeng
... Compiling module MatlabAPImat
... Compiling MatlabAPI_real.f example
... Compiling MatlabAPI_complex.f example
... Compiling MatlabAPI_getset.f example
MatlabAPI_getset.f(125): error #6633: The type of the actual argument differs from the type of the dummy argument. [LHS]
k = mexCallMATLAB(0,lhs,0,rhs,"figure")
-------------------------------^
MatlabAPI_getset.f(125): error #6633: The type of the actual argument differs from the type of the dummy argument. [RHS]
k = mexCallMATLAB(0,lhs,0,rhs,"figure")
-------------------------------------^
MatlabAPI_getset.f(126): error #6633: The type of the actual argument differs from the type of the dummy argument. [LHS]
k = mexCallMATLAB(0,lhs,3,rhs,"plot")
-------------------------------^
MatlabAPI_getset.f(126): error #6633: The type of the actual argument differs from the type of the dummy argument. [RHS]
k = mexCallMATLAB(0,lhs,3,rhs,"plot")
-------------------------------------^
MatlabAPI_getset.f(130): error #6633: The type of the actual argument differs from the type of the dummy argument. [LHS]
k = mexCallMATLAB(1,lhs,0,rhs,"gca")
-------------------------------^
MatlabAPI_getset.f(130): error #6633: The type of the actual argument differs from the type of the dummy argument. [RHS]
k = mexCallMATLAB(1,lhs,0,rhs,"gca")
-------------------------------------^
MatlabAPI_getset.f(164): warning #6075: The data type of the actual argument does not match the definition. [COLOR_NEW]
if( mexSet(handle, "Color", color_new) /= 0 ) then
----------------------------------^
MatlabAPI_getset.f(175): error #6633: The type of the actual argument differs from the type of the dummy argument. [LHS]
k = mexCallMATLAB(0,lhs,2,rhs,"title")
--------------------------^
MatlabAPI_getset.f(175): error #6633: The type of the actual argument differs from the type of the dummy argument. [RHS]
k = mexCallMATLAB(0,lhs,2,rhs,"title")
--------------------------------^
compilation aborted for MatlabAPI_getset.f (code 1)

C:\PROGRA~1\MATLAB\R2010B\BIN\MEX.PL: Error: Compile of 'MatlabAPI_getset.f' failed.

??? Error using ==> mex at 208
Unable to complete successfully.

Error in ==> MatlabAPI_build_intelf11msvs2008 at 57
mex MatlabAPI_getset.f MatlabAPImex.obj MatlabAPImx.obj

25 Dec 2010 James Tursa

@ Yu Cheong Kim: I don't have either of those products to test with, but there is nothing in the package that I am aware of that would not work with that combination.

23 Dec 2010 Yu Cheong Kim

Hello, James Tursa.
i have a queston. does this package still work for release 2010b and ifort 11?

02 Sep 2010 Renwen Lin  
23 Apr 2010 James Tursa

@Etienne: I do not have a linux setup to test with, so my help here may be somewhat limited. I am unaware of anything that would cause compilation errors on linux. You shouldn't have to change any integer*4 to integer*8 in the code ... all integer size or pointer variables use the mwSize and mwPointer macros to get that set properly, and those should be coming from the fintrf.h file for your system. But if they are not set properly in this file, or you are not using this file, then yes you will have to change the #defines for these in my code.

Maybe you could e-mail me with a detailed listing of your compilation errors and I could take a look to see what is going on. We may have to run some small tests with %val( ) etc to figure it out.

22 Apr 2010 Etienne

Hi James

I am trying to compile your functions on linux with the g95 compiler and getting some errors. My questions is if you think it will compile. I am not a linux guru, so I am not sure what changes I need to make to get it running. The obvious ones are changing integer*4 to integer*8 on the 64 bit platform we are using, but then I am lost. Any ideas of some information where I can find out about porting from Windows to Linux?

Cheers

Etienne

Updates
11 Dec 2009

Changed default address function from %LOC( ) to LOC( ). Added a new test routine MatlabAPI_implicit. Fixed some typos in the pdf file.

20 Dec 2009

Fixed another typo in the pdf file.

11 Dec 2011

Fixed hard-coded integer constants in arguments to be mwSize instead (mainly affects 64-bit compiler support). Added 0 argument functionality to fpReshape. Added explicit checks to disallow 0-sized targets.

Contact us