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

question about calling matlab function

张_堃_
Beginner
4,381 Views

hello:

        I'm learning about how to call matlab function by fortran , and I start with the example  matlabroot/extern/ examples/eng_mat/fengdemo.F, here is the code:

 

#include "engine.h"        
#include "fintrf.h"
#if 0
C     fengdemo.F
C     .F file need to be preprocessed to generate .for equivalent
C
#endif
C
C     fengdemo.f
C     This is a simple program that illustrates how to call the MATLAB
C     Engine functions from a FORTRAN program.
C
C Copyright 1984-2005 The MathWorks, Inc.
C======================================================================
C $Revision: 1.9.4.4 $
      program main
C-----------------------------------------------------------------------
C     (pointer) Replace integer by integer*8 on 64-bit platforms
C
      mwpointer engOpen, engGetVariable, mxCreateDoubleMatrix
      mwpointer mxGetPr
      mwpointer ep, T, D 
C----------------------------------------------------------------------
C
C     Other variable declarations here
      double precision time(10), dist(10)
      integer engPutVariable, engEvalString, engClose
      integer temp, status
      data time / 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 /
      ep = engOpen('matlab ')
      if (ep .eq. 0) then
         write(6,*) 'Can''t start MATLAB engine'
         stop
      endif
      T = mxCreateDoubleMatrix(1, 10, 0)
      call mxCopyReal8ToPtr(time, mxGetPr(T), 10)
C     Place the variable T into the MATLAB workspace
      status = engPutVariable(ep, 'T', T)
      if (status .ne. 0) then 
         write(6,*) 'engPutVariable failed'
         stop
      endif
C     Evaluate a function of time, distance = (1/2)g.*t.^2
C     (g is the acceleration due to gravity)
      if (engEvalString(ep, 'D = .5.*(-9.8).*T.^2;') .ne. 0) then
         write(6,*) 'engEvalString failed'
         stop
      endif
C     Plot the result
      if (engEvalString(ep, 'plot(T,D);') .ne. 0) then 
       write(6,*) 'engEvalString failed'
         stop
      endif
      if (engEvalString(ep, 'title(''Position vs. Time'')') .ne. 0) then
          write(6,*) 'engEvalString failed'
          stop
      endif
      if (engEvalString(ep, 'xlabel(''Time (seconds)'')') .ne. 0) then
          write(6,*) 'engEvalString failed'
          stop
      endif
      if (engEvalString(ep, 'ylabel(''Position (meters)'')') .ne. 0)then
          write(6,*) 'engEvalString failed'
          stop
      endif
C     read from console to make sure that we pause long enough to be
C     able to see the plot
      print *, 'Type 0 <return> to Exit'
      print *, 'Type 1 <return> to continue'
      read(*,*) temp
      if (temp.eq.0) then
         print *, 'EXIT!'
         status = engClose(ep)
         if (status .ne. 0) then 
            write(6,*) 'engClose failed'
         endif
         stop
      end if
      if (engEvalString(ep, 'close;') .ne. 0) then
         write(6,*) 'engEvalString failed'
         stop
      endif 
      D = engGetVariable(ep, 'D')
      call mxCopyPtrToReal8(mxGetPr(D), dist, 10)
      print *, 'MATLAB computed the following distances:'
      print *, '  time(s)  distance(m)'
      do 10 i=1,10
         print 20, time(i), dist(i)
 20      format(' ', G10.3, G10.3)
 10   continue
      call mxDestroyArray(T)
      call mxDestroyArray(D)
      status = engClose(ep)
      if (status .ne. 0) then 
         write(6,*) 'engClose failed'
         stop
      endif
      stop
      end

I use  ifort -I '/opt/MATLAB/extern/include' -B '/opt/MATLAB/extern/lib/glnx86'  fengdemo.F  to compile this,but it shows:

 

