40 unsigned char* spikeout_fixed;
41 unsigned char* spfixin_ovfl_;
42 unsigned char* spikein_fixed;
57 static double t_exchange_;
60 NRNMPI_Spike* spikeout;
61 NRNMPI_Spike* spikein;
63 void nrn_timeout(
int);
70 std::vector<std::map<int, InputPreSyn*>> localmaps;
72 static int ocapacity_;
76 static bool use_compress_;
77 static int spfixout_capacity_;
79 static void nrn_spike_exchange_compressed(NrnThread*);
87 static std::vector<NetParEvent>
npe_;
104 #if nrn_spikebuf_size > 0
133 inline static void sppk(
unsigned char* c,
int gid) {
134 for (
int i = localgid_size_ - 1;
i >= 0; --
i) {
139 inline static int spupk(
unsigned char* c) {
141 for (
int i = 1;
i < localgid_size_; ++
i) {
152 std::lock_guard<OMP_Mutex> lock(
mut);
156 if (idxout_ >= spfixout_capacity_) {
157 spfixout_capacity_ *= 2;
158 spikeout_fixed = (
unsigned char*)
erealloc(spikeout_fixed,
159 spfixout_capacity_ *
sizeof(
unsigned char));
161 spikeout_fixed[
i++] = (
unsigned char) ((firetime - t_exchange_) * dt1_ + .5);
162 spikeout_fixed[
i] = localgid;
171 std::lock_guard<OMP_Mutex> lock(
mut);
175 idxout_ += 1 + localgid_size_;
176 if (idxout_ >= spfixout_capacity_) {
177 spfixout_capacity_ *= 2;
178 spikeout_fixed = (
unsigned char*)
erealloc(spikeout_fixed,
179 spfixout_capacity_ *
sizeof(
unsigned char));
184 spikeout_fixed[
i++] = (
unsigned char) ((firetime - t_exchange_) * dt1_ + .5);
187 sppk(spikeout_fixed +
i, gid);
190 #if nrn_spikebuf_size == 0
192 if (
i >= ocapacity_) {
194 spikeout = (NRNMPI_Spike*)
erealloc(spikeout, ocapacity_ *
sizeof(NRNMPI_Spike));
197 spikeout[
i].gid = gid;
198 spikeout[
i].spiketime = firetime;
203 if (
i >= ocapacity_) {
205 spikeout = (NRNMPI_Spike*) hoc_Erealloc(spikeout,
206 ocapacity_ *
sizeof(NRNMPI_Spike));
209 spikeout[
i].gid = gid;
210 spikeout[
i].spiketime = firetime;
212 spbufout->
gid[
i] = gid;
230 npe_.shrink_to_fit();
255 hoc_execerror(
"usable mindelay is 0",
"(or less than dt for fixed step method)");
274 npe_.shrink_to_fit();
296 #if nrn_spikebuf_size > 0
321 nrn_spike_exchange_compressed(nt);
328 #if nrn_spikebuf_size > 0
334 nrnmpi_nin_, spikeout, icapacity, &spikein, ovfl, nout, spbufout, spbufin);
339 tbuf_[itbuf_++] = (
unsigned long) nout;
340 tbuf_[itbuf_++] = (
unsigned long) n;
351 #if nrn_spikebuf_size > 0
357 for (
int j = 0; j < nn; ++j) {
358 auto gid2in_it =
gid2in.find(spbufin[
i].gid[j]);
359 if (gid2in_it !=
gid2in.end()) {
360 InputPreSyn* ps = gid2in_it->second;
366 #endif // nrn_spikebuf_size > 0
367 for (
int i = 0;
i < n; ++
i) {
368 auto gid2in_it =
gid2in.find(spikein[
i].gid);
369 if (gid2in_it !=
gid2in.end()) {
370 InputPreSyn* ps = gid2in_it->second;
378 void nrn_spike_exchange_compressed(NrnThread* nt) {
386 assert(nout < 0x10000);
387 spikeout_fixed[1] = (
unsigned char) (nout & 0xff);
388 spikeout_fixed[0] = (
unsigned char) (nout >> 8);
404 tbuf_[itbuf_++] = (
unsigned long) nout;
405 tbuf_[itbuf_++] = (
unsigned long) n;
421 int nn = nrnmpi_nin_[
i];
424 if (nn > ag_send_nspike) {
425 idxov += (nn - ag_send_nspike) * (1 + localgid_size_);
429 std::map<int, InputPreSyn*> gps = localmaps[
i];
430 if (nn > ag_send_nspike) {
431 nnn = ag_send_nspike;
435 int idx = 2 +
i * ag_send_size;
436 for (j = 0; j < nnn; ++j) {
438 double firetime = spikein_fixed[idx++] *
dt + t_exchange_;
439 int lgid = (int) spikein_fixed[idx];
440 idx += localgid_size_;
441 auto gid2in_it = gps.find(lgid);
442 if (gid2in_it != gps.end()) {
443 InputPreSyn* ps = gid2in_it->second;
447 for (; j < nn; ++j) {
448 double firetime = spfixin_ovfl_[idxov++] *
dt + t_exchange_;
449 int lgid = (int) spfixin_ovfl_[idxov];
450 idxov += localgid_size_;
451 auto gid2in_it = gps.find(lgid);
452 if (gid2in_it != gps.end()) {
453 InputPreSyn* ps = gid2in_it->second;
461 int nn = nrnmpi_nin_[
i];
462 if (nn > ag_send_nspike) {
465 int idx = 2 +
i * ag_send_size;
466 for (
int j = 0; j < nn; ++j) {
468 double firetime = spikein_fixed[idx++] *
dt + t_exchange_;
469 int gid = spupk(spikein_fixed + idx);
470 idx += localgid_size_;
471 auto gid2in_it =
gid2in.find(gid);
472 if (gid2in_it !=
gid2in.end()) {
473 InputPreSyn* ps = gid2in_it->second;
480 for (
int i = 0;
i < n; ++
i) {
481 double firetime = spfixin_ovfl_[idx++] *
dt + t_exchange_;
482 int gid = spupk(spfixin_ovfl_ + idx);
483 idx += localgid_size_;
484 auto gid2in_it =
gid2in.find(gid);
485 if (gid2in_it !=
gid2in.end()) {
486 InputPreSyn* ps = gid2in_it->second;
501 static void mk_localgid_rep() {
505 for (
const auto& gid2out_elem:
gid2out) {
506 if (gid2out_elem.second->output_index_ >= 0) {
516 localgid_size_ =
sizeof(
unsigned char);
521 int* sbuf =
new int[ngidmax + 1];
527 for (
const auto& gid2out_elem:
gid2out) {
528 if (gid2out_elem.second->output_index_ >= 0) {
529 gid2out_elem.second->localgid_ = (
unsigned char) ngid;
530 sbuf[ngid] = gid2out_elem.second->output_index_;
550 sbuf = rbuf +
i * (ngidmax + 1);
552 for (
int k = 0; k < ngid; ++k) {
553 auto gid2in_it =
gid2in.find(
int(sbuf[k]));
554 if (gid2in_it !=
gid2in.end()) {
555 localmaps[
i][k] = gid2in_it->second;
579 auto gid2in_it =
gid2in.find(gid);
580 if (gid2in_it !=
gid2in.end()) {
585 }
else if (fake_out) {
586 std::map<int, PreSyn*>::iterator gid2out_it;
587 gid2out_it =
gid2out.find(gid);
588 if (gid2out_it !=
gid2out.end()) {
589 PreSyn* ps = gid2out_it->second;
614 hoc_execerror(
"mindelay is 0",
"(or less than dt for fixed step method)");
639 printf(
"\nSolver Time : %g\n",
nrn_wtime() - time);
644 double mindelay = maxdelay;
654 std::map<PreSyn*, NrnThread*> presynmap;
673 if (!negsrcgid_tid.empty() && gid < -1) {
674 tid = negsrcgid_tid[i_tid++];
684 if (ps && presynmap[ps] == &nt) {
688 if (chk && nc->
delay_ < mindelay) {
698 if (mindelay /
dt > 255) {
757 if (xchng_meth > 0) {
765 if (spikeout_fixed) {
766 free(spikeout_fixed);
767 spikeout_fixed =
nullptr;
771 spikein_fixed =
nullptr;
775 spfixin_ovfl_ =
nullptr;
780 use_compress_ =
false;
782 }
else if (nspike > 0) {
783 use_compress_ =
true;
784 ag_send_nspike = nspike;
791 "Notice: gid compression did not succeed. Probably more than 255 cells on "
797 localgid_size_ =
sizeof(
unsigned int);
799 ag_send_size = 2 + ag_send_nspike * (1 + localgid_size_);
800 spfixout_capacity_ = ag_send_size + 50 * (1 + localgid_size_);
801 spikeout_fixed = (
unsigned char*)
emalloc(spfixout_capacity_);
804 spfixin_ovfl_ = (
unsigned char*)
emalloc(ovfl_capacity * (1 + localgid_size_));
806 return ag_send_nspike;