NEURON
multicore.h
Go to the documentation of this file.
1 #pragma once
2 
3 /*
4 Starts from Hubert Eichner's modifications but incorporates a
5 significant refactorization. The best feature of Hubert's original
6 code is retained. I.e. the user level structures remain unchanged
7 and the vectors, e.g v_node, are ordered so that each thread uses
8 a contiguous region. We take this even further by changing rootnodecount
9 to nrn_global_ncell and ordering the rootnodes so they appear in the proper
10 place in the lists instead of all at the beginning. This means
11 most of the user level for i=0,rootnode-1 loops have to be
12 changed to iterate over all the nrn_thread_t.ncell. But underneath the
13 VECTORIZE part, most functions are given an ithread argument and none ever
14 get outside the array portions specified by the nrn_thread_t.
15 This means that the thread parallelization can be handled at the level
16 of fadvance() and a network sim can take advantage of the minimum
17 netcon delay interval
18 
19 The main caveat with threads is that mod files should not use pointers
20 that cross thread data boundaries. ie. gap junctions should use the
21 ParallelContext methods.
22 
23 */
24 
25 /* now included by section.h since this has take over the v_node,
26 actual_v, etc.
27 */
28 
29 #include "membfunc.h"
30 
31 #include <cstddef>
32 
33 typedef struct NrnThreadMembList { /* patterned after CvMembList in cvodeobj.h */
36  int index;
38 
39 typedef struct NrnThreadBAList {
40  Memb_list* ml; /* an item in the NrnThreadMembList */
44 
45 struct hoc_Item;
47 struct Object;
48 
49 /**
50  * \class NrnThread
51  * \brief Represent main neuron object computed by single thread
52  *
53  * NrnThread represent collection of cells or part of a cell computed
54  * by single thread within NEURON process.
55  *
56  * @warning The constructor/destructor of this struct are not called.
57  */
58 struct NrnThread {
59  double _t;
60  double _dt;
61  double cj;
64  int ncell; /* analogous to old rootnodecount */
65  int end; /* 1 + position of last in v_node array. Now v_node_count. */
66  int id; /* this is nrn_threads[id] */
67  int _stop_stepping; /* delivered an all thread HocEvent */
68  int _ecell_child_cnt; /* see _ecell_children below */
69 
70  /** @brief Offset in the global node data where this NrnThread's values start.
71  */
72  std::size_t _node_data_offset{};
73 
74  [[nodiscard]] double* node_a_storage();
75  [[nodiscard]] double* node_area_storage();
76  [[nodiscard]] double* node_b_storage();
77  [[nodiscard]] double* node_d_storage();
78  [[nodiscard]] double* node_rhs_storage();
79  [[nodiscard]] double* node_sav_d_storage();
80  [[nodiscard]] double* node_sav_rhs_storage();
81  [[nodiscard]] double* node_voltage_storage();
82  [[nodiscard]] double& actual_d(std::size_t row) {
83  return node_d_storage()[row];
84  }
85  [[nodiscard]] double& actual_rhs(std::size_t row) {
86  return node_rhs_storage()[row];
87  }
88 
92  double* _sp13_rhs; /* rhs matrix for sparse13 solver. updates to and from this vector
93  need to be transfered to actual_rhs */
94  char* _sp13mat; /* handle to general sparse matrix */
95  Memb_list* _ecell_memb_list; /* normally nullptr */
96  Node** _ecell_children; /* nodes with no extcell but parent has it */
97  void* _vcv; /* replaces old cvode_instance and nrn_cvode_ */
98 
99 #if 1
100  double _ctime; /* computation time in seconds (using nrnmpi_wtime) */
101 #endif
102 
103  NrnThreadBAList* tbl[BEFORE_AFTER_SIZE]; /* wasteful since almost all empty */
104  hoc_List* roots; /* ncell of these */
105  Object* userpart; /* the SectionList if this is a user defined partition */
106 };
107 
108 
109 extern int nrn_nthread;
110 extern NrnThread* nrn_threads;
111 
112 int nrn_allow_busywait(int b);
114 void nrn_threads_create(int n, bool parallel);
115 void nrn_thread_error(const char*);
116 using worker_job_t = void* (*) (NrnThread*);
120 void nrn_onethread_job(int, void* (*) (NrnThread*) );
121 void nrn_wait_for_threads();
123 void nrn_thread_partition(int it, Object* sl);
125 void nrn_threads_free();
126 int nrn_user_partition();
127 void reorder_secorder();
129 std::size_t nof_worker_threads();
130 
131 
132 // helper function for iterating over ``NrnThread``s
133 inline auto for_threads(NrnThread* threads, int num_threads) {
134  struct iterator {
136 
137  NrnThread* operator*() const {
138  return current;
139  }
140  iterator& operator++() {
141  ++current;
142  return *this;
143  }
144  bool operator!=(const iterator& other) const {
145  return current != other.current;
146  }
147  };
148 
149  struct iterable_wrapper {
150  NrnThread* base_;
151  int count_;
152 
153  iterable_wrapper(NrnThread* base, int count)
154  : base_(base)
155  , count_(count) {}
156 
157  iterator begin() const {
158  return iterator{base_};
159  }
160  iterator end() const {
161  return iterator{base_ + count_};
162  }
163  };
164 
165  return iterable_wrapper(threads, num_threads);
166 }
167 
168 
169 // olupton 2022-01-31: could add a _NrnThread typedef here for .mod file
170 // backwards compatibility if needed.
#define BEFORE_AFTER_SIZE
Definition: membfunc.hpp:72
void nrn_thread_memblist_setup()
Definition: multicore.cpp:629
void nrn_thread_error(const char *)
Definition: multicore.cpp:297
void nrn_multithread_job(worker_job_t)
Definition: multicore.cpp:836
void(*)(neuron::model_sorted_token const &, NrnThread &) worker_job_with_token_t
Definition: multicore.h:117
struct NrnThreadMembList NrnThreadMembList
int nrn_allow_busywait(int b)
Definition: multicore.cpp:1032
void nrn_onethread_job(int, void *(*)(NrnThread *))
void nrn_threads_free()
Definition: multicore.cpp:386
int nrn_nthread
Definition: multicore.cpp:57
void nrn_thread_table_check(neuron::model_sorted_token const &)
Definition: multicore.cpp:807
Object ** nrn_get_thread_partition(int it)
Definition: multicore.cpp:921
void *(*)(NrnThread *) worker_job_t
Definition: multicore.h:116
int nrn_user_partition()
Definition: multicore.cpp:940
NrnThread * nrn_threads
Definition: multicore.cpp:58
int nrn_how_many_processors()
Definition: multicore.cpp:1038
auto for_threads(NrnThread *threads, int num_threads)
Definition: multicore.h:133
void nrn_thread_partition(int it, Object *sl)
Definition: multicore.cpp:899
void nrn_threads_create(int n, bool parallel)
Definition: multicore.cpp:303
struct NrnThreadBAList NrnThreadBAList
void nrn_wait_for_threads()
Definition: multicore.cpp:891
void reorder_secorder()
Definition: multicore.cpp:661
std::size_t nof_worker_threads()
Definition: multicore.cpp:1048
bool operator!=(unified_allocator< T > const &x, unified_allocator< U > const &y) noexcept
Definition: memory.h:76
static unsigned row
Definition: nonlin.cpp:78
int const size_t const size_t n
Definition: nrngsl.h:10
static List * current
Definition: nrnunit.cpp:13
A view into a set of mechanism instances.
Definition: nrnoc_ml.h:34
Definition: section.h:105
BAMech * bam
Definition: multicore.h:41
struct NrnThreadBAList * next
Definition: multicore.h:42
Memb_list * ml
Definition: multicore.h:40
Represent main neuron object computed by single thread.
Definition: multicore.h:58
double * node_sav_d_storage()
Definition: multicore.cpp:1078
double _dt
Definition: multicore.h:60
int * _v_parent_index
Definition: multicore.h:89
NrnThreadMembList * tml
Definition: multicore.h:62
double & actual_d(std::size_t row)
Definition: multicore.h:82
int ncell
Definition: multicore.h:64
double * node_a_storage()
Definition: multicore.cpp:1054
char * _sp13mat
Definition: multicore.h:94
std::size_t _node_data_offset
Offset in the global node data where this NrnThread's values start.
Definition: multicore.h:72
int id
Definition: multicore.h:66
NrnThreadBAList * tbl[BEFORE_AFTER_SIZE]
Definition: multicore.h:103
double & actual_rhs(std::size_t row)
Definition: multicore.h:85
double cj
Definition: multicore.h:61
double * node_sav_rhs_storage()
Definition: multicore.cpp:1088
int _stop_stepping
Definition: multicore.h:67
double * node_rhs_storage()
Definition: multicore.cpp:1074
double * node_area_storage()
Definition: multicore.cpp:1059
int end
Definition: multicore.h:65
double _ctime
Definition: multicore.h:100
Memb_list ** _ml_list
Definition: multicore.h:63
int _ecell_child_cnt
Definition: multicore.h:68
Node ** _v_parent
Definition: multicore.h:91
hoc_List * roots
Definition: multicore.h:104
Node ** _ecell_children
Definition: multicore.h:96
double * node_d_storage()
Definition: multicore.cpp:1069
Memb_list * _ecell_memb_list
Definition: multicore.h:95
double * _sp13_rhs
Definition: multicore.h:92
void * _vcv
Definition: multicore.h:97
Object * userpart
Definition: multicore.h:105
Node ** _v_node
Definition: multicore.h:90
double * node_voltage_storage()
Definition: multicore.cpp:1098
double * node_b_storage()
Definition: multicore.cpp:1064
double _t
Definition: multicore.h:59
struct NrnThreadMembList * next
Definition: multicore.h:34
Memb_list * ml
Definition: multicore.h:35
Definition: hocdec.h:173