tmwtypes.h(125): #error: #if: syntax error.
tmwtypes.h(137): #error: #if: syntax error.
tmwtypes.h(149): #error: #if: syntax error.
tmwtypes.h(161): #error: #if: syntax error.
tmwtypes.h(173): #error: #if: syntax error.
tmwtypes.h(703): #error: #if: syntax error.
tmwtypes.h(776): #warning: keyword redefined: false
tmwtypes.h(779): #warning: keyword redefined: true
tmwtypes.h(790): #error: #if: syntax error.
tmwtypes.h(791): #error:  "This code must be compiled using a 2's complement representation for signed integer values"
features.h(184): #error: #if: syntax error.
features.h(202): #error: #if: syntax error.
features.h(206): #error: #if: syntax error.
features.h(210): #error: #if: syntax error.
features.h(214): #error: #if: syntax error.
features.h(218): #error: #if: syntax error.
features.h(322): #error: #if: syntax error.
cdefs.h(145): #error: #if: syntax error.
cdefs.h(304): #error: #if: syntax error.
stdlib.h(530): #error: incomplete macro call __nonnull.
stdlib.h(532): #error: '#ifdef' argument starts with wrong symbol.
stdlib.h(606): #error: '#ifdef' argument starts with wrong symbol.
stdlib.h(611): #error: #if: syntax error.
features.h(20): #error: '#ifndef' argument starts with wrong symbol.
features.h(21): #error: bad macro name.
features.h(118): #error: bad macro name.
features.h(122): #error: bad macro name.
features.h(184): #error: #if: syntax error.
features.h(202): #error: #if: syntax error.
features.h(206): #error: #if: syntax error.
features.h(210): #error: #if: syntax error.
features.h(214): #error: #if: syntax error.
features.h(218): #error: #if: syntax error.
features.h(322): #error: #if: syntax error.
assert.h(109): #error: #if: syntax error.

I don't know why ,could you help me ?

0 Kudos
20 Replies
Steven_L_Intel1
Employee
4,247 Views

Judging by the error messages, you're including one or more C headers, which Fortran isn't going to like.

0 Kudos
mecej4
Honored Contributor III
4,247 Views

The command "ifort /LD /fpp fengdemo.F libeng.lib libmx.lib" will build the MEX file for Win32, provided the Matlab include and library paths have been appended to %INCLUDE% and %LIB% environmental variables.

I do not have Matlab installed for Linux, but you should be able to adapt the above-mentioned build step to Linux.

0 Kudos
Timothy_P_Intel
Employee
4,247 Views

If the include files contain Fortran code, the -fpp option is needed to engage pre-processing.  The .F file naming will do this by default on linux, but not on Windows.

0 Kudos
Steven_L_Intel1
Employee
4,247 Views

This is the Linux/OS X forum, so I assumed Linux. Also the command line given is Linux/OS X. But the error messages strongly suggest that one of the .h files being #include-ed is for C, not Fortran. You can't mix these. The preprocessor is running, but it is seeing things it doesn't like. Unfortunately, while we can see the Fortran code, which looks fine, we can't see the .h files that are triggering the errors.

0 Kudos
Roman1
New Contributor I
4,247 Views

I have found a file "engine.h" in my Matlab installation, and it is definitely a C include file.  The other include file "fintrf.h" is a Fortran file.

 

0 Kudos
mecej4
Honored Contributor III
4,247 Views

It is possible for an include file to be valid when included in a Fortran source file and when included in a C/C++ source file. For instance, if the included file contains #define directives, and the syntax is accepted by a C preprocessor, the preprocessor output may produce correct C code or correct Fortran code after token substitutions are performed.

0 Kudos
张_堃_
Beginner
4,247 Views

Steve Lionel (Intel) wrote:

This is the Linux/OS X forum, so I assumed Linux. Also the command line given is Linux/OS X. But the error messages strongly suggest that one of the .h files being #include-ed is for C, not Fortran. You can't mix these. The preprocessor is running, but it is seeing things it doesn't like. Unfortunately, while we can see the Fortran code, which looks fine, we can't see the .h files that are triggering the errors.


thank you for your answer ,I sorry that I didn't mentioned  I'm using Linux, and I looked for the user's guide ,it says:


"You do not usually need to specify preprocessing for Fortran source programs.
The preprocessor is necessary only if your program uses C-style preprocessing
commands, such as #if, #define, and so forth.
Intel® Fortran Compiler for Linux* Systems User’s Guide Vol I
If you choose to preprocess your source programs, you must use the
preprocessor fpp, which is the preprocessor supplied with the Intel® Fortran
Compiler, or the preprocessing capability of a Fortran compiler. It is
recommended that you use fpp."


So I think that the preprocessor support this,and this is part of the .h file that cause errors:
# if   INT_MAX  == 0x7FL
# if   LONG_MAX  == 0x7FL
# if   SHRT_MAX  == 0x7FL

And when I use gfortran to compile this ,I get this error message :""You need a ISO C conforming compiler to use the glibc headers"" , so now I'm confused  , although I found that I can use lapack instead of calling  matlab ,but I still want to learn how to use the preprocessor ,thank you very much !

0 Kudos
张_堃_
Beginner
4,247 Views

Roman wrote:

I have found a file "engine.h" in my Matlab installation, and it is definitely a C include file.  The other include file "fintrf.h" is a Fortran file.

 

Thank you for your answer ,but  I found that both  "engine.h"  and  "fintrf.h" are  C include files on my computer,I think the intel fortran compile support this  while I found this in it's user's guide:


You do not usually need to specify preprocessing for Fortran source programs.
The preprocessor is necessary only if your program uses C-style preprocessing
commands, such as #if, #define, and so forth.
If you choose to preprocess your source programs, you must use the
preprocessor fpp, which is the preprocessor supplied with the Intel® Fortran
Compiler, or the preprocessing capability of a Fortran compiler. It is
recommended that you use fpp.

0 Kudos
TimP
Honored Contributor III
4,247 Views

Fortran doesn't support the C format for hexadecimal constant. In Fortran, those would be something like z'7f'  (if in 32-bit mode).  I wouldn't be totally surprised if fpp didn't support all the variations of hexadecimal in pre-processing.  The terminology "C-style pre-processing" doesn't mean that C can be translated to Fortran.  It does mean that it's outside the Fortran standard, so you will see differences between gfortran and ifort when you push the boundaries.  There are even differences between the ifort fpp and the open source one.  If you have something which doesn't work with any of the Fortran pre-processors, you can't expect them all to produce the same error messages.

The comment from gfortran  further supports the suggestion that you have C syntax in the include files which can't be pre-processed away even when using a C pre-processor.  As gfortran uses a C89 pre-processor, it may not choke on C code at the pre-processor stage, but that doesn't mean that the result of pre-processing can be accepted as Fortran.  If it's a question of the hexadecimals, the C form has to be acceptable for pre-processing by gfortran because it's processing C code at that stage, where the Fortran hexadecimal wouldn't work in a pre-processor comparison.

0 Kudos
张_堃_
Beginner
4,247 Views

Tim Prince wrote:

Fortran doesn't support the C format for hexadecimal constant. In Fortran, those would be something like z'7f'  (if in 32-bit mode).  I wouldn't be totally surprised if fpp didn't support all the variations of hexadecimal in pre-processing.  The terminology "C-style pre-processing" doesn't mean that C can be translated to Fortran.  It does mean that it's outside the Fortran standard, so you will see differences between gfortran and ifort when you push the boundaries.  There are even differences between the ifort fpp and the open source one.  If you have something which doesn't work with any of the Fortran pre-processors, you can't expect them all to produce the same error messages.

The comment from gfortran  further supports the suggestion that you have C syntax in the include files which can't be pre-processed away even when using a C pre-processor.  As gfortran uses a C89 pre-processor, it may not choke on C code at the pre-processor stage, but that doesn't mean that the result of pre-processing can be accepted as Fortran.  If it's a question of the hexadecimals, the C form has to be acceptable for pre-processing by gfortran because it's processing C code at that stage, where the Fortran hexadecimal wouldn't work in a pre-processor comparison.

