Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Help needed: read 3-dimensional array from a MAT-file in Fortran 90

217 views
Skip to first unread message

HIEU

unread,
Dec 27, 2009, 1:26:03 AM12/27/09
to
Hello,
After fighting the problem the whole Saturday, I think I need some experts' help.

My problem: a 3-dimensional array, say data(m,n,p) where m,n,p are positive integers, is written to a MAT-file in Matlab.

Question: How to read the MAT-file in Fortran F90 and store the data in a similar 3-dimensional array? I am, a novice of course, using Intel Visual Fortran Compiler on XP 32bit.

I tried to use the module MatData.f90 by Chen at:
http://www.mathworks.fr/matlabcentral/fileexchange/4902-matdata-ver-1-02
but was unable to get it to work and received a message "error LNK2019: unresolved external symbol _READ referenced in function _MAIN_"

Below is my simple fortran code to use the module:

PROGRAM READINPUT
USE MatData
IMPLICIT NONE
DOUBLE PRECISION, DIMENSION(2,2,2) :: localvar
CALL READ('test.mat','wind',localvar)
END PROGRAM READINPUT

where test.mat is a MAT-file stores a 2x2x2 array created by MATLAB.
It seems the module MatData.f90 by Chen does not work with Intel Fortran Compiler.

Do you have any idea or suggestion to solve the problem (read 3-dimensional array from a MAT-file in Fortran 90)?
Any helpwould be highly appreciated.
Thanks
Hieu

Rune Allnor

unread,
Dec 27, 2009, 1:41:51 AM12/27/09
to
On 27 Des, 07:26, "HIEU " <nguyenhuyh...@gmail.com> wrote:
> Hello,
> After fighting the problem the whole Saturday, I think I need some experts' help.
>
> My problem: a 3-dimensional array, say data(m,n,p) where m,n,p are positive integers, is written to a MAT-file in Matlab.
>
> Question: How to read the MAT-file in Fortran F90 and store the data in a similar 3-dimensional array? I am, a novice of course, using Intel Visual Fortran Compiler on XP 32bit.

You might be able to use a matlab engine, if this kind
of thing is available for fortran. Check the "External
Interfaces" section of the matlab documentation.

A quick'n dirty solution is to skip the .mat format
alltogether, and instead write the array to a text
file from matla, that is read from fortran. Write the
data as p tables of size m x n, either consecutively
in the same file, or in p files.

This kind of thing is fast to implement, but might
be a bit slow to run if the array is large.

Rune

James Tursa

unread,
Dec 27, 2009, 4:57:02 AM12/27/09
to
"HIEU " <nguyen...@gmail.com> wrote in message <hh6ulr$e38$1...@fred.mathworks.com>...

I wrote a Fortran 95 interface to the MATLAB API that should solve your problem. It has been tested with the Intel Fortran compiler. You can find the submission here:

http://www.mathworks.com/matlabcentral/fileexchange/25934-fortran-95-interface-to-matlab-api-with-extras

In particular, look at the MatlabAPI_matfile.f file for an example of loading variables from a mat file, and MatlabAPI_real.f for examples of turning mxArray variables into Fortran arrays and vice-versa. e.g., this line in the code loads an mxArray variable from the mat file:

mx = matGetVariable(matfile, names(i))

To turn that mxArray variable mx into a regular Fortran array that you can use downstream, I supply two functions. The first function points directly at the mxArray data area, so changes to the target array will be direct changes to the mxArray data area. It can be used like this for a 3D mxArray:

use MatlabAPImx
use MatlabAPImat
:
real(8), pointer :: fp(:,:,:)
:
mx = matGetVariable(matfile, names(i))
if( mx == 0 ) error, so do something
fp => fpGetPr(mx)
if( .not.associated(fp) ) error, so do something
fp(1,2,3) = 5.d0 ! <-- This will change the data area of mx

Then the Fortran pointer fp can be used just like a regular 3D Fortran array in all your downstream code, with changes to the fp target being direct changes to the data area of the mxArray mx. After you are done with the data, destroy the mxArray variable mx:

mxDestroyArray(mx)

The other method is to make a copy of the mxArray mx data area and get a pointer to that. Changes to the target array of this pointer will *not* affect the mxArray mx data area. The use for a 3D array is as follows:

use MatlabAPImx
use MatlabAPImat
:
real(8), pointer :: fp(:,:,:)
:
mx = matGetVariable(matfile, names(i))
if( mx == 0 ) error, so do something
fp => fpGetPrCopy(mx)
if( .not.associated(fp) ) error, so do something
fp(1,2,3) = 5.d0 ! <-- This will *not* change the data area of mx

Like above, this fp can be used downstream in your code just like it was a regular 3D Fortran array. When you are done with the target array of fp and the mxArray mx variable, deallocate fp and destroy mx as follows:

fpDeallocate(fp)
mxDestroyArray(mx)

