2012-06-27 24 views
13

Tôi có chức năng Mex (một hàm trong C++ mà bạn có thể gọi từ Matlab) mà tôi đã viết và tôi muốn cấu hình nó bằng valgrind/kcachegrind. Tôi biết làm thế nào để sử dụng valgrind/kcachegrind nếu bạn đang chạy một chương trình C++ trực tiếp, nhưng là có một cách để làm hồ sơ này nếu tôi gọi chương trình C++ từ Matlab?Làm cách nào để cấu hình chức năng MEX trong Matlab

+0

Câu hỏi hay, tôi thường tự hỏi về điều này. Đáng buồn là tôi không biết câu trả lời, nhưng tôi biết có thể lập hồ sơ mã Mex với Visual Studio ... –

+0

@BillCheatham Bạn có thể sử dụng valgrind trên Linux bằng cách sử dụng mã trình bao bọc để tải tệp MEX, về bản chất là thư viện động. Hãy xem câu trả lời của tôi. – angainor

+0

Alex, bạn có tìm thấy một số cách khác để cấu hình các tệp mex không? Tôi tò mò. – angainor

Trả lời

9

Tệp MEX hồ sơ là khó khăn vì tệp MEX là thư viện được chia sẻ. Nó không thể được thực hiện trên Linux bằng cách sử dụng phương pháp tiếp cận 'gprof' chuẩn - đơn giản là gprof không làm điều đó. Tôi đã cố gắng sử dụng sprof, nhưng tôi nhận được “PLTREL not found error” - sprof không thể được sử dụng một trong hai. Có một bài đăng trước đó here, nhưng không ai trả lời cuối cùng.

May mắn thay, có cách mà người ta có thể làm điều đó với valgrind trên Linux. Đầu tiên, chúng ta cần viết mã 'đang chạy' để tải tệp mex, cung cấp biểu tượng mexFunction để gọi và thiết lập các tham số của tệp MEX. Tôi đã chọn sử dụng cách được khuyến nghị để làm điều này với MATLAB - sử dụng MATLAB engine. Đoạn mã sau (lưu dưới dạng test.c) tải một tệp MEX và tìm biểu tượng mexFunction, nạp dữ liệu đầu vào từ một tệp được lưu trước đó dưới dạng 'input.mat' (có thể được thực hiện trong MATLAB bằng lệnh lưu) và gọi hàm 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; 
} 

Bản thân tệp MEX cũng phải được biên dịch bằng công tắc mex -g. Đoạn mã trên phải được biên dịch với mex -g và sử dụng engopts.sh làm tham số biên dịch. Từ MATLAB kiểu dòng lệnh

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

hoặc trong một tiêu chuẩn Linux Terminal chạy

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

Profiling file MEX với valgrind đòi hỏi phải chạy chương trình 'test' từ dòng lệnh. Trong thư mục chứa cả kiểm tra và tệp MEX, hãy nhập lệnh:

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 

Lưu ý rằng đường dẫn đến MATLAB và đường dẫn thư viện phụ thuộc vào kiến ​​trúc chính xác cần phải được đặt! MATLAB thực thi phải có mặt trong PATH, nếu không thì 'test' sẽ thất bại.

Còn một lần nữa. Động cơ MATLAB yêu cầu csh được cài đặt trên hệ thống (bạn có thể sử dụng bất kỳ shell nào, csh chỉ cần có mặt trong/bin). Vì vậy, nếu bạn không có nó, bạn phải cài đặt nó để làm việc này.

4

Bạn có thể bắt đầu MATLAB với các tùy chọn -D, như mô tả trên MatlabCentral thread này:

matlab -nojvm -nodesktop -nosplash -D"valgrind --error-limit=no --leak-check=yes --tool=memcheck -v --log-file=valgrind.log"

tôi sẽ thêm để đảm bảo rằng bạn có phiên bản mới nhất của valgrind. Khi tôi cố gắng để gỡ lỗi tập tin MEX của tôi với valgrind phiên bản 3.6, valgrind bị rơi thay vì báo cáo lỗi bộ nhớ.

Các vấn đề liên quan