Skip to Main Content Skip to Search
Product Documentation

Calling LAPACK and BLAS Functions from MEX-Files

What You Need to Know

You can call a LAPACK or BLAS function using a MEX-file. To create a MEX-file, you need C/C++ or Fortran programming experience and the software resources (compilers and linkers) to build an executable file. It also is helpful to understand how to use Fortran subroutines. MATLAB provides the mwlapack and mwblas libraries in matlabroot/extern/lib. To work with complex numbers, use the conversion routines in the fort.c and fort.h files in matlabroot/extern/examples/refbook. To help you get started, there are source code examples in matlabroot/extern/examples/refbook.

If you do not know how to use MEX-files, start with the following sections:

For an overview showing how to create and build sample MEX-files, start with the following sections:

Creating a MEX-File Using LAPACK and BLAS Functions

To call LAPACK or BLAS functions:

  1. Create a source MEX-file containing the mexFunction gateway routine, as described in the following topics:

  2. Select a supported compiler for your platform, as described in the following topics:

  3. Build a binary MEX-file using the mex command with one or more of the following options:

    • Link your source file to one or both of the libraries, mwlapack and mwblas.

    • Use the -largeArrayDims option; the mwlapack and mwblas libraries only support 64-bit integers for matrix dimensions.

    • If your function uses complex numbers, build your source file with fort.c and include the fort.h header file.

The following topics show how to use the mex command using the example matrixMultiply.c. To work with this file, copy it to a local folder. For example:

copyfile(fullfile(matlabroot, 'extern', 'examples', 'refbook', ...
  'matrixMultiply.c'), fullfile('c:', 'work'));

The example files are read-only files. To modify an example, ensure the file is writable by typing:

fileattrib('matrixMultiply.c','+w');

Building on Windows Platforms

There are compiler-specific versions of the libraries on the Windows platform. To link to a specific library, look at the matlabroot/extern/lib/ folder and choose the path for your architecture and compiler. For example, type:

cc = mex.getCompilerConfigurations('Any','Selected');
cc.Manufacturer
computer

If you selected a Microsoft C/C++ compiler on a 32-bit platform, MATLAB displays:

ans =
Microsoft
ans =
PCWIN

Link to the libraries in matlabroot/extern/lib/win32/microsoft/. To simplify the build command, create variables lapacklib and blaslib, which identify the full path and file name of each library.

lapacklib = fullfile(matlabroot, ...
  'extern', 'lib', 'win32', 'microsoft', 'libmwlapack.lib');
blaslib = fullfile(matlabroot, ...
  'extern', 'lib', 'win32', 'microsoft', 'libmwblas.lib');

When you use a variable to identify the library, you must use the function syntax of the mex command. (For more information, see Command vs. Function Syntax.) To build matrixMultiply.c, which uses functions from the BLAS library, type:

mex('-v', '-largeArrayDims', 'matrixMultiply.c', blaslib)

To build a MEX-file with functions that use complex numbers, see Handling Complex Numbers in LAPACK and BLAS Functions.

Building on UNIX Platforms

To build the MEX-file matrixMultiply.c, which uses functions from the BLAS library, type:

mex -v -largeArrayDims matrixMultiply.c -lmwblas

To build a MEX-file with functions that use complex numbers, see Handling Complex Numbers in LAPACK and BLAS Functions.

Testing the matrixMultiply MEX-File

To run the matrixMultiply MEX-file, type:

A = [1 3 5; 2 4 7];
B = [-5 8 11; 3 9 21; 4 0 8];
X = matrixMultiply(A,B)

MATLAB displays:

X =
    24    35   114
    30    52   162

Preserving Input Values from Modification

Many LAPACK and BLAS functions modify the values of arguments passed to them. It is good practice to make a copy of arguments you can modify before passing them to these functions. For information about how MATLAB handles arguments to the mexFunction, see Managing Input and Output Parameters.

Example — matrixDivide.c

The following example calls the LAPACK function dgesv that modifies its input arguments. The code in this example makes copies of prhs[0] and prhs[1], and passes the copies to dgesv to preserve the contents of the input arguments.

To see the example, open the file in the MATLAB Editor. To create the MEX-file, copy the source file to a working folder:

copyfile(fullfile(matlabroot, 'extern', 'examples', 'refbook', ...
  'matrixDivide.c'), fullfile('c:', 'work'));

To build the file on Windows, type:

lapacklib = fullfile(matlabroot, ...
  'extern', 'lib', 'win32', 'microsoft', 'libmwlapack.lib');
mex('-v', '-largeArrayDims', 'matrixDivide.c', lapacklib)

To build the file on UNIX type:

mex -v -largeArrayDims matrixDivide.c -lmwlapack