Take special note ... when you point at the data area of an mxArray directly, you do *not* deallocate the pointer fp. But when you point at a *copy* of the data area of an mxArray, there is newly allocated memory involved that needs to be deallocated with the fpDeallocate function.

If you need help please don't hesitate to post more questions.

James Tursa

James Tursa

unread,
Dec 27, 2009, 5:03:02 AM12/27/09
to
"James Tursa" <aclassyguy_wi...@hotmail.com> wrote in message <hh7b1e$t60$1...@fred.mathworks.com>...
>
> fp => fpGetPr(mx)

Typo, that should be

fp => fpGetPr3(mx)

> fp => fpGetPrCopy(mx)

and that should be

fp => fpGetPrCopy3(mx)

James Tursa

HIEU

unread,
Dec 28, 2009, 1:43:07 AM12/28/09
to
Rune Allnor <all...@tele.ntnu.no> wrote in message <9f0c134a-2bbd-485c...@d20g2000yqh.googlegroups.com>...
@Rune: Thanks for your suggestion. Unfortunately, I am dealing with large arrays so writing them to formatted data file is not so efficient.

HIEU

unread,
Dec 28, 2009, 1:53:08 AM12/28/09
to
@James Tursa: I realized you have been doing a great job on Fortran Interface to MATLAB API. Thanks for your hard work. But I am just a beginner and I need more help on this if you don't mind.

So by copying your routines, I have a Fortran program named readinput.f90 like this:

#include "mex.h"
#include "fintrf.h"

PROGRAM readinput
use MatlabAPImx
use MatlabAPImat

character(len=NameLengthMaxMex), pointer :: names(:)
mwPointer mx, matfile
integer*4 i, k


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

