1 #include <../../nrnconf.h>
4 #define USE_MIN_DELAY 1
24 #include "shared/sundialsmath.h"
43 #include <unordered_map>
44 #include <unordered_set>
48 #define lvardtloop(i, j) \
49 for (i = 0; i < nrn_nthread; ++i) \
50 for (j = 0; j < p[i].nlcv_; ++j)
53 #define PP2NT(pp) ((NrnThread*) ((pp)->_vnt))
54 #define PP2t(pp) (PP2NT(pp)->_t)
59 #define POINT_RECEIVE(type, tar, w, f) (*pnt_receive[type])(tar, w, f)
77 extern void nrn_cvfun(
double t,
double* y,
double* ydot);
79 #define nt_dt nrn_threads->_dt
80 #define nt_t nrn_threads->_t
165 #if COLLECT_TQueue_STATISTICS
204 return ps->
dil_.size();
211 void neosim2nrn_advance(
void*,
void*,
double);
212 void neosim2nrn_deliver(
void*,
void*);
213 void (*p_nrn2neosim_send)(
void*, double);
214 static void* neosim_entity_;
245 void ncs2nrn_inputevent(
int netcon_input_index,
double tdeliver);
248 extern void nrn2ncs_outputevent(
int netcon_output_index,
double firetime);
258 void nrn2ncs_netcons();
261 extern void nrn2ncs_outputevent(
int netcon_output_index,
double firetime);
266 extern bool use_bgpdma_;
267 extern void nrnbgp_messager_advance();
278 extern bool nrn_use_localgid_;
279 extern void nrn_outputevent(
unsigned char,
double);
364 sscanf(
buf,
"%d %d\n", &
type, &plr_index);
371 return new PlayRecordSave(
this);
375 PlayRecordSave*
prs =
nil;
397 prs =
new PlayRecordSave(plr);
400 prs->savestate_read(f);
404 PlayRecordSave::PlayRecordSave(
PlayRecord* plr) {
409 PlayRecordSave::~PlayRecordSave() {}
436 printf(
"NetCon from %s to ",
439 printf(
" weight index=%d\n", l);
482 for (
int i = 0;
i < s->
nnode; ++
i) {
510 for (
int i = 0;
i < s->
nnode; ++
i) {
518 obj = (*nrnpy_seg_from_sec_x)(s, x);
540 obj = (*nrnpy_seg_from_sec_x)(d->
target_->
sec, x);
569 o = (
OcList*) ((*po)->u.this_pointer);
584 for (
const auto& nc: d->
src_->
dil_) {
601 for (
const auto& nc: ps->
dil_) {
602 if (nc->obj_ && nc->target_ == d->
target_) {
622 for (
const auto& nc: ps->
dil_) {
643 for (
const auto& nc: ps->
dil_) {
677 hoc_execerror(
"argument must be a point process or NULLobject", 0);
684 #if DISCRETE_EVENT_OBSERVER
693 #if DISCRETE_EVENT_OBSERVER
731 double td =
chkarg(1, -1e20, 1e20);
743 hoc_execerror(
"Can only send fake self-events to ARTIFICIAL_CELLs", 0);
759 recid = (int) (*
getarg(3));
829 if (strcmp(s->
name,
"delay") == 0) {
833 }
else if (strcmp(s->
name,
"weight") == 0) {
840 }
else if (strcmp(s->
name,
"x") == 0) {
841 static double dummy = 0.;
849 }
else if (strcmp(s->
name,
"threshold") == 0) {
867 hoc_execerror(
"if arg 1 is an object it must be a point process or NULLObject", 0);
875 hoc_execerror(
"arg 2 must be a point process or NULLobject", 0);
877 double thresh = -1.e9;
883 delay =
chkarg(4, 0, 1e15);
926 for (p1 = s, p2 = b; *p1; ++p1, ++p2) {
982 if (!spost->pattern()) {
999 if (!star->pattern()) {
1020 if (precell == opre) {
1028 if (spre->
Match(s,
n, 0) > 0) {
1034 }
else if (ps->
osrc_) {
1037 if (presyn == opre) {
1045 if (spre->
Match(s,
n, 0) > 0) {
1053 for (
const auto& d: ps->
dil_) {
1064 if (postcell == opost) {
1072 if (spost->Match(s,
n, 0) > 0) {
1080 if (target == otar) {
1088 if (star->Match(s,
n, 0) > 0) {
1112 tpool_ =
new TQItemPool(1000, 1);
1115 sepool_ =
new SelfEventPool(1000, 1);
1158 Printf(
"interthread send td=%.15g DE type=%d thread=%d target=%d %s\n",
1197 Printf(
"interthread enqueue td=%.15g DE type=%d thread=%d target=%d %s\n",
1226 eps_ = 100. * UNIT_ROUNDOFF;
1251 prl_ =
new PlayRecList(10);
1279 for (
auto it = ps->
dil_.rbegin(); it != ps->
dil_.rend(); ++it) {
1293 while (
prl_->count()) {
1294 delete prl_->item(
prl_->count() - 1);
1360 for (b = *
first; b; b = bn) {
1453 for (
int j = 0;
j < d.
nlcv_; ++
j) {
1463 for (
int j = 0;
j < cv.
nctd_; ++
j) {
1470 if (cvode !=
gcv_) {
1481 cmlnext = cml->
next;
1502 for (cml = cmlist; cml; cml = cmlnext) {
1504 cmlnext = cml->
next;
1507 if (ml->nodeindices) {
1508 delete[] ml->nodeindices;
1538 }
else if (ps->
ssrc_) {
1544 z = cvsrc->
ctd_ + nt->
id;
1554 }
else if (ps->
ssrc_) {
1561 if (tid == nt->
id) {
1562 cvsrc =
p[tid].
lcv_ + cellnum[
j];
1564 if (nt == cvsrc->
nth_) {
1608 if (p_nrn2neosim_send)
1609 for (
i = 0;
i < nlist_; ++
i) {
1659 mf->ode_spec || mf->
state)) {
1675 cml->
ml->nodeindices = ml->nodeindices;
1730 if (_nt->
end == 0) {
1733 int* cellnum =
new int[_nt->
end];
1737 for (
i = _nt->
ncell; i < _nt->end; ++
i) {
1744 for (
i = 0;
i < _nt->
end; ++
i) {
1757 for (
i = 0;
i < _nt->
end; ++
i) {
1770 std::unordered_set<int> ba_candidate;
1773 for (
const auto& bat: batypes) {
1775 ba_candidate.insert(bam->type);
1785 (mf->
current || mf->ode_count || mf->ode_matsol || mf->ode_spec || mf->
state ||
1786 i ==
CAP || ba_candidate.count(
i) == 1)) {
1800 last[cellnum[inode]] = cml;
1802 if (last[cellnum[inode]]->
index ==
i) {
1806 last[cellnum[inode]]->
next = cml;
1808 last[cellnum[inode]] = cml;
1820 for (cml = cvml[
i]; cml; cml = cml->
next) {
1824 ml->nodeindices =
new int[ml->
nodecount];
1842 (mf->
current || mf->ode_count || mf->ode_matsol || mf->ode_spec || mf->
state ||
1843 i ==
CAP || ba_candidate.count(
i) == 1)) {
1847 if (cvml[icell]->
index !=
i) {
1848 cvml[icell] = cvml[icell]->
next;
1888 pp->
nvi_ = d.
lcv_ + cellnum[inode];
1904 for (tbl = nt->
tbl[bat]; tbl; tbl = tbl->
next) {
1920 for (
int icv = 0; icv < d.
nlcv_; ++icv) {
1924 if (cml->index == bam->
type) {
1948 for (ba = *pbml; ba; ba = ba->
next) {
2103 while (
p[0].tqe_->least_t() <= tout &&
stoprun == 0) {
2106 (*nrn_allthread_handle)();
2113 if (
p[0].tqe_->least()) {
2120 (*nrn_allthread_handle)();
2128 (*nrn_allthread_handle)();
2143 (*nrn_allthread_handle)();
2152 time_t rt = time(
nil);
2160 (*nrn_allthread_handle)();
2167 if (rt < time(
nil)) {
2180 for (
int i = 0;
i <
n; ++
i) {
2194 (*nrn_allthread_handle)();
2220 de->
pr(
"deliver", tt,
this);
2235 de->
pr(
"deliver", tt,
this);
2264 double tdiff = tt -
gcv_->
t_;
2274 if (
p[0].tqe_->least_t() <
gcv_->
t_) {
2318 }
else if (te <=
tn_) {
2320 }
else if (
t_ <
tn_) {
2339 if (tt <
PP2t(pnt)) {
2363 sprintf(
buf,
"artcell_net_move tt-nt_t = %g", tt - nt->
_t);
2368 if (tt <
p.immediate_deliver_) {
2385 Printf(
"NetCvode::move_event self event target %s t=%g, old=%g new=%g\n",
2394 if (neosim_entity_) {
2421 ++
p.unreffed_event_cnt_;
2431 if (neosim_entity_) {
2461 ++
p.unreffed_event_cnt_;
2469 q =
p.selfqueue_->insert(se);
2473 if (
q->t_ <
p.immediate_deliver_) {
2477 p.selfqueue_->remove(
q);
2489 if (time <
PP2t(pnt)) {
2496 if (neosim_entity_) {
2497 (*p_nrn2neosim_send)(neosim_entity_,
nt_t);
2513 if (!d[
i]._pvoid || !d[0]._pvoid) {
2522 for (
auto wc1: *wl) {
2524 if (wc1->qthresh_) {
2526 wc1->qthresh_ =
nil;
2623 for (
HTList* wl: htlists_of_thread) {
2635 int nn = offset +
n;
2636 if (d[offset]._pvoid) {
2640 for (
i = offset + 1;
i < nn; ++
i) {
2660 #if BBTQ == 3 || BBTQ == 4
2665 db->
pr(
"send", td,
this);
2670 x->resize_chunk(
n + 2);
2672 x->elem(
n + 1) = td;
2681 #define fifo_event event
2689 db->
pr(
"binq send", td,
this);
2702 db->
pr(
"send", td,
this);
2709 #define bin_event event
2715 db->
pr(
"send", td,
this);
2729 if (tt - nt->
_t < 0) {
2733 if (neosim_entity_) {
2745 if (!ppobj && tt -
nt_t < 0) {
2749 if (neosim_entity_) {
2785 HocEvent* he = (*allthread_hocevents_)[0];
2798 for (
i = 0;
i <
n; ++
i) {
2836 static PPArgs* ppargs;
2838 static void point_receive_job(
NrnThread* nt) {
2839 PPArgs*
p = ppargs + nt->
id;
2846 int id =
PP2NT(pp)->id;
2851 PPArgs*
p = ppargs +
id;
2909 if (p_nrn2neosim_send)
2910 for (
i = 0;
i < nlist_; ++
i) {
2912 while (tq->
least()) {
2974 #if BBTQ == 3 || BBTQ == 4
2982 ps->
delay_ = dil[0]->delay_;
2988 if (dil.size() > 2) {
2990 ps->
delay_ = dil[0]->delay_;
2995 for (
const auto& d: dil) {
2999 #if BBTQ == 3 || BBTQ == 4
3002 "Use of the event fifo queue is turned off due to more than one value for "
3027 for (
j = d->
cnt_ - 1;
j > 0; --
j) {
3053 for (
const auto& d:
dil_) {
3054 if (md > d->delay_) {
3103 switch (d->
type()) {
3122 for (
auto it = ps->dil_.rbegin(); it != ps->dil_.rend(); ++it) {
3124 double td = nc->delay_ - ps->delay_;
3154 ns->
event(tt,
this, nt);
3170 Printf(
"%s DiscreteEvent %.15g\n", s, tt);
3190 std::string ss(
"net-receive-");
3201 while ((
q = *(pq)) !=
nil &&
q->t_ < tt) {
3221 hoc_warning(
"errno set during NetCon deliver to NET_RECEIVE", (
char*) 0);
3237 hoc_warning(
"errno set during NetCon deliver to NET_RECEIVE", (
char*) 0);
3258 #if BBTQ == 3 || BBTQ == 4
3259 ns->fifo_event(tt +
delay_,
this);
3275 for (
const auto& d:
dil_) {
3276 if (d->active_ && d->target_) {
3285 ns->
event(tt + d->delay_, d,
PP2NT(d->target_));
3291 #if USENCS || NRNMPI
3300 if (nrn_use_localgid_) {
3301 nrn_outputevent(localgid_, tt);
3343 for (
const auto& d:
dil_) {
3344 if (d->active_ && d->target_ &&
PP2NT(d->target_) == nt) {
3345 double dtt = d->delay_ -
delay_;
3349 d->deliver(tt, ns, nt);
3350 }
else if (dtt < 0.) {
3351 hoc_execerror(
"internal error: Source delay is > NetCon delay", 0);
3354 ns->
event(tt + dtt, d, nt);
3364 for (
const auto& d:
dil_) {
3365 if (d->active_ && d->target_ &&
PP2NT(d->target_) == nt) {
3366 double dtt = d->delay_ -
delay_;
3387 for (
const auto& d:
dil_) {
3388 if (d->active_ && d->target_) {
3389 double dtt = d->delay_ -
delay_;
3391 hoc_execerror(
"internal error: Source delay is > NetCon delay", 0);
3394 ns->
event(tt + dtt, d, nt);
3428 int ppindex, ncindex, moff, pptype;
3432 sscanf(
buf,
"%s %d %d %d %d %lf\n", ppname, &ppindex, &pptype, &ncindex, &moff, &flag) ==
3460 sepp_->reserve(211);
3474 return iter->second;
3498 "%s %d %d %d %d %g\n",
3548 hoc_warning(
"errno set during SelfEvent deliver to NET_RECEIVE", (
char*) 0);
3579 Printf(
"%s PlayRecordEvent %.15g ", s, tt);
3593 Printf(
"microstep local retreat from %g (cvode_%p is at %g) for event onset=%g\n",
3604 Printf(
"after target solve time for %p is %g , dt=%g\n", cv, cv->
time(),
nt_dt);
3619 Printf(
"microstep retreat from %g (cvode_%p is at %g) for event onset=%g\n",
3632 Printf(
"after target solve time for %p is %g , dt=%g\n", cv, cv->
time(),
dt);
3639 bool neosim_deliver_self_events(
TQueue* tqe,
double til);
3640 bool neosim_deliver_self_events(
TQueue* tqe,
double til) {
3645 while (tqe->
least_t() <= til + .5e-8) {
3656 void neosim2nrn_advance(
void*
e,
void*
v,
double tout) {
3666 tqe = cv->neosim_self_events_;
3673 }
while (neosim_deliver_self_events(tqe,
t));
3680 void neosim2nrn_deliver(
void*
e,
void*
v) {
3718 while (
p[0].tqe_->least_t() == tt) {
3731 (*nrn_allthread_handle)();
3778 if (nrnmpi_pgvts_least(&tt, &op, &
init)) {
3782 }
else if (op == 4) {
3784 }
else if (ts == tt &&
q && ops == op) {
3824 return gcv_->use_partrans_;
3850 int n = (int) ((tstop -
nt_t) /
dt + 1
e-9);
3856 #if NRNMPI && !defined(USENCS)
3860 while (
nt_t <= ts) {
3862 ts = tstop - .5 *
dt;
3897 for (q1 = sq->first(); q1; q1 = q2) {
3927 void ncs2nrn_inputevent(
int i,
double tdeliver) {
3935 void nrn2ncs_netcons() {
3942 if (ncs2nrn_input_) {
3943 for (
i = 0;
i < ncs2nrn_input_->count(); ++
i) {
3946 ncs2nrn_input_->remove_all();
3950 for (
i = 0;
i < list->
count(); ++
i) {
3953 ncs2nrn_input_->append(nc);
3958 list = (
OcList*) (
o->u.this_pointer);
3959 for (
i = 0;
i < list->
count(); ++
i) {
3974 if (
i < 0 || ii++ ==
i) {
3979 Printf(
"NetCon active=%lu (not sent)=%lu delivered=%lu\n",
3984 "Condition O2 thresh detect=%lu via init=%lu effective=%lu abandoned=%lu (unnecesarily=%lu "
3985 "init+=%lu init-=%lu above=%lu below=%lu)\n",
3995 Printf(
"PreSyn send: mindelay=%lu direct=%lu\n",
3998 Printf(
"PreSyn deliver: O2 thresh=%lu NetCon=%lu (send=%lu deliver=%lu)\n",
4003 Printf(
"SelfEvent send=%lu move=%lu deliver=%lu\n",
4007 Printf(
"Watch send=%lu deliver=%lu\n",
4010 Printf(
"PlayRecord send=%lu deliver=%lu\n",
4013 Printf(
"HocEvent send=%lu deliver=%lu\n",
4016 Printf(
"SingleEvent deliver=%lu move=%lu\n",
4019 Printf(
"DiscreteEvent send=%lu deliver=%lu\n",
4023 Printf(
"Discrete event TQueue\n");
4026 Printf(
"Variable step integrator TQueue\n");
4104 double dtsav =
nt_dt;
4179 for (
const auto& d1: dil) {
4181 if (pnt && t2i[pnt->
prop->
type] > -1) {
4205 for (tml = nt->
tml; tml; tml = tml->
next)
4223 for (
const auto& d1: dil) {
4225 if (pnt && t2i[pnt->
prop->
type] > -1) {
4271 for (
i = 0;
i <
cnt; ++
i) {
4272 prl_->item(
i)->record_init();
4278 for (
i = 0;
i <
cnt; ++
i) {
4279 prl_->item(
i)->play_init();
4291 if (
sec ==
p[
i].lcv_[
j].ctd_[0].v_node_[
p[
i].lcv_[
j].ctd_[0].rootnodecount_]->
sec) {
4377 if (s->size() !=
size_t(d->
gcv_->
neq_)) {
4378 hoc_execerror(
"size of state vector != number of state equations", 0);
4383 ds->resize(s->size());
4394 if (s->size() !=
size_t(d->
gcv_->
neq_)) {
4395 hoc_execerror(
"size of state vector != number of state equations", 0);
4477 int i, it,
j,
n, neq;
4511 for (
j = 0;
j < neq; ++
j) {
4540 if (
j +
p[it].lcv_[
i].neq_ > is) {
4563 static char buf[200];
4572 char*
buf =
new char[strlen(
name) + 1];
4575 for (cp =
buf; *cp; ++cp) {
4586 if (sym && *cp ==
'\0' && (sym->
type == RANGEVAR || strcmp(sym->
name,
"Vector") == 0)) {
4589 }
else if (sym && sym->
type == TEMPLATE && *cp !=
'\0') {
4608 if ((
stiff_ == 0) != (x == 0)) {
4717 auto psti =
pst_->find(psrc);
4718 if (psti ==
pst_->end()) {
4719 ps =
new PreSyn(psrc, osrc, ssrc);
4734 ps =
new PreSyn(psrc, osrc, ssrc);
4741 }
else if (target) {
4781 for (
int it = 0; it <
gcv_->
nctd_; ++it) {
4784 for (
size_t j = 0;
j < psl->size(); ++
j) {
4785 if ((*psl)[
j] == ps) {
4786 psl->erase(psl->begin() +
j);
4796 for (
size_t j = 0;
j < psl->size(); ++
j) {
4797 if ((*psl)[
j] == ps) {
4798 psl->erase(psl->begin() +
j);
4813 hoc_execerror(
"DiscreteEvent::savestate_save:",
" is not the null_event_");
4820 Printf(
"null_event_ onto queue\n");
4841 if (target ==
nil) {
4851 #if DISCRETE_EVENT_OBSERVER
4861 for (
int i = 0;
i <
cnt_; ++
i) {
4874 #if DISCRETE_EVENT_OBSERVER
4993 (*idxtable_)[obj->
index] = nc;
5019 }
else if (ps->
ssrc_) {
5028 if (!
p[
i].psl_thr_) {
5042 if (
p[
i].psl_thr_) {
5067 for (
i = 0;
i <
n; ++
i) {
5096 if (
osrc_ && !src) {
5099 #if 1 || USENCS || NRNMPI
5108 #if DISCRETE_EVENT_OBSERVER
5124 #if DISCRETE_EVENT_OBSERVER
5135 #if DISCRETE_EVENT_OBSERVER
5146 for (
const auto& d:
dil_) {
5236 if (strlen(stmt) > 0) {
5252 #if DISCRETE_EVENT_OBSERVER
5263 #if DISCRETE_EVENT_OBSERVER
5315 for (
const auto& d:
dil_) {
5325 #if DISCRETE_EVENT_OBSERVER
5331 #if DISCRETE_EVENT_OBSERVER
5343 #if DISCRETE_EVENT_OBSERVER
5351 if (
value() > 0.0) {
5352 if (
flag_ ==
false) {
5356 if (neosim_entity_) {
5357 (*p_nrn2neosim_send)(neosim_entity_, tt);
5392 double val =
value();
5393 if (
flag_ ==
false && val >= 0.0) {
5396 if (cv->
t0_ == cv->
tn_) {
5410 th = th * nt->
_t + (1. - th) *
told_;
5439 Printf(
"abandon when t == qthresh_->t_ = %20.15g\n",
nt_t);
5441 if (cv->
t0_ == cv->
tn_) {
5442 if (
value() > 0.0) {
5448 if (
value() > 0.0) {
5535 hoc_warning(
"errno set during WatchCondition deliver to NET_RECEIVE", (
char*) 0);
5629 hoc_warning(
"errno set during WatchCondition deliver to NET_RECEIVE", (
char*) 0);
5645 hoc_warning(
"errno set during STECondition pgvts_deliver to NET_RECEIVE", (
char*) 0);
5674 ps->condition(
this);
5679 item = item->
Next()) {
5703 ps->check(nt, nt->
_t);
5708 item = item->
Next()) {
5718 for (
i = 0;
i <
cnt; ++
i) {
5720 if (
pr->ith_ == nt->
id) {
5721 pr->continuous(nt->
_t);
5729 for (
i = 0;
i <
cnt; ++
i) {
5731 if (
pr->ith_ == nt->
id) {
5732 pr->continuous(nt->
_t);
5760 int cur_size =
v->size();
5761 if (
v->buffer_size() < bsize + cur_size) {
5762 v->buffer_size(bsize + cur_size);
5765 v->resize(bsize + cur_size);
5768 pvars[i_trajec] = pd;
5772 types[i_trajec] = 0;
5773 indices[i_trajec] = 0;
5778 "Pointer %p of PlayRecord type %d ignored because not a Range Variable",
5809 double**& varrays) {
5828 for (
int i = 0;
i < cntp; ++
i) {
5830 if (
pr->ith_ == tid) {
5854 for (
int j = 0;
j < gvr->
count(); ++
j) {
5867 vpr =
new void*[n_pr];
5868 types =
new int[n_trajec];
5869 indices =
new int[n_trajec];
5871 varrays =
new double*[n_trajec];
5873 pvars =
new double*[n_trajec];
5878 for (
int i = 0;
i < cntp; ++
i) {
5881 if (
pr->ith_ == tid) {
5924 if (bsize && !glr->
v_) {
5947 for (GLineRecordEData::iterator it = ed.begin(); it != ed.end(); ++it) {
5948 double* pd = (*it).first;
5951 if (bsize &&
v ==
NULL) {
5980 for (
int j = 0;
j < gvr->
count(); ++
j) {
6010 if (n_trajec == 0) {
6034 printf(
"nrnthread_get_trajectory_requests tid=%d bsize=%d n_pr=%d n_trajec=%d\n", tid, bsize, n_pr, n_trajec);
6037 for (
int i=0;
i < n_pr; ++
i) {
6041 printf(
" %d %d prtype=%d %p type=%d index=%d\n",
i, i_trajec,
pr->type(), pd, types[i_trajec], indices[i_trajec]);
6047 i_trajec += ed.size();
6068 for (
int i = 0;
i < n_pr; ++
i) {
6078 oc.
run(
"screen_update()\n");
6106 for (
int i = 0;
i < n_pr; ++
i) {
6112 v->resize(
v->size() - (bsize - vecsz));
6115 v->resize(
v->size() - (bsize - vecsz));
6119 glr->
plot(vecsz, tt);
6139 if (ps->
nt_ == nt) {
6157 void (*
cb)(
int,
int,
int,
int,
int));
6165 for (
HTList* wl: htlists_of_thread) {
6179 nrnbgp_messager_advance();
6184 tm = nt->
_t + 0.5 * nt->
_dt;
6206 extern bool nrn_use_compress_;
6211 while ((
q =
p[tid].tqe_->dequeue_bin()) != 0) {
6215 db->
pr(
"binq deliver",
nt_t,
this);
6229 if (
p[tid].tqe_->top()) {
6250 for (
i = 0;
i <
cnt; ++
i) {
6257 for (
i = 0;
i <
cnt; ++
i) {
6264 for (
i = 0;
i <
cnt; ++
i) {
6274 for (
i = 0;
i <
cnt; ++
i) {
6283 assert(i < prl_->count());
6284 return prl_->item(
i);
6289 for (
i = 0;
i <
cnt; ++
i) {
6290 if (
prl_->item(
i)->uses(
v)) {
6291 return prl_->item(
i);
6433 : PlayRecordSave(prl) {
6501 : PlayRecordSave(prl) {}
6543 bool discrete = ((
ifarg(4) && (int)
chkarg(4, 0, 1) == 1) ?
true :
false);
6564 long i,
j, iprl, prlc;
6565 prlc =
prl_->count();
6575 for (iprl = 0; iprl < prlc; ++iprl) {
6597 hoc_execerror(
"We were unable to associate a PlayRecord item with a RANGE variable",
6607 hoc_execerror(
"We were unable to associate a PlayRecord item with a thread",
nil);
6620 if (&
NODEV(nd) == pd) {
6624 for (
p = nd->
prop;
p;
p =
p->next) {
6625 if (pd >=
p->param && pd < (
p->param +
p->param_size)) {
6653 for (in = i1; in < i3; ++in) {
6655 if (&
NODEV(nd) == pd) {
6659 for (
p = nd->
prop;
p;
p =
p->next) {
6660 if (pd >=
p->param && pd < (
p->param +
p->param_size)) {
6679 for (in = -1; in <
sec->nnode; ++in) {
6681 nd =
sec->parentnode;
6686 nd =
sec->pnode[in];
6688 if (&
NODEV(nd) == pd) {
6692 for (
p = nd->
prop;
p;
p =
p->next) {
6693 if (pd >=
p->param && pd < (
p->param +
p->param_size)) {
6706 " pointer not associated with currently accessed section\n\
6707 Use section ... (&var(x)...) intead of ...(§ion.var(x)...)\n");
6712 int on = (int)
chkarg(1, 0, 2);
6729 double* pamax = &
dummy;
6754 getacor = (int)
chkarg(2, 0, 1);
6789 for (
j = 0;
j <
n; ++
j) {
6791 auto msti =
mst_->find((
void*) sym);
6793 if (msti ==
mst_->end()) {
6798 (*mst_)[(
void*) sym] = msi;
6805 if (msi->
amax_ < ma[
j]) {
6821 for (
auto ti: *
mst_) {
6844 auto msti =
mst_->find((
void*) sym);
6845 if (msti !=
mst_->end()) {
6846 *pamax = msti->second->amax_;
6847 return msti->second->max_;
6858 for (
i = 0;
i <
cnt; ++
i) {
6905 for (
int i = 0;
i <
n; ++
i) {
6925 (*nrn_allthread_handle)();
6938 (*nrn_allthread_handle)();
6946 (*nrn_allthread_handle)();
6961 (*nrn_allthread_handle)();
6975 while (
nt_t < tout) {
6978 (*nrn_allthread_handle)();
6992 "presently limited to single thread.");
7011 de->
pr(
"deliver", tt, nc);
7034 double tdiff = tt -
gcv_->
t_;
7064 double tt,
min = 1e50;
7073 for (
int id = 0;
id <
pcnt_; ++
id) {
void bgp_dma_send(PreSyn *ps, double t)
const char * secname(Section *sec)
void nrn_pushsec(Section *sec)
double nrn_arc_position(Section *sec, Node *node)
Section * chk_access(void)
static void destruct(BAMechList **first)
BAMechList(BAMechList **first)
static unsigned long abandon_
static unsigned long deliver_qthresh_
virtual void check(NrnThread *, double sendtime, double teps=0.0)
static unsigned long send_qthresh_
virtual ~ConditionEvent()
void abandon_statistics(Cvode *)
static unsigned long init_above_
static unsigned long abandon_above_
static unsigned long abandon_init_above_
static unsigned long eq_abandon_
static unsigned long abandon_below_
static unsigned long abandon_init_below_
void record_add(PlayRecord *)
void play_add(PlayRecord *)
void check_deliver(NrnThread *nt=0)
void evaluate_conditions(NrnThread *nt=0)
void fun_thread(double t, double *y, double *ydot, NrnThread *nt)
void scatter_y(double *, int)
virtual int init(double t)
double * n_vector_data(N_Vector, int)
virtual int interpolate(double t)
void activate_maxstate(bool)
virtual int handle_step(NetCvode *, double)
void error_weights(double *)
virtual ~CvodeThreadData()
int nonvint_extra_offset_
CvMembList * cv_memb_list_
void delete_memb_list(CvMembList *)
CvMembList * no_cap_memb_
BAMechList * before_breakpoint_
BAMechList * after_solve_
BAMechList * before_step_
virtual DiscreteEvent * savestate_save()
virtual void pr(const char *, double t, NetCvode *)
virtual void savestate_write(FILE *)
virtual void deliver(double t, NetCvode *, NrnThread *)
static unsigned long discretevent_send_
static unsigned long discretevent_deliver_
static DiscreteEvent * savestate_read(FILE *)
virtual void pgvts_deliver(double t, NetCvode *)
virtual void send(double deliverytime, NetCvode *, NrnThread *)
virtual void savestate_restore(double deliverytime, NetCvode *)
virtual int pgvts_op(int &i)
virtual void frecord_init(TQItem *)
virtual NrnThread * thread()
GLineRecordEData pd_and_vec_
int execute(bool notify=true)
String * retrieve(double *)
Symbol * retrieve_sym(double *)
virtual void allthread_handle()
static HocEvent * alloc(const char *stmt, Object *, int, Object *pyact=nil)
static unsigned long hocevent_deliver_
static unsigned long hocevent_send_
static unsigned long singleevent_deliver_
static unsigned long singleevent_move_
static bool equal(float x, float y, float e)
static bool eq2(double x, double y, double e)
virtual void pr(const char *, double t, NetCvode *)
virtual NrnThread * thread()
virtual void deliver(double, NetCvode *, NrnThread *)
void replace_src(PreSyn *)
static unsigned long netcon_send_active_
virtual void disconnect(Observable *)
virtual DiscreteEvent * savestate_save()
virtual void send(double sendtime, NetCvode *, NrnThread *)
NetCon(PreSyn *src, Object *target)
static DiscreteEvent * savestate_read(FILE *)
static unsigned long netcon_deliver_
static unsigned long netcon_send_inactive_
virtual void pgvts_deliver(double t, NetCvode *)
static NetCon * weight2netcon(double *)
static NetCon * index2netcon(long)
virtual void savestate_restore(double deliverytime, NetCvode *)
virtual void savestate_write(FILE *)
static NetConSaveWeightTable * wtable_
static NetConSaveIndexTable * idxtable_
TQItem * bin_event(double tdeliver, DiscreteEvent *, NrnThread *)
int local_microstep(NrnThread *)
double state_magnitudes()
void ps_thread_link(PreSyn *)
void deliver_events(double til, NrnThread *)
double allthread_least_t(int &tid)
int pgvts_event(double &tt)
PlayRecList * fixed_record_
BAMechList * cvbml(int, BAMech *, Cvode *)
HocEventList * allthread_hocevents_
void deliver_least_event(NrnThread *)
static double eps(double x)
void local_retreat(double, Cvode *)
void consist_sec_pd(const char *, Section *, double *)
IvocVect * vec_event_store_
void check_thresh(NrnThread *)
void playrec_add(PlayRecord *)
int owned_by_thread(double *)
void retreat(double, Cvode *)
PlayRecList * fixed_play_
DiscreteEvent * pgvts_least(double &tt, int &op, int &init)
void deliver_net_events(NrnThread *)
int pgvts_cvode(double tt, int op)
const char * sym2name(Symbol *)
int fornetcon_change_cnt_
int solve_when_threads(double)
NetCon * install_deliver(double *psrc, Section *ssrc, Object *osrc, Object *target, double threshold, double delay, double weight)
void point_receive(int, Point_process *, double *, double)
void hoc_event(double, const char *hoc_stmt, Object *ppobj=nil, int reinit=0, Object *pyact=nil)
void fill_local_ba_cnt(int, int *, NetCvodeThreadData &)
NetCvode(bool single=true)
const char * statename(int, int style=1)
void maxstate_analyze_1(int, Cvode &, CvodeThreadData &)
void distribute_dinfo(int *, int)
void fill_global_ba(NrnThread *, int, BAMechList **)
MUTDEC void set_enqueueing()
void remove_event(TQItem *, int threadid)
void playrec_remove(PlayRecord *)
PlayRecList * playrec_list()
void psl_append(PreSyn *)
void presyn_disconnect(PreSyn *)
int global_microstep_when_threads()
void re_init(double t0=0.)
void fill_local_ba(int *, NetCvodeThreadData &)
TQueue * event_queue(NrnThread *nt)
void move_event(TQItem *, double, NrnThread *)
bool deliver_event(double til, NrnThread *)
void deliver_events_when_threads(double)
Symbol * name2sym(const char *)
void allthread_handle(double, HocEvent *, NrnThread *)
void fixed_record_continuous(NrnThread *)
int playrec_item(PlayRecord *)
void fixed_play_continuous(NrnThread *)
int structure_change_cnt_
PlayRecord * playrec_uses(void *)
TQItem * event(double tdeliver, DiscreteEvent *, NrnThread *)
virtual ~NetCvodeThreadData()
double immediate_deliver_
void interthread_send(double, DiscreteEvent *, NrnThread *)
InterThreadEvent * inter_thread_events_
void enqueue(NetCvode *, NrnThread *)
static void Detach(Object *, Observer *)
static void Attach(Object *, Observer *)
int run(int argc, const char **argv)
virtual void deliver(double, NetCvode *, NrnThread *)
virtual void frecord_init(TQItem *q)
static unsigned long playrecord_send_
virtual ~PlayRecordEvent()
static DiscreteEvent * savestate_read(FILE *)
virtual NrnThread * thread()
virtual void savestate_restore(double deliverytime, NetCvode *)
virtual void pr(const char *, double t, NetCvode *)
static unsigned long playrecord_deliver_
virtual void savestate_write(FILE *)
virtual DiscreteEvent * savestate_save()
virtual void update_ptr(double *)
static PlayRecordSave * savestate_read(FILE *)
virtual void frecord_init(TQItem *)
PlayRecord(double *pd, Object *ppobj=nil)
virtual void disconnect(Observable *)
virtual PlayRecordSave * savestate_save()
virtual PlayRecordEvent * event()
virtual void deliver(double t, NetCvode *)
virtual void pr(const char *, double t, NetCvode *)
void update_ptr(double *)
static unsigned long presyn_send_direct_
virtual void send(double sendtime, NetCvode *, NrnThread *)
void update(Observable *)
static unsigned long presyn_deliver_ncsend_
PreSyn(double *src, Object *osrc, Section *ssrc=nil)
void record_stmt(const char *)
void fanout(double, NetCvode *, NrnThread *)
virtual void deliver(double, NetCvode *, NrnThread *)
virtual NrnThread * thread()
static unsigned long presyn_deliver_direct_
void record(IvocVect *, IvocVect *idvec=nil, int rec_id=0)
virtual void pgvts_deliver(double t, NetCvode *)
static DiscreteEvent * savestate_read(FILE *)
virtual DiscreteEvent * savestate_save()
void disconnect(Observable *)
static unsigned long presyn_deliver_netcon_
static unsigned long presyn_send_mindelay_
virtual void savestate_write(FILE *)
virtual void savestate_restore(double deliverytime, NetCvode *)
static PreSynSaveIndexTable * idxtable_
static PreSyn * hindx2presyn(long)
int Match(const char *text, int length, int index)
const char * pattern() const
virtual void pgvts_deliver(double t, NetCvode *)
virtual NrnThread * thread()
STECondition(Point_process *, double(*)(Point_process *)=NULL)
virtual void deliver(double, NetCvode *, NrnThread *)
STETransition * add_transition()
StateTransitionEvent * ste_
static DiscreteEvent * savestate_read(FILE *)
static void savestate_free()
void call_net_receive(NetCvode *)
virtual void savestate_restore(double deliverytime, NetCvode *)
virtual NrnThread * thread()
static unsigned long selfevent_deliver_
virtual void pr(const char *, double t, NetCvode *)
static unsigned long selfevent_send_
static unsigned long selfevent_move_
virtual void savestate_write(FILE *)
static std::unique_ptr< SelfEventPPTable > sepp_
static Point_process * index2pp(int type, int oindex)
virtual void deliver(double, NetCvode *, NrnThread *)
virtual DiscreteEvent * savestate_save()
virtual void pgvts_deliver(double t, NetCvode *)
void transition(int src, int dest, double *var1, double *var2, HocCommand *)
const char * string() const
TQItem * enqueue_bin(double t, void *data)
void move(TQItem *, double tnew)
TQItem * insert_fifo(double t, void *data_)
TQItem * atomic_dq(double til)
void forall_callback(void(*)(const TQItem *, int))
TQItem * insert(double t, void *data_)
void move_least(double tnew)
void spike_stat(double *)
virtual void record_init()
virtual void disconnect(Observable *)
virtual void install(Cvode *)
TvecRecord(Section *, IvocVect *tvec, Object *ppobj=nil)
virtual void continuous(double t)
virtual void frecord_init(TQItem *)
virtual void install(Cvode *)
virtual void deliver(double t, NetCvode *)
virtual ~VecRecordDiscrete()
virtual PlayRecordSave * savestate_save()
VecRecordDiscrete(double *, IvocVect *y, IvocVect *t, Object *ppobj=nil)
virtual void record_init()
virtual void disconnect(Observable *)
VecRecordDiscreteSave(PlayRecord *)
virtual ~VecRecordDiscreteSave()
virtual void savestate_write(FILE *)
virtual void savestate_read(FILE *)
virtual void savestate_restore()
virtual void record_init()
virtual void disconnect(Observable *)
virtual void frecord_init(TQItem *)
virtual void deliver(double t, NetCvode *)
virtual void install(Cvode *)
virtual PlayRecordSave * savestate_save()
VecRecordDt(double *, IvocVect *y, double dt, Object *ppobj=nil)
VecRecordDtSave(PlayRecord *)
virtual ~VecRecordDtSave()
virtual void savestate_restore()
virtual NrnThread * thread()
static unsigned long watch_send_
static unsigned long watch_deliver_
virtual ~WatchCondition()
double(* c_)(Point_process *)
void activate(double flag)
virtual void deliver(double, NetCvode *, NrnThread *)
virtual void pgvts_deliver(double t, NetCvode *)
virtual void pr(const char *, double t, NetCvode *)
virtual void send(double, NetCvode *, NrnThread *)
WatchCondition(Point_process *, double(*)(Point_process *))
virtual void disconnect(Observable *)
virtual void install(Cvode *)
YvecRecord(double *, IvocVect *y, Object *ppobj=nil)
virtual void continuous(double t)
virtual void record_init()
Symbol * hoc_table_lookup(const char *, Symlist *)
std::vector< PreSyn * > PreSynList
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)
void hoc_execerror(const char *, const char *)
std::vector< std::pair< double *, IvocVect * > > GLineRecordEData
int hoc_is_object_arg(int narg)
Object * hoc_name2obj(const char *name, int index)
Object ** hoc_temp_objvar(Symbol *symtemp, void *v)
void hoc_pushpx(double *d)
int hoc_is_str_arg(int narg)
double * hoc_val_pointer(const char *s)
void hoc_warning(const char *, const char *)
int hoc_is_double_arg(int narg)
double nrn_event_queue_stats(double *stats)
void hoc_obj_ref(Object *obj)
char * hoc_object_name(Object *ob)
Symbol * hoc_lookup(const char *)
double * hoc_pgetarg(int narg)
void hoc_obj_unref(Object *obj)
struct Arrayinfo Arrayinfo
hoc_List * hoc_l_newlist()
hoc_Item * hoc_l_insertvoid(hoc_Item *, void *)
void hoc_l_freelist(hoc_List **)
void hoc_l_delete(hoc_Item *)
Object ** hoc_objgetarg(int)
void nrn_notify_when_void_freed(void *p, Observer *ob)
void nrn_notify_when_double_freed(double *p, Observer *ob)
void nrn_notify_pointer_disconnect(Observer *ob)
double * vector_vec(Vect *v)
Object ** hoc_temp_objptr(Object *)
#define BEFORE_BREAKPOINT
#define ITERATE(itm, lst)
void nrn_onethread_job(int i, void *(*job)(NrnThread *))
void nrn_multithread_job(void *(*job)(NrnThread *))
void nrn_wait_for_threads()
std::unordered_map< void *, NetCon * > NetConSaveWeightTable
#define DiscreteEventType
std::unordered_map< long, Point_process * > SelfEventPPTable
#define PlayRecordEventType
std::vector< NetCon * > NetConPList
std::unordered_map< long, PreSyn * > PreSynSaveIndexTable
std::unordered_map< long, NetCon * > NetConSaveIndexTable
static Node * node(Object *)
ReceiveFunc * pnt_receive_init
#define POINT_RECEIVE(type, tar, w, f)
void nrn2core_transfer_WATCH(void(*cb)(int, int, int, int, int))
static double nc_setpost(void *v)
static TQList * record_init_items_
short * nrn_is_artificial_
short * nrn_artcell_qindex_
static Object ** nc_precelllist(void *v)
static double nc_event(void *v)
Point_process * ob2pntproc(Object *)
void nrn_netcon_event(NetCon *nc, double td)
static void * pending_selfqueue(NrnThread *)
double nrn_hoc2scatter_y(void *v)
void nrn2core_transfer_WatchCondition(WatchCondition *wc, void(*cb)(int, int, int, int, int))
In nrncore_callbacks.cpp.
void(* nrnthread_v_transfer_)(NrnThread *)
int nrn_presyn_count(PreSyn *ps)
static Object ** nc_syn(void *v)
static double nc_active(void *v)
Point_process * nrn_netcon_target(NetCon *nc)
static double lvardt_tout_
static PreSyn * unused_presyn
int * nrn_fornetcon_type_
std::vector< WatchCondition * > WatchList
void _nrn_watch_allocate(Datum *d, double(*c)(Point_process *), int i, Point_process *pnt, double flag)
Introduced so corenrn->nrn can request the mod file to make sure all WatchCondition are allocated.
void _nrn_watch_activate(Datum *, double(*)(Point_process *), int, Point_process *, int, double)
void * nrn_presyn_netcon(PreSyn *ps, int i)
void nrnthread_trajectory_values(int tid, int n_pr, void **vpr, double t)
static void allthread_handle_callback()
void nrn_use_busywait(int)
double nrn_hoc2fixed_step(void *)
Symlist * hoc_top_level_symlist
void ncs2nrn_integrate(double tstop)
static Object ** nc_prelist(void *v)
void nrn_cleanup_presyn(PreSyn *)
int * nrn_fornetcon_index_
ReceiveFunc * pnt_receive
static void * lvardt_integrate(NrnThread *nt)
void net_event(Point_process *, double)
static double nc_preloc(void *v)
static Object ** nc_preseg(void *v)
double nrn_hoc2gather_y(void *v)
static Member_func members[]
static IvocVect * event_info_tvec_
static void event_info_callback(const TQItem *, int)
static Object ** nc_get_recordvec(void *v)
void nrn_cvfun(double t, double *y, double *ydot)
void record_init_clear(const TQItem *q, int)
int nrn_netcon_info(NetCon *nc, double **pw, Point_process **target, double **th, double **del)
static double nc_wcnt(void *v)
double nrn_netcon_get_thresh(NetCon *nc)
static void destruct(void *v)
cTemplate ** nrn_pnt_template_
static Object ** nc_postcell(void *v)
void net_move(void **, Point_process *, double)
void nrn_netcon_set_thresh(NetCon *nc, double th)
int nrn_netcon_weight(NetCon *nc, double **pw)
void * nrn_interthread_enqueue(NrnThread *)
void(* ReceiveFunc)(Point_process *, double *, double)
double nrn_hoc2fun(void *v)
double * nrn_recalc_ptr(double *)
void _nrn_free_watch(Datum *, int, int)
Called by Point_process destructor in translated mod file.
void(* nrn_allthread_handle)()
int linmod_extra_eqn_count()
Point_process * ob2pntproc_0(Object *)
Object *(* nrnpy_seg_from_sec_x)(Section *, double)
SelfEvent typedef std::vector< TQItem * > TQList
static double nc_record(void *v)
void nrnthread_trajectory_return(int tid, int n_pr, int bsize, int vecsz, void **vpr, double t)
static Member_ret_obj_func omembers[]
static char * escape_bracket(const char *s)
void net_send(void **, double *, Point_process *, double, double)
static Object ** nc_postseg(void *v)
void artcell_net_send(void **, double *, Point_process *, double, double)
void nrn_fixed_step_group(int)
static Object ** nc_postcelllist(void *v)
static DiscreteEvent * null_event_
void nrn_parent_info(Section *)
implementPtrList(PlayRecList, PlayRecord) void NetCvode
static void all_pending_selfqueue(double tt)
static Object ** newoclist(int i, OcList *&o)
TQueue * net_cvode_instance_event_queue(NrnThread *)
double nrn_netcon_get_delay(NetCon *nc)
Object * nrn_sec2cell(Section *)
static void steer_val(void *v)
PlayRecList * net_cvode_instance_prl()
void nrnthread_get_trajectory_requests(int tid, int &bsize, int &n_pr, void **&vpr, int &n_trajec, int *&types, int *&indices, double **&pvars, double **&varrays)
static void * cons(Object *o)
declarePool(SelfEventPool, SelfEvent) implementPool(SelfEventPool
static unsigned long net_event_cnt_
static Object ** nc_precell(void *v)
static Object ** nc_synlist(void *v)
static double nc_valid(void *v)
static void * chk_deliv(NrnThread *nt)
static int event_info_type_
void nrn_pending_selfqueue(double tt, NrnThread *)
static double nc_srcgid(void *v)
int _nrn_netcon_args(void *v, double ***argslist)
NetCvode * net_cvode_instance
int hoc_araypt(Symbol *, int)
static double pending_selfqueue_deliver_
static int trajec_buffered(NrnThread &nt, int bsize, IvocVect *v, double *pd, int i_pr, PlayRecord *pr, void **vpr, int i_trajec, int *types, int *indices, double **pvars, double **varrays)
static double nc_postloc(void *v)
void nrn_netcon_set_delay(NetCon *nc, double d)
int nrn_sec2cell_equals(Section *, Object *)
bool nrn_trajectory_request_per_time_step_
Symlist * hoc_built_in_symlist
static IvocVect * event_info_flagvec_
static void peq(const TQItem *, int)
void _nrn_free_fornetcon(void **)
void artcell_net_move(void **, Point_process *, double)
void nrn_watch_clear()
Watch info corenrn->nrn transfer requires all activated WatchCondition be deactivated prior to mirror...
static void * deliver_for_thread(NrnThread *nt)
static OcList * event_info_list_
static Object ** nc_pre(void *v)
static unsigned long deliver_cnt_
static void * eval_cond(NrnThread *nt)
hoc_Item * net_cvode_instance_psl()
void nrn_ba(NrnThread *, int)
std::unordered_map< double *, PreSyn * > PreSynTable
std::unordered_map< void *, MaxStateItem * > MaxStateTable
std::vector< HocEvent * > HocEventList
int is_point_process(Object *)
int nrn_dblpntr2nrncore(double *pd, NrnThread &nt, int &type, int &index)
static double check(double t, Daspk *ida)
int const size_t const size_t n
void nrnmusic_injectlist(void *vp, double tt)
#define MUTCONSTRUCT(mkmut)
void class2oc(const char *, void *(*cons)(Object *), void(*destruct)(void *), Member_func *, int(*checkpoint)(void **), Member_ret_obj_func *, Member_ret_str_func *)
struct Memb_list Memb_list
static philox4x32_key_t k
static void pr(N_Vector x)
static double cell(void *v)
static void pnode(Prop *)
check_obj_type(o, "SectionList")
struct NrnThreadBAList * next
Represent main neuron object computed by single thread.
NrnThreadBAList * tbl[BEFORE_AFTER_SIZE]
struct NrnThreadMembList * next
struct Symbol::@37::@38 rng
HocStruct cTemplate * ctemplate
implementPool(TQItemPool, TQItem) SelfQueue
static double stats(void *v)
#define GVectorRecordType
#define VecPlayContinuousType
#define VecRecordDiscreteType