12
#define MAX_FILE_NAME 2048
13
/*#define USE_UNDOCUMENTED*/
17
#define EXTERN_C extern "C"
19
#define EXTERN_C extern
23
#ifdef USE_UNDOCUMENTED
24
EXTERN_C mxArray *mxCreateSharedDataCopy(const mxArray *pr);
25
#endif /* USE_UNDOCUMENTED */
40
unsigned int initialized;
41
unsigned int width, max_block;
43
typedef struct MEXContextT MEXContextS;
44
typedef struct MEXContextT *MEXContext;
46
static MEXContext pstate = NULL;
48
MEXContext mexCreateContext() {
49
pstate = (MEXContext)malloc(sizeof(MEXContextS));
51
MRSESContext ctx = mrses_create_context();
57
memset(pstate, 0, sizeof(MEXContextS));
63
void mexDestroyContext(MEXContext pstate) {
66
mxDestroyArray(pstate->res);
69
mxDestroyArray(pstate->hist);
72
mrses_destroy_context(pstate->mrses);
78
static void selfClean() {
80
reportMessage("Cleaning hw instance");
82
mexDestroyContext(pstate);
88
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
94
static int32_t id = 0;
98
const mxArray *A, *B, *index;
100
unsigned int iterations;
101
unsigned int properties;
102
unsigned int block_size;
110
reportMessage("Initializing hw instance");
113
reportError("You should accept a single result from initialization call");
117
idMatrix = mxCreateNumericMatrix(1, 1, mxINT32_CLASS, mxREAL);
119
reportError("Initialization is failed");
123
if (pstate) mexDestroyContext(pstate);
124
pstate = mexCreateContext();
127
mexAtExit(selfClean);
130
reportError("Context initialization has failed");
134
idPtr = (int32_t*)mxGetData(idMatrix);
141
reportError("normxcorr_hw should be initialized first");
154
action = (TAction)(mxGetScalar((mxArray*)prhs[1]));
156
/*reportMessage("Executing normxcorr_hw action: %u", action);*/
160
if ((nrhs < 6)||(nrhs > 7)) {
161
reportError("Initialization call expects following arguments: 'width', 'block_size', matrices 'A' and 'B', distance_type");
165
width = (int)mxGetScalar(prhs[2]);
166
block_size = (int)mxGetScalar(prhs[3]);
168
dist = (int)mxGetScalar(prhs[6]) - 1;
169
if (dist >= MRSES_DISTANCE_LAST) {
170
reportError("Invalid distance mode is requested: %i", dist);
173
} else dist = BHATTACHARYYA;
177
properties = mxGetN(A);
178
if (properties != mxGetN(B)) {
179
reportError("Dimenssions of matrices A and B does not match: %i, %i", properties, mxGetN(B));
183
if ((mxGetClassID(A) == mxSINGLE_CLASS)&&(mxGetClassID(B) == mxSINGLE_CLASS)) {
184
err = mrses_init_context(ps->mrses, properties, mxGetM(A), mxGetData(A), mxGetM(B), mxGetData(B));
185
} else if ((mxGetClassID(A) == mxDOUBLE_CLASS)&&(mxGetClassID(B) == mxDOUBLE_CLASS)) {
186
err = mrses_init_context_from_double(ps->mrses, properties, mxGetM(A), mxGetData(A), mxGetM(B), mxGetData(B));
188
reportError("Only single-precision floating point numbers are supported");
193
reportError("Initialization is failed with error, %i", err);
197
err = mrses_set_distance_mode(ps->mrses, dist);
199
reportError("Failed to set distance mode, error %i", err);
203
err = mrses_prepare(ps->mrses, width, block_size);
205
reportError("Failed to prepare for execution, error %i", err);
209
if (ps->res) mxDestroyArray(ps->res);
210
ps->res = mxCreateNumericMatrix(block_size, 1, mxSINGLE_CLASS, mxREAL);
211
if (ps->res) mexMakeArrayPersistent(ps->res);
213
reportError("Allocation of result matrix of size %u*float bytes is failed", block_size);
217
if (ps->hist) mxDestroyArray(ps->hist);
218
ps->hist = mxCreateNumericMatrix(1, properties, mxUINT32_CLASS, mxREAL);
219
if (ps->hist) mexMakeArrayPersistent(ps->hist);
221
reportError("Allocation of result matrix of size %u*uint32_t bytes is failed", properties);
226
ps->max_block = block_size;
230
if (!pstate->initialized) {
231
reportError("We are not initialized yet, issue intialize call first");
235
if ((nlhs != 1)||((nrhs < 3)||(nrhs > 4))) {
236
reportError("Compute call expects following arguments: 'block_size', 'index'. It should accept a single result matrix as well.");
241
block_size = (int)mxGetScalar(prhs[2]);
244
if (mxGetN(index) < block_size) {
245
reportError("Index matrix does not contain specified number of blocks");
250
block_size = mxGetN(index);
253
if (block_size > pstate->max_block) {
254
reportError("The block is too big: maximum configured size is %i, but %i supplied", pstate->max_block, block_size);
258
width = mxGetM(index);
259
if (pstate->width != width) {
260
reportError("The index matrix dimension does not fit requirement: width = %i, but index side is %i", pstate->width, width);
264
if (mxGetClassID(index) != mxINT16_CLASS) {
265
reportError("Only 16 bit integers are supported for index");
270
mxSetN(res, block_size);
273
err = mrses_compute(ps->mrses, block_size, mxGetData(index), mxGetData(res));
275
reportError("Error executing compute, failed with code: %i", err);
279
#ifdef USE_UNDOCUMENTED
280
plhs[0] = mxCreateSharedDataCopy(res);
281
#else /* USE_UNDOCUMENTED */
282
plhs[0] = mxDuplicateArray(res);
283
#endif /* USE_UNDOCUMENTED */
287
if (!pstate->initialized) {
288
reportError("We are not initialized yet, issue intialize call first");
293
reportError("Iterate call expects following arguments: 'iterations', 'block_size'.");
297
iterations = (int)mxGetScalar(prhs[2]);
298
block_size = (int)mxGetScalar(prhs[3]);
300
if (block_size > pstate->max_block) {
301
reportError("The block is too big: maximum configured size is %i, but %i supplied", pstate->max_block, block_size);
306
idMatrix = mxCreateNumericMatrix(pstate->width, pstate->max_block, mxUINT16_CLASS, mxREAL);
307
mxSetN(idMatrix, block_size);
308
ires = mxGetData(idMatrix);
313
err = mrses_iterate(ps->mrses, iterations, block_size, ires);
315
reportError("Error executing iterate, failed with code: %i", err);
319
case ACTION_GET_HIST:
320
if (!pstate->initialized) {
321
reportError("We are not initialized yet, issue intialize call first");
325
if ((nlhs != 1)&&(nrhs != 2)) {
326
reportError("GetHist call returns histogram vector and expects no arguments.");
331
err = mrses_get_results(ps->mrses, mxGetData(res));
333
reportError("Error executing iterate, failed with code: %i", err);
337
plhs[0] = mxDuplicateArray(res);
340
reportError("Unknown request %i", action);