Thank for your answer, the .h files and the fortran example are written by Mathworks,  I wonder which fortran compile they use , I asked the same question on their forum , but unfortunately no one answers......

0 Kudos
Steven_L_Intel1
Employee
4,247 Views

At this point I suggest you ask Matlab support about which include files you should be using. I still think you've got the wrong one(s).

0 Kudos
张_堃_
Beginner
4,247 Views

Steve Lionel (Intel) wrote:

At this point I suggest you ask Matlab support about which include files you should be using. I still think you've got the wrong one(s).

Ok, thank you for your answer

0 Kudos
mecej4
Honored Contributor III
4,247 Views

张 堃:

I do not know which versions of Matlab and IFort you are using, and whether you are targeting 32-bit or 64-bit. I have access to a system running openSuse 12.3-X64 and Matlab 2007b X-64. On this system, I compiled the Mathworks-supplied fengdemo.F, which contains the line include "fintrf.h", using IFort 13.0.1, using the commands

     ifort -I $MLDIR/extern/include/ -c -fPIC fengdemo.F

     ifort -shared fengdemo.o -o fengdemo.mexa64 -L $MLDIR/bin/glnxa64/ -leng -lmat -lmx

The mex file was produced and I received no warning or error messages.

I recognize that this particular example is intended to be used to build an a.out file rather than a shared object, but at the preprocessing and compiling stages that fact should not matter.

0 Kudos
张_堃_
Beginner
4,247 Views

mecej4 wrote:
张 堃:

I do not know which versions of Matlab and IFort you are using, and whether you are targeting 32-bit or 64-bit. I have access to a system running openSuse 12.3-X64 and Matlab 2007b X-64. On this system, I compiled the Mathworks-supplied fengdemo.F, which contains the line include "fintrf.h", using IFort 13.0.1, using the commands

     ifort -I $MLDIR/extern/include/ -c -fPIC fengdemo.F

     ifort -shared fengdemo.o -o fengdemo.mexa64 -L $MLDIR/bin/glnxa64/ -leng -lmat -lmx

The mex file was produced and I received no warning or error messages.

I recognize that this particular example is intended to be used to build an a.out file rather than a shared object, but at the preprocessing and compiling stages that fact should not matter.

Thank for your answer, I found I included the wrong file 'engine.h'... Now it seems ok 

0 Kudos
mecej4
Honored Contributor III
4,247 Views

张 堃. wrote:

I found I included the wrong file 'engine.h'... Now it seems ok 

Yes; 'engine.h' is used only in the C examples of using the engine interface.

0 Kudos
张_堃_
Beginner
4,247 Views

mecej4 wrote:

Quote:

张 堃. wrote:

I found I included the wrong file 'engine.h'... Now it seems ok 

 

Yes; 'engine.h' is used only in the C examples of using the engine interface.

Hello, I type the same command as your's on my computer ,but I get this:
ipo: warning #11010: file format not recognized for /opt/MATLAB/bin/glnx86/libeng.so
ipo: warning #11010: file format not recognized for /opt/MATLAB/bin/glnx86/libmat.so
ipo: warning #11010: file format not recognized for /opt/MATLAB/bin/glnx86/libmx.so


can you help me? I run successfully under windows ,but I not so familiar with linux...

0 Kudos
mecej4
Honored Contributor III
4,247 Views

Which version of Matlab do you use on Linux? You may try turning off -ipo or using an optimization level that does not invoke IPO (InterProcedureOptimizations).

0 Kudos
张_堃_
Beginner
4,247 Views

mecej4 wrote:

Which version of Matlab do you use on Linux? You may try turning off -ipo or using an optimization level that does not invoke IPO (InterProcedureOptimizations).


It's 7.10 ,I thought it's may be the environment variable that lead to problem, when I use the engine on windows the first time ,I didn't add the matlabroot/bin/win64 (my windows system is 64 bit and linux is 32 bit )to the environment variable 'PATH' ,and I got the same question ,but after I add the /opt/MATLAB/bin/glnx86 to .bash_profile, the problem is still there...

