如何在Matlab中描述MEX函数 [英] How do I profile a MEX-function in Matlab

查看:150
本文介绍了如何在Matlab中描述MEX函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Mex函数(在c ++中的一个函数,你可以从Matlab调用),我已经写了,我想使用valgrind / kcachegrind配置文件。我知道如何使用valgrind / kcachegrind如果你直接运行一个c ++程序,但是有一种方法来做这个分析,如果我从Matlab调用c ++程序。

I have a Mex-function (a function in c++ that you can call from Matlab) that I have written, and I want to profile it using valgrind/kcachegrind. I know how to use valgrind/kcachegrind if you are running a c++ program directly, but is there a way to do this profiling if I am calling the c++ program from Matlab?

推荐答案

分析MEX文件很棘手,因为MEX文件是共享库。它不能在Linux上使用标准的gprof方法来完成 - gprof根本不这样做。我试图使用sprof,但我得到PLTREL未找到错误 - sprof可以也不要使用。之前有一条此处,但没有人给出最终答案。

Profiling MEX files is tricky since the MEX files are shared libraries. It can not be done on Linux using standard 'gprof' approach - gprof simply does not do that. I tried to use sprof, but I get "PLTREL not found error" - sprof can not be used either. There is a previous post here, but no one gave a final answer.

幸运的是,有一种方法可以在 Linux 上使用valgrind。首先,我们需要编写运行代码来加载mex文件,提供mexFunction符号供我们调用,并设置MEX文件的参数。我选择使用推荐的方法来做到这一点与MATLAB - 使用 MATLAB引擎。下面的代码(另存为test.c)加载MEX文件并找到mexFunction符号,从以前保存为input.mat的文件加载输入数据(可以在MATLAB中使用save命令完成),并调用mexFunction。

Luckily, there is a way in which one can do it with valgrind on Linux. First, we need to write 'running' code that loads the mex file, provides the mexFunction symbol for us to call, and sets up the parameters of the MEX file. I have chosen to use the recommended way to do this with MATLAB - using MATLAB engine. The following code (save as test.c) loads a MEX file and finds the mexFunction symbol, loads input data from a file previously saved as 'input.mat' (can be done in MATLAB using save command), and calls the mexFunction.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <dlfcn.h>
#include "engine.h"

typedef void (*mexFunction_t)(int nargout, mxArray *pargout [ ], int nargin, const mxArray *pargin[]);

int main(int argc, const char *argv[])

{
  Engine *ep;
  char buff[1024];
  int i;

  /* matlab must be in the PATH! */
  if (!(ep = engOpen("matlab -nodisplay"))) {
    fprintf(stderr, "Can't start MATLAB engine\n");
    return -1;
  }
  engOutputBuffer(ep, buff, 1023);

  /* load the mex file */
  if(argc<2){
    fprintf(stderr, "Error. Give full path to the MEX file as input parameter.\n");
    return -1;
  }
  void *handle = dlopen(argv[1], RTLD_NOW);
  if(!handle){
    fprintf(stderr, "Error loading MEX file: %s\n", strerror(errno));
    return -1;
  }

  /* grab mexFunction handle */
  mexFunction_t mexfunction = (mexFunction_t)dlsym(handle, "mexFunction");
  if(!mexfunction){
    fprintf(stderr, "MEX file does not contain mexFunction\n");
    return -1;
  }

  /* load input data - for convenience do that using MATLAB engine */
  /* NOTE: parameters are MEX-file specific, so one has to modify this*/
  /* to fit particular needs */
  engEvalString(ep, "load input.mat");
  mxArray *arg1 = engGetVariable(ep, "Ain");
  mxArray *arg2 = engGetVariable(ep, "opts");
  mxArray *pargout[1] = {0};
  const mxArray *pargin[2] = {arg1, arg2};

  /* execute the mex function */
  mexfunction(1, pargout, 2, pargin);

  /* print the results using MATLAB engine */
  engPutVariable(ep, "result", pargout[0]);
  engEvalString(ep, "result");
  printf("%s\n", buff);

  /* cleanup */
  mxDestroyArray(pargout[0]);
  engEvalString(ep, "clear all;");
  dlclose(handle);
  engClose(ep);

  return 0;
}

MEX文件本身也应该使用 mex -g 开关。上面的代码必须用 mex -g 编译,并使用engopts.sh作为编译参数。从MATLAB命令行类型

The MEX file itself should also compiled with the mex -g switch. The above code has to be compiled with mex -g and using engopts.sh as compilation parameters. From MATLAB command line type

mex('-v', '-f', fullfile(matlabroot,...
    'bin','engopts.sh'),...
    'test.c');

或在标准Linux终端运行

or in a standard Linux terminal run

/path/to/matlab/bin/mex -g -f /path/to/matlab/bin/engopts.sh test.c

使用valgrind分析MEX文件需要从命令行运行'test'程序。在测试和MEX文件所在的目录中,输入命令:

Profiling the MEX file with valgrind requires running the 'test' program from the command line. In the directory where both test and the MEX file reside type the command:

PATH=$PATH:/path/to/matlab/bin/ LD_LIBRARY_PATH=/path/to/matlab/bin/glnxa64/:/path/to/matlab/sys/os/glnxa64/ valgrind --tool=callgrind ./test ./mex_file.mexa64

请注意,需要设置MATLAB的路径和正确的基于架构的库路径。 matlab可执行文件必须存在于PATH中,否则test将失败。

Note that the path to MATLAB and correct architecture-dependent library paths need to be set! matlab executable must be present in the PATH, otherwise 'test' will fail.

还有一个catch。 MATLAB引擎需要在系统上安装csh(可以使用任何shell,csh只需要在/ bin中存在)。所以如果你没有它,你必须安装它为这个工作。

There is one more catch. MATLAB engine requires csh to be installed on the system (you can use any shell, csh just needs to be present in /bin). So if you don't have it, you have to install it for this to work.

这篇关于如何在Matlab中描述MEX函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