To test, type:

A = [1 2; 3 4];
B = [5; 6];
X = matrixDivide(A,B)

MATLAB displays:

X =
   -4.0000
    4.5000

Passing Arguments to Fortran Functions from C/C++ Programs

The LAPACK and BLAS functions are written in Fortran. Be aware that C/C++ and Fortran use different conventions for passing arguments to and from functions. Fortran functions expect the arguments to be passed by reference, while arguments to C/C++ functions are passed by value. When you pass by value, you pass a copy of the value. When you pass by reference, you pass a pointer to the value. A reference is also the address of the value.

When you call a Fortran subroutine, like a function from LAPACK or BLAS, from a C/C++ program, be sure to pass the arguments by reference. To do this, precede the argument with an ampersand (&), unless that argument is already a reference. For example, when you create a matrix using the mxGetPr function, you create a reference to the matrix and do not need the ampersand before the argument.

In the following code snippet, variables m, n, p, one, and zero need the & character to make them a reference. Variables A, B, C, and chn are pointers, which are references.

/* pointers to input & output matrices*/
double *A, *B, *C;
/* matrix dimensions */
mwSignedIndex m,n,p;
/* other inputs to dgemm */
char *chn = "N";
double one = 1.0, zero = 0.0;

/* call BLAS function */
dgemm(chn, chn, &m, &n, &p, &one, A, &m, B, &p, &zero, C, &m);

Example — matrixMultiply.c

The matrixMultiply.c example calls dgemm, passing all arguments by reference. To see the source code, open the file in the MATLAB Editor. To build and run this example, see Creating a MEX-File Using LAPACK and BLAS Functions.

Passing Arguments to Fortran Functions from Fortran Programs

You can call LAPACK and BLAS functions from Fortran MEX files. The following example takes two matrices and multiplies them by calling the BLAS routine dgemm:

#include "fintrf.h"

subroutine mexFunction(nlhs, plhs, nrhs, prhs)
mwPointer plhs(*), prhs(*)
integer nlhs, nrhs
mwPointer mxcreatedoublematrix
mwPointer mxgetpr
mwPointer A, B, C
mwSignedIndex mxgetm, mxgetn
mwSignedIndex m, n, p, numel
double precision one, zero, ar, br
character ch1, ch2

ch1 = 'N'
ch2 = 'N'
one = 1.0
zero = 0.0

A = mxgetpr(prhs(1))
B = mxgetpr(prhs(2))
m = mxgetm(prhs(1))
p = mxgetn(prhs(1))
n = mxgetn(prhs(2))

plhs(1) = mxcreatedoublematrix(m, n, 0.0)
C = mxgetpr(plhs(1))
numel = 1
call mxcopyptrtoreal8(A, ar, numel)
call mxcopyptrtoreal8(B, br, numel)

call dgemm(ch1, ch2, m, n, p, one, %val(A), m,
     +           %val(B), p, zero, %val(C), m)

return
end

Handling Complex Numbers in LAPACK and BLAS Functions

MATLAB stores complex numbers differently than Fortran. MATLAB stores the real and imaginary parts of a complex number in separate, equal length vectors, pr and pi. Fortran stores the same complex number in one location with the real and imaginary parts interleaved.

As a result, complex variables exchanged between MATLAB and a Fortran function are incompatible. Use the conversion routines, mat2fort and fort2mat, that change the storage format of complex numbers to address this incompatibility.

The fort.c and fort.h files provide routines for conversion between MATLAB and Fortran complex data structures. These files define the mat2fort and fort2mat routines.

To use these routines, you need to:

  1. Include the fort.h header file in your source file, using the statement #include "fort.h".

  2. Link the fort.c file with your program. Specify the full path, matlabroot/extern/examples/refbook for fort.c in the build command.

  3. Use the -Ipathname switch to indicate the header file. Specify the full path, matlabroot/extern/examples/refbook for fort.h in the build command.

  4. When you specify the full path, replace the term matlabroot with the actual folder name.

Handling Complex Number Input Values

It is unnecessary to copy arguments for functions that use complex number input values. The mat2fort conversion routine creates a copy of the arguments for you. For information, see Preserving Input Values from Modification.

Handling Complex Number Output Arguments

For complex variables returned by a Fortran function, do the following:

  1. When allocating storage for the variable, allocate a real variable with twice as much space as you would for a variable of the same size. Do this because the returned variable uses the Fortran format, which takes twice the space. See the allocation of zout in the example.

  2. Use the fort2mat function to make the variable compatible with MATLAB.

Example — Passing Complex Variables

This example shows how to call a function, passing complex prhs[0] as input and receiving complex plhs[0] as output. Temporary variables zin and zout contain the input and output values in Fortran format. To see the example, open the file in the MATLAB Editor. To create the MEX-file, copy the source file to a working folder:

