MATLAB® Gateways on Linux using the NAGWare f95 Compiler

Introduction

The Mathworks recommends using g77 as the Fortran compiler for generating MATLAB® MEX files on Linux. However, the NAGWare f95 Compiler may also be used as the Fortran compiler. Indeed there is some advantage to using NAGWare f95 rather than g77 as pointers and dynamic allocation of memory are available as part of the Fortran 95 language.

Dynamic Allocation of Memory using Fortran 95

The Fortran 95 language allows you to declare allocatable arrays which can be dimensioned at run time. If you are only working on platforms where a Fortran 95 compiler compatible with MATLAB is available, this might be the way you choose to allocate dynamically memory for temporary workspace arrays.

Dynamic Memory Allocation using the MATLAB API

The documented way to get dynamic allocation of memory is to use the MATLAB API to create a MATLAB array and store the pointer to this memory in an INTEGER variable which is passed out to another routine by value. The corresponding dummy argument in the receiving routine is declared to be an array of the correct length and data type.

Another common practice is to allocate memory using the MATLAB memory manager (mxCalloc) and pass this to another Fortran routine by value to create temporary arrays for copying, for example, integers to and from MATLAB arrays.

 

The g77 compiler does have the %VAL construct and this is the method used.

In Fortran 95 you can declare a pointer which can then be passed to another Fortran routine that is expecting an array argument. This means that the %VAL construct is not needed. Note, though, that the compiler may generate warnings because of the mismatch in type and attributes between actual and dummy arguments.

On Linux, the NAGWare f95 Compiler may be used to generate MEX files that make full use of dynamic allocation of memory. But, note that the "-mismatch_all" option must be specified to downgrade the argument type mismatch error to a warning.

Example of Dynamic Allocation of Memory using NAGWare f95

The code shown below is the example from page 33 of the MATLAB 5 Application Program Interface Guide reworked to use Fortran 95 pointers to store the address of memory allocated by mxGetPr.

The changes to the standard example are marked in the code with comments.

  • An interface block has been added to describe mxGetPr as an integer pointer function. Fortran 95 does not have generic pointers, so we just pretend that this pointer is always to integer type. Even if this is not true, it does not matter as the pointer is simply passed out to dbl_mat and is never dereferenced in mexfunction.
  • The variables pr_in and pr_out are declared as integer pointers.
  • Use pointer assignment for pr_in and pr_out.
  • The variables pr_in and pr_out are passed as actual arguments to dbl_mat.

Here is the full code for the example.

      subroutine mexfunction(nlhs, plhs, nrhs, prhs)
      integer nlhs, nrhs
      integer plhs(*), prhs(*)
      ! New interface block for pointer function mxGetPr.
      interface
         function mxgetpr(pm)
         integer,pointer :: mxgetpr
         integer :: pm
         end function mxgetpr
      end interface
      integer m_in, n_in
      ! New declaration for the pointers.
      integer, pointer :: pr_in, pr_out
      m_in = mxGetM(prhs(1))
      n_in = mxGetN(prhs(1))
      ! Use pointer assignment
      pr_in => mxgetpr(prhs(1))
      plhs(1) = mxcreatefull(m_in,n_in,0)
      ! Use pointer assignment
      pr_out => mxgetpr(plhs(1))
      ! pass pr_in and pr_out straight to dbl_mat
      call dbl_mat(pr_out,pr_in,m_in,n_in)
      end
      subroutine dbl_mat(out_mat,in_mat,m,n)
      integer m, n
      double precision out_mat(m,n), in_mat(m,n)
      ! We don't need DO loops in Fortran 95!
      out_mat = 2*in_mat
      end

Changes to mexopts.sh to use NAGWare f95

In the file "mexopts.sh", comment out the g77 definitions and add the definitions for NAGWare f95 shown below.

MATLAB 6 with NAGWare f95 Release 4.1 or later

Simple Method

FC='f95'
FFLAGS='-Wc,-fPIC -mismatch_all -dcfuns -w=all'
FLIBS='/usr/local/lib/f95/quickfit.o /usr/local/lib/f95/libf96.a'
LD='gcc'
Note, the FLIBS directory shown above may be different on your system.

Dynamic Linking of NAGWare Run Time Library

This method produces smaller MEX files.

FC='f95'
FFLAGS='-Wc,-fPIC -mismatch_all -dcfuns -w=all'
FLIBS=''
LD="$COMPILER"
NWF95='-ldarg -Wl,-export-dynamic'
TMWFLAGS="-Wl,-shared -ldarg -Wl,--version-script,$TMW_ROOT/extern
  /lib/$Arch/$MAPFILE"
LDFLAGS="$NWF95 $TMWFLAGS"
Note, the -ldarg option is equivalent to "-Wl," but allows commas in its argument.