NewMadeleine

Documentation

nm_mpi_private.h
Go to the documentation of this file.
1/*
2 * NewMadeleine
3 * Copyright (C) 2006-2024 (see AUTHORS file)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at
8 * your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 */
16#ifndef NM_MPI_PRIVATE_H
17#define NM_MPI_PRIVATE_H
18
30#include <stdint.h>
31#include <limits.h>
32#include <unistd.h>
33#include <assert.h>
34#include <complex.h>
35#include <execinfo.h>
36#include <sys/stat.h>
37
38#include <Padico/Puk.h>
39#include <nm_private_config.h>
40#include <nm_public.h>
41#include <nm_core_interface.h>
45#include <nm_coll_interface.h>
47#include <nm_private.h>
49#ifdef PIOMAN
50#include <pioman.h>
51#endif /* PIOMAN */
52
53#include "nm_mpi.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)
65
66/* fixed-size floats */
67#if SIZEOF_FLOAT==4
68typedef float nm_mpi_float4_t;
69#elif SIZEOF_DOUBLE==4
70typedef double nm_mpi_float4_t;
71#else
72# error "no C type for 4 bytes floats"
73#endif
74
75#if SIZEOF_FLOAT==8
76typedef float nm_mpi_float8_t;
77#elif SIZEOF_DOUBLE==8
78typedef double nm_mpi_float8_t;
79#else
80# error "no C type for 8 bytes floats"
81#endif
82
84typedef struct nm_mpi_errhandler_s
85{
86 int id;
87 union
88 {
96 {
104
107
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__)
111
113#define NM_MPI_ERROR_INTERNAL(ERRORCODE) (ERRORCODE)
114
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)) ) \
118 , ERRORCODE )
119
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)) ) \
124 , ERRORCODE )
125
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)) ) \
130 , ERRORCODE )
131
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)) ) \
136 , ERRORCODE )
137
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)) ) \
142 , ERRORCODE )
143
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)) ) \
147 , ERRORCODE )
148
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)
153
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)
158
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)
163
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)
168
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)
172
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)
176
177#define NM_MPI_WARNING(...) NM_WARN(__VA_ARGS__)
178
179#define NM_MPI_FATAL_ERROR(...) NM_FATAL(__VA_ARGS__)
180
181#define NM_MPI_TRACE(str, ...) NM_TRACEF(str, ## __VA_ARGS__)
182
183#define FREE_AND_SET_NULL(p) do { padico_free(p); p = NULL; } while (0/*CONSTCOND*/)
184
185
187PUK_LIST_TYPE(nm_mpi_refcount_holder,
188 const void*p_holder;
189 const char*func;
190 const char*file;
191 int line;
192 );
193
196{
198#ifdef NMAD_DEBUG
199 const char*type;
200 int id;
202 struct nm_mpi_refcount_holder_list_s holders;
203#endif /* NMAD_DEBUG */
204};
205
206#define NM_MPI_REFCOUNT_INVALID { .refcount = -1 }
207
209static inline void nm_mpi_refcount_init(struct nm_mpi_refcount_s*p_refcount, const char*type __attribute__((unused)), int id)
210{
211 p_refcount->refcount = 1;
212#ifdef NMAD_DEBUG
213 p_refcount->type = type;
214 p_refcount->id = id;
215 nm_mpi_spin_init(&p_refcount->lock);
216 nm_mpi_refcount_holder_list_init(&p_refcount->holders);
217#endif
218}
219
220static inline void nm_mpi_refcount_dump(struct nm_mpi_refcount_s*p_refcount __attribute__((unused)))
221{
222#ifdef NMAD_DEBUG
223 nm_mpi_refcount_holder_itor_t i;
224 puk_list_foreach(nm_mpi_refcount_holder, i, &p_refcount->holders)
225 {
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);
228 }
229#endif /* NMAD_DEBUG */
230}
231
232static inline void nm_mpi_refcount_destroy(struct nm_mpi_refcount_s*p_refcount __attribute__((unused)))
233{
234#ifdef NMAD_DEBUG
235 nm_mpi_refcount_dump(p_refcount);
236 nm_mpi_spin_destroy(&p_refcount->lock);
237 nm_mpi_refcount_holder_list_destroy(&p_refcount->holders);
238#endif /* NMAD_DEBUG */
239}
240
241#define nm_mpi_refcount_inc(REFCOUNT, HOLDER) \
242 nm_mpi_refcount_inc_internal(REFCOUNT, HOLDER, __FUNCTION__, __FILE__, __LINE__)
243
244static inline void nm_mpi_refcount_inc_internal(struct nm_mpi_refcount_s*p_refcount, const void*p_holder __attribute__((unused)),
245 const char*func __attribute__((unused)),
246 const char*file __attribute__((unused)),
247 const int line __attribute__((unused)))
248{
249 assert(p_refcount->refcount >= 0);
250 __sync_fetch_and_add(&p_refcount->refcount, 1);
251#ifdef NMAD_DEBUG
252 if(p_holder != NULL)
253 {
254 nm_mpi_spin_lock(&p_refcount->lock);
255#if 0
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));
258 if(i != NULL)
259 {
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);
265 }
266#endif /* 0 */
267 struct nm_mpi_refcount_holder_s*h = nm_mpi_refcount_holder_new();
268 h->p_holder = p_holder;
269 h->func = func;
270 h->file = file;
271 h->line = line;
272 nm_mpi_refcount_holder_list_push_back(&p_refcount->holders, h);
273 nm_mpi_spin_unlock(&p_refcount->lock);
274 }
275#endif /* NMAD_DEBUG */
276}
277
279static inline int nm_mpi_refcount_dec(struct nm_mpi_refcount_s*p_refcount, const void*p_holder __attribute__((unused)))
280{
281 const int nb_ref = __sync_sub_and_fetch(&p_refcount->refcount, 1);
282 assert(nb_ref >= 0);
283#ifdef NMAD_DEBUG
284 if(p_holder != NULL)
285 {
286 nm_mpi_spin_lock(&p_refcount->lock);
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));
289 if(i == NULL)
290 {
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);
293 }
294 else
295 {
296 nm_mpi_refcount_holder_list_remove(&p_refcount->holders, i);
297 nm_mpi_refcount_holder_delete(i);
298 }
299 nm_mpi_spin_unlock(&p_refcount->lock);
300 }
301#endif /* NMAD_DEBUG */
302 return nb_ref;
303}
304
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))
362
363
364void nm_mpi_info_destructor(char*p_key, char*p_data);
365
367PUK_HASHTABLE_TYPE(nm_mpi_info, char*, char*,
368 &puk_hash_string_default_hash, &puk_hash_string_default_eq, &nm_mpi_info_destructor);
369
372{
373 int id;
374 struct nm_mpi_info_hashtable_s content;
375};
376
381typedef void (nm_mpi_copy_subroutine_t)(int*id, int*keyval, void*extra_state,
382 void*attribute_val_in, void*attribute_val_out, int*flag, int*ierr);
383typedef void (nm_mpi_delete_subroutine_t)(int*id, int*keyval, void*attribute_val, void*extra_state, int*ierr);
384
386typedef int (nm_mpi_attr_copy_fn_t)(int object_id, int keyval_id, void*extra_state,
387 void*attribute_val_in, void*attribute_val_out, int*flag);
388typedef int (nm_mpi_attr_delete_fn_t)(int object_id, int keyval_id, void*attribute_val, void*extra_state);
389
392{
393 int id;
400};
401
402void nm_mpi_attr_destructor(struct nm_mpi_keyval_s*p_keyval, void*p_value);
403PUK_HASHTABLE_TYPE(nm_mpi_attr, struct nm_mpi_keyval_s*, void*,
404 &puk_hash_pointer_default_hash,
405 &puk_hash_pointer_default_eq,
407
410{
411 struct nm_mpi_attr_hashtable_s table;
412 int id;
413};
414
421typedef struct nm_mpi_group_s
422{
423 int id;
426
429{
430 int id;
435 char*name;
438 {
444 {
450 {
451 int ndims;
452 int*dims;
454 int size;
457 {
460 int rank;
469{
470 int id;
473};
478struct nm_mpi_window_s;
480struct nm_mpi_win_epoch_s;
487typedef int32_t nm_mpi_request_type_t;
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)
506
508#define NM_MPI_REQUEST_COLLECTIVE ((nm_mpi_request_type_t)0x0100)
510#define NM_MPI_REQUEST_PARTITIONED ((nm_mpi_request_type_t)0x0040)
511
512typedef int8_t nm_mpi_status_t;
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
518
519PUK_LIST_DECLARE_TYPE(nm_mpi_request);
520
522typedef struct nm_mpi_request_s
523{
549 union
550 {
551 void*rbuf;
552 const void*sbuf;
554 struct nm_mpi_file_op_s*p_file_op;
555 struct nm_mpi_grequest_s*p_grequest;
556 };
558 union
559 {
560 struct
561 {
564 struct
565 {
568 struct nm_mpi_grequest_s
569 {
576 struct
577 {
580 } rma;
581 };
583 PUK_LIST_LINK(nm_mpi_request);
584} __attribute__((__may_alias__)) nm_mpi_request_t;
585
586PUK_LIST_CREATE_FUNCS(nm_mpi_request);
587
594typedef struct nm_mpi_operator_s
595{
596 int id;
607typedef uint32_t nm_mpi_datatype_hash_t;
608
612{
618 size_t ser_size;
623 {
625 {
629 {
635 {
639 {
645 {
651 {
658 void*DATA;
661 {
668 void*DATA;
671 {
678 void*DATA;
681 {
688 void*DATA;
691 {
693 int ndims;
694 int order;
701 void*DATA;
704 {
711 void*DATA;
713 } p;
715
717typedef struct nm_mpi_datatype_s
718{
719 int id;
737 size_t size;
744 union
745 {
746 struct
747 {
750 struct
751 {
754 struct
755 {
758 struct
759 {
764 struct
765 {
770 struct
771 {
773 struct nm_mpi_type_indexed_map_s
774 {
779 struct
780 {
782 struct nm_mpi_type_hindexed_map_s
783 {
788 struct
789 {
794 struct
795 {
800 struct
801 {
803 int ndims;
804 int order;
805 struct nm_mpi_type_subarray_dim_s
806 {
807 int size;
809 int start;
812 struct
813 {
814 struct nm_mpi_type_struct_map_s
815 {
821 };
822 char*name;
824 size_t ser_size;
828
831{
832 void*ptr;
835};
836__PUK_SYM_INTERNAL extern const struct nm_data_ops_s nm_mpi_datatype_ops;
838
840typedef void (*nm_mpi_datatype_apply_t)(void*ptr, nm_len_t len, void*_ref);
841
843{
847};
848
851{
854};
855__PUK_SYM_INTERNAL extern const struct nm_data_ops_s nm_mpi_datatype_wrapper_ops;
857
858__PUK_SYM_INTERNAL extern const struct nm_data_ops_s nm_mpi_datatype_serialize_ops;
860
870{
872 struct nm_mpi_request_list_s pending;
874
881{
882 volatile int mode;
883 uint64_t nmsg;
884 uint64_t completed;
885};
886
893{
894 uint64_t excl_pending;
895 uint16_t lock_type;
896 uint64_t naccess;
899
904{
906 int id;
910 void*p_base;
931 int mode;
937 char*name;
946 uint16_t next_seq;
951 nm_mpi_request_t**end_reqs;
953 uint64_t*msg_count;
962};
963
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)
983#ifdef NMAD_PROFILE
985struct nm_mpi_profiling_s
986{
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;
990};
991extern struct nm_mpi_profiling_s nm_mpi_profile;
992#endif /* NMAD_PROFILE */
993
994/* ********************************************************* */
995
996#ifdef NMAD_DEBUG
997#define NM_MPI_HANDLE_DEBUG 1
998#else /* NMAD_DEBUG */
999#define NM_MPI_HANDLE_DEBUG 0
1000#endif /* NMAD_DEBUG */
1001
1002
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 \
1009 { \
1010 struct nm_mpi_entry_##ENAME##_vect_s table; \
1011 struct puk_int_vect_s pool; \
1012 int next_id; \
1013 nm_mpi_spinlock_t lock; \
1014 ENAME##_allocator_t allocator; \
1015 char*(*display)(TYPE*); \
1016 }; \
1017 __attribute__((unused)) \
1018 static int nm_mpi_handle_##ENAME##_initialized(struct nm_mpi_handle_##ENAME##_s*p_allocator) \
1019 { \
1020 return (p_allocator->allocator != NULL); \
1021 } \
1022 \
1023 __attribute__((unused)) \
1024 static int nm_mpi_handle_##ENAME##_load(struct nm_mpi_handle_##ENAME##_s*p_allocator) \
1025 { \
1026 int load = 0; \
1027 nm_mpi_entry_##ENAME##_vect_itor_t i; \
1028 puk_vect_foreach(i, nm_mpi_entry_##ENAME, &p_allocator->table) \
1029 { \
1030 if(*i != NULL) \
1031 { \
1032 load++; \
1033 } \
1034 } \
1035 return load; \
1036 } \
1037 \
1038 __attribute__((unused)) \
1039 static void nm_mpi_handle_##ENAME##_dump(struct nm_mpi_handle_##ENAME##_s*p_allocator) \
1040 { \
1041 if( (p_allocator->allocator != NULL) && \
1042 !nm_mpi_entry_##ENAME##_vect_empty(&p_allocator->table)) \
1043 { \
1044 nm_mpi_entry_##ENAME##_vect_itor_t i; \
1045 puk_vect_foreach(i, nm_mpi_entry_##ENAME, &p_allocator->table) \
1046 { \
1047 if(*i != NULL) \
1048 { \
1049 const int index = nm_mpi_entry_##ENAME##_vect_rank(&p_allocator->table, i); \
1050 if(index != (*i)->id) \
1051 { \
1052 NM_MPI_WARNING("inconsistency in " #ENAME " entry; index = %d; id = %d\n", index, (*i)->id); \
1053 } \
1054 if(index >= (OFFSET)) \
1055 { \
1056 char*d = NULL; \
1057 if(p_allocator->display != NULL) \
1058 { \
1059 d = (*p_allocator->display)(*i); \
1060 } \
1061 NM_MPI_WARNING("pending object; type = " #ENAME "; id = %d; ptr = %p; %s\n", (*i)->id, *i, \
1062 (d ? d : "")); \
1063 if(d) padico_free(d); \
1064 } \
1065 } \
1066 } \
1067 } \
1068 } \
1069 \
1070 __attribute__((unused)) \
1071 static void nm_mpi_handle_##ENAME##_init(struct nm_mpi_handle_##ENAME##_s*p_allocator) \
1072 { \
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); \
1079 int i; \
1080 for(i = 0; i < OFFSET; i++) \
1081 { \
1082 nm_mpi_entry_##ENAME##_vect_push_back(&p_allocator->table, NULL); \
1083 } \
1084 nm_mpi_cleanup_register((void (*)(void*))&nm_mpi_handle_ ## ENAME ## _dump, p_allocator); \
1085 } \
1086 __attribute__((unused)) \
1087 static void nm_mpi_handle_##ENAME##_finalize(struct nm_mpi_handle_##ENAME##_s*p_allocator, void(*destructor)(TYPE*)) \
1088 { \
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) \
1093 { \
1094 nm_mpi_entry_##ENAME##_vect_itor_t i; \
1095 puk_vect_foreach(i, nm_mpi_entry_##ENAME, &p_allocator->table) \
1096 { \
1097 if(*i != NULL) \
1098 { \
1099 (*destructor)(*i); \
1100 } \
1101 } \
1102 } \
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; \
1107 } \
1108 \
1109 __attribute__((unused)) \
1110 static TYPE*nm_mpi_handle_##ENAME##_store(struct nm_mpi_handle_##ENAME##_s*p_allocator, int id) \
1111 { \
1112 assert(nm_mpi_handle_##ENAME##_initialized(p_allocator)); \
1113 TYPE*e = ENAME ## _malloc(p_allocator->allocator); \
1114 if((id <= 0) || (id > OFFSET)) \
1115 { \
1116 NM_MPI_FATAL_ERROR("madmpi: cannot store invalid %s handle id %d\n", #ENAME, id); \
1117 } \
1118 if(nm_mpi_entry_##ENAME##_vect_at(&p_allocator->table, id) != NULL) \
1119 { \
1120 NM_MPI_FATAL_ERROR("madmpi: %s handle %d busy; cannot store.", #ENAME, id); \
1121 } \
1122 nm_mpi_entry_##ENAME##_vect_put(&p_allocator->table, e, id); \
1123 e->id = id; \
1124 return e; \
1125 } \
1126 \
1127 __attribute__((unused)) \
1128 static TYPE*nm_mpi_handle_##ENAME##_alloc(struct nm_mpi_handle_##ENAME##_s*p_allocator) \
1129 { \
1130 assert(nm_mpi_handle_##ENAME##_initialized(p_allocator)); \
1131 TYPE*e = ENAME ## _malloc(p_allocator->allocator); \
1132 int new_id = -1; \
1133 nm_mpi_spin_lock(&p_allocator->lock); \
1134 if(puk_int_vect_empty(&p_allocator->pool)) \
1135 { \
1136 new_id = p_allocator->next_id++; \
1137 nm_mpi_entry_##ENAME##_vect_resize(&p_allocator->table, new_id); \
1138 } \
1139 else \
1140 { \
1141 new_id = puk_int_vect_pop_back(&p_allocator->pool); \
1142 } \
1143 nm_mpi_entry_##ENAME##_vect_put(&p_allocator->table, e, new_id); \
1144 nm_mpi_spin_unlock(&p_allocator->lock); \
1145 e->id = new_id; \
1146 return e; \
1147 } \
1148 \
1149 __attribute__((unused)) \
1150 static void nm_mpi_handle_##ENAME##_release(struct nm_mpi_handle_##ENAME##_s*p_allocator, TYPE*e) \
1151 { \
1152 const int id = e->id; \
1153 assert(id > 0); \
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); \
1158 e->id = -1; \
1159 nm_mpi_spin_unlock(&p_allocator->lock); \
1160 } \
1161 \
1162 __attribute__((unused)) \
1163 static void nm_mpi_handle_##ENAME##_free(struct nm_mpi_handle_##ENAME##_s*p_allocator, TYPE*e) \
1164 { \
1165 if(e->id > 0) \
1166 nm_mpi_handle_##ENAME##_release(p_allocator, e); \
1167 ENAME ## _free(p_allocator->allocator, e); \
1168 } \
1169 \
1170 __attribute__((unused)) \
1171 static TYPE*nm_mpi_handle_##ENAME##_get(struct nm_mpi_handle_##ENAME##_s*p_allocator, int id) \
1172 { \
1173 assert(nm_mpi_handle_##ENAME##_initialized(p_allocator)); \
1174 TYPE*e = NULL; \
1175 if((id > 0) && (id < nm_mpi_entry_##ENAME##_vect_size(&p_allocator->table))) \
1176 { \
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); \
1180 } \
1181 else \
1182 { \
1183 return NULL; \
1184 } \
1185 return e; \
1186 } \
1187 __attribute__((unused)) \
1188 static void nm_mpi_handle_##ENAME##_set_display(struct nm_mpi_handle_##ENAME##_s*p_allocator, char*(*display)(TYPE*)) \
1189 { \
1190 p_allocator->display = display; \
1191 }
1192
1193#define NM_MPI_HANDLE_NULL { .allocator = NULL, .next_id = -1 }
1194
1195
1196/* ********************************************************* */
1197
1198/* ** submodules init/exit */
1199
1204
1207
1209
1212
1214
1216
1218
1221
1223
1227
1230
1232
1234
1237
1239
1241
1243
1246
1248
1251
1253
1256
1257void nm_mpi_cleanup_register(void(*p_func)(void*), void*p_arg);
1258void nm_mpi_cleanup_unregister(void(*p_func)(void*), void*p_arg);
1259
1260
1261/* ** Communicators **************************************** */
1262
1265{
1266 assert(p_comm->kind != NM_MPI_COMMUNICATOR_UNSPEC);
1267 if(p_comm->kind == NM_MPI_COMMUNICATOR_INTRA)
1268 return nm_comm_get_gate(p_comm->p_nm_comm, node);
1269 else if(p_comm->kind == NM_MPI_COMMUNICATOR_INTER)
1271 else
1272 NM_MPI_FATAL_ERROR("wrong kind %d for communicator %d.\n", p_comm->kind, p_comm->id);
1273 return NULL;
1274}
1275
1278{
1280 if(p_comm->kind == NM_MPI_COMMUNICATOR_INTER)
1281 {
1284 assert(rank >= 0);
1285 }
1286 return rank;
1287}
1288
1290{
1292}
1293
1294
1295/* ** Groups *********************************************** */
1296
1301
1306
1307
1308/* ** Err handlers ***************************************** */
1309
1314
1319
1320void nm_mpi_errhandler_exec_internal(struct nm_mpi_errhandler_s*p_errhandler, enum nm_mpi_errhandler_kind_e kind, int handle, int err,
1321 const char*func, const char*file, const int line);
1322
1325
1326/* ** Info Operations ************************************** */
1327
1332
1337
1342
1344void nm_mpi_info_define(struct nm_mpi_info_s*p_info, const char*p_key, const char*p_value);
1345
1350
1352void nm_mpi_info_copy(struct nm_mpi_info_s*p_dest_info, struct nm_mpi_info_s*p_src_info);
1353
1359void nm_mpi_info_update(struct nm_mpi_info_s*p_info_up, struct nm_mpi_info_s*p_info_origin);
1360
1361
1362/* ** Datatype functionalities ***************************** */
1363
1368
1369
1372
1377
1382
1383void nm_mpi_datatype_traversal_apply(const void*_content, nm_data_apply_t apply, void*_context);
1384
1390
1392#define nm_mpi_datatype_ref_inc(P_DATATYPE, P_HOLDER) nm_mpi_refcount_inc(&(P_DATATYPE)->refcount, (P_HOLDER))
1393
1394
1397
1399
1401
1402void nm_mpi_datatype_copy(const void*src_buf, nm_mpi_datatype_t*p_src_type, nm_mpi_count_t src_count,
1403 void*dest_buf, nm_mpi_datatype_t*p_dest_type, nm_mpi_count_t dest_count);
1404
1407{
1408 return buf + count * p_datatype->extent;
1409}
1410
1412static inline 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)
1413{
1414 nm_data_mpi_datatype_set(p_data, (struct nm_data_mpi_datatype_s){ .ptr = ptr, .p_datatype = p_datatype, .count = count });
1415}
1416
1422
1429
1431
1433{
1434 nm_mpi_datatype_hash_t z = puk_hash_oneatatime((const void*)&p_datatype->combiner, sizeof(nm_mpi_type_combiner_t))
1435 + puk_hash_oneatatime((const void*)&p_datatype->count, sizeof(MPI_Count))
1436 + puk_hash_oneatatime((const void*)&p_datatype->lb, sizeof(MPI_Aint))
1437 + puk_hash_oneatatime((const void*)&p_datatype->extent, sizeof(MPI_Aint))
1438 + puk_hash_oneatatime((const void*)&p_datatype->size, sizeof(size_t));
1439 return z;
1440}
1441
1442/* ** Requests functions *********************************** */
1443
1444nm_mpi_request_t*nm_mpi_request_alloc(void);
1445
1448
1451
1454
1455void nm_mpi_request_free(nm_mpi_request_t*req);
1456
1457nm_mpi_request_t*nm_mpi_request_get(MPI_Request req_id);
1458
1459int nm_mpi_request_test(nm_mpi_request_t*p_req);
1460
1461int nm_mpi_request_wait(nm_mpi_request_t*p_req);
1462
1463void nm_mpi_request_complete(nm_mpi_request_t*p_req, MPI_Request*request);
1464
1466static inline void nm_mpi_request_set_datatype(nm_mpi_request_t*p_req, struct nm_mpi_datatype_s*p_datatype)
1467{
1468 p_req->p_datatype = p_datatype;
1469 if(p_datatype != NULL)
1471}
1472
1474static inline void nm_mpi_request_add_datatype2(nm_mpi_request_t*p_req, struct nm_mpi_datatype_s*p_datatype2)
1475{
1476 if(p_datatype2 != NULL)
1477 {
1478 assert(p_req != NULL);
1479 assert(p_req->p_datatype2 == NULL);
1480 p_req->p_datatype2 = p_datatype2;
1482 }
1483}
1484
1485void nm_mpi_file_request_status_update(nm_mpi_request_t*p_req, struct nm_mpi_status_s*p_status);
1486
1487int nm_mpi_file_request_test(nm_mpi_request_t*p_req);
1488
1489int nm_mpi_file_request_wait(nm_mpi_request_t*p_req);
1490
1491
1492/* ** Send/recv/status functions *************************** */
1493
1497int nm_mpi_isend_init(nm_mpi_request_t *p_req, int dest, nm_mpi_communicator_t *p_comm);
1498
1502int nm_mpi_isend_start(nm_mpi_request_t *p_req);
1503
1507int nm_mpi_isend(nm_mpi_request_t *p_req, int dest, nm_mpi_communicator_t *p_comm);
1508
1512int nm_mpi_irecv_init(nm_mpi_request_t *p_req, int source, nm_mpi_communicator_t *p_comm);
1513
1517int nm_mpi_irecv_start(nm_mpi_request_t *p_req);
1518
1522int nm_mpi_irecv(nm_mpi_request_t *p_req, int source, nm_mpi_communicator_t *p_comm);
1523
1524
1525/* ** Collectives ****************************************** */
1526
1531
1536
1540void nm_mpi_coll_wait(nm_mpi_request_t*p_req);
1541
1545 const void*sendbuf, void*recvbuf,
1546 nm_tag_t tag, nm_mpi_operator_t*p_operator,
1552
1556 const void*sendbuf, void*recvbuf,
1557 nm_tag_t tag, nm_mpi_operator_t*p_operator);
1558
1559/* ** iallreduce */
1560
1563 const void*sendbuf, void*recvbuf,
1564 nm_tag_t tag, nm_mpi_operator_t*p_operator);
1565
1566/* ** ialltoall */
1567
1569 const void*sendbuf, nm_mpi_count_t sendcount, nm_mpi_datatype_t*p_send_datatype,
1570 void*recvbuf, nm_mpi_count_t recvcount, nm_mpi_datatype_t*p_recv_datatype);
1571
1572/* ** ialltoallv */
1573
1575 const void*sendbuf, const nm_mpi_count_t*sendcounts, const nm_mpi_aint_t*sdispls, nm_mpi_datatype_t*p_send_datatype,
1576 void*recvbuf, const nm_mpi_count_t*recvcounts, const nm_mpi_aint_t*rdispls, nm_mpi_datatype_t*p_recv_datatype);
1577
1578/* ** iallgather */
1579
1581 const void*sendbuf, nm_mpi_count_t sendcount, nm_mpi_datatype_t*p_send_datatype,
1582 void*recvbuf, nm_mpi_count_t recvcount, nm_mpi_datatype_t*p_recv_datatype);
1583
1584
1585/* ** Operators ******************************************** */
1586
1591
1599 nm_mpi_operator_t*p_operator);
1600
1601/* ** Communicator operations ****************************** */
1602
1604 enum nm_mpi_communicator_kind_e kind);
1605
1610
1612#define nm_mpi_communicator_ref_inc(P_COMM, P_HOLDER) nm_mpi_refcount_inc(&(P_COMM)->refcount, (P_HOLDER));
1613
1615
1616
1617/* ** Attributes ******************************************* */
1618
1620
1622
1624
1625void nm_mpi_attrs_create(struct nm_mpi_attrs_s*p_attrs, int id);
1626
1627int nm_mpi_attrs_copy(struct nm_mpi_attrs_s*p_old_attrs, struct nm_mpi_attrs_s*p_new_attrs);
1628
1629void nm_mpi_attrs_destroy(struct nm_mpi_attrs_s*p_old_attrs);
1630
1631int nm_mpi_attr_put(struct nm_mpi_attrs_s*p_attrs, struct nm_mpi_keyval_s*p_keyval, void*attr_value);
1632
1633void nm_mpi_attr_get(struct nm_mpi_attrs_s*p_attrs, struct nm_mpi_keyval_s*p_keyval, void**p_attr_value, int*flag);
1634
1635int nm_mpi_attr_delete(struct nm_mpi_attrs_s*p_attrs, struct nm_mpi_keyval_s*p_keyval);
1636
1637
1638/* ** Window operations *************************************/
1639
1644
1650{
1651 return __sync_fetch_and_add(&p_win->next_seq, 1);
1652}
1653
1658{
1659 int ret = __sync_bool_compare_and_swap(&p_epoch->nmsg, p_epoch->completed, p_epoch->nmsg);
1660 return ret;
1661}
1662
1668{
1669 int ret = NM_MPI_WIN_UNUSED != p_epoch->mode;
1670 return ret;
1671}
1672
1677static inline int nm_mpi_win_valid_assert(int assert)
1678{
1679 int ret = assert >= 0 && assert <= (MPI_MODE_NOCHECK | MPI_MODE_NOSTORE | MPI_MODE_NOPUT
1681 return ret;
1682}
1683
1689
1697
1698
1699/* ** RMA operations *************************************** */
1700
1705{
1706 return (tag & NM_MPI_TAG_PRIVATE_RMA_MASK_WIN) >> 32;
1707}
1708
1712static inline nm_tag_t nm_mpi_rma_win_to_tag(int win_id)
1713{
1714 return ((nm_tag_t)win_id) << 32;
1715}
1716
1720static inline uint16_t nm_mpi_rma_tag_to_seq(nm_tag_t tag)
1721{
1722 return (tag & NM_MPI_TAG_PRIVATE_RMA_MASK_SEQ) >> 8;
1723}
1724
1728static inline nm_tag_t nm_mpi_rma_seq_to_tag(uint16_t seq)
1729{
1730 return (nm_tag_t)((((nm_tag_t)seq) << 8) & 0xFFFF00);
1731}
1732
1737{
1738 return (tag & 0xF0) >> 4;
1739}
1740
1746{
1747 return (nm_tag_t)((((nm_tag_t)op) << 4) & 0xF0);
1748}
1749
1755{
1756 return nm_mpi_rma_seq_to_tag(seq) + (((nm_tag_t)user_tag) & 0xFC0000FF);
1757}
1758
1763static inline nm_tag_t nm_mpi_rma_create_tag(int win_id, uint16_t seq_num, int user_tag)
1764{
1765 return nm_mpi_rma_win_to_tag(win_id) + nm_mpi_rma_create_usertag(seq_num, user_tag);
1766}
1767
1768/* ** Keyval operations *************************************** */
1769
1771 nm_mpi_delete_subroutine_t*comm_delete_attr_fn,
1772 int*comm_keyval, void*extra_state);
1773
1775 nm_mpi_delete_subroutine_t*type_delete_attr_fn,
1776 int*type_keyval, void*extra_state);
1777
1779 nm_mpi_delete_subroutine_t*win_delete_attr_fn,
1780 int*win_keyval, void*extra_state);
1781
1782/* ** Threading ******************************************** */
1783
1784int nm_mpi_thread_level_get(int required);
1785
1786
1787/* ** Large counts ***************************************** */
1788
1790static inline MPI_Count*nm_mpi_array_count_from_int(nm_mpi_count_t n, const int*array_int)
1791{
1792 if(array_int == NULL)
1793 return NULL;
1794 MPI_Count*array_count = padico_malloc(sizeof(MPI_Count) * n);
1796 for(i = 0; i < n; i++)
1797 {
1798 array_count[i] = array_int[i];
1799 }
1800 return array_count;
1801}
1802
1804static inline MPI_Aint*nm_mpi_array_aint_from_int(nm_mpi_count_t n, const int*array_int)
1805{
1806 if(array_int == NULL)
1807 return NULL;
1808 MPI_Aint*array_aint = padico_malloc(sizeof(MPI_Aint) * n);
1810 for(i = 0; i < n; i++)
1811 {
1812 array_aint[i] = array_int[i];
1813 }
1814 return array_aint;
1815}
1816
1819{
1820 if(array_aint == NULL)
1821 return NULL;
1822 MPI_Count*array_count = padico_malloc(sizeof(MPI_Count) * n);
1824 for(i = 0; i < n; i++)
1825 {
1826 array_count[i] = array_aint[i];
1827 }
1828 return array_count;
1829}
1830
1831static inline void nm_mpi_array_count_free(MPI_Count*array_count)
1832{
1833 if(array_count != NULL)
1834 padico_free(array_count);
1835}
1836
1837static inline void nm_mpi_array_aint_free(MPI_Aint*array_aint)
1838{
1839 if(array_aint != NULL)
1840 padico_free(array_aint);
1841}
1842
1843
1846#endif /* NM_MPI_PRIVATE_H */
void(* nm_coll_req_notifier_t)(void *ref)
notification function for collective reqs
Definition: nm_coll.h:36
nm_gate_vect_t nm_group_t
type for groups; in practice, a vector of gates
Definition: nm_group.h:39
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
Definition: nm_data.h:100
without even the implied warranty of !MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE See the GNU !General Public License for more details !mpif h
Definition: mpif.h:19
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
static nm_gate_t p_gate
int nm_group_size(nm_group_t group)
nm_gate_t nm_group_get_gate(nm_group_t p_group, int rank)
uint64_t req
a type of debug request; unused for now
Definition: nm_headers.h:1
uint16_t len
chunk len
Definition: nm_headers.h:0
nm_seq_t seq
sequence number
Definition: nm_headers.h:2
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 *,...)
Definition: nm_mpi_io.h:39
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.
int8_t nm_mpi_status_t
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)
void * extra_state
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
Definition: nm_mpi_private.h:1
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
Definition: nm_mpi_private.h:9
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.
#define MPI_MODE_NOPUT
Definition: nm_mpi_types.h:459
int MPI_Op
Operator handle.
Definition: nm_mpi_types.h:422
int MPI_Grequest_free_function(void *extra_state)
Definition: nm_mpi_types.h:228
int MPI_Request
Request handle.
Definition: nm_mpi_types.h:214
int MPI_Grequest_cancel_function(void *extra_state, int complete)
Definition: nm_mpi_types.h:229
void() MPI_Comm_errhandler_function(MPI_Comm *, int *,...)
Definition: nm_mpi_types.h:507
int MPI_Group
Group handle.
Definition: nm_mpi_types.h:244
#define MPI_GRAPH
graph topology
Definition: nm_mpi_types.h:283
nm_mpi_type_combiner_t
Types of datatypes.
Definition: nm_mpi_types.h:390
nm_mpi_aint_t MPI_Aint
type that holds an address
Definition: nm_mpi_types.h:167
int MPI_Comm
Communicator handle.
Definition: nm_mpi_types.h:268
void() MPI_Win_errhandler_function(MPI_Win *, int *,...)
Definition: nm_mpi_types.h:509
int MPI_Win
Window handle.
Definition: nm_mpi_types.h:450
intptr_t nm_mpi_aint_t
internal type for counts
Definition: nm_mpi_types.h:165
void MPI_Session_errhandler_function(MPI_Session *, int *error_code,...)
Definition: nm_mpi_types.h:512
#define MPI_MODE_NOCHECK
Definition: nm_mpi_types.h:457
int MPI_Grequest_query_function(void *extra_state, MPI_Status *status)
Definition: nm_mpi_types.h:227
int64_t nm_mpi_count_t
internal type for counts
Definition: nm_mpi_types.h:170
int MPI_Info
An info opaque object.
Definition: nm_mpi_types.h:177
#define MPI_MODE_NOPRECEDE
Definition: nm_mpi_types.h:460
void() MPI_Handler_function(MPI_Comm *, int *,...)
Definition: nm_mpi_types.h:505
#define MPI_MODE_NOSUCCEED
Definition: nm_mpi_types.h:461
#define MPI_MODE_NOSTORE
Definition: nm_mpi_types.h:458
nm_mpi_count_t MPI_Count
public type for counts
Definition: nm_mpi_types.h:172
#define MPI_CART
cartesian topology
Definition: nm_mpi_types.h:286
#define MPI_UNDEFINED
Definition: nm_mpi_types.h:152
int MPI_Datatype
Datatype handle.
Definition: nm_mpi_types.h:305
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
Definition: nm_types.h:58
uint64_t nm_len_t
data length used by nmad
Definition: nm_types.h:70
nm_coll_req_notifier_t p_notify
notification function for op termination
nm_coll_req_kind_t kind
nm_mpi_datatype_hash_t datatype_hash
datatype-to-be-send hash
nm_mpi_count_t count
number of elements
nm_mpi_aint_t offset
data offset
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.
Definition: nm_data.h:175
block of static properties for a given data descriptor
Definition: nm_data.h:163
a data descriptor, used to pack/unpack data from app layout to/from contiguous buffers
Definition: nm_data.h:189
Connection to another process.
Definition: nm_gate.h:100
an attribute table
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 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
Internal communicator.
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
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
Internal datatype.
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
size_t size
size of type
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_count_t true_lb
nm_mpi_type_combiner_t combiner
combiner of datatype elements
void * DATA
The following array inlined in the structure : MPI_Aint*displacements; < displacement in bytes.
void * DATA
The two following arrays inlined in the structure : int*blocklengths; MPI_Aint*displacements; < displ...
void * DATA
The following array inlined in the structure : int*displacements;.
void * DATA
The two following arrays inlined in the structure : int*blocklengths; int*displacements; < displaceme...
void * DATA
The three following arrays inlined in the structure : nm_mpi_datatype_hash_t*old_types; int*blockleng...
void * DATA
The three following arrays inlined in the structure : int*sizes; int*subsizes; int*starts;.
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
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
Internal group.
nm_group_t p_nm_group
underlying nmad group
int id
ID of the group (handle)
content for MPI_Info
int id
object ID
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
int id
ID of this keyval.
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
Status handle.
Definition: nm_mpi_types.h:194
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
Content for MPI_Win.
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
char * name
window name
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
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