copyfile(fullfile(matlabroot, 'extern', 'examples', 'refbook', ...
  'matrixDivideComplex.c'), fullfile('c:', 'work'));

To build the file on a Windows platform, type:

lapacklib = fullfile(matlabroot, ...
    'extern', 'lib', 'win32', 'microsoft', 'libmwlapack.lib');
fortfile = fullfile(matlabroot, 'extern', 'examples', ...
    'refbook', 'fort.c');
fortheaderdir = fullfile(matlabroot, 'extern', 'examples', ...
    'refbook');
mex('-v', '-largeArrayDims', ['-I' fortheaderdir], ...
    'matrixDivideComplex.c', fortfile, lapacklib)

To build on a UNIX platform, type:

fortfile = fullfile(matlabroot, 'extern', 'examples', ...
    'refbook', 'fort.c');
fortheaderdir = fullfile(matlabroot, 'extern', 'examples', ...
    'refbook');
mex('-v', '-largeArrayDims', ['-I' fortheaderdir], ...
    'matrixDivideComplex.c', fortfile, '-lmwlapack')

To test:

Areal = [1 2; 3 4];
Aimag = [1 1; 0 0];
Breal = [5; 6];
Bimag = [0; 0];
Acomplex = complex(Areal,Aimag);
Bcomplex = complex(Breal,Bimag);
X = matrixDivideComplex(Acomplex,Bcomplex)

MATLAB displays:

X =
  -4.4000 + 0.8000i
   4.8000 - 0.6000i

Example — Handling Fortran Complex Return Type

Some level 1 BLAS functions (for example, zdotu and zdotc) return a double complex type, which the C language does not support. The following C MEX-file, dotProductComplex.c, shows how to handle the Fortran complex return type for function zdotu. To see the example, open the file in the MATLAB Editor.

The calling syntax for a C program calling a Fortran function that returns a value in an output argument is platform-dependent. On the Windows platform, the return value needs to be passed in as the first input argument. MATLAB provides a macro, FORTRAN_COMPLEX_FUNCTIONS_RETURN_VOID, to handle these differences.

The dotProductComplex example computes the dot product X of each element of two complex vectors A and B. The calling syntax is:

X = dotProductComplex(A,B)

where A and B are complex vectors of the same size and X is a complex scalar.

For example, to build the MEX-file on a Windows 32-bit platform as dotProductComplex.mexw32, type:

blaslib = fullfile(matlabroot, ...
  'extern', 'lib', 'win32', 'microsoft', 'libmwblas.lib');
fortfile = fullfile(matlabroot, 'extern', 'examples', ...
    'refbook', 'fort.c');
fortheaderdir = fullfile(matlabroot, 'extern', 'examples', ...
    'refbook');
mex('-v', '-largeArrayDims', ['-I' fortheaderdir], ...
    'dotProductComplex.c', fortfile, blaslib)

To test, type;

a1 = [1+2i; 2+3i];
b1 = [-1+2i; -1+3i];
X = dotProductComplex(a1,b1)

MATLAB displays:

X =
  -16.0000 + 3.0000i

Example — Symmetric Indefinite Factorization Using LAPACK

The example utdu_slv.c calls LAPACK functions zhesvx and dsysvx. To see the example, open the file in the MATLAB Editor. To create the MEX-file, copy the source file to a working folder:

copyfile(fullfile(matlabroot, 'extern', 'examples', 'refbook', ...
  'utdu_slv.c'), fullfile('c:', 'work'));

To build the file on Windows, type:

lapacklib = fullfile(matlabroot, ...
  'extern', 'lib', 'win32', 'microsoft', 'libmwlapack.lib');
fortheaderdir = fullfile(matlabroot, 'extern', 'examples', ...
    'refbook');
mex('-v', '-largeArrayDims', ['-I' fortheaderdir], ...
    'utdu_slv.c', fortfile, lapacklib)

To build on a UNIX platform, type:

mex -v -largeArrayDims utdu_slv.c -lmwlapack

Modifying the Function Name on UNIX Systems

Add an underscore character following the function name when calling LAPACK or BLAS functions on a UNIX system. For example, to call dgemm, use:

dgemm_(arg1, arg2, ..., argn);

Or add these lines to your source code:

#if !defined(_WIN32)
#define dgemm dgemm_
#endif
  


Recommended Products

Includes the most popular MATLAB recorded presentations with Q&A sessions led by MATLAB experts.

 © 1984-2012- The MathWorks, Inc.    -   Site Help   -   Patents   -   Trademarks   -   Privacy Policy   -   Preventing Piracy   -   RSS