Skip to content
This repository was archived by the owner on Mar 20, 2023. It is now read-only.

Commit bd747a8

Browse files
If a netcon_srcgid is negative, need to determine the thread. (#390)
* If a netcon_srcgid is negative, need to determine the thread. Only for direct transfer mode is it allowed that a negative srcgid is not in the same thread as the NetCon target. To enable thread determination an std::vector<int> involving the name netcon_negsrcgid_tid is associated with netcon_srcgid in that when a negative gid appears in netcon_srcgid, the tid is the value of the element in netcon_negsrcgid_tid. * always resize netcon_negsrcgid_tid * link netcon_negsrcgid_tid usage to corenrn_embedded * nrnthreads_netcon_srcgid is more meaninfgul name. * Revert "link netcon_negsrcgid_tid usage to corenrn_embedded" Comments indicate that nrnthreads_netcon_negsrc_gid_tid subvectors are definitely empty when single thread or file transfer. (will be empty anyway if there are no negative gids) This reverts commit c870bf3. Co-authored-by: Alexandru Savulescu <[email protected]>
1 parent 7af0c6e commit bd747a8

File tree

6 files changed

+67
-21
lines changed

6 files changed

+67
-21
lines changed

coreneuron/io/nrn2core_direct.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ extern int (*nrn2core_get_dat1_)(int tid,
3030
int& n_presyn,
3131
int& n_netcon,
3232
int*& output_gid,
33-
int*& netcon_srcgid);
33+
int*& netcon_srcgid,
34+
std::vector<int>& netcon_negsrcgid_tid);
3435

