0

倍精度の入力ベクトルを取り、精度を一時的な単精度ベクトルにダウンキャストし、処理を行ってから、処理の結果を再び倍精度にアップキャストする mex 関数があります。

次の簡略化されたコード例は、このプロセスをコンパイルして示しています。

#include "mex.h"

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{           
  int xM = mxGetM(prhs[0]); 
  int xN = mxGetN(prhs[0]);         
  int totalNumElements = xM*xN;       

  plhs[0] = mxCreateDoubleMatrix(xM,xN,mxREAL);

  double* out  = mxGetPr(plhs[0]); 
  double* in   = mxGetPr(prhs[0]);    

  float out32[totalNumElements]; 
  float  in32[totalNumElements]; 

  // ---------> DOWNCAST <---------
  for (int mm = 0; mm < totalNumElements; ++mm)
      in32[mm] = (float)in[mm];
  // ---------- DOWNCAST ----------

  // Do some single precision signal processing (just copy for this example)
  for (int mm = 0; mm < totalNumElements; ++mm)
      out32[mm] = in32[mm];

  // ---------> UPCAST <---------
  for (int mm = 0; mm < totalNumElements; ++mm)
      out[mm] = (double)out32[mm];
  // ---------- UPCAST ---------- 
}

私のマシンでは、このようにコンパイルされた mex 関数を呼び出すとうまくいきます。.

>> x = randn(1e6,1); y=demo(x);

...しかし、このように呼び出すと、Matlab が予期せず終了します

>> x = randn(1e7,1); y=demo(x);

クラッシュが入力ベクトルのサイズの増加によって引き起こされているのを見て、エラーはメモリ割り当ての失敗が原因であると推測しています。このようなエラーが発生した場合、Matlab を正常に終了してエラー メッセージを表示するにはどうすればよいですか? ありがとう。

4

1 に答える 1

2

方法 1

OK、これを行う 1 つの方法は、スタックに割り当てられた変数を C-style に置き換えることです。. .

 float*  in32  =  (float*)mxCalloc(totalNumElements, sizeof(float));
 float*  out32 =  (float*)mxCalloc(totalNumElements, sizeof(float));

メモリエラーが発生した場合、Matlab はきちんと次のエラーを出します。. .

デモ使用エラー メモリ不足です。

オプションに HELP MEMORY と入力します。

try-catchブロックや例外は必要ありません。

方法 2

もう 1 つの方法は、C++ スタイルを使用することですstd::exception。スタックに割り当てられた変数は、次のように置き換えることができます...

  float*  in32;
  float*  out32;
  try
  {
      in32  = new float[totalNumElements];
      out32 = new float[totalNumElements];
  }
  catch (std::exception& e)
  {
      std::string msg = std::string("Aw snap: ") + e.what();
      mexErrMsgTxt(msg.c_str());
  }

メモリエラーが発生した場合、Matlab はきちんと次のエラーを出します。. .

デモの使用中にエラーが発生しました

あースナップ: std::bad_alloc

ノート

方法 1 はよりコンパクトで、mex API との統合が向上しています。メソッド 1 を mex ゲートウェイ関数で使用し、メソッド 2 をライブラリで使用するのがおそらく最善です。これらの方法は両方とも、 および のヒープに割り当てられたメモリを使用するために、 ( solution) または ( solution) を使用する必要mxFreemxCallocありdeleteます。スタックオーバーフローを検出または処理する方法がまだわかりませんnewin32out32

于 2012-05-16T13:36:25.257 に答える