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

Calling Matlab from Fortran

forall
Beginner
1,710 Views
I am trying to call Matlab functions from within Fortran - mainly to use Matlab plotting facilities, but in principle I would like to use some of their numerics as well.

Looking through the web the only somewhat promising way I found was

ok=system("matlab /Automation commandText") or ok=system("matlab commandText")

where commandText is the command sent to matlab which may include setting variables, calling functions, etc. The /Automation just controls the mode Matlab starts in.

While this works in principle, it opens a new Matlab window/memory-space everytime, which isnt helpful when I try to do a sequence of commands. Is there any way to force the execution in the already-opened window (without using matlab scripts)?

Otherwise, any other approaches for accessing Matlab from Fortran that anybody was able to implement? Thanks in advance!


0 Kudos
1 Solution
IanH
Honored Contributor III
1,710 Views
Quoting - forall
1) While experimenting I did notice that IFAUTO is not used in your code - is it actually necessary?

I guess not! It will be a left over from something else.

2) ...

But what did you mean by "Fortran-77 interfaces, required preprocessor, external build script, etc.? I didnt end up using any of these.. At least I dont think I did ...

I just compiled an adjusted version of the Matlab-provided sample .f file - they didnt have the IMPLICIT NONE (oh, mine!!!) and so some integer handles became real values for about 40mins while I was trying to figure out the cause of access violation... argghhh!!!!


Its just personal preference. Given the documentation directs you towards use of the eng* routines that's probably where you should go. But I dislike:

  • the fact that the recommended way of building things requires use of the mex build script (previously I recall studying the script and appling the same settings within the VS IDE, but that's a nuisance)
  • that all the procedure interfaces are implicit (hence "F77 style" - as opposed to INTERFACE blocks), so argument mismatches will slip though undiagnosed, as you experienced.
  • that relevant variable definitions use a non-Fortran syntax (ie mwPointer p, versus something like INTEGER (pointer_kind) p, or TYPE(Pointer) p).
  • Related to the above, that your code needs to use the C preprocessor (#include, #define and friends) to mutate variable types and procedure names. Mutated variable names then use nonstandard INTEGER*kind rather than INTEGER(kind) style declarations.
Since the advent of F90, and particularly since the advent of the C interoperability features of F2003, none of the above is required. Things could be so much easier out-of-the-box with a mathworks provided module. But, as you note, given their examples don't have IMPLICIT NONE and are written in fixed form source, it looks like the Mathworks are happy being two decades out of date with respect to Fortran.

But that said, I also hate all the mucking around that you have to do with COM. So I guess you can't win.

Either way wrapper modules are the way to go. I actually started to put something together a while back to use the C libraries that are provided with Matlab from Fortran (using F03's C-interop), but got distracted.

View solution in original post

0 Kudos
5 Replies
IanH
Honored Contributor III
1,710 Views
You've got two options:

1. Use the Intel Fortran Module Wizard to generate the appropriate interfaces to the Matlab Automation server and then use those interfaces along with the supporting routines provided by the IFCOM and IFAUTO modules. Stupid example attached.

2. You could use the routines exposed by the Matlab engine. This is what the mathworks recommends, but I hate the old F77 style call interfaces, use of the pre-processor, requirement for an external build script, etc, etc. Supposedly this is just a wrapper around the COM stuff anyway.

You could wrap either method with your own set of interface routines to make your life easier.

Matlab's own documentation includes lots of supporting material.

IanH

0 Kudos
forall
Beginner
1,710 Views
Quoting - IanH
You've got two options:

1. Use the Intel Fortran Module Wizard to generate the appropriate interfaces to the Matlab Automation server and then use those interfaces along with the supporting routines provided by the IFCOM and IFAUTO modules. Stupid example attached.

2. You could use the routines exposed by the Matlab engine. This is what the mathworks recommends, but I hate the old F77 style call interfaces, use of the pre-processor, requirement for an external build script, etc, etc. Supposedly this is just a wrapper around the COM stuff anyway.

You could wrap either method with your own set of interface routines to make your life easier.

Matlab's own documentation includes lots of supporting material.

IanH


Thanks a lot Ian!

I spent about 2 days searching through the web and the matlab help - its crystal-clear once you know the solution to the problem you are trying to get help on :-). The main problem was they keep talking about using their MEX compiler - which seems a very 'awkward' tool in its own right - and as I now understood just obscures the real issues.

But after your post I had your code running in 10mins (I never used the Module Wizard - what a nifty tool!) and I am seeing (more or less) how this all fits together.

A few quick questions:

1) While experimenting I did notice that IFAUTO is not used in your code - is it actually necessary?

2) I also quickly implemented an analogous code using the native Matlab commands (engGetVariable, etc) - after I coincidentally found a semi-working example on the mathworks website. It was also relatively straightforward once I understood the mechanism.

