NewMadeleine

Documentation

« back to PM2 home.
nm_mpi_private.h
Go to the documentation of this file.
1/*
2 * NewMadeleine
3 * Copyright (C) 2006-2026 (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 <sys/stat.h>
36
37#include <Padico/Puk.h>
38#include <nm_private_config.h>
39#include <nm_public.h>
40#include <nm_core_interface.h>
42#include <nm_pack_interface.h>
45
46#include <nm_private.h>
47
48#ifdef PIOMAN
49#include <pioman.h>
50#endif /* PIOMAN */
52#include "nm_mpi_ext.h"
53#include "mpi.h"
54
55#ifndef NM_MPI_H
56#error including mpi.h does not include MadMPI; another mpi.h is in the way.
57#endif /* NM_MPI_H */
58
59#ifdef NM_MPI_EXTRACT_SYMBOLS
60
62#define NM_MPI_ALIAS(SYM_MPI, SYM_INTERNAL) NM_MPI_EXTRACT_SYMBOLS(SYM_MPI, SYM_INTERNAL);
64#else /* NM_MPI_EXTRACT_SYMBOLS */
65
67#define NM_MPI_ALIAS(SYM_MPI, SYM_INTERNAL) \
68 /* enforces symbol type consistency */ \
69 __typeof__(SYM_MPI) SYM_INTERNAL; \
70 /* define public MPI_* symbol */ \
71 __typeof__(SYM_MPI) SYM_MPI __attribute__ ((alias (#SYM_INTERNAL))) __attribute__ ((weak)); \
72 /* define public PMPI_* profiling symbol */ \
73 __typeof__(SYM_MPI) P ## SYM_MPI __attribute__ ((alias (#SYM_INTERNAL)));
77#define NM_MPI_PRIVATE_SYM(SYM_MPI, SYM_INTERNAL) __typeof__(SYM_MPI) SYM_INTERNAL
78
79#include "nm_mpi_private_syms.h"
81#endif /* NM_MPI_EXTRACT_SYMBOLS */
82
88#define nm_mpi_spinlock_t nm_spinlock_t
89#define nm_mpi_spin_init(LOCK) nm_spin_init(LOCK)
90#define nm_mpi_spin_destroy(LOCK) nm_spin_destroy(LOCK)
91#define nm_mpi_spin_lock(LOCK) nm_spin_lock(LOCK)
92#define nm_mpi_spin_unlock(LOCK) nm_spin_unlock(LOCK)
93
94/* fixed-size floats */
95#if SIZEOF_FLOAT==4
96typedef float nm_mpi_float4_t;
97#elif SIZEOF_DOUBLE==4
98typedef double nm_mpi_float4_t;
99#else
100# error "no C type for 4 bytes floats"
101#endif
103#if SIZEOF_FLOAT==8
104typedef float nm_mpi_float8_t;
105#elif SIZEOF_DOUBLE==8
106typedef double nm_mpi_float8_t;
107#else
108# error "no C type for 8 bytes floats"
109#endif
111#ifdef NMAD_FORTRAN
112typedef void (*nm_mpi_errhandler_subroutine_t)(MPI_Fint*, MPI_Fint*);
113#else
115#endif /* NMAD_FORTRAN */
116
146
149
150#define nm_mpi_errhandler_exec(P_ERRHANDLER, KIND, HANDLE, ERR) \
151 nm_mpi_errhandler_exec_internal(P_ERRHANDLER, KIND, HANDLE, ERR, \
152 __FUNCTION__, __FILE__, __LINE__)
153
155#define NM_MPI_ERROR_INTERNAL(ERRORCODE) (ERRORCODE)
156
157#define NM_MPI_ERROR_COMM(P_COMM, ERRORCODE) \
158 ( ( ((ERRORCODE) == MPI_SUCCESS) ? MPI_SUCCESS : \
159 nm_mpi_errhandler_exec((P_COMM)->p_errhandler, NM_MPI_ERRHANDLER_COMM, (P_COMM)->id, (ERRORCODE)) ) \
160 , ERRORCODE )
161
163#define NM_MPI_ERROR_SESSION(P_SESSION, ERRORCODE) \
164 ( ( ((ERRORCODE) == MPI_SUCCESS) ? MPI_SUCCESS : \
165 nm_mpi_errhandler_exec((P_SESSION)->p_errhandler, NM_MPI_ERRHANDLER_SESSION, (P_SESSION)->id, (ERRORCODE)) ) \
166 , ERRORCODE )
167
169#define NM_MPI_ERROR_WIN(P_WIN, ERRORCODE) \
170 ( ( ((ERRORCODE) == MPI_SUCCESS) ? MPI_SUCCESS : \
171 nm_mpi_errhandler_exec((P_WIN)->p_errhandler, NM_MPI_ERRHANDLER_WIN, (P_WIN)->id, (ERRORCODE)) ) \
172 , ERRORCODE )
173
175#define NM_MPI_ERROR_FILE(P_FILE, ERRORCODE) \
176 ( ( ((ERRORCODE) == MPI_SUCCESS) ? MPI_SUCCESS : \
177 nm_mpi_errhandler_exec((P_FILE)->p_errhandler, NM_MPI_ERRHANDLER_FILE, (P_FILE)->id, (ERRORCODE)) ) \
178 , ERRORCODE )
179
181#define NM_MPI_ERROR_FILE_DEFAULT(ERRORCODE) \
182 ( ( ((ERRORCODE) == MPI_SUCCESS) ? MPI_SUCCESS : \
183 nm_mpi_errhandler_exec(nm_mpi_file_errhandler, NM_MPI_ERRHANDLER_FILE, MPI_FILE_NULL, (ERRORCODE)) ) \
184 , ERRORCODE )
185
186#define NM_MPI_ERROR_WORLD(ERRORCODE) \
187 ( ( ((ERRORCODE) == MPI_SUCCESS) ? MPI_SUCCESS : \
188 nm_mpi_errhandler_exec(nm_mpi_communicator_get(MPI_COMM_WORLD)->p_errhandler, NM_MPI_ERRHANDLER_COMM, MPI_COMM_WORLD, (ERRORCODE)) ) \
189 , ERRORCODE )
190
192#define NM_MPI_COMMUNICATOR_CHECK(P_COMM) \
193 PUK_CHECK_TYPE(struct nm_mpi_communicator_s*, P_COMM); \
194 do { if((P_COMM) == NULL) return NM_MPI_ERROR_WORLD(MPI_ERR_COMM); } while(0)
195
197#define NM_MPI_GROUP_CHECK(P_GROUP) \
198 PUK_CHECK_TYPE(struct nm_mpi_group_s*, P_GROUP); \
199 do { if((P_GROUP) == NULL) return NM_MPI_ERROR_WORLD(MPI_ERR_GROUP); } while(0)
200
202#define NM_MPI_SESSION_CHECK(P_SESSION) \
203 PUK_CHECK_TYPE(struct nm_mpi_session_s*, P_SESSION); \
204 do { if((P_SESSION) == NULL) return NM_MPI_ERROR_WORLD(MPI_ERR_SESSION); } while(0)
205
207#define NM_MPI_DATATYPE_CHECK(P_DATATYPE) \
208 PUK_CHECK_TYPE(struct nm_mpi_datatype_s*, P_DATATYPE); \
209 do { if((P_DATATYPE) == NULL) return NM_MPI_ERROR_COMM(p_comm, MPI_ERR_TYPE); } while(0)
210
212#define NM_MPI_TAG_CHECK_RECV(TAG) \
213 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)
214
216#define NM_MPI_TAG_CHECK_SEND(TAG) \
217 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)
218
219#define NM_MPI_WARNING(...) NM_WARN(__VA_ARGS__)
220
221#define NM_MPI_FATAL_ERROR(...) NM_FATAL(__VA_ARGS__)
222
223#define NM_MPI_TRACE(str, ...) NM_TRACEF(str, ## __VA_ARGS__)
224
225#define FREE_AND_SET_NULL(p) do { padico_free(p); p = NULL; } while (0/*CONSTCOND*/)
226
227static inline void nm_mpi_refcount_init(struct nm_refcount_s*p_refcount, const char*type __attribute__((unused)), int id)
228{
229 char*object_id = NULL;
230#ifdef NMAD_DEBUG
231 object_id = padico_string_fmt("type = %s; id = %d", type, id);
232#endif
233 nm_refcount_init(p_refcount, object_id, NULL);
234}
235
236
238#define NM_MPI_TAG_MAX ((nm_tag_t)(0x7FFFFFFF))
240#define NM_MPI_TAG_PRIVATE_MASK ((nm_tag_t)(0x80000000))
242#define NM_MPI_TAG_PRIVATE_BASE ((nm_tag_t)(0xF0000000))
243#define NM_MPI_TAG_PRIVATE_BARRIER ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x11))
244#define NM_MPI_TAG_PRIVATE_BCAST ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x12))
245#define NM_MPI_TAG_PRIVATE_GATHER ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x13))
246#define NM_MPI_TAG_PRIVATE_GATHERV ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x14))
247#define NM_MPI_TAG_PRIVATE_SCATTER ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x15))
248#define NM_MPI_TAG_PRIVATE_SCATTERV ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x16))
249#define NM_MPI_TAG_PRIVATE_ALLTOALL ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x17))
250#define NM_MPI_TAG_PRIVATE_ALLTOALLV ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x18))
251#define NM_MPI_TAG_PRIVATE_REDUCE ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x19))
252#define NM_MPI_TAG_PRIVATE_ALLREDUCE ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x1A))
253#define NM_MPI_TAG_PRIVATE_SCAN ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x1B))
254#define NM_MPI_TAG_PRIVATE_REDUCESCATTER ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x1C))
255#define NM_MPI_TAG_PRIVATE_ALLGATHER ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x1D))
256#define NM_MPI_TAG_PRIVATE_TYPE_ADD ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x21))
257#define NM_MPI_TAG_PRIVATE_TYPE_ADD_ACK ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x22))
258#define NM_MPI_TAG_PRIVATE_WIN_INIT ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x23))
259#define NM_MPI_TAG_PRIVATE_WIN_FENCE ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x24))
260#define NM_MPI_TAG_PRIVATE_WIN_BARRIER ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x25))
261#define NM_MPI_TAG_PRIVATE_COMM_SPLIT ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0xF1))
262#define NM_MPI_TAG_PRIVATE_COMM_CREATE ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0xF2))
263#define NM_MPI_TAG_PRIVATE_COMM_INFO ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0xF3))
264#define NM_MPI_TAG_PRIVATE_FILE_OPEN ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0xF4))
266#define NM_MPI_TAG_PRIVATE_RMA_BASE ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x08000000))
267#define NM_MPI_TAG_PRIVATE_RMA_BASE_SYNC ((nm_tag_t)(NM_MPI_TAG_PRIVATE_BASE | 0x04000000))
268#define NM_MPI_TAG_PRIVATE_RMA_MASK_OP ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE | 0x0F))
269#define NM_MPI_TAG_PRIVATE_RMA_MASK_AOP ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE | 0xF0))
270#define NM_MPI_TAG_PRIVATE_RMA_MASK_FOP ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_MASK_OP | \
271 NM_MPI_TAG_PRIVATE_RMA_MASK_AOP))
272#define NM_MPI_TAG_PRIVATE_RMA_MASK_SEQ ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE | 0xFFFF00))
273#define NM_MPI_TAG_PRIVATE_RMA_MASK_WIN ((nm_tag_t)(0xFFFFFFFF00000000 | NM_MPI_TAG_PRIVATE_RMA_BASE))
274#define NM_MPI_TAG_PRIVATE_RMA_MASK_USER ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_MASK_FOP | \
275 NM_MPI_TAG_PRIVATE_RMA_MASK_SEQ))
276#define NM_MPI_TAG_PRIVATE_RMA_MASK ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_MASK_WIN | \
277 NM_MPI_TAG_PRIVATE_RMA_MASK_USER))
278#define NM_MPI_TAG_PRIVATE_RMA_MASK_SYNC ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE_SYNC | 0xFFFFFFFF000000FF))
279#define NM_MPI_TAG_PRIVATE_RMA_START ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE_SYNC | 0x01))
280#define NM_MPI_TAG_PRIVATE_RMA_END ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE_SYNC | 0x02))
281#define NM_MPI_TAG_PRIVATE_RMA_LOCK ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE_SYNC | 0x13))
282#define NM_MPI_TAG_PRIVATE_RMA_LOCK_R ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE_SYNC | 0x04))
283#define NM_MPI_TAG_PRIVATE_RMA_UNLOCK ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE_SYNC | 0x05))
284#define NM_MPI_TAG_PRIVATE_RMA_UNLOCK_R ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE_SYNC | 0x06))
286#define NM_MPI_TAG_PRIVATE_RMA_OP_CHECK ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE_SYNC | 0x0F))
287#define NM_MPI_TAG_PRIVATE_RMA_PUT ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE | 0x1))
288#define NM_MPI_TAG_PRIVATE_RMA_GET_REQ ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE | 0x2))
289#define NM_MPI_TAG_PRIVATE_RMA_ACC ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE | 0x3))
290#define NM_MPI_TAG_PRIVATE_RMA_GACC_REQ ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE | 0x4))
291#define NM_MPI_TAG_PRIVATE_RMA_FAO_REQ ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE | 0x5))
292#define NM_MPI_TAG_PRIVATE_RMA_CAS_REQ ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE | 0x6))
293#define NM_MPI_TAG_PRIVATE_RMA_REQ_RESP ((nm_tag_t)(NM_MPI_TAG_PRIVATE_RMA_BASE | 0xF))
294
295
296void nm_mpi_info_destructor(char*p_key, char*p_data);
297
299PUK_HASHTABLE_TYPE(nm_mpi_info, char*, char*,
300 &puk_hash_string_default_hash, &puk_hash_string_default_eq, &nm_mpi_info_destructor);
301
304{
305 int id;
306 struct nm_mpi_info_hashtable_s content;
307};
308
312#ifdef NMAD_FORTRAN
314typedef void (nm_mpi_copy_subroutine_t)(MPI_Fint*id, MPI_Fint*keyval, void*extra_state,
315 void*attribute_val_in, void*attribute_val_out, MPI_Fint*flag, MPI_Fint*ierr);
316typedef void (nm_mpi_delete_subroutine_t)(MPI_Fint*id, MPI_Fint*keyval, void*attribute_val, void*extra_state, MPI_Fint*ierr);
317#else /* NMAD_FORTRAN */
320#endif /* NMAD_FORTRAN */
321
323typedef int (nm_mpi_attr_copy_fn_t)(int object_id, int keyval_id, void*extra_state,
324 void*attribute_val_in, void*attribute_val_out, int*flag);
325typedef int (nm_mpi_attr_delete_fn_t)(int object_id, int keyval_id, void*attribute_val, void*extra_state);
326
338
339void nm_mpi_attr_destructor(struct nm_mpi_keyval_s*p_keyval, void*p_value);
340PUK_HASHTABLE_TYPE(nm_mpi_attr, struct nm_mpi_keyval_s*, void*,
341 &puk_hash_pointer_default_hash,
342 &puk_hash_pointer_default_eq,
344
347{
348 struct nm_mpi_attr_hashtable_s table;
349 int id;
350};
351
363
415struct nm_mpi_window_s;
417struct nm_mpi_win_epoch_s;
424typedef int32_t nm_mpi_request_type_t;
425#define NM_MPI_REQUEST_ZERO ((nm_mpi_request_type_t)0x0000)
426#define NM_MPI_REQUEST_RECV ((nm_mpi_request_type_t)0x0001)
427#define NM_MPI_REQUEST_PRECV ((nm_mpi_request_type_t)0x0041)
428#define NM_MPI_REQUEST_PROBE ((nm_mpi_request_type_t)0x0002)
429#define NM_MPI_REQUEST_SEND ((nm_mpi_request_type_t)0x0004)
430#define NM_MPI_REQUEST_RSEND ((nm_mpi_request_type_t)0x0014)
431#define NM_MPI_REQUEST_SSEND ((nm_mpi_request_type_t)0x0024)
432#define NM_MPI_REQUEST_PSEND ((nm_mpi_request_type_t)0x0044)
433#define NM_MPI_REQUEST_FILE ((nm_mpi_request_type_t)0x0008)
434#define NM_MPI_REQUEST_GREQUEST ((nm_mpi_request_type_t)0x0080)
435#define NM_MPI_REQUEST_IBARRIER ((nm_mpi_request_type_t)0x1100)
436#define NM_MPI_REQUEST_IBCAST ((nm_mpi_request_type_t)0x2100)
437#define NM_MPI_REQUEST_IREDUCE ((nm_mpi_request_type_t)0x3100)
438#define NM_MPI_REQUEST_IALLREDUCE ((nm_mpi_request_type_t)0x4100)
439#define NM_MPI_REQUEST_IALLTOALL ((nm_mpi_request_type_t)0x5100)
440#define NM_MPI_REQUEST_IALLTOALLV ((nm_mpi_request_type_t)0x6100)
441#define NM_MPI_REQUEST_IGATHER ((nm_mpi_request_type_t)0x7100)
442#define NM_MPI_REQUEST_IALLGATHER ((nm_mpi_request_type_t)0x8100)
443#define NM_MPI_REQUEST_ISCATTER ((nm_mpi_request_type_t)0x9100)
444
446#define NM_MPI_REQUEST_COLLECTIVE ((nm_mpi_request_type_t)0x0100)
448#define NM_MPI_REQUEST_PARTITIONED ((nm_mpi_request_type_t)0x0040)
449
450typedef int8_t nm_mpi_status_t;
451#define NM_MPI_STATUS_NONE ((nm_mpi_status_t)0x00)
452#define NM_MPI_REQUEST_CANCELLED ((nm_mpi_status_t)0x04)
453#define NM_MPI_REQUEST_PERSISTENT ((nm_mpi_status_t)0x08)
455#define _NM_MPI_MAX_DATATYPE_SIZE 64
456
457PUK_LIST_DECLARE_TYPE(nm_mpi_request);
458
460typedef struct nm_mpi_request_s
461{
487 union
488 {
489 void*rbuf;
490 const void*sbuf;
492 struct nm_mpi_file_op_s*p_file_op;
493 struct nm_mpi_grequest_s*p_grequest;
494 };
496 union
497 {
498 struct
499 {
501 union
502 {
503 struct
504 {
505 int root;
507 struct
508 {
509 int root;
510 const void*sendbuf;
514 struct
515 {
516 const void*sendbuf;
517 void*recvbuf;
518 struct nm_mpi_operator_s*p_op;
520 struct
521 {
522 int root;
526 struct
527 {
528 int root;
532 struct
533 {
537 struct
538 {
539 const void*sendbuf;
540 void*recvbuf;
544 struct
545 {
546 const void*sendbuf;
550 void*recvbuf;
555 };
557 struct
558 {
561 struct nm_mpi_grequest_s
562 {
569 struct
570 {
573 } rma;
574 };
576 PUK_LIST_LINK(nm_mpi_request);
577} __attribute__((__may_alias__)) nm_mpi_request_t;
578
579PUK_LIST_CREATE_FUNCS(nm_mpi_request);
580
600typedef uint32_t nm_mpi_datatype_hash_t;
601
605{
611 size_t ser_size;
616 {
706 } p;
708
710typedef struct nm_mpi_datatype_s
711{
712 int id;
730 size_t size;
737 union
738 {
739 struct
740 {
743 struct
744 {
747 struct
748 {
751 struct
752 {
757 struct
758 {
763 struct
764 {
766 struct nm_mpi_type_indexed_map_s
767 {
768 nm_mpi_count_t blocklength;
772 struct
773 {
775 struct nm_mpi_type_hindexed_map_s
776 {
777 nm_mpi_count_t blocklength;
778 nm_mpi_aint_t displacement;
781 struct
782 {
787 struct
788 {
793 struct
794 {
796 int ndims;
797 int order;
798 struct nm_mpi_type_subarray_dim_s
799 {
800 int size;
802 int start;
805 struct
806 {
807 struct nm_mpi_type_struct_map_s
808 {
809 struct nm_mpi_datatype_s*p_old_type;
810 nm_mpi_count_t blocklength;
811 nm_mpi_aint_t displacement;
814 };
815 char*name;
817 size_t ser_size;
821
829__PUK_SYM_INTERNAL extern const struct nm_data_ops_s nm_mpi_datatype_ops;
831
833typedef void (*nm_mpi_datatype_apply_t)(void*ptr, nm_len_t len, void*_ref);
834
841
848__PUK_SYM_INTERNAL extern const struct nm_data_ops_s nm_mpi_datatype_wrapper_ops;
850
851__PUK_SYM_INTERNAL extern const struct nm_data_ops_s nm_mpi_datatype_serialize_ops;
853
863{
865 struct nm_mpi_request_list_s pending;
867
874{
875 volatile int mode;
876 uint64_t nmsg;
877 uint64_t completed;
878};
879
892
956
959#define NM_MPI_WIN_UNUSED 0
960#define NM_MPI_WIN_ACTIVE_TARGET 1
961#define NM_MPI_WIN_PASSIVE_TARGET 2
962#define NM_MPI_WIN_PASSIVE_TARGET_END 4
963#define NM_MPI_WIN_PASSIVE_TARGET_PENDING 8
968#define NM_MPI_LOCK_NONE ((uint16_t)0)
969#define NM_MPI_LOCK_EXCLUSIVE ((uint16_t)MPI_LOCK_EXCLUSIVE)
970#define NM_MPI_LOCK_SHARED ((uint16_t)MPI_LOCK_SHARED)
971#define _NM_MPI_LOCK_OFFSET ((uint16_t)3)
976#ifdef NMAD_PROFILE
978struct nm_mpi_profiling_s
979{
980 unsigned long cur_req_send, max_req_send;
981 unsigned long cur_req_recv, max_req_recv;
982 unsigned long cur_req_total, max_req_total;
983};
984extern struct nm_mpi_profiling_s nm_mpi_profile;
985#endif /* NMAD_PROFILE */
986
987/* ********************************************************* */
988
989#ifdef NMAD_DEBUG
990#define NM_MPI_HANDLE_DEBUG 1
991#else /* NMAD_DEBUG */
992#define NM_MPI_HANDLE_DEBUG 0
993#endif /* NMAD_DEBUG */
994
995
998#define NM_MPI_HANDLE_TYPE(ENAME, TYPE, OFFSET, SLABSIZE) \
999 PUK_VECT_TYPE(nm_mpi_entry_ ## ENAME, TYPE*); \
1000 NM_ALLOCATOR_TYPE(ENAME, TYPE); \
1001 struct nm_mpi_handle_##ENAME##_s \
1002 { \
1003 struct nm_mpi_entry_##ENAME##_vect_s table; \
1004 struct puk_int_vect_s pool; \
1005 int next_id; \
1006 nm_mpi_spinlock_t lock; \
1007 struct ENAME##_allocator_s allocator; \
1008 char*(*display)(TYPE*); \
1009 }; \
1010 __attribute__((unused)) \
1011 static int nm_mpi_handle_##ENAME##_initialized(struct nm_mpi_handle_##ENAME##_s*p_allocator) \
1012 { \
1013 return (p_allocator->next_id != -1); \
1014 } \
1015 \
1016 __attribute__((unused)) \
1017 static int nm_mpi_handle_##ENAME##_load(struct nm_mpi_handle_##ENAME##_s*p_allocator) \
1018 { \
1019 int load = 0; \
1020 nm_mpi_entry_##ENAME##_vect_itor_t i; \
1021 puk_vect_foreach(i, nm_mpi_entry_##ENAME, &p_allocator->table) \
1022 { \
1023 if(*i != NULL) \
1024 { \
1025 load++; \
1026 } \
1027 } \
1028 return load; \
1029 } \
1030 \
1031 __attribute__((unused)) \
1032 static void nm_mpi_handle_##ENAME##_dump(struct nm_mpi_handle_##ENAME##_s*p_allocator) \
1033 { \
1034 NM_MPI_TRACE("dump pending objects of kind %s\n", #ENAME); \
1035 if( nm_mpi_handle_##ENAME##_initialized(p_allocator) && \
1036 !nm_mpi_entry_##ENAME##_vect_empty(&p_allocator->table)) \
1037 { \
1038 nm_mpi_entry_##ENAME##_vect_itor_t i; \
1039 puk_vect_foreach(i, nm_mpi_entry_##ENAME, &p_allocator->table) \
1040 { \
1041 if(*i != NULL) \
1042 { \
1043 const int index = nm_mpi_entry_##ENAME##_vect_rank(&p_allocator->table, i); \
1044 if(index != (*i)->id) \
1045 { \
1046 NM_MPI_WARNING("inconsistency in " #ENAME " entry; index = %d; id = %d\n", index, (*i)->id); \
1047 } \
1048 if(index >= (OFFSET)) \
1049 { \
1050 char*d = NULL; \
1051 if(p_allocator->display != NULL) \
1052 { \
1053 d = (*p_allocator->display)(*i); \
1054 } \
1055 NM_MPI_WARNING("pending object; type = " #ENAME "; id = %d; ptr = %p; %s\n", (*i)->id, *i, \
1056 (d ? d : "")); \
1057 if(d) padico_free(d); \
1058 } \
1059 } \
1060 } \
1061 } \
1062 } \
1063 \
1064 __attribute__((unused)) \
1065 static void nm_mpi_handle_##ENAME##_init(struct nm_mpi_handle_##ENAME##_s*p_allocator) \
1066 { \
1067 nm_mpi_entry_##ENAME##_vect_init(&p_allocator->table); \
1068 puk_int_vect_init(&p_allocator->pool); \
1069 p_allocator->next_id = OFFSET; \
1070 nm_mpi_spin_init(&p_allocator->lock); \
1071 p_allocator->display = NULL; \
1072 ENAME##_allocator_init(&p_allocator->allocator, SLABSIZE); \
1073 int i; \
1074 for(i = 0; i < OFFSET; i++) \
1075 { \
1076 nm_mpi_entry_##ENAME##_vect_push_back(&p_allocator->table, NULL); \
1077 } \
1078 nm_mpi_cleanup_register((void (*)(void*))&nm_mpi_handle_ ## ENAME ## _dump, p_allocator); \
1079 } \
1080 __attribute__((unused)) \
1081 static void nm_mpi_handle_##ENAME##_finalize(struct nm_mpi_handle_##ENAME##_s*p_allocator, void(*destructor)(TYPE*)) \
1082 { \
1083 nm_mpi_cleanup_unregister((void (*)(void*))&nm_mpi_handle_##ENAME##_dump, p_allocator); \
1084 if(NM_MPI_HANDLE_DEBUG) \
1085 nm_mpi_handle_##ENAME##_dump(p_allocator); \
1086 if(destructor != NULL) \
1087 { \
1088 nm_mpi_entry_##ENAME##_vect_itor_t i; \
1089 puk_vect_foreach(i, nm_mpi_entry_##ENAME, &p_allocator->table) \
1090 { \
1091 if(*i != NULL) \
1092 { \
1093 (*destructor)(*i); \
1094 } \
1095 } \
1096 } \
1097 nm_mpi_entry_##ENAME##_vect_destroy(&p_allocator->table); \
1098 puk_int_vect_destroy(&p_allocator->pool); \
1099 ENAME##_allocator_destroy(&p_allocator->allocator); \
1100 } \
1101 \
1102 __attribute__((unused)) \
1103 static TYPE*nm_mpi_handle_##ENAME##_store(struct nm_mpi_handle_##ENAME##_s*p_allocator, int id) \
1104 { \
1105 assert(nm_mpi_handle_##ENAME##_initialized(p_allocator)); \
1106 TYPE*e = ENAME##_malloc(&p_allocator->allocator); \
1107 if((id <= 0) || (id > OFFSET)) \
1108 { \
1109 NM_MPI_FATAL_ERROR("madmpi: cannot store invalid %s handle id %d\n", #ENAME, id); \
1110 } \
1111 if(nm_mpi_entry_##ENAME##_vect_at(&p_allocator->table, id) != NULL) \
1112 { \
1113 NM_MPI_FATAL_ERROR("madmpi: %s handle %d busy; cannot store.", #ENAME, id); \
1114 } \
1115 nm_mpi_entry_##ENAME##_vect_put(&p_allocator->table, e, id); \
1116 e->id = id; \
1117 return e; \
1118 } \
1119 \
1120 __attribute__((unused)) \
1121 static TYPE*nm_mpi_handle_##ENAME##_alloc(struct nm_mpi_handle_##ENAME##_s*p_allocator) \
1122 { \
1123 assert(nm_mpi_handle_##ENAME##_initialized(p_allocator)); \
1124 TYPE*e = ENAME##_malloc(&p_allocator->allocator); \
1125 int new_id = -1; \
1126 nm_mpi_spin_lock(&p_allocator->lock); \
1127 if(puk_int_vect_empty(&p_allocator->pool)) \
1128 { \
1129 new_id = p_allocator->next_id++; \
1130 nm_mpi_entry_##ENAME##_vect_resize(&p_allocator->table, new_id); \
1131 } \
1132 else \
1133 { \
1134 new_id = puk_int_vect_pop_back(&p_allocator->pool); \
1135 } \
1136 nm_mpi_entry_##ENAME##_vect_put(&p_allocator->table, e, new_id); \
1137 nm_mpi_spin_unlock(&p_allocator->lock); \
1138 e->id = new_id; \
1139 return e; \
1140 } \
1141 \
1142 __attribute__((unused)) \
1143 static void nm_mpi_handle_##ENAME##_release(struct nm_mpi_handle_##ENAME##_s*p_allocator, TYPE*e) \
1144 { \
1145 const int id = e->id; \
1146 assert(id > 0); \
1147 nm_mpi_spin_lock(&p_allocator->lock); \
1148 assert(nm_mpi_entry_##ENAME##_vect_at(&p_allocator->table, id) == e); \
1149 nm_mpi_entry_##ENAME##_vect_put(&p_allocator->table, NULL, id); \
1150 puk_int_vect_push_back(&p_allocator->pool, id); \
1151 e->id = -1; \
1152 nm_mpi_spin_unlock(&p_allocator->lock); \
1153 } \
1154 \
1155 __attribute__((unused)) \
1156 static void nm_mpi_handle_##ENAME##_free(struct nm_mpi_handle_##ENAME##_s*p_allocator, TYPE*e) \
1157 { \
1158 if(e->id > 0) \
1159 nm_mpi_handle_##ENAME##_release(p_allocator, e); \
1160 ENAME##_free(&p_allocator->allocator, e); \
1161 } \
1162 \
1163 __attribute__((unused)) \
1164 static TYPE*nm_mpi_handle_##ENAME##_get(struct nm_mpi_handle_##ENAME##_s*p_allocator, int id) \
1165 { \
1166 assert(nm_mpi_handle_##ENAME##_initialized(p_allocator)); \
1167 TYPE*e = NULL; \
1168 if((id > 0) && (id < nm_mpi_entry_##ENAME##_vect_size(&p_allocator->table))) \
1169 { \
1170 nm_mpi_spin_lock(&p_allocator->lock); \
1171 e = nm_mpi_entry_##ENAME##_vect_at(&p_allocator->table, id); \
1172 nm_mpi_spin_unlock(&p_allocator->lock); \
1173 } \
1174 else \
1175 { \
1176 return NULL; \
1177 } \
1178 return e; \
1179 } \
1180 __attribute__((unused)) \
1181 static void nm_mpi_handle_##ENAME##_set_display(struct nm_mpi_handle_##ENAME##_s*p_allocator, char*(*display)(TYPE*)) \
1182 { \
1183 p_allocator->display = display; \
1184 }
1185
1186#define NM_MPI_HANDLE_NULL { .next_id = -1 }
1187
1188
1189/* ********************************************************* */
1190
1191/* ** submodules init/exit */
1192
1197
1200
1202
1205
1207
1209
1211
1214
1216
1220
1223
1225
1227
1230
1232
1234
1236
1239
1241
1244
1246
1249
1250void nm_mpi_cleanup_register(void(*p_func)(void*), void*p_arg);
1251void nm_mpi_cleanup_unregister(void(*p_func)(void*), void*p_arg);
1252
1253
1254/* ** Communicators **************************************** */
1255
1258{
1259 assert(p_comm->kind != NM_MPI_COMMUNICATOR_UNSPEC);
1260 if(p_comm->kind == NM_MPI_COMMUNICATOR_INTRA)
1261 return nm_comm_get_gate(p_comm->p_nm_comm, node);
1262 else if(p_comm->kind == NM_MPI_COMMUNICATOR_INTER)
1264 else
1265 NM_MPI_FATAL_ERROR("wrong kind %d for communicator %d.\n", p_comm->kind, p_comm->id);
1266 return NULL;
1267}
1268
1271{
1273 if(p_comm->kind == NM_MPI_COMMUNICATOR_INTER)
1274 {
1277 assert(rank >= 0);
1278 }
1279 return rank;
1280}
1281
1286
1287
1288/* ** Groups *********************************************** */
1289
1294
1299
1300
1301/* ** Err handlers ***************************************** */
1302
1308
1313
1314void nm_mpi_errhandler_exec_internal(struct nm_mpi_errhandler_s*p_errhandler, enum nm_mpi_errhandler_kind_e kind, int handle, int err,
1315 const char*func, const char*file, const int line);
1316
1319
1321
1322/* ** Info Operations ************************************** */
1323
1328
1333
1338
1340void nm_mpi_info_define(struct nm_mpi_info_s*p_info, const char*p_key, const char*p_value);
1341
1346
1348void nm_mpi_info_copy(struct nm_mpi_info_s*p_dest_info, struct nm_mpi_info_s*p_src_info);
1349
1355void nm_mpi_info_update(struct nm_mpi_info_s*p_info_up, struct nm_mpi_info_s*p_info_origin);
1356
1357
1358/* ** Datatype functionalities ***************************** */
1359
1364
1365
1368
1373
1378
1379void nm_mpi_datatype_traversal_apply(const void*_content, struct nm_data_op_s*p_op);
1380
1386
1388#define nm_mpi_datatype_ref_inc(P_DATATYPE, P_HOLDER) nm_refcount_inc(&(P_DATATYPE)->refcount, (P_HOLDER))
1389
1390
1393
1396{
1397 return buf + count * p_datatype->extent;
1398}
1399
1402{
1403 nm_data_mpi_datatype_set(p_data, (struct nm_data_mpi_datatype_s){ .ptr = ptr, .p_datatype = p_datatype, .count = count });
1404}
1405
1407static inline void nm_mpi_datatype_pack(void*outbuf, const void*inbuf, nm_mpi_datatype_t*p_datatype, nm_mpi_count_t count)
1408{
1409 struct nm_data_s data;
1410 nm_mpi_data_build(&data, (void*)inbuf, p_datatype, count);
1411 nm_data_copy_from(&data, 0 /* offset */, nm_data_size(&data), outbuf);
1412}
1413
1415static inline void nm_mpi_datatype_unpack(const void*inbuf, void*outbuf, nm_mpi_datatype_t*p_datatype, nm_mpi_count_t count)
1416{
1417 struct nm_data_s data;
1418 nm_mpi_data_build(&data, outbuf, p_datatype, count);
1419 nm_data_copy_to(&data, 0 /* offset */, nm_data_size(&data), inbuf);
1420}
1421
1423static inline void nm_mpi_datatype_copy(const void*src_buf, nm_mpi_datatype_t*p_src_type, nm_mpi_count_t src_count,
1424 void*dest_buf, nm_mpi_datatype_t*p_dest_type, nm_mpi_count_t dest_count)
1425{
1426 struct nm_data_s src_data;
1427 nm_mpi_data_build(&src_data, (void*)src_buf, p_src_type, src_count);
1428 struct nm_data_s dest_data;
1429 nm_mpi_data_build(&dest_data, dest_buf, p_dest_type, dest_count);
1430 nm_data_copy(&dest_data, &src_data);
1431}
1432
1438
1445
1447
1449{
1450 nm_mpi_datatype_hash_t z = puk_hash_oneatatime((const void*)&p_datatype->combiner, sizeof(nm_mpi_type_combiner_t))
1451 + puk_hash_oneatatime((const void*)&p_datatype->count, sizeof(MPI_Count))
1452 + puk_hash_oneatatime((const void*)&p_datatype->lb, sizeof(MPI_Aint))
1453 + puk_hash_oneatatime((const void*)&p_datatype->extent, sizeof(MPI_Aint))
1454 + puk_hash_oneatatime((const void*)&p_datatype->size, sizeof(size_t));
1455 return z;
1456}
1457
1458/* ** Requests functions *********************************** */
1459
1460nm_mpi_request_t*nm_mpi_request_alloc(void);
1461
1464
1467
1470
1471void nm_mpi_request_free(nm_mpi_request_t*req);
1472
1473nm_mpi_request_t*nm_mpi_request_get(MPI_Request req_id);
1474
1475int nm_mpi_request_test(nm_mpi_request_t*p_req);
1476
1477int nm_mpi_request_wait(nm_mpi_request_t*p_req);
1478
1479void nm_mpi_request_complete(nm_mpi_request_t*p_req, MPI_Request*request);
1480
1482static inline void nm_mpi_request_set_datatype(nm_mpi_request_t*p_req, struct nm_mpi_datatype_s*p_datatype)
1483{
1484 p_req->p_datatype = p_datatype;
1485 if(p_datatype != NULL)
1487}
1488
1490static inline void nm_mpi_request_add_datatype2(nm_mpi_request_t*p_req, struct nm_mpi_datatype_s*p_datatype2)
1491{
1492 if(p_datatype2 != NULL)
1493 {
1494 assert(p_req != NULL);
1495 assert(p_req->p_datatype2 == NULL);
1496 p_req->p_datatype2 = p_datatype2;
1498 }
1499}
1500
1501void nm_mpi_file_request_status_update(nm_mpi_request_t*p_req, struct nm_mpi_status_s*p_status);
1502
1503int nm_mpi_file_request_test(nm_mpi_request_t*p_req);
1504
1505int nm_mpi_file_request_wait(nm_mpi_request_t*p_req);
1506
1507
1508/* ** Send/recv/status functions *************************** */
1509
1513int nm_mpi_isend_init(nm_mpi_request_t*p_req, int dest, nm_mpi_communicator_t*p_comm);
1514
1518int nm_mpi_isend_start(nm_mpi_request_t*p_req);
1519
1523int nm_mpi_isend(nm_mpi_request_t*p_req, int dest, nm_mpi_communicator_t*p_comm);
1524
1528int nm_mpi_irecv_init(nm_mpi_request_t*p_req, int source, nm_mpi_communicator_t*p_comm);
1529
1533int nm_mpi_irecv_start(nm_mpi_request_t*p_req);
1534
1538int nm_mpi_irecv(nm_mpi_request_t*p_req, int source, nm_mpi_communicator_t*p_comm);
1539
1540
1541/* ** Collectives ****************************************** */
1542
1547
1552
1556void nm_mpi_coll_wait(nm_mpi_request_t*p_req);
1557
1560int nm_mpi_coll_start(nm_mpi_request_t*p_req);
1561
1562void nm_mpi_coll_free(nm_mpi_request_t*p_req);
1563
1564
1568 const void*sendbuf, void*recvbuf,
1569 nm_tag_t tag, nm_mpi_operator_t*p_operator,
1575
1579 const void*sendbuf, void*recvbuf,
1580 nm_tag_t tag, nm_mpi_operator_t*p_operator);
1581
1585 const void*sendbuf, void*recvbuf,
1586 nm_tag_t tag, nm_mpi_operator_t*p_operator);
1587
1588/* ** iallreduce */
1589
1592 const void*sendbuf, void*recvbuf,
1593 nm_tag_t tag, nm_mpi_operator_t*p_operator);
1594
1595/* ** ialltoall */
1596
1598 const void*sendbuf, nm_mpi_count_t sendcount, nm_mpi_datatype_t*p_send_datatype,
1599 void*recvbuf, nm_mpi_count_t recvcount, nm_mpi_datatype_t*p_recv_datatype);
1600
1601/* ** ialltoallv */
1602
1604 const void*sendbuf, const nm_mpi_count_t*sendcounts, const nm_mpi_aint_t*sdispls, nm_mpi_datatype_t*p_send_datatype,
1605 void*recvbuf, const nm_mpi_count_t*recvcounts, const nm_mpi_aint_t*rdispls, nm_mpi_datatype_t*p_recv_datatype);
1606
1607/* ** Operators ******************************************** */
1608
1613
1621 nm_mpi_operator_t*p_operator);
1622
1623/* ** Communicator operations ****************************** */
1624
1626 enum nm_mpi_communicator_kind_e kind);
1627
1632
1634#define nm_mpi_communicator_ref_inc(P_COMM, P_HOLDER) nm_refcount_inc(&(P_COMM)->refcount, (P_HOLDER));
1635
1637
1638
1639/* ** Attributes ******************************************* */
1640
1642
1644
1646
1647void nm_mpi_attrs_create(struct nm_mpi_attrs_s*p_attrs, int id);
1648
1649int nm_mpi_attrs_copy(struct nm_mpi_attrs_s*p_old_attrs, struct nm_mpi_attrs_s*p_new_attrs);
1650
1651void nm_mpi_attrs_destroy(struct nm_mpi_attrs_s*p_old_attrs);
1652
1653int nm_mpi_attr_put(struct nm_mpi_attrs_s*p_attrs, struct nm_mpi_keyval_s*p_keyval, void*attr_value);
1654
1655void nm_mpi_attr_get(struct nm_mpi_attrs_s*p_attrs, struct nm_mpi_keyval_s*p_keyval, void**p_attr_value, int*flag);
1656
1657int nm_mpi_attr_delete(struct nm_mpi_attrs_s*p_attrs, struct nm_mpi_keyval_s*p_keyval);
1658
1659
1660/* ** Window operations *************************************/
1661
1666
1672{
1673 return __sync_fetch_and_add(&p_win->next_seq, 1);
1674}
1675
1680{
1681 int ret = __sync_bool_compare_and_swap(&p_epoch->nmsg, p_epoch->completed, p_epoch->nmsg);
1682 return ret;
1683}
1684
1690{
1691 int ret = NM_MPI_WIN_UNUSED != p_epoch->mode;
1692 return ret;
1693}
1694
1699static inline int nm_mpi_win_valid_assert(int assert)
1700{
1703 return ret;
1704}
1705
1711
1719
1720
1721/* ** RMA operations *************************************** */
1722
1727{
1728 return (tag & NM_MPI_TAG_PRIVATE_RMA_MASK_WIN) >> 32;
1729}
1730
1734static inline nm_tag_t nm_mpi_rma_win_to_tag(int win_id)
1735{
1736 return ((nm_tag_t)win_id) << 32;
1737}
1738
1742static inline uint16_t nm_mpi_rma_tag_to_seq(nm_tag_t tag)
1743{
1744 return (tag & NM_MPI_TAG_PRIVATE_RMA_MASK_SEQ) >> 8;
1745}
1746
1750static inline nm_tag_t nm_mpi_rma_seq_to_tag(uint16_t seq)
1751{
1752 return (nm_tag_t)((((nm_tag_t)seq) << 8) & 0xFFFF00);
1753}
1754
1759{
1760 return (tag & 0xF0) >> 4;
1761}
1762
1768{
1769 return (nm_tag_t)((((nm_tag_t)op) << 4) & 0xF0);
1770}
1771
1777{
1778 return nm_mpi_rma_seq_to_tag(seq) + (((nm_tag_t)user_tag) & 0xFC0000FF);
1779}
1780
1785static inline nm_tag_t nm_mpi_rma_create_tag(int win_id, uint16_t seq_num, int user_tag)
1786{
1787 return nm_mpi_rma_win_to_tag(win_id) + nm_mpi_rma_create_usertag(seq_num, user_tag);
1788}
1789
1790/* ** Keyval operations *************************************** */
1791
1793 nm_mpi_delete_subroutine_t*comm_delete_attr_fn,
1794 int*comm_keyval, void*extra_state);
1795
1797 nm_mpi_delete_subroutine_t*type_delete_attr_fn,
1798 int*type_keyval, void*extra_state);
1799
1801 nm_mpi_delete_subroutine_t*win_delete_attr_fn,
1802 int*win_keyval, void*extra_state);
1803
1804/* ** Threading ******************************************** */
1805
1806int nm_mpi_thread_level_get(int required);
1807
1808
1809/* ** Large counts ***************************************** */
1810
1812static inline nm_mpi_count_t*nm_mpi_array_count_from_int(nm_mpi_count_t n, const int*array_int)
1813{
1814 if(array_int == NULL)
1815 return NULL;
1816 nm_mpi_count_t*array_count = padico_malloc(sizeof(nm_mpi_count_t) * n);
1818 for(i = 0; i < n; i++)
1819 {
1820 array_count[i] = array_int[i];
1821 }
1822 return array_count;
1823}
1824
1826static inline nm_mpi_aint_t*nm_mpi_array_aint_from_int(nm_mpi_count_t n, const int*array_int)
1827{
1828 if(array_int == NULL)
1829 return NULL;
1830 nm_mpi_aint_t*array_aint = padico_malloc(sizeof(nm_mpi_aint_t) * n);
1832 for(i = 0; i < n; i++)
1833 {
1834 array_aint[i] = array_int[i];
1835 }
1836 return array_aint;
1837}
1838
1841{
1842 if(array_aint == NULL)
1843 return NULL;
1844 nm_mpi_count_t*array_count = padico_malloc(sizeof(nm_mpi_count_t) * n);
1846 for(i = 0; i < n; i++)
1847 {
1848 array_count[i] = array_aint[i];
1849 }
1850 return array_count;
1851}
1852
1854{
1855 if(array_count == NULL)
1856 return NULL;
1857 nm_mpi_count_t*copy_array_count = padico_malloc(sizeof(nm_mpi_count_t) * n);
1859 for(i = 0; i < n; i++)
1860 {
1861 copy_array_count[i] = array_count[i];
1862 }
1863 return copy_array_count;
1864}
1865
1867{
1868 if(array_aint == NULL)
1869 return NULL;
1870 nm_mpi_aint_t*copy_array_aint = padico_malloc(sizeof(nm_mpi_aint_t) * n);
1872 for(i = 0; i < n; i++)
1873 {
1874 copy_array_aint[i] = array_aint[i];
1875 }
1876 return copy_array_aint;
1877}
1878
1879static inline void nm_mpi_array_count_free(nm_mpi_count_t*array_count)
1880{
1881 if(array_count != NULL)
1882 padico_free(array_count);
1883}
1884
1885static inline void nm_mpi_array_aint_free(nm_mpi_aint_t*array_aint)
1886{
1887 if(array_aint != NULL)
1888 padico_free(array_aint);
1889}
1890
1891
1894#endif /* NM_MPI_PRIVATE_H */
void(* nm_coll_req_notifier_t)(void *ref)
notification function for collective reqs
Definition nm_coll.h:131
int nm_group_size(nm_group_t group)
nm_gate_t nm_group_get_gate(nm_group_t p_group, int rank)
struct nm_group_s * nm_group_t
type for groups
Definition nm_group.h:38
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
void nm_mpi_info_destructor(char *p_key, char *p_data)
#define nm_mpi_spinlock_t
void * nm_mpi_errhandler_subroutine_t
static void nm_mpi_refcount_init(struct nm_refcount_s *p_refcount, const char *type __attribute__((unused)), int id)
struct nm_mpi_errhandler_s * nm_mpi_file_errhandler
default errhandler for files, attached to MPI_FILE_NULL
#define NM_MPI_FATAL_ERROR(...)
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
struct nm_core_event_s __attribute__
Definition nm_data.h:539
#define NM_DATA_TYPE(ENAME, CONTENT_TYPE, OPS)
macro to generate typed functions to init/access data fields.
Definition nm_data.h:223
static nm_len_t nm_data_size(const struct nm_data_s *p_data)
returns the amount of data contained in the descriptor
Definition nm_data.h:674
void nm_data_copy(struct nm_data_s *p_dest, struct nm_data_s *p_from)
copy from nm_data to another nm_data
void nm_data_copy_to(const struct nm_data_s *p_data, nm_len_t offset, nm_len_t len, const void *srcbuf)
copy chunk of data from contiguous buffer to user layout
void nm_data_copy_from(const struct nm_data_s *p_data, nm_len_t offset, nm_len_t len, void *destbuf)
copy chunk of data from user layout to contiguous buffer
nm_status_t nm_cond_status_t
status with synchronization (wait/signal)
standard MPI public header
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 void nm_refcount_init(struct nm_refcount_s *p_refcount, char *p_object_id, const void *p_init_holder)
initialize a new refcount object; get the object ID to make debugging easier; we take ownership of ob...
assert(p_data->ops.p_traversal !=NULL)
nm_len_t len
Definition nm_data.h:1007
nm_data_propertie_gpu_preinit & p_data
Definition nm_data.h:539
static nm_gate_t p_gate
uint64_t req
a type of debug request; unused for now
Definition nm_headers.h:1
nm_seq_t seq
sequence number
Definition nm_headers.h:2
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)
void * nm_mpi_copy_subroutine_t
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.
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
static void nm_mpi_array_count_free(nm_mpi_count_t *array_count)
void nm_mpi_comm_lazy_init(void)
init communicator sub-system
void nm_mpi_cleanup_unregister(void(*p_func)(void *), void *p_arg)
int nm_mpi_comm_create_errhandler_fort(nm_mpi_errhandler_subroutine_t subroutine, MPI_Errhandler *errhandler)
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_mpi_count_t recvcount
nm_gate_t gate
gate of the destination or the source node
int root
void nm_mpi_attrs_destroy(struct nm_mpi_attrs_s *p_old_attrs)
struct nm_mpi_errhandler_s * nm_mpi_errhandler_alloc(enum nm_mpi_errhandler_kind_e kind, MPI_Handler_function *func, nm_mpi_errhandler_subroutine_t subroutine)
Allocate a new internal representation of a errhandler.
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_delete_subroutine_t
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)
static nm_mpi_aint_t * nm_mpi_array_aint_copy(nm_mpi_count_t n, const nm_mpi_aint_t *array_aint)
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)
static nm_mpi_count_t * nm_mpi_array_count_copy(nm_mpi_count_t n, const nm_mpi_count_t *array_count)
PUK_LIST_DECLARE_TYPE(nm_mpi_request)
struct nm_mpi_operator_s * p_op
static void nm_mpi_datatype_unpack(const void *inbuf, void *outbuf, nm_mpi_datatype_t *p_datatype, nm_mpi_count_t count)
Unpack data from a contiguous buffers.
void nm_mpi_coll_free(nm_mpi_request_t *p_req)
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)
static void nm_mpi_array_aint_free(nm_mpi_aint_t *array_aint)
const void * sendbuf
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 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_coll_start(nm_mpi_request_t *p_req)
Start a persistent collective.
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)
static nm_mpi_aint_t * 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
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.
int user_tag
tag given by the user
void nm_mpi_attr_destructor(struct nm_mpi_keyval_s *p_keyval, void *p_value)
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.
void * recvbuf
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)
static 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)
Copy data using datatype layout.
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_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 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)
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
nm_mpi_count_t sendcount
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)
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)
int nm_mpi_coll_allreduce(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)
blocking allreduce
void nm_mpi_rma_exit(void)
void nm_mpi_cleanup_register(void(*p_func)(void *), void *p_arg)
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
static nm_mpi_count_t * 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
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.
static void nm_mpi_datatype_pack(void *outbuf, const void *inbuf, nm_mpi_datatype_t *p_datatype, nm_mpi_count_t count)
Pack data into a contiguous buffers.
struct nm_mpi_communicator_s nm_mpi_communicator_t
Internal communicator.
void nm_mpi_datatype_traversal_apply(const void *_content, struct nm_data_op_s *p_op)
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_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.
static nm_mpi_count_t * 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
#define MPI_MODE_NOPUT
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_Errhandler
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 address
void MPI_Session_errhandler_function(MPI_Session *, int *error_code,...)
#define MPI_MODE_NOCHECK
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
#define MPI_MODE_NOSTORE
nm_mpi_count_t MPI_Count
public type for counts
#define MPI_CART
cartesian topology
#define MPI_UNDEFINED
int MPI_Datatype
Datatype handle.
nm_len_t size
size of the onsided data (not incuding target-side completion)
main header for private nmad definitions.
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:56
uint64_t nm_len_t
data length used by nmad
Definition nm_types.h:68
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:189
block of static properties for a given data descriptor
Definition nm_data.h:94
a data descriptor, used to pack/unpack data from app layout to/from contiguous buffers
Definition nm_data.h:200
Connection to another process.
Definition nm_gate.h:109
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_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.
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::@70::@76 HVECTOR
nm_mpi_datatype_ser_t * p_serialized
serialized version of the type.
struct nm_mpi_datatype_s::@70::@81::nm_mpi_type_subarray_dim_s * p_dims
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::@70::@77::nm_mpi_type_indexed_map_s * p_map
struct nm_mpi_attrs_s attrs
datatype attributes, hashed by keyval descriptor
struct nm_mpi_datatype_s::@70::@78 HINDEXED
nm_mpi_aint_t * array_of_displacements
nm_mpi_aint_t hstride
stride in bytes
struct nm_refcount_s refcount
number of references pointing to this type (active communications, handle)
int is_compact
whether contiguous && lb == 0 && extent == size
struct nm_mpi_datatype_s::@70::@72 DUP
struct nm_data_properties_s props
pre-computed data properties
nm_mpi_count_t * array_of_displacements
struct nm_mpi_datatype_s::@70::@75 VECTOR
struct nm_mpi_datatype_s::@70::@73 RESIZED
struct nm_mpi_datatype_s * p_old_type
nm_mpi_aint_t displacement
displacement in multiple of oldtype extent
size_t size
size of type
struct nm_mpi_datatype_s::@70::@82 STRUCT
nm_mpi_aint_t stride
stride in multiple of datatype extent
nm_mpi_count_t true_extent
nm_mpi_count_t count
number of blocks in type map
struct nm_mpi_datatype_s::@70::@81 SUBARRAY
nm_mpi_datatype_hash_t hash
(probably unique) datatype hash
struct nm_mpi_datatype_s::@70::@74 CONTIGUOUS
nm_mpi_count_t extent
extent of type; upper bound is lb + extent
struct nm_mpi_datatype_s::@70::@77 INDEXED
struct nm_mpi_datatype_s::@70::@80 HINDEXED_BLOCK
int committed
whether committed or not
nm_mpi_count_t true_lb
nm_mpi_type_combiner_t combiner
combiner of datatype elements
struct nm_mpi_datatype_s::@70::@79 INDEXED_BLOCK
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
union nm_mpi_errhandler_s::@34 function
nm_mpi_errhandler_subroutine_t legacy
nm_mpi_errhandler_subroutine_t win_subroutine
nm_mpi_errhandler_subroutine_t session_subroutine
enum nm_mpi_errhandler_s::nm_mpi_errhandler_kind_e kind
union nm_mpi_errhandler_s::@35 subroutine
nm_mpi_errhandler_subroutine_t file_subroutine
MPI_Handler_function * legacy
nm_mpi_errhandler_subroutine_t comm_subroutine
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_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
Internal communication request.
MPI_Request id
identifier of the request
struct nm_data_s * p_send_data
struct nm_mpi_datatype_s * p_datatype
type of the exchanged data
MPI_Grequest_cancel_function * cancel_fn
nm_mpi_count_t * p_recvcounts
nm_mpi_window_t * p_win
corresponding rma window
nm_mpi_aint_t * p_sdispls
int user_tag
tag given by the user
const void * sendbuf
nm_mpi_status_t status
status of request
nm_mpi_request_type_t request_type
type of the request
struct nm_data_s recv_data
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_request_s::@38::@40::@43::@50 allgather
struct nm_mpi_request_s::@38::@42 rma
fields for send/recv requests created by the RMA operations
struct nm_mpi_file_op_s * p_file_op
MPI-IO operation.
nm_gate_t gate
gate of the destination or the source node
struct nm_mpi_request_s::@38::@40::@43::@48 scatter
struct nm_mpi_request_s::@38::@40 collective
struct nm_mpi_datatype_s * p_sendtype
struct nm_mpi_request_s::@38::@40::@43::@46 reduce
nm_mpi_count_t * p_sendcounts
struct nm_mpi_request_s::@38::nm_mpi_grequest_s grequest
nm_mpi_count_t sendcount
int request_source
rank of the source node (used for incoming request)
struct nm_mpi_request_s::@38::@40::@43::@51 alltoall
struct nm_mpi_request_s::@38::@40::@43::@45 bcast
nm_mpi_aint_t * p_rdispls
struct nm_mpi_datatype_s * p_recvtype
const void * sbuf
pointer for sending
struct nm_mpi_grequest_s * p_grequest
generalized request
struct nm_mpi_request_s::@38::@40::@43::@47 allreduce
PUK_LIST_LINK(nm_mpi_request)
Link for nm_mpi_reqlist_t lists.
struct nm_mpi_request_s::@38::@41 partitioned
nm_mpi_count_t count
number of elements to be exchanged
struct nm_mpi_request_s::@38::@40::@43::@49 gather
MPI_Grequest_query_function * query_fn
MPI_Grequest_free_function * free_fn
struct nm_mpi_request_s::@38::@40::@43::@52 alltoallv
nm_mpi_count_t recvcount
nm_sr_request_t request_nmad
nmad request for sendrecv interface
int partitions
number of partitions
struct nm_mpi_operator_s * p_op
struct nm_coll_req_s * p_coll_req
non-blocking nmad native collective
struct nm_data_s * p_recv_data
nm_cond_status_t completed
set to NM_STATUS_FINALIZED when user signals completion
struct nm_data_s send_data
void * rbuf
pointer used for receiving
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_info_s * p_info
nm_mpi_errhandler_t * p_errhandler
error handler attached to session
Status handle.
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 reference-counter that keeps trace of who increments/decrements in debug: full reference tracking i...
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