!\
! Open the mat file in read-only mode.
!/
k = mexPrint("... Opening mat file test.mat")
matfile = matOpen("test.mat","r")
if( matfile == 0 ) then
call mexErrMsgTxt("Unable to open mat file")
endif
!\
! Get a list of variable names in the mat file.
!/
k = mexPrint("... List of variable names in the file:")
names => fpMatGetNames(matfile)
if( associated(names) ) then
do i=1,size(names)
k = mexPrint(names(i))
enddo
else
call mexErrMsgTxt("Unable to read the variable names")
endif
!\
! Go get the variables and print out some info
!/
k = mexPrint("... Getting all the variables from the file")
do i=1,size(names)
mx = matGetVariable(matfile, names(i))
if( mx /= 0 ) then
k = mexPrint("Got the variable "//names(i))
!call mxDestroyArray(mx)
else
call mexErrMsgTxt("Unable to get variable "//names(i))
endif
enddo
!call fpDeallocate1CharacterMex(names)

mx = matGetVariable(matfile, wind)
if( mx /= 0 ) then
k = mexPrint("Got the variable "//names(i))
call mxDestroyArray(mx)
else
call mexErrMsgTxt("Unable to get variable "//names(i))
endif

fp => fpGetPr3(mx)
if( .not.associated(fp) ) then
call mxDestroyArray(mx)
call mexErrMsgTxt("Unable to associate pointer fp")
endif

write (*,*) 'Hello, world!' ! This is an inline comment
write (*,*) , fp

! After you are done with the data, destroy the mxArray variable mx:
! mxDestroyArray(mx)

k = mexPrint("... Done.")
k = matClose(matfile)

END PROGRAM readinput


Then I did the followings in Matlab:
1. > mex -setup % set Intel Fortran 11 + Visual Studio 2005 as compiler
2. > options = [matlabroot '\bin\win32\mexopts\intelf11msvs2005opts.bat']
% intelf11msvs2005opts.bat is from the FEX
http://www.mathworks.com/matlabcentral/fileexchange/22290-windows-mex-setup-with-ifort-11-0
3. > mex('-f',options,'readinput.f90')

All I get is a bunch of: "sal.h(502): #error: macro recursion: __pre"
So could you please take a look at my code and point out what I am missing or any error I made? Also, what do I need to do with linking (and compiling)?
many thanks,
Hieu

James Tursa

unread,
Dec 28, 2009, 2:05:21 AM12/28/09
to

First, make sure you have the modules compiled (maybe you have already done this, but you didn't mention it). It is a one-time operation. e.g.,

mex -c MatlabAPImex.f
mex -c MatlabAPImx.f
mex -c MatlabAPImat.f

Then be sure to include the associated object files in your mex command for readinput. e.g.,

mex('-f', options,'readinput.f90','MatlabAPImex.obj','MatlabAPImx.obj','MatlabAPImat.obj')

Also, what is "wind"? I don't see it defined anywhere in your program. Are you trying to read a 3D variable named "wind" from the mat file, or what?

James Tursa

Rune Allnor

unread,
Dec 28, 2009, 4:17:31 AM12/28/09
to
On 28 Des, 07:43, "HIEU " <nguyenhuyh...@gmail.com> wrote:
> Rune Allnor <all...@tele.ntnu.no> wrote in message <9f0c134a-2bbd-485c-9abb-21f2559d6...@d20g2000yqh.googlegroups.com>...

It might be worth a try as a first attempt. It is
usually better to have an inefficient solution that
works, than no solution at all.

Rune

James Tursa

unread,
Dec 28, 2009, 7:17:04 AM12/28/09
to
"James Tursa" <aclassyguy_wi...@hotmail.com> wrote in message <hh9lbh$cp4$1...@fred.mathworks.com>...

I just noticed a couple of other things.

1) You are compiling an engine application but are using mex functions. i.e., You have a program but call the mexPrint function. You can't call any of the mex___ functions inside an engine application.

2) You have included "mex.h" in your Fortran program. You can't do that ... mex.h is strictly for C applications, not Fortran. Delete this line.

Is there some reason why you are building a program instead of a mexFunction routine? If you used a mexFunction interface then passing the variable data would not need the mat file.

Assuming you still want a program, try this:

#include "fintrf.h"

PROGRAM readinput
use MatlabAPImx
use MatlabAPImat

character(len=63), pointer :: names(:)


mwPointer mx, matfile
integer*4 i, k
real(8), pointer :: fp(:,:,:)

!\
! Open the mat file in read-only mode.
!/

write(*,*) "... Opening mat file test.mat"


matfile = matOpen("test.mat","r")
if( matfile == 0 ) then

write(*,*) "Unable to open mat file"
stop


endif
!\
! Get a list of variable names in the mat file.
!/

write(*,*) "... List of variable names in the file:"


names => fpMatGetNames(matfile)
if( associated(names) ) then
do i=1,size(names)

write(*,*) names(i)
enddo
else
write(*,*) "Unable to read the variable names"
stop


endif
!\
! Go get the variables and print out some info
!/

write(*,*) "... Getting all the variables from the file"


do i=1,size(names)
mx = matGetVariable(matfile, names(i))
if( mx /= 0 ) then

write(*,*) "Got the variable "//names(i)
call mxDestroyArray(mx)
else
write(*,*) "Unable to get variable "//names(i)
stop
endif
enddo
call fpDeallocate(names)

mx = matGetVariable(matfile, "wind")


if( mx /= 0 ) then

write(*,*) 'Got the variable "wind"'
else
write(*,*) 'Unable to get variable "wind"'
stop
endif

fp => fpGetPr3(mx)
if( .not.associated(fp) ) then
call mxDestroyArray(mx)

write(*,*) "Unable to associate pointer fp"
stop
endif

write (*,*) 'Hello, world!' ! This is an inline comment
write (*,*) , fp

! After you are done with the data, destroy the mxArray variable mx:

call mxDestroyArray(mx)

write(*,*) "... Done."
k = matClose(matfile)

END PROGRAM readinput


James Tursa

HIEU

unread,
Dec 28, 2009, 12:08:05 PM12/28/09
to
> It might be worth a try as a first attempt. It is
> usually better to have an inefficient solution that
> works, than no solution at all.
>
> Rune

@Rune: You are absolutely right. I will try both approaches. Thank you.

HIEU

unread,
Dec 28, 2009, 12:10:22 PM12/28/09
to
"James Tursa" <aclassyguy_wi...@hotmail.com> wrote in message <hh9lbh$cp4$1...@fred.mathworks.com>...

@James Tursa: yes, "wind" is a 3D variable from the mat file.

HIEU

unread,
Dec 28, 2009, 12:21:04 PM12/28/09
to
"James Tursa" <aclassyguy_wi...@hotmail.com> wrote in message <hha7k0$hml$1...@fred.mathworks.com>...

@ James Tursa: I am grateful to you. Your detailed help is so helpful to a novice like me. I will try it again today and give you an update.

Regarding my problem, I am trying to write a fortran program that can read a 3-dimensional arrays (created by matlab). Since the arrays are large, I would like to write them to a mat-file (binary format). I already have a few fortran subroutines that will take the arrays as inputs and produce results. All the subroutines have *.f90 format. That's why I am writing this f90 fortran program.

Again, thank you.
Hieu

HIEU

unread,
Dec 28, 2009, 2:15:22 PM12/28/09
to
@ James Tursa
I tried the code and got the following errors. Any idea?

>> options = [matlabroot '\bin\win32\mexopts\intelf11msvs2005engmatopts.bat']

options =

C:\Program Files\MATLAB\R2008a\bin\win32\mexopts\intelf11msvs2005engmatopts.bat

>> mex('-f', options,'readinput.f90','MatlabAPImex.obj','MatlabAPImx.obj','MatlabAPImat.obj')

MatlabAPImex.obj : error LNK2019: unresolved external symbol _MEXCALLMATLAB referenced in function _MATLABAPIMEX_mp_MEXCREATESPARSELOGICALMATRIX
MatlabAPImex.obj : error LNK2019: unresolved external symbol _MEXPRINTF referenced in function _MATLABAPIMEX_mp_MEXPRINT
MatlabAPImex.obj : error LNK2019: unresolved external symbol _MEXSETTRAPFLAG referenced in function _MATLABAPIMEX_mp_MEXGET
readinput.exe : fatal error LNK1120: 3 unresolved externals

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

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


As you mentioned before, is this possible to build a mexFunction routine instead in order to do the work? I have no idea how to do that and I would love to be advised.

Thanks,
Hieu

James Tursa

unread,
Dec 28, 2009, 3:00:21 PM12/28/09
to
"HIEU " <nguyen...@gmail.com> wrote in message <hhb04a$5uh$1...@fred.mathworks.com>...

Hi. My bad. I should have been more explicit. For a PROGRAM (also known as an engine application as far as the build process is concerned) you cannot have *any* mex routines in the build. So do not include the 'MatlabAPImex.obj' file in your build. I had that included in my earlier post because I mistakenly assumed you were building a mexFunction routine, which you were not. The mex command should be:

mex('-f', options,'readinput.f90','MatlabAPImx.obj','MatlabAPImat.obj')

See if that works.

For large arrays, the mexFunction approach is the most efficient since no disk writing is involved, and in some cases no data copying either. An example would be:

#include "fintrf.h"
subroutine mexFunction(nlhs, plhs, nrhs, prhs)
use MatlabAPImex
use MatlabAPImx
implicit none
!-ARG
mwPointer plhs(*), prhs(*)
integer*4 nlhs, nrhs
!-LOC


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

!-----
!\
! Check the input
!/
if( nrhs /= 1 ) then
call mexErrMsgTxt("This function needs exactly one input")
endif
if( nlhs /= 0 ) then
call mexErrMsgTxt("This function does not return outputs")
endif
!\
! Get a pointer to the input data
!/
fp => fpGetPr3(prhs(1)) ! Assumes that fp will be used as input only
if( .not.associated(fp) ) then
call mexErrMsgTxt("Unable to associate pointer fp")
endif
!\
! Use the fp array here
!/
call DisplayMatrixExplicit3(fp)
!\
! Done
!/
return
!\
! All of the contained routines have explicit interfaces and can use
! assumed shape arguments.
!/
contains
!----------------------------------------------------------------------
subroutine DisplayMatrixExplicit3(A)
use MatlabAPImex
implicit none
!-ARG
real(8), intent(in) :: A(:,:,:) ! Assumed shape A
!-LOC
mwSize M, N, P
character(len=1000) line
integer(4) i, j, k
mwPointer address
!-----
k = mexPrint("Explicit Interface 3D Matrix Print")
M = size(A,1)
N = size(A,2)
P = size(A,3)
if( M*N*P == 0 ) return
address = %loc(A)
write(line,'(1X,A,Z8)') 'Address of data = ',address
k = mexPrint(line)
do j=1,p
write(line,*) 'Sub-Matrix',j
k = mexPrint(line)
do i=1,M
write(line,*) 'Row',i,' = ',int(A(i,:,j),1)
k = mexPrint(line)
enddo
enddo
return
end subroutine DisplayMatrixExplicit3
!----------------------------------------------------------------------
end subroutine mexFunction

To compile the mexFunction do this (assumes the above file is named passtest.f):

mex passtest.f MatlabAPImex.obj MatlabAPImx.obj

This is just a demonstration routine meant to work with small 3D arrays with integral values (so the printing is reasonable). No checking is done on the printing so if you pass it an array that is too large it will bomb. To run it you can do this:

A = floor(rand(3,3,3)*99) % <-- small size, integral values !!
passtest(A)

Note particularly in this mexFunction example that I do not call fpDeallocate(fp). That is because fp is pointing directly at the input data area, not a copy. That is, fp is pointing directly at the data area of a variable that exists in the MATLAB workspace. So the fp memory must not be freed, and the fp target must be used as read-only in all downstream code. If you wish to modify the fp target then you will need to use fpGetPrCopy3 instead of fpGetPr3, and then at the end you would call fpDeallocate(fp).

James Tursa

HIEU

unread,
Dec 28, 2009, 4:00:23 PM12/28/09
to
"James Tursa" <aclassyguy_wi...@hotmail.com> wrote in message <hhb2ol$lb8$1...@fred.mathworks.com>...

> "HIEU " <nguyen...@gmail.com> wrote in message <hhb04a$5uh$1...@fred.mathworks.com>...
> > @ James Tursa
> > I tried the code and got the following errors. Any idea?
> >
> > >> options = [matlabroot '\bin\win32\mexopts\intelf11msvs2005engmatopts.bat']
> >
> > options =
> >
> > C:\Program Files\MATLAB\R2008a\bin\win32\mexopts\intelf11msvs2005engmatopts.bat
> >
> > >> mex('-f', options,'readinput.f90','MatlabAPImex.obj','MatlabAPImx.obj','MatlabAPImat.obj')
> > MatlabAPImex.obj : error LNK2019: unresolved external symbol _MEXCALLMATLAB referenced in function _MATLABAPIMEX_mp_MEXCREATESPARSELOGICALMATRIX
> > MatlabAPImex.obj : error LNK2019: unresolved external symbol _MEXPRINTF referenced in function _MATLABAPIMEX_mp_MEXPRINT
> > MatlabAPImex.obj : error LNK2019: unresolved external symbol _MEXSETTRAPFLAG referenced in function _MATLABAPIMEX_mp_MEXGET
> > readinput.exe : fatal error LNK1120: 3 unresolved externals
> >
> > C:\PROGRA~1\MATLAB\R2008A\BIN\MEX.PL: Error: Link of 'readinput.exe' failed.
> >
> > ??? Error using ==> mex at 207
> > Unable to complete successfully.
> >
> >
> > As you mentioned before, is this possible to build a mexFunction routine instead in order to do the work? I have no idea how to do that and I would love to be advised.
> >
> > Thanks,
> > Hieu
>
> Hi. My bad. I should have been more explicit. For a PROGRAM (also known as an engine application as far as the build process is concerned) you cannot have *any* mex routines in the build. So do not include the 'MatlabAPImex.obj' file in your build. I had that included in my earlier post because I mistakenly assumed you were building a mexFunction routine, which you were not. The mex command should be:
>
> mex('-f', options,'readinput.f90','MatlabAPImx.obj','MatlabAPImat.obj')
>
> See if that works.
>

@ James Tursa: Thank you. I also tried that mex command before (i.e without matlabAPImex.obj). It does compile but when I run the exe with the bang operator
!readinput.exe
nothing happens.
when I tried to run the exe at a windows command prompt it returns the following runtime error:
Severe:
MATLAB:I18n:MissingICUdata - ICU data not found.
The program '...' has excited with code 2 (0x2)

Have you ever encountered this error? I am running XP pro 32bit. The input file test.mat (holding a simple 3d array) is in the same folder.
Hieu

James Tursa

unread,
Dec 28, 2009, 4:28:03 PM12/28/09
to
"HIEU " <nguyen...@gmail.com> wrote in message <hhb697$46h$1...@fred.mathworks.com>...

Hmmm ... both files I posted work fine with Intel 10.0 WinXP 32-bit. I ran them before posting them. I am not sure what could be different with Intel 11.0. I don't have that compiler to test with. The only thing I could guess at is that not all of the necessary libraries have been linked in. Maybe you could compare the opts.bat files for Intel 10.0 and Intel 11.0 to see what might be missing. Have you tried the mexFunction file yet?

James Tursa

HIEU

unread,
Dec 28, 2009, 7:49:05 PM12/28/09
to
> Hmmm ... both files I posted work fine with Intel 10.0 WinXP 32-bit. I ran them before posting them. I am not sure what could be different with Intel 11.0. I don't have that compiler to test with. The only thing I could guess at is that not all of the necessary libraries have been linked in. Maybe you could compare the opts.bat files for Intel 10.0 and Intel 11.0 to see what might be missing. Have you tried the mexFunction file yet?
>
> James Tursa

Dear James,

I tried the mex file, it compiled but when I ran it with:
>> A = floor(rand(3,3,3)*99);
>> passtest(A)

I got:
??? Invalid MEX-file 'C:\Fortran\passtest.mexw32': The specified procedure could not be found.

I will older Matlab version and see if the readinput program works.
Thanks,
Hieu

James Tursa

unread,
Dec 29, 2009, 2:44:05 AM12/29/09
to
"HIEU " <nguyen...@gmail.com> wrote in message <hhbjm1$r6o$1...@fred.mathworks.com>...

>
> I tried the mex file, it compiled but when I ran it with:
> >> A = floor(rand(3,3,3)*99);
> >> passtest(A)
>
> I got:
> ??? Invalid MEX-file 'C:\Fortran\passtest.mexw32': The specified procedure could not be found.

That message is typical when you compile a mex routine with one version of MATLAB and try to run it under another version, indicating some type of mismatch in the interface. Are you compiling and running with the same version?

James Tursa

James Tursa

unread,
Dec 29, 2009, 2:47:03 AM12/29/09
to
Also, can you just compile a do-nothing mex routine and see if it runs? e.g.,

#include "fintrf.h"
subroutine mexFunction(nlhs, plhs, nrhs, prhs)

mwPointer plhs(*), prhs(*)
integer*4 nlhs, nrhs

return
end subroutine mexFunction

James Tursa

HIEU

unread,
Dec 29, 2009, 11:37:03 AM12/29/09
to
"James Tursa" <aclassyguy_wi...@hotmail.com> wrote in message <hhcc05$70r$1...@fred.mathworks.com>...

Yes, I am running with the same version R2008a.

HIEU

unread,
Dec 29, 2009, 11:46:04 AM12/29/09
to
"James Tursa" <aclassyguy_wi...@hotmail.com> wrote in message <hhcc5m$him$1...@fred.mathworks.com>...

I got the same error. Do you think there are some problems with my MATLAB, Fortran Compiler, or with the bat files?

Hieu

James Tursa

unread,
Dec 29, 2009, 3:59:04 PM12/29/09
to
"HIEU " <nguyen...@gmail.com> wrote in message <hhdboc$ogg$1...@fred.mathworks.com>...

Since I know that Intel Fortran compilers work with MATLAB, and I know that the source files I have given you work with Intel Fortran compilers, that leaves the bat files as the most likely culprit. I assume you got these off of the FEX, since MATLAB does not officially support 11.0 yet. Is that true?

James Tursa

HIEU

unread,
Dec 29, 2009, 8:06:03 PM12/29/09
to
> Since I know that Intel Fortran compilers work with MATLAB, and I know that the source files I have given you work with Intel Fortran compilers, that leaves the bat files as the most likely culprit. I assume you got these off of the FEX, since MATLAB does not officially support 11.0 yet. Is that true?
>
> James Tursa

Yes, I got these file from FEX. I modified them a bit. Can you take a look at them?

1. intelf11msvs2005opts.stp
# $Revision: 1.1.6.1 $ $Date: 2007/12/06 13:15:26 $

# This file updated from the version 10.1 file by Kristjan Jonasson (jona...@hi.is)
# It is accompanied by intelf11msvs2005opts.bat and the pair should be copied to
# the folder c:\program files\matlab\r20xyz\bin\win32\mexopts. Then mex -setup
# should work. NOTE: r20xyz could for example be r2008a or r2008b.


sub intelf11msvs2005opts
{
#===================================================================
# intelf11msvs2005opts: Define where the Intel Visual Fortran
# compiler 11.0 is installed. Also sets language, version, and
# environment variables.
#===================================================================

my $input = shift;
# This is where the vendor installs the compiler by default
my $default_location = "C:\\Program Files\\Intel\\Compiler\\11.1\\038\\bin\\ia32";

# Return language/technology this compiler compiles.
my @language_handled = ('FORTRAN');

# Find MSVC80
my $msvc80_record = callstpfile($input->{'matlab_bin'}."/mexopts/","msvc80opts.stp");
my $msvc80_location_fcn = $msvc80_record->{"locate"};
my @msvc80_locations = &$msvc80_location_fcn;
my $msvc80_dir = pop @msvc80_locations;

my $locate_fcn = sub {
#===================================================================
# locate_fcn: A local function to return potential location where this compiler
# is installed. The return value is used to set the COMPILER_ROOT
# directory. It makes three guesses: The system path, the registry, and
# the default location where the compiler tries to install itself.
#===================================================================

my @ifort_roots = ();

# Search the default environment variable location.
$ifort_root = $ENV{'IFORT_COMPILER11'};
if (-e "$ifort_root\\Bin\\IA32\\ifort.exe"){
if (&correct_version("$ifort_root\\Bin\\IA32\\ifort.exe","11.1")){
push(@ifort_roots, $ifort_root);
}
}

# Search the default install location.
# Verify it is the right version and strip part that is not the ROOT.
if (-e $default_location . "\\Bin\\IA32\\ifort.exe"){
if (&correct_version($default_location . "\\Bin\\IA32\\ifort.exe","11.1")){
push(@ifort_roots, $default_location);
}
}

return @ifort_roots;
};


my $root_val = sub {
my $base_directory = shift;
if (!$msvc80_dir){
my $errMsg="\nError: Microsoft Visual Studio 2005 was not found by mex -setup.\n" .
" The Microsoft Visual Studio 2005 linker is required\n".
" to build Intel Fortran MEX-files. Please make sure that\n".
" Microsoft Visual Studio 2005 is installed properly.\n\n";
die $errMsg;
}

return $base_directory;
};


return {
"vendor_name" => "Intel Visual Fortran",
"version" => "11.1",
"group_id" => "INTELF",
"serial" => 11.1,
"root_var" => "IFORT_COMPILER11",
"linker_var" => "VS80COMNTOOLS",
"optfile_name" => "intelf11msvs2005opts.bat",
"linker_optfile_name" => "msvc80opts",
"default_location" => $default_location,
"language_handled" => \@language_handled,
"root_val" => $root_val,
"link_val" => $msvc80_dir,
"locate" => $locate_fcn,
};
}
1;

2. intelf11msvs2005engmatopts.bat
@echo off
rem INTEL10MSVS2005ENGMATOPTS.BAT
rem
rem Compile and link options used for building stand-alone engine or
rem MAT programs with the Intel® Visual Fortran Compiler 11.0 with the
rem Microsoft® Visual Studio® 2005 linker.
rem
rem This file is updated from the version 10.1 file by Kristjan Jonasson
rem (jona...@hi.is). It is accompanied by intelf11msvs2005opts.stp and
rem intelf11msvs2005opts.bat, and the three files should be copied to the folder
rem c:\program files\matlab\r20xyz\bin\win32\mexopts. Then mex -setup should work
rem NOTE: r20xyz could for example be r2008a or r2008b.
rem
rem $Revision: 1.1.6.1 $ $Date: 2007/12/06 13:15:24 $
rem
rem ********************************************************************
rem General parameters
rem ********************************************************************
set MATLAB=%MATLAB%
set IFORT_COMPILER11=c:\program files\intel\compiler\11.1\038
set VS80COMNTOOLS=%VS80COMNTOOLS%
set LINKERDIR=C:\Program Files\Microsoft Visual Studio 8
set PATH=%IFORT_COMPILER11%\Bin\IA32;%LINKERDIR%\VC\BIN;%LINKERDIR%\Common7\Tools;%LINKERDIR%\Common7\Tools\bin;%LINKERDIR%\Common7\IDE;%LINKERDIR%\SDK\v2.0\bin;%PATH%
set INCLUDE=%IFORT_COMPILER11%\Include\IA32;%IFORT_COMPILER11%\Include;%LINKERDIR%\VC\ATLMFC\INCLUDE;%LINKERDIR%\VC\INCLUDE;%LINKERDIR%\VC\PlatformSDK\include;%INCLUDE%
set LIB=%IFORT_COMPILER11%\Lib\IA32;%LINKERDIR%\VC\ATLMFC\LIB;%LINKERDIR%\VC\LIB;%LINKERDIR%\VC\PlatformSDK\lib;%MATLAB%\extern\lib\win32;%LIB%
set MW_TARGET_ARCH=win32

rem ********************************************************************
rem Compiler parameters
rem ********************************************************************
set COMPILER=ifort
set COMPFLAGS=/fpp /Qprec /I"%MATLAB%/extern/include" /c /nologo /fp:source /MD
set OPTIMFLAGS=/Ox /DNDEBUG
set DEBUGFLAGS=/Zi /Fd"%OUTDIR%%MEX_NAME%.pdb"
set NAME_OBJECT=/Fo

rem ********************************************************************
rem Linker parameters
rem ********************************************************************
set LIBLOC=%MATLAB%\extern\lib\win32\microsoft
set LINKER=link
set LINKFLAGS=/LIBPATH:"%LIBLOC%" libmx.lib libmat.lib libeng.lib /nologo /subsystem:console
set LINKOPTIMFLAGS=
set LINKDEBUGFLAGS=/debug /PDB:"%OUTDIR%%MEX_NAME%.pdb" /INCREMENTAL:NO
set LINK_FILE=
set LINK_LIB=
set NAME_OUTPUT=/out:"%OUTDIR%%MEX_NAME%.exe"
set RSP_FILE_INDICATOR=@

rem ********************************************************************
rem Resource compiler parameters
rem ********************************************************************
set RC_COMPILER=
set RC_LINKER=
set POSTLINK_CMDS1=mt -outputresource:"%OUTDIR%%MEX_NAME%.exe";1 -manifest "%OUTDIR%%MEX_NAME%.exe.manifest"
set POSTLINK_CMDS2=del "%OUTDIR%%MEX_NAME%.exe.manifest"

3. intelf11msvs2005opts.bat
@echo off
rem INTELF11MSVS2005OPTS.BAT
rem
rem Compile and link options used for building MEX-files using the
rem Intel® Fortran Compiler 11.1 with the Microsoft® Visual Studio®
rem 2005 linker.
rem
rem This file updated from the version 10.1 file by Kristjan Jonasson (jona...@hi.is)
rem It is accompanied by intelf11msvs2005opts.stp and the pair should be copied to
rem the folder c:\program files\matlab\r20xyz\bin\win32\mexopts. Then mex -setup
rem should work. NOTE: r20xyz could for example be r2008a or r2008b.
rem
rem StorageVersion: 1.0
rem FortrankeyFileName: INTELF11MSVS2005OPTS.BAT
rem FortrankeyName: Intel Visual Fortran
rem FortrankeyManufacturer: Intel
rem FortrankeyVersion: 11.0
rem FortrankeyLanguage: Fortran
rem
rem $Revision: 1.1.6.1 $ $Date: 2007/12/06 13:15:25 $
rem
rem ********************************************************************
rem General parameters
rem ********************************************************************
set MATLAB=%MATLAB%
set IFORT_COMPILER11=c:\program files\intel\compiler\11.1\038
set VS80COMNTOOLS=%VS80COMNTOOLS%
set LINKERDIR=C:\Program Files\Microsoft Visual Studio 8
set PATH=%IFORT_COMPILER11%\Bin\ia32;%LINKERDIR%\VC\BIN;%LINKERDIR%\Common7\Tools;%LINKERDIR%\Common7\Tools\bin;%LINKERDIR%\Common7\IDE;%LINKERDIR%\SDK\v2.0\bin;%PATH%
set INCLUDE=%IFORT_COMPILER11%\Include\ia32;%IFORT_COMPILER11%\Include;%LINKERDIR%\VC\ATLMFC\INCLUDE;%LINKERDIR%\VC\INCLUDE;%LINKERDIR%\VC\PlatformSDK\include;%INCLUDE%
set LIB=%IFORT_COMPILER11%\Lib\IA32;%LINKERDIR%\VC\ATLMFC\LIB;%LINKERDIR%\VC\LIB;%LINKERDIR%\VC\PlatformSDK\lib;%MATLAB%\extern\lib\win32;%LIB%
set MW_TARGET_ARCH=win32

rem ********************************************************************
rem Compiler parameters
rem ********************************************************************
set COMPILER=ifort
set COMPFLAGS=/fpp /Qprec "/I%MATLAB%/extern/include" -c -nologo -DMATLAB_MEX_FILE /MD /fp:source
set OPTIMFLAGS=-Ox -DNDEBUG
set DEBUGFLAGS=/Z7
set NAME_OBJECT=/Fo

rem ********************************************************************
rem Linker parameters
rem ********************************************************************
set LIBLOC=%MATLAB%\extern\lib\win32\microsoft
set LINKER=link
set LINKFLAGS=/DLL /EXPORT:MEXFUNCTION /LIBPATH:"%LIBLOC%" libmx.lib libmex.lib libmat.lib /implib:"%LIB_NAME%.x" /MAP:"%OUTDIR%%MEX_NAME%%MEX_EXT%.map" /NOLOGO /INCREMENTAL:NO
set LINKOPTIMFLAGS=
set LINKDEBUGFLAGS=/debug /PDB:"%OUTDIR%%MEX_NAME%%MEX_EXT%.pdb"
set LINK_FILE=
set LINK_LIB=
set NAME_OUTPUT="/out:%OUTDIR%%MEX_NAME%%MEX_EXT%"
set RSP_FILE_INDICATOR=@

rem ********************************************************************
rem Resource compiler parameters
rem ********************************************************************
set RC_COMPILER=rc /fo "%OUTDIR%mexversion.res"
set RC_LINKER=

set POSTLINK_CMDS=del "%OUTDIR%%MEX_NAME%%MEX_EXT%.map"
set POSTLINK_CMDS1=del "%LIB_NAME%.x" "%LIB_NAME%.exp"
set POSTLINK_CMDS2=mt -outputresource:"%OUTDIR%%MEX_NAME%%MEX_EXT%";2 -manifest "%OUTDIR%%MEX_NAME%%MEX_EXT%.manifest"
set POSTLINK_CMDS3=del "%OUTDIR%%MEX_NAME%%MEX_EXT%.manifest"

Did you see anything wrong?
Thanks,
Hieu

James Tursa

unread,
Dec 30, 2009, 3:53:03 AM12/30/09
to
"HIEU " <nguyen...@gmail.com> wrote in message <hhe91r$sgn$1...@fred.mathworks.com>...

> > Since I know that Intel Fortran compilers work with MATLAB, and I know that the source files I have given you work with Intel Fortran compilers, that leaves the bat files as the most likely culprit. I assume you got these off of the FEX, since MATLAB does not officially support 11.0 yet. Is that true?
> >
> > James Tursa
>
> Yes, I got these file from FEX. I modified them a bit. Can you take a look at them?
>

I have never examined these files in any detail, so it would take some time to try to ferret out the problem of 10.0 vs 11.0. Presumably the original files worked for the author that posted them to the FEX. May I ask what changes you made and why?

James Tursa

HIEU

unread,
Dec 30, 2009, 12:57:21 PM12/30/09
to
> I have never examined these files in any detail, so it would take some time to try to ferret out the problem of 10.0 vs 11.0. Presumably the original files worked for the author that posted them to the FEX. May I ask what changes you made and why?
>
> James Tursa

I did not make many changes but only the the path of the installation directory to make the bat files work:
for example:
set IFORT_COMPILER11=c:\program files\intel\compiler\11.0\066\Fortran
was changed to:


set IFORT_COMPILER11=c:\program files\intel\compiler\11.1\038

Hieu

HIEU

unread,
Jan 1, 2010, 2:24:04 AM1/1/10
to
@James Tursa: Happy New Year! Thank your for all your help.
Hieu
0 new messages