00001 #ifndef multicore_h 00002 #define multicore_h 00003 00004 /* 00005 Starts from Hubert Eichner's modifications but incorporates a 00006 significant refactorization. The best feature of Hubert's original 00007 code is retained. I.e. the user level structures remain unchanged 00008 and the vectors, e.g v_node, are ordered so that each thread uses 00009 a contiguous region. We take this even further by changing rootnodecount 00010 to nrn_global_ncell and ordering the rootnodes so they appear in the proper 00011 place in the lists instead of all at the beginning. This means 00012 most of the user level for i=0,rootnode-1 loops have to be 00013 changed to iterate over all the nrn_thread_t.ncell. But underneath the 00014 VECTORIZE part, most functions are given an ithread argument and none ever 00015 get outside the array portions specified by the nrn_thread_t. 00016 This means that the thread parallelization can be handled at the level 00017 of fadvance() and a network sim can take advantage of the minimum 00018 netcon delay interval 00019 00020 The main caveat with threads is that mod files should not use pointers 00021 that cross thread data boundaries. ie. gap junctions should use the 00022 ParallelContext methods. 00023 00024 */ 00025 00026 /* now included by section.h since this has take over the v_node, 00027 actual_v, etc. 00028 */ 00029 00030 #include <membfunc.h> 00031 00032 #if defined(__cplusplus) 00033 extern "C" { 00034 #endif 00035 00036 typedef struct NrnThreadMembList{ /* patterned after CvMembList in cvodeobj.h */ 00037 struct NrnThreadMembList* next; 00038 Memb_list* ml; 00039 int index; 00040 } NrnThreadMembList; 00041 00042 typedef struct NrnThreadBAList { 00043 Memb_list* ml; /* an item in the NrnThreadMembList */ 00044 BAMech* bam; 00045 struct NrnThreadBAList* next; 00046 } NrnThreadBAList; 00047 00048 typedef struct NrnThread { 00049 double _t; 00050 double _dt; 00051 double cj; 00052 NrnThreadMembList* tml; 00053 int ncell; /* analogous to old rootnodecount */ 00054 int end; /* 1 + position of last in v_node array. Now v_node_count. */ 00055 int id; /* this is nrn_threads[id] */ 00056 int _stop_stepping; /* delivered an all thread HocEvent */ 00057 00058 double* _actual_rhs; 00059 double* _actual_d; 00060 double* _actual_a; 00061 double* _actual_b; 00062 double* _actual_v; 00063 double* _actual_area; 00064 int* _v_parent_index; 00065 Node** _v_node; 00066 Node** _v_parent; 00067 char* _sp13mat; /* handle to general sparse matrix */ 00068 Memb_list* _ecell_memb_list; /* normally nil */ 00069 void* _vcv; /* replaces old cvode_instance and nrn_cvode_ */ 00070 00071 #if 1 00072 double _ctime; /* computation time in seconds (using nrnmpi_wtime) */ 00073 #endif 00074 00075 NrnThreadBAList* tbl[BEFORE_AFTER_SIZE]; /* wasteful since almost all empty */ 00076 hoc_List* roots; /* ncell of these */ 00077 Object* userpart; /* the SectionList if this is a user defined partition */ 00078 00079 } NrnThread; 00080 00081 extern int nrn_nthread; 00082 extern NrnThread* nrn_threads; 00083 extern void nrn_thread_error(char*); 00084 extern void nrn_multithread_job(void*(*)(NrnThread*)); 00085 extern void nrn_onethread_job(int, void*(*)(NrnThread*)); 00086 extern void nrn_wait_for_threads(); 00087 extern void nrn_thread_table_check(); 00088 00089 #define FOR_THREADS(nt) for (nt = nrn_threads; nt < nrn_threads + nrn_nthread; ++nt) 00090 00091 #if defined(__cplusplus) 00092 } 00093 #endif 00094 00095 #endif