3536
extern int (*nrn2core_get_dat2_1_)(int tid,
3637
int& ngid,

coreneuron/io/nrn_setup.cpp

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,14 @@ void (*nrn2core_all_weights_return_)(std::vector<double*>& weights);
113113
// encode the thread number into the negative gid
114114
// (i.e -ith - nth*(type +1000*index)) failed due to not large enough
115115
// integer domain size.
116+
// Note that for file transfer it is an error if a negative srcgid is
117+
// not in the same thread as the target. This is because there it may
118+
// not be the case that threads in a NEURON process end up on same process
119+
// in CoreNEURON. NEURON will raise an error if this
120+
// is the case. However, for direct memory transfer, it is allowed that
121+
// a negative srcgid may be in a different thread than the target. So
122+
// nrn2core_get_dat1 has a last arg netcon_negsrcgid_tid that specifies
123+
// for the negative gids in netcon_srcgid (in that order) the source thread.
116124
//
117125
// <firstgid>_2.dat
118126
// n_output n_real_output, nnode
@@ -178,7 +186,11 @@ std::map<int, InputPreSyn*> gid2in;
178186
std::vector<NetCon*> netcon_in_presyn_order_;
179187

180188
/// Only for setup vector of netcon source gids
181-
std::vector<int*> netcon_srcgid;
189+
std::vector<int*> nrnthreads_netcon_srcgid;
190+
191+
/// If a nrnthreads_netcon_srcgid is negative, need to determine the thread when
192+
/// in order to use the correct neg_gid2out[tid] map
193+
std::vector<std::vector<int> > nrnthreads_netcon_negsrcgid_tid;
182194

183195
/* read files.dat file and distribute cellgroups to all mpi ranks */
184196
void nrn_read_filesdat(int& ngrp, int*& grp, const char* filesdat) {
@@ -275,8 +287,11 @@ void determine_inputpresyn() {
275287
NrnThread& nt = nrn_threads[ith];
276288
// associate gid with InputPreSyn and increase PreSyn and InputPreSyn count
277289
nt.n_input_presyn = 0;
290+
// if single thread or file transfer then definitely empty.
291+
std::vector<int>& negsrcgid_tid = nrnthreads_netcon_negsrcgid_tid[ith];
292+
size_t i_tid = 0;
278293
for (int i = 0; i < nt.n_netcon; ++i) {
279-
int gid = netcon_srcgid[ith][i];
294+
int gid = nrnthreads_netcon_srcgid[ith][i];
280295
if (gid >= 0) {
281296
/// If PreSyn or InputPreSyn is already in the map
282297
auto gid2out_it = gid2out.find(gid);
@@ -299,8 +314,12 @@ void determine_inputpresyn() {
299314
inputpresyn_.push_back(psi);
300315
++nt.n_input_presyn;
301316
} else {
302-
auto gid2out_it = neg_gid2out[nt.id].find(gid);
303-
if (gid2out_it != neg_gid2out[nt.id].end()) {
317+
int tid = nt.id;
318+
if (!negsrcgid_tid.empty()) {
319+
tid = negsrcgid_tid[i_tid++];
320+
}
321+
auto gid2out_it = neg_gid2out[tid].find(gid);
322+
if (gid2out_it != neg_gid2out[tid].end()) {
304323
/// Increase negative PreSyn count
305324
++gid2out_it->second->nc_cnt_;
306325
}
@@ -361,16 +380,23 @@ void determine_inputpresyn() {
361380

362381
// fill the netcon_in_presyn_order and recompute nc_cnt_
363382
// note that not all netcon_in_presyn will be filled if there are netcon
364-
// with no presyn (ie. netcon_srcgid[nt.id][i] = -1) but that is ok since they are
383+
// with no presyn (ie. nrnthreads_netcon_srcgid[nt.id][i] = -1) but that is ok since they are
365384
// only used via ps.nc_index_ and ps.nc_cnt_;
366385
for (int ith = 0; ith < nrn_nthread; ++ith) {
367386
NrnThread& nt = nrn_threads[ith];
387+
// if single thread or file transfer then definitely empty.
388+
std::vector<int>& negsrcgid_tid = nrnthreads_netcon_negsrcgid_tid[ith];
389+
size_t i_tid = 0;
368390
for (int i = 0; i < nt.n_netcon; ++i) {
369391
NetCon* nc = nt.netcons + i;
370-
int gid = netcon_srcgid[ith][i];
392+
int gid = nrnthreads_netcon_srcgid[ith][i];
393+
int tid = ith;
394+
if (!negsrcgid_tid.empty() && gid < -1) {
395+
tid = negsrcgid_tid[i_tid++];
396+
}
371397
PreSyn* ps;
372398
InputPreSyn* psi;
373-
netpar_tid_gid2ps(ith, gid, &ps, &psi);
399+
netpar_tid_gid2ps(tid, gid, &ps, &psi);
374400
if (ps) {
375401
netcon_in_presyn_order_[ps->nc_index_ + ps->nc_cnt_] = nc;
376402
++ps->nc_cnt_;
@@ -390,10 +416,11 @@ void determine_inputpresyn() {
390416
/// Clean up
391417
void nrn_setup_cleanup() {
392418
for (int ith = 0; ith < nrn_nthread; ++ith) {
393-
if (netcon_srcgid[ith])
394-
delete[] netcon_srcgid[ith];
419+
if (nrnthreads_netcon_srcgid[ith])
420+
delete[] nrnthreads_netcon_srcgid[ith];
395421
}
396-
netcon_srcgid.clear();
422+
nrnthreads_netcon_srcgid.clear();
423+
nrnthreads_netcon_negsrcgid_tid.clear();
397424
neg_gid2out.clear();
398425
}
399426

@@ -448,9 +475,9 @@ void nrn_setup(const char* filesdat,
448475
/// std::map<int, PreSyn*> gid2out;
449476
gid2out.clear();
450477

451-
netcon_srcgid.resize(nrn_nthread);
478+
nrnthreads_netcon_srcgid.resize(nrn_nthread);
452479
for (int i = 0; i < nrn_nthread; ++i)
453-
netcon_srcgid[i] = nullptr;
480+
nrnthreads_netcon_srcgid[i] = nullptr;
454481

455482
// gap junctions
456483
if (nrn_have_gaps) {
@@ -469,6 +496,7 @@ void nrn_setup(const char* filesdat,
469496
nrn_partrans::gap_mpi_setup(userParams.ngroup);
470497
}
471498

499+
nrnthreads_netcon_negsrcgid_tid.resize(nrn_nthread);
472500
if (!corenrn_embedded) {
473501
coreneuron::phase_wrapper<coreneuron::phase::one>(userParams);
474502
} else {
@@ -480,7 +508,7 @@ void nrn_setup(const char* filesdat,
480508
});
481509
}
482510

483-
// from the gid2out map and the netcon_srcgid array,
511+
// from the gid2out map and the nrnthreads_netcon_srcgid array,
484512
// fill the gid2in, and from the number of entries,
485513
// allocate the process wide InputPreSyn array
486514
determine_inputpresyn();

coreneuron/io/phase1.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ int (*nrn2core_get_dat1_)(int tid,
1010
int& n_presyn,
1111
int& n_netcon,
1212
int*& output_gid,
13-
int*& netcon_srcgid);
13+
int*& netcon_srcgid,
14+
std::vector<int>& netcon_negsrcgid_tid);
1415

1516
namespace coreneuron {
1617
void Phase1::read_file(FileHandler& F) {
@@ -20,6 +21,8 @@ void Phase1::read_file(FileHandler& F) {
2021

2122
this->output_gids = F.read_vector<int>(n_presyn);
2223
this->netcon_srcgids = F.read_vector<int>(n_netcon);
24+
// For file mode transfer, it is not allowed that negative gids exist
25+
// in different threads. So this->netcon_tids remains clear.
2326

2427
F.close();
2528
}
@@ -32,7 +35,7 @@ void Phase1::read_direct(int thread_id) {
3235

3336
// TODO : check error codes for NEURON - CoreNEURON communication
3437
int valid =
35-
(*nrn2core_get_dat1_)(thread_id, n_presyn, n_netcon, output_gids, netcon_srcgid);
38+
(*nrn2core_get_dat1_)(thread_id, n_presyn, n_netcon, output_gids, netcon_srcgid, this->netcon_negsrcgid_tid);
3639
if (!valid) {
3740
return;
3841
}
@@ -47,9 +50,12 @@ void Phase1::populate(NrnThread& nt, OMP_Mutex& mut) {
4750
nt.n_presyn = this->output_gids.size();
4851
nt.n_netcon = this->netcon_srcgids.size();
4952

50-
netcon_srcgid[nt.id] = new int[nt.n_netcon];
53+
nrnthreads_netcon_srcgid[nt.id] = new int[nt.n_netcon];
5154
std::copy(this->netcon_srcgids.begin(), this->netcon_srcgids.end(),
52-
netcon_srcgid[nt.id]);
55+
nrnthreads_netcon_srcgid[nt.id]);
56+
57+
// netcon_negsrcgid_tid is empty if file transfer or single thread
58+
coreneuron::nrnthreads_netcon_negsrcgid_tid[nt.id] = this->netcon_negsrcgid_tid;
5359

5460
nt.netcons = new NetCon[nt.n_netcon];
5561
nt.presyns_helper = (PreSynHelper*)ecalloc_align(nt.n_presyn, sizeof(PreSynHelper));

coreneuron/io/phase1.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class Phase1 {
1818
private:
1919
std::vector<int> output_gids;
2020
std::vector<int> netcon_srcgids;
21+
std::vector<int> netcon_negsrcgid_tid; // entries only for negative srcgids
2122
};
2223

2324
} // namespace coreneuron

coreneuron/network/netpar.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,10 +641,17 @@ double set_mindelay(double maxdelay) {
641641

642642
for (int ith = 0; ith < nrn_nthread; ++ith) {
643643
NrnThread& nt = nrn_threads[ith];
644+
// if single thread or file transfer then definitely empty.
645+
std::vector<int>& negsrcgid_tid = nrnthreads_netcon_negsrcgid_tid[ith];
646+
size_t i_tid = 0;
644647
for (int i = 0; i < nt.n_netcon; ++i) {
645648
NetCon* nc = nt.netcons + i;
646649
bool chk = false; // ignore nc.delay_
647-
int gid = netcon_srcgid[ith][i];
650+
int gid = nrnthreads_netcon_srcgid[ith][i];
651+
int tid = ith;
652+
if (!negsrcgid_tid.empty() && gid < -1) {
653+
tid = negsrcgid_tid[i_tid++];
654+
}
648655
PreSyn* ps;
649656
InputPreSyn* psi;
650657
netpar_tid_gid2ps(ith, gid, &ps, &psi);

coreneuron/nrniv/nrniv_decl.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,11 @@ extern std::map<int, InputPreSyn*> gid2in;
4848

4949
/// InputPreSyn.nc_index_ to + InputPreSyn.nc_cnt_ give the NetCon*
5050
extern std::vector<NetCon*> netcon_in_presyn_order_;
51-
/// Only for setup vector of netcon source gids
52-
extern std::vector<int*> netcon_srcgid;
51+
/// Only for setup vector of netcon source gids and mindelay determination
52+
extern std::vector<int*> nrnthreads_netcon_srcgid;
53+
/// Companion to nrnthreads_netcon_srcgid when src gid is negative to allow
54+
/// determination of the NrnThread of the source PreSyn.
55+
extern std::vector<std::vector<int> > nrnthreads_netcon_negsrcgid_tid;
5356

5457
extern void mk_mech(const char* path);
5558
extern void set_globals(const char* path, bool cli_global_seed, int cli_global_seed_value);

0 commit comments

Comments
 (0)