gabo
Posts:
1
Registered:
4/7/09
|
|
Re: matlab/mex function doesn't free memory
Posted:
Apr 7, 2009 7:26 PM
|
|
"Alex Berkovich" <alexber@tx.technion> wrote in message <gi3i3u$m5q$1@fred.mathworks.com>... > Hello all, > > I'm running a mex function that calls for c code (compiled in the same file as the mex function itself). > when a simulation is done, it seems matlab doesn't release the memory it uses since i see a growing amount of memory being used by matlab (via task manager). > > it reaches the limit of my computer and then either crashes or simply continues to run forever. > > any suggestion on how to solve this problem is very appriciated. >
Hi all,
It DOES seem that MatLab leaks memory when running mex files. Take a look at the following: Below is a c-mex file (trace2plane.c) that finds intersections between hyperplanes and polygonal-line traces. Run the test code (test_trace2plane.m, down at the bottom) several times and you'll discover MatLab is taking up more and more memory in the task manager. I've been trying to figure out the problem for almost a month now, any insigths or help of any kind will be much appreciated.
Gabriel
/* trace2plane.c */ #include "mex.h" #include <math.h>
#define min(a, b) (((a) < (b)) ? (a) : (b)) #define max(a, b) (((a) > (b)) ? (a) : (b)) #define sqr(a) ((a)*(a)) #define abs(a) (((a) > (0)) ? (a) : (-a)) #define sgn(a) (((a) > (0)) ? (1) : (-1))
/* Gateway foutine. */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* Declare variables. */ int i, j, k; double *center, *direction, *trace; double **position, **velocity, *location, *distance; int **member; double *pointer, dot, norm, delta; int length, dimension, total, product, index; int size = 0, count = 0, increment; char buffer[100]; /* Check argument count. */ if (nrhs < 3) mexErrMsgTxt("Not enough inputs."); if (nlhs > 5) mexErrMsgTxt("Too many outputs."); /* Check input class. */ for (i = 0; i < nrhs; i++) { if (!(mxIsNumeric(prhs[i]))) { sprintf(buffer, "Input %d must be numeric.", i + 1); mexErrMsgTxt(buffer); } if (mxIsComplex(prhs[i])) { sprintf(buffer, "Input %d must be real.", i + 1); mexErrMsgTxt(buffer); } if (!(mxIsDouble(prhs[i]))) { sprintf(buffer, "Input %d must be of class double.", i + 1); mexErrMsgTxt(buffer); } } /* Check input size. */ dimension = mxGetN(prhs[0]); for (i = 0; i < nrhs; i++) { if (mxGetNumberOfDimensions(prhs[i]) > 2) { sprintf(buffer, "Input %d must be a matrix.", i + 1); mexErrMsgTxt(buffer); } if (mxGetN(prhs[i]) != dimension) { sprintf(buffer, "Input %d must have %d columns.", i + 1, dimension); mexErrMsgTxt(buffer); } } total = mxGetM(prhs[0]); if (mxGetM(prhs[1]) != total) { sprintf(buffer, "Input 2 must have %d rows.", total); mexErrMsgTxt(buffer); } product = mxGetNumberOfElements(prhs[0]); /* Check for early return. */ if (mxIsEmpty(prhs[0]) || mxIsEmpty(prhs[2])) { plhs[0] = mxCreateNumericMatrix(count, dimension, mxDOUBLE_CLASS, mxREAL); if (nlhs > 1) { plhs[1] = mxCreateNumericMatrix(count, dimension, mxDOUBLE_CLASS, mxREAL); if (nlhs > 2) { plhs[2] = mxCreateNumericMatrix(count, 2, mxDOUBLE_CLASS, mxREAL); if (nlhs > 3) { plhs[3] = mxCreateNumericMatrix(count, 1, mxDOUBLE_CLASS, mxREAL); if (nlhs > 4) { plhs[4] = mxCreateNumericMatrix(count, 1, mxDOUBLE_CLASS, mxREAL); } } } } return; } /* Allocate space. */ increment = nrhs - 2; size = increment; position = mxMalloc(size*sizeof(double*)); velocity = mxMalloc(size*sizeof(double*)); member = mxMalloc(size*sizeof(int*)); for (i = 0; i < size; i++) { position[i] = mxMalloc(dimension*sizeof(double)); velocity[i] = mxMalloc(dimension*sizeof(double)); member[i] = mxMalloc(2*sizeof(int)); } location = mxMalloc(size*sizeof(double)); distance = mxMalloc(size*sizeof(double)); /* Get pointer. */ center = mxGetPr(prhs[0]); direction = mxGetPr(prhs[1]); for (i = 0; i < total; i++) { /* Calculate projections. */ for (j = 2; j < nrhs; j++) { trace = mxGetPr(prhs[j]); length = mxGetM(prhs[j]); for (k = 0; k < length - 1; k++) { dot = 0.0; delta = 0.0; pointer = trace + k; for (index = i; index < product; index += total, pointer += length) { dot += direction[index]*(center[index] - *pointer); delta += direction[index]*(*(pointer + 1) - *pointer); } if (delta != 0.0) { dot /= delta; if ((dot > 0.0) && (dot <= 1.0)) { /* Allocate more space if necessary. */ if (count >= size) { size += increment; position = mxRealloc(position, size*sizeof(double*)); velocity = mxRealloc(velocity, size*sizeof(double*)); member = mxRealloc(member, size*sizeof(int*)); for (index = size - increment; index < size; index++) { position[index] = mxMalloc(dimension*sizeof(double)); velocity[index] = mxMalloc(dimension*sizeof(double)); member[index] = mxMalloc(2*sizeof(int)); } location = mxRealloc(location, size*sizeof(double)); distance = mxRealloc(distance, size*sizeof(double)); } /* Append. */ norm = 0.0; pointer = trace + k; for (index = 0; index < dimension; index++, pointer += length) { delta = *(pointer + 1) - *pointer; position[count][index] = *pointer + dot*delta; velocity[count][index] = delta; delta = center[i + index*dimension] - position[count][index]; norm += sqr(delta); } member[count][0] = i + 1; member[count][1] = j - 1; location[count] = dot + (double) (k + 1); distance[count] = sqrt(norm); count++; } } } } /* Trim. */ for (i = size - count; k < size; k++) { mxFree(position[i]); mxFree(velocity[i]); mxFree(member[i]); } position = mxRealloc(position, count*sizeof(double*)); velocity = mxRealloc(velocity, count*sizeof(double*)); member = mxRealloc(member, count*sizeof(int*)); location = mxRealloc(location, count*sizeof(double)); distance = mxRealloc(distance, count*sizeof(double)); } /* Fill in position. */ plhs[0] = mxCreateNumericMatrix(count, dimension, mxDOUBLE_CLASS, mxREAL); pointer = mxGetPr(plhs[0]); for (j = 0; j < dimension; j++) for (i = 0; i < count; i++) { *pointer = position[i][j]; pointer++; } if (nlhs > 1) { /* Fill in velocity. */ plhs[1] = mxCreateNumericMatrix(count, dimension, mxDOUBLE_CLASS, mxREAL); pointer = mxGetPr(plhs[1]); for (j = 0; j < dimension; j++) for (i = 0; i < count; i++) { *pointer = velocity[i][j]; pointer++; } if (nlhs > 2) { /* Fill in member. */ plhs[2] = mxCreateNumericMatrix(count, 2, mxDOUBLE_CLASS, mxREAL); pointer = mxGetPr(plhs[2]); for (j = 0; j < 2; j++) for (i = 0; i < count; i++) { *pointer = (double) member[i][j]; pointer++; } if (nlhs > 3) { /* Fill in location. */ plhs[3] = mxCreateNumericMatrix(count, 1, mxDOUBLE_CLASS, mxREAL); pointer = mxGetPr(plhs[3]); for (i = 0; i < count; i++) pointer[i] = location[i]; if (nlhs > 4) { /* Fill in distance. */ plhs[4] = mxCreateNumericMatrix(count, 1, mxDOUBLE_CLASS, mxREAL); pointer = mxGetPr(plhs[4]); for (i = 0; i < count; i++) pointer[i] = distance[i]; } } } } /* Free space. */ for (i = 0; i < size; i++) { mxFree(position[i]); mxFree(velocity[i]); mxFree(member[i]); } mxFree(position); mxFree(velocity); mxFree(member); mxFree(location); mxFree(distance); }
function test_trace2plane
%-------------------------------------------------------------------------% % First case % %-------------------------------------------------------------------------%
% Generate data. length = 5; dimension = 2; center = zeros(1, dimension); direction = randn(1, dimension); trace = randn(length, dimension); trace = cumsum(trace, 1); trace = bsxfun(@minus, trace, mean(trace, 1)); trace = bsxfun(@times, trace, 1./std(trace, 1, 1));
% Project. [position, velocity, member, location, distance] = ... trace2plane(center, direction, trace);
% Create line. x = transpose(linspace(-1.0, 1.0, length)); [q, r] = qr(transpose(direction)); i = eq(r, 0.0); x = bsxfun(@plus, x*q(i, :), center);
% Plot. figure set(gca, ... 'Color', get(gcf, 'Color'), ... 'XGrid', 'on', ... 'YGrid', 'on', ... 'DataAspectRatio', ones(1, 3), ... 'NextPlot', 'add') quiver(center(:, 1), center(:, 2), ... direction(:, 1), direction(:, 2), ... 'Color', 'r', ... 'Marker', '.', ... 'AutoScale', 'off') plot(x(:, 1), x(:, 2), ... 'Color', 'r', ... 'LineStyle', '--') plot(trace(:, 1), trace(:, 2),... 'Color', 'b', ... 'Marker', '.') plot(transpose(cat(2, ... center(ones(size(position, 1), 1), 1), ... position(:, 1))), ... transpose(cat(2, ... center(ones(size(position, 1), 1), 2), ... position(:, 2))), ... 'Color', 'y', ... 'Marker', 'none', ... 'LineStyle', '-') for i = 1:length text(trace(i, 1), trace(i, 2), ... sprintf('%d', i), ... 'HorizontalAlignment', 'Left', ... 'VerticalAlignment', 'Bottom') end for i = 1:size(position, 1) text(position(i, 1), position(i, 2), ... sprintf('%4.4f', location(i)), ... 'Color', 'g', ... 'HorizontalAlignment', 'Right', ... 'VerticalAlignment', 'Top') text(0.5*(center(1) + position(i, 1)), ... 0.5*(center(2) + position(i, 2)), ... sprintf('%4.4f', distance(i)), ... 'Color', 'y', ... 'HorizontalAlignment', 'Right', ... 'VerticalAlignment', 'Top') end plot(position(:, 1), position(:, 2), ... 'Color', 'g', ... 'Marker', '.', ... 'LineStyle', 'none')
%-------------------------------------------------------------------------% % Second case % %-------------------------------------------------------------------------%
% Generate data. length = 5; dimension = 3; center = zeros(1, dimension); direction = randn(1, dimension); trace = randn(length, dimension); trace = cumsum(trace, 1); trace = bsxfun(@minus, trace, mean(trace, 1)); trace = bsxfun(@times, trace, 1./std(trace, 1, 1));
% Project. [position, velocity, member, location, distance] = ... trace2plane(center, direction, trace);
% Create plane. x = cell(1, 2); [x{:}] = meshgrid(transpose(linspace(-1.0, 1.0, length))); for i = 1:2 x{i} = x{i}(:); end x = cat(2, x{:}); [q, r] = qr(transpose(direction)); i = eq(r, 0.0); x = bsxfun(@plus, x*q(i, :), center); x = mat2cell(x, length^2, ones(1, 3)); for i = 1:3 x{i} = reshape(x{i}, length, length); end
% Plot. figure set(gca, ... 'Color', get(gcf, 'Color'), ... 'XGrid', 'on', ... 'YGrid', 'on', ... 'ZGrid', 'on', ... 'DataAspectRatio', ones(1, 3), ... 'NextPlot', 'add') quiver3(center(:, 1), center(:, 2), center(:, 3), ... direction(:, 1), direction(:, 2), direction(:, 3), ... 'Color', 'r', ... 'Marker', '.', ... 'AutoScale', 'off') surf(x{1}, x{2}, x{3}, ... 'EdgeColor', 'r', ... 'FaceColor', 'none') plot3(trace(:, 1), trace(:, 2), trace(:, 3), ... 'Color', 'b', ... 'Marker', '.') plot3(transpose(cat(2, ... center(ones(size(position, 1), 1), 1), ... position(:, 1))), ... transpose(cat(2, ... center(ones(size(position, 1), 1), 2), ... position(:, 2))), ... transpose(cat(2, ... center(ones(size(position, 1), 1), 3), ... position(:, 3))), ... 'Color', 'y', ... 'Marker', 'none', ... 'LineStyle', '-') for i = 1:length text(trace(i, 1), trace(i, 2), trace(i, 3), ... sprintf('%d', i), ... 'HorizontalAlignment', 'Left', ... 'VerticalAlignment', 'Bottom') end for i = 1:size(position, 1) text(position(i, 1), position(i, 2), position(i, 3), ... sprintf('%4.4f', location(i)), ... 'Color', 'g', ... 'HorizontalAlignment', 'Right', ... 'VerticalAlignment', 'Top') text(0.5*(center(1) + position(i, 1)), ... 0.5*(center(2) + position(i, 2)), ... 0.5*(center(3) + position(i, 3)), ... sprintf('%4.4f', distance(i)), ... 'Color', 'y', ... 'HorizontalAlignment', 'Right', ... 'VerticalAlignment', 'Top') end plot3(position(:, 1), position(:, 2), position(:, 3), ... 'Color', 'g', ... 'Marker', '.', ... 'LineStyle', 'none')
return
|
|