1 #include <../../nrnconf.h>
176 #include <nrnmpiuse.h>
180 #include <sys/stat.h>
181 #include <unordered_map>
182 #include <unordered_set>
219 extern void nrn_fake_fire(
int gid,
double firetime,
int fake_out);
238 for (
int i = 0;
i < scnt[0]; ++
i) {
248 for (
int i = 0;
i < scnt[0]; ++
i) {
256 for (
int i = 0;
i <
n; ++
i) {
261 for (
int i = 0;
i <
n[0]; ++
i) {
266 for (
int i = 0;
i <
n[0]; ++
i) {
273 extern bool use_bgpdma_;
283 extern bool nrn_use_compress_;
284 extern bool nrn_use_localgid_;
307 extern "C" void*
bbss_buffer_counts(
int* len,
int** gids,
int** sizes,
int* global_size);
338 extern "C" void bbss_save(
void*
bbss,
int gid,
char* buffer,
int sz);
346 extern "C" void bbss_restore(
void*
bbss,
int gid,
int npiece,
char* buffer,
int sz);
367 #define PDEBUG printf("%s\n", dbuf)
369 #define PDEBUG f->s(dbuf, 1)
382 virtual void i(
int&
j,
int chk = 0);
383 virtual void d(
int n,
double&
p);
384 virtual void d(
int n,
double*
p);
385 virtual void s(
char* cp,
int chk = 0);
411 ns += strlen(cp) + 1;
420 return ni *
sizeof(int) +
nd *
sizeof(
double) +
ns;
430 virtual void i(
int&
j,
int chk = 0);
431 virtual void d(
int n,
double&
p);
432 virtual void d(
int n,
double*
p);
433 virtual void s(
char* cp,
int chk = 0);
451 for (
int i = 0;
i <
n; ++
i) {
467 virtual void i(
int&
j,
int chk = 0);
468 virtual void d(
int n,
double&
p) {
471 virtual void d(
int n,
double*
p);
472 virtual void s(
char* cp,
int chk = 0);
476 virtual void skip(
int);
490 int rval = fscanf(
f,
"%d\n", &
k);
498 for (
int i = 0;
i <
n; ++
i) {
512 for (
int i = 0;
i <
n; ++
i) {
521 virtual void i(
int&
j,
int chk = 0);
522 virtual void d(
int n,
double&
p);
523 virtual void d(
int n,
double*
p);
524 virtual void s(
char* cp,
int chk = 0);
527 virtual void cpy(
int size,
char* cp);
539 cpy(
sizeof(
int), (
char*) (&
j));
542 cpy(
sizeof(
double), (
char*) (&
d));
545 cpy(
n *
sizeof(
double), (
char*)
d);
548 cpy(strlen(cp) + 1, cp);
558 for (
int ii = 0; ii < ns; ++ii) {
567 virtual void i(
int&
j,
int chk = 0);
568 virtual void s(
char* cp,
int chk = 0);
573 virtual void cpy(
int size,
char* cp);
580 cpy(
sizeof(
int), (
char*) (&
k));
590 cpy(strlen(
p) + 1, cp);
597 for (
int ii = 0; ii < ns; ++ii) {
630 nrn_use_compress_ =
false;
631 nrn_use_localgid_ =
false;
662 int len = ss->
counts(&gids, &sizes);
664 sizevec->resize(len);
665 for (
int i = 0;
i < len; ++
i) {
666 gidvec->elem(
i) = double(gids[
i]);
667 sizevec->elem(
i) = double(sizes[
i]);
677 printf(
"save_gid not implemented\n");
682 printf(
"restore_gid not implemented\n");
696 mkdir(
"bbss_out", 0770);
704 int len = ss->
counts(&gids, &sizes);
705 for (
int i = 0;
i < len; ++
i) {
721 int len, *gids, *sizes, global_size;
728 buf =
new char[global_size];
732 fwrite(
buf,
sizeof(
char), global_size, f);
738 fprintf(f,
"%d\n", global_size);
741 for (
int i = 0;
i < len; ++
i) {
742 buf =
new char[sizes[
i]];
746 fwrite(
buf,
sizeof(
char), sizes[
i], f);
773 (*pp_ignore_map)[pp] = 0;
800 *len = ss->
counts(gids, sizes);
832 for (
int i = 0;
i < ngroup; ++
i) {
929 int len = ss->
counts(&gids, &sizes);
930 for (
int i = 0;
i < len; ++
i) {
937 for (
int j = 0;
j < ngroup; ++
j) {
952 int len, *gids, *sizes, global_size, npiece, sz;
971 nrn_assert(fread(
buf,
sizeof(
char), global_size, f) == global_size);
978 for (
int i = 0;
i < len; ++
i) {
1078 if (
ssi[im].offset < 0) {
1117 typedef std::unordered_map<Point_process*, DEList*>
PP2DE;
1208 double t1 = int(tt /
dt + 0.5 + 1
e-10) *
dt;
1235 const auto& dl1iter =
pp2de->find(pp);
1236 if (dl1iter !=
pp2de->end()) {
1237 dl1 = dl1iter->second;
1238 sew =
new SEWrap(tq, dl1);
1279 cntinc = ps->
dil_.size();
1284 if (ps->
gid_ >= 0) {
1287 const auto& dliter =
src2send->find(srcid);
1289 dl = dliter->second;
1307 for (
i = 0;
i < dl->size();
i += 2) {
1308 double x =
fabs((*dl)[
i] - ts);
1316 dl->push_back(cntinc);
1317 }
else if (m > 1
e-12) {
1320 (*dl)[im + 1] += cntinc;
1325 dl->push_back(cntinc);
1326 (*src2send)[srcid] = dl;
1343 const auto& dbiter =
nc2dblist->find(nc);
1346 (*nc2dblist)[nc] = db;
1348 db = dbiter->second;
1350 db->push_back(tq->
t_);
1356 const auto& dbiter =
nc2dblist->find(nc);
1359 (*nc2dblist)[nc] = db;
1361 db = dbiter->second;
1363 db->push_back(tq->
t_);
1432 const auto& delistiter =
pp2de->find(pp);
1434 if (delistiter !=
pp2de->end()) {
1435 dl1 = delistiter->second;
1471 for (
const auto& dlpair: *
pp2de) {
1472 auto dl = dlpair.second;
1473 for (; dl; dl = dl1) {
1544 int base = spgid % 10000000;
1545 if (spgid == base || !
base2spgid->count(base)) {
1546 (*base2spgid)[base] = spgid;
1580 *
gids = (
int*) malloc(gidcnt *
sizeof(
int));
1581 *cnts = (
int*) malloc(gidcnt *
sizeof(
int));
1584 printf(
"Error : Memory allocation failure in BBSaveState\n");
1594 auto base = pair.first;
1595 auto spgid = pair.second;
1596 (*gids)[gidcnt] = base;
1597 c->ni =
c->nd =
c->ns =
c->nl = 0;
1603 (*cnts)[gidcnt] =
c->bytecnt();
1681 const auto& spgiditer =
base2spgid->find(basegid);
1683 spgid = spgiditer->second;
1769 size_t last_dot =
name.rfind(
".");
1770 assert(last_dot != std::string::npos);
1772 std::string basename =
name.substr(last_dot + 1);
1773 if (sn2s.find(basename) != sn2s.end()) {
1774 hoc_execerr_ext(
"Python Section name, %s, is not unique in the Python cell",
1777 sn2s[basename] =
sec;
1793 return search->second;
1833 for (qsec =
first; qsec != last; qsec = qsec->
next) {
1849 int i = (int) (n2s.size());
1851 for (
auto& iter: n2s) {
1852 const std::string&
name = iter.first;
1860 int indx =
sec->prop->dparam[5].i;
1879 std::unordered_set<std::string> snames;
1882 for (
i = 0;
i <
cnt; ++
i) {
1892 if (snames.find(
buf) != snames.end()) {
1897 snames.emplace(
buf);
1898 auto search = (*n2s).find(
buf);
1899 if (search != (*n2s).end()) {
1900 sec = search->second;
1931 int indx =
sec->prop->dparam[5].i;
1939 sprintf(
dbuf,
"Enter section(%s)",
sec->prop->dparam[0].sym->name);
1944 sprintf(
dbuf,
"Leave section(%s)",
sec->prop->dparam[0].sym->name);
1951 sprintf(
dbuf,
"Enter sectionsize(%s)",
sec->prop->dparam[0].sym->name);
1965 sprintf(
dbuf,
"Leave sectionsize(%s)",
sec->prop->dparam[0].sym->name);
1973 sprintf(
dbuf,
"Enter seccontents(%s)",
sec->prop->dparam[0].sym->name);
1980 nseg =
sec->nnode - 1;
1982 for (
i = 0;
i < nseg; ++
i) {
1988 sprintf(
dbuf,
"Leave seccontents(%s)",
sec->prop->dparam[0].sym->name);
2006 for (
i = 0,
p = nd->
prop;
p;
p =
p->next) {
2018 for (
p = nd->
prop;
p;
p =
p->next) {
2042 for (
i = 0,
p = nd->
prop;
p;
p =
p->next) {
2053 for (
p = nd->
prop;
p;
p =
p->next) {
2097 double* xval =
NULL;
2109 xval =
new double[sz];
2152 const auto& dliter =
pp2de->find(pp);
2153 if (dliter ==
pp2de->end()) {
2156 dl = dliter->second;
2174 const auto& dbiter =
nc2dblist->find(nc);
2176 db = dbiter->second;
2179 for (
int i = 0;
i <
j; ++
i) {
2180 double x = (*db)[
i];
2202 for (
int i = 0;
i <
j; ++
i) {
2243 for (
int i = 0;
i <
cnt; ++
i) {
2245 double flag, tt, *w;
2251 void** movable =
NULL;
2267 if (ncindex == -1) {
2271 for (
j = 0, dl1 = dliter->second; j < ncindex; ++j, dl1 = dl1->
next) {
2295 int*
c =
new int[np];
2297 for (
i = 0;
i < np; ++
i) {
2299 rdispl[
i + 1] = rdispl[
i] +
c[
i];
2304 for (
i = 0;
i < np; ++
i) {
2305 rdispl[
i + 1] = rdispl[
i] + rcnt[
i];
2312 int* rcnt =
new int[np];
2313 int* rdispl =
new int[np + 1];
2337 int* rcnt =
new int[np];
2338 int* rdispl =
new int[np + 1];
2344 tsdest =
new double[size];
2381 for (
const auto& pair: *
src2send) {
2382 ndsrctotal += pair.second->size();
2384 tssrc =
new double[ndsrctotal];
2395 for (
const auto& pair: *
src2send) {
2396 int gid = pair.first;
2399 dcnts[host] += pair.second->size();
2405 off[
i + 1] = off[
i] + cnts[
i];
2406 doff[
i + 1] = doff[
i] + dcnts[
i];
2413 for (
const auto& pair: *
src2send) {
2414 const auto dl = pair.second;
2415 int gid = pair.first;
2417 gidsrc[off[host] + cnts[host]] = gid;
2418 ndsrc[off[host] + cnts[host]++] = int(dl->size());
2419 for (
size_t i = 0;
i < dl->size(); ++
i) {
2420 tssrc[doff[host] + dcnts[host]++] = (*dl)[
i];
2423 for (
const auto& pair: *
src2send) {
2452 rdspl[
i + 1] = rdspl[
i] + rcnt[
i];
2464 int i, rsize, *rg =
NULL, *rtscnts =
NULL;
2473 rg =
new int[rsize];
2474 rtscnts =
new int[rsize];
2492 for (
i = 0;
i < rsize; ++
i) {
2495 dl->reserve(rtscnts[
i]);
2497 for (
int j = 0;
j < rtscnts[
i]; ++
j) {
2498 dl->push_back(rts[tsoff +
j]);
2501 tsoff += rtscnts[
i];
2528 std::unique_ptr<Int2DblList> m{
new Int2DblList()};
2529 m->reserve(
cnt + 1);
2533 for (
i = 0;
i <
cnt; ++
i) {
2536 const auto& dliter = m->find(gid);
2537 if (dliter != m->end()) {
2538 dl = dliter->second;
2547 for (
int k = 0;
k < tscnt;
k += 2) {
2548 double t1 =
tsdest[its++];
2549 int inccnt =
tsdest[its++];
2554 for (
int j = 0;
j < dl->size();
j += 2) {
2555 double dt =
fabs((*dl)[
j] - t1);
2557 (*dl)[
j + 1] += inccnt;
2560 }
else if (
dt < .1) {
2566 dl->push_back(inccnt);
2593 gidsrc =
new int[mcnt];
2594 tssrc_cnt =
new int[mcnt];
2595 tssrc =
new double[mdcnt];
2599 for (
const auto& pair: *m) {
2600 auto dl = pair.second;
2601 gidsrc[mcnt] = pair.first;
2602 tssrc_cnt[mcnt] = dl->size();
2603 for (
int i = 0;
i < dl->size(); ++
i) {
2604 tssrc[mdcnt++] = (*dl)[
i];
2660 i = (ps->
ssrc_ != 0 ? 1 : -1);
2664 if (output_index >= 0 &&
i == 1) {
2667 int j = (ps->
flag_ ? 1 : 0);
2689 dl = dliter->second;
2693 for (
i = 0;
i < dl->size();
i += 2) {
2696 int unc = (*dl)[
i + 1];
2738 (*queuecheck_gid2unc)[
i] = dl;
2740 for (
int j = 0;
j <
cnt;
j += 2) {
2765 for (
int j = 0;
j <
cnt;
j += 2) {
2783 auto gid = pair.first;
2784 auto dl = pair.second;
2788 dl2 = dl2iter->second;
2789 if (dl->size() == dl2->size()) {
2790 for (
int i = 0;
i < dl->size();
i += 2) {
2791 if ((
fabs((*dl)[
i] - (*dl2)[
i]) > 1
e-12) || (*dl)[
i + 1] != (*dl2)[
i + 1]) {
2793 "error: gid=%d expect t=%g %d but queue contains t=%g %d "
2800 (*dl)[
i] - (*dl2)[
i]);
2804 printf(
"error: gid=%d distinct delivery times, expect %ld, actual %ld\n",
2810 printf(
"error: gid=%d expect spikes but none on queue\n", gid);
2811 for (
int i = 0;
i < dl->size() - 1;
i += 2) {
2812 printf(
" %g %d", (*dl)[
i],
int((*dl)[
i + 1]));
2818 auto gid = pair.first;
2819 auto dl2 = pair.second;
2823 dl = dliter->second;
2824 printf(
"error: gid=%d expect no spikes but some on queue\n", gid);
2825 for (
int i = 0;
i < int(dl2->size()) - 1;
i += 2) {
2826 printf(
" %g %d", (*dl)[
i],
int((*dl)[
i + 1]));
void nrn_netcon_event(NetCon *, double)
static StateStructInfo * ssi
static void nrnmpi_int_alltoallv(int *s, int *scnt, int *sdispl, int *r, int *rcnt, int *rdispl)
std::unordered_map< std::string, Section * > SecName2Sec
static void scatteritems()
short * nrn_is_artificial_
Point_process * ob2pntproc(Object *)
void(* nrn_binq_enqueue_error_handler)(double, TQItem *)
void nrn_gidout_iter(PFIO)
std::vector< TQItem * > TQItemList
static double binq_time(double tt)
std::vector< SEWrap * > SEWrapList
static std::unique_ptr< PP2DE > pp2de
static std::unordered_map< void *, SecName2Sec > pycell_name2sec_maps
static TQItemList * tq_removal_list
static std::unique_ptr< NetCon2DblList > nc2dblist
static double vector_play_init(void *v)
static SecName2Sec & pycell_name2sec_map(Object *c)
static void bbss_queuecheck()
int nrn_gid_exists(int gid)
static void nrn_spike_exchange(NrnThread *)
std::unordered_map< NetCon *, DblList * > NetCon2DblList
ReceiveFunc * pnt_receive
Object * nrn_gid2obj(int gid)
static void all2allv_int2(int *scnt, int *sdispl, int *gidsrc, int *ndsrc)
PlayRecList * net_cvode_instance_prl()
static void pycell_name2sec_maps_fill()
static Member_func members[]
static std::unique_ptr< Int2DblList > queuecheck_gid2unc
static void * cons(Object *)
static void allgatherv_helper(int cnt, int *rcnt, int *rdspl)
static void all2allv_dbl1(int *scnt, int *sdispl, double *tssrc)
static bool use_spikecompress_
static BBSaveState * bbss
static void spikes_on_correct_host(int cnt, int *g, int *dcnts, int tscnt, double *ts, Int2DblList *m)
std::unordered_map< int, DblList * > Int2DblList
static void pycell_name2sec_maps_clear()
static void destruct(void *v)
cTemplate ** nrn_pnt_template_
static void bbss_remove_delivered()
void(* ReceiveFunc)(Point_process *, double *, double)
static double save_gid(void *v)
static int ignored(Prop *p)
static double ppignore(void *v)
static void nrnmpi_dbl_alltoallv(double *s, int *scnt, int *sdispl, double *r, int *rcnt, int *rdispl)
static double restore_gid(void *v)
static double restore_test_bin(void *v)
static void base2spgid_item(int spgid, Object *obj)
void net_send(void **, double *, Point_process *, double, double)
static std::unique_ptr< Int2DblList > src2send
PreSyn * nrn_gid2presyn(int gid)
hoc_Item * net_cvode_instance_psl()
std::unordered_map< int, int > Int2Int
std::vector< double > DblList
static void bbss_restore_begin()
static void nrnmpi_dbl_allgatherv(double *s, double *r, int *n, int *dspl)
void(* PFIO)(int, Object *)
Section * nrn_section_exists(char *name, int index, Object *cell)
static void tqcallback(const TQItem *tq, int i)
static double save(void *v)
static void nrnmpi_int_allgather(int *s, int *r, int n)
static double restore_test(void *v)
static double save_test_bin(void *v)
static std::unique_ptr< Int2Int > base2spgid
void nrn_fake_fire(int gid, double firetime, int fake_out)
static std::unique_ptr< Int2DblList > presyn_queue
std::unordered_map< Point_process *, DEList * > PP2DE
static bool use_gidcompress_
TQueue * net_cvode_instance_event_queue(NrnThread *)
NetCvode * net_cvode_instance
static void del_presyn_info()
static void all2allv_helper(int *scnt, int *sdispl, int *rcnt, int *rdispl)
static void construct_presyn_queue()
static double save_request(void *v)
static std::unique_ptr< PointProcessMap > pp_ignore_map
Symlist * hoc_built_in_symlist
static void nrnmpi_barrier()
static double save_test(void *v)
static TQItemList * tq_presyn_fanout
static void cb_gidobj(int gid, Object *obj)
static void nrnmpi_int_allgatherv(int *s, int *r, int *n, int *dspl)
static void bbss_early(double td, TQItem *tq)
static double restore(void *v)
std::unordered_map< Point_process *, int > PointProcessMap
static int nrnmpi_int_allmax(int x)
static SEWrapList * sewrap_list
const char * secname(Section *sec)
virtual void s(char *cp, int chk=0)
virtual void cpy(int size, char *cp)
virtual void i(int &j, int chk=0)
BBSS_BufferIn(char *buffer, int size)
virtual void d(int n, double &p)
virtual void i(int &j, int chk=0)
virtual void cpy(int size, char *cp)
virtual ~BBSS_BufferOut()
virtual void s(char *cp, int chk=0)
BBSS_BufferOut(char *buffer, int size)
virtual void d(int n, double &p)
virtual void i(int &j, int chk=0)
virtual void s(char *cp, int chk=0)
virtual void d(int n, double &p)=0
virtual void s(char *cp, int chk=0)=0
virtual void i(int &j, int chk=0)=0
BBSS_TxtFileIn(const char *)
virtual ~BBSS_TxtFileIn()
virtual void s(char *cp, int chk=0)
virtual void d(int n, double &p)
virtual void i(int &j, int chk=0)
virtual void i(int &j, int chk=0)
virtual ~BBSS_TxtFileOut()
BBSS_TxtFileOut(const char *)
virtual void s(char *cp, int chk=0)
virtual void d(int n, double &p)
virtual void apply(BBSS_IO *io)
void node01(Section *, Node *)
void possible_presyn(int gid)
void gid2buffer(int gid, char *buffer, int size)
void netrecv_pp(Point_process *)
void section_exist_info(Section *)
int sectionsize(Section *)
void buffer2gid(int gid, char *buffer, int size)
void seccontents(Section *)
int counts(int **gids, int **counts)
virtual void pr(const char *, double t, NetCvode *)
virtual void savestate_restore(double deliverytime, NetCvode *)
int prop_index(const Symbol *) const
int var_type(Symbol *) const
void fanout(double, NetCvode *, NrnThread *)
SEWrap(const TQItem *, DEList *)
void forall_callback(void(*)(const TQItem *, int))
Symbol * hoc_table_lookup(const char *, Symlist *)
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)
void bbss_restore_global(void *bbss, char *buffer, int sz)
void * nrn_opaque_obj2pyobj(Object *ho)
void hoc_execerr_ext(const char *fmt,...)
printf style specification of hoc_execerror message.
void bbss_restore(void *bbss, int gid, int npiece, char *buffer, int sz)
size_t hoc_total_array_data(Symbol *s, Objectdata *obd)
void hoc_pushpx(double *d)
void hoc_call_ob_proc(Object *ob, Symbol *sym, int narg)
void bbss_restore_done(void *bbss)
void bbss_save(void *bbss, int gid, char *buffer, int sz)
char * hoc_object_name(Object *ob)
void bbss_save_done(void *bbss)
void * bbss_buffer_counts(int *len, int **gids, int **sizes, int *global_size)
Symbol * hoc_lookup(const char *)
void bbss_save_global(void *bbss, char *buffer, int sz)
void hoc_obj_unref(Object *obj)
Object ** hoc_objgetarg(int)
#define ITERATE(itm, lst)
Object * nrn_sec2cell(Section *)
int is_point_process(Object *)
int const size_t const size_t n
void nrnmpi_abort(int errcode)
double nrn_call_mech_func(Symbol *s, int narg, Prop *p, int type)
void class2oc(const char *, void *(*cons)(Object *), void(*destruct)(void *), Member_func *, int(*checkpoint)(void **), Member_ret_obj_func *, Member_ret_str_func *)
static philox4x32_key_t k
static double ref(void *v)
static double cell(void *v)
Represent main neuron object computed by single thread.
HocStruct hoc_Item * secelm_
HocStruct cTemplate * ctemplate
static const char * fname(const char *name)