Main Content

64 ビット API を使用するように MEX ファイルをアップグレード

mex コマンドは、既定で -largeArrayDims オプションを使用します。このトピックでは、64 ビット API を使用するように MEX ファイルをアップグレードする方法を説明します。

-compatibleArrayDims オプションを指定して mex コマンドを呼び出すと、引き続き 32 ビット API を使用することができます。ただし、このオプションの使用の詳細については、アップグレードしない場合どうなるかを参照してください。

MEX ファイル ソース コードを確認して更新するには、次のチェックリストを使用します。

  1. 編集する前にコードを準備します。ファイルのバックアップとテストの作成を参照。

  2. コード変更とテストを繰り返します。

    64 ビット API で MEX ファイルをビルドする前に、変数の更新を、また Fortran の場合は64 ビット API を使用するように Fortran MEX ファイルをアップグレードを使用して既存のコードをリファクタリングします。

    変更のたびにコードのビルドとテストを行います。

  3. 64 ビット API を使用してコンパイルします。myMexFile.c をビルドするには、以下を入力します。

    mex myMexFile.c

  4. エラーと警告を解決します。-largeArrayDims のビルド エラーと警告の解決を参照。

  5. 結果を比較します。64 ビット MEX ファイルの実行結果を 32 ビット バージョンと比較を参照。

  6. メモリをチェックします。大規模配列での実施を参照。

以下の手順では C/C++ の用語とコード例を使用します。Fortran の MEX ファイルの場合も同様ですが、64 ビット API を使用するように Fortran MEX ファイルをアップグレードに説明されている作業が追加になります。

ファイルのバックアップとテストの作成

コードを変更する前に、MEX ファイルが 32 ビット API で動作することを確認してください。少なくとも想定される入出力のリストを作成するか、完全なテスト スイートを作成します。これらのテストを使用して、結果を更新されたソース コードと比較します。結果は両者で一致しなければなりません。

すべてのソース ファイル、バイナリ ファイル、テスト ファイルのバックアップを取ります。

変数の更新

大規模配列を処理するために、配列インデックスまたは配列サイズを含む変数を、32 ビット int 型の代わりに、mwSize 型と mwIndex 型を使用するよう変換します。コードに次の型の変数が含まれていないかどうかチェックします。

64 ビット API で関数呼び出しに使用される引数の更新

コード内で mwSize 型/mwIndex 型を使用する 64 ビット API 関数を特定します。関数の一覧については、64 ビット API の使用を参照してください。関数の呼び出しに使用する変数を検索します。関数のリファレンス ドキュメンテーションの「構文」の見出しの下に示されている、関数シグネチャをチェックします。シグネチャにより、入力値または出力値として mwSize 値または mwIndex 値を取る変数が特定されます。正しい型が使用されるように変数を変更します。

たとえば、以下のステートメントに示すように、コードが関数 mxCreateDoubleMatrix を使用すると仮定します。

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

関数シグネチャを表示するには、以下を入力します。

doc mxCreateDoubleMatrix

シグネチャは以下のとおりです。

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

入力引数 mn の型は mwSize です。表に示すようにコードを変更します。

次を置き換えます。変更後
int nrows,ncolumns;
mwSize nrows,ncolumns;

配列インデックスと配列サイズに使用される変数の更新

コードがサイズ値とインデックス値の計算に中間変数を使用している場合、これらの変数に mwSize / mwIndex を使用します。たとえば、次のコードは関数 mxCreateDoubleMatrix への入力に mwSize 型を宣言しています。

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

この例では、中間変数 numDataPoints (int 型) を使用して ncolumns の値を計算します。nrows からの 64 ビット値を 32 ビット変数 numDataPoints にコピーすると、結果として値が切り捨てられます。MEX ファイルがクラッシュするか、または正しくない結果を生成する可能性があります。次の表に示すように、numDataPoints には mwSize 型を使用します。

次を置き換えます。変更後
int numDataPoints;
mwSize numDataPoints;

その他の変数の解析

コード内の整数変数をすべて変更する必要はありません。たとえば、構造体のフィールド番号とステータス コードは int 型です。しかし、多目的に使用される変数を識別する必要がある場合は、必要に応じて、これらを複数の変数で置き換えます。

この例では、センサーの数に基づいて、行列 myNumeric と構造体 myStruct を作成します。コードは 1 つの変数 numSensors を、配列のサイズと構造体のフィールド数の両方の意味で使用します。

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

関数 mxCreateDoubleMatrix と関数 mxCreateStructMatrix に対する関数シグネチャは、以下のとおりです。

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

関数 mxCreateDoubleMatrix では、コードは変数 m に numSensors を使用しています。m の型は mwSize です。関数 mxCreateStructMatrix では、コードは変数 nfields に numSensors を使用しています。nfields の型は int です。両方の関数を処理するために、次の表に示すように numSensors を新しい 2 つの変数に置き換えます。

次を置き換えます。変更後
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);

各リファクタリング実行後のテスト、デバッグ、および差異の解決

32 ビット API により myMexFile.c をビルドするには、以下を入力します。

mex -compatibleArrayDims myMexFile.c

このプロセスの最初に作成したテストを使用し、更新された MEX ファイルの結果を元のバイナリ ファイルの結果と比較します。両方の MEX ファイルから返される結果は一致しなければなりません。そうでない場合は、デバッグして差異を解決します。差異は、64 ビット API を使用してビルドする場合よりも今回の方が容易に解決できます。

-largeArrayDims のビルド エラーと警告の解決

コードを確認して更新した後、大規模配列ハンドリング API を使用して MEX ファイルをコンパイルします。64 ビット API を使用して myMexFile.c をビルドするには、以下を入力します。

mex myMexFile.c

mwSize 型および mwIndex 型は MATLAB® の型のため、コンパイラがこれらを size_tunsigned_int64 またはその他類似の名前により参照する場合があります。

ビルド問題の大半は 32 ビット型と 64 ビット型の型の不一致に関連するものです。特定のコンパイラの一般的なビルド問題と、考えられる解決方法を確認するには、How do I update MEX-files to use the large array handling API (-largeArrayDims)? の手順 5 を参照してください。

64 ビット MEX ファイルの実行結果を 32 ビット バージョンと比較

64 ビット API でコンパイル済みの MEX ファイルを実行して、元のバイナリの結果と比較します。差異やエラーがある場合は、デバッガーを使用して原因を調べます。デバッガー機能の詳細については、コンパイラのドキュメンテーションを参照してください。

MEX ファイルを実行するときに発生する問題と、考えられる解決方法を確認するには、How do I update MEX-files to use the large array handling API (-largeArrayDims)? の手順 6 を参照してください。

問題の解決と MEX ファイルのアップグレードの実施後、MEX ファイルは大規模配列ハンドリング API の使用において元のコードの機能を再現します。

大規模配列での実施

大容量メモリのマシンにアクセスする場合、大規模配列を試すことができます。232 の要素をもつ倍精度浮動小数点 (MATLAB の既定) の配列は約 32 GB のメモリを使用します。

大規模配列を使用する例については、C MEX ファイルでの大規模な mxArrays の処理arraySize.c MEX ファイルを参照してください。

関連する例

詳細

外部の Web サイト