C/C++ API

Anything that doesn't fit elsewhere.
stephanmg
Posts: 68
Joined: Tue Jul 03, 2012 4:40 am

Re: C/C++ API

Post by stephanmg »

You're my hero for today. :)

All the best,
Stephan
stephanmg
Posts: 68
Joined: Tue Jul 03, 2012 4:40 am

Re: C/C++ API

Post by stephanmg »

One question concerning hoc_valid_stmt(..., ...):

How can I make it less talky, i. e. supress the output of the executed statement? If this would be possible, it would be great.

All the best,
Stephan

Edit: great forum!
Found the (partial) answer here:
Another question would be:
How can I quit the ivocmain interpreter. I start it by ivocmain(argc, argc, env) but i need also to quit it. :)
hines
Site Admin
Posts: 1687
Joined: Wed May 18, 2005 3:32 pm

Re: C/C++ API

Post by hines »

see how the hoc 'quit()' function is executed in src/oc/hoc.c via hoc_quit(). That perhaps goes to far as it executes exit(0) but you can see the two
cleanup functions called.
stephanmg
Posts: 68
Joined: Tue Jul 03, 2012 4:40 am

Re: C/C++ API

Post by stephanmg »

hines wrote:see how the hoc 'quit()' function is executed in src/oc/hoc.c via hoc_quit(). That perhaps goes to far as it executes exit(0) but you can see the two
cleanup functions called.
Excellent! I sticked to src/ivoc/ivoc.cpp => I just needed to cleanup the hoc environment (i. e. clear all variables etc.). I think ivoc_cleanup() should be enough for that purpose, actually is it? :)

Oh I see, if i call them and/or hoc_final_quit and ivoc_final_quit my variables are still defined and the interpreter isn't be exited.

Thanks for your instant reply.

All the best,
Stephan
stephanmg
Posts: 68
Joined: Tue Jul 03, 2012 4:40 am

Re: C/C++ API

Post by stephanmg »

Oh i see, it does not clear all variables, i utilize:

Code: Select all

hoc_final_exit();
	ivoc_final_exit();
	ivoc_cleanup();
But that has no effect at all.

All the best,
Stephan
hines
Site Admin
Posts: 1687
Joined: Wed May 18, 2005 3:32 pm

Re: C/C++ API

Post by hines »

if you can figure out how to send a (control)D to the stdin, that will cause ivocmain to return normally.
stephanmg
Posts: 68
Joined: Tue Jul 03, 2012 4:40 am

Re: C/C++ API

Post by stephanmg »

hines wrote:if you can figure out how to send a (control)D to the stdin, that will cause ivocmain to return normally.
Ah okay, it would also be enough if i just could free all variables. :)


Thanks!

All the best,
Stephan
hines
Site Admin
Posts: 1687
Joined: Wed May 18, 2005 3:32 pm

Re: C/C++ API

Post by hines »

There is no single function that frees all variables. Instead unreferences the objects that were created and that causes the memory to be reclaimed.
If there are a lot of large Vector objects and you can't unreference them completely, then you can free most of their space with
objref vlist
vlist = new List("Vector")
for i=0, vlist.count()-1 { vlist.o(i).buffer_size(1) } // I'm not sure whether or not a buffer size of 0 would work
objref vlist
Sections that live in cell objects (and all of the point processes on those sections) are freed when the cell reference count goes to 0 (usually cells are in a celllist and it is sufficient to 'objref cellist')
But first it is useful to delete all the NetCon objects (usually something like 'objref netconlist'
The idea is that it is usually not to difficult to completely free the memory used by a model. Note that
forall delete_section()
will free all the top level sections as well as those in cell objects.
stephanmg
Posts: 68
Joined: Tue Jul 03, 2012 4:40 am

Re: C/C++ API

Post by stephanmg »

hines wrote:There is no single function that frees all variables. Instead unreferences the objects that were created and that causes the memory to be reclaimed.
If there are a lot of large Vector objects and you can't unreference them completely, then you can free most of their space with
objref vlist
vlist = new List("Vector")
for i=0, vlist.count()-1 { vlist.o(i).buffer_size(1) } // I'm not sure whether or not a buffer size of 0 would work
objref vlist
Sections that live in cell objects (and all of the point processes on those sections) are freed when the cell reference count goes to 0 (usually cells are in a celllist and it is sufficient to 'objref cellist')
But first it is useful to delete all the NetCon objects (usually something like 'objref netconlist'
The idea is that it is usually not to difficult to completely free the memory used by a model. Note that
forall delete_section()
will free all the top level sections as well as those in cell objects.
Ah okay. Would forall delete_section() also delete all points which are added by pt3dadd?

All the best,
Stephan
hines
Site Admin
Posts: 1687
Joined: Wed May 18, 2005 3:32 pm

Re: C/C++ API

Post by hines »

Would forall delete_section() also delete all points which are added by pt3dadd?
yes
stephanmg
Posts: 68
Joined: Tue Jul 03, 2012 4:40 am

Re: C/C++ API

Post by stephanmg »

okay, here we go. thanks again. i guess this could be enough for my purposes. :)
all the best,
Stephan

Edit: Ah no, it does not, i now iterate over all sections and do pt3dclear() :)

