1 /*
2  * Copyright (C) by Argonne National Laboratory
3  *     See COPYRIGHT in top-level directory
4  */
5 
6 #ifndef CH4_TYPES_H_INCLUDED
7 #define CH4_TYPES_H_INCLUDED
8 
9 #include <mpidimpl.h>
10 #include <stdio.h>
11 #include "mpir_cvars.h"
12 #include "ch4i_workq_types.h"
13 #include "mpidu_genq.h"
14 
15 /* Macros and inlines */
16 #define MPIDIU_MAP_NOT_FOUND      ((void*)(-1UL))
17 
18 /* VCI attributes */
19 enum {
20     MPIDI_VCI_TX = 0x1,         /* Can send */
21     MPIDI_VCI_RX = 0x2, /* Can receive */
22 };
23 
24 #define MPIDIU_REQUEST_POOL_NUM_CELLS_PER_CHUNK (1024)
25 #define MPIDIU_REQUEST_POOL_MAX_NUM_CELLS (257 * 1024)
26 #define MPIDIU_REQUEST_POOL_CELL_SIZE (256)
27 
28 /* Flags for MPIDI_Progress_test
29  *
30  * Flags argument allows to control execution of different parts of progress function,
31  * for aims of prioritization of different transports and reentrant-safety of progress call.
32  *
33  * MPIDI_PROGRESS_HOOKS - enables progress on progress hooks. Hooks may invoke upper-level logic internaly,
34  *      that's why MPIDI_Progress_test call with MPIDI_PROGRESS_HOOKS set isn't reentrant safe, and shouldn't be called from netmod's fallback logic.
35  * MPIDI_PROGRESS_NM and MPIDI_PROGRESS_SHM enables progress on transports only, and guarantee reentrant-safety.
36  */
37 #define MPIDI_PROGRESS_HOOKS  (1)
38 #define MPIDI_PROGRESS_NM     (1<<1)
39 #define MPIDI_PROGRESS_SHM    (1<<2)
40 
41 #define MPIDI_PROGRESS_ALL (MPIDI_PROGRESS_HOOKS|MPIDI_PROGRESS_NM|MPIDI_PROGRESS_SHM)
42 
43 enum {
44     MPIDIG_EPOTYPE_NONE = 0,          /**< No epoch in affect */
45     MPIDIG_EPOTYPE_LOCK = 1,          /**< MPI_Win_lock access epoch */
46     MPIDIG_EPOTYPE_START = 2,         /**< MPI_Win_start access epoch */
47     MPIDIG_EPOTYPE_POST = 3,          /**< MPI_Win_post exposure epoch */
48     MPIDIG_EPOTYPE_FENCE = 4,         /**< MPI_Win_fence access/exposure epoch */
49     MPIDIG_EPOTYPE_REFENCE = 5,       /**< MPI_Win_fence possible access/exposure epoch */
50     MPIDIG_EPOTYPE_LOCK_ALL = 6       /**< MPI_Win_lock_all access epoch */
51 };
52 
53 /* Enum for calling types between netmod and shm */
54 enum {
55     MPIDI_NETMOD = 0,
56     MPIDI_SHM = 1
57 };
58 
59 /* Enum for src buffer kind when computing accumulate op */
60 enum {
61     MPIDIG_ACC_SRCBUF_DEFAULT = 0,
62     MPIDIG_ACC_SRCBUF_PACKED = 1
63 };
64 
65 typedef struct MPIDIG_hdr_t {
66     int src_rank;
67     int tag;
68     MPIR_Context_id_t context_id;
69     int error_bits;
70     uint8_t flags;
71     MPIR_Request *sreq_ptr;
72     size_t data_sz;
73 } MPIDIG_hdr_t;
74 
75 typedef struct MPIDIG_send_cts_msg_t {
76     MPIR_Request *sreq_ptr;
77     MPIR_Request *rreq_ptr;
78 } MPIDIG_send_cts_msg_t;
79 
80 typedef struct MPIDIG_send_data_msg_t {
81     MPIR_Request *rreq_ptr;
82 } MPIDIG_send_data_msg_t;
83 
84 typedef struct MPIDIG_ssend_ack_msg_t {
85     MPIR_Request *sreq_ptr;
86 } MPIDIG_ssend_ack_msg_t;
87 
88 typedef struct MPIDIG_win_cntrl_msg_t {
89     uint64_t win_id;
90     uint32_t origin_rank;
91     int16_t lock_type;
92 } MPIDIG_win_cntrl_msg_t;
93 
94 typedef struct MPIDIG_put_msg_t {
95     int src_rank;
96     uint64_t win_id;
97     MPIR_Request *preq_ptr;
98     MPI_Aint target_disp;
99     MPI_Aint target_count;
100     MPI_Aint target_datatype;
101     MPI_Aint target_true_lb;
102     int flattened_sz;
103 } MPIDIG_put_msg_t;
104 
105 typedef struct MPIDIG_put_dt_ack_msg_t {
106     int src_rank;
107     MPIR_Request *target_preq_ptr;
108     MPIR_Request *origin_preq_ptr;
109 } MPIDIG_put_dt_ack_msg_t;
110 typedef MPIDIG_put_dt_ack_msg_t MPIDIG_acc_dt_ack_msg_t;
111 typedef MPIDIG_put_dt_ack_msg_t MPIDIG_get_acc_dt_ack_msg_t;
112 
113 typedef struct MPIDIG_put_dat_msg_t {
114     MPIR_Request *preq_ptr;
115 } MPIDIG_put_dat_msg_t;
116 typedef MPIDIG_put_dat_msg_t MPIDIG_acc_dat_msg_t;
117 typedef MPIDIG_put_dat_msg_t MPIDIG_get_acc_dat_msg_t;
118 
119 typedef struct MPIDIG_put_ack_msg_t {
120     MPIR_Request *preq_ptr;
121 } MPIDIG_put_ack_msg_t;
122 
123 typedef struct MPIDIG_get_msg_t {
124     int src_rank;
125     uint64_t win_id;
126     MPIR_Request *greq_ptr;
127     MPI_Aint target_disp;
128     MPI_Aint target_count;
129     MPI_Aint target_datatype;
130     MPI_Aint target_true_lb;
131     int flattened_sz;
132 } MPIDIG_get_msg_t;
133 
134 typedef struct MPIDIG_get_ack_msg_t {
135     MPIR_Request *greq_ptr;
136 } MPIDIG_get_ack_msg_t;
137 
138 typedef struct MPIDIG_cswap_req_msg_t {
139     int src_rank;
140     uint64_t win_id;
141     MPIR_Request *req_ptr;
142     MPI_Aint target_disp;
143     MPI_Datatype datatype;
144 } MPIDIG_cswap_req_msg_t;
145 
146 typedef struct MPIDIG_cswap_ack_msg_t {
147     MPIR_Request *req_ptr;
148 } MPIDIG_cswap_ack_msg_t;
149 
150 typedef struct MPIDIG_acc_req_msg_t {
151     int src_rank;
152     uint64_t win_id;
153     MPIR_Request *req_ptr;
154     int origin_count;
155     MPI_Datatype origin_datatype;
156     int target_count;
157     MPI_Datatype target_datatype;
158     MPI_Op op;
159     MPI_Aint target_disp;
160     uint64_t result_data_sz;
161     int n_iov;
162     int flattened_sz;
163 } MPIDIG_acc_req_msg_t;
164 
165 typedef struct MPIDIG_acc_req_msg_t MPIDIG_get_acc_req_msg_t;
166 
167 typedef struct MPIDIG_acc_ack_msg_t {
168     MPIR_Request *req_ptr;
169 } MPIDIG_acc_ack_msg_t;
170 
171 typedef MPIDIG_acc_ack_msg_t MPIDIG_get_acc_ack_msg_t;
172 
173 typedef struct MPIDIG_comm_req_list_t {
174     MPIR_Comm *comm[2][4];
175     MPIDIG_rreq_t *uelist[2][4];
176 } MPIDIG_comm_req_list_t;
177 
178 typedef struct {
179     int max_n_avts;
180     int n_avts;
181     int next_avtid;
182     int *free_avtid;
183 } MPIDIU_avt_manager;
184 
185 typedef struct {
186     uint64_t key;
187     void *value;
188     UT_hash_handle hh;          /* makes this structure hashable */
189 } MPIDIU_map_entry_t;
190 
191 typedef struct MPIDIU_map_t {
192     MPIDIU_map_entry_t *head;
193 } MPIDIU_map_t;
194 
195 typedef struct {
196     unsigned mt_model;
197 } MPIDI_CH4_configurations_t;
198 
199 /* Defining them in the global struct avoids duplicate of declarations and
200  * definitions; However, it makes debugging a bit cryptic */
201 #define MPIDIU_THREAD_PROGRESS_MUTEX      MPIDI_global.m[0]
202 #define MPIDIU_THREAD_UTIL_MUTEX          MPIDI_global.m[1]
203 
204 /* Protects MPIDIG global structures (e.g. global unexpected message queue) */
205 #define MPIDIU_THREAD_MPIDIG_GLOBAL_MUTEX MPIDI_global.m[2]
206 
207 #define MPIDIU_THREAD_SCHED_LIST_MUTEX    MPIDI_global.m[3]
208 #define MPIDIU_THREAD_TSP_QUEUE_MUTEX     MPIDI_global.m[4]
209 #ifdef HAVE_LIBHCOLL
210 #define MPIDIU_THREAD_HCOLL_MUTEX         MPIDI_global.m[5]
211 #endif
212 
213 /* Protects dynamic process tag, connection_id, avtable etc. */
214 #define MPIDIU_THREAD_DYNPROC_MUTEX       MPIDI_global.m[6]
215 
216 #define MAX_CH4_MUTEXES 7
217 
218 /* per-VCI structure -- using union to force minimum size */
219 typedef union MPIDI_vci {
220     struct {
221         int attr;
222         MPID_Thread_mutex_t lock;
223     } vci;
224     char pad[MPL_CACHELINE_SIZE];
225 } MPIDI_vci_t;
226 
227 #define MPIDI_VCI(i) MPIDI_global.vci[i].vci
228 
229 typedef struct MPIDI_CH4_Global_t {
230     MPIR_Request *request_test;
231     MPIR_Comm *comm_test;
232     int pname_set;
233     int pname_len;
234     char pname[MPI_MAX_PROCESSOR_NAME];
235     char parent_port[MPIDI_MAX_KVS_VALUE_LEN];
236     int is_initialized;
237     MPIDIU_avt_manager avt_mgr;
238     int is_ch4u_initialized;
239     int **node_map, max_node_id;
240     MPIDIG_comm_req_list_t *comm_req_lists;
241     MPIR_Commops MPIR_Comm_fns_store;
242     MPID_Thread_mutex_t m[MAX_CH4_MUTEXES];
243     MPIDIU_map_t *win_map;
244 #ifndef MPIDI_CH4U_USE_PER_COMM_QUEUE
245     MPIDIG_rreq_t *posted_list;
246     MPIDIG_rreq_t *unexp_list;
247 #endif
248     MPIDIG_req_ext_t *cmpl_list;
249     MPL_atomic_uint64_t exp_seq_no;
250     MPL_atomic_uint64_t nxt_seq_no;
251     MPIDU_genq_private_pool_t request_pool;
252     MPIDU_genq_private_pool_t unexp_pack_buf_pool;
253 #ifdef HAVE_SIGNAL
254     void (*prev_sighandler) (int);
255     volatile int sigusr1_count;
256     int my_sigusr1_count;
257 #endif
258 
259     int n_vcis;
260     MPIDI_vci_t vci[MPIDI_CH4_MAX_VCIS];
261     int progress_counts[MPIDI_CH4_MAX_VCIS];
262 
263 #if defined(MPIDI_CH4_USE_WORK_QUEUES)
264     /* TODO: move into MPIDI_vci to have per-vci workqueue */
265     MPIDI_workq_t workqueue;
266 #endif
267     MPIDI_CH4_configurations_t settings;
268     void *csel_root;
269 
270 #ifndef MPIDI_CH4_DIRECT_NETMOD
271     MPIDI_SHM_Global_t shm;
272 #endif
273     MPIDI_NM_Global_t nm;
274 } MPIDI_CH4_Global_t;
275 extern MPIDI_CH4_Global_t MPIDI_global;
276 extern char MPIDI_coll_generic_json[];
277 #ifdef MPL_USE_DBG_LOGGING
278 extern MPL_dbg_class MPIDI_CH4_DBG_GENERAL;
279 extern MPL_dbg_class MPIDI_CH4_DBG_MAP;
280 extern MPL_dbg_class MPIDI_CH4_DBG_COMM;
281 extern MPL_dbg_class MPIDI_CH4_DBG_MEMORY;
282 #endif
283 
284 #endif /* CH4_TYPES_H_INCLUDED */
285