mcdougallab / matlabneuroninterface

Interface for connecting NEURON and MATLAB
BSD 3-Clause "New" or "Revised" License
5 stars 1 forks source link

sections aren't being garbage collected #73

Closed ramcdougal closed 12 months ago

ramcdougal commented 1 year ago

Running

dend2 = n.Section("dend2");
dend2 = n.Section("dend2");

leaves TWO sections, both called "dend2"

vijayiyer05 commented 1 year ago

By default, MATLAB classes are value classes. To get the behavior you desire, I think it simply needs to be defined as a handle class.

See comparison of the two types at: https://www.mathworks.com/help/matlab/matlab_oop/comparing-handle-and-value-classes.html

edovanveen commented 1 year ago

I don't think making the Matlab class a handle class will fix this issue; the issue (as far as I understand) has to do with the C++ object not being garbage collected properly. In other words, we probably have to fix the reference count decrease for the Section by calling the correct NEURON functions in the correct order.

vijayiyer05 commented 1 year ago

I think handle class specification would impact calls to underlying C++ object constructors.

If there's a need to explicitly call the C++ object destructors, then that likely requires to implement explicitly the handle class destructor to make sure the underlying C++ destructor is called.

edovanveen commented 1 year ago

@vijayiyer05 Making Section a handle subclass now makes matlab call delete() as expected.

@ramcdougal However, the C++ object still is not deleted properly. I have tried a few ways to delete the Section but I run into some problems. When I follow the example in https://github.com/mcdougallab/neuron-c-api-demos/blob/delete-section/delete-section-demo/delete-section-demo.cpp#L64, by using:

        function delete(self)
            self.push();
            clib.neuron.hoc_oc("delete_section()");
            clib.neuron.nrn_sec_pop();
        end

The first run (of example_allsec) goes well, but upon subsequent runs I get warnings:

nrn_test: Accessing a deleted section
 near line 0
 delete_section()
                 ^
Warning: The following error was caught while executing 'neuron.Section' class destructor:
Error using clib.neuron.nrn_sec_pop
User Library threw std::exception with message:'hoc_execerror: Accessing a deleted section'.

Error in neuron.Section/delete (line 61)
            clib.neuron.nrn_sec_pop();

Error in clearvars (line 107)
evalin('caller', clearExpr);

Error in example_allsec (line 2)
clearvars -except testCase;  % Make sure testing params are not cleared. 
> In clearvars (line 107)
In example_allsec (line 2) 
nrn_test: Accessing a deleted section
 near line 1
 delete_section()
                 ^
        delete_section()
nrn_test: Section access unspecified
 near line 0
 ^
Warning: The following error was caught while executing 'neuron.Section' class destructor:
Error using clib.neuron.nrn_sec_pop
User Library threw std::exception with message:'hoc_execerror: Section access unspecified'.

Error in neuron.Section/delete (line 61)
            clib.neuron.nrn_sec_pop();

Error in clearvars (line 107)
evalin('caller', clearExpr);

Error in example_allsec (line 2)
clearvars -except testCase;  % Make sure testing params are not cleared. 
> In clearvars (line 107)
In example_allsec (line 2) 
nrn_test: Accessing a deleted section
 near line 1
 delete_section()
                 ^
        delete_section()
nrn_test: Section access unspecified
 near line 0
 ^
Warning: The following error was caught while executing 'neuron.Section' class destructor:
Error using clib.neuron.nrn_sec_pop
User Library threw std::exception with message:'hoc_execerror: Section access unspecified'.

Error in neuron.Section/delete (line 61)
            clib.neuron.nrn_sec_pop();

Error in clearvars (line 107)
evalin('caller', clearExpr);

Error in example_allsec (line 2)
clearvars -except testCase;  % Make sure testing params are not cleared. 
> In clearvars (line 107)
In example_allsec (line 2) 
nrn_test: Accessing a deleted section
 near line 1
 delete_section()
                 ^
        delete_section()
nrn_test: Section access unspecified
 near line 0
 ^
Warning: The following error was caught while executing 'neuron.Section' class destructor:
Error using clib.neuron.nrn_sec_pop
User Library threw std::exception with message:'hoc_execerror: Section access unspecified'.

Error in neuron.Section/delete (line 61)
            clib.neuron.nrn_sec_pop();

Error in clearvars (line 107)
evalin('caller', clearExpr);

Error in example_allsec (line 2)
clearvars -except testCase;  % Make sure testing params are not cleared. 
> In clearvars (line 107)
In example_allsec (line 2) 

I am now wondering if I need to be using clib.neuron.section_unref(self.sec) in the destructor.

edovanveen commented 1 year ago

Update: I think it's fixed now!