2 #include <unordered_map>
15 #include "nrnran123.h"
39 #if defined(HAVE_DLFCN_H)
43 fprintf(stderr,
"Could not get symbol %s from CoreNEURON\n",
cnbs[
i].
name);
46 void**
c = (
void**) sym;
67 int n_vars = ml.get_num_variables();
69 for (
size_t i = 0;
i < n_vars; ++
i) {
83 if (strcmp(
name,
"secondorder") == 0) {
85 }
else if (strcmp(
name,
"Random123_global_index") == 0) {
98 for (; sp; sp = sp->
next) {
105 val =
new double[size];
106 for (
int i = 0;
i < a->
sub[0]; ++
i) {
115 val[0] = *sp->
u.
pval;
143 for (
int i = 0;
i < nc->
cnt_; ++
i) {
175 }
else if (
type == 0) {
179 auto set_mdata = [&mdata](
Memb_list* ml) ->
size_t {
181 return ml->nodecount;
218 std::vector<int>& output_gid,
220 std::vector<int>& netcon_negsrcgid_tid) {
241 nsec =
c->num_sections();
242 nseg =
c->num_segments();
243 n_seclist =
c->size();
248 std::string& sclname,
251 size_t& total_lfp_factors,
253 std::vector<int>& data_sec,
254 std::vector<int>& data_seg,
255 std::vector<double>& data_lfp) {
261 total_lfp_factors =
s->seglfp_factors.size();
262 n_electrodes =
s->num_electrodes;
263 data_sec =
s->sections;
264 data_seg =
s->segments;
265 data_lfp =
s->seglfp_factors;
295 int vdata_offset = 0;
296 tml_index =
new int[nmech];
297 ml_nodecount =
new int[nmech];
299 for (
size_t j = 0;
j < mla.size(); ++
j) {
300 int type = mla[
j].first;
307 if (ds[psz] == -4 || ds[psz] == -6 || ds[psz] == -7 || ds[psz] == -11 || ds[psz] == 0) {
314 nvdata = vdata_offset;
326 int*& v_parent_index,
358 diamvec =
new double[nt.
end];
360 for (
int i = 0;
i < nt.
end; ++
i) {
381 std::vector<uint32_t>& nmodlrandom,
382 std::vector<int>& pointer2type) {
389 int type = mlai.first;
392 bool copy =
data ? true :
false;
397 int n_vars = ml->get_num_variables();
404 data =
new double[
n * sz];
406 for (
auto instance = 0,
k = 0; instance <
n; ++instance) {
407 for (
int variable = 0; variable < n_vars; ++variable) {
409 for (
int array_index = 0; array_index < array_dim; ++array_index) {
410 data[
k++] = ml->
data(instance, variable, array_index);
423 for (
int i = 0;
i <
n; ++
i) {
435 for (
int i = 0;
i < nn; ++
i) {
452 nmodlrandom.reserve(1 + indices.size() + 5 *
n * indices.size());
453 nmodlrandom.push_back(indices.size());
454 for (
int ix: indices) {
455 nmodlrandom.push_back((uint32_t) ix);
457 for (
int ix: indices) {
460 for (
int i = 0;
i <
n; ++
i) {
461 auto& datum = ml->
pdata[
i][ix];
465 data[4] = uint32_t(which);
467 nmodlrandom.push_back(
j);
478 double*& output_threshold,
479 int*& netcon_pnttype,
480 int*& netcon_pntindex,
488 output_vindex =
new int[cg.
n_presyn];
507 for (
int i = 0;
i <
n; ++
i) {
509 for (
int j = 0;
j < nc->
cnt_; ++
j) {
514 delays =
new double[
n];
515 for (
int i = 0;
i <
n; ++
i) {
530 for (
size_t i = 0;
i < mla.size(); ++
i) {
557 nullptr,
nullptr, &dcnt, &icnt, ml,
i, ml->
pdata[
i], ml->
_thread,
nullptr, &nt);
562 iArray =
new int[icnt];
565 dArray =
new double[dcnt];
571 dArray, iArray, &dcnt, &icnt, ml,
i, ml->
pdata[
i], ml->
_thread,
nullptr, &nt);
598 dArray, iArray, &dk, &ik, ml,
i, ml->
pdata[
i], ml->
_thread,
nullptr, &nt);
608 const std::vector<int>& indices,
609 const std::vector<double>& nmodlrandom) {
622 assert(nrnindices == indices);
626 for (
const auto ix: nrnindices) {
628 auto& datum = ml->
pdata[
i][ix];
642 std::vector<int>& pointer2type) {
649 for (
int j = 0;
j < sz; ++
j) {
653 const int seman = semantics[
j];
663 pointer2type.push_back(etype);
664 }
else if (etype == -1) {
671 }
else if (etype == -9) {
678 }
else if (etype == -2) {
680 }
else if (etype == -4) {
681 pdata[jj] = ml_vdata_offset + eindex;
683 }
else if (etype == -6) {
684 pdata[jj] = ml_vdata_offset + eindex;
686 }
else if (etype == -7) {
687 pdata[jj] = ml_vdata_offset + eindex;
689 }
else if (etype == -11) {
690 pdata[jj] = ml_vdata_offset + eindex;
746 if (vp->discon_indices_ ==
NULL) {
747 if (vp->ith_ == nt.
id) {
749 indices.push_back(
i);
782 if (!vp->discon_indices_) {
783 if (vp->ith_ == nt.
id) {
784 auto* pd =
static_cast<double*
>(vp->pd_);
793 if (legacy_index >= 0) {
805 last_index = vp->last_index_;
806 discon_index = vp->discon_index_;
807 ubound_index = vp->ubound_index_;
847 int triggered = wc->
flag_ ? 1 : 0;
903 std::unordered_map<
NetCon*, std::vector<size_t>>& netcon2intdata,
904 std::unordered_map<
PreSyn*, std::vector<size_t>>& presyn2intdata,
905 std::unordered_map<
double*, std::vector<size_t>>& weight2intdata) {
908 double tdeliver = tqi->
t_;
910 core_te->
td.push_back(tdeliver);
922 size_t iloc = core_te->
intdata.size();
923 core_te->
intdata.push_back(-1);
926 netcon2intdata[nc].push_back(iloc);
951 size_t iloc_wt = core_te->
intdata.size();
953 weight2intdata[wt].push_back(iloc_wt);
955 core_te->
intdata.push_back(-1);
961 bool const condition = movable && (*movable).
get<
TQItem*>() == tqi;
962 core_te->
intdata.push_back(condition);
973 bool skip = (ps->
nt_ && (ps->
nt_->
id != tid)) ? true :
false;
976 skip = (!ps->
nt_ && tid != 0) ?
true : skip;
979 core_te->
type.pop_back();
980 core_te->
td.pop_back();
1000 size_t iloc = core_te->
intdata.size();
1001 core_te->
intdata.push_back(-1);
1002 presyn2intdata[ps].push_back(iloc);
1014 core_te->
td.pop_back();
1015 core_te->
type.pop_back();
1019 "WARNING: CVode.event(...) for delivery at time step nearest %g discarded. "
1020 "CoreNEURON cannot presently handle interpreter events (rank %d, thread %d).\n",
1045 std::unordered_map<NetCon*, std::vector<size_t>> netcon2intdata;
1046 std::unordered_map<PreSyn*, std::vector<size_t>> presyn2intdata;
1047 std::unordered_map<double*, std::vector<size_t>> weight2intdata;
1061 set_info(tqi, tid, core_te, netcon2intdata, presyn2intdata, weight2intdata);
1067 set_info(tqi, tid, core_te, netcon2intdata, presyn2intdata, weight2intdata);
1074 for (
int i = 0;
i < cg.n_netcon; ++
i) {
1076 auto iter = netcon2intdata.find(nc);
1077 if (iter != netcon2intdata.end()) {
1078 for (
auto iloc: iter->second) {
1085 #define NRN_SENTINAL 100000000000
1086 for (
int i = 0;
i < cg.n_presyn; ++
i) {
1088 auto iter = presyn2intdata.find(ps);
1089 if (iter != presyn2intdata.end()) {
1092 for (
auto iloc: iter->second) {
1100 for (
auto& iter: presyn2intdata) {
1107 for (
int i = 0;
i < cg.n_netcon; ++
i) {
1110 auto iter = weight2intdata.find(wt);
1111 if (iter != weight2intdata.end()) {
1112 for (
auto iloc: iter->second) {
1171 auto*
const movable_arg = pnt->
prop->
dparam + movable_index;
1172 auto*
const old_movable_arg = (*movable_arg).
get<
TQItem*>();
1175 *movable_arg = old_movable_arg;
1207 double* weight =
NULL;
1226 if (presyns_flag_true.empty()) {
1237 if (presyns_flag_true.erase(index_v)) {
1239 if (presyns_flag_true.empty()) {
1260 if (ps->flag_ && ps->thvar_) {
1265 presyns_flag_true.insert(index_v);
1278 for (
size_t i = 0;
i < wi.size(); ++
i) {
1282 for (
auto watch_item: active_watch_items) {
1284 bool above_thresh = watch_item.second;
1293 wc->
flag_ = above_thresh ? 1 : 0;
1310 if (strcmp(
memb_func[
i].sym->name,
"PatternStim") == 0) {
1325 int& subworld_index,
1327 int& numprocs_subworld,
1328 int& numprocs_world) {
1330 nrnmpi_get_subworld_info(
1331 &
cnt, &subworld_index, &subworld_rank, &numprocs_subworld, &numprocs_world);
1334 subworld_index = -1;
1336 numprocs_subworld = 1;
std::vector< MlWithArtItem > MlWithArt
std::pair< int, Memb_list * > MlWithArtItem
TQItem * first()
Iterate in ascending bin order starting at current bin.
std::vector< NetCon * > netcons
std::vector< int > output_vindex
static void clean_deferred_netcons()
std::vector< int > output_gid
static void defer_clean_netcons(CellGroup *)
static int nrncore_pntindex_for_queue(Prop *p, int tid, int type)
static void clean_art(CellGroup *)
static std::vector< std::vector< NetCon * > > deferred_netcons
std::vector< int > netcon_negsrcgid_tid
std::vector< PreSyn * > output_ps
static Deferred_Type2ArtMl deferred_type2artml_
DatumIndices * datumindices
virtual void send(double sendtime, NetCvode *, NrnThread *)
std::vector< PlayRecord * > * fixed_play_
neuron::container::data_handle< double > thvar_
TQItem * atomic_dq(double til)
double(* c_)(Point_process *)
#define VecPlayContinuousType
#define PlayRecordEventType
DLFCN_NOINLINE DLFCN_EXPORT void * dlsym(void *handle, const char *name)
void nrnran123_getids3(nrnran123_State *s, std::uint32_t *id1, std::uint32_t *id2, std::uint32_t *id3)
void nrnran123_setseq(nrnran123_State *s, std::uint32_t seq, char which)
Set a Random123 sequence for a sequnece ID and which selector.
void nrnran123_getseq(nrnran123_State *s, std::uint32_t *seq, char *which)
Get sequence number and selector from an nrnran123_State object.
double * hoc_val_pointer(const char *s)
Symbol * hoc_lookup(const char *)
bool is_array(const Symbol &sym)
bool nrn_semantics_is_ion(int i)
bool nrn_semantics_is_ionstyle(int i)
#define ITERATE(itm, lst)
void move(Item *q1, Item *q2, Item *q3)
double * vector_vec(IvocVect *v)
bool nrn_use_bin_queue_
Flag to use the bin queue.
std::vector< int > & nrn_mech_random_indices(int type)
void hoc_execerror(const char *s1, const char *s2)
const char * bbcore_write_version
static void * emalloc(size_t size)
int vector_capacity(IvocVect *v)
uint32_t nrnran123_get_globalindex()
handle_interface< non_owning_identifier< storage > > handle
Non-owning handle to a Mechanism instance.
icycle< ncycle;++icycle) { int istride=stride[icycle];nrn_pragma_acc(loop vector) nrn_pragma_omp(loop bind(parallel)) for(int icore=0;icore< warpsize;++icore) { int i=ii+icore;if(icore< istride) { int ip=GPU_PARENT(i);GPU_RHS(i) -=GPU_B(i) *GPU_RHS(ip);GPU_RHS(i)/=GPU_D(i);} i+=istride;} ii+=istride;} }}void solve_interleaved2(int ith) { NrnThread *nt=nrn_threads+ith;InterleaveInfo &ii=interleave_info[ith];int nwarp=ii.nwarp;if(nwarp==0) return;int ncore=nwarp *warpsize;int *ncycles=ii.cellsize;int *stridedispl=ii.stridedispl;int *strides=ii.stride;int *rootbegin=ii.firstnode;int *nodebegin=ii.lastnode;if(0) { nrn_pragma_acc(parallel loop gang present(nt[0:1], strides[0:nstride], ncycles[0:nwarp], stridedispl[0:nwarp+1], rootbegin[0:nwarp+1], nodebegin[0:nwarp+1]) async(nt->stream_id)) nrn_pragma_omp(target teams loop map(present, alloc:nt[:1], strides[:nstride], ncycles[:nwarp], stridedispl[:nwarp+1], rootbegin[:nwarp+1], nodebegin[:nwarp+1])) for(int icore=0;icore< ncore;icore+=warpsize) { solve_interleaved2_loop_body(nt, icore, ncycles, strides, stridedispl, rootbegin, nodebegin);} nrn_pragma_acc(wait(nt->stream_id)) } else { for(int icore=0;icore< ncore;icore+=warpsize) { solve_interleaved2_loop_body(nt, icore, ncycles, strides, stridedispl, rootbegin, nodebegin);} }}void solve_interleaved1(int ith) { NrnThread *nt=nrn_threads+ith;int ncell=nt-> ncell
int Sprintf(char(&buf)[N], const char *fmt, Args &&... args)
Redirect sprintf to snprintf if the buffer size can be deduced.
#define DiscreteEventType
neuron::model_sorted_token nrn_ensure_model_data_are_sorted()
Ensure neuron::container::* data are sorted.
short * nrn_is_artificial_
int nrnthread_dat1(int tid, int &n_presyn, int &n_netcon, std::vector< int > &output_gid, int *&netcon_srcgid, std::vector< int > &netcon_negsrcgid_tid)
size_t nrnthreads_type_return(int type, int tid, double *&data, std::vector< double * > &mdata)
Return location for CoreNEURON to copy data into.
void nrn2core_transfer_WatchCondition(WatchCondition *wc, void(*cb)(int, int, int, int, int))
getting one item at a time from nrn2core_transfer_WATCH
void nrnthread_group_ids(int *grp)
NrnCoreTransferEvents * nrn2core_transfer_tqueue(int tid)
void nrnthread_dat3_cell_count(int &cell_count)
int nrnthread_dat2_corepointer_mech(int tid, int type, int &icnt, int &dcnt, int *&iArray, double *&dArray)
void core2nrn_NetCon_event(int tid, double td, size_t nc_index)
Called from CoreNEURON core2nrn_tqueue_item.
int nrnthread_dat2_3(int tid, int nweight, int *&output_vindex, double *&output_threshold, int *&netcon_pnttype, int *&netcon_pntindex, double *&weights, double *&delays)
static void core2nrn_SelfEvent_helper(int tid, double td, int tar_type, int tar_index, double flag, double *weight, int is_movable)
void map_coreneuron_callbacks(void *handle)
Populate function pointers by mapping function pointers for callback.
void nrnthread_dat3_cellmapping(int i, int &gid, int &nsec, int &nseg, int &n_seclist)
void * get_global_dbl_item(void *p, const char *&name, int &size, double *&val)
void nrn2core_PreSyn_flag(int tid, std::set< int > &presyns_flag_true)
static std::map< int, int > type2movable
int * datum2int(int type, Memb_list *ml, NrnThread &nt, CellGroup &cg, DatumIndices &di, int ml_vdata_offset, std::vector< int > &pointer2type)
void core2nrn_SelfEvent_event(int tid, double td, int tar_type, int tar_index, double flag, size_t nc_index, int is_movable)
int nrnthread_dat2_1(int tid, int &ncell, int &ngid, int &n_real_gid, int &nnode, int &ndiam, int &nmech, int *&tml_index, int *&ml_nodecount, int &nidata, int &nvdata, int &nweight)
int nrnthread_dat2_vecplay(int tid, std::vector< int > &indices)
void nrnthread_dat3_secmapping(int i_c, int i_sec, std::string &sclname, int &nsec, int &nseg, size_t &total_lfp_factors, int &n_electrodes, std::vector< int > &data_sec, std::vector< int > &data_seg, std::vector< double > &data_lfp)
void core2nrn_SelfEvent_event_noweight(int tid, double td, int tar_type, int tar_index, double flag, int is_movable)
void nrn2core_subworld_info(int &cnt, int &subworld_index, int &subworld_rank, int &numprocs_subworld, int &numprocs_world)
static void setup_type2semantics()
int nrnthread_dat2_vecplay_inst(int tid, int i, int &vptype, int &mtype, int &ix, int &sz, double *&yvec, double *&tvec, int &last_index, int &discon_index, int &ubound_index)
void core2nrn_vecplay_events()
start the vecplay events
int core2nrn_nmodlrandom(int tid, int type, const std::vector< int > &indices, const std::vector< double > &nmodlrandom)
void core2nrn_PreSyn_flag(int tid, std::set< int > presyns_flag_true)
void write_memb_mech_types_direct(std::ostream &s)
void nrnthreads_all_weights_return(std::vector< double * > &weights)
Copy weights from all coreneuron::NrnThread to NetCon instances.
void * nrn_patternstim_info_ref(Datum *)
int get_global_int_item(const char *name)
int nrnthread_dat2_corepointer(int tid, int &n)
void core2nrn_watch_activate(int tid, int type, int watch_begin, Core2NrnWatchInfo &wi)
void core2nrn_vecplay(int tid, int i, int last_index, int discon_index, int ubound_index)
getting one item at a time from CoreNEURON
int nrnthread_dat2_2(int tid, int *&v_parent_index, double *&a, double *&b, double *&area, double *&v, double *&diamvec)
bbcore_write_t * nrn_bbcore_write_
int core2nrn_corepointer_mech(int tid, int type, int icnt, int dcnt, int *iArray, double *dArray)
static int patternstim_type
TQueue * net_cvode_instance_event_queue(NrnThread *)
NetCvode * net_cvode_instance
int nrnthread_dat2_mech(int tid, size_t i, int dsz_inst, int *&nodeindices, double *&data, int *&pdata, std::vector< uint32_t > &nmodlrandom, std::vector< int > &pointer2type)
void nrn2core_patternstim(void **info)
bbcore_write_t * nrn_bbcore_read_
double nrn_ion_charge(Symbol *)
void * nrn_interthread_enqueue(NrnThread *)
void core2nrn_clear_queues(double time)
Initialize queues before transfer Probably aleady clear, but if binq then must be initialized to time...
NrnMappingInfo mapinfo
mapping information
static void set_info(TQItem *tqi, int tid, NrnCoreTransferEvents *core_te, std::unordered_map< NetCon *, std::vector< size_t >> &netcon2intdata, std::unordered_map< PreSyn *, std::vector< size_t >> &presyn2intdata, std::unordered_map< double *, std::vector< size_t >> &weight2intdata)
static core2nrn_callback_t cnbs[]
std::vector< Core2NrnWatchInfoItem > Core2NrnWatchInfo
std::vector< std::pair< int, bool > > Core2NrnWatchInfoItem
void(*)(double *, int *, int *, int *, Memb_list *, std::size_t, Datum *, Datum *, double *, NrnThread *) bbcore_write_t
int nrn_dblpntr2nrncore(neuron::container::data_handle< double > dh, NrnThread &nt, int &type, int &index)
void nrn_net_send(Datum *v, double *weight, Point_process *pnt, double td, double flag)
void _nrn_watch_activate(Datum *d, double(*c)(Point_process *), int i, Point_process *pnt, int r, double flag)
int const size_t const size_t n
int * nrn_prop_param_size_
std::vector< Memb_func > memb_func
NrnWatchAllocateFunc_t * nrn_watch_allocate_
std::vector< Memb_list > memb_list
std::unordered_map< int, void(*)(Prop *)> nrn_mech_inst_destruct
Symlist * hoc_built_in_symlist
Compartment mapping information for a cell.
A view into a set of mechanism instances.
std::ptrdiff_t legacy_index(double const *ptr) const
Calculate a legacy index of the given pointer in this mechanism data.
std::vector< double * > data()
Get a vector of double* representing the model data.
int get_array_dims(int variable) const
Get the array_dims of field variable.
std::vector< double > dbldata
std::vector< int > intdata
Compartment mapping information for NrnThread.
size_t size()
number of cells
std::vector< CellMapping * > mapping
list of cells mapping
Represent main neuron object computed by single thread.
double * node_a_storage()
double * node_sav_rhs_storage()
double * node_area_storage()
double * node_voltage_storage()
double * node_b_storage()
struct NrnThreadMembList * next
A point process is computed just like regular mechanisms.
Section to segment mapping.
Non-template stable handle to a generic value.
T get() const
Explicit conversion to any T.
int Fprintf(FILE *stream, const char *fmt, Args... args)