Poul K. Sørensen
Poul K. Sørensen

Reputation: 17560

How can i destroy memory in my mex files when variables are destroyed in matlab?

I am handling some memory in my mex files and passing a handle back to matlab. Are there a way to deal with the event of a user clearing or deleting that specific handle stored in a variable in matlab, such I know it can be deleted in the mex file also.

Upvotes: 2

Views: 835

Answers (1)

Andrew Janke
Andrew Janke

Reputation: 23898

Sounds like you're trying to link the lifespan of allocations managed inside your MEX layer to the lifecycle of the M-code level structures that are using them. You probably want to wrap those raw uint64 handle values in a Matlab data structure that supports cleanup callbacks.

You could wrap them in a Matlab handle subclass that you define, and give it a delete method that calls your ocl_mex to do the appropriate cleanup. Delete is a destructor and will automatically get invoked when the last copy of the object is cleared from the Matlab workspace. (And once you're using objects, you could provide more concise methods corresponding to the various ocl_mex calling forms, a nicer display, maybe * syntax for multiplication using operator overloads, and so on.) See http://www.mathworks.com/help/matlab/matlab_oop/handle-class-destructors.html for details. This can work nicely if you then make the mex function a private function inside the class. Makes it easy to add debugging logging and sanity checks around your mex access, etc.

The code could look a little like this.

class ocl < handle
    properties (SetAccess = private)
        ocl_handle  # the raw uint64 handle the MEX layer works with
    end
    methods
        function out = ocl(mex_handle) # maybe make this private
           out.ocl_handle = mex_handle;
        end
        function delete(obj)
            if ~isempty(obj.ocl_handle)
               ocl_mex(obj.ocl_handle, 'cleanup');
            end
        end
        function out = mat_mult(A, B)
           handle_c = ocl_mex('mat_mult', A.ocl_handle, B.ocl_handle);
           out = ocl(handle_c); # And now the new handle has a cleanup hook, too...
        end
    end
    methods (Static = true)
        function out = allocate(some_args)
            new_handle = ocl_mex([], 'allocate', some_args);
            out = ocl(new_handle);
        end
    end
end

If you want to avoid using classes, you can also stick them in a plain struct and use onCleanup to create a callback that automatically gets invoked when the last copy is cleared.

The gotcha is that you have to make sure all access to the handle goes through the object or struct, and nothing pops it out and "leaks" the raw handle value. Easier to enforce with objects.

Upvotes: 3

Related Questions