But what did you mean by "Fortran-77 interfaces, required preprocessor, external build script, etc.? I didnt end up using any of these.. At least I dont think I did ...

I just compiled an adjusted version of the Matlab-provided sample .f file - they didnt have the IMPLICIT NONE (oh, mine!!!) and so some integer handles became real values for about 40mins while I was trying to figure out the cause of access violation... argghhh!!!!

But the actual calls to the matlab-provided tools seem clean-enough.

Or am I missing something regarding the relative merits of your strategies 1 and 2? I am happy to hear an advanced explanation if thats what it takes (and if you have the inclination to do so) , since I'd rather invest my time from the start into a better code (I will indeed write wrappers etc to hide that ugliness).

thanks for ur help - and in advance!
dmitri
0 Kudos
IanH
Honored Contributor III
1,711 Views
Quoting - forall
1) While experimenting I did notice that IFAUTO is not used in your code - is it actually necessary?

I guess not! It will be a left over from something else.

2) ...

But what did you mean by "Fortran-77 interfaces, required preprocessor, external build script, etc.? I didnt end up using any of these.. At least I dont think I did ...

I just compiled an adjusted version of the Matlab-provided sample .f file - they didnt have the IMPLICIT NONE (oh, mine!!!) and so some integer handles became real values for about 40mins while I was trying to figure out the cause of access violation... argghhh!!!!


Its just personal preference. Given the documentation directs you towards use of the eng* routines that's probably where you should go. But I dislike:

  • the fact that the recommended way of building things requires use of the mex build script (previously I recall studying the script and appling the same settings within the VS IDE, but that's a nuisance)
  • that all the procedure interfaces are implicit (hence "F77 style" - as opposed to INTERFACE blocks), so argument mismatches will slip though undiagnosed, as you experienced.
  • that relevant variable definitions use a non-Fortran syntax (ie mwPointer p, versus something like INTEGER (pointer_kind) p, or TYPE(Pointer) p).
  • Related to the above, that your code needs to use the C preprocessor (#include, #define and friends) to mutate variable types and procedure names. Mutated variable names then use nonstandard INTEGER*kind rather than INTEGER(kind) style declarations.
Since the advent of F90, and particularly since the advent of the C interoperability features of F2003, none of the above is required. Things could be so much easier out-of-the-box with a mathworks provided module. But, as you note, given their examples don't have IMPLICIT NONE and are written in fixed form source, it looks like the Mathworks are happy being two decades out of date with respect to Fortran.

But that said, I also hate all the mucking around that you have to do with COM. So I guess you can't win.

Either way wrapper modules are the way to go. I actually started to put something together a while back to use the C libraries that are provided with Matlab from Fortran (using F03's C-interop), but got distracted.
0 Kudos
forall
Beginner
1,710 Views
Quoting - IanH
Its just personal preference. Given the documentation directs you towards use of the eng* routines that's probably where you should go. But I dislike:

  • the fact that the recommended way of building things requires use of the mex build script (previously I recall studying the script and appling the same settings within the VS IDE, but that's a nuisance)
  • that all the procedure interfaces are implicit (hence "F77 style" - as opposed to INTERFACE blocks), so argument mismatches will slip though undiagnosed, as you experienced.
  • that relevant variable definitions use a non-Fortran syntax (ie mwPointer p, versus something like INTEGER (pointer_kind) p, or TYPE(Pointer) p).
  • Related to the above, that your code needs to use the C preprocessor (#include, #define and friends) to mutate variable types and procedure names. Mutated variable names then use nonstandard INTEGER*kind rather than INTEGER(kind) style declarations.
Either way wrapper modules are the way to go. I actually started to put something together a while back to use the C libraries that are provided with Matlab from Fortran (using F03's C-interop), but got distracted.


Ian,

I attach a file showing calls to Matlab from CVF/IVF without all the #include and mwpointer stuff - just linking to 3 matlab-provided .lib files and all with standard Fortran (as far as I can see). I didnt bother converting to free-form: once in a while its fun to have fixed-form :-) But since the MEX compiler is not used, the code works in both free and fixed form. No preprocesssing scripts are needed either.

Though I agree the implicit interfaces is a rather inconvenient drawback and so I will write a proper COM interface when i have more time.

I would also be keen to see your Matlab-Fortran C library if it can help clarify these things.

thanks!
d
0 Kudos
IanH
Honored Contributor III
1,710 Views
Yep - good stuff. I can see that I've done that with the mat* library calls when writing a DLL that's called by matlab (ok, so why didn't I do this for the eng* calls when going the other way and avoid COM? I've got no idea...). You could also safeguard against potential 32/64 bit issues (or compiler options changing the default kinds) by parameterising your variable kinds (I've used C_INTPTR_T from ISO_C_BINDING for the kind of the mwpointer replacement, I presume that's suitable?). For legacy code the preprocessing actually renames some function calls, but I guess that shouldn't be an issue going forward.
0 Kudos
Reply