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