1 /*
2 * Copyright (C) by Argonne National Laboratory
3 * See COPYRIGHT in top-level directory
4 */
5
6 #ifndef OFI_TYPES_H_INCLUDED
7 #define OFI_TYPES_H_INCLUDED
8
9 #include <netdb.h>
10 #include <stddef.h>
11 #include <inttypes.h>
12 #ifdef HAVE_STDINT_H
13 #include <stdint.h>
14 #endif
15 #include "ofi_pre.h"
16 #include "ch4_types.h"
17 #include "mpidch4r.h"
18 #include "mpidu_genq.h"
19
20 #define __SHORT_FILE__ \
21 (strrchr(__FILE__,'/') \
22 ? strrchr(__FILE__,'/')+1 \
23 : __FILE__ \
24 )
25
26 /* TODO: This should come from provider capability */
27 #define MPIDI_OFI_MAX_VNIS 16
28
29 #define MPIDI_OFI_MAP_NOT_FOUND ((void*)(-1UL))
30 #define MPIDI_OFI_DEFAULT_SHORT_SEND_SIZE (16 * 1024)
31 #define MPIDI_OFI_MAX_NUM_AM_BUFFERS (8)
32 #define MPIDI_OFI_AM_BUFF_SZ (1 * 1024 * 1024)
33 #define MPIDI_OFI_CACHELINE_SIZE (MPL_CACHELINE_SIZE)
34 #define MPIDI_OFI_IOV_MAX (32)
35 #define MPIDI_OFI_AM_HDR_POOL_CELL_SIZE (1024)
36 #define MPIDI_OFI_AM_HDR_POOL_NUM_CELLS_PER_CHUNK (1024)
37 #define MPIDI_OFI_AM_HDR_POOL_MAX_NUM_CELLS (257 * 1024)
38 #define MPIDI_OFI_NUM_CQ_BUFFERED (1024)
39
40 /* The number of bits in the immediate data field allocated to the source rank. */
41 #define MPIDI_OFI_IDATA_SRC_BITS (30)
42 /* The number of bits in the immediate data field allocated to the error propagation. */
43 #define MPIDI_OFI_IDATA_ERROR_BITS (2)
44 /* Bit mask for MPIR_ERR_OTHER */
45 #define MPIDI_OFI_ERR_OTHER (0x1ULL)
46 /* Bit mask for MPIR_PROC_FAILED */
47 #define MPIDI_OFI_ERR_PROC_FAILED (0x2ULL)
48
49 /* Set the error bits */
MPIDI_OFI_idata_set_error_bits(uint64_t * data_field,MPIR_Errflag_t errflag)50 MPL_STATIC_INLINE_PREFIX void MPIDI_OFI_idata_set_error_bits(uint64_t * data_field,
51 MPIR_Errflag_t errflag)
52 {
53 switch (errflag) {
54 case MPIR_ERR_OTHER:
55 *data_field = (*data_field) | (MPIDI_OFI_ERR_OTHER << MPIDI_OFI_IDATA_SRC_BITS);
56 break;
57 case MPIR_ERR_PROC_FAILED:
58 *data_field = (*data_field) | (MPIDI_OFI_ERR_PROC_FAILED << MPIDI_OFI_IDATA_SRC_BITS);
59 break;
60 case MPIR_ERR_NONE:
61 /*do nothing */
62 break;
63 }
64 }
65
66 /* Get the error flag from the OFI data field. */
MPIDI_OFI_idata_get_error_bits(uint64_t idata)67 MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_idata_get_error_bits(uint64_t idata)
68 {
69 if ((idata >> MPIDI_OFI_IDATA_SRC_BITS) & MPIDI_OFI_ERR_OTHER) {
70 return MPIR_ERR_OTHER;
71 } else if ((idata >> MPIDI_OFI_IDATA_SRC_BITS) & MPIDI_OFI_ERR_PROC_FAILED) {
72 return MPIR_ERR_PROC_FAILED;
73 } else {
74 return MPI_SUCCESS;
75 }
76 }
77
78
79 #define MPIDI_OFI_PROTOCOL_BITS (3) /* This is set to 3 even though we actually use 4. The ssend
80 * ack bit needs to live outside the protocol bit space to avoid
81 * accidentally matching unintended messages. Because of this,
82 * we shift the PROTOCOL_MASK one extra bit to the left to take
83 * the place of the empty SSEND_ACK bit. */
84
85 #if MPIDI_OFI_ENABLE_RUNTIME_CHECKS == MPIDI_OFI_ON
86 #define MPIDI_OFI_SYNC_SEND_ACK (1ULL << (MPIDI_OFI_CONTEXT_BITS + MPIDI_OFI_SOURCE_BITS + MPIDI_OFI_TAG_BITS))
87 #define MPIDI_OFI_SYNC_SEND (2ULL << (MPIDI_OFI_CONTEXT_BITS + MPIDI_OFI_SOURCE_BITS + MPIDI_OFI_TAG_BITS))
88 #define MPIDI_OFI_DYNPROC_SEND (4ULL << (MPIDI_OFI_CONTEXT_BITS + MPIDI_OFI_SOURCE_BITS + MPIDI_OFI_TAG_BITS))
89 #define MPIDI_OFI_HUGE_SEND (8ULL << (MPIDI_OFI_CONTEXT_BITS + MPIDI_OFI_SOURCE_BITS + MPIDI_OFI_TAG_BITS))
90 #define MPIDI_OFI_PROTOCOL_MASK (((1ULL << MPIDI_OFI_PROTOCOL_BITS) - 1) << 1 << (MPIDI_OFI_CONTEXT_BITS + MPIDI_OFI_SOURCE_BITS + MPIDI_OFI_TAG_BITS))
91 #define MPIDI_OFI_CONTEXT_MASK (((1ULL << MPIDI_OFI_CONTEXT_BITS) - 1) << (MPIDI_OFI_SOURCE_BITS + MPIDI_OFI_TAG_BITS))
92 #define MPIDI_OFI_SOURCE_MASK (((1ULL << MPIDI_OFI_SOURCE_BITS) - 1) << MPIDI_OFI_TAG_BITS)
93 #define MPIDI_OFI_TAG_MASK ((1ULL << MPIDI_OFI_TAG_BITS) - 1)
94 /* This value comes from the fact that we use a uint32_t in
95 * MPIDI_OFI_send_handler to define the dest and that is the size we expect
96 * from the OFI provider for its immediate data field. */
97 #define MPIDI_OFI_MAX_RANK_BITS (MPIDI_OFI_SOURCE_BITS > 0 ? MPIDI_OFI_SOURCE_BITS : 32)
98 #else
99 #if MPIDI_OFI_SOURCE_BITS == 0
100 /* This value comes from the fact that we use a uint32_t in
101 * MPIDI_OFI_send_handler to define the dest and that is the size we expect
102 * from the OFI provider for its immediate data field. */
103 #define MPIDI_OFI_MAX_RANK_BITS 32
104 #else
105 #define MPIDI_OFI_MAX_RANK_BITS MPIDI_OFI_SOURCE_BITS
106 #endif
107 #endif
108
109 #define MPIDI_OFI_THREAD_UTIL_MUTEX MPIDI_OFI_global.mutexes[0].m
110 #define MPIDI_OFI_THREAD_PROGRESS_MUTEX MPIDI_OFI_global.mutexes[1].m
111 #define MPIDI_OFI_THREAD_FI_MUTEX MPIDI_OFI_global.mutexes[2].m
112 #define MPIDI_OFI_THREAD_SPAWN_MUTEX MPIDI_OFI_global.mutexes[3].m
113 #define MAX_OFI_MUTEXES 4
114
115 /* Field accessor macros */
116 #define MPIDI_OFI_AMREQUEST(req,field) ((req)->dev.ch4.am.netmod_am.ofi.field)
117 #define MPIDI_OFI_AMREQUEST_HDR(req,field) ((req)->dev.ch4.am.netmod_am.ofi.req_hdr->field)
118 #define MPIDI_OFI_AMREQUEST_HDR_PTR(req) ((req)->dev.ch4.am.netmod_am.ofi.req_hdr)
119 #define MPIDI_OFI_REQUEST(req,field) ((req)->dev.ch4.netmod.ofi.field)
120 #define MPIDI_OFI_AV(av) ((av)->netmod.ofi)
121
122 #define MPIDI_OFI_COMM(comm) ((comm)->dev.ch4.netmod.ofi)
123
124 #define MPIDI_OFI_NUM_CQ_ENTRIES 8
125
126 /* Typedefs */
127 enum {
128 MPIDI_OFI_CTRL_HUGE, /**< Huge message */
129 MPIDI_OFI_CTRL_HUGEACK /**< Huge message ack */
130 /**< Huge message cleanup */
131 };
132
133 enum {
134 MPIDI_OFI_EVENT_ABORT,
135 MPIDI_OFI_EVENT_SEND,
136 MPIDI_OFI_EVENT_RECV,
137 MPIDI_OFI_EVENT_AM_SEND,
138 MPIDI_OFI_EVENT_AM_SEND_PIPELINE,
139 MPIDI_OFI_EVENT_AM_RECV,
140 MPIDI_OFI_EVENT_AM_READ,
141 MPIDI_OFI_EVENT_PEEK,
142 MPIDI_OFI_EVENT_RECV_HUGE,
143 MPIDI_OFI_EVENT_RECV_PACK,
144 MPIDI_OFI_EVENT_RECV_NOPACK,
145 MPIDI_OFI_EVENT_SEND_HUGE,
146 MPIDI_OFI_EVENT_SEND_PACK,
147 MPIDI_OFI_EVENT_SEND_NOPACK,
148 MPIDI_OFI_EVENT_SSEND_ACK,
149 MPIDI_OFI_EVENT_GET_HUGE,
150 MPIDI_OFI_EVENT_CHUNK_DONE,
151 MPIDI_OFI_EVENT_INJECT_EMU,
152 MPIDI_OFI_EVENT_DYNPROC_DONE,
153 MPIDI_OFI_EVENT_ACCEPT_PROBE
154 };
155
156 enum {
157 MPIDI_OFI_PEEK_START,
158 MPIDI_OFI_PEEK_NOT_FOUND,
159 MPIDI_OFI_PEEK_FOUND
160 };
161
162 enum {
163 MPIDI_OFI_DYNPROC_DISCONNECTED = 0,
164 MPIDI_OFI_DYNPROC_LOCAL_DISCONNECTED_CHILD,
165 MPIDI_OFI_DYNPROC_LOCAL_DISCONNECTED_PARENT,
166 MPIDI_OFI_DYNPROC_CONNECTED_CHILD,
167 MPIDI_OFI_DYNPROC_CONNECTED_PARENT
168 };
169
170 typedef struct {
171 char pad[MPIDI_REQUEST_HDR_SIZE];
172 struct fi_context context[MPIDI_OFI_CONTEXT_STRUCTS]; /* fixed field, do not move */
173 int event_id; /* fixed field, do not move */
174 int index;
175 } MPIDI_OFI_am_repost_request_t;
176
177 /* chunked request for AM eager/pipeline send operation */
178 typedef struct MPIDI_OFI_am_send_pipeline_request {
179 char pad[MPIDI_REQUEST_HDR_SIZE];
180 struct fi_context context[MPIDI_OFI_CONTEXT_STRUCTS]; /* fixed field, do not move */
181 int event_id; /* fixed field, do not move */
182 MPIR_Request *sreq;
183 void *pack_buffer;
184 void *am_hdr;
185 uint16_t am_hdr_sz;
186 MPIDI_OFI_am_header_t msg_hdr MPL_ATTR_ALIGNED(MAX_ALIGNMENT);
187 uint8_t am_hdr_buf[MPIDI_OFI_MAX_AM_HDR_SIZE] MPL_ATTR_ALIGNED(MAX_ALIGNMENT);
188 /* FI_ASYNC_IOV requires an iov storage to be alive until a request completes */
189 struct iovec iov[3];
190 } MPIDI_OFI_am_send_pipeline_request_t;
191
192 typedef struct {
193 char pad[MPIDI_REQUEST_HDR_SIZE];
194 struct fi_context context[MPIDI_OFI_CONTEXT_STRUCTS]; /* fixed field, do not move */
195 int event_id; /* fixed field, do not move */
196 MPIR_Request *signal_req;
197 } MPIDI_OFI_ssendack_request_t;
198
199 typedef struct {
200 char pad[MPIDI_REQUEST_HDR_SIZE];
201 struct fi_context context[MPIDI_OFI_CONTEXT_STRUCTS]; /* fixed field, do not move */
202 int event_id; /* fixed field, do not move */
203 int done;
204 uint32_t tag;
205 uint32_t source;
206 uint64_t msglen;
207 } MPIDI_OFI_dynamic_process_request_t;
208
209 typedef struct {
210 uint8_t op;
211 uint8_t dt;
212 unsigned atomic_valid:2;
213 unsigned fetch_atomic_valid:2;
214 unsigned compare_atomic_valid:2;
215 unsigned dtsize:10;
216 uint64_t max_atomic_count;
217 uint64_t max_compare_atomic_count;
218 uint64_t max_fetch_atomic_count;
219 bool mpi_acc_valid;
220 } MPIDI_OFI_atomic_valid_t;
221
222 typedef struct {
223 struct fid_domain *domain;
224 struct fid_av *av;
225 struct fid_ep *ep;
226 struct fid_cntr *rma_cmpl_cntr;
227
228 struct fid_ep *tx;
229 struct fid_ep *rx;
230 struct fid_cq *cq;
231 } MPIDI_OFI_context_t;
232
233 typedef union {
234 MPID_Thread_mutex_t m;
235 char cacheline[MPIDI_OFI_CACHELINE_SIZE];
236 } MPIDI_OFI_cacheline_mutex_t MPL_ATTR_ALIGNED(MPIDI_OFI_CACHELINE_SIZE);
237
238 typedef struct MPIDI_OFI_cq_list_t {
239 struct fi_cq_tagged_entry cq_entry;
240 fi_addr_t source;
241 struct MPIDI_OFI_cq_list_t *next;
242 } MPIDI_OFI_cq_list_t;
243
244 typedef struct {
245 struct fi_cq_tagged_entry cq_entry;
246 } MPIDI_OFI_cq_buff_entry_t;
247
248 typedef struct {
249 unsigned enable_av_table:1;
250 unsigned enable_scalable_endpoints:1;
251 unsigned enable_shared_contexts:1;
252 unsigned enable_mr_scalable:1;
253 unsigned enable_mr_virt_address:1;
254 unsigned enable_mr_allocated:1;
255 unsigned enable_mr_prov_key:1;
256 unsigned enable_tagged:1;
257 unsigned enable_am:1;
258 unsigned enable_rma:1;
259 unsigned enable_atomics:1;
260 unsigned enable_pt2pt_nopack:1;
261 unsigned enable_hmem:1;
262 unsigned enable_data_auto_progress:1;
263 unsigned enable_control_auto_progress:1;
264
265 int max_endpoints;
266 int max_endpoints_bits;
267
268 int fetch_atomic_iovecs;
269
270 int context_bits;
271 int source_bits;
272 int tag_bits;
273 int major_version;
274 int minor_version;
275 int num_am_buffers;
276 } MPIDI_OFI_capabilities_t;
277
278 typedef struct {
279 fi_addr_t dest;
280 int rank;
281 int state;
282 } MPIDI_OFI_conn_t;
283
284 typedef struct MPIDI_OFI_conn_manager_t {
285 int max_n_conn; /* Maximum number of connections up to this point */
286 int n_conn; /* Current number of open connections */
287 int next_conn_id; /* The next connection id to be used. */
288 int *free_conn_id; /* The list of the next connection id to be used so we
289 * can garbage collect as we go. */
290 MPIDI_OFI_conn_t *conn_list; /* The list of connection structs to track the
291 * outstanding dynamic process connections. */
292 } MPIDI_OFI_conn_manager_t;
293
294 /* Global state data */
295 #define MPIDI_KVSAPPSTRLEN 1024
296 typedef struct {
297 /* OFI objects */
298 int avtid;
299 struct fi_info *prov_use;
300 struct fid_fabric *fabric;
301
302 struct fid_stx *rma_stx_ctx; /* shared TX context for RMA */
303 struct fid_ep *rma_sep; /* dedicated scalable EP for RMA */
304
305 int got_named_av;
306
307 /* Queryable limits */
308 uint64_t max_buffered_send;
309 uint64_t max_buffered_write;
310 uint64_t max_msg_size;
311 uint64_t max_short_send;
312 uint64_t max_mr_key_size;
313 uint64_t max_rma_key_bits;
314 uint64_t max_huge_rmas;
315 int rma_key_type_bits;
316 int context_shift;
317 size_t tx_iov_limit;
318 size_t rx_iov_limit;
319 size_t rma_iov_limit;
320 int max_rma_sep_tx_cnt; /* Max number of transmit context on one RMA scalable EP */
321 size_t max_order_raw;
322 size_t max_order_war;
323 size_t max_order_waw;
324
325 /* Mutexes and endpoints */
326 MPIDI_OFI_cacheline_mutex_t mutexes[MAX_OFI_MUTEXES];
327 MPIDI_OFI_context_t ctx[MPIDI_OFI_MAX_VNIS];
328 int num_vnis;
329
330 /* Window/RMA Globals */
331 void *win_map;
332 uint64_t rma_issued_cntr;
333 /* OFI atomics limitation of each pair of <dtype, op> returned by the
334 * OFI provider at MPI initialization.*/
335 MPIDI_OFI_atomic_valid_t win_op_table[MPIR_DATATYPE_N_PREDEFINED][MPIDIG_ACCU_NUM_OP];
336 UT_array *rma_sep_idx_array; /* Array of available indexes of transmit contexts on sep */
337
338 /* Active Message Globals */
339 struct iovec am_iov[MPIDI_OFI_MAX_NUM_AM_BUFFERS];
340 struct fi_msg am_msg[MPIDI_OFI_MAX_NUM_AM_BUFFERS];
341 void *am_bufs[MPIDI_OFI_MAX_NUM_AM_BUFFERS];
342 MPIDI_OFI_am_repost_request_t am_reqs[MPIDI_OFI_MAX_NUM_AM_BUFFERS];
343 MPIDU_genq_private_pool_t am_hdr_buf_pool;
344 MPL_atomic_int_t am_inflight_inject_emus;
345 MPL_atomic_int_t am_inflight_rma_send_mrs;
346 /* Sequence number trackers for active messages */
347 void *am_send_seq_tracker;
348 void *am_recv_seq_tracker;
349 /* Queue (utlist) to store early-arrival active messages */
350 MPIDI_OFI_am_unordered_msg_t *am_unordered_msgs;
351
352 /* Pack buffers for various communication */
353 MPIDU_genq_private_pool_t pack_buf_pool;
354
355 /* Completion queue buffering */
356 MPIDI_OFI_cq_buff_entry_t cq_buffered_static_list[MPIDI_OFI_NUM_CQ_BUFFERED];
357 int cq_buffered_static_head;
358 int cq_buffered_static_tail;
359 MPIDI_OFI_cq_list_t *cq_buffered_dynamic_head, *cq_buffered_dynamic_tail;
360
361 /* Process management and PMI globals */
362 int pname_set;
363 int pname_len;
364 char addrname[FI_NAME_MAX];
365 size_t addrnamelen;
366 char pname[MPI_MAX_PROCESSOR_NAME];
367 int port_name_tag_mask[MPIR_MAX_CONTEXT_MASK];
368
369 /* Communication info for dynamic processes */
370 MPIDI_OFI_conn_manager_t conn_mgr;
371
372 void *req_map;
373 MPIDI_OFI_deferred_am_isend_req_t *deferred_am_isend_q;
374
375 /* Capability settings */
376 #ifdef MPIDI_OFI_ENABLE_RUNTIME_CHECKS
377 MPIDI_OFI_capabilities_t settings;
378 #endif
379 } MPIDI_OFI_global_t;
380
381 typedef struct {
382 int16_t type;
383 int16_t seqno;
384 int origin_rank;
385 MPIR_Request *ackreq;
386 uintptr_t send_buf;
387 size_t msgsize;
388 int comm_id;
389 uint64_t rma_key;
390 int tag;
391 int vni_src;
392 int vni_dst;
393 } MPIDI_OFI_send_control_t;
394
395 typedef struct MPIDI_OFI_win_acc_hint {
396 uint64_t dtypes_max_count[MPIR_DATATYPE_N_PREDEFINED]; /* translate CH4 which_accumulate_ops hints to
397 * atomicity support of all OFI datatypes. A datatype
398 * is supported only when all enabled ops are valid atomic
399 * provided by the OFI provider (recored in MPIDI_OFI_global.win_op_table).
400 * Invalid <dtype, op> defined in MPI standard are excluded.
401 * This structure is prepared at window creation time. */
402 } MPIDI_OFI_win_acc_hint_t;
403
404 enum {
405 MPIDI_OFI_PUT,
406 MPIDI_OFI_GET,
407 MPIDI_OFI_ACC,
408 MPIDI_OFI_GET_ACC,
409 };
410
411 typedef struct MPIDI_OFI_pack_chunk {
412 struct MPIDI_OFI_pack_chunk *next;
413 void *pack_buffer;
414 MPI_Aint unpack_size;
415 MPI_Aint unpack_offset;
416 } MPIDI_OFI_pack_chunk;
417
418 typedef struct MPIDI_OFI_win_request {
419 struct MPIDI_OFI_win_request *next;
420 struct MPIDI_OFI_win_request *prev;
421 int rma_type;
422 MPIR_Request **sigreq;
423 MPIDI_OFI_pack_chunk *chunks;
424 union {
425 struct {
426 struct {
427 const void *addr;
428 int count;
429 MPI_Datatype datatype;
430 MPI_Aint total_bytes;
431 MPI_Aint pack_offset;
432 } origin;
433 struct {
434 void *base;
435 int count;
436 MPI_Datatype datatype;
437 struct iovec *iov;
438 MPI_Aint iov_len;
439 MPI_Aint total_iov_len;
440 MPI_Aint iov_offset;
441 MPI_Aint iov_cur;
442 MPIDI_av_entry_t *addr;
443 uint64_t key;
444 } target;
445 } put;
446 struct {
447 struct {
448 void *addr;
449 int count;
450 MPI_Datatype datatype;
451 MPI_Aint total_bytes;
452 MPI_Aint pack_offset;
453 } origin;
454 struct {
455 void *base;
456 int count;
457 MPI_Datatype datatype;
458 struct iovec *iov;
459 MPI_Aint iov_len;
460 MPI_Aint total_iov_len;
461 MPI_Aint iov_offset;
462 MPI_Aint iov_cur;
463 MPIDI_av_entry_t *addr;
464 uint64_t key;
465 } target;
466 } get;
467 } noncontig;
468 } MPIDI_OFI_win_request_t;
469
470 typedef struct {
471 char pad[MPIDI_REQUEST_HDR_SIZE];
472 struct fi_context context[MPIDI_OFI_CONTEXT_STRUCTS]; /* fixed field, do not move */
473 int event_id; /* fixed field, do not move */
474 MPIR_Request *parent; /* Parent request */
475 } MPIDI_OFI_chunk_request;
476
477 typedef struct MPIDI_OFI_target_mr {
478 uint64_t addr; /* Unlikely used. Needed for calculating relative offset
479 * only when FI_MR_VIRT_ADDRESS is off but registration with MPI_BOTTOM fails
480 * at win creation. However, we always store it for code simplicity. */
481 uint64_t mr_key;
482 } MPIDI_OFI_target_mr_t;
483
484 typedef struct MPIDI_OFI_huge_recv {
485 char pad[MPIDI_REQUEST_HDR_SIZE];
486 struct fi_context context[MPIDI_OFI_CONTEXT_STRUCTS]; /* fixed field, do not move */
487 int event_id; /* fixed field, do not move */
488 int (*done_fn) (struct fi_cq_tagged_entry * wc, MPIR_Request * req, int event_id);
489 MPIDI_OFI_send_control_t remote_info;
490 bool peek; /* Flag to indicate whether this struct has been created to track an uncompleted peek
491 * operation. */
492 size_t cur_offset;
493 MPIR_Comm *comm_ptr;
494 MPIR_Request *localreq;
495 struct fi_cq_tagged_entry wc;
496 struct MPIDI_OFI_huge_recv *next; /* Points to the next entry in the unexpected list
497 * (when in the unexpected list) */
498 } MPIDI_OFI_huge_recv_t;
499
500 /* The list of posted huge receives that haven't been matched yet. These need
501 * to get matched up when handling the control message that starts transfering
502 * data from the remote memory region and we need a way of matching up the
503 * control messages with the "real" requests. */
504 typedef struct MPIDI_OFI_huge_recv_list {
505 int comm_id;
506 int rank;
507 int tag;
508 MPIR_Request *rreq;
509 struct MPIDI_OFI_huge_recv_list *next;
510 } MPIDI_OFI_huge_recv_list_t;
511
512 /* Externs */
513 extern MPIDI_OFI_global_t MPIDI_OFI_global;
514 extern MPIDI_OFI_huge_recv_t *MPIDI_unexp_huge_recv_head;
515 extern MPIDI_OFI_huge_recv_t *MPIDI_unexp_huge_recv_tail;
516 extern MPIDI_OFI_huge_recv_list_t *MPIDI_posted_huge_recv_head;
517 extern MPIDI_OFI_huge_recv_list_t *MPIDI_posted_huge_recv_tail;
518
519 extern MPIDI_OFI_capabilities_t MPIDI_OFI_caps_list[MPIDI_OFI_NUM_SETS];
520
521 #endif /* OFI_TYPES_H_INCLUDED */
522