Main Content

Upgrade MEX Files to Use 64-Bit API

The mex command uses the -largeArrayDims option by default. This topic describes how to upgrade your MEX files to use the 64-bit API.

You can continue to use the 32-bit API by calling the mex command with the -compatibleArrayDims option. However, for more information about using this option, see What If I Do Not Upgrade?.

To review and update MEX file source code, use the following checklist.

  1. Prepare your code before editing — see Back Up Files and Create Tests.

  2. Iteratively change and test code.

    Before building your MEX files with the 64-bit API, refactor your existing code using Update Variables and, for Fortran, Upgrade Fortran MEX Files to use 64-bit API.

    After each change, build and test your code:

  3. Compile using the 64-bit API. To build myMexFile.c, type:

    mex myMexFile.c

  4. Resolve failures and warnings — see Resolve -largeArrayDims Build Failures and Warnings.

  5. Compare Results — see Execute 64-Bit MEX File and Compare Results with 32-Bit Version.

  6. Check memory — see Experiment with Large Arrays.

The following procedures use C/C++ terminology and example code. Fortran MEX files share issues, with more tasks described in Upgrade Fortran MEX Files to use 64-bit API.

Back Up Files and Create Tests

Before modifying your code, verify that the MEX file works with the 32-bit API. At a minimum, build a list of expected inputs and outputs, or create a full test suite. Use these tests to compare the results with the updated source code. The results should be identical.

Back up all source, binary, and test files.

Update Variables

To handle large arrays, convert variables containing array indices or sizes to use the mwSize and mwIndex types instead of the 32-bit int type. Review your code to see if it contains the following types of variables:

Update Arguments Used to Call Functions in the 64-Bit API

Identify the 64-bit API functions in your code that use the mwSize / mwIndex types. For the list of functions, see Using the 64-Bit API. Search for the variables that you use to call the functions. Check the function signature, shown under the Syntax heading on the function reference documentation. The signature identifies the variables that take mwSize / mwIndex values as input or output values. Change your variables to use the correct type.

For example, suppose that your code uses the mxCreateDoubleMatrix function, as shown in the following statements:

int nrows,ncolumns;
...
y_out = mxCreateDoubleMatrix(nrows, ncolumns, mxREAL);

To see the function signature, type:

doc mxCreateDoubleMatrix

The signature is:

mxArray *mxCreateDoubleMatrix(mwSize m, mwSize n, 
    mxComplexity ComplexFlag)

The type for input arguments m and n is mwSize. Change your code as shown in the table.

Replace:With:
int nrows,ncolumns;
mwSize nrows,ncolumns;

Update Variables Used for Array Indices and Sizes

If your code uses intermediate variables to calculate size and index values, use mwSize / mwIndex for these variables. For example, the following code declares the inputs to mxCreateDoubleMatrix as type mwSize:

mwSize nrows,ncolumns;	/* inputs to mxCreateDoubleMatrix */
int numDataPoints;
nrows = 3;
numDataPoints = nrows * 2;
ncolumns = numDataPoints + 1;
...
y_out = mxCreateDoubleMatrix(nrows, ncolumns, mxREAL);

This example uses the intermediate variable, numDataPoints (of type int), to calculate the value of ncolumns. If you copy a 64-bit value from nrows into the 32-bit variable, numDataPoints, the resulting value truncates. Your MEX file could crash or produce incorrect results. Use type mwSize for numDataPoints, as shown in the following table.

Replace:With:
int numDataPoints;
mwSize numDataPoints;

Analyze Other Variables

You do not need to change every integer variable in your code. For example, field numbers in structures and status codes are of type int. However, you need to identify variables used for multiple purposes and, if necessary, replace them with multiple variables.

The following example creates a matrix, myNumeric, and a structure, myStruct, based on the number of sensors. The code uses one variable, numSensors, for both the size of the array and the number of fields in the structure.

mxArray *myNumeric, *myStruct;
int numSensors;
mwSize m, n;
char **fieldnames;
...
myNumeric = mxCreateDoubleMatrix(numSensors, n, mxREAL);
myStruct = mxCreateStructMatrix(m, n, numSensors, fieldnames);

The function signatures for mxCreateDoubleMatrix and mxCreateStructMatrix are:

mxArray *mxCreateDoubleMatrix(mwSize m, mwSize n,
    mxComplexity ComplexFlag)
mxArray *mxCreateStructMatrix(mwSize m, mwSize n,
    int nfields, const char **fieldnames);

For the mxCreateDoubleMatrix function, your code uses numSensors for the variable m. The type for m is mwSize. For the mxCreateStructMatrix function, your code uses numSensors for the variable nfields. The type for nfields is int. To handle both functions, replace numSensors with two new variables, as shown in the following table.

Replace:With:
int numSensors;
/* create 2 variables   */
/* of different types */
mwSize numSensorSize;
int numSensorFields;
myNumeric = 
    mxCreateDoubleMatrix(
    numSensors,
    n, mxREAL);
/* use mwSize variable */
/* numSensorSize       */
myNumeric = 
    mxCreateDoubleMatrix(
    numSensorSize,
    n, mxREAL);
myStruct = 
    mxCreateStructMatrix(
    m, n,
    numSensors,
    fieldnames);
/* use int variable */
/* numSensorFields  */
myStruct = 
    mxCreateStructMatrix(
    m, n,
    numSensorFields,
    fieldnames);

Test, Debug, and Resolve Differences After Each Refactoring Iteration

To build myMexFile.c with the 32-bit API, type:

mex -compatibleArrayDims myMexFile.c

Use the tests you created at the beginning of this process to compare the results of your updated MEX file with your original binary file. Both MEX files should return identical results. If not, debug and resolve any differences. Differences are easier to resolve now than when you build using the 64-bit API.

Resolve -largeArrayDims Build Failures and Warnings

After reviewing and updating your code, compile your MEX file using the large array handling API. To build myMexFile.c with the 64-bit API, type:

mex myMexFile.c

Since the mwSize / mwIndex types are MATLAB® types, your compiler sometimes refers to them as size_t, unsigned_int64, or by other similar names.

Most build problems are related to type mismatches between 32-bit and 64-bit types. Refer to Step 5 in How do I update MEX-files to use the large array handling API (-largeArrayDims)? to identify common build problems for specific compilers, and possible solutions.

Execute 64-Bit MEX File and Compare Results with 32-Bit Version

Compare the results of running your MEX file compiled with the 64-bit API with the results from your original binary. If there are any differences or failures, use a debugger to investigate the cause. For information on the capabilities of your debugger, refer to your compiler documentation.

To identify issues—and possible solutions—you might encounter when running your MEX files, refer to Step 6 in How do I update MEX-files to use the large array handling API (-largeArrayDims)?.

After you resolve issues and upgrade your MEX file, it replicates the functionality of your original code while using the large array handling API.

Experiment with Large Arrays

If you have access to a machine with large amounts of memory, you can experiment with large arrays. An array of double-precision floating-point numbers (the default in MATLAB) with 232 elements takes approximately 32 GB of memory.

For an example that demonstrates the use of large arrays, see the arraySize.c MEX file in Handling Large mxArrays in C MEX Files.

Related Examples

More About

External Websites