Pages

uzy12. Powered by Blogger.

Meng-Compile Beberapa Fungsi C/MEX dalam Satu File MEX di Matlab

Atau dengan kata lain: Membuat Library MEX

Salah satu kemelahan MEX adalah setiap fungsi C yang akan dicompile, harus di-wrap dalam sebuah fungsi beranama mexFunction, dan nama file yang berisi mexFunction harus sama dengan nama fungsi yang diinginkan. Misalnya, kita ingin membuat fungsi"adder: di MEX berikut:
123456789101112131415161718192021222324252627
#include "mex.h"
/* Input Arguments */
#define X1 prhs[0]
#define X2 prhs[1]
/* Output Arguments */
#define Y plhs[0]
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[] )
{
printf("adder\n");
/* Check for proper number of arguments */
if (nrhs != 2) {
mexErrMsgTxt("Two input arguments required.");
} else if (nlhs > 1) {
mexErrMsgTxt("Too many output arguments.");
} else {
printf("Adder from MEX function\n");
}
//Allocate ouptut
Y = mxCreateNumericMatrix(1, 1, mxDOUBLE_CLASS, mxREAL);
//Adder function
*mxGetPr(Y) = *mxGetPr(X1) + *mxGetPr(X2);
}
view rawgistfile1.cThis Gist brought to you by GitHub.
FIle tersebut jika dicompile menggunakan MEX, akan menghasilkan file .mex (atau .mexgw, .mexw64, dsb), dimana namafungsi sama dengan nama file-nya. Agar fungsi hasil compileasi bisa dipanggil di Matlab dengan cara berikut:
>> adder(2,3)
adder
Adder from MEX function

ans =

     5
Maka file tersebut harus disimpan dengan nama file adder.c, sehinggal ketika dicompile menghasilkan file adder.mex (lihat keterangan diatas).
Demikian juga kalau kita punya beberapa fungsi C lainnya yang ingin dicompile ke MEX, maka tiap fungsi harus disimpan dalam nama file yang sesuai dengan nama fungsi yang dimaksud. Ini menjadi drawback ketika kita punya banyak sekali fungsi, sehingga terpaksa dicompile dalam banyak file MEX (misal: adder.mex, mult.mex, div.mex, dsb.). Bisakah kita mengcompile semua fungsi MEX tersebut dalam satu file MEX saja, sebutlahlibrary.mex? Bisa.
Berikut workaround-nya:
1. Buat satu fungsi MEX (library.c) yang berfungsi untuk memparsing nama fungsi.
Masukkan nama-nama fungsi sebagai header, misalnya:
void mexAdder( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] );
void mexMult( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] );
Lihat code library.c berikut:
12345678910111213141516171819202122232425262728
#include "mex.h"
#include <string.h>
void mexAdder( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] );
void mexMult( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] );
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[] )
{
char *functionName;
int functionNameLen;
/* Get the length of the function name string. */
functionNameLen = (mxGetM(prhs[0]) * mxGetN(prhs[0])) + 1;
/* Allocate memory for input strings. */
functionName = (char *) mxCalloc(functionNameLen, sizeof(char));
/* Copy the string to functionName. */
functionName = mxArrayToString(prhs[0]);
if ( !strcmp(functionName,"adder") ) {
mexAdder(nlhs, plhs, nrhs-1, &(prhs[1]));
} else if ( !strcmp(functionName,"mult") ) {
mexMult(nlhs, plhs, nrhs-1, &(prhs[1]));
}
}
view rawgistfile1.cThis Gist brought to you by GitHub.
2. Sesuaikan nama fungsi pada masing-masing file sesuai nama yang ada di header (poin 1).
Misalnya untuk adder.c jadi begini:
1234567891011121314
#include "mex.h"
/* Input Arguments */
#define X1 prhs[0]
#define X2 prhs[1]
/* Output Arguments */
#define Y plhs[0]
void mexAdder( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[] )
{
printf("adder\n");
...
view rawgistfile1.cThis Gist brought to you by GitHub.
3. Compile library.c bersamaan dengan fungsi-fungsi lainnya.
>> mex library.c adder.c mult.c
4. Selesai! Untuk memanggil fungsi, caranya:
>> library('adder', 2, 3)
adder
Adder from MEX function

ans =

     5
Sekarang kita punya satu file MEX (library.mex) yang berisi semua fungsi C/MEX. Mudah kan!? (ya2n) :D