Sadly this does not help to delete all the points. :(
hines
Site Admin
Posts: 1687
Joined: Wed May 18, 2005 3:32 pm

Re: C/C++ API

Post by hines »

so 'forall pt3dclear()'
was sufficent to free the space used by the 3d points but 'forall delete_section' was not.
I guess that is due to section space not being freed (just removed from the simulation) until
a section's reference count is decremented to 0. So you would have to destroy all the SectionList
instances and any cell instance where a section was created. It would help to destroy all NetCon
as well since there can be a chain of pointers from NetCon to internal PreSyn to Section.
It can be a good idea to build a model entirely as an instance of a Model class, never hold a permanent
reference to anything in the Model class and then it is convenient to destory the Model instance merely
by setting model=nil
One other aspect of destroying parallel models is important and that is to release all the gid (global identifiers) using
ParallelContext.gid_clear()
stephanmg
Posts: 68
Joined: Tue Jul 03, 2012 4:40 am

Re: C/C++ API

Post by stephanmg »

Hey hines, thank you very much for your efforts and help.

I give an example of the common geometries we need to load and reset in hoc in the Appendix.

I attached a geom.hoc file for that purpose under this post: https://www.dropbox.com/s/nm6f0hz0opttxbs/geom.hoc

It would be good, if one could do it for this type of geometry files in a generic way, i. e. not to check the geom.hoc first - instead just delete the stuff.

Maybe this helps to figure out how I could reset/delete really all pt3dpoints.

Best regards,
Stephan
hines
Site Admin
Posts: 1687
Joined: Wed May 18, 2005 3:32 pm

Re: C/C++ API

Post by hines »

I tried 'nrniv temp.hoc' where temp.hoc was

Code: Select all

nrn_mallinfo(0)
{load_file("geom.hoc")}
nrn_mallinfo(0)
forall delete_section()
nrn_mallinfo(0)
objref all, somatic, axonal, basal
nrn_mallinfo(0)
proc celldef(){}
proc topol(){}
strdef s
for i=1,14 {
  sprint(s, "proc shape3d_%d(){}", i)
  execute1(s)
}
proc basic_shape(){}
proc subsets(){}
proc geom(){}
proc biophys(){}
proc geom_nseg(){}

nrn_mallinfo(0)

and got the output
3357328
5384176
5259136
5236992
3485168

It turns out that the sections and 3d points are freed after the delete_section (I did a second test with
printf("sec_free %s\n", secname(sec));
uncommented in nrn/src/nrnoc/solve.c : sec_free line 490

Note that you still had all the program text with all the pt3dadd calls still in memory so when all the proc's are stubbed out that returns
memory closer to its original value.
stephanmg
Posts: 68
Joined: Tue Jul 03, 2012 4:40 am

Re: C/C++ API

Post by stephanmg »

Okay, that works, but:

consider my geometry from above with 103 sections and about 3000 points:

I load it with hoc_valid_stmt("",0) => I have 103 sections and about 3000 points by counting n3d() in each section by iterating over all sections.

Then I delete all sections and points by forall pt3dclear() and forall delete_section() => now i arrive at 0 points if i iterate again over all sections and counting by n3d().

Third, I load again the same geometry - I get NO sections and NO points and the geometry I load is unchanged? I'm struggling.

Code:

Code: Select all

hoc_valid_stmt("load_file(\"foo.hoc\"), 0)
hoc_valid_stmt("forall { printf(\"Points in section: %i \", n3d() }", 0) // outputs 25, 100, 27, 110, ... for all 103 sections
hoc_valid_stmt("forall pt3dclear()", 0)
hoc_valid_stmt("forall delete_section()", 0)
hoc_valid_stmt("load_file(\"foo.hoc\"), 0)
hoc_valid_stmt("load_file(\"foo.hoc\"), 0) // outputs 0, 0, 0, .. for all 103 sections, why?
Have a nice Weekend and Thanks again.

All the best,
Stephan
Post Reply