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