NEURON
nrnmusic.cpp
Go to the documentation of this file.
1 #define NO_PYTHON_H 1
2 #include <../neuronmusic/nrnmusic.h>
3 
4 extern int nrnmusic;
5 extern MPI_Comm nrnmusic_comm;
6 
7 void nrnmusic_init(int*, char***);
8 void nrnmusic_terminate();
9 
10 void nrnmusic_injectlist(void* vp, double tt);
11 void nrnmusic_inject(void* port, int gindex, double tt);
12 void nrnmusic_spikehandle(void* vport, double tt, int gindex);
13 
14 extern Object* nrnpy_po2ho(PyObject*);
15 extern PyObject* nrnpy_ho2po(Object*);
16 extern Object* hoc_new_object(Symbol*, void*);
17 
18 MUSIC::Setup* nrnmusic_setup;
19 MUSIC::Runtime* nrnmusic_runtime;
20 
21 class NrnMusicEventHandler : public MUSIC::EventHandlerLocalIndex {
22  public:
23  void operator() (double t, MUSIC::LocalIndex id);
26 };
27 
29 public:
30  MusicPortPair(void* port, int gindex, void* p);
31  virtual ~MusicPortPair();
32  void clear(); // avoid recursion on delete by first calling clear
33  void* port_;
34  int gindex_;
36 };
37 MusicPortPair::MusicPortPair(void* port, int gindex, void* vp) {
38  port_ = port;
39  gindex_ = gindex;
40  next_ = (MusicPortPair*)vp;
41 }
43  if (next_) { delete next_; }
44 }
46  MusicPortPair* i, *j;
47  for (i=next_; i; i = j) {
48  j = i->next_;
49  i->next_ = 0;
50  delete i;
51  }
52 }
53 
55 public:
57  virtual ~NetParMusicEvent();
58  virtual void send(double, NetCvode*, NrnThread*);
59  virtual void deliver(double, NetCvode*, NrnThread*);
60  virtual int type() { return 100; }
61 };
63 
64 #include <OS/table.h>
65 declareTable(PortTable, void*, int) // used as set
66 implementTable(PortTable, void*, int)
67 static PortTable* music_input_ports;
68 static PortTable* music_output_ports;
69 
70 declareTable(Gi2PreSynTable, int, PreSyn*)
71 implementTable(Gi2PreSynTable, int, PreSyn*)
72 
74 }
76 }
77 void NetParMusicEvent::send(double t, NetCvode* nc, NrnThread* nt) {
78  nc->event(t + usable_mindelay_, this, nt);
79 }
81  nrnmusic_runtime->tick();
82  send(t, nc, nt);
83 }
84 
86  if (music_input_ports) { return; }
87  music_input_ports = new PortTable(64);
88  music_output_ports = new PortTable(64);
89 }
90 
91 void nrnmusic_injectlist(void* vp, double tt) {
92  MusicPortPair* mpp;
93  for (mpp = (MusicPortPair*)vp; mpp; mpp = mpp->next_) {
94  nrnmusic_inject(mpp->port_, mpp->gindex_, tt);
95  }
96 }
97 
98 void nrnmusic_inject(void* vport, int gi, double tt) {
99  //printf("nrnmusic_inject %p %d %g\n", vport, gi, tt);
100  ((MUSIC::EventOutputPort*)vport)->
101  insertEvent(tt / 1000.0, // unit conversion ms -> s
102  (MUSIC::GlobalIndex)gi);
103 }
104 
106  table = new PreSyn*[cnt];
107  int j = 0;
108  for (TableIterator(Gi2PreSynTable) i(*port->gi_table); i.more(); i.next()) {
109  PreSyn* ps = i.cur_value();
110  table[j] = ps;
111  ++j;
112  }
113 }
114 
115 void NrnMusicEventHandler::operator () (double t, MUSIC::LocalIndex id) {
116  PreSyn* ps = table[id];
117  ps->send(1000.0 * t, net_cvode_instance, nrn_threads);
118  //printf("event handler t=%g id=%d ps=%p\n", t, int(id), ps);
119 }
120 
122  return new NRNMUSIC::EventOutputPort (nrnmusic_setup, id);
123 }
124 
126  // analogous to pc.cell
127  // except pc.cell(gid, nc) has already been called and this
128  // will add this to the PreSyn.music_out_ list.
130  auto iter = gid2out_.find(gid);
131  if (iter == gid2out_.end()) {
132  return;
133  }
134  PreSyn* ps = iter->second;
135  ps->music_port_ = new MusicPortPair((void*)this, gi, ps->music_port_);
136 
137  // to create an IndexList for a later map, need to
138  // save the indices used for each port
139  int i = 0;
140  if (!music_output_ports->find(i, (void*)this)) {
141  music_output_ports->insert((void*)this, i);
142  gi_table = new Gi2PreSynTable(1024);
143  }
144  PreSyn* ps2;
145  nrn_assert(!gi_table->find(ps2, gi));
146 //printf("gid2index insert %p %d\n", this, gi);
147  gi_table->insert(gi, ps);
148 }
149 
150 NRNMUSIC::EventInputPort::EventInputPort(MUSIC::Setup* s, std::string id)
151  : MUSIC::Port (s, id), MUSIC::EventInputPort(s, id) {
152  gi_table = new Gi2PreSynTable(1024);
153 }
154 
156  return new NRNMUSIC::EventInputPort (nrnmusic_setup, id);
157 }
158 
159 PyObject* NRNMUSIC::EventInputPort::index2target(int gi, PyObject* ptarget) {
160  // analogous to pc.gid_connect
161  Object* target = nrnpy_po2ho(ptarget);
162  if (!is_point_process(target)) {
163  hoc_execerror("target arg must be a Point_process", 0);
164  }
166  PreSyn* ps;
167  int i = 0;
168  if (!music_input_ports->find(i, (void*)this)) {
169  music_input_ports->insert((void*)this, i);
170  }
171  //nrn_assert (!gi_table->find(ps, gi));
172  if (!gi_table->find(ps, gi)) {
173  ps = new PreSyn(NULL, NULL, NULL);
175  gi_table->insert(gi, ps);
176  }
177  ps->gid_ = -2;
178  ps->output_index_ = -2;
179 
180  NetCon* nc = new NetCon(ps, target);
182  nc->obj_ = o;
183  PyObject* po = nrnpy_ho2po(o);
184 //printf("index2target %d %s\n", gi, hoc_object_name(target));
185  return po;
186 }
187 
188 void nrnmusic_init(int* pargc, char*** pargv) {
189  int i;
190  int& argc = *pargc;
191  char**& argv = *pargv;
192  if (strlen(argv[0]) >= 5 &&
193  strcmp(argv[0] + strlen(argv[0]) - 5, "music") == 0) {
194  nrnmusic = 1;
195  }
196  for (i=0; i < argc; ++i) {
197  if (strcmp(argv[i], "-music") == 0) {
198  nrnmusic = 1;
199  }
200  }
201  if (getenv ("_MUSIC_CONFIG_"))
202  nrnmusic = 1; // temporary kludge
203  if (nrnmusic) {
204  nrnmusic_setup = new MUSIC::Setup(argc, argv);
205  nrnmusic_comm = nrnmusic_setup->communicator();
206  }
207 }
208 
210  if (!nrnmusic_runtime) {
211  nrnmusic_runtime = new MUSIC::Runtime(nrnmusic_setup, 1);
212  }
213  nrnmusic_runtime->finalize ();
214  delete nrnmusic_runtime;
215 }
216 
217 // Called from nrn_spike_exchange_init so usable_mindelay is ready to use
218 // For now, can only be called once.
219 static void nrnmusic_runtime_phase() {
220  static int called = 0;
221  assert(!called);
222  called = 1;
223 
224  // call map on all the input ports
225  for (TableIterator(PortTable) i(*music_input_ports); i.more(); i.next()) {
228  Gi2PreSynTable* pst = eip->gi_table;
229  std::vector<MUSIC::GlobalIndex> gindices;
230  //iterate over pst and create indices
231  int cnt = 0;
232  for (TableIterator(Gi2PreSynTable) j(*pst); j.more(); j.next()) {
233  int gi = j.cur_key();
234 //printf("input port eip=%p gi=%d\n", eip, gi);
235  gindices.push_back (gi);
236  ++cnt;
237  }
238  eh->filltable(eip, cnt);
239  MUSIC::PermutationIndex indices (&gindices.front (),
240  gindices.size ());
241  eip->map(&indices, eh, usable_mindelay_ / 1000.0);
242  delete eip->gi_table;
243  }
244  delete music_input_ports;
245 
246  // call map on all the output ports
247  for (TableIterator(PortTable) i(*music_output_ports); i.more(); i.next()) {
249  Gi2PreSynTable* pst = eop->gi_table;
250  std::vector<MUSIC::GlobalIndex> gindices;
251  //iterate over pst and create indices
252  for (TableIterator(Gi2PreSynTable) j(*pst); j.more(); j.next()) {
253  int gi = j.cur_key();
254 //printf("output port eop=%p gi = %d\n", eop, gi);
255  gindices.push_back (gi);
256  }
257  MUSIC::PermutationIndex indices (&gindices.front (),
258  gindices.size ());
259  eop->map(&indices, MUSIC::Index::GLOBAL);
260  delete eop->gi_table;
261  }
262  delete music_output_ports;
263 
264  //switch to the runtime phase
265  //printf("usable_mindelay = %g\n", usable_mindelay_);
266  nrnmusic_runtime = new MUSIC::Runtime(nrnmusic_setup,
267  usable_mindelay_ / 1000.0);
268  npme = new NetParMusicEvent();
270 }
o
Definition: seclist.cpp:180
void filltable(NRNMUSIC::EventInputPort *, int)
Definition: nrnmusic.cpp:105
#define nrn_assert(ex)
Definition: nrnassrt.h:35
#define assert(ex)
Definition: hocassrt.h:26
TQItem * event(double tdeliver, DiscreteEvent *, NrnThread *)
Definition: netcvode.cpp:2623
static Gid2PreSyn gid2out_
Definition: netpar.cpp:33
static NetParMusicEvent * npme
Definition: nrnmusic.cpp:62
Definition: netcon.h:232
void operator()(double t, MUSIC::LocalIndex id)
Definition: nrnmusic.cpp:115
PyObject * nrnpy_ho2po(Object *)
Definition: nrnpy_hoc.cpp:503
void static int PortTable * music_input_ports
Definition: nrnmusic.cpp:66
MusicPortPair(void *port, int gindex, void *p)
Definition: nrnmusic.cpp:37
virtual void send(double sendtime, NetCvode *, NrnThread *)
Definition: netcvode.cpp:3165
virtual void deliver(double, NetCvode *, NrnThread *)
Definition: nrnmusic.cpp:80
size_t p
Represent main neuron object computed by single thread.
Definition: multicore.h:58
int output_index_
Definition: netcon.h:276
Object * obj_
Definition: netcon.h:108
Gi2PreSynTable * gi_table
Definition: nrnmusic.h:25
void psl_append(PreSyn *)
Definition: netcvode.cpp:4592
MusicPortPair * next_
Definition: nrnmusic.cpp:35
EventOutputPort * publishEventOutput(std::string identifier)
Definition: nrnmusic.cpp:121
Object * hoc_new_object(Symbol *, void *)
Definition: hoc_oop.cpp:465
virtual ~MusicPortPair()
Definition: nrnmusic.cpp:42
#define implementTable(Table, Key, Value)
Definition: table.h:113
Object * nrnpy_po2ho(PyObject *)
Definition: nrnpy_hoc.cpp:524
void nrnmusic_init(int *, char ***)
Definition: nrnmusic.cpp:188
void nrnmusic_injectlist(void *vp, double tt)
Definition: nrnmusic.cpp:91
MUSIC::Setup * nrnmusic_setup
Definition: nrnmusic.cpp:18
_CONST char * s
Definition: system.cpp:74
NrnThread * nrn_threads
Definition: multicore.cpp:45
virtual ~NetParMusicEvent()
Definition: nrnmusic.cpp:75
void alloc_music_space()
Definition: nrnmusic.cpp:85
static double usable_mindelay_
Definition: netpar.cpp:207
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:741
int nrnmusic
PyObject * index2target(int gi, PyObject *target)
Definition: nrnmusic.cpp:159
#define cnt
Definition: spt2queue.cpp:19
int is_point_process(Object *)
Definition: point.cpp:405
char * getenv(const char *s)
Definition: macprt.cpp:67
size_t j
Definition: model.h:57
Definition: netcon.h:82
int gid_
Definition: netcon.h:277
virtual void send(double, NetCvode *, NrnThread *)
Definition: nrnmusic.cpp:77
void send(const char *url)
Definition: hel2mos.cpp:212
#define TableIterator(Table)
Definition: table.h:38
MUSIC::Runtime * nrnmusic_runtime
Definition: nrnmusic.cpp:19
void * port_
Definition: nrnmusic.cpp:33
void clear()
Definition: nrnmusic.cpp:45
void gid2index(int gid, int gi)
Definition: nrnmusic.cpp:125
void nrnmusic_inject(void *port, int gindex, double tt)
Definition: nrnmusic.cpp:98
virtual int type()
Definition: nrnmusic.cpp:60
Definition: hocdec.h:226
static void nrnmusic_runtime_phase()
Definition: nrnmusic.cpp:219
EventInputPort * publishEventInput(std::string identifier)
Definition: nrnmusic.cpp:155
declareTable(PortTable, void *, int) implementTable(PortTable
#define i
Definition: md1redef.h:12
#define id
Definition: md1redef.h:33
void nrnmusic_spikehandle(void *vport, double tt, int gindex)
void nrnmusic_terminate()
Definition: nrnmusic.cpp:209
static Symbol * netcon_sym_
Definition: netpar.cpp:32
EventInputPort(MUSIC::Setup *s, std::string id)
Definition: nrnmusic.cpp:150
static int argc
Definition: inithoc.cpp:53
Gi2PreSynTable * gi_table
Definition: nrnmusic.h:35
double t
Definition: init.cpp:123
static PortTable * music_output_ports
Definition: nrnmusic.cpp:68
return NULL
Definition: cabcode.cpp:461
NetCvode * net_cvode_instance
Definition: cvodestb.cpp:27
MPI_Comm nrnmusic_comm
static char ** argv
Definition: inithoc.cpp:54
Definition: units.cpp:95