16#ifndef NM_MPI_PRIVATE_H
17#define NM_MPI_PRIVATE_H
38#include <Padico/Puk.h>
39#include <nm_private_config.h>
60#define nm_mpi_spinlock_t nm_spinlock_t
61#define nm_mpi_spin_init(LOCK) nm_spin_init(LOCK)
62#define nm_mpi_spin_destroy(LOCK) nm_spin_destroy(LOCK)
63#define nm_mpi_spin_lock(LOCK) nm_spin_lock(LOCK)
64#define nm_mpi_spin_unlock(LOCK) nm_spin_unlock(LOCK)
68typedef float nm_mpi_float4_t;
70typedef double nm_mpi_float4_t;
72# error "no C type for 4 bytes floats"
76typedef float nm_mpi_float8_t;
78typedef double nm_mpi_float8_t;
80# error "no C type for 8 bytes floats"
108#define nm_mpi_errhandler_exec(P_ERRHANDLER, KIND, HANDLE, ERR) \
109 nm_mpi_errhandler_exec_internal(P_ERRHANDLER, KIND, HANDLE, ERR, \
110 __FUNCTION__, __FILE__, __LINE__)
113#define NM_MPI_ERROR_INTERNAL(ERRORCODE) (ERRORCODE)
115#define NM_MPI_ERROR_COMM(P_COMM, ERRORCODE) \
116 ( ( ((ERRORCODE) == MPI_SUCCESS) ? MPI_SUCCESS : \
117 nm_mpi_errhandler_exec((P_COMM)->p_errhandler, NM_MPI_ERRHANDLER_COMM, (P_COMM)->id, (ERRORCODE)) ) \
121#define NM_MPI_ERROR_SESSION(P_SESSION, ERRORCODE) \
122 ( ( ((ERRORCODE) == MPI_SUCCESS) ? MPI_SUCCESS : \
123 nm_mpi_errhandler_exec((P_SESSION)->p_errhandler, NM_MPI_ERRHANDLER_SESSION, (P_SESSION)->id, (ERRORCODE)) ) \
127#define NM_MPI_ERROR_WIN(P_WIN, ERRORCODE) \
128 ( ( ((ERRORCODE) == MPI_SUCCESS) ? MPI_SUCCESS : \
129 nm_mpi_errhandler_exec((P_WIN)->p_errhandler, NM_MPI_ERRHANDLER_WIN, (P_WIN)->id, (ERRORCODE)) ) \
133#define NM_MPI_ERROR_FILE(P_FILE, ERRORCODE) \
134 ( ( ((ERRORCODE) == MPI_SUCCESS) ? MPI_SUCCESS : \
135 nm_mpi_errhandler_exec((P_FILE)->p_errhandler, NM_MPI_ERRHANDLER_FILE, (P_FILE)->id, (ERRORCODE)) ) \
139#define NM_MPI_ERROR_FILE_DEFAULT(ERRORCODE) \
140 ( ( ((ERRORCODE) == MPI_SUCCESS) ? MPI_SUCCESS : \
141 nm_mpi_errhandler_exec(nm_mpi_file_errhandler, NM_MPI_ERRHANDLER_FILE, MPI_FILE_NULL, (ERRORCODE)) ) \
144#define NM_MPI_ERROR_WORLD(ERRORCODE) \
145 ( ( ((ERRORCODE) == MPI_SUCCESS) ? MPI_SUCCESS : \
146 nm_mpi_errhandler_exec(nm_mpi_communicator_get(MPI_COMM_WORLD)->p_errhandler, NM_MPI_ERRHANDLER_COMM, MPI_COMM_WORLD, (ERRORCODE)) ) \
150#define NM_MPI_COMMUNICATOR_CHECK(P_COMM) \
151 PUK_CHECK_TYPE(struct nm_mpi_communicator_s*, P_COMM); \
152 do { if((P_COMM) == NULL) return NM_MPI_ERROR_WORLD(MPI_ERR_COMM); } while(0)
155#define NM_MPI_GROUP_CHECK(P_GROUP) \
156 PUK_CHECK_TYPE(struct nm_mpi_group_s*, P_GROUP); \
157 do { if((P_GROUP) == NULL) return NM_MPI_ERROR_WORLD(MPI_ERR_GROUP); } while(0)
160#define NM_MPI_SESSION_CHECK(P_SESSION) \
161 PUK_CHECK_TYPE(struct nm_mpi_session_s*, P_SESSION); \
162 do { if((P_SESSION) == NULL) return NM_MPI_ERROR_WORLD(MPI_ERR_SESSION); } while(0)
165#define NM_MPI_DATATYPE_CHECK(P_DATATYPE) \
166 PUK_CHECK_TYPE(struct nm_mpi_datatype_s*, P_DATATYPE); \
167 do { if((P_DATATYPE) == NULL) return NM_MPI_ERROR_COMM(p_comm, MPI_ERR_TYPE); } while(0)
170#define NM_MPI_TAG_CHECK_RECV(TAG) \
171 do { if(((TAG) != MPI_ANY_TAG) && ((TAG) < 0 || (TAG) > NM_MPI_TAG_MAX)) return NM_MPI_ERROR_COMM(p_comm, MPI_ERR_TAG); } while(0)
174#define NM_MPI_TAG_CHECK_SEND(TAG) \
175 do { if( ((TAG) < 0) || ((TAG) > NM_MPI_TAG_MAX) || ((TAG) == MPI_ANY_TAG)) return NM_MPI_ERROR_COMM(p_comm, MPI_ERR_TAG); } while(0)
177#define NM_MPI_WARNING(...) NM_WARN(__VA_ARGS__)
179#define NM_MPI_FATAL_ERROR(...) NM_FATAL(__VA_ARGS__)
181#define NM_MPI_TRACE(str, ...) NM_TRACEF(str, ## __VA_ARGS__)
183#define FREE_AND_SET_NULL(p) do { padico_free(p); p = NULL; } while (0)
202 struct nm_mpi_refcount_holder_list_s holders;
206#define NM_MPI_REFCOUNT_INVALID { .refcount = -1 }
213 p_refcount->type = type;
216 nm_mpi_refcount_holder_list_init(&p_refcount->holders);
223 nm_mpi_refcount_holder_itor_t i;
224 puk_list_foreach(nm_mpi_refcount_holder, i, &p_refcount->holders)
226 NM_MPI_WARNING(
"pending ref- type = %s; id = %d; p_holder = %p; %s:%d %s()\n",
227 p_refcount->type, p_refcount->id, i->p_holder, i->file, i->line, i->func);
237 nm_mpi_refcount_holder_list_destroy(&p_refcount->holders);
241#define nm_mpi_refcount_inc(REFCOUNT, HOLDER) \
242 nm_mpi_refcount_inc_internal(REFCOUNT, HOLDER, __FUNCTION__, __FILE__, __LINE__)
250 __sync_fetch_and_add(&p_refcount->
refcount, 1);
256 nm_mpi_refcount_holder_itor_t i;
257 PUK_LIST_FIND(nm_mpi_refcount_holder, i, &p_refcount->holders, (i->p_holder == p_holder));
260 NM_MPI_WARNING(
"p_holder = %p already holding a ref to p_refcount = %p (type = %s; id = %d)\n"
261 " new holder: %s:%d %s()\n"
262 " previous holder: %s:%d %s()\n",
263 p_holder, p_refcount, p_refcount->type, p_refcount->id,
264 file, line, func, i->file, i->line, i->func);
267 struct nm_mpi_refcount_holder_s*
h = nm_mpi_refcount_holder_new();
268 h->p_holder = p_holder;
272 nm_mpi_refcount_holder_list_push_back(&p_refcount->holders,
h);
281 const int nb_ref = __sync_sub_and_fetch(&p_refcount->
refcount, 1);
287 nm_mpi_refcount_holder_itor_t i;
288 PUK_LIST_FIND(nm_mpi_refcount_holder, i, &p_refcount->holders, (i->p_holder == p_holder));
291 NM_MPI_FATAL_ERROR(
"p_holder = %p not holding ref to p_refcount = %p (type = %s; id = %d); cannot release\n",
292 p_holder, p_refcount, p_refcount->type, p_refcount->id);
296 nm_mpi_refcount_holder_list_remove(&p_refcount->holders, i);
297 nm_mpi_refcount_holder_delete(i);
306#define NM_MPI_TAG_MAX ((nm_tag_t)(0x7FFFFFFF))
308#define NM_MPI_TAG_PRIVATE_MASK ((nm_tag_t)(0x80000000))
310#define NM_MPI_TAG_PRIVATE_BASE ((nm_tag_t)(0xF0000000))
311#define NM_MPI_TAG_PRIVATE_BARRIER ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x11))
312#define NM_MPI_TAG_PRIVATE_BCAST ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x12))
313#define NM_MPI_TAG_PRIVATE_GATHER ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x13))
314#define NM_MPI_TAG_PRIVATE_GATHERV ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x14))
315#define NM_MPI_TAG_PRIVATE_SCATTER ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x15))
316#define NM_MPI_TAG_PRIVATE_SCATTERV ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x16))
317#define NM_MPI_TAG_PRIVATE_ALLTOALL ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x17))
318#define NM_MPI_TAG_PRIVATE_ALLTOALLV ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x18))
319#define NM_MPI_TAG_PRIVATE_REDUCE ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x19))
320#define NM_MPI_TAG_PRIVATE_ALLREDUCE ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x1A))
321#define NM_MPI_TAG_PRIVATE_SCAN ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x1B))
322#define NM_MPI_TAG_PRIVATE_REDUCESCATTER ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x1C))
323#define NM_MPI_TAG_PRIVATE_ALLGATHER ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x1D))
324#define NM_MPI_TAG_PRIVATE_TYPE_ADD ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x21))
325#define NM_MPI_TAG_PRIVATE_TYPE_ADD_ACK ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x22))
326#define NM_MPI_TAG_PRIVATE_WIN_INIT ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x23))
327#define NM_MPI_TAG_PRIVATE_WIN_FENCE ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x24))
328#define NM_MPI_TAG_PRIVATE_WIN_BARRIER ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x25))
329#define NM_MPI_TAG_PRIVATE_COMM_SPLIT ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0xF1))
330#define NM_MPI_TAG_PRIVATE_COMM_CREATE ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0xF2))
331#define NM_MPI_TAG_PRIVATE_COMM_INFO ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0xF3))
332#define NM_MPI_TAG_PRIVATE_FILE_OPEN ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0xF4))
334#define NM_MPI_TAG_PRIVATE_RMA_BASE ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x08000000))
335#define NM_MPI_TAG_PRIVATE_RMA_BASE_SYNC ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x04000000))
336#define NM_MPI_TAG_PRIVATE_RMA_MASK_OP ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE | 0x0F))
337#define NM_MPI_TAG_PRIVATE_RMA_MASK_AOP ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE | 0xF0))
338#define NM_MPI_TAG_PRIVATE_RMA_MASK_FOP ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_MASK_OP | \
339 NM_MPI_TAG_PRIVATE_RMA_MASK_AOP))
340#define NM_MPI_TAG_PRIVATE_RMA_MASK_SEQ ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE | 0xFFFF00))
341#define NM_MPI_TAG_PRIVATE_RMA_MASK_WIN ((nm_tag_t)(0xFFFFFFFF00000000 | NM_MPI_TAG_PRIVATE_RMA_BASE))
342#define NM_MPI_TAG_PRIVATE_RMA_MASK_USER ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_MASK_FOP | \
343 NM_MPI_TAG_PRIVATE_RMA_MASK_SEQ))
344#define NM_MPI_TAG_PRIVATE_RMA_MASK ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_MASK_WIN | \
345 NM_MPI_TAG_PRIVATE_RMA_MASK_USER))
346#define NM_MPI_TAG_PRIVATE_RMA_MASK_SYNC ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE_SYNC | 0xFFFFFFFF000000FF))
347#define NM_MPI_TAG_PRIVATE_RMA_START ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE_SYNC | 0x01))
348#define NM_MPI_TAG_PRIVATE_RMA_END ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE_SYNC | 0x02))
349#define NM_MPI_TAG_PRIVATE_RMA_LOCK ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE_SYNC | 0x13))
350#define NM_MPI_TAG_PRIVATE_RMA_LOCK_R ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE_SYNC | 0x04))
351#define NM_MPI_TAG_PRIVATE_RMA_UNLOCK ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE_SYNC | 0x05))
352#define NM_MPI_TAG_PRIVATE_RMA_UNLOCK_R ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE_SYNC | 0x06))
354#define NM_MPI_TAG_PRIVATE_RMA_OP_CHECK ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE_SYNC | 0x0F))
355#define NM_MPI_TAG_PRIVATE_RMA_PUT ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE | 0x1))
356#define NM_MPI_TAG_PRIVATE_RMA_GET_REQ ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE | 0x2))
357#define NM_MPI_TAG_PRIVATE_RMA_ACC ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE | 0x3))
358#define NM_MPI_TAG_PRIVATE_RMA_GACC_REQ ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE | 0x4))
359#define NM_MPI_TAG_PRIVATE_RMA_FAO_REQ ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE | 0x5))
360#define NM_MPI_TAG_PRIVATE_RMA_CAS_REQ ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE | 0x6))
361#define NM_MPI_TAG_PRIVATE_RMA_REQ_RESP ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE | 0xF))
382 void*attribute_val_in,
void*attribute_val_out,
int*flag,
int*ierr);
387 void*attribute_val_in,
void*attribute_val_out,
int*flag);
404 &puk_hash_pointer_default_hash,
405 &puk_hash_pointer_default_eq,
411 struct nm_mpi_attr_hashtable_s
table;
488#define NM_MPI_REQUEST_ZERO ((nm_mpi_request_type_t)0x0000)
489#define NM_MPI_REQUEST_RECV ((nm_mpi_request_type_t)0x0001)
490#define NM_MPI_REQUEST_PRECV ((nm_mpi_request_type_t)0x0041)
491#define NM_MPI_REQUEST_PROBE ((nm_mpi_request_type_t)0x0002)
492#define NM_MPI_REQUEST_SEND ((nm_mpi_request_type_t)0x0004)
493#define NM_MPI_REQUEST_RSEND ((nm_mpi_request_type_t)0x0014)
494#define NM_MPI_REQUEST_SSEND ((nm_mpi_request_type_t)0x0024)
495#define NM_MPI_REQUEST_PSEND ((nm_mpi_request_type_t)0x0044)
496#define NM_MPI_REQUEST_FILE ((nm_mpi_request_type_t)0x0008)
497#define NM_MPI_REQUEST_GREQUEST ((nm_mpi_request_type_t)0x0080)
498#define NM_MPI_REQUEST_IBARRIER ((nm_mpi_request_type_t)0x1100)
499#define NM_MPI_REQUEST_IBCAST ((nm_mpi_request_type_t)0x2100)
500#define NM_MPI_REQUEST_IREDUCE ((nm_mpi_request_type_t)0x3100)
501#define NM_MPI_REQUEST_IALLREDUCE ((nm_mpi_request_type_t)0x4100)
502#define NM_MPI_REQUEST_IALLTOALL ((nm_mpi_request_type_t)0x5100)
503#define NM_MPI_REQUEST_IALLTOALLV ((nm_mpi_request_type_t)0x6100)
504#define NM_MPI_REQUEST_IGATHER ((nm_mpi_request_type_t)0x7100)
505#define NM_MPI_REQUEST_IALLGATHER ((nm_mpi_request_type_t)0x8100)
508#define NM_MPI_REQUEST_COLLECTIVE ((nm_mpi_request_type_t)0x0100)
510#define NM_MPI_REQUEST_PARTITIONED ((nm_mpi_request_type_t)0x0040)
513#define NM_MPI_STATUS_NONE ((nm_mpi_status_t)0x00)
514#define NM_MPI_REQUEST_CANCELLED ((nm_mpi_status_t)0x04)
515#define NM_MPI_REQUEST_PERSISTENT ((nm_mpi_status_t)0x08)
517#define _NM_MPI_MAX_DATATYPE_SIZE 64
568 struct nm_mpi_grequest_s
773 struct nm_mpi_type_indexed_map_s
782 struct nm_mpi_type_hindexed_map_s
805 struct nm_mpi_type_subarray_dim_s
814 struct nm_mpi_type_struct_map_s
966#define NM_MPI_WIN_UNUSED 0
967#define NM_MPI_WIN_ACTIVE_TARGET 1
968#define NM_MPI_WIN_PASSIVE_TARGET 2
969#define NM_MPI_WIN_PASSIVE_TARGET_END 4
970#define NM_MPI_WIN_PASSIVE_TARGET_PENDING 8
975#define NM_MPI_LOCK_NONE ((uint16_t)0)
976#define NM_MPI_LOCK_EXCLUSIVE ((uint16_t)MPI_LOCK_EXCLUSIVE)
977#define NM_MPI_LOCK_SHARED ((uint16_t)MPI_LOCK_SHARED)
978#define _NM_MPI_LOCK_OFFSET ((uint16_t)3)
985struct nm_mpi_profiling_s
987 unsigned long cur_req_send, max_req_send;
988 unsigned long cur_req_recv, max_req_recv;
989 unsigned long cur_req_total, max_req_total;
991extern struct nm_mpi_profiling_s nm_mpi_profile;
997#define NM_MPI_HANDLE_DEBUG 1
999#define NM_MPI_HANDLE_DEBUG 0
1005#define NM_MPI_HANDLE_TYPE(ENAME, TYPE, OFFSET, SLABSIZE) \
1006 PUK_VECT_TYPE(nm_mpi_entry_ ## ENAME, TYPE*); \
1007 NM_ALLOCATOR_TYPE(ENAME, TYPE); \
1008 struct nm_mpi_handle_##ENAME##_s \
1010 struct nm_mpi_entry_##ENAME##_vect_s table; \
1011 struct puk_int_vect_s pool; \
1013 nm_mpi_spinlock_t lock; \
1014 ENAME##_allocator_t allocator; \
1015 char*(*display)(TYPE*); \
1017 __attribute__((unused)) \
1018 static int nm_mpi_handle_##ENAME##_initialized(struct nm_mpi_handle_##ENAME##_s*p_allocator) \
1020 return (p_allocator->allocator != NULL); \
1023 __attribute__((unused)) \
1024 static int nm_mpi_handle_##ENAME##_load(struct nm_mpi_handle_##ENAME##_s*p_allocator) \
1027 nm_mpi_entry_##ENAME##_vect_itor_t i; \
1028 puk_vect_foreach(i, nm_mpi_entry_##ENAME, &p_allocator->table) \
1038 __attribute__((unused)) \
1039 static void nm_mpi_handle_##ENAME##_dump(struct nm_mpi_handle_##ENAME##_s*p_allocator) \
1041 if( (p_allocator->allocator != NULL) && \
1042 !nm_mpi_entry_##ENAME##_vect_empty(&p_allocator->table)) \
1044 nm_mpi_entry_##ENAME##_vect_itor_t i; \
1045 puk_vect_foreach(i, nm_mpi_entry_##ENAME, &p_allocator->table) \
1049 const int index = nm_mpi_entry_##ENAME##_vect_rank(&p_allocator->table, i); \
1050 if(index != (*i)->id) \
1052 NM_MPI_WARNING("inconsistency in " #ENAME " entry; index = %d; id = %d\n", index, (*i)->id); \
1054 if(index >= (OFFSET)) \
1057 if(p_allocator->display != NULL) \
1059 d = (*p_allocator->display)(*i); \
1061 NM_MPI_WARNING("pending object; type = " #ENAME "; id = %d; ptr = %p; %s\n", (*i)->id, *i, \
1063 if(d) padico_free(d); \
1070 __attribute__((unused)) \
1071 static void nm_mpi_handle_##ENAME##_init(struct nm_mpi_handle_##ENAME##_s*p_allocator) \
1073 nm_mpi_entry_##ENAME##_vect_init(&p_allocator->table); \
1074 puk_int_vect_init(&p_allocator->pool); \
1075 p_allocator->next_id = OFFSET; \
1076 nm_mpi_spin_init(&p_allocator->lock); \
1077 p_allocator->display = NULL; \
1078 p_allocator->allocator = ENAME ## _allocator_new(SLABSIZE); \
1080 for(i = 0; i < OFFSET; i++) \
1082 nm_mpi_entry_##ENAME##_vect_push_back(&p_allocator->table, NULL); \
1084 nm_mpi_cleanup_register((void (*)(void*))&nm_mpi_handle_ ## ENAME ## _dump, p_allocator); \
1086 __attribute__((unused)) \
1087 static void nm_mpi_handle_##ENAME##_finalize(struct nm_mpi_handle_##ENAME##_s*p_allocator, void(*destructor)(TYPE*)) \
1089 nm_mpi_cleanup_unregister((void (*)(void*))&nm_mpi_handle_##ENAME##_dump, p_allocator); \
1090 if(NM_MPI_HANDLE_DEBUG) \
1091 nm_mpi_handle_##ENAME##_dump(p_allocator); \
1092 if(destructor != NULL) \
1094 nm_mpi_entry_##ENAME##_vect_itor_t i; \
1095 puk_vect_foreach(i, nm_mpi_entry_##ENAME, &p_allocator->table) \
1099 (*destructor)(*i); \
1103 nm_mpi_entry_##ENAME##_vect_destroy(&p_allocator->table); \
1104 puk_int_vect_destroy(&p_allocator->pool); \
1105 ENAME##_allocator_delete(p_allocator->allocator); \
1106 p_allocator->allocator = NULL; \
1109 __attribute__((unused)) \
1110 static TYPE*nm_mpi_handle_##ENAME##_store(struct nm_mpi_handle_##ENAME##_s*p_allocator, int id) \
1112 assert(nm_mpi_handle_##ENAME##_initialized(p_allocator)); \
1113 TYPE*e = ENAME ## _malloc(p_allocator->allocator); \
1114 if((id <= 0) || (id > OFFSET)) \
1116 NM_MPI_FATAL_ERROR("madmpi: cannot store invalid %s handle id %d\n", #ENAME, id); \
1118 if(nm_mpi_entry_##ENAME##_vect_at(&p_allocator->table, id) != NULL) \
1120 NM_MPI_FATAL_ERROR("madmpi: %s handle %d busy; cannot store.", #ENAME, id); \
1122 nm_mpi_entry_##ENAME##_vect_put(&p_allocator->table, e, id); \
1127 __attribute__((unused)) \
1128 static TYPE*nm_mpi_handle_##ENAME##_alloc(struct nm_mpi_handle_##ENAME##_s*p_allocator) \
1130 assert(nm_mpi_handle_##ENAME##_initialized(p_allocator)); \
1131 TYPE*e = ENAME ## _malloc(p_allocator->allocator); \
1133 nm_mpi_spin_lock(&p_allocator->lock); \
1134 if(puk_int_vect_empty(&p_allocator->pool)) \
1136 new_id = p_allocator->next_id++; \
1137 nm_mpi_entry_##ENAME##_vect_resize(&p_allocator->table, new_id); \
1141 new_id = puk_int_vect_pop_back(&p_allocator->pool); \
1143 nm_mpi_entry_##ENAME##_vect_put(&p_allocator->table, e, new_id); \
1144 nm_mpi_spin_unlock(&p_allocator->lock); \
1149 __attribute__((unused)) \
1150 static void nm_mpi_handle_##ENAME##_release(struct nm_mpi_handle_##ENAME##_s*p_allocator, TYPE*e) \
1152 const int id = e->id; \
1154 nm_mpi_spin_lock(&p_allocator->lock); \
1155 assert(nm_mpi_entry_##ENAME##_vect_at(&p_allocator->table, id) == e); \
1156 nm_mpi_entry_##ENAME##_vect_put(&p_allocator->table, NULL, id); \
1157 puk_int_vect_push_back(&p_allocator->pool, id); \
1159 nm_mpi_spin_unlock(&p_allocator->lock); \
1162 __attribute__((unused)) \
1163 static void nm_mpi_handle_##ENAME##_free(struct nm_mpi_handle_##ENAME##_s*p_allocator, TYPE*e) \
1166 nm_mpi_handle_##ENAME##_release(p_allocator, e); \
1167 ENAME ## _free(p_allocator->allocator, e); \
1170 __attribute__((unused)) \
1171 static TYPE*nm_mpi_handle_##ENAME##_get(struct nm_mpi_handle_##ENAME##_s*p_allocator, int id) \
1173 assert(nm_mpi_handle_##ENAME##_initialized(p_allocator)); \
1175 if((id > 0) && (id < nm_mpi_entry_##ENAME##_vect_size(&p_allocator->table))) \
1177 nm_mpi_spin_lock(&p_allocator->lock); \
1178 e = nm_mpi_entry_##ENAME##_vect_at(&p_allocator->table, id); \
1179 nm_mpi_spin_unlock(&p_allocator->lock); \
1187 __attribute__((unused)) \
1188 static void nm_mpi_handle_##ENAME##_set_display(struct nm_mpi_handle_##ENAME##_s*p_allocator, char*(*display)(TYPE*)) \
1190 p_allocator->display = display; \
1193#define NM_MPI_HANDLE_NULL { .allocator = NULL, .next_id = -1 }
1266 assert(
p_comm->
kind != NM_MPI_COMMUNICATOR_UNSPEC);
1267 if(
p_comm->
kind == NM_MPI_COMMUNICATOR_INTRA)
1269 else if(
p_comm->
kind == NM_MPI_COMMUNICATOR_INTER)
1280 if(
p_comm->
kind == NM_MPI_COMMUNICATOR_INTER)
1321 const char*func,
const char*file,
const int line);
1392#define nm_mpi_datatype_ref_inc(P_DATATYPE, P_HOLDER) nm_mpi_refcount_inc(&(P_DATATYPE)->refcount, (P_HOLDER))
1438 + puk_hash_oneatatime((
const void*)&
p_datatype->
size,
sizeof(
size_t));
1478 assert(p_req != NULL);
1479 assert(p_req->p_datatype2 == NULL);
1545 const void*sendbuf,
void*recvbuf,
1556 const void*sendbuf,
void*recvbuf,
1563 const void*sendbuf,
void*recvbuf,
1604 enum nm_mpi_communicator_kind_e
kind);
1612#define nm_mpi_communicator_ref_inc(P_COMM, P_HOLDER) nm_mpi_refcount_inc(&(P_COMM)->refcount, (P_HOLDER));
1738 return (
tag & 0xF0) >> 4;
1792 if(array_int == NULL)
1796 for(i = 0; i < n; i++)
1798 array_count[i] = array_int[i];
1806 if(array_int == NULL)
1810 for(i = 0; i < n; i++)
1812 array_aint[i] = array_int[i];
1820 if(array_aint == NULL)
1824 for(i = 0; i < n; i++)
1826 array_count[i] = array_aint[i];
1833 if(array_count != NULL)
1834 padico_free(array_count);
1839 if(array_aint != NULL)
1840 padico_free(array_aint);
void(* nm_coll_req_notifier_t)(void *ref)
notification function for collective reqs
nm_gate_vect_t nm_group_t
type for groups; in practice, a vector of gates
nm_status_t nm_cond_status_t
status with synchronization (wait/signal)
static void nm_mpi_refcount_dump(struct nm_mpi_refcount_s *p_refcount __attribute__((unused)))
PUK_LIST_TYPE(nm_mpi_refcount_holder, const void *p_holder;const char *func;const char *file;int line;)
elements for nm_mpi_refcount_s
struct nm_mpi_errhandler_s nm_mpi_errhandler_t
error handler
#define NM_MPI_TAG_PRIVATE_RMA_MASK_SEQ
#define NM_MPI_TAG_PRIVATE_RMA_MASK_WIN
static void nm_mpi_refcount_destroy(struct nm_mpi_refcount_s *p_refcount __attribute__((unused)))
void nm_mpi_info_destructor(char *p_key, char *p_data)
#define nm_mpi_spinlock_t
static void nm_mpi_refcount_inc_internal(struct nm_mpi_refcount_s *p_refcount, const void *p_holder __attribute__((unused)), const char *func __attribute__((unused)), const char *file __attribute__((unused)), const int line __attribute__((unused)))
static int nm_mpi_refcount_dec(struct nm_mpi_refcount_s *p_refcount, const void *p_holder __attribute__((unused)))
decrement refcount for holder; returns refcount (if 0, caller may free ref-counted resource)
#define nm_mpi_spin_unlock(LOCK)
static void nm_mpi_refcount_init(struct nm_mpi_refcount_s *p_refcount, const char *type __attribute__((unused)), int id)
initialize a new refcount object; get the type of object and its ID to make debugging easier
#define nm_mpi_spin_init(LOCK)
struct nm_mpi_errhandler_s * nm_mpi_file_errhandler
default errhandler for files, attached to MPI_FILE_NULL
#define NM_MPI_FATAL_ERROR(...)
#define nm_mpi_spin_destroy(LOCK)
#define nm_mpi_spin_lock(LOCK)
PUK_HASHTABLE_TYPE(nm_mpi_info, char *, char *, &puk_hash_string_default_hash, &puk_hash_string_default_eq, &nm_mpi_info_destructor)
hashtable type for info entries
#define NM_MPI_WARNING(...)
void(* nm_data_apply_t)(void *ptr, nm_len_t len, void *_context)
function to apply to each data chunk upon traversal
without even the implied warranty of !MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE See the GNU !General Public License for more details !mpif h
static nm_gate_t nm_comm_get_gate(nm_comm_t p_comm, int rank)
static nm_session_t nm_comm_get_session(nm_comm_t p_comm)
static int nm_comm_get_dest(nm_comm_t p_comm, nm_gate_t p_gate)
nm_tag_t tag
the user-supplied tag
int nm_group_size(nm_group_t group)
nm_gate_t nm_group_get_gate(nm_group_t p_group, int rank)
main MadMPI public header
void MPI_User_function(void *invec, void *inoutvec, int *len, MPI_Datatype *datatype)
User combination function for reduction.
void MPI_User_function_c(void *invec, void *inoutvec, MPI_Count *len, MPI_Datatype *datatype)
void() MPI_File_errhandler_function(MPI_File *, int *,...)
static nm_tag_t nm_mpi_rma_seq_to_tag(uint16_t seq)
Encode a sequence number inside the tag to handle THREAD_MULTIPLE.
int nm_mpi_irecv_init(nm_mpi_request_t *p_req, int source, nm_mpi_communicator_t *p_comm)
Initialises a receiving request.
void nm_mpi_info_lazy_init(void)
nm_mpi_request_t * nm_mpi_coll_irecv(void *buffer, nm_mpi_count_t count, nm_mpi_datatype_t *p_datatype, int source, nm_tag_t tag, nm_mpi_communicator_t *p_comm)
Receive data sent over the communicator via nm_mpi_coll_isend.
static int nm_mpi_win_valid_assert(int assert)
Check whether or not an assert if only a combination of defined symbols.
void nm_mpi_datatype_unpack(const void *src_ptr, void *dest_ptr, nm_mpi_datatype_t *p_datatype, nm_mpi_count_t count)
static int nm_mpi_communicator_get_dest(nm_mpi_communicator_t *p_comm, nm_gate_t p_gate)
Gets the node associated to the given gate.
nm_mpi_group_t * nm_mpi_group_alloc(void)
Allocate a new internal representation of a group.
int nm_mpi_attr_delete(struct nm_mpi_attrs_s *p_attrs, struct nm_mpi_keyval_s *p_keyval)
void nm_mpi_attrs_lazy_exit(void)
void nm_mpi_datatype_hashtable_insert(nm_mpi_datatype_t *p_datatype)
struct nm_mpi_win_locklist_s nm_mpi_win_locklist_t
void nm_mpi_comm_lazy_init(void)
init communicator sub-system
void nm_mpi_cleanup_unregister(void(*p_func)(void *), void *p_arg)
void nm_mpi_datatype_exchange_init(void)
struct nm_mpi_group_s nm_mpi_group_t
Internal group.
__PUK_SYM_INTERNAL const struct nm_data_ops_s nm_mpi_datatype_ops
void nm_mpi_datatype_deserialize(nm_mpi_datatype_ser_t *p_datatype, MPI_Datatype *p_newtype)
Deserialize a new datatype from the informations given in p_datatype.
nm_mpi_request_t * nm_mpi_coll_isend(const void *buffer, nm_mpi_count_t count, nm_mpi_datatype_t *p_datatype, int dest, nm_tag_t tag, nm_mpi_communicator_t *p_comm)
Collective send over the communicator.
struct nm_coll_req_s * nm_mpi_coll_ialltoall(nm_mpi_communicator_t *p_comm, const void *sendbuf, nm_mpi_count_t sendcount, nm_mpi_datatype_t *p_send_datatype, void *recvbuf, nm_mpi_count_t recvcount, nm_mpi_datatype_t *p_recv_datatype)
int nm_mpi_irecv_start(nm_mpi_request_t *p_req)
Starts a receiving request.
int nm_mpi_win_addr_is_valid(void *base, nm_mpi_aint_t extent, nm_mpi_window_t *p_win)
Check whether base is part of a memory segment attached to p_win, and if the data fit,...
nm_mpi_request_t * nm_mpi_request_alloc_send(nm_mpi_request_type_t type, nm_mpi_count_t count, const void *sbuf, struct nm_mpi_datatype_s *p_datatype, int tag, struct nm_mpi_communicator_s *p_comm)
void nm_mpi_info_update(struct nm_mpi_info_s *p_info_up, struct nm_mpi_info_s *p_info_origin)
Update or add new entry in p_info_origin based on the entry from p_info_up.
#define _NM_MPI_MAX_DATATYPE_SIZE
uint32_t nm_mpi_datatype_hash_t
a hash to identify a datatype across nodes
struct nm_mpi_info_s * nm_mpi_info_alloc(void)
Allocates a new instance of the internal representation of an info.
static int nm_mpi_win_completed_epoch(nm_mpi_win_epoch_t *p_epoch)
Returns whether the epoch requests are all completed.
void nm_mpi_coll_wait(nm_mpi_request_t *p_req)
Wait for the end of the p2p communication over communicator via nm_mpi_coll_isend.
nm_mpi_communicator_t * nm_mpi_communicator_alloc(nm_comm_t p_nm_comm, struct nm_mpi_errhandler_s *p_errhandler, enum nm_mpi_communicator_kind_e kind)
__PUK_SYM_INTERNAL const struct nm_data_ops_s nm_mpi_datatype_serialize_ops
void nm_mpi_win_init(void)
init window sub-system
void nm_mpi_io_exit(void)
MPI_Request id
identifier of the request
void nm_mpi_datatype_exchange_exit(void)
int nm_mpi_isend_start(nm_mpi_request_t *p_req)
Starts a sending request.
nm_gate_t gate
gate of the destination or the source node
void nm_mpi_attrs_destroy(struct nm_mpi_attrs_s *p_old_attrs)
int nm_mpi_attr_put(struct nm_mpi_attrs_s *p_attrs, struct nm_mpi_keyval_s *p_keyval, void *attr_value)
struct nm_mpi_info_s * nm_mpi_info_dup(struct nm_mpi_info_s *p_info)
Duplicates the internal representation of the given info.
struct nm_mpi_datatype_s * p_datatype2
second datatype for collectives that need different types for send & recv; used only for ref counting
void nm_mpi_info_lazy_exit(void)
const void * sbuf
pointer for sending
void nm_mpi_file_request_status_update(nm_mpi_request_t *p_req, struct nm_mpi_status_s *p_status)
int nm_mpi_coll_reduce(nm_mpi_communicator_t *p_comm, int root, nm_mpi_count_t count, nm_mpi_datatype_t *p_datatype, const void *sendbuf, void *recvbuf, nm_tag_t tag, nm_mpi_operator_t *p_operator)
blocking reduce
void nm_mpi_info_free(struct nm_mpi_info_s *p_info)
Frees the given instance of the internal representation of an info.
static nm_session_t nm_mpi_communicator_get_session(nm_mpi_communicator_t *p_comm)
nm_mpi_request_t * nm_mpi_request_alloc(void)
struct nm_coll_req_s * nm_mpi_coll_iallgather(nm_mpi_communicator_t *p_comm, const void *sendbuf, nm_mpi_count_t sendcount, nm_mpi_datatype_t *p_send_datatype, void *recvbuf, nm_mpi_count_t recvcount, nm_mpi_datatype_t *p_recv_datatype)
int nm_mpi_datatype_send(nm_gate_t gate, nm_mpi_datatype_t *p_datatype)
Send a datatype to a distant node identified by its gate.
static void * nm_mpi_datatype_get_ptr(void *buf, nm_mpi_count_t count, const nm_mpi_datatype_t *p_datatype)
get a pointer on the count'th data buffer
int nm_mpi_thread_level_get(int required)
PUK_LIST_DECLARE_TYPE(nm_mpi_request)
int nm_mpi_win_create_keyval_fort(nm_mpi_copy_subroutine_t *win_copy_attr_fn, nm_mpi_delete_subroutine_t *win_delete_attr_fn, int *win_keyval, void *extra_state)
void nm_mpi_op_lazy_init(void)
nm_mpi_request_t * nm_mpi_request_alloc_recv(nm_mpi_count_t count, void *rbuf, struct nm_mpi_datatype_s *p_datatype, int tag, struct nm_mpi_communicator_s *p_comm)
static MPI_Count * nm_mpi_array_count_from_aint(nm_mpi_count_t n, const nm_mpi_aint_t *array_aint)
convert an array of MPI_Aint to an array of counts
static nm_gate_t nm_mpi_communicator_get_gate(nm_mpi_communicator_t *p_comm, int node)
Gets the in/out gate for the given node.
void nm_mpi_datatype_lazy_exit(void)
struct nm_mpi_keyval_s * nm_mpi_keyval_get(int id)
struct nm_mpi_win_pass_mngmt_s nm_mpi_win_pass_mngmt_t
void nm_mpi_group_lazy_exit(void)
void nm_mpi_info_copy(struct nm_mpi_info_s *p_dest_info, struct nm_mpi_info_s *p_src_info)
Copy content o p_src_info into p_dest_info.
void nm_mpi_win_exit(void)
int nm_mpi_type_create_keyval_fort(nm_mpi_copy_subroutine_t *type_copy_attr_fn, nm_mpi_delete_subroutine_t *type_delete_attr_fn, int *type_keyval, void *extra_state)
struct nm_mpi_datatype_s nm_mpi_datatype_t
Internal datatype.
void nm_mpi_op_lazy_exit(void)
nm_mpi_request_t * nm_mpi_request_get(MPI_Request req_id)
struct nm_mpi_datatype_s * p_datatype
type of the exchanged data
nm_mpi_count_t nm_mpi_datatype_get_elements(nm_mpi_datatype_t *p_datatype, nm_len_t size)
get how many base elements from datatype fit into given size
void nm_mpi_comm_lazy_exit(void)
int nm_mpi_win_send_datatype(nm_mpi_datatype_t *p_datatype, int target_rank, nm_mpi_window_t *p_win)
Looks up in the hashtable if the datatype is already exchanged with the target node.
void nm_mpi_info_define(struct nm_mpi_info_s *p_info, const char *p_key, const char *p_value)
Define a value in the given infoset.
void nm_mpi_coll_ireduce_start(struct nm_coll_req_s *p_coll_req)
start an already initialized ireduce
__PUK_SYM_INTERNAL const struct nm_data_ops_s nm_mpi_datatype_wrapper_ops
nm_mpi_communicator_t * p_comm
communicator used for communication
int nm_mpi_request_test(nm_mpi_request_t *p_req)
int() nm_mpi_attr_delete_fn_t(int object_id, int keyval_id, void *attribute_val, void *extra_state)
#define nm_mpi_datatype_ref_inc(P_DATATYPE, P_HOLDER)
increment refcount on given datatype
void nm_mpi_attrs_create(struct nm_mpi_attrs_s *p_attrs, int id)
void * rbuf
pointer used for receiving
nm_mpi_window_t * p_win
corresponding rma window
struct nm_coll_req_s * nm_mpi_coll_ireduce_init(nm_mpi_communicator_t *p_comm, int root, nm_mpi_count_t count, nm_mpi_datatype_t *p_datatype, const void *sendbuf, void *recvbuf, nm_tag_t tag, nm_mpi_operator_t *p_operator, nm_coll_req_notifier_t p_notify, void *ref)
internal implementation of collective Ireduce
void nm_mpi_request_free(nm_mpi_request_t *req)
NM_DATA_TYPE(mpi_datatype, struct nm_data_mpi_datatype_s, &nm_mpi_datatype_ops)
void nm_mpi_session_lazy_exit(void)
static int nm_mpi_win_is_ready(nm_mpi_win_epoch_t *p_epoch)
Check whether the epoch (exposure or acces, passive or active) is opened.
void() nm_mpi_delete_subroutine_t(int *id, int *keyval, void *attribute_val, void *extra_state, int *ierr)
void nm_mpi_datatype_copy(const void *src_buf, nm_mpi_datatype_t *p_src_type, nm_mpi_count_t src_count, void *dest_buf, nm_mpi_datatype_t *p_dest_type, nm_mpi_count_t dest_count)
int user_tag
tag given by the user
void nm_mpi_attr_destructor(struct nm_mpi_keyval_s *p_keyval, void *p_value)
static MPI_Aint * nm_mpi_array_aint_from_int(nm_mpi_count_t n, const int *array_int)
convert an array of int to an array of aint
nm_mpi_datatype_t * nm_mpi_datatype_hashtable_get(nm_mpi_datatype_hash_t datatype_hash)
Gets the internal representation of the given datatype from its hash.
nm_mpi_window_t * nm_mpi_window_get(MPI_Win win)
Gets the internal representation of the given window.
int nm_mpi_comm_create_keyval_fort(nm_mpi_copy_subroutine_t *comm_copy_attr_fn, nm_mpi_delete_subroutine_t *comm_delete_attr_fn, int *comm_keyval, void *extra_state)
struct nm_mpi_keyval_s * nm_mpi_keyval_new(void)
void(* nm_mpi_datatype_apply_t)(void *ptr, nm_len_t len, void *_ref)
function apply to each datatype or sub-datatype upon traversal
static nm_tag_t nm_mpi_rma_create_usertag(uint16_t seq, int user_tag)
Create the tag for private rma operations, without the window encoded id.
void nm_mpi_io_init(void)
init MPI I/O sub-system
void nm_mpi_attrs_lazy_init(void)
int nm_mpi_datatype_ref_dec(nm_mpi_datatype_t *p_datatype, const void *p_holder)
decrements refcount on given datatype, free datatype if refcount reaches 0.
static nm_tag_t nm_mpi_rma_mpi_op_to_tag(MPI_Op op)
Encode an operation id inside the tag for MPI_Accumulate and MPI_Get_accumulate functions.
struct nm_mpi_errhandler_s * nm_mpi_errhandler_alloc(enum nm_mpi_errhandler_kind_e kind, MPI_Handler_function *func)
Allocate a new internal representation of a errhandler.
struct nm_coll_req_s * nm_mpi_coll_ialltoallv(nm_mpi_communicator_t *p_comm, const void *sendbuf, const nm_mpi_count_t *sendcounts, const nm_mpi_aint_t *sdispls, nm_mpi_datatype_t *p_send_datatype, void *recvbuf, const nm_mpi_count_t *recvcounts, const nm_mpi_aint_t *rdispls, nm_mpi_datatype_t *p_recv_datatype)
static int nm_mpi_rma_tag_to_win(nm_tag_t tag)
Decode the win_id from the tag.
void nm_mpi_err_lazy_exit(void)
decrement refcount to 'err' submodule
static MPI_Count * nm_mpi_array_count_from_int(nm_mpi_count_t n, const int *array_int)
convert an array of int to an array of counts
static uint16_t nm_mpi_win_get_next_seq(nm_mpi_window_t *p_win)
Returns the next sequence number for the given window, and increments it, lock free.
int nm_mpi_request_wait(nm_mpi_request_t *p_req)
void nm_mpi_datatype_pack(void *dest_ptr, const void *src_ptr, nm_mpi_datatype_t *p_datatype, nm_mpi_count_t count)
int nm_mpi_irecv(nm_mpi_request_t *p_req, int source, nm_mpi_communicator_t *p_comm)
Receives data.
static MPI_Op nm_mpi_rma_tag_to_mpi_op(nm_tag_t tag)
Decode the operation id from the tag.
nm_mpi_request_t * nm_mpi_request_alloc_icol(nm_mpi_request_type_t type, nm_mpi_count_t count, struct nm_mpi_datatype_s *p_datatype, struct nm_mpi_communicator_s *p_comm)
void nm_mpi_datatype_properties_compute(nm_mpi_datatype_t *p_datatype)
Computes properties for datatype (LB, UB, extent, contig, etc.) Called automatically upon commit or d...
int nm_mpi_file_request_wait(nm_mpi_request_t *p_req)
static nm_mpi_datatype_hash_t nm_mpi_datatype_hash_common(const nm_mpi_datatype_t *p_datatype)
static void nm_mpi_request_add_datatype2(nm_mpi_request_t *p_req, struct nm_mpi_datatype_s *p_datatype2)
attach a second datatype to this request
#define NM_MPI_WIN_UNUSED
int nm_mpi_err_lastused(void)
get the last used error class
static void nm_mpi_array_aint_free(MPI_Aint *array_aint)
static void nm_mpi_data_build(struct nm_data_s *p_data, void *ptr, struct nm_mpi_datatype_s *p_datatype, nm_mpi_count_t count)
build a data descriptor for mpi data
nm_mpi_operator_t * nm_mpi_operator_get(MPI_Op op)
Gets the function associated to the given operator.
struct nm_coll_req_s * p_coll_req
non-blocking nmad native collective
struct nm_coll_req_s * nm_mpi_coll_iallreduce(nm_mpi_communicator_t *p_comm, nm_mpi_count_t count, nm_mpi_datatype_t *p_datatype, const void *sendbuf, void *recvbuf, nm_tag_t tag, nm_mpi_operator_t *p_operator)
static void nm_mpi_request_set_datatype(nm_mpi_request_t *p_req, struct nm_mpi_datatype_s *p_datatype)
attach data to a request
void nm_mpi_rma_init(void)
init rma sub-system
void nm_mpi_request_complete(nm_mpi_request_t *p_req, MPI_Request *request)
void() nm_mpi_copy_subroutine_t(int *id, int *keyval, void *extra_state, void *attribute_val_in, void *attribute_val_out, int *flag, int *ierr)
subroutine types for FORTRAN attributes binding
int nm_mpi_attrs_copy(struct nm_mpi_attrs_s *p_old_attrs, struct nm_mpi_attrs_s *p_new_attrs)
void nm_mpi_errhandler_exec_internal(struct nm_mpi_errhandler_s *p_errhandler, enum nm_mpi_errhandler_kind_e kind, int handle, int err, const char *func, const char *file, const int line)
void nm_mpi_rma_exit(void)
void nm_mpi_cleanup_register(void(*p_func)(void *), void *p_arg)
static void nm_mpi_array_count_free(MPI_Count *array_count)
void nm_mpi_err_lazy_init(void)
increment refcount to 'err' submodule
nm_mpi_communicator_t * nm_mpi_communicator_get(MPI_Comm comm)
Gets the internal representation of the given communicator.
struct nm_mpi_datatype_ser_s nm_mpi_datatype_ser_t
Serialized version of the internal datatype.
nm_mpi_count_t count
number of elements to be exchanged
void nm_mpi_datatype_lazy_init(void)
init datatype subsystem
static uint16_t nm_mpi_rma_tag_to_seq(nm_tag_t tag)
Decode the sequence number from the tag.
struct nm_mpi_communicator_s nm_mpi_communicator_t
Internal communicator.
void nm_mpi_request_lazy_exit(void)
struct nm_mpi_errhandler_s * nm_mpi_errhandler_get(int errhandler, enum nm_mpi_errhandler_kind_e kind)
Gets the internal representation of the given errhandler.
struct nm_mpi_operator_s nm_mpi_operator_t
Internal reduce operators.
PUK_LIST_CREATE_FUNCS(nm_mpi_request)
void nm_mpi_communicator_ref_dec(nm_mpi_communicator_t *p_comm, const void *p_holder)
void nm_mpi_session_lazy_init(void)
void nm_mpi_group_lazy_init(void)
increment refcount for 'group' sub-system
int nm_mpi_isend_init(nm_mpi_request_t *p_req, int dest, nm_mpi_communicator_t *p_comm)
Initialises a sending request.
int nm_mpi_file_request_test(nm_mpi_request_t *p_req)
nm_mpi_win_epoch_t * p_epoch
corresponding epoch management structure for rma operations
size_t nm_mpi_datatype_size(nm_mpi_datatype_t *p_datatype)
Gets the size of the given datatype.
void nm_mpi_datatype_traversal_apply(const void *_content, nm_data_apply_t apply, void *_context)
struct nm_mpi_request_s __attribute__((__may_alias__)) nm_mpi_request_t
Internal communication request.
void nm_mpi_keyval_delete(struct nm_mpi_keyval_s *p_keyval)
struct nm_mpi_info_s * nm_mpi_info_get(MPI_Info info)
Gets the internal representation of the given info.
static nm_tag_t nm_mpi_rma_win_to_tag(int win_id)
Encode a window id inside the tag to handle the multiple windows.
void nm_mpi_operator_apply(void *invec, void *outvec, nm_mpi_count_t count, nm_mpi_datatype_t *p_datatype, nm_mpi_operator_t *p_operator)
Apply the operator to every chunk of data described by p_datatype and pointed by outvec,...
void nm_mpi_request_lazy_init(void)
init request sub-system
int32_t nm_mpi_request_type_t
Type of a communication request.
static nm_tag_t nm_mpi_rma_create_tag(int win_id, uint16_t seq_num, int user_tag)
Create the tag for private rma operations, with the first 32 bits used for window id.
nm_mpi_group_t * nm_mpi_group_get(MPI_Group group)
Gets the internal representation of the given group.
int() nm_mpi_attr_copy_fn_t(int object_id, int keyval_id, void *extra_state, void *attribute_val_in, void *attribute_val_out, int *flag)
generic C type for comm/win/types attributes
nm_mpi_datatype_t * nm_mpi_datatype_get(MPI_Datatype datatype)
Gets the internal representation of the given datatype.
void nm_mpi_attr_get(struct nm_mpi_attrs_s *p_attrs, struct nm_mpi_keyval_s *p_keyval, void **p_attr_value, int *flag)
int nm_mpi_isend(nm_mpi_request_t *p_req, int dest, nm_mpi_communicator_t *p_comm)
Sends data.
int MPI_Op
Operator handle.
int MPI_Grequest_free_function(void *extra_state)
int MPI_Request
Request handle.
int MPI_Grequest_cancel_function(void *extra_state, int complete)
void() MPI_Comm_errhandler_function(MPI_Comm *, int *,...)
int MPI_Group
Group handle.
#define MPI_GRAPH
graph topology
nm_mpi_type_combiner_t
Types of datatypes.
nm_mpi_aint_t MPI_Aint
type that holds an address
int MPI_Comm
Communicator handle.
void() MPI_Win_errhandler_function(MPI_Win *, int *,...)
int MPI_Win
Window handle.
intptr_t nm_mpi_aint_t
internal type for counts
void MPI_Session_errhandler_function(MPI_Session *, int *error_code,...)
int MPI_Grequest_query_function(void *extra_state, MPI_Status *status)
int64_t nm_mpi_count_t
internal type for counts
int MPI_Info
An info opaque object.
#define MPI_MODE_NOPRECEDE
void() MPI_Handler_function(MPI_Comm *, int *,...)
#define MPI_MODE_NOSUCCEED
nm_mpi_count_t MPI_Count
public type for counts
#define MPI_CART
cartesian topology
int MPI_Datatype
Datatype handle.
nm_len_t size
size of the onsided data (not incuding target-side completion)
This is the common public header for NewMad.
uint64_t nm_tag_t
user tags, 64 bits, contained in indirect hashtable
uint64_t nm_len_t
data length used by nmad
nm_coll_req_notifier_t p_notify
notification function for op termination
content for datatype traversal
void * ptr
pointer to base data
struct nm_mpi_datatype_s * p_datatype
datatype describing data layout
nm_mpi_count_t count
number of elements
content for datatype traversal and sending
struct nm_data_mpi_datatype_header_s header
header for datatype
struct nm_data_mpi_datatype_s data
datatype describing data layout
set of operations available on data type.
block of static properties for a given data descriptor
a data descriptor, used to pack/unpack data from app layout to/from contiguous buffers
Connection to another process.
int id
ID of the object this table is attached to (comm, datatype, win, ...)
struct nm_mpi_attr_hashtable_s table
int * dims
number of procs in each dim.
int ndims
number of dimensions
int * periods
whether each dim.
int size
pre-computed size of cartesian topology
int remote_offset
offset of remote group in global nm_comm
int rank
rank of self in local group
nm_group_t p_remote_group
struct nm_mpi_attrs_s attrs
communicator attributes, hashed by keyval descriptor
struct nm_mpi_communicator_s::nm_mpi_cart_topology_s cart_topology
struct nm_mpi_refcount_s refcount
number of references pointing to this type (active communications, handle)
struct nm_mpi_info_s * p_info
info hints
nm_mpi_communicator_kind_e
@ NM_MPI_COMMUNICATOR_INTRA
@ NM_MPI_COMMUNICATOR_UNSPEC
@ NM_MPI_COMMUNICATOR_INTER
enum nm_mpi_communicator_s::nm_mpi_topology_kind_e topo
nm_comm_t p_nm_comm
underlying nmad intra-communicator (or overlay for inter-communicator)
enum nm_mpi_communicator_s::nm_mpi_communicator_kind_e kind
struct nm_mpi_communicator_s::nm_mpi_intercomm_s intercomm
int id
id of the communicator
char * name
communicator name
nm_mpi_errhandler_t * p_errhandler
error handler attached to communicator
struct nm_mpi_datatype_s::@42::@49::nm_mpi_type_indexed_map_s * p_map
int is_contig
whether entirely contiguous
size_t ser_size
size of the datatype once serialized
nm_mpi_count_t blocklength
struct nm_mpi_datatype_s::@42::@45 RESIZED
nm_mpi_datatype_ser_t * p_serialized
serialized version of the type.
struct nm_mpi_refcount_s refcount
number of references pointing to this type (active communications, handle)
nm_mpi_count_t lb
lower bound of type
nm_mpi_count_t elements
number of base elements in the datatype
struct nm_mpi_datatype_s::@42::@46 CONTIGUOUS
struct nm_mpi_datatype_s::@42::@53 SUBARRAY
struct nm_mpi_attrs_s attrs
datatype attributes, hashed by keyval descriptor
nm_mpi_aint_t * array_of_displacements
nm_mpi_aint_t hstride
stride in bytes
int is_compact
whether contiguous && lb == 0 && extent == size
struct nm_data_properties_s props
pre-computed data properties
nm_mpi_count_t * array_of_displacements
struct nm_mpi_datatype_s::@42::@53::nm_mpi_type_subarray_dim_s * p_dims
struct nm_mpi_datatype_s * p_old_type
nm_mpi_aint_t displacement
displacement in multiple of oldtype extent
struct nm_mpi_datatype_s::@42::@50 HINDEXED
struct nm_mpi_datatype_s::@42::@44 DUP
nm_mpi_aint_t stride
stride in multiple of datatype extent
nm_mpi_count_t true_extent
struct nm_mpi_datatype_s::@42::@52 HINDEXED_BLOCK
nm_mpi_count_t count
number of blocks in type map
nm_mpi_datatype_hash_t hash
(probably unique) datatype hash
struct nm_mpi_datatype_s::@42::@47 VECTOR
nm_mpi_count_t extent
extent of type; upper bound is lb + extent
struct nm_mpi_datatype_s::@42::@54 STRUCT
struct nm_mpi_datatype_s::@42::@49 INDEXED
struct nm_mpi_datatype_s::@42::@51 INDEXED_BLOCK
struct nm_mpi_datatype_s::@42::@48 HVECTOR
int committed
whether committed or not
nm_mpi_type_combiner_t combiner
combiner of datatype elements
nm_mpi_datatype_hash_t old_type
nm_mpi_datatype_hash_t old_type
void * DATA
The following array inlined in the structure : MPI_Aint*displacements; < displacement in bytes.
nm_mpi_datatype_hash_t old_type
nm_mpi_datatype_hash_t old_type
void * DATA
The two following arrays inlined in the structure : int*blocklengths; MPI_Aint*displacements; < displ...
nm_mpi_count_t blocklength
nm_mpi_datatype_hash_t old_type
nm_mpi_count_t hstride
stride in bytes
void * DATA
The following array inlined in the structure : int*displacements;.
nm_mpi_datatype_hash_t old_type
void * DATA
The two following arrays inlined in the structure : int*blocklengths; int*displacements; < displaceme...
nm_mpi_datatype_hash_t old_type
nm_mpi_datatype_hash_t old_type
void * DATA
The three following arrays inlined in the structure : nm_mpi_datatype_hash_t*old_types; int*blockleng...
nm_mpi_datatype_hash_t old_type
void * DATA
The three following arrays inlined in the structure : int*sizes; int*subsizes; int*starts;.
nm_mpi_count_t blocklength
nm_mpi_datatype_hash_t old_type
nm_mpi_count_t stride
stride in multiple of datatype extent
Serialized version of the internal datatype.
size_t ser_size
size of the datatype once serialized
nm_mpi_type_combiner_t combiner
combiner of datatype elements
nm_mpi_datatype_hash_t hash
(probably unique) datatype hash
nm_mpi_count_t count
number of blocks in type map
union nm_mpi_datatype_ser_s::nm_mpi_datatype_ser_param_u p
MPI_Comm_errhandler_function * comm_func
enum nm_mpi_errhandler_s::nm_mpi_errhandler_kind_e kind
@ NM_MPI_ERRHANDLER_SESSION
MPI_Handler_function * legacy
union nm_mpi_errhandler_s::@27 function
MPI_Win_errhandler_function * win_func
MPI_File_errhandler_function * file_func
MPI_Session_errhandler_function * session_func
nm_group_t p_nm_group
underlying nmad group
int id
ID of the group (handle)
struct nm_mpi_info_hashtable_s content
hashtable of <keys, values>
a keyval used to index comm/types/win attributes
nm_mpi_attr_delete_fn_t * delete_fn
delete callback function for C binding
struct nm_mpi_refcount_s refcount
number of attributes indexed by this keyval
nm_mpi_delete_subroutine_t * delete_subroutine
delete callback function for Fortran binding
nm_mpi_copy_subroutine_t * copy_subroutine
copy callback function for Fortran binding
void * extra_state
user-supplied pointer given to callbacks
nm_mpi_attr_copy_fn_t * copy_fn
copy callback function for C binding
Internal reduce operators.
MPI_User_function_c * function_c
MPI_User_function * function
a reference-counter that keeps trace of who increments/decrements
Internal communication request.
MPI_Request id
identifier of the request
struct nm_mpi_datatype_s * p_datatype
type of the exchanged data
MPI_Grequest_cancel_function * cancel_fn
nm_mpi_window_t * p_win
corresponding rma window
int user_tag
tag given by the user
nm_mpi_status_t status
status of request
nm_mpi_request_type_t request_type
type of the request
nm_mpi_win_epoch_t * p_epoch
corresponding epoch management structure for rma operations
char static_buf[64]
static buffer of max predefined datatype size
struct nm_mpi_file_op_s * p_file_op
MPI-IO operation.
nm_gate_t gate
gate of the destination or the source node
int request_source
rank of the source node (used for incoming request)
struct nm_mpi_request_s::@30::@32 collective
const void * sbuf
pointer for sending
struct nm_mpi_grequest_s * p_grequest
generalized request
PUK_LIST_LINK(nm_mpi_request)
Link for nm_mpi_reqlist_t lists.
nm_mpi_count_t count
number of elements to be exchanged
MPI_Grequest_query_function * query_fn
MPI_Grequest_free_function * free_fn
nm_sr_request_t request_nmad
nmad request for sendrecv interface
int partitions
number of partitions
struct nm_coll_req_s * p_coll_req
non-blocking nmad native collective
nm_cond_status_t completed
set to NM_STATUS_FINALIZED when user signals completion
void * rbuf
pointer used for receiving
struct nm_mpi_request_s::@30::@34 rma
fields for send/recv requests created by the RMA operations
struct nm_mpi_request_s::@30::nm_mpi_grequest_s grequest
nm_mpi_communicator_t * p_comm
communicator used for communication
struct nm_mpi_datatype_s * p_datatype2
second datatype for collectives that need different types for send & recv; used only for ref counting
int request_error
error status of the request, using MPI error codes
struct nm_mpi_request_s::@30::@33 partitioned
struct nm_mpi_info_s * p_info
nm_mpi_errhandler_t * p_errhandler
error handler attached to session
volatile int mode
window mode for the given pair
uint64_t completed
counter of completed requests
uint64_t nmsg
number of messages exchanges during this epoch
struct nm_mpi_request_list_s pending
pending requests
nm_spinlock_t lock
lock for pending requests access
nm_mpi_win_locklist_t q
lock protected pending lock request list
uint16_t lock_type
current lock type.
uint64_t excl_pending
whether there is an exclusive lock request pending
uint64_t naccess
number of procs that are currently accessing this window
int id
identifier of the window
nm_mpi_win_epoch_t * exposure
nm_mpi_win_epoch_t * access
epoch management
uint16_t next_seq
SEQUENCE/EPOCH NUMBER MANAGEMENT
struct nm_sr_monitor_s monitor
window core monitor for asynchronous call
void * p_base
data base address of the window
nm_spinlock_t lock
memory access protecting lock
int mem_model
window memory model
int myrank
window's rank into the communicator
nm_mpi_win_pass_mngmt_t waiting_queue
management queue for passive target
int * win_ids
Distant windows id.
struct nm_mpi_attrs_s attrs
window attributes, hashed by keyval descriptor
struct nm_mpi_info_s * p_info
WINDOW ATTRIBUTES
int * disp_unit
displacement unit
nm_mpi_errhandler_t * p_errhandler
error handler attached to window
nm_mpi_communicator_t * p_comm
window communicator
char shared_file_name[32]
shared memory file name
nm_mpi_aint_t * size
window's memory size
nm_mpi_request_t ** end_reqs
pending closing exposing epoch requests
struct nm_sr_monitor_s monitor_sync
window core monitor for asynchronous lock
int flavor
bit-vector window's flavor (the function used to allocate the window
uint64_t * msg_count
counter to receive the amount of messages to be expected from a given distant window
int mode
bit-vector OR of MPI_MODE_* constants (used in assert)
nm_mpi_win_locklist_t * pending_ops
pending passive RMA operation
nm_group_t p_group
group of processor that interact with this window
a global monitor to listen to events on the full session
internal defintion of the sendrecv request
combiner specific parameters
struct nm_mpi_datatype_ser_s::nm_mpi_datatype_ser_param_u::nm_mpi_datatype_ser_param_struct_s STRUCT
struct nm_mpi_datatype_ser_s::nm_mpi_datatype_ser_param_u::nm_mpi_datatype_ser_param_subarray_s SUBARRAY
struct nm_mpi_datatype_ser_s::nm_mpi_datatype_ser_param_u::nm_mpi_datatype_ser_param_contiguous_s CONTIGUOUS
struct nm_mpi_datatype_ser_s::nm_mpi_datatype_ser_param_u::nm_mpi_datatype_ser_param_hindexed_s HINDEXED
struct nm_mpi_datatype_ser_s::nm_mpi_datatype_ser_param_u::nm_mpi_datatype_ser_param_dup_s DUP
struct nm_mpi_datatype_ser_s::nm_mpi_datatype_ser_param_u::nm_mpi_datatype_ser_param_hindexed_block_s HINDEXED_BLOCK
struct nm_mpi_datatype_ser_s::nm_mpi_datatype_ser_param_u::nm_mpi_datatype_ser_param_indexed_block_s INDEXED_BLOCK
struct nm_mpi_datatype_ser_s::nm_mpi_datatype_ser_param_u::nm_mpi_datatype_ser_param_resized_s RESIZED
struct nm_mpi_datatype_ser_s::nm_mpi_datatype_ser_param_u::nm_mpi_datatype_ser_param_indexed_s INDEXED
struct nm_mpi_datatype_ser_s::nm_mpi_datatype_ser_param_u::nm_mpi_datatype_ser_param_hvector_s HVECTOR
struct nm_mpi_datatype_ser_s::nm_mpi_datatype_ser_param_u::nm_mpi_datatype_ser_param_vector_s VECTOR