NEURON
subworld.cpp
Go to the documentation of this file.
1 // included by ocbbs.cpp
2 
4  // execute the same thing that execute_worker is executing. This
5  // is done for all the nrnmpi_myid_bbs == -1 workers associated with
6  // the specific nrnmpi_myid == 0 with nrnmpi_myid_bbs >= 0.
7  // All the nrnmpi/mpispike.cpp functions can be used since the
8  // proper communicators for a subworld are used by those functions.
9  // The broadcast functions are particularly useful and those are
10  // how execute_worker passes messages into here.
11 
12  // printf("%d enter subworld_worker_execute\n", nrnmpi_myid_world);
13  int info[2];
14  // wait for something to do
16  // info[0] = -1 means it was from a pc.context. Also -2 means
17  // DONE.
18  // printf("%d subworld_worker_execute info %d %d\n", nrnmpi_myid_world, info[0], info[1]);
19  int id = info[0];
20  if (id == -2) { // DONE, so quit.
21  done();
22  }
23  hoc_ac_ = double(id);
24  int style = info[1];
25  if (style == 0) { // hoc statement form
26  int size;
27  nrnmpi_int_broadcast(&size, 1, 0); // includes terminator
28  char* s = new char[size];
29  nrnmpi_char_broadcast(s, size, 0);
30  hoc_obj_run(s, nil);
31  delete[] s;
32  // printf("%d leave subworld_worker_execute\n", nrnmpi_myid_world);
33  return;
34  }
35  int i, j;
36  int npickle;
37  char* s;
38  Symbol* fname = 0;
39  Object* ob = nil;
40  char* sarg[20]; // up to 20 arguments may be strings
41  int ns = 0; // number of args that are strings
42  int narg = 0; // total number of args
43 
44  if (style == 3) { // python callable
45  nrnmpi_int_broadcast(&npickle, 1, 0);
46  s = new char[npickle];
47  nrnmpi_char_broadcast(s, npickle, 0);
48  } else if (style == 1) { // hoc function
49  int size;
50  nrnmpi_int_broadcast(&size, 1, 0); // includes terminator
51  // printf("%d subworld hoc function string size = %d\n", nrnmpi_myid_world, size);
52  s = new char[size];
53  nrnmpi_char_broadcast(s, size, 0);
54  fname = hoc_lookup(s);
55  if (!fname) {
56  return;
57  } // error raised by sender
58  } else {
59  return; // no others implemented, error raised by sender
60  }
61 
62  // now get the args
63  int argtypes;
64  nrnmpi_int_broadcast(&argtypes, 1, 0);
65  // printf("%d subworld argtypes = %d\n", nrnmpi_myid_world, argtypes);
66  for (j = argtypes; (i = j % 5) != 0; j /= 5) {
67  ++narg;
68  if (i == 1) { // double
69  double x;
70  nrnmpi_dbl_broadcast(&x, 1, 0);
71  // printf("%d subworld scalar = %g\n", nrnmpi_myid_world, x);
72  hoc_pushx(x);
73  } else if (i == 2) { // string
74  int size;
75  nrnmpi_int_broadcast(&size, 1, 0);
76  sarg[ns] = new char[size];
77  nrnmpi_char_broadcast(sarg[ns], size, 0);
78  hoc_pushstr(sarg + ns);
79  ns++;
80  } else if (i == 3) { // Vector
81  int n;
82  nrnmpi_int_broadcast(&n, 1, 0);
83  Vect* vec = new Vect(n);
84  nrnmpi_dbl_broadcast(vec->data(), n, 0);
85  hoc_pushobj(vec->temp_objvar());
86  } else { // PythonObject
87  int n;
88  nrnmpi_int_broadcast(&n, 1, 0);
89  char* s;
90  s = new char[n];
91  nrnmpi_char_broadcast(s, n, 0);
92  Object* po = nrnpy_pickle2po(s, size_t(n));
93  delete[] s;
95  }
96  }
97 
98  if (style == 3) {
99  size_t size;
100  char* rs = (*nrnpy_callpicklef)(s, size_t(npickle), narg, &size);
101  assert(rs);
102  delete[] rs;
103  } else {
104  // printf("%d subworld hoc call %s narg=%d\n", nrnmpi_myid_world, fname->name, narg);
106  // printf("%d subworld return from hoc call %s\n", nrnmpi_myid_world, fname->name);
107  }
108  delete[] s;
109  for (i = 0; i < ns; ++i) {
110  delete[] sarg[i];
111  }
112 }
#define nil
Definition: enter-scope.h:36
void subworld_worker_execute()
Definition: subworld.cpp:3
virtual void done()
Definition: bbs.cpp:487
void hoc_pushstr(char **d)
Definition: code.cpp:680
void hoc_pushobj(Object **d)
Definition: code.cpp:663
double hoc_call_objfunc(Symbol *s, int narg, Object *ob)
Definition: hoc_oop.cpp:389
double hoc_ac_
Definition: hoc_init.cpp:397
Symbol * hoc_lookup(const char *)
#define assert(ex)
Definition: hocassrt.h:32
int hoc_obj_run(const char *, Object *)
Definition: hoc_oop.cpp:322
void hoc_pushx(double)
static int narg()
Definition: ivocvect.cpp:150
#define Vect
Definition: ivocvect.h:14
Object ** hoc_temp_objptr(Object *)
Definition: code.cpp:216
#define i
Definition: md1redef.h:12
static List * info
int const size_t const size_t n
Definition: nrngsl.h:11
size_t j
Object *(* nrnpy_pickle2po)(char *, size_t size)
Definition: ocbbs.cpp:36
static char * sarg
Definition: nrnversion.cpp:17
static void nrnmpi_dbl_broadcast(double *, int, int)
Definition: ocbbs.cpp:62
static void nrnmpi_char_broadcast(char *, int, int)
Definition: ocbbs.cpp:61
static void nrnmpi_int_broadcast(int *, int, int)
Definition: ocbbs.cpp:60
Definition: hocdec.h:227
Definition: model.h:57
static const char * fname(const char *name)
Definition: nrnbbs.cpp:113