0 Kudos
张_堃_
Beginner
4,247 Views

mecej4 wrote:

Which version of Matlab do you use on Linux? You may try turning off -ipo or using an optimization level that does not invoke IPO (InterProcedureOptimizations).

Sorry ,I found that I my linux is 64 bit ,and I changed the library path ,this time I got :
ld: warning: libut.so, needed by /opt/MATLAB/bin/glnxa64/libeng.so, not found (try using -rpath or -rpath-link)
ld: warning: libhdf5_hl.so.6, needed by /opt/MATLAB/bin/glnxa64/libmat.so, not found (try using -rpath or -rpath-link)
ld: warning: libhdf5.so.6, needed by /opt/MATLAB/bin/glnxa64/libmat.so, not found (try using -rpath or -rpath-link)
ld: warning: libmwfl.so, needed by /opt/MATLAB/bin/glnxa64/libmx.so, not found (try using -rpath or -rpath-link)
ld: warning: libicudata.so.40, needed by /opt/MATLAB/bin/glnxa64/libmx.so, not found (try using -rpath or -rpath-link)
ld: warning: libicuuc.so.40, needed by /opt/MATLAB/bin/glnxa64/libmx.so, not found (try using -rpath or -rpath-link)
ld: warning: libicui18n.so.40, needed by /opt/MATLAB/bin/glnxa64/libmx.so, not found (try using -rpath or -rpath-link)
ld: warning: libicuio.so.40, needed by /opt/MATLAB/bin/glnxa64/libmx.so, not found (try using -rpath or -rpath-link)

But those files are under /opt/MATLAB/bin/glnxa64 , and I add  /opt/MATLAB/bin/glnxa64 to .bash_profile ...

0 Kudos
steve_o_
Beginner
4,067 Views

 

Hi 

Just came across this thread when I was searching for clues. I got this working in OS X 10.10 with latest Matlab 2014b

I was getting the following when compiling naively from the command line

Undefined symbols for architecture x86_64:
  "_mxcopyptrtoreal8730_", referenced from:
      _MAIN__ in fengdemo.o
  "_mxcopyreal8toptr730_", referenced from:
      _MAIN__ in fengdemo.o
  "_mxcreatedoublematrix730_", referenced from:
      _MAIN__ in fengdemo.o
  "_mxdestroyarray_", referenced from:
      _MAIN__ in fengdemo.o
  "_mxgetpr_", referenced from:
      _MAIN__ in fengdemo.o
ld: symbol(s) not found for architecture x86_64

After some fiddling I got
 ./fengdemo
dyld: Library not loaded: @rpath/libeng.dylib
  Referenced from: /Users/ericnoodle/dummydesktop/build/./fengdemo
  Reason: image not found
Trace/BPT trap: 5

after more fiddling I got 
matlab: Command not found.
 Can't start MATLAB engine

 

so in order to get it to work I did the followingf

from bash, $MLDIR is my Matlab install folder in /Applications

DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:$MLDIR/bin/maci64/

and to fix the $PATH
PATH=$PATH:$MLDIR/bin

then compile, link and run
ifort -I $MLDIR/extern/include/ -c -fPIC fengdemo.F90
ifort  fengdemo.o -o fengdemo -L $MLDIR/bin/maci64/ -leng -lmat -lmx
./fengdemo

There may be a more efficient way ? but it works

- hope it helps and it'll be useful for me in a few months time when I forgot what I did ;-)

 

XXXXXXXXXXXXX:~/dummydesktop/build$ ./fengdemo

 Type 0 <return> to Exit

 Type 1 <return> to continue

1

 MATLAB computed the following distances:

   time(s)  distance(m)

   1.00     -4.90    

   2.00     -19.6    

   3.00     -44.1    

   4.00     -78.4    

   5.00     -123.    

   6.00     -176.    

   7.00     -240.    

   8.00     -314.    

   9.00     -397.    

   10.0     -490.    

XXXXXXXXX:~/dummydesktop/build$

 

0 Kudos
Reply