NEURON
cxprop.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 
3 /*
4 allocate and free property data and Datum arrays for nrniv
5 this allows for the possibility of
6 greater cache efficiency
7 */
8 
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <InterViews/resource.h>
12 #include <nrnmpi.h>
13 #include <nrnoc2iv.h>
14 #include <membfunc.h>
15 #include <nrnmenu.h>
16 #include <arraypool.h>
17 #include <structpool.h>
18 
19 extern void nrn_mk_prop_pools(int);
20 extern void nrn_cache_prop_realloc();
21 extern int nrn_is_ion(int);
22 extern "C" void nrn_update_ion_pointer(Symbol* sion, Datum* dp, int id, int ip);
23 void nrn_delete_prop_pool(int type);
24 #if EXTRACELLULAR
25 extern void nrn_extcell_update_param();
26 #endif
27 extern void nrn_recalc_ptrs(double*(*)(double*));
28 static double* recalc_ptr(double*);
29 
31 
32 #define APSIZE 1000
35 
36 static int force;
37 static int npools_;
40 static void mk_prop_pools(int n);
41 
42 #define NRN_MECH_REORDER 1
43 
44 /*
45 Based on the nrn_threads tml->ml->nodelist order from the last
46 call to nrn_cache_prop_realloc() (which writes a data file) from
47 a previous launch, on this launch, read that file and create
48 pools matched to the space needed by each thread and which, from
49 the sequence of data allocation requests returns space that ends
50 up being laid out in memory in just the way we want.
51 The data file format is
52 maxtype // so we can be sure we have large enough npools_
53 nthread // number of threads
54 nmech // number of mechanisms used in this thread
55 type sz1 sz2 ntget cnt // mechanism type, double/Datum array size total number of times alloc was called, how many needed for this thread
56 // the above specifies the pool allocation
57 // note that the pool chain order is the same as the thread order
58 // there are nthread of the following lists
59 cnt // number of mechanisms in thread
60 type i seq // i is the tml->ml->data[i], seq is the allocation order
61 // ie we want
62 
63 Note that the overall memory allocation sequence has to be identical
64 to the original sequence in terms of get/put for the final
65 layout to be exactly right for cache efficiency and for threads not
66 to share cache lines. However, if this is not the case, the memory allocation
67 is still correct, just not as efficient.
68 */
69 
70 #if NRN_MECH_REORDER
71 
72 static void read_temp1() {
73  // return;
74  FILE* f;
75  int nscan, maxtype, imech, nmech, type, sz1, sz2, ntget, ith, nth, i, j, cnt, seq;
76  char line[200];
77  sprintf(line, "temp_%d_%d", nrnmpi_myid, nrnmpi_numprocs);
78  f = fopen(line, "r");
79  if (!f) { return; }
80  force = 1;
81  nrn_assert(fgets(line, 200, f)); nrn_assert(sscanf(line, "%d", &maxtype) == 1);
82  mk_prop_pools(maxtype);
83  long* ntget1 = new long[maxtype];
84  for (i=0; i < maxtype; ++i) { ntget1[i] = 0; }
85 
86  // allocate the pool space
87  nrn_assert(fgets(line, 200, f)); nrn_assert(sscanf(line, "%d", &nth) == 1);
88  for (ith=0; ith < nth; ++ith) {
89  nrn_assert(fgets(line, 200, f)); nrn_assert(sscanf(line, "%d", &nmech) == 1);
90  for (imech=0; imech < nmech; ++imech) {
91  nrn_assert(fgets(line, 200, f));
92 nrn_assert(sscanf(line, "%d %d %d %d %d", &type, &sz1, &sz2, &ntget, &cnt) == 5);
93 // printf("(%d %d %d %d %d) %s", type, sz1, sz2, ntget, cnt, line);
94  ntget1[type] = ntget;
95  if (sz1) {
96  if (!dblpools_[type]) {
97  dblpools_[type] = new DoubleArrayPool(cnt, sz1);
98  }else{
99  dblpools_[type]->grow(cnt);
100  }
101  }
102  if (sz2) {
103  if (!datumpools_[type]) {
104  datumpools_[type] = new DatumArrayPool(cnt, sz2);
105  }else{
106  datumpools_[type]->grow(cnt);
107  }
108  }
109  }
110  }
111  for (i = 0; i < maxtype; ++i) {
112  if (dblpools_[i] && dblpools_[i]->size() < ntget1[i]) {
113  dblpools_[i]->grow(ntget1[i] - dblpools_[i]->size());
114  }
115  if (datumpools_[i] && datumpools_[i]->size() < ntget1[i]) {
116  datumpools_[i]->grow(ntget1[i] - datumpools_[i]->size());
117  }
118  }
119  delete [] ntget1;
120 
121  // now the tricky part, put items in an unnatural order
122  // first set all pointers to 0
123  for (i = 0; i < maxtype; ++i) {
124  if (dblpools_[i]) {
125  double** items = dblpools_[i]->items();
126  int sz = dblpools_[i]->size();
127  for (int j=0; j < sz; ++j) {
128  items[j] = 0;
129  }
130  }
131  if (datumpools_[i]) {
132  Datum** items = datumpools_[i]->items();
133  int sz = datumpools_[i]->size();
134  for (int j=0; j < sz; ++j) {
135  items[j] = 0;
136  }
137  }
138  }
139 
140  // then set the proper seq pointers
143  int* chain = new int[npools_];
144  for (i=0; i < npools_; ++i) {
145  p1[i] = dblpools_[i];
146  p2[i] = datumpools_[i];
147  chain[i] = 0;
148  }
149  for (ith = 0; ith < nth; ++ith) {
150  nrn_assert(fgets(line, 200, f)); nrn_assert(sscanf(line, "%d", &cnt) == 1);
151  for (i=0; i < cnt; ++i) {
152  nrn_assert(fgets(line, 200, f));
153  nrn_assert(sscanf(line, "%d %d %d", &type, &j, &seq));
154  if (dblpools_[type]) {
155  double** items = dblpools_[type]->items();
156  assert(items[seq] == 0);
157  items[seq] = p1[type]->element(j);
158  ++chain[type];
159  }
160  if (datumpools_[type]) {
161  Datum** items = datumpools_[type]->items();
162  assert(items[seq] == 0);
163  items[seq] = p2[type]->element(j);
164  ++chain[type];
165  }
166  }
167  for (i=0; i < npools_; ++i) {
168  if (chain[i]) {
169  if (p1[i] && p2[i]) {
170  assert(chain[i] == (p1[i]->chain_size() + p2[i]->chain_size()));
171  }else if (p1[i]) {
172  assert(chain[i] == p1[i]->chain_size());
173  }else if (p2[i]) {
174  assert(chain[i] == p2[i]->chain_size());
175  }
176  if (p1[i]) {p1[i] = p1[i]->chain();}
177  if (p2[i]) {p2[i] = p2[i]->chain();}
178  chain[i] = 0;
179  }
180  }
181  }
182  // finally set the rest
183  for (i=0; i < npools_; ++i) {
184  if (p1[i]) {
185  int j = 0;
186  int k = 0;
187  int n = dblpools_[i]->size();
188  int sz = p1[i]->chain_size();
189  double** items = dblpools_[i]->items();
190  for (j = 0; j < n; ++j) {
191  if (items[j] == 0) {
192  assert(k < sz);
193  items[j] = p1[i]->element(k);
194  ++k;
195  }
196  }
197  assert(k == sz);
198  }
199  if (p2[i]) {
200  int j = 0;
201  int k = 0;
202  int n = datumpools_[i]->size();
203  int sz = p2[i]->chain_size();
204  Datum** items = datumpools_[i]->items();
205  for (j = 0; j < n; ++j) {
206  if (items[j] == 0) {
207  assert(k < sz);
208  items[j] = p2[i]->element(k);
209  ++k;
210  }
211  }
212  assert(k == sz);
213  }
214  }
215  delete [] p1;
216  delete [] p2;
217  fclose(f);
218 }
219 #endif // NRN_MECH_REORDER
220 
221 static void mk_prop_pools(int n) {
222  int i;
223  if (n > npools_) {
224  DoubleArrayPool** p1 = new DoubleArrayPool*[n];
225  DatumArrayPool** p2 = new DatumArrayPool*[n];
226  for (i=0; i < n; ++i) {
227  p1[i] = 0;
228  p2[i] = 0;
229  }
230  if (dblpools_) {
231  for (i=0; i < npools_; ++i) {
232  p1[i] = dblpools_[i];
233  p2[i] = datumpools_[i];
234  }
235  delete [] dblpools_;
236  delete [] datumpools_;
237  }
238  dblpools_ = p1;
239  datumpools_ = p2;
240  npools_ = n;
241  }
242 }
243 
245  assert(type < npools_);
246  if (dblpools_[type]) {
247  if (dblpools_[type]->nget() > 0) {
248  hoc_execerror(memb_func[type].sym->name, "prop pool in use");
249  }
250  delete dblpools_[type];
251  dblpools_[type] = NULL;
252  }
253 }
254 
255 void nrn_mk_prop_pools(int n) {
256 #if NRN_MECH_REORDER
257  if (force == 0) { read_temp1(); }
258 #endif
259  mk_prop_pools(n);
260 }
261 
262 extern "C" double* nrn_prop_data_alloc(int type, int count, Prop* p) {
263  if (!dblpools_[type]) {
264  dblpools_[type] = new DoubleArrayPool(APSIZE, count);
265  }
266  assert(dblpools_[type]->d2() == count);
267  p->_alloc_seq = dblpools_[type]->ntget();
268  double* pd = dblpools_[type]->alloc();
269 //if (type > 1) printf("nrn_prop_data_alloc %d %s %d %p\n", type, memb_func[type].sym->name, count, pd);
270  return pd;
271 }
272 
273 extern "C" Datum* nrn_prop_datum_alloc(int type, int count, Prop* p) {
274  int i;
275  Datum* ppd;
276  if (!datumpools_[type]) {
277  datumpools_[type] = new DatumArrayPool(APSIZE, count);
278  }
279  assert(datumpools_[type]->d2() == count);
280  p->_alloc_seq = datumpools_[type]->ntget();
281  ppd = datumpools_[type]->alloc();
282 //if (type > 1) printf("nrn_prop_datum_alloc %d %s %d %p\n", type, memb_func[type].sym->name, count, ppd);
283  for (i=0; i < count; ++i) { ppd[i]._pvoid = 0; }
284  return ppd;
285 }
286 
287 extern "C" void nrn_prop_data_free(int type, double* pd) {
288 //if (type > 1) printf("nrn_prop_data_free %d %s %p\n", type, memb_func[type].sym->name, pd);
289  if (pd) {
290  dblpools_[type]->hpfree(pd);
291  }
292 }
293 
294 extern "C" void nrn_prop_datum_free(int type, Datum* ppd) {
295 //if (type > 1) printf("nrn_prop_datum_free %d %s %p\n", type, memb_func[type].sym->name, ppd);
296  if (ppd) {
297  datumpools_[type]->hpfree(ppd);
298  }
299 }
300 
302 
304 
306  if (!secpool_) {
307  secpool_ = new SectionPool(1000);
308  }
309  Section* s = secpool_->alloc();
310  return s;
311 }
313  secpool_->hpfree(s);
314 }
315 
317  if (!secpool_) {return 0; }
318  return secpool_->is_valid_ptr(v);
319 }
320 
323  int r = 1;
324  for (int i=0; i < npools_; ++i) {
325  p[i] = dblpools_[i];
326  }
327  for (int it = 0; it < nrn_nthread; ++it) {
328  NrnThread* nt = nrn_threads + it;
329  for (NrnThreadMembList* tml = nt->tml; tml; tml = tml->next) {
330  Memb_list* ml = tml->ml;
331  int i = tml->index;
332  if (ml->nodecount > 0) {
333  if (!p[i]) {
334 //printf("thread %d mechanism %s pool chain does not exist\n", it, memb_func[i].sym->name);
335  r = 0;
336  continue;
337  }
338  if (p[i]->chain_size() != ml->nodecount) {
339 //printf("thread %d mechanism %s chain_size %d nodecount=%d\n", it, memb_func[i].sym->name, p[i]->chain_size(), ml->nodecount);
340  r = 0;
341  p[i] = p[i]->chain();
342  continue;
343  }
344  for (int j = 0; j < ml->nodecount; ++j) {
345  if (p[i]->element(j) != ml->data[j]) {
346 //printf("thread %d mechanism %s instance %d element %p data %p\n",
347 //it, memb_func[i].sym->name, j, p[i]->element(j), (ml->data + j));
348  r = 0;
349  }
350  }
351  p[i] = p[i]->chain();
352  }
353  }
354  }
355  delete [] p;
356  return r;
357 }
358 
359 // in-place data reallocation only intended to work when only ion data has
360 // pointers to it and no one uses pointers to other prop data. If this does
361 // not hold, then segmentation violations are likely to occur.
362 // Note that the tml list is already ordered properly so ions are first.
363 // We can therefore call the mechanism pdata_update function (which normally
364 // contains pointers to ion variables) and the ion variables will exist
365 // in their new proper locations.
366 
367 // we do one type (for all threads) at a time. Sadly, we have to keep the
368 // original pool in existence til the new pool is complete. And we have to
369 // keep old ion pools til the end.
370 
371 static DoubleArrayPool** oldpools_; // only here to allow assertion checking
372 
373 // extending to gui pointers and other well-known things that hold pointers
374 // the idea is that there are not *that* many.
375 static int recalc_index_; // the one we are working on
376 static double* recalc_ptr(double* old) {
377  // is old in the op pool?
378  for (DoubleArrayPool* op = oldpools_[recalc_index_]; op; op = op->chain()) {
379  long ds = op->chain_size() * op->d2();
380  if (old >= op->pool() && old < (op->pool() + ds)) {
381  // if so then the value gives us the pointer in the new pool
382  long offset = old - op->pool();
383  offset %= op->d2();
384  DoubleArrayPool* np = dblpools_[recalc_index_];
385  long i = (long)(*old);
386 //if (i < 0 || i >= np->size()) abort();
387  assert(i >= 0 && i < np->size());
388  double* n = np->items()[i] + offset;
389 //printf("recalc_ptr old=%p new=%p value=%g\n", old, n, *n);
390  return n;
391  }
392  }
393  return old;
394 }
395 
397 
398 static int in_place_data_realloc() {
399  int status = 0;
400  NrnThread* nt;
401  // what types are in use
402  int* types = new int[n_memb_func];
403  oldpools_ = new DoubleArrayPool*[n_memb_func];
404  for (int i=0; i < n_memb_func; ++i) {
405  types[i] = 0;
406  oldpools_[i] = dblpools_[i];
407  }
408  FOR_THREADS(nt) {
409  for (NrnThreadMembList* tml = nt->tml; tml; tml = tml->next) {
410  ++types[tml->index];
411  }
412  }
413  // iterate over those types
414  for (int i=0; i < n_memb_func; ++i) if (types[i]) {
415  int ision = nrn_is_ion(i);
416  DoubleArrayPool* oldpool = dblpools_[i];
417  DoubleArrayPool* newpool = 0;
418  // create the pool with proper chain sizes
419  int ml_total_count = 0; // so we can know if we get them all
420  FOR_THREADS(nt) {
421  for (NrnThreadMembList* tml = nt->tml; tml; tml = tml->next) if (i == tml->index) {
422  ml_total_count += tml->ml->nodecount;
423  if (!newpool) {
424  newpool = new DoubleArrayPool(tml->ml->nodecount, oldpool->d2());
425  }else{
426  newpool->grow(tml->ml->nodecount);
427  }
428  break;
429  }
430  }
431  // Any extras? Put them in a new last chain.
432  // actually ml_total_count cannot be 0.
433  int extra = oldpool->nget() - ml_total_count;
434  assert(extra >= 0 && newpool);
435  if (extra) {
436  newpool->grow(extra);
437  }
438  newpool->free_all(); // items in pool data order
439  // reset ml->data pointers to the new pool and copy the values
440  FOR_THREADS(nt) {
441  for (NrnThreadMembList* tml = nt->tml; tml; tml = tml->next) if (i == tml->index) {
442  Memb_list* ml = tml->ml;
443  for (int j=0; j < ml->nodecount; ++j) {
444  double* data = ml->data[j];
445  int ntget = newpool->ntget();
446  ml->data[j] = newpool->alloc();
447  for (int k=0; k < newpool->d2(); ++k) {
448  ml->data[j][k] = data[k];
449  }
450  // store in old location enough info
451  // to construct a pointer to the new location
452  for (int k=0; k < newpool->d2(); ++k) {
453  data[k] = double(ntget);
454  }
455  }
456  // update any Datum pointers to ion variable locations
457  void (*s)(Datum*) = memb_func[i]._update_ion_pointers;
458  if (s) for (int j=0; j < ml->nodecount; ++j) {
459  (*s)(ml->pdata[j]);
460  }
461  }
462  }
463  // the newpool items are in the correct order for thread cache
464  // efficiency. But there may be other old items,
465  // e.g MechanismStandard that are not part of the memb lists.
466  // We made the chain item for them above. Now, sadly, we
467  // need to iterate over the MechanismStandards to find the
468  // old pool data.
469  if (extra) {
470  // should assert that newpool last chain is empty.
471  if (!mechstanlist_) {
472  Symbol* s = hoc_lookup("MechanismStandard");
473  mechstanlist_ = s->u.ctemplate->olist;
474  }
475  hoc_Item* q;
476  int found = 0;
477  int looked_at = 0;
478  ITERATE(q, mechstanlist_) {
479  ++looked_at;
480  MechanismStandard* ms = (MechanismStandard*)(OBJ(q)->u.this_pointer);
481  NrnProperty* np = ms->np();
482  if (np->type() == i && np->deleteable()) {
483  Prop* p = np->prop();
484  double* data = p->param;
485  int ntget = newpool->ntget();
486  p->param = newpool->alloc();
487  for (int k=0; k < newpool->d2(); ++k) {
488  p->param[k] = data[k];
489  }
490  // store in old location enough info
491  // to construct a pointer to the new location
492  for (int k=0; k < newpool->d2(); ++k) {
493  data[k] = double(ntget);
494  }
495  ++found;
496  }
497  }
498  // unless we missed something that holds a prop pointer.
499 // printf("%d extra %s, looked at %d, found %d\n", extra, memb_func[i].sym->name, looked_at, found);
500  assert(extra == found);
501  }
502 
503  dblpools_[i] = newpool;
504  // let the gui and other things update
505  recalc_index_ = i;
507 
508  if (0 && !ision) {
509  delete oldpool;
510  assert (oldpool == oldpools_[i]);
511  oldpools_[i] = 0;
512  }
513  }
514  // update p->param for the node properties
515  Memb_list** mlmap = new Memb_list*[n_memb_func];
516  FOR_THREADS(nt) {
517  // make a map
518  for (int i=0; i < n_memb_func; ++i) { mlmap[i] = 0; }
519  for (NrnThreadMembList* tml = nt->tml; tml; tml = tml->next) {
520  mlmap[tml->index] = tml->ml;
521  tml->ml->nodecount = 0;
522  }
523  // fill
524  for (int i=0; i < nt->end; ++i) {
525  Node* nd = nt->_v_node[i];
526  for (Prop* p = nd->prop; p; p = p->next) {
527  if (memb_func[p->type].current
528  || memb_func[p->type].state
529  || memb_func[p->type].initialize
530  ) {
531  Memb_list* ml = mlmap[p->type];
532  assert(ml->nodelist[ml->nodecount] == nd);
533  if (!memb_func[p->type].hoc_mech) {
534  p->param = ml->data[ml->nodecount];
535  }
536  ++ml->nodecount;
537  }
538  }
539  }
540  }
541  // one more thing to do for extracellular
542 #if EXTRACELLULAR
544 #endif
545  // finally get rid of the old ion pools
546  for (int i=0; i < n_memb_func; ++i) if (types[i] && oldpools_[i]) {
547  delete oldpools_[i];
548  }
549  delete [] oldpools_;
550  delete [] types;
551  delete [] mlmap;
552  // if useful, we could now realloc the Datum pools and just make
553  // bit copies of the Datum values.
554  return status;
555 }
556 
557 extern "C" void nrn_update_ion_pointer(Symbol* sion, Datum* dp, int id, int ip) {
558  int iontype = sion->subtype;
559  DoubleArrayPool* np = dblpools_[iontype];
560  DoubleArrayPool* op = oldpools_[iontype];
561  assert(np);
562  assert(op);
563  assert(ip < op->d2());
564  assert(1); // should point into pool() for one of the op pool chains
565  // and the index should be a pointer to the double in np
566  long i = (long)(*dp[id].pval);
567  assert(i >= 0 && i < np->size());
568  double* pvar = np->items()[i];
569  dp[id].pval = pvar + ip;
570 }
571 
574 // printf("begin nrn_prop_is_cache_efficient %d\n", nrn_prop_is_cache_efficient());
576 // printf("end nrn_prop_is_cache_efficient %d\n", nrn_prop_is_cache_efficient());
577  }
578  return;
579 
580 
581 #if NRN_MECH_REORDER
583  FILE* f;
584  char buf[100];
585  int i, it, type;
586  // we wish to rearrange the arrays so that they are in memb_list->data order within
587  // the ArrayPools. We do not want to use up a lot of temporary space to do this
588  // because there may not be much left.
589  // In each pool all the pointers between put and get (nget of them) are in use.
590  if (force) {
591  sprintf(buf, "temp2_%d", nrnmpi_myid);
592  }else{
593  sprintf(buf, "temp_%d_%d", nrnmpi_myid, nrnmpi_numprocs);
594  }
595  f = fopen(buf, "w");
596  fprintf(f, "%d\n", n_memb_func);
597  fprintf(f, "%d\n", nrn_nthread);
598  for (it = 0; it < nrn_nthread; ++it) {
599  NrnThread* nt = nrn_threads + it;
600  // how many mechanisms used in this thread
601  i=0; for (NrnThreadMembList* tml = nt->tml; tml; tml = tml->next) { ++i; }
602  fprintf(f, "%d\n", i);
603  for (NrnThreadMembList* tml = nt->tml; tml; tml = tml->next) {
604  Memb_list* ml = tml->ml;
605  i = tml->index;
606  int j, cnt = ml->nodecount;
607  int sz1 = 0, sz2 = 0, ntget = 0;
608  if (dblpools_[i]) {
609  sz1 = dblpools_[i]->d2();
610  ntget = dblpools_[i]->ntget();
611  }
612  if (datumpools_[i]) {sz2 = datumpools_[i]->d2(); }
613 fprintf(f, "%d %d %d %d %d %s\n", i, sz1, sz2, ntget, cnt, memb_func[i].sym->name);
614  }
615  }
616  // above is enough for allocating the pools. Now the proper order info.
617  Memb_list** mlmap = new Memb_list*[n_memb_func];
618  for (it = 0; it < nrn_nthread; ++it) {
619  NrnThread* nt = nrn_threads + it;
620  for (i=0; i < n_memb_func; ++i) { mlmap[i] = 0; } //unnecessary but ...
621  // how many prop used in this thread
622  int cnt=0; for (NrnThreadMembList* tml = nt->tml; tml; tml = tml->next) {
623  cnt += tml->ml->nodecount;
624  tml->ml->nodecount = 0; // recount them below
625  mlmap[tml->index] = tml->ml;
626  }
627  fprintf(f, "%d\n", cnt);
628  int cnt2 = 0;
629  for (i=0; i < nt->end; ++i) {
630  Node* nd = nt->_v_node[i];
631  for (Prop* p = nd->prop; p; p = p->next) {
632  if (memb_func[p->type].current
633  || memb_func[p->type].state
634  || memb_func[p->type].initialize
635  ) {
636  Memb_list* ml = mlmap[p->type];
637 if(!ml || nd != ml->nodelist[ml->nodecount]) { abort(); }
638  assert(ml && nd == ml->nodelist[ml->nodecount]);
639 nrn_assert(fprintf(f, "%d %d %ld\n", p->type, ml->nodecount++, p->_alloc_seq) > 0);
640  ++cnt2;
641  }
642  }
643  }
644  assert(cnt == cnt2);
645  }
646  delete [] mlmap;
647  fclose(f);
648 #endif
649 }
650 
651 // for avoiding interthread cache line sharing
652 // each thread needs its own pool instance
653 extern "C" void* nrn_pool_create(long count, int itemsize) {
654  CharArrayPool* p = new CharArrayPool(count, itemsize);
655  return (void*)p;
656 }
657 extern "C" void nrn_pool_delete(void* pool) {
658  CharArrayPool* p = (CharArrayPool*)pool;
659  delete p;
660 }
661 extern "C" void* nrn_pool_alloc(void* pool) {
662  CharArrayPool* p = (CharArrayPool*)pool;
663  return (void*)p->alloc();
664 }
665 extern "C" void nrn_pool_free(void* pool, void* item) {
666  CharArrayPool* p = (CharArrayPool*)pool;
667  p->hpfree(static_cast<char*>(item));
668 }
669 extern "C" void nrn_pool_freeall(void* pool) {
670  CharArrayPool* p = (CharArrayPool*)pool;
671  p->free_all();
672 }
673 
#define data
Definition: rbtqueue.cpp:49
ArrayPool< char > CharArrayPool
Definition: cxprop.cpp:30
static int force
Definition: cxprop.cpp:36
ms
Definition: extargs.h:1
long d2()
Definition: arraypool.h:36
static double * recalc_ptr(double *)
Definition: cxprop.cpp:376
static int npools_
Definition: cxprop.cpp:37
FOR_THREADS(_nt)
Definition: multicore.cpp:887
static hoc_List * mechstanlist_
Definition: cxprop.cpp:396
#define nrn_assert(ex)
Definition: nrnassrt.h:35
double * param
Definition: section.h:218
#define assert(ex)
Definition: hocassrt.h:26
short type
Definition: cabvars.h:10
void nrn_prop_data_free(int type, double *pd)
Definition: cxprop.cpp:287
int size()
Definition: arraypool.h:29
void * _pvoid
Definition: hocdec.h:186
struct NrnThreadMembList * next
Definition: multicore.h:34
void nrn_mk_prop_pools(int)
Definition: cxprop.cpp:255
int nrn_prop_is_cache_efficient()
Definition: cxprop.cpp:321
void nrn_section_free(Section *s)
Definition: cxprop.cpp:312
#define ITERATE(itm, lst)
Definition: model.h:25
double * pval
Definition: hocdec.h:180
int iontype(char *s1, char *s2)
Definition: nocpout.cpp:1730
Symbol * hoc_lookup(const char *)
void * nrn_pool_alloc(void *pool)
Definition: cxprop.cpp:661
void
Pvmi current
Definition: membfunc.h:33
size_t p
Represent main neuron object computed by single thread.
Definition: multicore.h:58
int is_valid_ptr(void *)
Definition: structpool.h:93
T ** items()
Definition: arraypool.h:38
Memb_func * memb_func
Definition: init.cpp:161
nd
Definition: treeset.cpp:893
long _alloc_seq
Definition: section.h:223
#define v
Definition: md1redef.h:4
double ** data
Definition: nrnoc_ml.h:14
long nget()
Definition: arraypool.h:34
bool deleteable()
Definition: ndatclas.cpp:107
ArrayPool< double > DoubleArrayPool
Definition: cxprop.cpp:33
static DoubleArrayPool ** oldpools_
Definition: cxprop.cpp:371
void * hoc_mech
Definition: membfunc.h:54
static philox4x32_key_t k
Definition: nrnran123.cpp:11
sprintf(buf," if (secondorder) {\ " int _i;\" " for(_i=0;_i< %d;++_i) {\" " _p[_slist%d[_i]]+=dt *_p[_dlist%d[_i]];\" " }}\", numeqn, listnum, listnum)
static DatumArrayPool ** datumpools_
Definition: cxprop.cpp:39
hoc_List * olist
Definition: hocdec.h:203
return status
void * nrn_pool_create(long count, int itemsize)
Definition: cxprop.cpp:653
T * alloc()
Definition: arraypool.h:123
Pool< Section > SectionPool
Definition: cxprop.cpp:301
long
Definition: netcvode.cpp:4792
ArrayPool * chain()
Definition: arraypool.h:40
void hpfree(T *)
Definition: arraypool.h:134
int nrn_nthread
Definition: multicore.cpp:44
Node ** _v_node
Definition: multicore.h:77
int const size_t const size_t n
Definition: nrngsl.h:12
int nodecount
Definition: nrnoc_ml.h:18
int nrnmpi_numprocs
_CONST char * s
Definition: system.cpp:74
NrnThread * nrn_threads
Definition: multicore.cpp:45
Pvmi state
Definition: membfunc.h:35
void grow(long ninc)
Definition: arraypool.h:80
void free_all()
Definition: arraypool.h:142
void nrn_recalc_ptrs(double *(*)(double *))
void nrn_prop_datum_free(int type, Datum *ppd)
Definition: cxprop.cpp:294
static void mk_prop_pools(int n)
Definition: cxprop.cpp:221
void nrn_pool_delete(void *pool)
Definition: cxprop.cpp:657
void nrn_pool_freeall(void *pool)
Definition: cxprop.cpp:669
int n_memb_func
Definition: init.cpp:471
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:741
#define cnt
Definition: spt2queue.cpp:19
size_t j
Datum ** pdata
Definition: nrnoc_ml.h:15
fprintf(stderr, "Don't know the location of params at %p\, pp)
Pvmi initialize
Definition: membfunc.h:36
Definition: model.h:57
T * alloc()
Definition: structpool.h:109
Definition: section.h:213
int nrn_is_valid_section_ptr(void *v)
Definition: cxprop.cpp:316
NrnProperty * np()
Definition: nrnmenu.h:34
int type() const
Definition: ndatclas.cpp:119
int end
Definition: multicore.h:65
long subtype
Definition: model.h:59
#define OBJ(q)
Definition: hoclist.h:67
Node ** nodelist
Definition: nrnoc_ml.h:5
void nrn_update_ion_pointer(Symbol *sion, Datum *dp, int id, int ip)
Definition: cxprop.cpp:557
static SectionPool * secpool_
Definition: cxprop.cpp:303
void nrn_cache_prop_realloc()
Definition: cxprop.cpp:572
int nrnmpi_myid
HocStruct cTemplate * ctemplate
Definition: hocdec.h:151
double * nrn_prop_data_alloc(int type, int count, Prop *p)
Definition: cxprop.cpp:262
long ntget()
Definition: arraypool.h:35
void hpfree(T *)
Definition: structpool.h:119
Section * nrn_section_alloc()
Definition: cxprop.cpp:305
#define i
Definition: md1redef.h:12
T * element(long i)
Definition: arraypool.h:37
#define id
Definition: md1redef.h:33
void nrn_extcell_update_param(void)
Definition: extcelln.cpp:326
static int recalc_index_
Definition: cxprop.cpp:375
static char line[MAXLINE]
Definition: ivecop.c:35
#define APSIZE
Definition: cxprop.cpp:32
Datum * nrn_prop_datum_alloc(int type, int count, Prop *p)
Definition: cxprop.cpp:273
char buf[512]
Definition: init.cpp:13
NrnThreadMembList * tml
Definition: multicore.h:62
union Symbol::@18 u
static int in_place_data_realloc()
Definition: cxprop.cpp:398
Definition: section.h:132
void nrn_delete_prop_pool(int type)
Definition: cxprop.cpp:244
size_t q
Definition: hocdec.h:176
Prop * prop() const
Definition: ndatclas.cpp:123
static void read_temp1()
Definition: cxprop.cpp:72
static DoubleArrayPool ** dblpools_
Definition: cxprop.cpp:38
FILE * fopen()
#define pval
Definition: md1redef.h:32
return NULL
Definition: cabcode.cpp:461
int nrn_is_ion(int)
Definition: eion.cpp:45
ArrayPool< Datum > DatumArrayPool
Definition: cxprop.cpp:34
void nrn_pool_free(void *pool, void *item)
Definition: cxprop.cpp:665
struct Prop * prop
Definition: section.h:151
long chain_size()
Definition: arraypool.h:41