NEURON
ocbbs.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 #include "bbsconf.h"
3 #include <InterViews/resource.h>
4 #include "classreg.h"
5 #include "oc2iv.h"
6 #include "ivocvect.h"
7 #include "hoclist.h"
8 #include "bbs.h"
9 #include "bbsimpl.h"
10 #include "ivocvect.h"
11 #include "parse.hpp"
12 #include "section.h"
13 #include "membfunc.h"
15 #include <nrnmpi.h>
16 #include <errno.h>
17 
18 #undef MD
19 #define MD 2147483647.
20 
21 extern int hoc_return_type_code;
22 
23 extern int vector_arg_px(int, double**);
25 void bbs_done();
26 extern double t;
28 extern int nrnmpi_spike_compress(int nspike, bool gid_compress, int xchng_meth);
29 extern int nrnmpi_splitcell_connect(int that_host);
30 extern int nrnmpi_multisplit(Section*, double x, int sid, int backbonestyle);
31 extern int nrn_set_timeout(int timeout);
32 extern void nrnmpi_gid_clear(int);
34 extern double nrn_bgp_receive_time(int);
35 char* (*nrnpy_po2pickle)(Object*, size_t*);
36 Object* (*nrnpy_pickle2po)(char*, size_t);
37 char* (*nrnpy_callpicklef)(char*, size_t, int, size_t*);
38 Object* (*nrnpympi_alltoall_type)(int, int);
39 extern void nrn_prcellstate(int gid, const char* suffix);
41 #if PARANEURON
42 double nrnmpi_transfer_wait_;
44 #endif
45 #if NRNMPI
46 extern "C" {
47 void nrnmpi_barrier();
48 double nrnmpi_dbl_allreduce(double, int);
49 void nrnmpi_dbl_allreduce_vec(double* src, double* dest, int cnt, int type);
50 void nrnmpi_dbl_allgather(double*, double*, int);
51 void nrnmpi_int_alltoallv(int*, int*, int*, int*, int*, int*);
52 void nrnmpi_dbl_alltoallv(double*, int*, int*, double*, int*, int*);
53 double nrmpi_wtime();
54 void nrnmpi_int_broadcast(int*, int, int);
55 void nrnmpi_char_broadcast(char*, int, int);
56 void nrnmpi_dbl_broadcast(double*, int, int);
57 extern void nrnmpi_subworld_size(int n);
58 } // extern "C"
59 #else
60 static void nrnmpi_int_broadcast(int*, int, int) {}
61 static void nrnmpi_char_broadcast(char*, int, int) {}
62 static void nrnmpi_dbl_broadcast(double*, int, int) {}
63 #endif
64 extern double* nrn_mech_wtime_;
65 extern int nrn_nthread;
66 extern void nrn_threads_create(int, int);
67 extern void nrn_thread_partition(int, Object*);
68 extern void nrn_thread_stat();
69 extern int nrn_allow_busywait(int);
70 extern int nrn_how_many_processors();
71 extern size_t nrncore_write();
72 extern size_t nrnbbcore_register_mapping();
73 extern int nrncore_run(const char*);
75 extern int nrncore_is_enabled();
76 extern int nrncore_is_file_mode();
77 extern int nrncore_psolve(double tstop, int file_mode);
78 
79 class OcBBS: public BBS, public Resource {
80  public:
81  OcBBS(int nhost_request);
82  virtual ~OcBBS();
83 
84  public:
85  double retval_;
86  int userid_;
88 };
89 
91  : BBS(n) {
92  next_local_ = 0;
93 }
94 
96 
97 static bool posting_ = false;
98 static void pack_help(int, OcBBS*);
99 static void unpack_help(int, OcBBS*);
100 static int submit_help(OcBBS*);
101 static char* key_help();
102 
103 void bbs_done() {
104 #if USEBBS
105  Symbol* sym = hoc_lookup("ParallelContext");
106  sym = hoc_which_template(sym);
107  hoc_Item *q, *ql;
108  ql = sym->u.ctemplate->olist;
109  q = ql->next;
110  if (q != ql) {
111  Object* ob = OBJ(q);
112  OcBBS* bbs = (OcBBS*) ob->u.this_pointer;
113  if (bbs->is_master()) {
114  bbs->done();
115  }
116  }
117 #endif
118 }
119 
120 static int submit_help(OcBBS* bbs) {
121  int id, i, firstarg, style;
122  char* pname = 0; // if using Python callable
123  posting_ = true;
124  bbs->pkbegin();
125  i = 1;
126  if (hoc_is_double_arg(i)) {
127  bbs->pkint((id = (int) chkarg(i++, 0, MD)));
128  } else {
129  bbs->pkint((id = --bbs->next_local_));
130  }
131  bbs->pkint(0); // space for working_id
132  if (ifarg(i + 1)) {
133 #if 1
134  int argtypes = 0;
135  int ii = 1;
136  if (hoc_is_str_arg(i)) {
137  style = 1;
138  bbs->pkint(style); // "fname", arg1, ... style
139  bbs->pkstr(gargstr(i++));
140  } else {
141  Object* ob = *hoc_objgetarg(i++);
142  size_t size;
143  if (nrnpy_po2pickle) {
144  pname = (*nrnpy_po2pickle)(ob, &size);
145  }
146  if (pname) {
147  style = 3;
148  bbs->pkint(style); // pyfun, arg1, ... style
149  bbs->pkpickle(pname, size);
150  delete[] pname;
151  } else {
152  style = 2;
153  bbs->pkint(style); // [object],"fname", arg1, ... style
154  bbs->pkstr(ob->ctemplate->sym->name);
155  bbs->pkint(ob->index);
156  // printf("ob=%s\n", hoc_object_name(ob));
157  bbs->pkstr(gargstr(i++));
158  }
159  }
160  firstarg = i;
161  for (; ifarg(i); ++i) { // first is least significant
162  if (hoc_is_double_arg(i)) {
163  argtypes += 1 * ii;
164  } else if (hoc_is_str_arg(i)) {
165  argtypes += 2 * ii;
166  } else if (is_vector_arg(i)) { // hoc Vector
167  argtypes += 3 * ii;
168  } else { // must be a PythonObject
169  argtypes += 4 * ii;
170  }
171  ii *= 5;
172  }
173  // printf("submit style %d %s argtypes=%o\n", style, gargstr(firstarg-1), argtypes);
174  bbs->pkint(argtypes);
175  pack_help(firstarg, bbs);
176 #endif
177  } else {
178  if (hoc_is_str_arg(i)) {
179  bbs->pkint(0); // hoc statement style
180  bbs->pkstr(gargstr(i));
181  } else if (nrnpy_po2pickle) {
182  size_t size;
183  pname = (*nrnpy_po2pickle)(*hoc_objgetarg(i), &size);
184  bbs->pkint(3); // pyfun with no arg style
185  bbs->pkpickle(pname, size);
186  bbs->pkint(0); // argtypes
187  delete[] pname;
188  }
189  }
190  posting_ = false;
191  return id;
192 }
193 
194 static double submit(void* v) {
195  int id;
196  OcBBS* bbs = (OcBBS*) v;
197  id = submit_help(bbs);
198  bbs->submit(id);
199  return double(id);
200 }
201 
202 static double context(void* v) {
203  OcBBS* bbs = (OcBBS*) v;
204  submit_help(bbs);
205  // printf("%d context %s %s\n", bbs->myid(), hoc_object_name(*hoc_objgetarg(1)), gargstr(2));
206  bbs->context();
207  return 1.;
208 }
209 
210 static double working(void* v) {
211  OcBBS* bbs = (OcBBS*) v;
212  int id;
213  bool b = bbs->working(id, bbs->retval_, bbs->userid_);
214  hoc_return_type_code = 1; // integer
215  if (b) {
216  return double(id);
217  } else {
218  return 0.;
219  }
220 }
221 
222 static double retval(void* v) {
223  OcBBS* bbs = (OcBBS*) v;
224  return bbs->retval_;
225 }
226 
227 static double userid(void* v) {
228  OcBBS* bbs = (OcBBS*) v;
229  return (double) bbs->userid_;
230 }
231 
232 static double nhost(void* v) {
234  return nrnmpi_numprocs;
235 }
236 
237 static double nrn_rank(void* v) {
239  return nrnmpi_myid;
240 }
241 
242 static double nhost_world(void* v) {
243  hoc_return_type_code = 1; // integer
244  return nrnmpi_numprocs_world;
245 }
246 
247 static double rank_world(void* v) {
249  return nrnmpi_myid_world;
250 }
251 
252 static double nhost_bbs(void* v) {
254  return nrnmpi_numprocs_bbs;
255 }
256 
257 static double rank_bbs(void* v) {
259  return nrnmpi_myid_bbs;
260 }
261 
262 static double subworlds(void* v) {
263  int n = int(chkarg(1, 1, nrnmpi_numprocs_world));
264 #if NRNMPI
265  nrnmpi_subworld_size(n);
266 #endif
267  return 0.;
268 }
269 
270 static double worker(void* v) {
271  OcBBS* bbs = (OcBBS*) v;
272  bbs->worker();
273  return 0.;
274 }
275 
276 static double master_works(void* v) {
277  OcBBS* bbs = (OcBBS*) v;
278  bbs->master_works(int(chkarg(1, 0, 1)));
279  return 0.;
280 }
281 
282 static double done(void* v) {
283  OcBBS* bbs = (OcBBS*) v;
284  bbs->done();
285  return 0.;
286 }
287 
288 static void pack_help(int i, OcBBS* bbs) {
289  if (!posting_) {
290  bbs->pkbegin();
291  posting_ = true;
292  }
293  for (; ifarg(i); ++i) {
294  if (hoc_is_double_arg(i)) {
295  bbs->pkdouble(*getarg(i));
296  } else if (hoc_is_str_arg(i)) {
297  bbs->pkstr(gargstr(i));
298  } else if (is_vector_arg(i)) {
299  int n;
300  double* px;
301  n = vector_arg_px(i, &px);
302  bbs->pkint(n);
303  bbs->pkvec(n, px);
304  } else { // must be a PythonObject
305  size_t size;
306  char* s = nrnpy_po2pickle(*hoc_objgetarg(i), &size);
307  bbs->pkpickle(s, size);
308  delete[] s;
309  }
310  }
311 }
312 
313 static double pack(void* v) {
314  OcBBS* bbs = (OcBBS*) v;
315  pack_help(1, bbs);
316  return 0.;
317 }
318 
319 static double post(void* v) {
320  OcBBS* bbs = (OcBBS*) v;
321  pack_help(2, bbs);
322  posting_ = false;
323  if (hoc_is_str_arg(1)) {
324  bbs->post(gargstr(1));
325  } else {
326  char key[50];
327  sprintf(key, "%g", *getarg(1));
328  bbs->post(key);
329  }
330  return 1.;
331 }
332 
333 static void unpack_help(int i, OcBBS* bbs) {
334  for (; ifarg(i); ++i) {
335  if (hoc_is_pdouble_arg(i)) {
336  *hoc_pgetarg(i) = bbs->upkdouble();
337  } else if (hoc_is_str_arg(i)) {
338  char* s = bbs->upkstr();
339  char** ps = hoc_pgargstr(i);
340  hoc_assign_str(ps, s);
341  delete[] s;
342  } else if (is_vector_arg(i)) {
343  Vect* vec = vector_arg(i);
344  int n = bbs->upkint();
345  vec->resize(n);
346  bbs->upkvec(n, vec->data());
347  } else {
348  hoc_execerror("pc.unpack can only unpack str, scalar, or Vector.",
349  "use pc.upkpyobj to unpack a Python Object");
350  }
351  }
352 }
353 
354 static double unpack(void* v) {
355  OcBBS* bbs = (OcBBS*) v;
356  unpack_help(1, bbs);
357  return 1.;
358 }
359 
360 static double upkscalar(void* v) {
361  OcBBS* bbs = (OcBBS*) v;
362  return bbs->upkdouble();
363 }
364 
365 static const char** upkstr(void* v) {
366  OcBBS* bbs = (OcBBS*) v;
367  char* s = bbs->upkstr();
368  char** ps = hoc_pgargstr(1);
369  hoc_assign_str(ps, s);
370  delete[] s;
371  return (const char**) ps;
372 }
373 
374 static Object** upkvec(void* v) {
375  OcBBS* bbs = (OcBBS*) v;
376  Vect* vec;
377  int n = bbs->upkint();
378  if (ifarg(1)) {
379  vec = vector_arg(1);
380  vec->resize(n);
381  } else {
382  vec = new Vect(n);
383  }
384  bbs->upkvec(n, vec->data());
385  return vec->temp_objvar();
386 }
387 
388 static Object** upkpyobj(void* v) {
389  OcBBS* bbs = (OcBBS*) v;
390  size_t n;
391  char* s = bbs->upkpickle(&n);
393  Object* po = (*nrnpy_pickle2po)(s, n);
394  delete[] s;
395  return hoc_temp_objptr(po);
396 }
397 
398 static Object** pyret(void* v) {
399  OcBBS* bbs = (OcBBS*) v;
400  return bbs->pyret();
401 }
405  Object* po = (*nrnpy_pickle2po)(impl_->pickle_ret_, impl_->pickle_ret_size_);
406  delete[] impl_->pickle_ret_;
407  impl_->pickle_ret_ = 0;
408  impl_->pickle_ret_size_ = 0;
409  return hoc_temp_objptr(po);
410 }
411 
412 static Object** py_alltoall_type(int type) {
414  // for py_gather, py_broadcast, and py_scatter,
415  // the second arg refers to the root rank of the operation (default 0)
416  int size = 0;
417  if (ifarg(2)) {
418  size = int(chkarg(2, -1, 2.14748e9));
419  }
420  Object* po = (*nrnpympi_alltoall_type)(size, type);
421  return hoc_temp_objptr(po);
422 }
423 
424 static Object** py_alltoall(void*) {
425  return py_alltoall_type(1);
426 }
427 
428 static Object** py_allgather(void*) {
429  return py_alltoall_type(2);
430 }
431 
432 static Object** py_gather(void*) {
433  return py_alltoall_type(3);
434 }
435 
436 static Object** py_broadcast(void*) {
437  return py_alltoall_type(4);
438 }
439 
440 static Object** py_scatter(void*) {
441  return py_alltoall_type(5);
442 }
443 
444 static char* key_help() {
445  static char key[50];
446  if (hoc_is_str_arg(1)) {
447  return gargstr(1);
448  } else {
449  sprintf(key, "%g", *getarg(1));
450  return key;
451  }
452 }
453 
454 static double take(void* v) {
455  OcBBS* bbs = (OcBBS*) v;
456  bbs->take(key_help());
457  unpack_help(2, bbs);
458  return 1.;
459 }
460 
461 static double look(void* v) {
462  OcBBS* bbs = (OcBBS*) v;
463  hoc_return_type_code = 2; // boolean
464  if (bbs->look(key_help())) {
465  unpack_help(2, bbs);
466  return 1.;
467  }
468  return 0.;
469 }
470 
471 static double look_take(void* v) {
472  OcBBS* bbs = (OcBBS*) v;
473  hoc_return_type_code = 2; // boolean
474  if (bbs->look_take(key_help())) {
475  unpack_help(2, bbs);
476  return 1.;
477  }
478  return 0.;
479 }
480 
481 static double pctime(void* v) {
482  return ((OcBBS*) v)->time();
483 }
484 
485 static double vtransfer_time(void* v) {
486  int mode = ifarg(1) ? int(chkarg(1, 0., 2.)) : 0;
487  if (mode == 2) {
488  return nrnmpi_rtcomp_time_;
489 #if PARANEURON
490  } else if (mode == 1) {
491  return nrnmpi_splitcell_wait_;
492  } else {
493  return nrnmpi_transfer_wait_;
494  }
495 #else
496  }
497  return 0;
498 #endif
499 }
500 
501 static double mech_time(void* v) {
502  if (ifarg(1)) {
503  if (nrn_mech_wtime_) {
504  int i = (int) chkarg(1, 0, n_memb_func - 1);
505  return nrn_mech_wtime_[i];
506  }
507  } else {
508  if (!nrn_mech_wtime_) {
509  nrn_mech_wtime_ = new double[n_memb_func];
510  }
511  for (int i = 0; i < n_memb_func; ++i) {
512  nrn_mech_wtime_[i] = 0.0;
513  }
514  }
515  return 0;
516 }
517 
518 static double prcellstate(void* v) {
519  nrn_prcellstate(int(*hoc_getarg(1)), hoc_gargstr(2));
520  return 0;
521 }
522 
523 static double wait_time(void* v) {
524  double w = ((OcBBS*) v)->wait_time();
525  return w;
526 }
527 
528 static double step_time(void* v) {
529  double w = ((OcBBS*) v)->integ_time();
530 #if PARANEURON
531  w -= nrnmpi_transfer_wait_ + nrnmpi_splitcell_wait_;
532 #endif
533  return w;
534 }
535 
536 static double step_wait(void* v) {
537  if (ifarg(1)) {
538  nrnmpi_step_wait_ = chkarg(1, -1.0, 0.0);
539  }
540  double w = nrnmpi_step_wait_;
541 #if PARANEURON
542  // sadly, no calculation of transfer and multisplit barrier times.
543 #endif
544  if (w < 0.) {
545  w = 0.0;
546  }
547  return w;
548 }
549 
550 static double send_time(void* v) {
551  int arg = ifarg(1) ? int(chkarg(1, 0, 20)) : 0;
552  if (arg) {
553  return nrn_bgp_receive_time(arg);
554  }
555  return ((OcBBS*) v)->send_time();
556 }
557 
558 static double event_time(void* v) {
559  return 0.;
560 }
561 
562 static double integ_time(void* v) {
563  return 0.;
564 }
565 
566 static double set_gid2node(void* v) {
567  OcBBS* bbs = (OcBBS*) v;
568  bbs->set_gid2node(int(chkarg(1, 0, MD)), int(chkarg(2, 0, MD)));
569  return 0.;
570 }
571 
572 static double gid_exists(void* v) {
573  OcBBS* bbs = (OcBBS*) v;
574  hoc_return_type_code = 1; // NOTE: possible returns are integers 0 - 3
575  return int(bbs->gid_exists(int(chkarg(1, 0, MD))));
576 }
577 
578 static double cell(void* v) {
579  OcBBS* bbs = (OcBBS*) v;
580  bbs->cell();
581  return 0.;
582 }
583 
584 static double threshold(void* v) {
585  OcBBS* bbs = (OcBBS*) v;
586  return bbs->threshold();
587 }
588 
589 static double spcompress(void* v) {
590  int nspike = -1;
591  bool gid_compress = true;
592  int xchng_meth = 0;
593  if (ifarg(1)) {
594  nspike = (int) chkarg(1, -1, MD);
595  }
596  if (ifarg(2)) {
597  gid_compress = (chkarg(2, 0, 1) ? true : false);
598  }
599  if (ifarg(3)) {
600  xchng_meth = (int) chkarg(3, 0, 15);
601  }
602  return (double) nrnmpi_spike_compress(nspike, gid_compress, xchng_meth);
603 }
604 
605 static double splitcell_connect(void* v) {
606  int that_host = (int) chkarg(1, 0, nrnmpi_numprocs - 1);
607  // also needs a currently accessed section that is the root of this_tree
608  nrnmpi_splitcell_connect(that_host);
609  return 0.;
610 }
611 
612 static double multisplit(void* v) {
613  double x = -1.;
614  Section* sec = NULL;
615  int sid = -1;
616  int backbone_style = 2;
617  int reducedtree_host = 0;
618  if (ifarg(1)) {
619  nrn_seg_or_x_arg(1, &sec, &x);
620  sid = (int) chkarg(2, 0, (double) (0x7fffffff));
621  }
622  if (ifarg(3)) {
623  backbone_style = (int) chkarg(3, 0, 2);
624  }
625  // also needs a currently accessed section
626  nrnmpi_multisplit(sec, x, sid, backbone_style);
627  return 0.;
628 }
629 
630 static double set_timeout(void* v) {
631  int arg = 0;
632  if (ifarg(1)) {
633  arg = int(chkarg(1, 0, 10000));
634  }
636  return double(arg);
637 }
638 
639 static double set_mpiabort_on_error(void*) {
640  double ret = double(nrn_mpiabort_on_error_);
641  if (ifarg(1)) {
642  nrn_mpiabort_on_error_ = int(chkarg(1, 0, 1));
643  }
644  return ret;
645 }
646 
647 static double gid_clear(void* v) {
648  int arg = 0;
649  if (ifarg(1)) {
650  arg = int(chkarg(1, 0, 4));
651  }
653  return 0.;
654 }
655 
656 static double outputcell(void* v) {
657  OcBBS* bbs = (OcBBS*) v;
658  int gid = int(chkarg(1, 0., MD));
659  bbs->outputcell(gid);
660  return 0.;
661 }
662 
663 static double spike_record(void* v) {
664  OcBBS* bbs = (OcBBS*) v;
665  IvocVect* spikevec = vector_arg(2);
666  IvocVect* gidvec = vector_arg(3);
667  if (hoc_is_object_arg(1) && is_vector_arg(1)) {
668  IvocVect* gids = vector_arg(1);
669  bbs->spike_record(gids, spikevec, gidvec);
670  } else {
671  int gid = int(chkarg(1, -1., MD));
672  bbs->spike_record(gid, spikevec, gidvec);
673  }
674  return 0.;
675 }
676 
677 static double psolve(void* v) {
679  OcBBS* bbs = (OcBBS*) v;
680  double tstop = chkarg(1, t, 1e9);
681  int enabled = nrncore_is_enabled();
682  int file_mode = nrncore_is_file_mode();
683  if (enabled == 1) {
684  nrncore_psolve(tstop, file_mode);
685  } else if (enabled == 0) {
686  // Classic case
687  bbs->netpar_solve(tstop);
688  }
690  return double(enabled);
691 }
692 
693 static double set_maxstep(void* v) {
694  OcBBS* bbs = (OcBBS*) v;
695  return bbs->netpar_mindelay(chkarg(1, 1e-6, 1e9));
696 }
697 
698 static double spike_stat(void* v) {
699  OcBBS* bbs = (OcBBS*) v;
700  int nsend, nsendmax, nrecv, nrecv_useful;
701  hoc_return_type_code = 1; // integer
702  nsend = nsendmax = nrecv = nrecv_useful = 0;
703  bbs->netpar_spanning_statistics(&nsend, &nsendmax, &nrecv, &nrecv_useful);
704  if (ifarg(1)) {
705  *hoc_pgetarg(1) = nsend;
706  }
707  if (ifarg(2)) {
708  *hoc_pgetarg(2) = nrecv;
709  }
710  if (ifarg(3)) {
711  *hoc_pgetarg(3) = nrecv_useful;
712  }
713  return double(nsendmax);
714 }
715 
716 static double maxhist(void* v) {
717  OcBBS* bbs = (OcBBS*) v;
718  IvocVect* vec = ifarg(1) ? vector_arg(1) : nil;
719  if (vec) {
720  hoc_obj_ref(vec->obj_);
721  }
722  vec = bbs->netpar_max_histogram(vec);
723  if (vec) {
724  hoc_obj_unref(vec->obj_);
725  }
726  return 0.;
727 }
728 
729 static double source_var(void*) { // &source_variable, source_global_index
730  // At BEFORE BREAKPOINT, the value of variable is sent to the
731  // target machine(s). This can only be executed on the
732  // source machine (where source_variable exists).
734  return 0.;
735 }
736 
737 static double target_var(void*) { // &target_variable, source_global_index
738  // At BEFORE BREAKPOINT, the value of the target_variable is set
739  // to the value of the source variable associated
740  // with the source_global_index. This can only be executed on the
741  // target machine (where target_variable exists).
743  return 0.;
744 }
745 
746 static double setup_transfer(void*) { // after all source/target and before init and run
748  return 0.;
749 }
750 
751 static double barrier(void*) {
752  // return wait time
753  double t = 0.;
754 #if NRNMPI
755  if (nrnmpi_numprocs > 1) {
756  t = nrnmpi_wtime();
757  nrnmpi_barrier();
758  t = nrnmpi_wtime() - t;
759  }
760  errno = 0;
761 #endif
762  return t;
763 }
764 
765 static double allreduce(void*) {
766  // type 1,2,3 sum, max, min
767  if (hoc_is_object_arg(1)) {
768  Vect* vec = vector_arg(1);
769  int n = vec->size();
770  if (n == 0) {
771  return 0.0;
772  }
773 #if NRNMPI
774  if (nrnmpi_numprocs > 1) {
775  int type = (int) chkarg(2, 1, 3);
776  double* px = vector_vec(vec);
777  double* dest = new double[n];
778  nrnmpi_dbl_allreduce_vec(px, dest, n, type);
779  for (int i = 0; i < n; ++i) {
780  px[i] = dest[i];
781  }
782  delete[] dest;
783  }
784  errno = 0;
785 #endif
786  return 0.;
787  } else {
788  double val = *getarg(1);
789 #if NRNMPI
790  if (nrnmpi_numprocs > 1) {
791  int type = (int) chkarg(2, 1, 3);
792  val = nrnmpi_dbl_allreduce(val, type);
793  }
794  errno = 0;
795 #endif
796  return val;
797  }
798 }
799 
800 static double allgather(void*) {
801  double val = *getarg(1);
802  Vect* vec = vector_arg(2);
804  double* px = vector_vec(vec);
805 
806 #if NRNMPI
807  if (nrnmpi_numprocs > 1) {
808  nrnmpi_dbl_allgather(&val, px, 1);
809  errno = 0;
810  } else {
811  px[0] = val;
812  }
813 #else
814  px[0] = val;
815 #endif
816  return 0.;
817 }
818 
819 static double alltoall(void*) {
820  int i, ns, np = nrnmpi_numprocs;
821  Vect* vsrc = vector_arg(1);
822  Vect* vscnt = vector_arg(2);
823  ns = vector_capacity(vsrc);
824  double* s = vector_vec(vsrc);
825  if (vector_capacity(vscnt) != np) {
826  hoc_execerror("size of source counts vector is not nhost", 0);
827  }
828  double* x = vector_vec(vscnt);
829  int* scnt = new int[np];
830  int* sdispl = new int[np + 1];
831  sdispl[0] = 0;
832  for (i = 0; i < np; ++i) {
833  scnt[i] = int(x[i]);
834  sdispl[i + 1] = sdispl[i] + scnt[i];
835  }
836  if (ns != sdispl[np]) {
837  hoc_execerror("sum of source counts is not the size of the src vector", 0);
838  }
839  Vect* vdest = vector_arg(3);
840  if (nrnmpi_numprocs > 1) {
841 #if NRNMPI
842  int* rcnt = new int[np];
843  int* rdispl = new int[np + 1];
844  int* c = new int[np];
845  rdispl[0] = 0;
846  for (i = 0; i < np; ++i) {
847  c[i] = 1;
848  rdispl[i + 1] = i + 1;
849  }
850  nrnmpi_int_alltoallv(scnt, c, rdispl, rcnt, c, rdispl);
851  delete[] c;
852  for (i = 0; i < np; ++i) {
853  rdispl[i + 1] = rdispl[i] + rcnt[i];
854  }
855  vector_resize(vdest, rdispl[np]);
856  double* r = vector_vec(vdest);
857  nrnmpi_dbl_alltoallv(s, scnt, sdispl, r, rcnt, rdispl);
858  delete[] rcnt;
859  delete[] rdispl;
860 #endif
861  } else {
862  vector_resize(vdest, ns);
863  double* r = vector_vec(vdest);
864  for (i = 0; i < ns; ++i) {
865  r[i] = s[i];
866  }
867  }
868  delete[] scnt;
869  delete[] sdispl;
870  return 0.;
871 }
872 
873 static double broadcast(void*) {
874  int srcid = int(chkarg(2, 0, nrnmpi_numprocs - 1));
875  int cnt = 0;
876 #if NRNMPI
877  if (nrnmpi_numprocs > 1) {
878  if (hoc_is_str_arg(1)) {
879  char* s;
880  if (srcid == nrnmpi_myid) {
881  s = gargstr(1);
882  cnt = strlen(s) + 1;
883  }
884  nrnmpi_int_broadcast(&cnt, 1, srcid);
885  if (srcid != nrnmpi_myid) {
886  s = new char[cnt];
887  }
888  nrnmpi_char_broadcast(s, cnt, srcid);
889  if (srcid != nrnmpi_myid) {
891  delete[] s;
892  }
893  } else {
894  Vect* vec = vector_arg(1);
895  if (srcid == nrnmpi_myid) {
896  cnt = vec->size();
897  }
898  nrnmpi_int_broadcast(&cnt, 1, srcid);
899  if (srcid != nrnmpi_myid) {
900  vec->resize(cnt);
901  }
902  nrnmpi_dbl_broadcast(vector_vec(vec), cnt, srcid);
903  }
904  } else {
905 #else
906  {
907 #endif
908  if (hoc_is_str_arg(1)) {
909  cnt = strlen(gargstr(1));
910  } else {
911  cnt = vector_arg(1)->size();
912  }
913  }
914  return double(cnt);
915 }
916 
917 static double nthrd(void*) {
918  int ip = 1;
919  hoc_return_type_code = 1; // integer
920  if (ifarg(1)) {
921  if (ifarg(2)) {
922  ip = int(chkarg(2, 0, 1));
923  }
924  nrn_threads_create(int(chkarg(1, 1, 1e5)), ip);
925  }
926  return double(nrn_nthread);
927 }
928 
929 static double partition(void*) {
930  Object* ob = 0;
931  int it;
932  if (ifarg(2)) {
933  ob = *hoc_objgetarg(2);
934  if (ob) {
935  check_obj_type(ob, "SectionList");
936  }
937  }
938  if (ifarg(1)) {
939  it = (int) chkarg(1, 0, nrn_nthread - 1);
940  nrn_thread_partition(it, ob);
941  } else {
942  for (it = 0; it < nrn_nthread; ++it) {
943  nrn_thread_partition(it, ob);
944  }
945  }
946  return 0.0;
947 }
948 
949 static double thread_stat(void*) {
950  nrn_thread_stat();
951  return 0.0;
952 }
953 
954 static double thread_busywait(void*) {
955  int old = nrn_allow_busywait(int(chkarg(1, 0, 1)));
956  return double(old);
957 }
958 
959 static double thread_how_many_proc(void*) {
960  hoc_return_type_code = 1; // integer
961  int i = nrn_how_many_processors();
962  return double(i);
963 }
964 
965 static double sec_in_thread(void*) {
966  hoc_return_type_code = 2; // boolean
967  Section* sec = chk_access();
968  return double(sec->pnode[0]->_nt->id);
969 }
970 
971 static double thread_ctime(void*) {
972  int i;
973 #if 1
974  if (ifarg(1)) {
975  i = int(chkarg(1, 0, nrn_nthread));
976  return nrn_threads[i]._ctime;
977  } else {
978  for (i = 0; i < nrn_nthread; ++i) {
979  nrn_threads[i]._ctime = 0.0;
980  }
981  }
982 #endif
983  return 0.0;
984 }
985 
986 static double nrn_thread_t(void*) {
987  int i;
988  i = int(chkarg(1, 0, nrn_nthread));
989  return nrn_threads[i]._t;
990 }
991 
992 static double thread_dt(void*) {
993  int i;
994  i = int(chkarg(1, 0, nrn_nthread));
995  return nrn_threads[i]._dt;
996 }
997 
998 static double nrncorewrite_argvec(void*) {
999  if (ifarg(2) && !(hoc_is_object_arg(2) && is_vector_arg(2))) {
1000  hoc_execerror("nrnbbcore_write: optional second arg is not a Vector", NULL);
1001  }
1002  return double(nrncore_write());
1003 }
1004 
1005 static double nrncorewrite_argappend(void*) {
1006  if (ifarg(2) && !hoc_is_double_arg(2)) {
1007  hoc_execerror(
1008  "nrncore_write: optional second arg is not a number (True or False append flag)", NULL);
1009  }
1010  return double(nrncore_write());
1011 }
1012 
1013 static double nrncorerun(void*) {
1014  if (ifarg(2)) {
1015  nrn_trajectory_request_per_time_step_ = chkarg(2, 0., 1.) != 0.0;
1016  }
1017  return double(nrncore_run(gargstr(1)));
1018 }
1019 
1020 static double nrnbbcore_register_mapping(void*) {
1021  return double(nrnbbcore_register_mapping());
1022 }
1023 
1024 static Object** gid2obj(void* v) {
1025  OcBBS* bbs = (OcBBS*) v;
1026  return bbs->gid2obj(int(chkarg(1, 0, MD)));
1027 }
1028 
1029 static Object** gid2cell(void* v) {
1030  OcBBS* bbs = (OcBBS*) v;
1031  return bbs->gid2cell(int(chkarg(1, 0, MD)));
1032 }
1033 
1034 static Object** gid_connect(void* v) {
1035  OcBBS* bbs = (OcBBS*) v;
1036  return bbs->gid_connect(int(chkarg(1, 0, MD)));
1037 }
1038 
1039 static Member_func members[] = {"submit",
1040  submit,
1041  "working",
1042  working,
1043  "retval",
1044  retval,
1045  "userid",
1046  userid,
1047  "pack",
1048  pack,
1049  "post",
1050  post,
1051  "unpack",
1052  unpack,
1053  "upkscalar",
1054  upkscalar,
1055  "take",
1056  take,
1057  "look",
1058  look,
1059  "look_take",
1060  look_take,
1061  "runworker",
1062  worker,
1063  "master_works_on_jobs",
1064  master_works,
1065  "done",
1066  done,
1067  "id",
1068  nrn_rank,
1069  "nhost",
1070  nhost,
1071  "id_world",
1072  rank_world,
1073  "nhost_world",
1074  nhost_world,
1075  "id_bbs",
1076  rank_bbs,
1077  "nhost_bbs",
1078  nhost_bbs,
1079  "subworlds",
1080  subworlds,
1081  "context",
1082  context,
1083 
1084  "time",
1085  pctime,
1086  "wait_time",
1087  wait_time,
1088  "step_time",
1089  step_time,
1090  "step_wait",
1091  step_wait,
1092  "send_time",
1093  send_time,
1094  "event_time",
1095  event_time,
1096  "integ_time",
1097  integ_time,
1098  "vtransfer_time",
1100  "mech_time",
1101  mech_time,
1102  "timeout",
1103  set_timeout,
1104  "mpiabort_on_error",
1106 
1107  "set_gid2node",
1108  set_gid2node,
1109  "gid_exists",
1110  gid_exists,
1111  "outputcell",
1112  outputcell,
1113  "cell",
1114  cell,
1115  "threshold",
1116  threshold,
1117  "spike_record",
1118  spike_record,
1119  "psolve",
1120  psolve,
1121  "set_maxstep",
1122  set_maxstep,
1123  "spike_statistics",
1124  spike_stat,
1125  "max_histogram",
1126  maxhist,
1127  "spike_compress",
1128  spcompress,
1129  "gid_clear",
1130  gid_clear,
1131  "prcellstate",
1132  prcellstate,
1133 
1134  "source_var",
1135  source_var,
1136  "target_var",
1137  target_var,
1138  "setup_transfer",
1140  "splitcell_connect",
1142  "multisplit",
1143  multisplit,
1144 
1145  "barrier",
1146  barrier,
1147  "allreduce",
1148  allreduce,
1149  "allgather",
1150  allgather,
1151  "alltoall",
1152  alltoall,
1153  "broadcast",
1154  broadcast,
1155 
1156  "nthread",
1157  nthrd,
1158  "partition",
1159  partition,
1160  "thread_stat",
1161  thread_stat,
1162  "thread_busywait",
1164  "thread_how_many_proc",
1166  "sec_in_thread",
1167  sec_in_thread,
1168  "thread_ctime",
1169  thread_ctime,
1170  "dt",
1171  thread_dt,
1172  "t",
1173  nrn_thread_t,
1174 
1175  "nrnbbcore_write",
1177  "nrncore_write",
1179  "nrnbbcore_register_mapping",
1181  "nrncore_run",
1182  nrncorerun,
1183 
1184  0,
1185  0};
1186 
1187 static Member_ret_str_func retstr_members[] = {"upkstr", upkstr, 0, 0};
1188 
1190  "upkvec", upkvec, "gid2obj", gid2obj, "gid2cell", gid2cell,
1191  "gid_connect", gid_connect, "upkpyobj", upkpyobj, "pyret", pyret,
1192  "py_alltoall", py_alltoall, "py_allgather", py_allgather, "py_gather", py_gather,
1193  "py_broadcast", py_broadcast, "py_scatter", py_scatter, 0, 0};
1194 
1195 static void* cons(Object*) {
1196  // not clear at moment what is best way to handle nested context
1197  int i = -1;
1198  if (ifarg(1)) {
1199  i = int(chkarg(1, 0, 10000));
1200  }
1201  OcBBS* bbs = new OcBBS(i);
1202  bbs->ref();
1203  return bbs;
1204 }
1205 
1206 static void destruct(void* v) {
1207  OcBBS* bbs = (OcBBS*) v;
1208  bbs->unref();
1209 }
1210 
1212  class2oc("ParallelContext", cons, destruct, members, nil, retobj_members, retstr_members);
1213 }
1214 
1215 char* BBSImpl::execute_helper(size_t* size, int id, bool exec) {
1216  char* s;
1217  int subworld = (nrnmpi_numprocs > 1 && nrnmpi_numprocs_bbs < nrnmpi_numprocs_world);
1218  int style = upkint();
1219  if (subworld) {
1220  assert(nrnmpi_myid == 0);
1221  int info[2];
1222  info[0] = id;
1223  info[1] = style;
1224  nrnmpi_int_broadcast(info, 2, 0);
1225  }
1226  char* rs = 0;
1227  *size = 0;
1228  switch (style) {
1229  case 0:
1230  s = upkstr();
1231  if (subworld) {
1232  int size = strlen(s) + 1;
1233  nrnmpi_int_broadcast(&size, 1, 0);
1234  nrnmpi_char_broadcast(s, size, 0);
1235  }
1236  hoc_obj_run(s, nil);
1237  delete[] s;
1238  break;
1239  default: {
1240 #if 1
1241  int i, j;
1242  size_t npickle;
1243  Symbol* fname = 0;
1244  Object* ob = nil;
1245  char* sarg[20]; // upto 20 argument may be strings
1246  int ns = 0; // number of args that are strings
1247  int narg = 0; // total number of args
1248  if (style == 2) { // object first
1249  s = upkstr(); // template name
1250  i = upkint(); // object index
1251  // printf("template |%s| index=%d\n", s, i);
1252  Symbol* sym = hoc_lookup(s);
1253  if (sym) {
1254  sym = hoc_which_template(sym);
1255  }
1256  if (!sym) {
1257  hoc_execerror(s, "is not a template");
1258  }
1259  hoc_Item *q, *ql;
1260  ql = sym->u.ctemplate->olist;
1261  ITERATE(q, ql) {
1262  ob = OBJ(q);
1263  if (ob->index == i) {
1264  break;
1265  }
1266  ob = nil;
1267  }
1268  if (!ob) {
1269  fprintf(stderr, "%s[%d] is not an Object in this process\n", s, i);
1270  hoc_execerror("ParallelContext execution error", 0);
1271  }
1272  delete[] s;
1273  s = upkstr();
1275  if (subworld) {
1276  hoc_execerror("with subworlds, this submit style not implemented", 0);
1277  }
1278  } else if (style == 3) { // Python callable
1279  s = upkpickle(&npickle);
1280  if (subworld) {
1281  int size = npickle;
1282  nrnmpi_int_broadcast(&size, 1, 0);
1283  nrnmpi_char_broadcast(s, size, 0);
1284  }
1285  } else {
1286  s = upkstr();
1287  if (subworld) {
1288  int size = strlen(s) + 1;
1289  // printf("%d exec hoc fun size = %d\n", nrnmpi_myid_world, size);
1290  nrnmpi_int_broadcast(&size, 1, 0);
1291  nrnmpi_char_broadcast(s, size, 0);
1292  }
1293  fname = hoc_lookup(s);
1294  }
1295  // printf("execute helper style %d fname=%s obj=%s\n", style, fname->name,
1296  // hoc_object_name(ob));
1297  if (style != 3 && !fname) {
1298  fprintf(stderr, "%s not a function in %s\n", s, hoc_object_name(ob));
1299  hoc_execerror("ParallelContext execution error", 0);
1300  }
1301  int argtypes = upkint(); // first is least signif
1302  if (subworld) {
1303  // printf("%d exec argtypes = %d\n", nrnmpi_myid_world, argtypes);
1304  nrnmpi_int_broadcast(&argtypes, 1, 0);
1305  }
1306  for (j = argtypes; (i = j % 5) != 0; j /= 5) {
1307  ++narg;
1308  if (i == 1) {
1309  double x = upkdouble();
1310  // printf("%d arg %d scalar %g\n", nrnmpi_myid_world, narg, x);
1311  if (subworld) {
1312  nrnmpi_dbl_broadcast(&x, 1, 0);
1313  }
1314  hoc_pushx(x);
1315  } else if (i == 2) {
1316  sarg[ns] = upkstr();
1317  // printf("arg %d string |%s|\n", narg, sarg[ns]);
1318  if (subworld) {
1319  int size = strlen(sarg[ns]) + 1;
1320  nrnmpi_int_broadcast(&size, 1, 0);
1321  nrnmpi_char_broadcast(sarg[ns], size, 0);
1322  }
1323  hoc_pushstr(sarg + ns);
1324  ns++;
1325  } else if (i == 3) {
1326  int n;
1327  n = upkint();
1328  if (subworld) {
1329  nrnmpi_int_broadcast(&n, 1, 0);
1330  }
1331  Vect* vec = new Vect(n);
1332  // printf("arg %d vector size=%d\n", narg, n);
1333  upkvec(n, vec->data());
1334  if (subworld) {
1335  nrnmpi_dbl_broadcast(vec->data(), n, 0);
1336  }
1337  hoc_pushobj(vec->temp_objvar());
1338  } else { // PythonObject
1339  size_t n;
1340  char* s = upkpickle(&n);
1341  int size = n;
1342  if (subworld) {
1343  nrnmpi_int_broadcast(&size, 1, 0);
1344  nrnmpi_char_broadcast(s, size, 0);
1345  }
1347  Object* po = nrnpy_pickle2po(s, n);
1348  delete[] s;
1350  }
1351  }
1352  if (style == 3) {
1354  if (pickle_ret_) {
1355  delete[] pickle_ret_;
1356  pickle_ret_ = 0;
1357  pickle_ret_size_ = 0;
1358  }
1359  if (exec) {
1360  rs = (*nrnpy_callpicklef)(s, npickle, narg, size);
1361  }
1362  hoc_ac_ = 0.;
1363  } else {
1364  // printf("%d exec hoc call %s narg=%d\n", nrnmpi_myid_world, fname->name, narg);
1365  if (exec) {
1367  } else {
1368  hoc_ac_ = 0.;
1369  }
1370  // printf("%d exec return from hoc call %s narg=%d\n", nrnmpi_myid_world, fname->name,
1371  // narg);
1372  }
1373  delete[] s;
1374  for (i = 0; i < ns; ++i) {
1375  delete[] sarg[i];
1376  }
1377 #endif
1378  } break;
1379  }
1380  return rs;
1381 }
1382 
1383 #include "subworld.cpp"
1384 
1385 void BBSImpl::return_args(int id) {
1386  // the message has been set up by the subclass
1387  // perhaps it would be better to do this directly
1388  // and avoid the meaningless create and delete.
1389  // but then they all would have to know this format
1390  int i;
1391  char* s;
1392  // printf("BBSImpl::return_args(%d):\n", id);
1393  i = upkint(); // userid
1394  int wid = upkint();
1395  int style = upkint();
1396  // printf("message userid=%d style=%d\n", i, style);
1397  switch (style) {
1398  case 0:
1399  s = upkstr(); // the statement
1400  // printf("statement |%s|\n", s);
1401  delete[] s;
1402  break;
1403  case 2: // obj first
1404  s = upkstr(); // template name
1405  i = upkint(); // instance index
1406  // printf("object %s[%d]\n", s, i);
1407  delete[] s;
1408  // fall through
1409  case 1:
1410  s = upkstr(); // fname
1411  i = upkint(); // arg manifest
1412  // printf("fname=|%s| manifest=%o\n", s, i);
1413  delete[] s;
1414  break;
1415  case 3:
1416  size_t n;
1417  s = upkpickle(&n); // pickled callable
1418  i = upkint(); // arg manifest
1419  delete[] s;
1420  break;
1421  }
1422  // now only args are left and ready to unpack.
1423 }
#define nil
Definition: enter-scope.h:36
static void nrnmpi_int_alltoallv(int *s, int *scnt, int *sdispl, int *r, int *rcnt, int *rdispl)
static void nrnmpi_dbl_alltoallv(double *s, int *scnt, int *sdispl, double *r, int *rcnt, int *rdispl)
static void nrnmpi_barrier()
Section * chk_access(void)
Definition: cabcode.cpp:444
short type
Definition: cabvars.h:9
Definition: bbs.h:8
bool look_take(const char *)
Definition: bbs.cpp:453
Object ** gid2cell(int)
Definition: netpar.cpp:1169
void spike_record(int, IvocVect *, IvocVect *)
Definition: netpar.cpp:1115
Object ** gid_connect(int)
Definition: netpar.cpp:1195
void master_works(int flag)
Definition: bbs.cpp:353
void set_gid2node(int, int)
Definition: netpar.cpp:952
void pkstr(const char *)
Definition: bbs.cpp:231
Object ** pyret()
Definition: ocbbs.cpp:402
void upkvec(int n, double *px)
Definition: bbs.cpp:180
void netpar_solve(double)
Definition: netpar.cpp:1255
void pkdouble(double)
Definition: bbs.cpp:217
void pkint(int)
Definition: bbs.cpp:210
void pkvec(int n, double *px)
Definition: bbs.cpp:224
void done()
Definition: bbs.cpp:481
int upkint()
Definition: bbs.cpp:164
bool working(int &id, double &x, int &userid)
Definition: bbs.cpp:349
bool is_master()
Definition: bbs.cpp:113
Object ** gid2obj(int)
Definition: netpar.cpp:1165
void pkbegin()
Definition: bbs.cpp:203
IvocVect * netpar_max_histogram(IvocVect *)
Definition: netpar.cpp:1440
int gid_exists(int)
Definition: netpar.cpp:1059
void post(const char *)
Definition: bbs.cpp:446
void worker()
Definition: bbs.cpp:421
bool look(const char *)
Definition: bbs.cpp:461
void cell()
Definition: netpar.cpp:1076
void netpar_spanning_statistics(int *, int *, int *, int *)
Definition: netpar.cpp:1430
void pkpickle(const char *, size_t size)
Definition: bbs.cpp:238
int submit(int userid)
Definition: bbs.cpp:322
BBSImpl * impl_
Definition: bbs.h:74
void outputcell(int)
Definition: netpar.cpp:1106
char * upkstr()
Definition: bbs.cpp:187
void take(const char *)
Definition: bbs.cpp:469
double netpar_mindelay(double maxdelay)
Definition: netpar.cpp:1422
double threshold()
Definition: netpar.cpp:1063
char * upkpickle(size_t *size)
Definition: bbs.cpp:195
double upkdouble()
Definition: bbs.cpp:172
void context()
Definition: bbs.cpp:340
virtual int upkint()=0
virtual void return_args(int userid)
Definition: ocbbs.cpp:1385
char * execute_helper(size_t *, int id, bool exec=true)
Definition: ocbbs.cpp:1215
virtual void upkvec(int, double *)=0
virtual char * upkstr()=0
char * pickle_ret_
Definition: bbsimpl.h:58
virtual double upkdouble()=0
size_t pickle_ret_size_
Definition: bbsimpl.h:59
virtual char * upkpickle(size_t *)=0
Object * obj_
Definition: ivocvect.h:94
Definition: ocbbs.cpp:79
OcBBS(int nhost_request)
Definition: ocbbs.cpp:90
int userid_
Definition: ocbbs.cpp:86
int next_local_
Definition: ocbbs.cpp:87
virtual ~OcBBS()
Definition: ocbbs.cpp:95
double retval_
Definition: ocbbs.cpp:85
virtual void ref() const
Definition: resource.cpp:47
virtual void unref() const
Definition: resource.cpp:52
Symbol * hoc_table_lookup(const char *, Symlist *)
Definition: symbol.cpp:61
sprintf(buf, " if (secondorder) {\n" " int _i;\n" " for (_i = 0; _i < %d; ++_i) {\n" " _p[_slist%d[_i]] += dt*_p[_dlist%d[_i]];\n" " }}\n", numeqn, listnum, listnum)
double chkarg(int, double low, double high)
Definition: code2.cpp:638
#define c
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:754
int hoc_is_object_arg(int narg)
Definition: code.cpp:756
void hoc_pushstr(char **d)
Definition: code.cpp:680
int vector_arg_px(int, double **)
Definition: ivocvect.cpp:413
void hoc_pushobj(Object **d)
Definition: code.cpp:663
int hoc_is_str_arg(int narg)
Definition: code.cpp:752
void hoc_assign_str(char **cpp, const char *buf)
Definition: code.cpp:2350
double hoc_call_objfunc(Symbol *s, int narg, Object *ob)
Definition: hoc_oop.cpp:389
int hoc_is_double_arg(int narg)
Definition: code.cpp:744
Vect * vector_arg(int i)
Definition: ivocvect.cpp:397
double hoc_ac_
Definition: hoc_init.cpp:397
void hoc_obj_ref(Object *obj)
Definition: hoc_oop.cpp:1810
char * hoc_object_name(Object *ob)
Definition: hoc_oop.cpp:72
int is_vector_arg(int i)
Definition: ivocvect.cpp:405
Symbol * hoc_lookup(const char *)
int hoc_is_pdouble_arg(int narg)
Definition: code.cpp:748
double * hoc_pgetarg(int narg)
Definition: code.cpp:1623
void bbs_done()
Definition: ocbbs.cpp:103
void hoc_obj_unref(Object *obj)
Definition: hoc_oop.cpp:1828
int nrn_mpiabort_on_error_
Definition: hoc.cpp:77
char ** hoc_pgargstr(int narg)
Definition: code.cpp:1599
#define assert(ex)
Definition: hocassrt.h:32
#define getarg
Definition: hocdec.h:15
#define gargstr
Definition: hocdec.h:14
#define OBJ(q)
Definition: hoclist.h:67
Object ** hoc_objgetarg(int)
Definition: code.cpp:1587
int hoc_obj_run(const char *, Object *)
Definition: hoc_oop.cpp:322
int ifarg(int)
Definition: code.cpp:1581
void hoc_pushx(double)
int vector_capacity(Vect *v)
Definition: ivocvect.cpp:319
void vector_resize(Vect *v, int n)
Definition: ivocvect.cpp:322
double * vector_vec(Vect *v)
Definition: ivocvect.cpp:328
static int narg()
Definition: ivocvect.cpp:150
#define Vect
Definition: ivocvect.h:14
Object ** hoc_temp_objptr(Object *)
Definition: code.cpp:216
#define v
Definition: md1redef.h:4
#define sec
Definition: md1redef.h:13
#define id
Definition: md1redef.h:33
#define i
Definition: md1redef.h:12
#define ITERATE(itm, lst)
Definition: model.h:25
NrnThread * nrn_threads
Definition: multicore.cpp:47
static double nrnmpi_splitcell_wait_
Definition: multisplit.cpp:43
static double nrnmpi_wtime()
Definition: multisplit.cpp:55
#define fprintf
Definition: mwprefix.h:30
static void phase_begin(const char *name)
static void phase_end(const char *name)
static List * info
static char suffix[256]
Definition: nocpout.cpp:149
void nrn_seg_or_x_arg(int iarg, Section **psec, double *px)
Definition: point.cpp:185
int const size_t const size_t n
Definition: nrngsl.h:11
size_t q
if(status)
size_t j
int nrnmpi_myid
int nrnmpi_numprocs_world
int nrnmpi_numprocs
int nrnmpi_myid_world
int nrnmpi_numprocs_bbs
int nrnmpi_myid_bbs
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
static char * sarg
Definition: nrnversion.cpp:17
static const char ** pname(void *v)
Definition: ocpointer.cpp:70
static double spike_record(void *v)
Definition: ocbbs.cpp:663
static double spike_stat(void *v)
Definition: ocbbs.cpp:698
int nrncore_run(const char *)
int nrn_set_timeout(int timeout)
Definition: netpar.cpp:1248
static double step_time(void *v)
Definition: ocbbs.cpp:528
static double partition(void *)
Definition: ocbbs.cpp:929
char *(* nrnpy_po2pickle)(Object *, size_t *)
Definition: ocbbs.cpp:35
size_t nrnbbcore_register_mapping()
For BBP use case, we want to write section-segment mapping to gid_3.dat file.
static Object ** upkpyobj(void *v)
Definition: ocbbs.cpp:388
static double nhost(void *v)
Definition: ocbbs.cpp:232
static double nthrd(void *)
Definition: ocbbs.cpp:917
static Object ** upkvec(void *v)
Definition: ocbbs.cpp:374
void ParallelContext_reg()
Definition: ocbbs.cpp:1211
Symbol * hoc_which_template(Symbol *)
Definition: hoc_oop.cpp:1468
static double userid(void *v)
Definition: ocbbs.cpp:227
static double nrncorerun(void *)
Definition: ocbbs.cpp:1013
void nrn_prcellstate(int gid, const char *suffix)
static double pctime(void *v)
Definition: ocbbs.cpp:481
static double thread_dt(void *)
Definition: ocbbs.cpp:992
static bool posting_
Definition: ocbbs.cpp:97
static double prcellstate(void *v)
Definition: ocbbs.cpp:518
static void unpack_help(int, OcBBS *)
Definition: ocbbs.cpp:333
static double nhost_world(void *v)
Definition: ocbbs.cpp:242
static double look_take(void *v)
Definition: ocbbs.cpp:471
double nrnmpi_step_wait_
Definition: ocbbs.cpp:40
static double working(void *v)
Definition: ocbbs.cpp:210
static double send_time(void *v)
Definition: ocbbs.cpp:550
static double alltoall(void *)
Definition: ocbbs.cpp:819
static double wait_time(void *v)
Definition: ocbbs.cpp:523
int nrn_allow_busywait(int)
Definition: multicore.cpp:1310
int nrncore_is_enabled()
void nrn_thread_partition(int, Object *)
Definition: multicore.cpp:1195
static double outputcell(void *v)
Definition: ocbbs.cpp:656
static double master_works(void *v)
Definition: ocbbs.cpp:276
static double done(void *v)
Definition: ocbbs.cpp:282
static Object ** gid2cell(void *v)
Definition: ocbbs.cpp:1029
int nrn_nthread
Definition: multicore.cpp:46
static double event_time(void *v)
Definition: ocbbs.cpp:558
static Member_ret_str_func retstr_members[]
Definition: ocbbs.cpp:1187
static double thread_stat(void *)
Definition: ocbbs.cpp:949
static Member_func members[]
Definition: ocbbs.cpp:1039
int nrncore_is_file_mode()
double * nrn_mech_wtime_
Definition: treeset.cpp:29
double nrn_bgp_receive_time(int)
Definition: bgpdma.cpp:354
static void * cons(Object *)
Definition: ocbbs.cpp:1195
static double set_gid2node(void *v)
Definition: ocbbs.cpp:566
static void pack_help(int, OcBBS *)
Definition: ocbbs.cpp:288
static double nrncorewrite_argvec(void *)
Definition: ocbbs.cpp:998
int nrncore_psolve(double tstop, int file_mode)
static double rank_bbs(void *v)
Definition: ocbbs.cpp:257
static void destruct(void *v)
Definition: ocbbs.cpp:1206
static double retval(void *v)
Definition: ocbbs.cpp:222
static Object ** py_gather(void *)
Definition: ocbbs.cpp:432
static double context(void *v)
Definition: ocbbs.cpp:202
static Object ** py_alltoall_type(int type)
Definition: ocbbs.cpp:412
static double spcompress(void *v)
Definition: ocbbs.cpp:589
static void nrnmpi_dbl_broadcast(double *, int, int)
Definition: ocbbs.cpp:62
static double nrn_thread_t(void *)
Definition: ocbbs.cpp:986
static double thread_how_many_proc(void *)
Definition: ocbbs.cpp:959
static double thread_ctime(void *)
Definition: ocbbs.cpp:971
static double splitcell_connect(void *v)
Definition: ocbbs.cpp:605
static double gid_clear(void *v)
Definition: ocbbs.cpp:647
static double source_var(void *)
Definition: ocbbs.cpp:729
static void nrnmpi_char_broadcast(char *, int, int)
Definition: ocbbs.cpp:61
static double setup_transfer(void *)
Definition: ocbbs.cpp:746
static char * key_help()
Definition: ocbbs.cpp:444
static Object ** py_broadcast(void *)
Definition: ocbbs.cpp:436
static double allgather(void *)
Definition: ocbbs.cpp:800
static double threshold(void *v)
Definition: ocbbs.cpp:584
static double nhost_bbs(void *v)
Definition: ocbbs.cpp:252
static double integ_time(void *v)
Definition: ocbbs.cpp:562
char *(* nrnpy_callpicklef)(char *, size_t, int, size_t *)
Definition: ocbbs.cpp:37
static double sec_in_thread(void *)
Definition: ocbbs.cpp:965
static double thread_busywait(void *)
Definition: ocbbs.cpp:954
double t
Definition: cvodeobj.cpp:59
static double take(void *v)
Definition: ocbbs.cpp:454
static double step_wait(void *v)
Definition: ocbbs.cpp:536
static Object ** pyret(void *v)
Definition: ocbbs.cpp:398
static double subworlds(void *v)
Definition: ocbbs.cpp:262
static double vtransfer_time(void *v)
Definition: ocbbs.cpp:485
static double pack(void *v)
Definition: ocbbs.cpp:313
size_t nrncore_write()
double nrnmpi_rtcomp_time_
Definition: ocbbs.cpp:33
int nrn_how_many_processors()
Definition: multicore.cpp:1349
static double cell(void *v)
Definition: ocbbs.cpp:578
static double mech_time(void *v)
Definition: ocbbs.cpp:501
static void nrnmpi_int_broadcast(int *, int, int)
Definition: ocbbs.cpp:60
void nrn_thread_stat()
Definition: multicore.cpp:473
static Object ** py_alltoall(void *)
Definition: ocbbs.cpp:424
Object *(* nrnpympi_alltoall_type)(int, int)
Definition: ocbbs.cpp:38
static double set_timeout(void *v)
Definition: ocbbs.cpp:630
void nrnmpi_gid_clear(int)
Definition: netpar.cpp:994
static double multisplit(void *v)
Definition: ocbbs.cpp:612
void nrn_threads_create(int, int)
Definition: multicore.cpp:504
#define MD
Definition: ocbbs.cpp:19
int nrnmpi_spike_compress(int nspike, bool gid_compress, int xchng_meth)
Definition: netpar.cpp:1494
int hoc_return_type_code
Definition: code.cpp:42
static double nrncorewrite_argappend(void *)
Definition: ocbbs.cpp:1005
static double post(void *v)
Definition: ocbbs.cpp:319
static double rank_world(void *v)
Definition: ocbbs.cpp:247
static double gid_exists(void *v)
Definition: ocbbs.cpp:572
static double set_maxstep(void *v)
Definition: ocbbs.cpp:693
static Member_ret_obj_func retobj_members[]
Definition: ocbbs.cpp:1189
static double submit(void *v)
Definition: ocbbs.cpp:194
static double worker(void *v)
Definition: ocbbs.cpp:270
static Object ** gid_connect(void *v)
Definition: ocbbs.cpp:1034
static Object ** py_allgather(void *)
Definition: ocbbs.cpp:428
static double nrn_rank(void *v)
Definition: ocbbs.cpp:237
static double target_var(void *)
Definition: ocbbs.cpp:737
static double broadcast(void *)
Definition: ocbbs.cpp:873
void nrnmpi_target_var()
static Object ** gid2obj(void *v)
Definition: ocbbs.cpp:1024
void nrnmpi_setup_transfer()
Definition: partrans.cpp:693
int nrnmpi_multisplit(Section *, double x, int sid, int backbonestyle)
Definition: multisplit.cpp:309
static double barrier(void *)
Definition: ocbbs.cpp:751
bool nrn_trajectory_request_per_time_step_
Definition: netcvode.cpp:140
static Object ** py_scatter(void *)
Definition: ocbbs.cpp:440
static int submit_help(OcBBS *)
Definition: ocbbs.cpp:120
static double unpack(void *v)
Definition: ocbbs.cpp:354
Object *(* nrnpy_pickle2po)(char *, size_t)
Definition: ocbbs.cpp:36
static const char ** upkstr(void *v)
Definition: ocbbs.cpp:365
int nrnmpi_splitcell_connect(int that_host)
Definition: splitcell.cpp:49
static double upkscalar(void *v)
Definition: ocbbs.cpp:360
static double maxhist(void *v)
Definition: ocbbs.cpp:716
void nrnmpi_source_var()
static double look(void *v)
Definition: ocbbs.cpp:461
static double psolve(void *v)
Definition: ocbbs.cpp:677
static double allreduce(void *)
Definition: ocbbs.cpp:765
static double set_mpiabort_on_error(void *)
Definition: ocbbs.cpp:639
#define e
Definition: passive0.cpp:22
#define arg
Definition: redef.h:28
#define ret
Definition: redef.h:123
check_obj_type(o, "SectionList")
#define cnt
Definition: spt2queue.cpp:19
#define key
Definition: spt2queue.cpp:20
#define NULL
Definition: sptree.h:16
double _dt
Definition: multicore.h:60
double _ctime
Definition: multicore.h:86
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: model.h:57
union Symbol::@18 u
HocStruct cTemplate * ctemplate
Definition: hocdec.h:152
Symlist * symtable
Definition: hocdec.h:197
hoc_List * olist
Definition: hocdec.h:204
struct hoc_Item * next
Definition: hoclist.h:50
static const char * fname(const char *name)
Definition: nrnbbs.cpp:113