NEURON
savstate.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 #undef check
3 #include <InterViews/resource.h>
4 #include <stdio.h>
5 #include <inttypes.h>
6 #include "ocfile.h"
7 #include "nrnoc2iv.h"
8 #include "classreg.h"
9 #include "ndatclas.h"
10 #include "nrniv_mf.h"
11 
12 #include "tqueue.h"
13 #include "netcon.h"
14 #include "vrecitem.h"
15 
16 typedef void (*ReceiveFunc)(Point_process*, double*, double);
17 
18 #include "membfunc.h"
19 extern int section_count;
20 extern "C" void nrn_shape_update();
21 extern Section** secorder;
22 extern ReceiveFunc* pnt_receive;
25 extern "C" void clear_event_queue();
27 extern PlayRecList* net_cvode_instance_prl();
28 extern double t;
29 extern short* nrn_is_artificial_;
30 static void tqcallback(const TQItem* tq, int i);
31 void (*nrnpy_restore_savestate)(int64_t, char*) = NULL;
32 void (*nrnpy_store_savestate)(char** save_data, uint64_t* save_data_size) = NULL;
33 
34 #define ASSERTfgets(a, b, c) nrn_assert(fgets(a, b, c) != 0)
35 #define ASSERTfread(a, b, c, d) nrn_assert(fread(a, b, c, d) == c)
36 #define ASSERTfwrite(a, b, c, d) nrn_assert(fwrite(a, b, c, d) == c)
37 
38 class SaveState: public Resource {
39  public:
40  SaveState();
41  ~SaveState();
42  virtual void save();
43  virtual void restore(int type);
44  virtual void read(OcFile*, bool close);
45  virtual void write(OcFile*, bool close);
46  struct NodeState {
47  double v;
48  int nmemb;
49  int* type;
50  int nstate;
51  double* state;
52  };
53  struct SecState {
55  int nnode;
56  struct NodeState* ns;
57  struct NodeState* root; // non-zero for rootnode
58  };
59  struct StateStructInfo {
60  int offset;
61  int size;
62  };
63  struct ACellState {
64  int type;
65  int ncell;
66  double* state;
67  };
68  struct NetConState {
69  int object_index; // for checking
70  int nstate;
71  double* state;
72  };
73  struct PreSynState {
74  bool flag; // is it firing?
75  double valthresh, valold, told;
76  };
77  struct TQState {
78  int nstate;
79  double* tdeliver;
81  };
82 
83  private:
84  bool check(bool warn);
85  void alloc();
86  void ssfree();
87  void ssi_def();
88 
89  private:
90  void fread_NodeState(NodeState*, int, FILE*);
91  void fwrite_NodeState(NodeState*, int, FILE*);
92  void fread_SecState(SecState*, int, FILE*);
93  void fwrite_SecState(SecState*, int, FILE*);
94 
95  private:
96  double t_;
97  int nroot_;
98  int nsec_;
100  int nacell_; // number of types
102  int nncs_;
104  int npss_;
107  int tqcnt_; // volatile for index of forall_callback
108  int nprs_;
109  PlayRecordSave** prs_;
113  uint64_t plugin_size_;
114 
115  private:
116  void savenode(NodeState&, Node*);
117  void restorenode(NodeState&, Node*);
118  bool checknode(NodeState&, Node*, bool);
119  void allocnode(NodeState&, Node*);
120 
121  void saveacell(ACellState&, int type);
122  void restoreacell(ACellState&, int type);
123  bool checkacell(ACellState&, int type, bool);
124  void allocacell(ACellState&, int type);
125 
126  void savenet();
127  void restorenet();
128  void readnet(FILE*);
129  void writenet(FILE*);
130  bool checknet(bool);
131  void allocnet();
132  void free_tq();
133  void alloc_tq();
134 
135  public:
136  void tqcount(const TQItem*, int);
137  void tqsave(const TQItem*, int);
138 };
139 
141 static int callback_mode;
142 
143 void tqcallback(const TQItem* tq, int i) {
144  if (callback_mode == 0) {
145  this_savestate->tqcount(tq, i);
146  } else {
147  this_savestate->tqsave(tq, i);
148  }
149 }
150 
152  int i, j;
153  nct = NULL;
154  ssi_def();
155  nroot_ = 0;
156  ss_ = NULL;
157  nsec_ = 0;
158  nncs_ = 0;
159  ncs_ = NULL;
160  npss_ = 0;
161  pss_ = NULL;
162  tqs_ = new TQState();
163  tqs_->nstate = 0;
164  nprs_ = 0;
165  prs_ = NULL;
166  nacell_ = 0;
167  plugin_data_ = NULL;
168  plugin_size_ = 0;
169  for (i = 0; i < n_memb_func; ++i)
170  if (nrn_is_artificial_[i]) {
171  ++nacell_;
172  }
173  acell_ = new ACellState[nacell_];
174  for (i = 0; i < nacell_; ++i) {
175  acell_[i].ncell = 0;
176  acell_[i].state = 0;
177  }
178  for (i = 0, j = 0; i < n_memb_func; ++i)
179  if (nrn_is_artificial_[i]) {
180  acell_[j].type = i;
181  ++j;
182  }
183 }
184 
186  ssfree();
187  delete tqs_;
188  delete[] acell_;
189  delete[] ssi;
190 }
191 
192 void SaveState::fread_NodeState(NodeState* ns, int cnt, FILE* f) {
193  for (int i = 0; i < cnt; ++i) {
194  ASSERTfread(&ns[i].v, sizeof(double), 1, f);
195  ASSERTfread(&ns[i].nmemb, sizeof(int), 1, f);
196  ASSERTfread(&ns[i].nstate, sizeof(int), 1, f);
197  }
198 }
199 void SaveState::fwrite_NodeState(NodeState* ns, int cnt, FILE* f) {
200  for (int i = 0; i < cnt; ++i) {
201  ASSERTfwrite(&ns[i].v, sizeof(double), 1, f);
202  ASSERTfwrite(&ns[i].nmemb, sizeof(int), 1, f);
203  ASSERTfwrite(&ns[i].nstate, sizeof(int), 1, f);
204  }
205 }
206 void SaveState::fread_SecState(SecState* ss, int cnt, FILE* f) {
207  int b;
208  for (int i = 0; i < cnt; ++i) {
209  ASSERTfread(&ss[i].nnode, sizeof(int), 1, f);
210  ASSERTfread(&b, sizeof(int), 1, f);
211  if (b) {
212  ss[i].root = new NodeState;
213  } else {
214  ss[i].root = 0;
215  }
216  }
217 }
218 void SaveState::fwrite_SecState(SecState* ss, int cnt, FILE* f) {
219  int b;
220  for (int i = 0; i < cnt; ++i) {
221  ASSERTfwrite(&ss[i].nnode, sizeof(int), 1, f);
222  b = ss[i].root ? 1 : 0;
223  ASSERTfwrite(&b, sizeof(int), 1, f);
224  }
225 }
226 
228  if (nct) {
229  return;
230  }
231  Symbol* s = hoc_lookup("NetCon");
232  nct = s->u.ctemplate;
234  int sav = v_structure_change;
235  for (int im = 0; im < n_memb_func; ++im) {
236  ssi[im].offset = -1;
237  ssi[im].size = 0;
238  if (!memb_func[im].sym) {
239  continue;
240  }
241  NrnProperty* np = new NrnProperty(memb_func[im].sym->name);
242  // generally we only save STATE variables. However for
243  // models containing a NET_RECEIVE block, we also need to
244  // save everything except the parameters
245  // because they often contain
246  // logic and analytic state values. Unfortunately, it is often
247  // the case that the ASSIGNED variables are not declared as
248  // RANGE variables so to avoid missing state, save the whole
249  // param array including PARAMETERs.
250  if (pnt_receive[im]) {
251  ssi[im].offset = 0;
252  ssi[im].size = np->prop()->param_size;
253  } else {
254  int type = STATE;
255  for (Symbol* sym = np->first_var(); np->more_var(); sym = np->next_var()) {
256  if (np->var_type(sym) == type || np->var_type(sym) == STATE ||
257  sym->subtype == _AMBIGUOUS) {
258  if (ssi[im].offset < 0) {
259  ssi[im].offset = np->prop_index(sym);
260  }
261  ssi[im].size += hoc_total_array_data(sym, 0);
262  }
263  }
264  }
265  delete np;
266  }
267  // Following set to 1 when NrnProperty constructor calls prop_alloc.
268  // so change back to original value.
269  v_structure_change = sav;
270 }
271 
272 bool SaveState::check(bool warn) {
273  hoc_Item* qsec;
274  int isec;
275  if (nsec_ != section_count) {
276  if (warn) {
277  fprintf(stderr,
278  "SaveState warning: %d sections exist but saved %d\n",
280  nsec_);
281  }
282  return false;
283  }
284  if (nroot_ != nrn_global_ncell) {
285  if (warn) {
286  fprintf(stderr,
287  "SaveState warning: %d cells exist but saved %d\n",
289  nroot_);
290  }
291  return false;
292  }
293  if (nsec_ && ss_[0].sec == NULL) { // got the data from a read
294  isec = 0;
295  // ForAllSections(sec)
296  ITERATE(qsec, section_list) {
297  Section* sec = hocSEC(qsec);
298  ss_[isec].sec = sec;
299  section_ref(ss_[isec].sec);
300  ++isec;
301  }
302  }
303  for (int i = 0, j = 0; i < n_memb_func; ++i)
304  if (nrn_is_artificial_[i]) {
305  if (!checkacell(acell_[j], i, warn)) {
306  return false;
307  }
308  ++j;
309  }
310  for (int isec = 0; isec < nsec_; ++isec) {
311  SecState& ss = ss_[isec];
312  Section* sec = ss.sec;
313  if (!sec->prop || sec->nnode != ss.nnode) {
314  if (warn) {
315  if (!sec->prop) {
316  fprintf(stderr, "SaveState warning: saved section no longer exists\n");
317  } else {
318  fprintf(stderr,
319  "SaveState warning: %s has %d nodes but saved %d\n",
320  secname(sec),
321  sec->nnode,
322  ss.nnode);
323  }
324  }
325  return false;
326  }
327  for (int inode = 0; inode < ss.nnode; ++inode) {
328  NodeState& ns = ss.ns[inode];
329  Node* nd = sec->pnode[inode];
330  int i = 0;
331  Prop* p;
332  for (p = nd->prop; p; p = p->next) {
333  if (ssi[p->type].size == 0) {
334  continue;
335  }
336  if (i >= ns.nmemb) {
337  if (warn) {
338  fprintf(stderr,
339  "SaveState warning: \
340 fewer mechanisms saved than exist at node %d of %s\n",
341  inode,
342  secname(sec));
343  }
344  return false;
345  }
346  if (p->type != ns.type[i]) {
347  if (warn) {
348  fprintf(stderr,
349  "SaveState warning: mechanisms out of order at node %d of %s\n\
350 saved %s but need %s\n",
351  inode,
352  secname(sec),
353  memb_func[i].sym->name,
354  memb_func[p->type].sym->name);
355  }
356  return false;
357  }
358  ++i;
359  }
360  if (i != ns.nmemb) {
361  if (warn) {
362  fprintf(
363  stderr,
364  "SaveState warning: more mechanisms saved than exist at node %d of %s\n",
365  inode,
366  secname(sec));
367  }
368  return false;
369  }
370  }
371  if (!sec->parentsec || ss.root) {
372  if (sec->parentsec || !ss.root) {
373  if (warn) {
374  fprintf(stderr,
375  "SaveState warning: Saved section and %s are not both root sections.\n",
376  secname(sec));
377  }
378  }
379  if (!checknode(*ss.root, sec->parentnode, warn)) {
380  return false;
381  }
382  }
383  }
384  if (!checknet(warn)) {
385  return false;
386  }
387  return true;
388 }
389 
390 bool SaveState::checknode(NodeState& ns, Node* nd, bool warn) {
391  int i = 0;
392  Prop* p;
393  for (p = nd->prop; p; p = p->next) {
394  if (ssi[p->type].size == 0) {
395  continue;
396  }
397  if (i >= ns.nmemb) {
398  if (warn) {
399  fprintf(stderr,
400  "SaveState warning: \
401 fewer mechanisms saved than exist at a root node\n");
402  }
403  return false;
404  }
405  if (p->type != ns.type[i]) {
406  if (warn) {
407  fprintf(stderr,
408  "SaveState warning: mechanisms out of order at a rootnode\n\
409 saved %s but need %s\n",
410  memb_func[i].sym->name,
411  memb_func[p->type].sym->name);
412  }
413  return false;
414  }
415  ++i;
416  }
417  if (i != ns.nmemb) {
418  if (warn) {
419  fprintf(stderr, "SaveState warning: more mechanisms saved than exist at a rootnode\n");
420  }
421  return false;
422  }
423  return true;
424 }
425 
426 bool SaveState::checkacell(ACellState& ac, int type, bool warn) {
427  if (memb_list[type].nodecount != ac.ncell) {
428  if (warn) {
429  fprintf(stderr,
430  "SaveState warning: different number of %s saved than exist.\n",
431  memb_func[type].sym->name);
432  }
433  return false;
434  }
435  return true;
436 }
437 
439  ssfree();
440  int inode, isec;
441  hoc_Item* qsec;
443  if (nsec_) {
444  ss_ = new SecState[nsec_];
445  }
446  nroot_ = 0;
447  isec = 0;
448  // ForAllSections(sec)
449  ITERATE(qsec, section_list) {
450  Section* sec = hocSEC(qsec);
451  SecState& ss = ss_[isec];
452  ss.sec = sec;
453  section_ref(ss.sec);
454  ss.nnode = ss.sec->nnode;
455  ss.ns = new NodeState[ss.nnode];
456  for (inode = 0; inode < ss.nnode; ++inode) {
457  Node* nd = ss.sec->pnode[inode];
458  NodeState& ns = ss.ns[inode];
459  allocnode(ns, nd);
460  }
461  if (!sec->parentsec) {
462  assert(sec->parentnode);
463  ss.root = new NodeState;
464  allocnode(*ss.root, sec->parentnode);
465  ++nroot_;
466  } else {
467  ss.root = 0;
468  }
469  ++isec;
470  }
471  assert(isec == section_count);
473  for (int i = 0, j = 0; i < n_memb_func; ++i)
474  if (nrn_is_artificial_[i]) {
475  allocacell(acell_[j], i);
476  ++j;
477  }
478  PlayRecList* prl = net_cvode_instance_prl();
479  nprs_ = prl->count();
480  if (nprs_) {
481  prs_ = new PlayRecordSave*[nprs_];
482  }
483  allocnet();
484 }
485 
487  ns.nmemb = 0;
488  ns.type = NULL;
489  ns.state = NULL;
490  ns.nstate = 0;
491  Prop* p;
492  for (p = nd->prop; p; p = p->next) {
493  if (ssi[p->type].size == 0) {
494  continue;
495  }
496  ++ns.nmemb;
497  ns.nstate += ssi[p->type].size;
498  }
499  if (ns.nmemb) {
500  ns.type = new int[ns.nmemb];
501  }
502  if (ns.nstate) {
503  ns.state = new double[ns.nstate];
504  }
505  int i = 0;
506  for (p = nd->prop; p; p = p->next) {
507  if (ssi[p->type].size == 0) {
508  continue;
509  }
510  ns.type[i] = p->type;
511  ++i;
512  }
513 }
514 
516  Memb_list& ml = memb_list[type];
517  ac.type = type;
518  ac.ncell = ml.nodecount;
519  if (ac.ncell) {
520  ac.state = new double[ac.ncell * ssi[type].size];
521  }
522 }
523 
525  int i, isec, inode;
526  for (isec = 0; isec < nsec_; ++isec) {
527  SecState& ss = ss_[isec];
528  for (inode = 0; inode < ss.nnode; ++inode) {
529  NodeState& ns = ss.ns[inode];
530  if (ns.nmemb) {
531  delete[] ns.type;
532  }
533  if (ns.nstate) {
534  delete[] ns.state;
535  }
536  }
537  if (ss.root) {
538  NodeState& ns = *ss.root;
539  if (ns.nmemb) {
540  delete[] ns.type;
541  }
542  if (ns.nstate) {
543  delete[] ns.state;
544  }
545  delete ss.root;
546  }
547  if (ss.nnode) {
548  delete[] ss.ns;
549  }
550  if (ss.sec) { // got info from an fread but never checked it
551  section_unref(ss.sec);
552  }
553  }
554  if (nsec_) {
555  delete[] ss_;
556  }
557  nsec_ = 0;
558  ss_ = NULL;
559  for (i = 0; i < nacell_; ++i) {
560  if (acell_[i].ncell) {
561  delete[] acell_[i].state;
562  acell_[i].state = 0;
563  acell_[i].ncell = 0;
564  }
565  } // note we do not destroy the acell_.
566  if (nncs_) {
567  for (i = 0; i < nncs_; ++i) {
568  if (ncs_[i].nstate) {
569  delete[] ncs_[i].state;
570  }
571  }
572  delete[] ncs_;
573  }
574  nncs_ = 0;
575  ncs_ = NULL;
576  if (npss_) {
577  delete[] pss_;
578  }
579  npss_ = 0;
580  pss_ = NULL;
581  free_tq();
582  if (nprs_) {
583  for (i = 0; i < nprs_; ++i) {
584  delete prs_[i];
585  }
586  delete[] prs_;
587  }
588  nprs_ = 0;
589  if (plugin_data_) {
590  delete[] plugin_data_;
591  plugin_data_ = NULL;
592  plugin_size_ = 0;
593  }
594 }
595 
597  NrnThread* nt;
598  if (!check(false)) {
599  alloc();
600  }
601  FOR_THREADS(nt) {
602  assert(t == nt->_t);
603  }
604  t_ = t;
605  int inode;
606  for (int isec = 0; isec < nsec_; ++isec) {
607  SecState& ss = ss_[isec];
608  Section* sec = ss.sec;
609  for (inode = 0; inode < ss.nnode; ++inode) {
610  NodeState& ns = ss.ns[inode];
611  Node* nd = sec->pnode[inode];
612  savenode(ns, nd);
613  }
614  if (ss.root) {
615  NodeState& ns = *ss.root;
616  Node* nd = sec->parentnode;
617  savenode(ns, nd);
618  }
619  }
620  for (int i = 0, j = 0; i < n_memb_func; ++i)
621  if (nrn_is_artificial_[i]) {
622  saveacell(acell_[j], i);
623  ++j;
624  }
625  if (nprs_) {
626  PlayRecList* prl = net_cvode_instance_prl();
627  int i;
628  assert(nprs_ == prl->count());
629  for (i = 0; i < nprs_; ++i) {
630  prs_[i] = prl->item(i)->savestate_save();
631  }
632  }
633  savenet();
634  if (nrnpy_store_savestate) {
636  } else {
637  plugin_size_ = 0;
638  plugin_data_ = NULL;
639  }
640 }
641 
643  ns.v = NODEV(nd);
644  int istate = 0;
645  Prop* p;
646  for (p = nd->prop; p; p = p->next) {
647  if (ssi[p->type].size == 0) {
648  continue;
649  }
650  int type = p->type;
651  int max = ssi[type].offset + ssi[type].size;
652 #if EXTRACELLULAR
653  if (type == EXTRACELL) {
654  for (int i = 0; i < nlayer; ++i) {
655  ns.state[istate++] = nd->extnode->v[i];
656  }
657  } else
658 #endif
659  {
660  for (int ip = ssi[type].offset; ip < max; ++ip) {
661  ns.state[istate++] = p->param[ip];
662  }
663  }
664  }
665 }
666 
668  Memb_list& ml = memb_list[type];
669  int sz = ssi[type].size;
670  double* p = ac.state;
671  for (int i = 0; i < ml.nodecount; ++i) {
672  double* d = ml.data[i];
673  for (int j = 0; j < sz; ++j) {
674  (*p++) = d[j];
675  }
676  }
677 }
678 
680  NrnThread* nt;
681  if (!check(true)) {
682  hoc_execerror("SaveState:", "Stored state inconsistent with current neuron structure");
683  }
684  t = t_;
685  FOR_THREADS(nt) {
686  nt->_t = t_;
687  }
688  int inode;
689  for (int isec = 0; isec < nsec_; ++isec) {
690  SecState& ss = ss_[isec];
691  Section* sec = ss.sec;
692  for (inode = 0; inode < ss.nnode; ++inode) {
693  NodeState& ns = ss.ns[inode];
694  Node* nd = sec->pnode[inode];
695  restorenode(ns, nd);
696  }
697  if (ss.root) {
698  NodeState& ns = *ss.root;
699  Node* nd = sec->parentnode;
700  restorenode(ns, nd);
701  }
702  }
703  for (int i = 0, j = 0; i < n_memb_func; ++i)
704  if (nrn_is_artificial_[i]) {
705  restoreacell(acell_[j], i);
706  ++j;
707  }
708  if (type == 1) {
709  return;
710  }
711  PlayRecList* prl = net_cvode_instance_prl();
712  // during a local step the PlayRecList is augmented with GLineRecord
713  // assert(nprs_ == prl->count());
714  assert(nprs_ <= prl->count());
715  int i;
716  for (i = 0; i < nprs_; ++i) {
717  prs_[i]->savestate_restore();
718  }
719  restorenet();
720  if (plugin_size_) {
722  hoc_execerror("SaveState:", "This state requires Python to unpack.");
723  }
725  }
726 }
727 
729  NODEV(nd) = ns.v;
730  ;
731  int istate = 0;
732  Prop* p;
733  for (p = nd->prop; p; p = p->next) {
734  if (ssi[p->type].size == 0) {
735  continue;
736  }
737  int type = p->type;
738  int max = ssi[type].offset + ssi[type].size;
739 #if EXTRACELLULAR
740  if (type == EXTRACELL) {
741  for (int i = 0; i < nlayer; ++i) {
742  nd->extnode->v[i] = ns.state[istate++];
743  }
744  } else
745 #endif
746  {
747  for (int ip = ssi[type].offset; ip < max; ++ip) {
748  p->param[ip] = ns.state[istate++];
749  }
750  }
751  }
752 }
753 
755  Memb_list& ml = memb_list[type];
756  int sz = ssi[type].size;
757  double* p = ac.state;
758  for (int i = 0; i < ml.nodecount; ++i) {
759  double* d = ml.data[i];
760  for (int j = 0; j < sz; ++j) {
761  d[j] = (*p++);
762  }
763  }
764 }
765 
766 void SaveState::read(OcFile* ocf, bool close) {
767  int version = 6;
768  if (!ocf->open(ocf->get_name(), "r")) {
769  hoc_execerror("Couldn't open file for reading:", ocf->get_name());
770  }
772  BinaryMode(ocf) FILE* f = ocf->file();
773  ssfree();
774  char buf[200];
775  ASSERTfgets(buf, 200, f);
776  if (strcmp(buf, "SaveState binary file version 6.0\n") != 0) {
777  if (strcmp(buf, "SaveState binary file version 7.0\n") == 0) {
778  version = 7;
779  } else {
780  ocf->close();
781  hoc_execerror("Bad SaveState binary file", " Neither version 6.0 or 7.0");
782  }
783  }
784  ASSERTfread(&t_, sizeof(double), 1, f);
785  // fscanf(f, "%d %d\n", &nsec_, &nrootnode_);
786  // on some os's fscanf leaves file pointer at wrong place for next fread
787  // can check it with ftell(f)
788  ASSERTfgets(buf, 200, f);
789  sscanf(buf, "%d %d\n", &nsec_, &nroot_);
790  // to enable comparison of SaveState files, we avoid
791  // putting pointers in the files and instead explicitly read/write
792  // structure elements.
793  if (nsec_) {
794  ss_ = new SecState[nsec_];
795  fread_SecState(ss_, nsec_, f);
796  }
797  for (int isec = 0; isec < nsec_; ++isec) {
798  SecState& ss = ss_[isec];
799  ss.sec = NULL;
800  ss.ns = new NodeState[ss.nnode];
801  fread_NodeState(ss.ns, ss.nnode, f);
802  for (int inode = 0; inode < ss.nnode; ++inode) {
803  NodeState& ns = ss.ns[inode];
804  if (ns.nmemb) {
805  ns.type = new int[ns.nmemb];
806  ASSERTfread(ns.type, sizeof(int), ns.nmemb, f);
807  }
808  if (ns.nstate) {
809  ns.state = new double[ns.nstate];
810  ASSERTfread(ns.state, sizeof(double), ns.nstate, f);
811  }
812  }
813  if (ss.root) {
814  fread_NodeState(ss.root, 1, f);
815  NodeState& ns = *ss.root;
816  if (ns.nmemb) {
817  ns.type = new int[ns.nmemb];
818  ASSERTfread(ns.type, sizeof(int), ns.nmemb, f);
819  }
820  if (ns.nstate) {
821  ns.state = new double[ns.nstate];
822  ASSERTfread(ns.state, sizeof(double), ns.nstate, f);
823  }
824  }
825  }
826  int n = 0;
827  ASSERTfgets(buf, 20, f);
828  sscanf(buf, "%d\n", &n);
829  assert(n == nacell_);
830  for (int i = 0, j = 0; i < n_memb_func; ++i)
831  if (nrn_is_artificial_[i]) {
832  int nt = 0, nc = 0, ns = 0;
833  ASSERTfgets(buf, 200, f);
834  nrn_assert(sscanf(buf, "%d %d %d\n", &nt, &nc, &ns) == 3);
835  assert(nt == i && nc == memb_list[i].nodecount);
836  assert(ns == nc * ssi[i].size);
837  acell_[j].ncell = nc;
838  if (nc) {
839  acell_[j].state = new double[ns];
840  ASSERTfread(acell_[j].state, sizeof(double), ns, f);
841  }
842  ++j;
843  }
844  ASSERTfgets(buf, 20, f);
845  sscanf(buf, "%d\n", &nprs_);
846  if (nprs_) {
847  prs_ = new PlayRecordSave*[nprs_];
848  for (int i = 0; i < nprs_; ++i) {
850  }
851  }
852  readnet(f);
853  // any old plugin information is no longer relevant regardless of what version
854  if (plugin_data_) {
855  delete[] plugin_data_;
856  plugin_data_ = NULL;
857  }
858  plugin_size_ = 0;
859  // if version 7, load new plugin data
860  if (version == 7) {
861  ASSERTfread(&plugin_size_, sizeof(int64_t), 1, f);
862  try {
863  plugin_data_ = new char[plugin_size_];
864  } catch (const std::bad_alloc& e) {
865  ocf->close();
866  hoc_execerror("SaveState:", "Failed to allocate memory.");
867  }
868  if (plugin_data_ == NULL) {
869  ocf->close();
870  hoc_execerror("SaveState:", "Failed to allocate memory.");
871  }
872  ASSERTfread(plugin_data_, sizeof(char), plugin_size_, f);
873  }
874  if (close) {
875  ocf->close();
876  }
877 }
878 
879 void SaveState::write(OcFile* ocf, bool close) {
880  if (!ocf->open(ocf->get_name(), "w")) {
881  hoc_execerror("Couldn't open file for writing:", ocf->get_name());
882  }
883  BinaryMode(ocf) FILE* f = ocf->file();
884  int version = plugin_size_ ? 7 : 6;
885  fprintf(f, "SaveState binary file version %d.0\n", version);
886  ASSERTfwrite(&t_, sizeof(double), 1, f);
887  fprintf(f, "%d %d\n", nsec_, nroot_);
889  for (int isec = 0; isec < nsec_; ++isec) {
890  SecState& ss = ss_[isec];
891  fwrite_NodeState(ss.ns, ss.nnode, f);
892  for (int inode = 0; inode < ss.nnode; ++inode) {
893  NodeState& ns = ss.ns[inode];
894  if (ns.nmemb) {
895  ASSERTfwrite(ns.type, sizeof(int), ns.nmemb, f);
896  }
897  if (ns.nstate) {
898  ASSERTfwrite(ns.state, sizeof(double), ns.nstate, f);
899  }
900  }
901  if (ss.root) {
902  fwrite_NodeState(ss.root, 1, f);
903  NodeState& ns = *ss.root;
904  if (ns.nmemb) {
905  ASSERTfwrite(ns.type, sizeof(int), ns.nmemb, f);
906  }
907  if (ns.nstate) {
908  ASSERTfwrite(ns.state, sizeof(double), ns.nstate, f);
909  }
910  }
911  }
912  fprintf(f, "%d\n", nacell_);
913  for (int i = 0, j = 0; i < n_memb_func; ++i)
914  if (nrn_is_artificial_[i]) {
915  int sz = acell_[j].ncell * ssi[i].size;
916  fprintf(f, "%d %d %d\n", acell_[j].type, acell_[j].ncell, sz);
917  ASSERTfwrite(acell_[j].state, sizeof(double), sz, f);
918  ++j;
919  }
920  fprintf(f, "%d\n", nprs_);
921  for (int i = 0; i < nprs_; ++i) {
922  fprintf(f, "%d %d\n", prs_[i]->pr_->type(), i);
923  prs_[i]->savestate_write(f);
924  }
925  writenet(f);
926  if (version == 7) {
927  ASSERTfwrite(&plugin_size_, sizeof(int64_t), 1, f);
929  }
930  if (close) {
931  ocf->close();
932  }
933 }
934 
936  int i, j, n;
937  double* w;
938  hoc_Item* q;
939  Object* ob;
940  NetCon* d;
941  PreSyn* ps;
942  i = 0;
943  ITERATE(q, nct->olist) {
944  ob = OBJ(q);
945  d = (NetCon*) ob->u.this_pointer;
946  n = ncs_[i].nstate;
947  w = ncs_[i].state;
948  for (j = 0; j < n; ++j) {
949  w[j] = d->weight_[j];
950  }
951  ++i;
952  }
953  i = 0;
956  ps = (PreSyn*) VOIDITM(q);
957  ps->hi_index_ = i;
958  pss_[i].flag = ps->flag_;
959  pss_[i].valthresh = ps->valthresh_;
960  pss_[i].valold = ps->valold_;
961  pss_[i].told = ps->told_;
962  ++i;
963  }
964  alloc_tq();
965  tqcnt_ = 0;
966  NrnThread* nt;
967  FOR_THREADS(nt) {
969  this_savestate = this;
970  callback_mode = 1;
972  }
973 }
974 
975 void SaveState::tqcount(const TQItem*, int) {
976  ++tqcnt_;
977 }
978 
979 void SaveState::tqsave(const TQItem* q, int) {
980  DiscreteEvent* de = (DiscreteEvent*) q->data_;
981  tqs_->tdeliver[tqcnt_] = q->t_;
982  tqs_->items[tqcnt_] = de->savestate_save();
983  ++tqcnt_;
984 }
985 
987  int i, j, n;
988  double* w;
989  hoc_Item* q;
990  Object* ob;
991  NetCon* d;
992  PreSyn* ps;
993  // NetCon's
994  i = 0;
995  ITERATE(q, nct->olist) {
996  ob = OBJ(q);
997  d = (NetCon*) ob->u.this_pointer;
998  n = ncs_[i].nstate;
999  w = ncs_[i].state;
1000  for (j = 0; j < n; ++j) {
1001  d->weight_[j] = w[j];
1002  }
1003  ++i;
1004  }
1005  // PreSyn's
1006  i = 0;
1007  if (net_cvode_instance_psl())
1009  ps = (PreSyn*) VOIDITM(q);
1010  ps->hi_index_ = i;
1011  ps->flag_ = pss_[i].flag;
1012  ps->valthresh_ = pss_[i].valthresh;
1013  ps->valold_ = pss_[i].valold;
1014  ps->told_ = pss_[i].told;
1015  ++i;
1016  }
1017 
1018  // event queue
1019  // clear it
1021  // restore it
1022  n = tqs_->nstate;
1023  for (i = 0; i < n; ++i) {
1025  }
1026 }
1027 
1028 void SaveState::readnet(FILE* f) {
1029  free_tq();
1030  char buf[200];
1031  ASSERTfgets(buf, 200, f);
1032  sscanf(buf, "%d\n", &nncs_);
1033  if (nncs_ != 0) {
1034  ncs_ = new NetConState[nncs_];
1035  }
1036  int i, n, type;
1037  for (i = 0; i < nncs_; ++i) {
1038  ASSERTfgets(buf, 200, f);
1039  sscanf(buf, "%d %d\n", &ncs_[i].object_index, &ncs_[i].nstate);
1040  if (ncs_[i].nstate) {
1041  ncs_[i].state = new double[ncs_[i].nstate];
1042  ASSERTfread(ncs_[i].state, sizeof(double), ncs_[i].nstate, f);
1043  }
1044  }
1045  // PreSyn's
1046  ASSERTfgets(buf, 200, f);
1047  sscanf(buf, "%d\n", &npss_);
1048  if (npss_ != 0) {
1049  pss_ = new PreSynState[npss_];
1050  ASSERTfread(pss_, sizeof(PreSynState), npss_, f);
1051  PreSyn* ps;
1052  i = 0;
1053  hoc_Item* q;
1054  if (net_cvode_instance_psl())
1056  ps = (PreSyn*) VOIDITM(q);
1057  ps->hi_index_ = i;
1058  ++i;
1059  }
1060  assert(npss_ == i);
1061  }
1062 
1063  ASSERTfgets(buf, 200, f);
1064  sscanf(buf, "%d\n", &n);
1065  tqs_->nstate = n;
1066  if (n) {
1067  tqs_->items = new DiscreteEvent*[n];
1068  tqs_->tdeliver = new double[n];
1069  ASSERTfread(tqs_->tdeliver, sizeof(double), n, f);
1070  for (i = 0; i < n; ++i) {
1071  DiscreteEvent* de = NULL;
1072  ASSERTfgets(buf, 200, f);
1073  sscanf(buf, "%d\n", &type);
1074  switch (type) {
1075  case DiscreteEventType:
1077  break;
1078  case NetConType:
1079  de = NetCon::savestate_read(f);
1080  break;
1081  case SelfEventType:
1082  de = SelfEvent::savestate_read(f);
1083  break;
1084  case PreSynType:
1085  de = PreSyn::savestate_read(f);
1086  break;
1087  case HocEventType:
1088  de = HocEvent::savestate_read(f);
1089  break;
1090  case PlayRecordEventType:
1092  break;
1093  case NetParEventType:
1095  break;
1096  default:
1097  hoc_execerror("SaveState::readnet", "Unimplemented DiscreteEvent type");
1098  break;
1099  }
1100  tqs_->items[i] = de;
1101  }
1102  }
1103 }
1104 
1105 void SaveState::writenet(FILE* f) {
1106  fprintf(f, "%d\n", nncs_);
1107  int i, n;
1108  for (i = 0; i < nncs_; ++i) {
1109  fprintf(f, "%d %d\n", ncs_[i].object_index, ncs_[i].nstate);
1110  if (ncs_[i].nstate) {
1111  ASSERTfwrite(ncs_[i].state, sizeof(double), ncs_[i].nstate, f);
1112  }
1113  }
1114  fprintf(f, "%d\n", npss_);
1115  if (npss_) {
1116  ASSERTfwrite(pss_, sizeof(PreSynState), npss_, f);
1117  }
1118  n = tqs_->nstate;
1119  fprintf(f, "%d\n", n);
1120  if (n) {
1121  ASSERTfwrite(tqs_->tdeliver, sizeof(double), n, f);
1122  for (i = 0; i < n; ++i) {
1123  tqs_->items[i]->savestate_write(f);
1124  }
1125  }
1126 }
1127 
1128 bool SaveState::checknet(bool warn) {
1129  if (nncs_ != nct->count) {
1130  if (warn) {
1131  fprintf(stderr,
1132  "SaveState warning: There are %d NetCon but %d saved\n",
1133  nct->count,
1134  nncs_);
1135  }
1136  return false;
1137  }
1138  int i;
1139  hoc_Item* q;
1140  Object* ob;
1141  NetCon* d;
1142  i = 0;
1143  ITERATE(q, nct->olist) {
1144  ob = OBJ(q);
1145  d = (NetCon*) ob->u.this_pointer;
1146  if (ob->index != ncs_[i].object_index) {
1147  if (warn) {
1148  fprintf(stderr,
1149  "SaveState warning: %s is matched with NetCon[%d]\n",
1150  hoc_object_name(ob),
1151  ncs_[i].object_index);
1152  }
1153  return false;
1154  }
1155  if (d->cnt_ != ncs_[i].nstate) {
1156  if (warn) {
1157  fprintf(stderr,
1158  "SaveState warning: %s has %d weight states but saved %d\n",
1159  hoc_object_name(ob),
1160  d->cnt_,
1161  ncs_[i].nstate);
1162  }
1163  return false;
1164  }
1165  ++i;
1166  }
1167  // PreSyn's
1168  i = 0;
1169  if (net_cvode_instance_psl())
1171  ++i;
1172  }
1173  if (npss_ != i) {
1174  if (warn) {
1175  fprintf(stderr,
1176  "SaveState warning: There are %d internal PreSyn but %d saved\n",
1177  i,
1178  npss_);
1179  }
1180  return false;
1181  }
1182  return true;
1183 }
1184 
1186  nncs_ = nct->count;
1187  if (nncs_ != 0) {
1188  ncs_ = new NetConState[nncs_];
1189  }
1190  int i, n;
1191  hoc_Item* q;
1192  Object* ob;
1193  NetCon* d;
1194  i = 0;
1195  ITERATE(q, nct->olist) {
1196  ob = OBJ(q);
1197  d = (NetCon*) ob->u.this_pointer;
1198  ncs_[i].object_index = ob->index;
1199  ncs_[i].nstate = d->cnt_;
1200  if (d->cnt_) {
1201  ncs_[i].state = new double[d->cnt_];
1202  }
1203  ++i;
1204  }
1205  PreSyn* ps;
1206  npss_ = 0;
1207  if (net_cvode_instance_psl())
1209  ps = (PreSyn*) VOIDITM(q);
1210  ps->hi_index_ = npss_;
1211  ++npss_;
1212  }
1213  if (npss_ != 0) {
1214  pss_ = new PreSynState[npss_];
1215  }
1216 }
1217 
1218 // The event TQueue is highly volatile so it needs to be freed and allocated
1219 // on every save and fread
1221  int i;
1222  if (tqs_->nstate) {
1223  for (i = 0; i < tqs_->nstate; ++i) {
1224  delete tqs_->items[i];
1225  }
1226  tqs_->nstate = 0;
1227  delete[] tqs_->items;
1228  delete[] tqs_->tdeliver;
1229  }
1230 }
1232  int n;
1233  free_tq();
1234  tqcnt_ = 0;
1235  NrnThread* nt;
1236  FOR_THREADS(nt) {
1238  this_savestate = this;
1239  callback_mode = 0;
1241  }
1242  n = tqcnt_;
1243  tqs_->nstate = n;
1244  if (n) {
1245  tqs_->items = new DiscreteEvent*[n];
1246  tqs_->tdeliver = new double[n];
1247  }
1248 }
1249 
1250 static void* cons(Object*) {
1251  SaveState* ss = new SaveState();
1252  ss->ref();
1253  return (void*) ss;
1254 }
1255 
1256 static void destruct(void* v) {
1257  SaveState* ss = (SaveState*) v;
1258  Resource::unref(ss);
1259 }
1260 
1261 static double save(void* v) {
1262  SaveState* ss = (SaveState*) v;
1263  ss->save();
1264  return 1.;
1265 }
1266 
1267 static double restore(void* v) {
1268  SaveState* ss = (SaveState*) v;
1269  int type = 0;
1270  if (ifarg(1)) {
1271  type = (int) chkarg(1, 0, 1);
1272  }
1273  ss->restore(type);
1274  return 1.;
1275 }
1276 
1277 static double ssread(void* v) {
1278  bool close = true;
1279  SaveState* ss = (SaveState*) v;
1280  Object* obj = *hoc_objgetarg(1);
1281  check_obj_type(obj, "File");
1282  if (ifarg(2)) {
1283  close = chkarg(2, 0, 1) ? true : false;
1284  }
1285  OcFile* f = (OcFile*) obj->u.this_pointer;
1286  ss->read(f, close);
1287  return 1.;
1288 }
1289 
1290 static double sswrite(void* v) {
1291  bool close = true;
1292  SaveState* ss = (SaveState*) v;
1293  Object* obj = *hoc_objgetarg(1);
1294  check_obj_type(obj, "File");
1295  if (ifarg(2)) {
1296  close = chkarg(2, 0, 1) ? true : false;
1297  }
1298  OcFile* f = (OcFile*) obj->u.this_pointer;
1299  ss->write(f, close);
1300  return 1.;
1301 }
1302 
1304  {"save", save, "restore", restore, "fread", ssread, "fwrite", sswrite, 0, 0};
1305 
1307  class2oc("SaveState", cons, destruct, members, NULL, NULL, NULL);
1308 }
const char * secname(Section *sec)
Definition: cabcode.cpp:1776
Memb_func * memb_func
Definition: init.cpp:123
short type
Definition: cabvars.h:9
bool flag_
Definition: netcon.h:198
double told_
Definition: netcon.h:195
double valthresh_
Definition: netcon.h:196
double valold_
Definition: netcon.h:195
virtual DiscreteEvent * savestate_save()
Definition: netcvode.cpp:4809
virtual void savestate_write(FILE *)
Definition: netcvode.cpp:4828
static DiscreteEvent * savestate_read(FILE *)
Definition: netcvode.cpp:4824
virtual void savestate_restore(double deliverytime, NetCvode *)
Definition: netcvode.cpp:4818
static DiscreteEvent * savestate_read(FILE *)
Definition: hocevent.cpp:157
Definition: netcon.h:83
double * weight_
Definition: netcon.h:112
int cnt_
Definition: netcon.h:114
static DiscreteEvent * savestate_read(FILE *)
Definition: netcvode.cpp:4929
static DiscreteEvent * savestate_read(FILE *)
Definition: netpar.cpp:287
int prop_index(const Symbol *) const
Definition: ndatclas.cpp:215
int var_type(Symbol *) const
Definition: ndatclas.cpp:153
Symbol * first_var()
Definition: ndatclas.cpp:127
Symbol * next_var()
Definition: ndatclas.cpp:140
bool more_var()
Definition: ndatclas.cpp:132
Prop * prop() const
Definition: ndatclas.cpp:123
Definition: ocfile.h:9
void close()
Definition: ocfile.cpp:308
FILE * file()
Definition: ocfile.cpp:367
const char * get_name()
Definition: ocfile.h:15
bool open(const char *filename, const char *type)
Definition: ocfile.cpp:343
static DiscreteEvent * savestate_read(FILE *)
Definition: netcvode.cpp:360
static PlayRecordSave * savestate_read(FILE *)
Definition: netcvode.cpp:374
Definition: netcon.h:255
long hi_index_
Definition: netcon.h:303
static DiscreteEvent * savestate_read(FILE *)
Definition: netcvode.cpp:5167
virtual void ref() const
Definition: resource.cpp:47
virtual void unref() const
Definition: resource.cpp:52
virtual void write(OcFile *, bool close)
Definition: savstate.cpp:879
void readnet(FILE *)
Definition: savstate.cpp:1028
void restorenode(NodeState &, Node *)
Definition: savstate.cpp:728
void ssi_def()
Definition: savstate.cpp:227
virtual void restore(int type)
Definition: savstate.cpp:679
void restoreacell(ACellState &, int type)
Definition: savstate.cpp:754
int nacell_
Definition: savstate.cpp:100
void allocnet()
Definition: savstate.cpp:1185
void saveacell(ACellState &, int type)
Definition: savstate.cpp:667
int nsec_
Definition: savstate.cpp:98
StateStructInfo * ssi
Definition: savstate.cpp:110
bool checknode(NodeState &, Node *, bool)
Definition: savstate.cpp:390
void fwrite_SecState(SecState *, int, FILE *)
Definition: savstate.cpp:218
void alloc_tq()
Definition: savstate.cpp:1231
bool checknet(bool)
Definition: savstate.cpp:1128
void restorenet()
Definition: savstate.cpp:986
void tqsave(const TQItem *, int)
Definition: savstate.cpp:979
void fread_SecState(SecState *, int, FILE *)
Definition: savstate.cpp:206
void fread_NodeState(NodeState *, int, FILE *)
Definition: savstate.cpp:192
void free_tq()
Definition: savstate.cpp:1220
NetConState * ncs_
Definition: savstate.cpp:103
void savenet()
Definition: savstate.cpp:935
PreSynState * pss_
Definition: savstate.cpp:105
TQState * tqs_
Definition: savstate.cpp:106
SecState * ss_
Definition: savstate.cpp:99
virtual void read(OcFile *, bool close)
Definition: savstate.cpp:766
void writenet(FILE *)
Definition: savstate.cpp:1105
uint64_t plugin_size_
Definition: savstate.cpp:113
ACellState * acell_
Definition: savstate.cpp:101
void savenode(NodeState &, Node *)
Definition: savstate.cpp:642
void alloc()
Definition: savstate.cpp:438
virtual void save()
Definition: savstate.cpp:596
void ssfree()
Definition: savstate.cpp:524
double t_
Definition: savstate.cpp:96
bool checkacell(ACellState &, int type, bool)
Definition: savstate.cpp:426
void allocnode(NodeState &, Node *)
Definition: savstate.cpp:486
bool check(bool warn)
Definition: savstate.cpp:272
cTemplate * nct
Definition: savstate.cpp:111
int nroot_
Definition: savstate.cpp:97
int tqcnt_
Definition: savstate.cpp:107
void tqcount(const TQItem *, int)
Definition: savstate.cpp:975
char * plugin_data_
Definition: savstate.cpp:112
PlayRecordSave ** prs_
Definition: savstate.cpp:109
void fwrite_NodeState(NodeState *, int, FILE *)
Definition: savstate.cpp:199
void allocacell(ACellState &, int type)
Definition: savstate.cpp:515
static DiscreteEvent * savestate_read(FILE *)
Definition: netcvode.cpp:3424
Definition: bbtqueue.h:6
void forall_callback(void(*)(const TQItem *, int))
Definition: bbtqueue.cpp:115
int v_structure_change
Definition: cvodestb.cpp:99
double chkarg(int, double low, double high)
Definition: code2.cpp:638
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:754
char buf[512]
Definition: init.cpp:13
size_t hoc_total_array_data(Symbol *s, Objectdata *obd)
Definition: hoc_oop.cpp:94
char * hoc_object_name(Object *ob)
Definition: hoc_oop.cpp:72
Symbol * hoc_lookup(const char *)
#define assert(ex)
Definition: hocassrt.h:32
#define hocSEC(q)
Definition: hoclist.h:66
#define OBJ(q)
Definition: hoclist.h:67
#define VOIDITM(q)
Definition: hoclist.h:68
Object ** hoc_objgetarg(int)
Definition: code.cpp:1587
void
int ifarg(int)
Definition: code.cpp:1581
#define max(a, b)
Definition: matrix.h:154
#define v
Definition: md1redef.h:4
#define sec
Definition: md1redef.h:13
#define nodecount
Definition: md1redef.h:30
#define i
Definition: md1redef.h:12
#define _AMBIGUOUS
Definition: membfunc.h:100
#define STATE
Definition: membfunc.h:71
#define ITERATE(itm, lst)
Definition: model.h:25
#define FOR_THREADS(nt)
Definition: multicore.h:104
#define fprintf
Definition: mwprefix.h:30
#define NetParEventType
Definition: netcon.h:47
#define PreSynType
Definition: netcon.h:43
#define HocEventType
Definition: netcon.h:44
#define DiscreteEventType
Definition: netcon.h:39
#define SelfEventType
Definition: netcon.h:42
#define PlayRecordEventType
Definition: netcon.h:45
#define NetConType
Definition: netcon.h:41
void section_ref(Section *)
Definition: solve.cpp:575
void section_unref(Section *)
Definition: solve.cpp:565
#define nrn_assert(ex)
Definition: nrnassrt.h:53
int const size_t const size_t n
Definition: nrngsl.h:11
size_t q
for(i=0;i< n;i++)
if(status)
size_t p
size_t j
hoc_List * section_list
Definition: init.cpp:102
Memb_list * memb_list
Definition: init.cpp:124
int nrn_global_ncell
Definition: init.cpp:103
void class2oc(const char *, void *(*cons)(Object *), void(*destruct)(void *), Member_func *, int(*checkpoint)(void **), Member_ret_obj_func *, Member_ret_str_func *)
Definition: hoc_oop.cpp:1560
int n_memb_func
Definition: init.cpp:440
#define BinaryMode(ocfile)
Definition: ocfile.h:61
#define e
Definition: passive0.cpp:22
Section ** secorder
Definition: solve.cpp:77
short * nrn_is_artificial_
Definition: init.cpp:193
static double ssread(void *v)
Definition: savstate.cpp:1277
#define ASSERTfread(a, b, c, d)
Definition: savstate.cpp:35
ReceiveFunc * pnt_receive
Definition: init.cpp:133
PlayRecList * net_cvode_instance_prl()
Definition: netcvode.cpp:327
static SaveState * this_savestate
Definition: savstate.cpp:140
static Member_func members[]
Definition: savstate.cpp:1303
static void * cons(Object *)
Definition: savstate.cpp:1250
#define ASSERTfgets(a, b, c)
Definition: savstate.cpp:34
static void destruct(void *v)
Definition: savstate.cpp:1256
void(* ReceiveFunc)(Point_process *, double *, double)
Definition: savstate.cpp:16
static double sswrite(void *v)
Definition: savstate.cpp:1290
double t
Definition: cvodeobj.cpp:59
hoc_Item * net_cvode_instance_psl()
Definition: netcvode.cpp:323
int section_count
Definition: solve.cpp:76
void(* nrnpy_restore_savestate)(int64_t, char *)
Definition: savstate.cpp:31
static double save(void *v)
Definition: savstate.cpp:1261
#define ASSERTfwrite(a, b, c, d)
Definition: savstate.cpp:36
static int callback_mode
Definition: savstate.cpp:141
static void tqcallback(const TQItem *tq, int i)
Definition: savstate.cpp:143
void nrn_shape_update()
Definition: treeset.cpp:945
TQueue * net_cvode_instance_event_queue(NrnThread *)
Definition: netcvode.cpp:319
NetCvode * net_cvode_instance
Definition: cvodestb.cpp:27
void SaveState_reg()
Definition: savstate.cpp:1306
void clear_event_queue()
Definition: cvodestb.cpp:57
static double restore(void *v)
Definition: savstate.cpp:1267
void(* nrnpy_store_savestate)(char **save_data, uint64_t *save_data_size)
Definition: savstate.cpp:32
check_obj_type(o, "SectionList")
#define NODEV(n)
Definition: section.h:115
#define nlayer
Definition: section.h:188
static int nstate
Definition: simultan.cpp:221
#define cnt
Definition: spt2queue.cpp:19
#define NULL
Definition: sptree.h:16
double * v
Definition: section.h:196
Symbol * sym
Definition: membfunc.h:38
int nodecount
Definition: nrnoc_ml.h:18
double ** data
Definition: nrnoc_ml.h:14
Definition: section.h:133
struct Extnode * extnode
Definition: section.h:161
struct Prop * prop
Definition: section.h:152
Represent main neuron object computed by single thread.
Definition: multicore.h:58
double _t
Definition: multicore.h:59
Definition: hocdec.h:227
void * this_pointer
Definition: hocdec.h:232
int index
Definition: hocdec.h:229
union Object::@39 u
Definition: section.h:214
int param_size
Definition: section.h:218
struct NodeState * ns
Definition: savstate.cpp:56
struct NodeState * root
Definition: savstate.cpp:57
double * tdeliver
Definition: savstate.cpp:79
DiscreteEvent ** items
Definition: savstate.cpp:80
struct Node ** pnode
Definition: section.h:51
short nnode
Definition: section.h:41
Definition: model.h:57
union Symbol::@18 u
char * name
Definition: model.h:72
HocStruct cTemplate * ctemplate
Definition: hocdec.h:152
hoc_List * olist
Definition: hocdec.h:204
int count
Definition: hocdec.h:203