From f2aef77e744fd60cd4a38e7e497e761be8a7c138 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 29 Sep 2021 09:39:57 -0500 Subject: [PATCH 001/607] ch4: move mpidig sources and unify mpidig prefix The generic implementation code are split between ch4r, mpidig, and mpdiig_am prefix. This makes navigating code difficult. This patch moves all generic code back into src/mpid/ch4/src folder and unify the prefix to use mpidig_. ch4r_init.h and ch4r_init.c are merged into mpidig.h and mpidig_init.c. ch4r_callbacks.[ch] are renamed into mpidig_pt2pt_callbacks.[ch]. ch4r_rma_{origin,target}_callbacks.[ch] are merged into mpidig_rma_callbacks.[ch]. --- src/mpid/ch4/Makefile.mk | 1 - src/mpid/ch4/generic/Makefile.mk | 6 - src/mpid/ch4/generic/am/Makefile.mk | 21 --- src/mpid/ch4/include/mpidch4.h | 2 +- src/mpid/ch4/include/mpidch4r.h | 32 ++-- src/mpid/ch4/netmod/ofi/ofi_impl.h | 1 - src/mpid/ch4/src/Makefile.mk | 41 +++-- src/mpid/ch4/src/ch4_impl.h | 2 +- src/mpid/ch4/src/ch4_win.h | 2 +- src/mpid/ch4/src/ch4r_init.c | 57 ------ src/mpid/ch4/src/ch4r_init.h | 14 -- src/mpid/ch4/src/ch4r_rma_origin_callbacks.c | 167 ------------------ src/mpid/ch4/src/ch4r_rma_origin_callbacks.h | 29 --- .../{generic/am/mpidig_am.h => src/mpidig.h} | 11 +- .../mpidig_comm_abort.c} | 0 .../am/mpidig_am_init.c => src/mpidig_init.c} | 51 +++++- .../am/mpidig_am_part.c => src/mpidig_part.c} | 2 +- .../am/mpidig_am_part.h => src/mpidig_part.h} | 2 +- .../mpidig_part_callbacks.c} | 4 +- .../mpidig_part_callbacks.h} | 6 +- .../mpidig_part_utils.h} | 6 +- .../ch4/src/{ch4r_probe.h => mpidig_probe.h} | 6 +- ...r_callbacks.c => mpidig_pt2pt_callbacks.c} | 2 +- ...r_callbacks.h => mpidig_pt2pt_callbacks.h} | 8 +- .../am/mpidig_am_recv.h => src/mpidig_recv.h} | 6 +- .../mpidig_recv_utils.h} | 6 +- .../ch4/src/{ch4r_recvq.c => mpidig_recvq.c} | 2 +- .../ch4/src/{ch4r_recvq.h => mpidig_recvq.h} | 7 +- .../mpidig_req_cache.h} | 6 +- .../src/{ch4r_request.h => mpidig_request.h} | 6 +- src/mpid/ch4/src/{ch4r_rma.h => mpidig_rma.h} | 6 +- ...get_callbacks.c => mpidig_rma_callbacks.c} | 167 +++++++++++++++++- ...get_callbacks.h => mpidig_rma_callbacks.h} | 38 +++- .../am/mpidig_am_send.h => src/mpidig_send.h} | 6 +- .../mpidig_send_utils.h} | 6 +- .../ch4/src/{ch4r_util.h => mpidig_util.h} | 0 src/mpid/ch4/src/{ch4r_win.c => mpidig_win.c} | 2 +- src/mpid/ch4/src/{ch4r_win.h => mpidig_win.h} | 6 +- 38 files changed, 341 insertions(+), 396 deletions(-) delete mode 100644 src/mpid/ch4/generic/Makefile.mk delete mode 100644 src/mpid/ch4/generic/am/Makefile.mk delete mode 100644 src/mpid/ch4/src/ch4r_init.c delete mode 100644 src/mpid/ch4/src/ch4r_init.h delete mode 100644 src/mpid/ch4/src/ch4r_rma_origin_callbacks.c delete mode 100644 src/mpid/ch4/src/ch4r_rma_origin_callbacks.h rename src/mpid/ch4/{generic/am/mpidig_am.h => src/mpidig.h} (94%) rename src/mpid/ch4/{generic/am/mpidig_am_comm_abort.c => src/mpidig_comm_abort.c} (100%) rename src/mpid/ch4/{generic/am/mpidig_am_init.c => src/mpidig_init.c} (91%) rename src/mpid/ch4/{generic/am/mpidig_am_part.c => src/mpidig_part.c} (99%) rename src/mpid/ch4/{generic/am/mpidig_am_part.h => src/mpidig_part.h} (99%) rename src/mpid/ch4/{generic/am/mpidig_am_part_callbacks.c => src/mpidig_part_callbacks.c} (98%) rename src/mpid/ch4/{generic/am/mpidig_am_part_callbacks.h => src/mpidig_part_callbacks.h} (82%) rename src/mpid/ch4/{generic/am/mpidig_am_part_utils.h => src/mpidig_part_utils.h} (96%) rename src/mpid/ch4/src/{ch4r_probe.h => mpidig_probe.h} (96%) rename src/mpid/ch4/src/{ch4r_callbacks.c => mpidig_pt2pt_callbacks.c} (99%) rename src/mpid/ch4/src/{ch4r_callbacks.h => mpidig_pt2pt_callbacks.h} (88%) rename src/mpid/ch4/{generic/am/mpidig_am_recv.h => src/mpidig_recv.h} (99%) rename src/mpid/ch4/{generic/am/mpidig_am_recv_utils.h => src/mpidig_recv_utils.h} (99%) rename src/mpid/ch4/src/{ch4r_recvq.c => mpidig_recvq.c} (99%) rename src/mpid/ch4/src/{ch4r_recvq.h => mpidig_recvq.h} (98%) rename src/mpid/ch4/{generic/am/mpidig_am_req_cache.h => src/mpidig_req_cache.h} (93%) rename src/mpid/ch4/src/{ch4r_request.h => mpidig_request.h} (98%) rename src/mpid/ch4/src/{ch4r_rma.h => mpidig_rma.h} (99%) rename src/mpid/ch4/src/{ch4r_rma_target_callbacks.c => mpidig_rma_callbacks.c} (95%) rename src/mpid/ch4/src/{ch4r_rma_target_callbacks.h => mpidig_rma_callbacks.h} (85%) rename src/mpid/ch4/{generic/am/mpidig_am_send.h => src/mpidig_send.h} (98%) rename src/mpid/ch4/{generic/am/mpidig_am_send_utils.h => src/mpidig_send_utils.h} (95%) rename src/mpid/ch4/src/{ch4r_util.h => mpidig_util.h} (100%) rename src/mpid/ch4/src/{ch4r_win.c => mpidig_win.c} (99%) rename src/mpid/ch4/src/{ch4r_win.h => mpidig_win.h} (99%) diff --git a/src/mpid/ch4/Makefile.mk b/src/mpid/ch4/Makefile.mk index 00123dcfe2c..5b7bde33523 100644 --- a/src/mpid/ch4/Makefile.mk +++ b/src/mpid/ch4/Makefile.mk @@ -7,7 +7,6 @@ if BUILD_CH4 include $(top_srcdir)/src/mpid/ch4/include/Makefile.mk include $(top_srcdir)/src/mpid/ch4/src/Makefile.mk -include $(top_srcdir)/src/mpid/ch4/generic/Makefile.mk include $(top_srcdir)/src/mpid/ch4/netmod/Makefile.mk if BUILD_CH4_SHM include $(top_srcdir)/src/mpid/ch4/shm/Makefile.mk diff --git a/src/mpid/ch4/generic/Makefile.mk b/src/mpid/ch4/generic/Makefile.mk deleted file mode 100644 index 3a76828f34a..00000000000 --- a/src/mpid/ch4/generic/Makefile.mk +++ /dev/null @@ -1,6 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -include $(top_srcdir)/src/mpid/ch4/generic/am/Makefile.mk diff --git a/src/mpid/ch4/generic/am/Makefile.mk b/src/mpid/ch4/generic/am/Makefile.mk deleted file mode 100644 index 9d001031e80..00000000000 --- a/src/mpid/ch4/generic/am/Makefile.mk +++ /dev/null @@ -1,21 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -AM_CPPFLAGS += -I$(top_srcdir)/src/mpid/ch4/generic/am - -noinst_HEADERS += src/mpid/ch4/generic/am/mpidig_am_send.h \ - src/mpid/ch4/generic/am/mpidig_am_recv.h \ - src/mpid/ch4/generic/am/mpidig_am_recv_utils.h \ - src/mpid/ch4/generic/am/mpidig_am_send_utils.h \ - src/mpid/ch4/generic/am/mpidig_am_req_cache.h \ - src/mpid/ch4/generic/am/mpidig_am_part.h \ - src/mpid/ch4/generic/am/mpidig_am_part_callbacks.h \ - src/mpid/ch4/generic/am/mpidig_am_part_utils.h \ - src/mpid/ch4/generic/am/mpidig_am.h - -mpi_core_sources += src/mpid/ch4/generic/am/mpidig_am_init.c \ - src/mpid/ch4/generic/am/mpidig_am_comm_abort.c \ - src/mpid/ch4/generic/am/mpidig_am_part.c \ - src/mpid/ch4/generic/am/mpidig_am_part_callbacks.c diff --git a/src/mpid/ch4/include/mpidch4.h b/src/mpid/ch4/include/mpidch4.h index 9520b2e87d7..49301fda3ac 100644 --- a/src/mpid/ch4/include/mpidch4.h +++ b/src/mpid/ch4/include/mpidch4.h @@ -332,7 +332,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_av_is_local(MPIDI_av_entry_t * av); #include "ch4_vci.h" /* Active message and generic implementatiions */ -#include "mpidig_am.h" +#include "mpidig.h" #include "mpidch4r.h" /* Include netmod and shm implementations */ diff --git a/src/mpid/ch4/include/mpidch4r.h b/src/mpid/ch4/include/mpidch4r.h index f6b8ed3e2ef..fdd3a395332 100644 --- a/src/mpid/ch4/include/mpidch4r.h +++ b/src/mpid/ch4/include/mpidch4r.h @@ -6,23 +6,21 @@ #ifndef MPIDCH4R_H_INCLUDED #define MPIDCH4R_H_INCLUDED -#include "ch4r_recvq.h" +#include "mpidig_recvq.h" #include "ch4r_proc.h" -#include "ch4r_init.h" -#include "ch4r_callbacks.h" -#include "ch4r_probe.h" -#include "ch4r_proc.h" -#include "ch4r_request.h" -#include "ch4r_rma_origin_callbacks.h" -#include "ch4r_rma_target_callbacks.h" -#include "ch4r_rma.h" -#include "ch4r_win.h" -#include "mpidig_am_recv_utils.h" -#include "mpidig_am_send_utils.h" -#include "mpidig_am_req_cache.h" -#include "mpidig_am_recv.h" -#include "mpidig_am_send.h" -#include "mpidig_am_part.h" -#include "mpidig_am_part_callbacks.h" +#include "mpidig.h" +#include "mpidig_pt2pt_callbacks.h" +#include "mpidig_probe.h" +#include "mpidig_request.h" +#include "mpidig_rma_callbacks.h" +#include "mpidig_rma.h" +#include "mpidig_win.h" +#include "mpidig_recv_utils.h" +#include "mpidig_send_utils.h" +#include "mpidig_req_cache.h" +#include "mpidig_recv.h" +#include "mpidig_send.h" +#include "mpidig_part.h" +#include "mpidig_part_callbacks.h" #endif /* MPIDCH4R_H_INCLUDED */ diff --git a/src/mpid/ch4/netmod/ofi/ofi_impl.h b/src/mpid/ch4/netmod/ofi/ofi_impl.h index 2a52421ff03..40f39c8f751 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_impl.h +++ b/src/mpid/ch4/netmod/ofi/ofi_impl.h @@ -10,7 +10,6 @@ /* NOTE: headers with global struct need be included before ofi_types.h */ #include "ofi_types.h" #include "mpidch4r.h" -#include "mpidig_am.h" #include "ch4_impl.h" extern unsigned long long PVAR_COUNTER_nic_sent_bytes_count[MPIDI_OFI_MAX_NICS] ATTRIBUTE((unused)); diff --git a/src/mpid/ch4/src/Makefile.mk b/src/mpid/ch4/src/Makefile.mk index e1db6e4f949..7768285442d 100644 --- a/src/mpid/ch4/src/Makefile.mk +++ b/src/mpid/ch4/src/Makefile.mk @@ -18,18 +18,25 @@ noinst_HEADERS += src/mpid/ch4/src/ch4_comm.h \ src/mpid/ch4/src/ch4_win.h \ src/mpid/ch4/src/ch4_wait.h \ src/mpid/ch4/src/ch4_part.h \ - src/mpid/ch4/src/ch4r_probe.h \ - src/mpid/ch4/src/ch4r_rma.h \ - src/mpid/ch4/src/ch4r_win.h \ - src/mpid/ch4/src/ch4r_init.h \ src/mpid/ch4/src/ch4r_proc.h \ src/mpid/ch4/src/ch4i_comm.h \ - src/mpid/ch4/src/ch4r_recvq.h \ - src/mpid/ch4/src/ch4r_callbacks.h \ - src/mpid/ch4/src/ch4r_rma_origin_callbacks.h \ - src/mpid/ch4/src/ch4r_rma_target_callbacks.h \ - src/mpid/ch4/src/ch4r_util.h \ - src/mpid/ch4/src/ch4r_request.h + src/mpid/ch4/src/mpidig.h \ + src/mpid/ch4/src/mpidig_util.h \ + src/mpid/ch4/src/mpidig_request.h \ + src/mpid/ch4/src/mpidig_recvq.h \ + src/mpid/ch4/src/mpidig_pt2pt_callbacks.h \ + src/mpid/ch4/src/mpidig_rma_callbacks.h \ + src/mpid/ch4/src/mpidig_send.h \ + src/mpid/ch4/src/mpidig_recv.h \ + src/mpid/ch4/src/mpidig_probe.h \ + src/mpid/ch4/src/mpidig_rma.h \ + src/mpid/ch4/src/mpidig_win.h \ + src/mpid/ch4/src/mpidig_send_utils.h \ + src/mpid/ch4/src/mpidig_recv_utils.h \ + src/mpid/ch4/src/mpidig_req_cache.h \ + src/mpid/ch4/src/mpidig_part.h \ + src/mpid/ch4/src/mpidig_part_callbacks.h \ + src/mpid/ch4/src/mpidig_part_utils.h mpi_core_sources += src/mpid/ch4/src/ch4_globals.c \ src/mpid/ch4/src/ch4_impl.c \ @@ -41,13 +48,15 @@ mpi_core_sources += src/mpid/ch4/src/ch4_globals.c \ src/mpid/ch4/src/ch4_part.c \ src/mpid/ch4/src/ch4_self.c \ src/mpid/ch4/src/ch4i_comm.c \ - src/mpid/ch4/src/ch4r_init.c \ src/mpid/ch4/src/ch4r_proc.c \ - src/mpid/ch4/src/ch4r_recvq.c \ - src/mpid/ch4/src/ch4r_callbacks.c \ - src/mpid/ch4/src/ch4r_rma_origin_callbacks.c \ - src/mpid/ch4/src/ch4r_rma_target_callbacks.c \ - src/mpid/ch4/src/ch4r_win.c \ + src/mpid/ch4/src/mpidig_init.c \ + src/mpid/ch4/src/mpidig_recvq.c \ + src/mpid/ch4/src/mpidig_pt2pt_callbacks.c \ + src/mpid/ch4/src/mpidig_rma_callbacks.c \ + src/mpid/ch4/src/mpidig_win.c \ + src/mpid/ch4/src/mpidig_part.c \ + src/mpid/ch4/src/mpidig_part_callbacks.c \ + src/mpid/ch4/src/mpidig_comm_abort.c \ src/mpid/ch4/src/mpid_ch4_net_array.c if BUILD_CH4_COLL_TUNING diff --git a/src/mpid/ch4/src/ch4_impl.h b/src/mpid/ch4/src/ch4_impl.h index 7eb82280e03..3f94c874c79 100644 --- a/src/mpid/ch4/src/ch4_impl.h +++ b/src/mpid/ch4/src/ch4_impl.h @@ -7,7 +7,7 @@ #define CH4_IMPL_H_INCLUDED #include "ch4_types.h" -#include "mpidig_am.h" +#include "mpidig.h" #include "mpidu_shm.h" #include "ch4r_proc.h" #include "ch4_self.h" diff --git a/src/mpid/ch4/src/ch4_win.h b/src/mpid/ch4/src/ch4_win.h index 70e5975ca34..02af577def0 100644 --- a/src/mpid/ch4/src/ch4_win.h +++ b/src/mpid/ch4/src/ch4_win.h @@ -7,7 +7,7 @@ #define CH4_WIN_H_INCLUDED #include "ch4_impl.h" -#include "ch4r_win.h" +#include "mpidig_win.h" MPL_STATIC_INLINE_PREFIX int MPID_Win_start(MPIR_Group * group, int assert, MPIR_Win * win) { diff --git a/src/mpid/ch4/src/ch4r_init.c b/src/mpid/ch4/src/ch4r_init.c deleted file mode 100644 index 0d20c836227..00000000000 --- a/src/mpid/ch4/src/ch4r_init.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) by Argonne National Laboratory - * See COPYRIGHT in top-level directory - */ - -#include "mpidimpl.h" -#include "ch4r_init.h" - -int MPIDIG_init_comm(MPIR_Comm * comm) -{ - int mpi_errno = MPI_SUCCESS; - - MPIR_FUNC_ENTER; - - if (MPIR_CONTEXT_READ_FIELD(DYNAMIC_PROC, comm->recvcontext_id)) - goto fn_exit; - - MPIDIG_COMM(comm, window_instance) = 0; - fn_exit: - MPIR_FUNC_EXIT; - return mpi_errno; -} - -int MPIDIG_destroy_comm(MPIR_Comm * comm) -{ - int mpi_errno = MPI_SUCCESS; - MPIR_FUNC_ENTER; - - if (MPIR_CONTEXT_READ_FIELD(DYNAMIC_PROC, comm->recvcontext_id)) - goto fn_exit; - - fn_exit: - MPIR_FUNC_EXIT; - return mpi_errno; -} - -void *MPIDIG_mpi_alloc_mem(MPI_Aint size, MPIR_Info * info_ptr) -{ - MPIR_FUNC_ENTER; - void *p; - - p = MPL_malloc(size, MPL_MEM_USER); - - MPIR_FUNC_EXIT; - return p; -} - -int MPIDIG_mpi_free_mem(void *ptr) -{ - int mpi_errno = MPI_SUCCESS; - MPIR_FUNC_ENTER; - - MPL_free(ptr); - - MPIR_FUNC_EXIT; - return mpi_errno; -} diff --git a/src/mpid/ch4/src/ch4r_init.h b/src/mpid/ch4/src/ch4r_init.h deleted file mode 100644 index a431dab1488..00000000000 --- a/src/mpid/ch4/src/ch4r_init.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (C) by Argonne National Laboratory - * See COPYRIGHT in top-level directory - */ - -#ifndef CH4R_INIT_H_INCLUDED -#define CH4R_INIT_H_INCLUDED - -int MPIDIG_init_comm(MPIR_Comm * comm); -int MPIDIG_destroy_comm(MPIR_Comm * comm); -void *MPIDIG_mpi_alloc_mem(MPI_Aint size, MPIR_Info * info_ptr); -int MPIDIG_mpi_free_mem(void *ptr); - -#endif /* CH4R_INIT_H_INCLUDED */ diff --git a/src/mpid/ch4/src/ch4r_rma_origin_callbacks.c b/src/mpid/ch4/src/ch4r_rma_origin_callbacks.c deleted file mode 100644 index 3a9faa77370..00000000000 --- a/src/mpid/ch4/src/ch4r_rma_origin_callbacks.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (C) by Argonne National Laboratory - * See COPYRIGHT in top-level directory - */ - -#include "mpidimpl.h" -#include "ch4r_rma_origin_callbacks.h" - -/* This file includes all RMA callback routines on the packet issuing side. - * All handler functions are named with suffix "_origin_cb". */ - -int MPIDIG_put_ack_origin_cb(MPIR_Request * req) -{ - int mpi_errno = MPI_SUCCESS; - MPIR_FUNC_ENTER; - MPID_Request_complete(req); - MPIR_FUNC_EXIT; - return mpi_errno; -} - -int MPIDIG_acc_ack_origin_cb(MPIR_Request * req) -{ - int mpi_errno = MPI_SUCCESS; - MPIR_FUNC_ENTER; - MPID_Request_complete(req); - MPIR_FUNC_EXIT; - return mpi_errno; -} - -int MPIDIG_get_acc_ack_origin_cb(MPIR_Request * req) -{ - int mpi_errno = MPI_SUCCESS; - - MPIR_FUNC_ENTER; - MPL_free(MPIDIG_REQUEST(req, req->areq.data)); - - MPID_Request_complete(req); - MPIR_FUNC_EXIT; - return mpi_errno; -} - -int MPIDIG_cswap_ack_origin_cb(MPIR_Request * req) -{ - int mpi_errno = MPI_SUCCESS; - - MPIR_FUNC_ENTER; - - MPL_free(MPIDIG_REQUEST(req, req->creq.data)); - MPID_Request_complete(req); - - MPIR_FUNC_EXIT; - return mpi_errno; -} - -int MPIDIG_get_ack_origin_cb(MPIR_Request * req) -{ - int mpi_errno = MPI_SUCCESS; - - MPIR_FUNC_ENTER; - - MPL_free(MPIDIG_REQUEST(req, req->greq.flattened_dt)); - if (MPIDIG_REQUEST(req, req->greq.dt)) - MPIR_Datatype_ptr_release(MPIDIG_REQUEST(req, req->greq.dt)); - - MPID_Request_complete(req); - MPIR_FUNC_EXIT; - return mpi_errno; -} - -int MPIDIG_put_origin_cb(MPIR_Request * sreq) -{ - int mpi_errno = MPI_SUCCESS; - MPIR_FUNC_ENTER; - MPID_Request_complete(sreq); - MPIR_FUNC_EXIT; - return mpi_errno; -} - -int MPIDIG_cswap_origin_cb(MPIR_Request * sreq) -{ - int mpi_errno = MPI_SUCCESS; - MPIR_FUNC_ENTER; - MPID_Request_complete(sreq); - MPIR_FUNC_EXIT; - return mpi_errno; -} - -int MPIDIG_acc_origin_cb(MPIR_Request * sreq) -{ - int mpi_errno = MPI_SUCCESS; - MPIR_FUNC_ENTER; - MPID_Request_complete(sreq); - MPIR_FUNC_EXIT; - return mpi_errno; -} - -int MPIDIG_get_acc_origin_cb(MPIR_Request * sreq) -{ - int mpi_errno = MPI_SUCCESS; - MPIR_FUNC_ENTER; - MPID_Request_complete(sreq); - MPIR_FUNC_EXIT; - return mpi_errno; -} - -int MPIDIG_put_data_origin_cb(MPIR_Request * sreq) -{ - int mpi_errno = MPI_SUCCESS; - MPIR_FUNC_ENTER; - MPID_Request_complete(sreq); - MPIR_FUNC_EXIT; - return mpi_errno; -} - -int MPIDIG_acc_data_origin_cb(MPIR_Request * sreq) -{ - int mpi_errno = MPI_SUCCESS; - MPIR_FUNC_ENTER; - MPID_Request_complete(sreq); - MPIR_FUNC_EXIT; - return mpi_errno; -} - -int MPIDIG_get_acc_data_origin_cb(MPIR_Request * sreq) -{ - int mpi_errno = MPI_SUCCESS; - MPIR_FUNC_ENTER; - MPID_Request_complete(sreq); - MPIR_FUNC_EXIT; - return mpi_errno; -} - -int MPIDIG_put_dt_origin_cb(MPIR_Request * sreq) -{ - int mpi_errno = MPI_SUCCESS; - MPIR_FUNC_ENTER; - MPID_Request_complete(sreq); - MPIR_FUNC_EXIT; - return mpi_errno; -} - -int MPIDIG_acc_dt_origin_cb(MPIR_Request * sreq) -{ - int mpi_errno = MPI_SUCCESS; - MPIR_FUNC_ENTER; - MPID_Request_complete(sreq); - MPIR_FUNC_EXIT; - return mpi_errno; -} - -int MPIDIG_get_acc_dt_origin_cb(MPIR_Request * sreq) -{ - int mpi_errno = MPI_SUCCESS; - MPIR_FUNC_ENTER; - MPID_Request_complete(sreq); - MPIR_FUNC_EXIT; - return mpi_errno; -} - -int MPIDIG_get_origin_cb(MPIR_Request * sreq) -{ - int mpi_errno = MPI_SUCCESS; - MPIR_FUNC_ENTER; - MPID_Request_complete(sreq); - MPIR_FUNC_EXIT; - return mpi_errno; -} diff --git a/src/mpid/ch4/src/ch4r_rma_origin_callbacks.h b/src/mpid/ch4/src/ch4r_rma_origin_callbacks.h deleted file mode 100644 index 4e41facf93a..00000000000 --- a/src/mpid/ch4/src/ch4r_rma_origin_callbacks.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) by Argonne National Laboratory - * See COPYRIGHT in top-level directory - */ - -#ifndef CH4R_RMA_ORIGIN_CALLBACKS_H_INCLUDED -#define CH4R_RMA_ORIGIN_CALLBACKS_H_INCLUDED - -/* This file includes all RMA callback routines on the packet issuing side. - * All handler functions are named with suffix "_origin_cb". */ - -int MPIDIG_put_ack_origin_cb(MPIR_Request * req); -int MPIDIG_acc_ack_origin_cb(MPIR_Request * req); -int MPIDIG_get_acc_ack_origin_cb(MPIR_Request * req); -int MPIDIG_cswap_ack_origin_cb(MPIR_Request * req); -int MPIDIG_get_ack_origin_cb(MPIR_Request * req); -int MPIDIG_put_origin_cb(MPIR_Request * sreq); -int MPIDIG_cswap_origin_cb(MPIR_Request * sreq); -int MPIDIG_acc_origin_cb(MPIR_Request * sreq); -int MPIDIG_get_acc_origin_cb(MPIR_Request * sreq); -int MPIDIG_put_data_origin_cb(MPIR_Request * sreq); -int MPIDIG_acc_data_origin_cb(MPIR_Request * sreq); -int MPIDIG_get_acc_data_origin_cb(MPIR_Request * sreq); -int MPIDIG_put_dt_origin_cb(MPIR_Request * sreq); -int MPIDIG_acc_dt_origin_cb(MPIR_Request * sreq); -int MPIDIG_get_acc_dt_origin_cb(MPIR_Request * sreq); -int MPIDIG_get_origin_cb(MPIR_Request * sreq); - -#endif /* CH4R_RMA_ORIGIN_CALLBACKS_H_INCLUDED */ diff --git a/src/mpid/ch4/generic/am/mpidig_am.h b/src/mpid/ch4/src/mpidig.h similarity index 94% rename from src/mpid/ch4/generic/am/mpidig_am.h rename to src/mpid/ch4/src/mpidig.h index 592f84e7992..03929472c32 100644 --- a/src/mpid/ch4/generic/am/mpidig_am.h +++ b/src/mpid/ch4/src/mpidig.h @@ -3,8 +3,8 @@ * See COPYRIGHT in top-level directory */ -#ifndef MPIDIG_AM_H_INCLUDED -#define MPIDIG_AM_H_INCLUDED +#ifndef MPIDIG_H_INCLUDED +#define MPIDIG_H_INCLUDED #define MPIDI_AM_HANDLERS_MAX (64) #define MPIDI_AM_RNDV_CB_MAX (10) @@ -140,4 +140,9 @@ int MPIDIG_am_comm_abort(MPIR_Comm * comm, int exit_code); int MPIDIG_am_check_init(void); -#endif /* MPIDIG_AM_H_INCLUDED */ +int MPIDIG_init_comm(MPIR_Comm * comm); +int MPIDIG_destroy_comm(MPIR_Comm * comm); +void *MPIDIG_mpi_alloc_mem(MPI_Aint size, MPIR_Info * info_ptr); +int MPIDIG_mpi_free_mem(void *ptr); + +#endif /* MPIDIG_H_INCLUDED */ diff --git a/src/mpid/ch4/generic/am/mpidig_am_comm_abort.c b/src/mpid/ch4/src/mpidig_comm_abort.c similarity index 100% rename from src/mpid/ch4/generic/am/mpidig_am_comm_abort.c rename to src/mpid/ch4/src/mpidig_comm_abort.c diff --git a/src/mpid/ch4/generic/am/mpidig_am_init.c b/src/mpid/ch4/src/mpidig_init.c similarity index 91% rename from src/mpid/ch4/generic/am/mpidig_am_init.c rename to src/mpid/ch4/src/mpidig_init.c index 53bb68ba1f9..8290759b9a8 100644 --- a/src/mpid/ch4/generic/am/mpidig_am_init.c +++ b/src/mpid/ch4/src/mpidig_init.c @@ -4,7 +4,6 @@ */ #include "mpidimpl.h" -#include "mpidig_am.h" #include "mpidch4r.h" #include "mpidu_genq.h" @@ -244,3 +243,53 @@ void MPIDIG_am_finalize(void) MPIR_FUNC_EXIT; } + +int MPIDIG_init_comm(MPIR_Comm * comm) +{ + int mpi_errno = MPI_SUCCESS; + + MPIR_FUNC_ENTER; + + if (MPIR_CONTEXT_READ_FIELD(DYNAMIC_PROC, comm->recvcontext_id)) + goto fn_exit; + + MPIDIG_COMM(comm, window_instance) = 0; + fn_exit: + MPIR_FUNC_EXIT; + return mpi_errno; +} + +int MPIDIG_destroy_comm(MPIR_Comm * comm) +{ + int mpi_errno = MPI_SUCCESS; + MPIR_FUNC_ENTER; + + if (MPIR_CONTEXT_READ_FIELD(DYNAMIC_PROC, comm->recvcontext_id)) + goto fn_exit; + + fn_exit: + MPIR_FUNC_EXIT; + return mpi_errno; +} + +void *MPIDIG_mpi_alloc_mem(MPI_Aint size, MPIR_Info * info_ptr) +{ + MPIR_FUNC_ENTER; + void *p; + + p = MPL_malloc(size, MPL_MEM_USER); + + MPIR_FUNC_EXIT; + return p; +} + +int MPIDIG_mpi_free_mem(void *ptr) +{ + int mpi_errno = MPI_SUCCESS; + MPIR_FUNC_ENTER; + + MPL_free(ptr); + + MPIR_FUNC_EXIT; + return mpi_errno; +} diff --git a/src/mpid/ch4/generic/am/mpidig_am_part.c b/src/mpid/ch4/src/mpidig_part.c similarity index 99% rename from src/mpid/ch4/generic/am/mpidig_am_part.c rename to src/mpid/ch4/src/mpidig_part.c index d4369192972..04b38e920c9 100644 --- a/src/mpid/ch4/generic/am/mpidig_am_part.c +++ b/src/mpid/ch4/src/mpidig_part.c @@ -5,7 +5,7 @@ #include "mpidimpl.h" #include "mpidch4r.h" -#include "mpidig_am_part_utils.h" +#include "mpidig_part_utils.h" static int part_req_create(void *buf, int partitions, MPI_Aint count, MPI_Datatype datatype, int rank, int tag, diff --git a/src/mpid/ch4/generic/am/mpidig_am_part.h b/src/mpid/ch4/src/mpidig_part.h similarity index 99% rename from src/mpid/ch4/generic/am/mpidig_am_part.h rename to src/mpid/ch4/src/mpidig_part.h index 984d254b485..356ae446225 100644 --- a/src/mpid/ch4/generic/am/mpidig_am_part.h +++ b/src/mpid/ch4/src/mpidig_part.h @@ -7,7 +7,7 @@ #define MPIDIG_AM_PART_H_INCLUDED #include "ch4_impl.h" -#include "mpidig_am_part_utils.h" +#include "mpidig_part_utils.h" void MPIDIG_precv_matched(MPIR_Request * part_req); int MPIDIG_mpi_psend_init(void *buf, int partitions, MPI_Aint count, diff --git a/src/mpid/ch4/generic/am/mpidig_am_part_callbacks.c b/src/mpid/ch4/src/mpidig_part_callbacks.c similarity index 98% rename from src/mpid/ch4/generic/am/mpidig_am_part_callbacks.c rename to src/mpid/ch4/src/mpidig_part_callbacks.c index 923b28ecc5e..4aaedaa1637 100644 --- a/src/mpid/ch4/generic/am/mpidig_am_part_callbacks.c +++ b/src/mpid/ch4/src/mpidig_part_callbacks.c @@ -5,8 +5,8 @@ #include "mpidimpl.h" #include "mpidch4r.h" -#include "mpidig_am_part_callbacks.h" -#include "mpidig_am_part_utils.h" +#include "mpidig_part_callbacks.h" +#include "mpidig_part_utils.h" static void part_rreq_update_sinfo(MPIR_Request * rreq, MPIDIG_part_send_init_msg_t * msg_hdr) { diff --git a/src/mpid/ch4/generic/am/mpidig_am_part_callbacks.h b/src/mpid/ch4/src/mpidig_part_callbacks.h similarity index 82% rename from src/mpid/ch4/generic/am/mpidig_am_part_callbacks.h rename to src/mpid/ch4/src/mpidig_part_callbacks.h index 420eb14bb74..b9b8245f8b2 100644 --- a/src/mpid/ch4/generic/am/mpidig_am_part_callbacks.h +++ b/src/mpid/ch4/src/mpidig_part_callbacks.h @@ -3,8 +3,8 @@ * See COPYRIGHT in top-level directory */ -#ifndef MPIDIG_AM_PART_CALLBACKS_H_INCLUDED -#define MPIDIG_AM_PART_CALLBACKS_H_INCLUDED +#ifndef MPIDIG_PART_CALLBACKS_H_INCLUDED +#define MPIDIG_PART_CALLBACKS_H_INCLUDED int MPIDIG_part_send_data_origin_cb(MPIR_Request * req); @@ -15,4 +15,4 @@ int MPIDIG_part_cts_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, int MPIDIG_part_send_data_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, uint32_t attr, MPIR_Request ** req); -#endif /* MPIDIG_AM_PART_CALLBACKS_H_INCLUDED */ +#endif /* MPIDIG_PART_CALLBACKS_H_INCLUDED */ diff --git a/src/mpid/ch4/generic/am/mpidig_am_part_utils.h b/src/mpid/ch4/src/mpidig_part_utils.h similarity index 96% rename from src/mpid/ch4/generic/am/mpidig_am_part_utils.h rename to src/mpid/ch4/src/mpidig_part_utils.h index c11a0198cb8..1c032c5e977 100644 --- a/src/mpid/ch4/generic/am/mpidig_am_part_utils.h +++ b/src/mpid/ch4/src/mpidig_part_utils.h @@ -3,8 +3,8 @@ * See COPYRIGHT in top-level directory */ -#ifndef MPIDIG_AM_PART_UTILS_H_INCLUDED -#define MPIDIG_AM_PART_UTILS_H_INCLUDED +#ifndef MPIDIG_PART_UTILS_H_INCLUDED +#define MPIDIG_PART_UTILS_H_INCLUDED #include "ch4_impl.h" @@ -84,4 +84,4 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_part_issue_data(MPIR_Request * part_sreq, fn_fail: goto fn_exit; } -#endif /* MPIDIG_AM_PART_UTILS_H_INCLUDED */ +#endif /* MPIDIG_PART_UTILS_H_INCLUDED */ diff --git a/src/mpid/ch4/src/ch4r_probe.h b/src/mpid/ch4/src/mpidig_probe.h similarity index 96% rename from src/mpid/ch4/src/ch4r_probe.h rename to src/mpid/ch4/src/mpidig_probe.h index e7ad2524854..712a41da0d8 100644 --- a/src/mpid/ch4/src/ch4r_probe.h +++ b/src/mpid/ch4/src/mpidig_probe.h @@ -3,8 +3,8 @@ * See COPYRIGHT in top-level directory */ -#ifndef CH4R_PROBE_H_INCLUDED -#define CH4R_PROBE_H_INCLUDED +#ifndef MPIDIG_PROBE_H_INCLUDED +#define MPIDIG_PROBE_H_INCLUDED #include "ch4_impl.h" @@ -80,4 +80,4 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_mpi_improbe(int source, int tag, MPIR_Comm * return mpi_errno; } -#endif /* CH4R_PROBE_H_INCLUDED */ +#endif /* MPIDIG_PROBE_H_INCLUDED */ diff --git a/src/mpid/ch4/src/ch4r_callbacks.c b/src/mpid/ch4/src/mpidig_pt2pt_callbacks.c similarity index 99% rename from src/mpid/ch4/src/ch4r_callbacks.c rename to src/mpid/ch4/src/mpidig_pt2pt_callbacks.c index e0c47937a00..9f264f27bfd 100644 --- a/src/mpid/ch4/src/ch4r_callbacks.c +++ b/src/mpid/ch4/src/mpidig_pt2pt_callbacks.c @@ -5,7 +5,7 @@ #include "mpidimpl.h" #include "mpidch4r.h" -#include "ch4r_callbacks.h" +#include "mpidig_pt2pt_callbacks.h" static int handle_unexp_cmpl(MPIR_Request * rreq); static int recv_target_cmpl_cb(MPIR_Request * rreq); diff --git a/src/mpid/ch4/src/ch4r_callbacks.h b/src/mpid/ch4/src/mpidig_pt2pt_callbacks.h similarity index 88% rename from src/mpid/ch4/src/ch4r_callbacks.h rename to src/mpid/ch4/src/mpidig_pt2pt_callbacks.h index dd2be8cb9b3..cdec222d435 100644 --- a/src/mpid/ch4/src/ch4r_callbacks.h +++ b/src/mpid/ch4/src/mpidig_pt2pt_callbacks.h @@ -3,15 +3,15 @@ * See COPYRIGHT in top-level directory */ -#ifndef CH4R_CALLBACKS_H_INCLUDED -#define CH4R_CALLBACKS_H_INCLUDED +#ifndef MPIDIG_PT2PT_CALLBACKS_H_INCLUDED +#define MPIDIG_PT2PT_CALLBACKS_H_INCLUDED /* This file includes all callback routines and the completion function of * receive callback for send-receive AM. All handlers on the packet issuing * side are named with suffix "_origin_cb", and all handlers on the * packet receiving side are named with "_target_msg_cb". */ -#include "mpidig_am.h" +#include "mpidig.h" int MPIDIG_do_cts(MPIR_Request * rreq); int MPIDIG_send_origin_cb(MPIR_Request * sreq); @@ -26,4 +26,4 @@ int MPIDIG_ssend_ack_target_msg_cb(void *am_hdr, void *data, int MPIDIG_send_cts_target_msg_cb(void *am_hdr, void *data, MPI_Aint p_data_sz, uint32_t attr, MPIR_Request ** req); -#endif /* CH4R_CALLBACKS_H_INCLUDED */ +#endif /* MPIDIG_PT2PT_CALLBACKS_H_INCLUDED */ diff --git a/src/mpid/ch4/generic/am/mpidig_am_recv.h b/src/mpid/ch4/src/mpidig_recv.h similarity index 99% rename from src/mpid/ch4/generic/am/mpidig_am_recv.h rename to src/mpid/ch4/src/mpidig_recv.h index 0216baa71ef..821b0e73a15 100644 --- a/src/mpid/ch4/generic/am/mpidig_am_recv.h +++ b/src/mpid/ch4/src/mpidig_recv.h @@ -3,8 +3,8 @@ * See COPYRIGHT in top-level directory */ -#ifndef MPIDIG_AM_RECV_H_INCLUDED -#define MPIDIG_AM_RECV_H_INCLUDED +#ifndef MPIDIG_RECV_H_INCLUDED +#define MPIDIG_RECV_H_INCLUDED #include "ch4_impl.h" #include "ch4r_proc.h" @@ -379,4 +379,4 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_mpi_cancel_recv(MPIR_Request * rreq) return mpi_errno; } -#endif /* MPIDIG_AM_RECV_H_INCLUDED */ +#endif /* MPIDIG_RECV_H_INCLUDED */ diff --git a/src/mpid/ch4/generic/am/mpidig_am_recv_utils.h b/src/mpid/ch4/src/mpidig_recv_utils.h similarity index 99% rename from src/mpid/ch4/generic/am/mpidig_am_recv_utils.h rename to src/mpid/ch4/src/mpidig_recv_utils.h index 7a6e2a2dd89..070816b6cdc 100644 --- a/src/mpid/ch4/generic/am/mpidig_am_recv_utils.h +++ b/src/mpid/ch4/src/mpidig_recv_utils.h @@ -3,8 +3,8 @@ * See COPYRIGHT in top-level directory */ -#ifndef MPIDIG_AM_MSG_H_INCLUDED -#define MPIDIG_AM_MSG_H_INCLUDED +#ifndef MPIDIG_RECV_UTILS_H_INCLUDED +#define MPIDIG_RECV_UTILS_H_INCLUDED /* This file is for supporting routines used for generic layer message matching * and data transfer. They are used by protocols such as send, ssend, and send_long. @@ -380,4 +380,4 @@ MPL_STATIC_INLINE_PREFIX void MPIDIG_convert_datatype(MPIR_Request * rreq) } } -#endif /* MPIDIG_AM_MSG_H_INCLUDED */ +#endif /* MPIDIG_RECV_UTILS_H_INCLUDED */ diff --git a/src/mpid/ch4/src/ch4r_recvq.c b/src/mpid/ch4/src/mpidig_recvq.c similarity index 99% rename from src/mpid/ch4/src/ch4r_recvq.c rename to src/mpid/ch4/src/mpidig_recvq.c index 24ec613f65b..406ec02d07c 100644 --- a/src/mpid/ch4/src/ch4r_recvq.c +++ b/src/mpid/ch4/src/mpidig_recvq.c @@ -4,7 +4,7 @@ */ #include "mpidimpl.h" -#include "ch4r_recvq.h" +#include "mpidig_recvq.h" int unexp_message_indices[2]; diff --git a/src/mpid/ch4/src/ch4r_recvq.h b/src/mpid/ch4/src/mpidig_recvq.h similarity index 98% rename from src/mpid/ch4/src/ch4r_recvq.h rename to src/mpid/ch4/src/mpidig_recvq.h index e0a49081df9..401e6daabdc 100644 --- a/src/mpid/ch4/src/ch4r_recvq.h +++ b/src/mpid/ch4/src/mpidig_recvq.h @@ -3,11 +3,10 @@ * See COPYRIGHT in top-level directory */ -#ifndef CH4R_RECVQ_H_INCLUDED -#define CH4R_RECVQ_H_INCLUDED +#ifndef MPIDIG_RECVQ_H_INCLUDED +#define MPIDIG_RECVQ_H_INCLUDED #include -#include "mpidig_am.h" #include "utlist.h" #include "ch4_impl.h" @@ -195,4 +194,4 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_delete_posted(MPIR_Request * req, MPIR_Reque return found; } -#endif /* CH4R_RECVQ_H_INCLUDED */ +#endif /* MPIDIG_RECVQ_H_INCLUDED */ diff --git a/src/mpid/ch4/generic/am/mpidig_am_req_cache.h b/src/mpid/ch4/src/mpidig_req_cache.h similarity index 93% rename from src/mpid/ch4/generic/am/mpidig_am_req_cache.h rename to src/mpid/ch4/src/mpidig_req_cache.h index 0e4d6d00edb..01a960452ca 100644 --- a/src/mpid/ch4/generic/am/mpidig_am_req_cache.h +++ b/src/mpid/ch4/src/mpidig_req_cache.h @@ -3,8 +3,8 @@ * See COPYRIGHT in top-level directory */ -#ifndef MPIDIG_AM_REQ_CACHE_H_INCLUDED -#define MPIDIG_AM_REQ_CACHE_H_INCLUDED +#ifndef MPIDIG_REQ_CACHE_H_INCLUDED +#define MPIDIG_REQ_CACHE_H_INCLUDED /* the request cache is for saving the mapping between sreq and rreq for recv request that has more * data coming. The implementation uses a hash table that maps (sreq, key2) -> (rreq). We only @@ -45,4 +45,4 @@ static inline void MPIDIG_req_cache_remove(void *req_map, uint64_t key) } } -#endif /* MPIDIG_AM_REQ_CACHE_H_INCLUDED */ +#endif /* MPIDIG_REQ_CACHE_H_INCLUDED */ diff --git a/src/mpid/ch4/src/ch4r_request.h b/src/mpid/ch4/src/mpidig_request.h similarity index 98% rename from src/mpid/ch4/src/ch4r_request.h rename to src/mpid/ch4/src/mpidig_request.h index 1661ce56034..40c72165517 100644 --- a/src/mpid/ch4/src/ch4r_request.h +++ b/src/mpid/ch4/src/mpidig_request.h @@ -3,8 +3,8 @@ * See COPYRIGHT in top-level directory */ -#ifndef CH4R_REQUEST_H_INCLUDED -#define CH4R_REQUEST_H_INCLUDED +#ifndef MPIDIG_REQUEST_H_INCLUDED +#define MPIDIG_REQUEST_H_INCLUDED #include "ch4_types.h" #include "mpidu_genq.h" @@ -168,4 +168,4 @@ MPL_STATIC_INLINE_PREFIX void MPIDI_anysrc_free_partner(MPIR_Request * rreq) } #endif /* MPIDI_CH4_DIRECT_NETMOD */ -#endif /* CH4R_REQUEST_H_INCLUDED */ +#endif /* MPIDIG_REQUEST_H_INCLUDED */ diff --git a/src/mpid/ch4/src/ch4r_rma.h b/src/mpid/ch4/src/mpidig_rma.h similarity index 99% rename from src/mpid/ch4/src/ch4r_rma.h rename to src/mpid/ch4/src/mpidig_rma.h index 382bcb333cb..30a8e8be5be 100644 --- a/src/mpid/ch4/src/ch4r_rma.h +++ b/src/mpid/ch4/src/mpidig_rma.h @@ -3,8 +3,8 @@ * See COPYRIGHT in top-level directory */ -#ifndef CH4R_RMA_H_INCLUDED -#define CH4R_RMA_H_INCLUDED +#ifndef MPIDIG_RMA_H_INCLUDED +#define MPIDIG_RMA_H_INCLUDED #include "ch4_impl.h" @@ -822,4 +822,4 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_mpi_fetch_and_op(const void *origin_addr, vo goto fn_exit; } -#endif /* CH4R_RMA_H_INCLUDED */ +#endif /* MPIDIG_RMA_H_INCLUDED */ diff --git a/src/mpid/ch4/src/ch4r_rma_target_callbacks.c b/src/mpid/ch4/src/mpidig_rma_callbacks.c similarity index 95% rename from src/mpid/ch4/src/ch4r_rma_target_callbacks.c rename to src/mpid/ch4/src/mpidig_rma_callbacks.c index b9d427f1007..be7e8a9c1a8 100644 --- a/src/mpid/ch4/src/ch4r_rma_target_callbacks.c +++ b/src/mpid/ch4/src/mpidig_rma_callbacks.c @@ -4,9 +4,8 @@ */ #include "mpidimpl.h" -#include "mpidch4r.h" -#include "ch4r_rma_target_callbacks.h" -#include "ch4r_util.h" /* for completion order check */ +#include "mpidig_rma_callbacks.h" +#include "mpidig_util.h" /* for completion order check */ /* ** RMA PROTOCOLS ** */ /* Put (contig or small flattened_dt) @@ -81,6 +80,168 @@ * MPIDIG_WIN_UNLOCKALL_ACK <- */ +/* This file includes all RMA callback routines on the packet issuing side. + * All handler functions are named with suffix "_origin_cb". */ + +int MPIDIG_put_ack_origin_cb(MPIR_Request * req) +{ + int mpi_errno = MPI_SUCCESS; + MPIR_FUNC_ENTER; + MPID_Request_complete(req); + MPIR_FUNC_EXIT; + return mpi_errno; +} + +int MPIDIG_acc_ack_origin_cb(MPIR_Request * req) +{ + int mpi_errno = MPI_SUCCESS; + MPIR_FUNC_ENTER; + MPID_Request_complete(req); + MPIR_FUNC_EXIT; + return mpi_errno; +} + +int MPIDIG_get_acc_ack_origin_cb(MPIR_Request * req) +{ + int mpi_errno = MPI_SUCCESS; + + MPIR_FUNC_ENTER; + MPL_free(MPIDIG_REQUEST(req, req->areq.data)); + + MPID_Request_complete(req); + MPIR_FUNC_EXIT; + return mpi_errno; +} + +int MPIDIG_cswap_ack_origin_cb(MPIR_Request * req) +{ + int mpi_errno = MPI_SUCCESS; + + MPIR_FUNC_ENTER; + + MPL_free(MPIDIG_REQUEST(req, req->creq.data)); + MPID_Request_complete(req); + + MPIR_FUNC_EXIT; + return mpi_errno; +} + +int MPIDIG_get_ack_origin_cb(MPIR_Request * req) +{ + int mpi_errno = MPI_SUCCESS; + + MPIR_FUNC_ENTER; + + MPL_free(MPIDIG_REQUEST(req, req->greq.flattened_dt)); + if (MPIDIG_REQUEST(req, req->greq.dt)) + MPIR_Datatype_ptr_release(MPIDIG_REQUEST(req, req->greq.dt)); + + MPID_Request_complete(req); + MPIR_FUNC_EXIT; + return mpi_errno; +} + +int MPIDIG_put_origin_cb(MPIR_Request * sreq) +{ + int mpi_errno = MPI_SUCCESS; + MPIR_FUNC_ENTER; + MPID_Request_complete(sreq); + MPIR_FUNC_EXIT; + return mpi_errno; +} + +int MPIDIG_cswap_origin_cb(MPIR_Request * sreq) +{ + int mpi_errno = MPI_SUCCESS; + MPIR_FUNC_ENTER; + MPID_Request_complete(sreq); + MPIR_FUNC_EXIT; + return mpi_errno; +} + +int MPIDIG_acc_origin_cb(MPIR_Request * sreq) +{ + int mpi_errno = MPI_SUCCESS; + MPIR_FUNC_ENTER; + MPID_Request_complete(sreq); + MPIR_FUNC_EXIT; + return mpi_errno; +} + +int MPIDIG_get_acc_origin_cb(MPIR_Request * sreq) +{ + int mpi_errno = MPI_SUCCESS; + MPIR_FUNC_ENTER; + MPID_Request_complete(sreq); + MPIR_FUNC_EXIT; + return mpi_errno; +} + +int MPIDIG_put_data_origin_cb(MPIR_Request * sreq) +{ + int mpi_errno = MPI_SUCCESS; + MPIR_FUNC_ENTER; + MPID_Request_complete(sreq); + MPIR_FUNC_EXIT; + return mpi_errno; +} + +int MPIDIG_acc_data_origin_cb(MPIR_Request * sreq) +{ + int mpi_errno = MPI_SUCCESS; + MPIR_FUNC_ENTER; + MPID_Request_complete(sreq); + MPIR_FUNC_EXIT; + return mpi_errno; +} + +int MPIDIG_get_acc_data_origin_cb(MPIR_Request * sreq) +{ + int mpi_errno = MPI_SUCCESS; + MPIR_FUNC_ENTER; + MPID_Request_complete(sreq); + MPIR_FUNC_EXIT; + return mpi_errno; +} + +int MPIDIG_put_dt_origin_cb(MPIR_Request * sreq) +{ + int mpi_errno = MPI_SUCCESS; + MPIR_FUNC_ENTER; + MPID_Request_complete(sreq); + MPIR_FUNC_EXIT; + return mpi_errno; +} + +int MPIDIG_acc_dt_origin_cb(MPIR_Request * sreq) +{ + int mpi_errno = MPI_SUCCESS; + MPIR_FUNC_ENTER; + MPID_Request_complete(sreq); + MPIR_FUNC_EXIT; + return mpi_errno; +} + +int MPIDIG_get_acc_dt_origin_cb(MPIR_Request * sreq) +{ + int mpi_errno = MPI_SUCCESS; + MPIR_FUNC_ENTER; + MPID_Request_complete(sreq); + MPIR_FUNC_EXIT; + return mpi_errno; +} + +int MPIDIG_get_origin_cb(MPIR_Request * sreq) +{ + int mpi_errno = MPI_SUCCESS; + MPIR_FUNC_ENTER; + MPID_Request_complete(sreq); + MPIR_FUNC_EXIT; + return mpi_errno; +} + +/* All RMA callback routines on the packet receiving side. */ + static int ack_put(MPIR_Request * rreq); static int ack_cswap(MPIR_Request * rreq); static int ack_acc(MPIR_Request * rreq); diff --git a/src/mpid/ch4/src/ch4r_rma_target_callbacks.h b/src/mpid/ch4/src/mpidig_rma_callbacks.h similarity index 85% rename from src/mpid/ch4/src/ch4r_rma_target_callbacks.h rename to src/mpid/ch4/src/mpidig_rma_callbacks.h index 9e1b6508fb3..3fe440cdc7d 100644 --- a/src/mpid/ch4/src/ch4r_rma_target_callbacks.h +++ b/src/mpid/ch4/src/mpidig_rma_callbacks.h @@ -3,13 +3,8 @@ * See COPYRIGHT in top-level directory */ -#ifndef CH4R_RMA_TARGET_CALLBACKS_H_INCLUDED -#define CH4R_RMA_TARGET_CALLBACKS_H_INCLUDED - -/* This file includes all RMA callback routines and the completion function of - * each callback (e.g., received all data) on the packet receiving side. All handler - * functions are named with suffix "_target_msg_cb", and all handler completion - * function are named with suffix "_target_cmpl_cb". */ +#ifndef MPIDIG_RMA_CALLBACKS_H_INCLUDED +#define MPIDIG_RMA_CALLBACKS_H_INCLUDED extern MPIR_T_pvar_timer_t PVAR_TIMER_rma_winlock_getlocallock ATTRIBUTE((unused)); extern MPIR_T_pvar_timer_t PVAR_TIMER_rma_targetcb_put ATTRIBUTE((unused)); @@ -32,8 +27,33 @@ extern MPIR_T_pvar_timer_t PVAR_TIMER_rma_targetcb_acc_dt_ack ATTRIBUTE((unused) extern MPIR_T_pvar_timer_t PVAR_TIMER_rma_targetcb_get_acc_dt_ack ATTRIBUTE((unused)); extern MPIR_T_pvar_timer_t PVAR_TIMER_rma_targetcb_acc_data ATTRIBUTE((unused)); extern MPIR_T_pvar_timer_t PVAR_TIMER_rma_targetcb_get_acc_data ATTRIBUTE((unused)); - int MPIDIG_RMA_Init_targetcb_pvars(void); + +/* RMA callback routines on the packet issuing side. + * All handler functions are named with suffix "_origin_cb". */ + +int MPIDIG_put_ack_origin_cb(MPIR_Request * req); +int MPIDIG_acc_ack_origin_cb(MPIR_Request * req); +int MPIDIG_get_acc_ack_origin_cb(MPIR_Request * req); +int MPIDIG_cswap_ack_origin_cb(MPIR_Request * req); +int MPIDIG_get_ack_origin_cb(MPIR_Request * req); +int MPIDIG_put_origin_cb(MPIR_Request * sreq); +int MPIDIG_cswap_origin_cb(MPIR_Request * sreq); +int MPIDIG_acc_origin_cb(MPIR_Request * sreq); +int MPIDIG_get_acc_origin_cb(MPIR_Request * sreq); +int MPIDIG_put_data_origin_cb(MPIR_Request * sreq); +int MPIDIG_acc_data_origin_cb(MPIR_Request * sreq); +int MPIDIG_get_acc_data_origin_cb(MPIR_Request * sreq); +int MPIDIG_put_dt_origin_cb(MPIR_Request * sreq); +int MPIDIG_acc_dt_origin_cb(MPIR_Request * sreq); +int MPIDIG_get_acc_dt_origin_cb(MPIR_Request * sreq); +int MPIDIG_get_origin_cb(MPIR_Request * sreq); + +/* All RMA callback routines and the completion function of + * each callback (e.g., received all data) on the packet receiving side. All handler + * functions are named with suffix "_target_msg_cb", and all handler completion + * function are named with suffix "_target_cmpl_cb". */ + int MPIDIG_put_ack_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, uint32_t attr, MPIR_Request ** req); int MPIDIG_acc_ack_target_msg_cb(void *am_hdr, void *data, @@ -93,4 +113,4 @@ int MPIDIG_get_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, int MPIDIG_get_ack_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, uint32_t attr, MPIR_Request ** req); -#endif /* CH4R_RMA_TARGET_CALLBACKS_H_INCLUDED */ +#endif /* MPIDIG_RMA_CALLBACKS_H_INCLUDED */ diff --git a/src/mpid/ch4/generic/am/mpidig_am_send.h b/src/mpid/ch4/src/mpidig_send.h similarity index 98% rename from src/mpid/ch4/generic/am/mpidig_am_send.h rename to src/mpid/ch4/src/mpidig_send.h index 976a365dd68..aad31e5ca12 100644 --- a/src/mpid/ch4/generic/am/mpidig_am_send.h +++ b/src/mpid/ch4/src/mpidig_send.h @@ -3,8 +3,8 @@ * See COPYRIGHT in top-level directory */ -#ifndef MPIDIG_AM_SEND_H_INCLUDED -#define MPIDIG_AM_SEND_H_INCLUDED +#ifndef MPIDIG_SEND_H_INCLUDED +#define MPIDIG_SEND_H_INCLUDED #include "ch4_impl.h" @@ -188,4 +188,4 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_mpi_cancel_send(MPIR_Request * sreq) return mpi_errno; } -#endif /* MPIDIG_AM_SEND_H_INCLUDED */ +#endif /* MPIDIG_SEND_H_INCLUDED */ diff --git a/src/mpid/ch4/generic/am/mpidig_am_send_utils.h b/src/mpid/ch4/src/mpidig_send_utils.h similarity index 95% rename from src/mpid/ch4/generic/am/mpidig_am_send_utils.h rename to src/mpid/ch4/src/mpidig_send_utils.h index 5b139b16be6..ac6d1edac84 100644 --- a/src/mpid/ch4/generic/am/mpidig_am_send_utils.h +++ b/src/mpid/ch4/src/mpidig_send_utils.h @@ -3,8 +3,8 @@ * See COPYRIGHT in top-level directory */ -#ifndef MPIDIG_AM_SEND_UTILS_H_INCLUDED -#define MPIDIG_AM_SEND_UTILS_H_INCLUDED +#ifndef MPIDIG_SEND_UTILS_H_INCLUDED +#define MPIDIG_SEND_UTILS_H_INCLUDED /* This file is for supporting routines used for pipelined data send. These routines mainly is for * managing the send request counters, completion counters and DT refcount */ @@ -68,4 +68,4 @@ MPL_STATIC_INLINE_PREFIX bool MPIDIG_am_send_async_finish_seg(MPIR_Request * sre return is_done; } -#endif /* MPIDIG_AM_SEND_UTILS_H_INCLUDED */ +#endif /* MPIDIG_SEND_UTILS_H_INCLUDED */ diff --git a/src/mpid/ch4/src/ch4r_util.h b/src/mpid/ch4/src/mpidig_util.h similarity index 100% rename from src/mpid/ch4/src/ch4r_util.h rename to src/mpid/ch4/src/mpidig_util.h diff --git a/src/mpid/ch4/src/ch4r_win.c b/src/mpid/ch4/src/mpidig_win.c similarity index 99% rename from src/mpid/ch4/src/ch4r_win.c rename to src/mpid/ch4/src/mpidig_win.c index f2d7725265d..cb21c1e1d09 100644 --- a/src/mpid/ch4/src/ch4r_win.c +++ b/src/mpid/ch4/src/mpidig_win.c @@ -5,7 +5,7 @@ #include "mpidimpl.h" #include "mpidch4r.h" -#include "ch4r_win.h" +#include "mpidig_win.h" enum { SHM_WIN_OPTIONAL, diff --git a/src/mpid/ch4/src/ch4r_win.h b/src/mpid/ch4/src/mpidig_win.h similarity index 99% rename from src/mpid/ch4/src/ch4r_win.h rename to src/mpid/ch4/src/mpidig_win.h index fe3be03f72b..5f7dcc6c282 100644 --- a/src/mpid/ch4/src/ch4r_win.h +++ b/src/mpid/ch4/src/mpidig_win.h @@ -3,8 +3,8 @@ * See COPYRIGHT in top-level directory */ -#ifndef CH4R_WIN_H_INCLUDED -#define CH4R_WIN_H_INCLUDED +#ifndef MPIDIG_WIN_H_INCLUDED +#define MPIDIG_WIN_H_INCLUDED #include "ch4_types.h" @@ -869,4 +869,4 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_mpi_win_lock_all(int assert, MPIR_Win * win) goto fn_exit; } -#endif /* CH4R_WIN_H_INCLUDED */ +#endif /* MPIDIG_WIN_H_INCLUDED */ From 19e7e684b0b3a9962a3ad4e459604efb24cd9afd Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 30 Aug 2021 10:46:17 -0500 Subject: [PATCH 002/607] ch4: update comments replace ch4r to mpidig --- src/mpid/ch4/src/ch4_request.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mpid/ch4/src/ch4_request.h b/src/mpid/ch4/src/ch4_request.h index 773af6fb3bf..f462519fc72 100644 --- a/src/mpid/ch4/src/ch4_request.h +++ b/src/mpid/ch4/src/ch4_request.h @@ -50,13 +50,13 @@ MPL_STATIC_INLINE_PREFIX void MPID_Request_set_completed(MPIR_Request * req) They create request objects that are not usable by the lower layers until further initialization takes place. - CH4R_request_xxx functions can be used to create and destroy + MPIDIG_request_xxx functions can be used to create and destroy request objects at any CH4 layer, including shmmod and netmod. These functions create and initialize a base request with the appropriate "above device" fields initialized, and any required CH4 layer fields initialized. - The net/shm mods can upcall to CH4R to create a request, or + The net/shm mods can upcall to MPIDIG to create a request, or they can iniitalize their own requests internally, but note that all the fields from the upper layers must be initialized properly. @@ -68,7 +68,7 @@ MPL_STATIC_INLINE_PREFIX void MPID_Request_set_completed(MPIR_Request * req) ref hits zero or there will be a memory leak. The generic release function will not release any memory pointed to by the request because it does not know about the internals of - the ch4r/netmod/shmmod fields of the request. + the mpidig/netmod/shmmod fields of the request. */ MPL_STATIC_INLINE_PREFIX int MPID_Request_complete(MPIR_Request * req) { From b4023855eeb436b5d9211223ec0e3cd914ed2b5e Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 29 Sep 2021 15:54:08 -0500 Subject: [PATCH 003/607] ch4: move ch4r_proc into ch4_proc The proc functions are not generic fallbacks and thus need use ch4 namespace. --- src/mpid/ch4/include/mpidch4r.h | 2 +- src/mpid/ch4/src/Makefile.mk | 4 +- src/mpid/ch4/src/ch4_coll.h | 2 +- src/mpid/ch4/src/ch4_impl.h | 2 +- src/mpid/ch4/src/ch4_probe.h | 2 +- src/mpid/ch4/src/{ch4r_proc.c => ch4_proc.c} | 4 +- src/mpid/ch4/src/ch4_proc.h | 249 +++++++++++++++++- src/mpid/ch4/src/ch4_send.h | 2 +- src/mpid/ch4/src/ch4r_proc.h | 258 ------------------- src/mpid/ch4/src/mpidig_recv.h | 2 +- 10 files changed, 258 insertions(+), 269 deletions(-) rename src/mpid/ch4/src/{ch4r_proc.c => ch4_proc.c} (99%) delete mode 100644 src/mpid/ch4/src/ch4r_proc.h diff --git a/src/mpid/ch4/include/mpidch4r.h b/src/mpid/ch4/include/mpidch4r.h index fdd3a395332..322d7487816 100644 --- a/src/mpid/ch4/include/mpidch4r.h +++ b/src/mpid/ch4/include/mpidch4r.h @@ -7,7 +7,7 @@ #define MPIDCH4R_H_INCLUDED #include "mpidig_recvq.h" -#include "ch4r_proc.h" +#include "ch4_proc.h" #include "mpidig.h" #include "mpidig_pt2pt_callbacks.h" #include "mpidig_probe.h" diff --git a/src/mpid/ch4/src/Makefile.mk b/src/mpid/ch4/src/Makefile.mk index 7768285442d..aabb97d5fe7 100644 --- a/src/mpid/ch4/src/Makefile.mk +++ b/src/mpid/ch4/src/Makefile.mk @@ -18,7 +18,7 @@ noinst_HEADERS += src/mpid/ch4/src/ch4_comm.h \ src/mpid/ch4/src/ch4_win.h \ src/mpid/ch4/src/ch4_wait.h \ src/mpid/ch4/src/ch4_part.h \ - src/mpid/ch4/src/ch4r_proc.h \ + src/mpid/ch4/src/ch4_proc.h \ src/mpid/ch4/src/ch4i_comm.h \ src/mpid/ch4/src/mpidig.h \ src/mpid/ch4/src/mpidig_util.h \ @@ -48,7 +48,7 @@ mpi_core_sources += src/mpid/ch4/src/ch4_globals.c \ src/mpid/ch4/src/ch4_part.c \ src/mpid/ch4/src/ch4_self.c \ src/mpid/ch4/src/ch4i_comm.c \ - src/mpid/ch4/src/ch4r_proc.c \ + src/mpid/ch4/src/ch4_proc.c \ src/mpid/ch4/src/mpidig_init.c \ src/mpid/ch4/src/mpidig_recvq.c \ src/mpid/ch4/src/mpidig_pt2pt_callbacks.c \ diff --git a/src/mpid/ch4/src/ch4_coll.h b/src/mpid/ch4/src/ch4_coll.h index 394648a4a76..3c96bc84672 100644 --- a/src/mpid/ch4/src/ch4_coll.h +++ b/src/mpid/ch4/src/ch4_coll.h @@ -7,7 +7,7 @@ #define CH4_COLL_H_INCLUDED #include "ch4_impl.h" -#include "ch4r_proc.h" +#include "ch4_proc.h" #include "ch4_coll_impl.h" MPL_STATIC_INLINE_PREFIX int MPID_Barrier(MPIR_Comm * comm, MPIR_Errflag_t * errflag) diff --git a/src/mpid/ch4/src/ch4_impl.h b/src/mpid/ch4/src/ch4_impl.h index 3f94c874c79..0544a628407 100644 --- a/src/mpid/ch4/src/ch4_impl.h +++ b/src/mpid/ch4/src/ch4_impl.h @@ -9,7 +9,7 @@ #include "ch4_types.h" #include "mpidig.h" #include "mpidu_shm.h" -#include "ch4r_proc.h" +#include "ch4_proc.h" #include "ch4_self.h" #include "ch4_vci.h" diff --git a/src/mpid/ch4/src/ch4_probe.h b/src/mpid/ch4/src/ch4_probe.h index a2a0d9cd6e5..c24559b1f70 100644 --- a/src/mpid/ch4/src/ch4_probe.h +++ b/src/mpid/ch4/src/ch4_probe.h @@ -6,7 +6,7 @@ #ifndef CH4_PROBE_H_INCLUDED #define CH4_PROBE_H_INCLUDED -#include "ch4r_proc.h" +#include "ch4_proc.h" #include "ch4_impl.h" MPL_STATIC_INLINE_PREFIX int MPIDI_iprobe(int source, diff --git a/src/mpid/ch4/src/ch4r_proc.c b/src/mpid/ch4/src/ch4_proc.c similarity index 99% rename from src/mpid/ch4/src/ch4r_proc.c rename to src/mpid/ch4/src/ch4_proc.c index 09bd9735471..16464fe3b39 100644 --- a/src/mpid/ch4/src/ch4r_proc.c +++ b/src/mpid/ch4/src/ch4_proc.c @@ -4,10 +4,10 @@ */ #include "mpidimpl.h" -#include "ch4r_proc.h" +#include "ch4_proc.h" /* There are 3 terms referencing processes -- upid, lpid, gpid. - * Refer to comment in ch4r_proc.h + * Refer to comment in ch4_proc.h */ static int get_next_avtid(void); diff --git a/src/mpid/ch4/src/ch4_proc.h b/src/mpid/ch4/src/ch4_proc.h index 26e47a0d81a..df8d46109cf 100644 --- a/src/mpid/ch4/src/ch4_proc.h +++ b/src/mpid/ch4/src/ch4_proc.h @@ -6,7 +6,254 @@ #ifndef CH4_PROC_H_INCLUDED #define CH4_PROC_H_INCLUDED -#include "ch4_impl.h" +#include "ch4_types.h" + +/* There are 3 terms referencing processes: + * upid, or "unversal process id", is netmod layer address (addrname) + * lpid, or "local process id", is av entry index in an ch4-layer table + * gpid, or "global process id", is av table index plus av entry index + * + * For non-dynamic processes, av table index is 0, thus lpid equals to gpid (other than type). + * The upid is used when establishing netmod connections. + * The lpid and gpid are defined here with avt manager. + */ + +int MPIDIU_get_n_avts(void); +int MPIDIU_get_avt_size(int avtid); +int MPIDIU_new_avt(int size, int *avtid); +int MPIDIU_free_avt(int avtid); +int MPIDIU_avt_add_ref(int avtid); +int MPIDIU_avt_release_ref(int avtid); +int MPIDIU_avt_init(void); +int MPIDIU_avt_destroy(void); +int MPIDIU_get_node_id(MPIR_Comm * comm, int rank, int *id_p); + +int MPIDIU_upids_to_gpids(int size, int *remote_upid_size, char *remote_upids, + uint64_t * remote_gpids); +int MPIDIU_alloc_lut(MPIDI_rank_map_lut_t ** lut, int size); +int MPIDIU_release_lut(MPIDI_rank_map_lut_t * lut); +int MPIDIU_alloc_mlut(MPIDI_rank_map_mlut_t ** mlut, int size); +int MPIDIU_release_mlut(MPIDI_rank_map_mlut_t * mlut); + +MPL_STATIC_INLINE_PREFIX int MPIDIU_comm_rank_to_pid(MPIR_Comm * comm, int rank, int *idx, + int *avtid) +{ + MPIR_FUNC_ENTER; + + *avtid = 0; + + switch (MPIDI_COMM(comm, map).mode) { + case MPIDI_RANK_MAP_DIRECT: + *avtid = MPIDI_COMM(comm, map).avtid; + *idx = rank; + break; + case MPIDI_RANK_MAP_DIRECT_INTRA: + *idx = rank; + break; + case MPIDI_RANK_MAP_OFFSET: + *avtid = MPIDI_COMM(comm, map).avtid; + *idx = rank + MPIDI_COMM(comm, map).reg.offset; + break; + case MPIDI_RANK_MAP_OFFSET_INTRA: + *idx = rank + MPIDI_COMM(comm, map).reg.offset; + break; + case MPIDI_RANK_MAP_STRIDE: + *avtid = MPIDI_COMM(comm, map).avtid; + *idx = MPIDI_CALC_STRIDE_SIMPLE(rank, MPIDI_COMM(comm, map).reg.stride.stride, + MPIDI_COMM(comm, map).reg.stride.offset); + break; + case MPIDI_RANK_MAP_STRIDE_INTRA: + *idx = MPIDI_CALC_STRIDE_SIMPLE(rank, MPIDI_COMM(comm, map).reg.stride.stride, + MPIDI_COMM(comm, map).reg.stride.offset); + break; + case MPIDI_RANK_MAP_STRIDE_BLOCK: + *avtid = MPIDI_COMM(comm, map).avtid; + *idx = MPIDI_CALC_STRIDE(rank, MPIDI_COMM(comm, map).reg.stride.stride, + MPIDI_COMM(comm, map).reg.stride.blocksize, + MPIDI_COMM(comm, map).reg.stride.offset); + break; + case MPIDI_RANK_MAP_STRIDE_BLOCK_INTRA: + *idx = MPIDI_CALC_STRIDE(rank, MPIDI_COMM(comm, map).reg.stride.stride, + MPIDI_COMM(comm, map).reg.stride.blocksize, + MPIDI_COMM(comm, map).reg.stride.offset); + break; + case MPIDI_RANK_MAP_LUT: + *avtid = MPIDI_COMM(comm, map).avtid; + *idx = MPIDI_COMM(comm, map).irreg.lut.lpid[rank]; + break; + case MPIDI_RANK_MAP_LUT_INTRA: + *idx = MPIDI_COMM(comm, map).irreg.lut.lpid[rank]; + break; + case MPIDI_RANK_MAP_MLUT: + *idx = MPIDI_COMM(comm, map).irreg.mlut.gpid[rank].lpid; + *avtid = MPIDI_COMM(comm, map).irreg.mlut.gpid[rank].avtid; + break; + case MPIDI_RANK_MAP_NONE: + MPIR_Assert(0); + break; + } + MPL_DBG_MSG_FMT(MPIDI_CH4_DBG_MAP, VERBOSE, + (MPL_DBG_FDEST, " comm_to_pid: rank=%d, avtid=%d idx=%d", rank, *avtid, *idx)); + MPIR_FUNC_EXIT; + return *idx; +} + +MPL_STATIC_INLINE_PREFIX MPIDI_av_entry_t *MPIDIU_comm_rank_to_av(MPIR_Comm * comm, int rank) +{ + MPIDI_av_entry_t *ret = NULL; + MPIR_FUNC_ENTER; + + int lpid; + switch (MPIDI_COMM(comm, map).mode) { + case MPIDI_RANK_MAP_DIRECT: + ret = &MPIDI_global.avt_mgr.av_tables[MPIDI_COMM(comm, map).avtid]->table[rank]; + break; + case MPIDI_RANK_MAP_DIRECT_INTRA: + ret = &MPIDI_global.avt_mgr.av_table0->table[rank]; + break; + case MPIDI_RANK_MAP_OFFSET: + ret = &MPIDI_global.avt_mgr.av_tables[MPIDI_COMM(comm, map).avtid] + ->table[rank + MPIDI_COMM(comm, map).reg.offset]; + break; + case MPIDI_RANK_MAP_OFFSET_INTRA: + ret = &MPIDI_global.avt_mgr.av_table0->table[rank + MPIDI_COMM(comm, map).reg.offset]; + break; + case MPIDI_RANK_MAP_STRIDE: + lpid = MPIDI_CALC_STRIDE_SIMPLE(rank, MPIDI_COMM(comm, map).reg.stride.stride, + MPIDI_COMM(comm, map).reg.stride.offset); + ret = &MPIDI_global.avt_mgr.av_tables[MPIDI_COMM(comm, map).avtid]->table[lpid]; + break; + case MPIDI_RANK_MAP_STRIDE_INTRA: + lpid = MPIDI_CALC_STRIDE_SIMPLE(rank, MPIDI_COMM(comm, map).reg.stride.stride, + MPIDI_COMM(comm, map).reg.stride.offset); + ret = &MPIDI_global.avt_mgr.av_table0->table[lpid]; + break; + case MPIDI_RANK_MAP_STRIDE_BLOCK: + lpid = MPIDI_CALC_STRIDE(rank, MPIDI_COMM(comm, map).reg.stride.stride, + MPIDI_COMM(comm, map).reg.stride.blocksize, + MPIDI_COMM(comm, map).reg.stride.offset); + ret = &MPIDI_global.avt_mgr.av_tables[MPIDI_COMM(comm, map).avtid]->table[lpid]; + break; + case MPIDI_RANK_MAP_STRIDE_BLOCK_INTRA: + lpid = MPIDI_CALC_STRIDE(rank, MPIDI_COMM(comm, map).reg.stride.stride, + MPIDI_COMM(comm, map).reg.stride.blocksize, + MPIDI_COMM(comm, map).reg.stride.offset); + ret = &MPIDI_global.avt_mgr.av_table0->table[lpid]; + break; + case MPIDI_RANK_MAP_LUT: + ret = &MPIDI_global.avt_mgr.av_tables[MPIDI_COMM(comm, map).avtid] + ->table[MPIDI_COMM(comm, map).irreg.lut.lpid[rank]]; + break; + case MPIDI_RANK_MAP_LUT_INTRA: + ret = + &MPIDI_global.avt_mgr.av_table0->table[MPIDI_COMM(comm, map).irreg.lut.lpid[rank]]; + break; + case MPIDI_RANK_MAP_MLUT: + ret = &MPIDI_global.avt_mgr.av_tables[MPIDI_COMM(comm, map).irreg.mlut.gpid[rank].avtid] + ->table[MPIDI_COMM(comm, map).irreg.mlut.gpid[rank].lpid]; + break; + case MPIDI_RANK_MAP_NONE: + MPIR_Assert(0); + break; + } + + MPL_DBG_MSG_FMT(MPIDI_CH4_DBG_MAP, VERBOSE, + (MPL_DBG_FDEST, " comm_to_av_addr: rank=%d, av addr=%p", rank, (void *) ret)); + MPIR_FUNC_EXIT; + return ret; +} + +MPL_STATIC_INLINE_PREFIX int MPIDIU_comm_rank_to_pid_local(MPIR_Comm * comm, int rank, int *idx, + int *avtid) +{ + MPIR_FUNC_ENTER; + + *avtid = MPIDI_COMM(comm, local_map).avtid; + switch (MPIDI_COMM(comm, local_map).mode) { + case MPIDI_RANK_MAP_DIRECT: + case MPIDI_RANK_MAP_DIRECT_INTRA: + *idx = rank; + break; + case MPIDI_RANK_MAP_OFFSET: + case MPIDI_RANK_MAP_OFFSET_INTRA: + *idx = rank + MPIDI_COMM(comm, local_map).reg.offset; + break; + case MPIDI_RANK_MAP_STRIDE: + case MPIDI_RANK_MAP_STRIDE_INTRA: + *idx = MPIDI_CALC_STRIDE_SIMPLE(rank, MPIDI_COMM(comm, local_map).reg.stride.stride, + MPIDI_COMM(comm, local_map).reg.stride.offset); + break; + case MPIDI_RANK_MAP_STRIDE_BLOCK: + case MPIDI_RANK_MAP_STRIDE_BLOCK_INTRA: + *idx = MPIDI_CALC_STRIDE(rank, MPIDI_COMM(comm, local_map).reg.stride.stride, + MPIDI_COMM(comm, local_map).reg.stride.blocksize, + MPIDI_COMM(comm, local_map).reg.stride.offset); + break; + case MPIDI_RANK_MAP_LUT: + case MPIDI_RANK_MAP_LUT_INTRA: + *idx = MPIDI_COMM(comm, local_map).irreg.lut.lpid[rank]; + break; + case MPIDI_RANK_MAP_MLUT: + *idx = MPIDI_COMM(comm, local_map).irreg.mlut.gpid[rank].lpid; + *avtid = MPIDI_COMM(comm, local_map).irreg.mlut.gpid[rank].avtid; + break; + case MPIDI_RANK_MAP_NONE: + MPIR_Assert(0); + break; + } + MPL_DBG_MSG_FMT(MPIDI_CH4_DBG_MAP, VERBOSE, + (MPL_DBG_FDEST, " comm_to_pid_local: rank=%d, avtid=%d idx=%d", + rank, *avtid, *idx)); + MPIR_FUNC_EXIT; + return *idx; +} + +MPL_STATIC_INLINE_PREFIX int MPIDIU_rank_is_local(int rank, MPIR_Comm * comm) +{ + int ret = 0; + MPIR_FUNC_ENTER; + +#ifdef MPIDI_BUILD_CH4_LOCALITY_INFO + ret = MPIDIU_comm_rank_to_av(comm, rank)->is_local; + MPL_DBG_MSG_FMT(MPIDI_CH4_DBG_MAP, VERBOSE, + (MPL_DBG_FDEST, " is_local=%d, rank=%d", ret, rank)); +#endif + + MPIR_FUNC_EXIT; + return ret; +} + +MPL_STATIC_INLINE_PREFIX int MPIDIU_av_is_local(MPIDI_av_entry_t * av) +{ + int ret = 0; + MPIR_FUNC_ENTER; + +#ifdef MPIDI_BUILD_CH4_LOCALITY_INFO + ret = av->is_local; + MPL_DBG_MSG_FMT(MPIDI_CH4_DBG_MAP, VERBOSE, + (MPL_DBG_FDEST, " is_local=%d, av=%p", ret, (void *) av)); +#endif + + MPIR_FUNC_EXIT; + return ret; +} + +MPL_STATIC_INLINE_PREFIX int MPIDIU_rank_to_lpid(int rank, MPIR_Comm * comm) +{ + int ret; + MPIR_FUNC_ENTER; + + int avtid = 0, lpid = 0; + MPIDIU_comm_rank_to_pid(comm, rank, &lpid, &avtid); + if (avtid == 0) { + ret = lpid; + } else { + ret = -1; + } + + MPIR_FUNC_EXIT; + return ret; +} MPL_STATIC_INLINE_PREFIX int MPIDI_rank_is_local(int rank, MPIR_Comm * comm) { diff --git a/src/mpid/ch4/src/ch4_send.h b/src/mpid/ch4/src/ch4_send.h index 2493e2a505a..67cc2c43eb5 100644 --- a/src/mpid/ch4/src/ch4_send.h +++ b/src/mpid/ch4/src/ch4_send.h @@ -7,7 +7,7 @@ #define CH4_SEND_H_INCLUDED #include "ch4_impl.h" -#include "ch4r_proc.h" +#include "ch4_proc.h" MPL_STATIC_INLINE_PREFIX int MPIDI_isend(const void *buf, MPI_Aint count, diff --git a/src/mpid/ch4/src/ch4r_proc.h b/src/mpid/ch4/src/ch4r_proc.h deleted file mode 100644 index 578153ff844..00000000000 --- a/src/mpid/ch4/src/ch4r_proc.h +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (C) by Argonne National Laboratory - * See COPYRIGHT in top-level directory - */ - -#ifndef CH4R_PROC_H_INCLUDED -#define CH4R_PROC_H_INCLUDED - -#include "ch4_types.h" - -/* There are 3 terms referencing processes: - * upid, or "unversal process id", is netmod layer address (addrname) - * lpid, or "local process id", is av entry index in an ch4-layer table - * gpid, or "global process id", is av table index plus av entry index - * - * For non-dynamic processes, av table index is 0, thus lpid equals to gpid (other than type). - * The upid is used when establishing netmod connections. - * The lpid and gpid are defined here with avt manager. - */ - -int MPIDIU_get_n_avts(void); -int MPIDIU_get_avt_size(int avtid); -int MPIDIU_new_avt(int size, int *avtid); -int MPIDIU_free_avt(int avtid); -int MPIDIU_avt_add_ref(int avtid); -int MPIDIU_avt_release_ref(int avtid); -int MPIDIU_avt_init(void); -int MPIDIU_avt_destroy(void); -int MPIDIU_get_node_id(MPIR_Comm * comm, int rank, int *id_p); - -int MPIDIU_upids_to_gpids(int size, int *remote_upid_size, char *remote_upids, - uint64_t * remote_gpids); -int MPIDIU_alloc_lut(MPIDI_rank_map_lut_t ** lut, int size); -int MPIDIU_release_lut(MPIDI_rank_map_lut_t * lut); -int MPIDIU_alloc_mlut(MPIDI_rank_map_mlut_t ** mlut, int size); -int MPIDIU_release_mlut(MPIDI_rank_map_mlut_t * mlut); - -MPL_STATIC_INLINE_PREFIX int MPIDIU_comm_rank_to_pid(MPIR_Comm * comm, int rank, int *idx, - int *avtid) -{ - MPIR_FUNC_ENTER; - - *avtid = 0; - - switch (MPIDI_COMM(comm, map).mode) { - case MPIDI_RANK_MAP_DIRECT: - *avtid = MPIDI_COMM(comm, map).avtid; - *idx = rank; - break; - case MPIDI_RANK_MAP_DIRECT_INTRA: - *idx = rank; - break; - case MPIDI_RANK_MAP_OFFSET: - *avtid = MPIDI_COMM(comm, map).avtid; - *idx = rank + MPIDI_COMM(comm, map).reg.offset; - break; - case MPIDI_RANK_MAP_OFFSET_INTRA: - *idx = rank + MPIDI_COMM(comm, map).reg.offset; - break; - case MPIDI_RANK_MAP_STRIDE: - *avtid = MPIDI_COMM(comm, map).avtid; - *idx = MPIDI_CALC_STRIDE_SIMPLE(rank, MPIDI_COMM(comm, map).reg.stride.stride, - MPIDI_COMM(comm, map).reg.stride.offset); - break; - case MPIDI_RANK_MAP_STRIDE_INTRA: - *idx = MPIDI_CALC_STRIDE_SIMPLE(rank, MPIDI_COMM(comm, map).reg.stride.stride, - MPIDI_COMM(comm, map).reg.stride.offset); - break; - case MPIDI_RANK_MAP_STRIDE_BLOCK: - *avtid = MPIDI_COMM(comm, map).avtid; - *idx = MPIDI_CALC_STRIDE(rank, MPIDI_COMM(comm, map).reg.stride.stride, - MPIDI_COMM(comm, map).reg.stride.blocksize, - MPIDI_COMM(comm, map).reg.stride.offset); - break; - case MPIDI_RANK_MAP_STRIDE_BLOCK_INTRA: - *idx = MPIDI_CALC_STRIDE(rank, MPIDI_COMM(comm, map).reg.stride.stride, - MPIDI_COMM(comm, map).reg.stride.blocksize, - MPIDI_COMM(comm, map).reg.stride.offset); - break; - case MPIDI_RANK_MAP_LUT: - *avtid = MPIDI_COMM(comm, map).avtid; - *idx = MPIDI_COMM(comm, map).irreg.lut.lpid[rank]; - break; - case MPIDI_RANK_MAP_LUT_INTRA: - *idx = MPIDI_COMM(comm, map).irreg.lut.lpid[rank]; - break; - case MPIDI_RANK_MAP_MLUT: - *idx = MPIDI_COMM(comm, map).irreg.mlut.gpid[rank].lpid; - *avtid = MPIDI_COMM(comm, map).irreg.mlut.gpid[rank].avtid; - break; - case MPIDI_RANK_MAP_NONE: - MPIR_Assert(0); - break; - } - MPL_DBG_MSG_FMT(MPIDI_CH4_DBG_MAP, VERBOSE, - (MPL_DBG_FDEST, " comm_to_pid: rank=%d, avtid=%d idx=%d", rank, *avtid, *idx)); - MPIR_FUNC_EXIT; - return *idx; -} - -MPL_STATIC_INLINE_PREFIX MPIDI_av_entry_t *MPIDIU_comm_rank_to_av(MPIR_Comm * comm, int rank) -{ - MPIDI_av_entry_t *ret = NULL; - MPIR_FUNC_ENTER; - - int lpid; - switch (MPIDI_COMM(comm, map).mode) { - case MPIDI_RANK_MAP_DIRECT: - ret = &MPIDI_global.avt_mgr.av_tables[MPIDI_COMM(comm, map).avtid]->table[rank]; - break; - case MPIDI_RANK_MAP_DIRECT_INTRA: - ret = &MPIDI_global.avt_mgr.av_table0->table[rank]; - break; - case MPIDI_RANK_MAP_OFFSET: - ret = &MPIDI_global.avt_mgr.av_tables[MPIDI_COMM(comm, map).avtid] - ->table[rank + MPIDI_COMM(comm, map).reg.offset]; - break; - case MPIDI_RANK_MAP_OFFSET_INTRA: - ret = &MPIDI_global.avt_mgr.av_table0->table[rank + MPIDI_COMM(comm, map).reg.offset]; - break; - case MPIDI_RANK_MAP_STRIDE: - lpid = MPIDI_CALC_STRIDE_SIMPLE(rank, MPIDI_COMM(comm, map).reg.stride.stride, - MPIDI_COMM(comm, map).reg.stride.offset); - ret = &MPIDI_global.avt_mgr.av_tables[MPIDI_COMM(comm, map).avtid]->table[lpid]; - break; - case MPIDI_RANK_MAP_STRIDE_INTRA: - lpid = MPIDI_CALC_STRIDE_SIMPLE(rank, MPIDI_COMM(comm, map).reg.stride.stride, - MPIDI_COMM(comm, map).reg.stride.offset); - ret = &MPIDI_global.avt_mgr.av_table0->table[lpid]; - break; - case MPIDI_RANK_MAP_STRIDE_BLOCK: - lpid = MPIDI_CALC_STRIDE(rank, MPIDI_COMM(comm, map).reg.stride.stride, - MPIDI_COMM(comm, map).reg.stride.blocksize, - MPIDI_COMM(comm, map).reg.stride.offset); - ret = &MPIDI_global.avt_mgr.av_tables[MPIDI_COMM(comm, map).avtid]->table[lpid]; - break; - case MPIDI_RANK_MAP_STRIDE_BLOCK_INTRA: - lpid = MPIDI_CALC_STRIDE(rank, MPIDI_COMM(comm, map).reg.stride.stride, - MPIDI_COMM(comm, map).reg.stride.blocksize, - MPIDI_COMM(comm, map).reg.stride.offset); - ret = &MPIDI_global.avt_mgr.av_table0->table[lpid]; - break; - case MPIDI_RANK_MAP_LUT: - ret = &MPIDI_global.avt_mgr.av_tables[MPIDI_COMM(comm, map).avtid] - ->table[MPIDI_COMM(comm, map).irreg.lut.lpid[rank]]; - break; - case MPIDI_RANK_MAP_LUT_INTRA: - ret = - &MPIDI_global.avt_mgr.av_table0->table[MPIDI_COMM(comm, map).irreg.lut.lpid[rank]]; - break; - case MPIDI_RANK_MAP_MLUT: - ret = &MPIDI_global.avt_mgr.av_tables[MPIDI_COMM(comm, map).irreg.mlut.gpid[rank].avtid] - ->table[MPIDI_COMM(comm, map).irreg.mlut.gpid[rank].lpid]; - break; - case MPIDI_RANK_MAP_NONE: - MPIR_Assert(0); - break; - } - - MPL_DBG_MSG_FMT(MPIDI_CH4_DBG_MAP, VERBOSE, - (MPL_DBG_FDEST, " comm_to_av_addr: rank=%d, av addr=%p", rank, (void *) ret)); - MPIR_FUNC_EXIT; - return ret; -} - -MPL_STATIC_INLINE_PREFIX int MPIDIU_comm_rank_to_pid_local(MPIR_Comm * comm, int rank, int *idx, - int *avtid) -{ - MPIR_FUNC_ENTER; - - *avtid = MPIDI_COMM(comm, local_map).avtid; - switch (MPIDI_COMM(comm, local_map).mode) { - case MPIDI_RANK_MAP_DIRECT: - case MPIDI_RANK_MAP_DIRECT_INTRA: - *idx = rank; - break; - case MPIDI_RANK_MAP_OFFSET: - case MPIDI_RANK_MAP_OFFSET_INTRA: - *idx = rank + MPIDI_COMM(comm, local_map).reg.offset; - break; - case MPIDI_RANK_MAP_STRIDE: - case MPIDI_RANK_MAP_STRIDE_INTRA: - *idx = MPIDI_CALC_STRIDE_SIMPLE(rank, MPIDI_COMM(comm, local_map).reg.stride.stride, - MPIDI_COMM(comm, local_map).reg.stride.offset); - break; - case MPIDI_RANK_MAP_STRIDE_BLOCK: - case MPIDI_RANK_MAP_STRIDE_BLOCK_INTRA: - *idx = MPIDI_CALC_STRIDE(rank, MPIDI_COMM(comm, local_map).reg.stride.stride, - MPIDI_COMM(comm, local_map).reg.stride.blocksize, - MPIDI_COMM(comm, local_map).reg.stride.offset); - break; - case MPIDI_RANK_MAP_LUT: - case MPIDI_RANK_MAP_LUT_INTRA: - *idx = MPIDI_COMM(comm, local_map).irreg.lut.lpid[rank]; - break; - case MPIDI_RANK_MAP_MLUT: - *idx = MPIDI_COMM(comm, local_map).irreg.mlut.gpid[rank].lpid; - *avtid = MPIDI_COMM(comm, local_map).irreg.mlut.gpid[rank].avtid; - break; - case MPIDI_RANK_MAP_NONE: - MPIR_Assert(0); - break; - } - MPL_DBG_MSG_FMT(MPIDI_CH4_DBG_MAP, VERBOSE, - (MPL_DBG_FDEST, " comm_to_pid_local: rank=%d, avtid=%d idx=%d", - rank, *avtid, *idx)); - MPIR_FUNC_EXIT; - return *idx; -} - -MPL_STATIC_INLINE_PREFIX int MPIDIU_rank_is_local(int rank, MPIR_Comm * comm) -{ - int ret = 0; - MPIR_FUNC_ENTER; - -#ifdef MPIDI_BUILD_CH4_LOCALITY_INFO - ret = MPIDIU_comm_rank_to_av(comm, rank)->is_local; - MPL_DBG_MSG_FMT(MPIDI_CH4_DBG_MAP, VERBOSE, - (MPL_DBG_FDEST, " is_local=%d, rank=%d", ret, rank)); -#endif - - MPIR_FUNC_EXIT; - return ret; -} - -MPL_STATIC_INLINE_PREFIX int MPIDIU_av_is_local(MPIDI_av_entry_t * av) -{ - int ret = 0; - MPIR_FUNC_ENTER; - -#ifdef MPIDI_BUILD_CH4_LOCALITY_INFO - ret = av->is_local; - MPL_DBG_MSG_FMT(MPIDI_CH4_DBG_MAP, VERBOSE, - (MPL_DBG_FDEST, " is_local=%d, av=%p", ret, (void *) av)); -#endif - - MPIR_FUNC_EXIT; - return ret; -} - -MPL_STATIC_INLINE_PREFIX int MPIDIU_rank_to_lpid(int rank, MPIR_Comm * comm) -{ - int ret; - MPIR_FUNC_ENTER; - - int avtid = 0, lpid = 0; - MPIDIU_comm_rank_to_pid(comm, rank, &lpid, &avtid); - if (avtid == 0) { - ret = lpid; - } else { - ret = -1; - } - - MPIR_FUNC_EXIT; - return ret; -} - -#endif /* CH4R_PROC_H_INCLUDED */ diff --git a/src/mpid/ch4/src/mpidig_recv.h b/src/mpid/ch4/src/mpidig_recv.h index 821b0e73a15..48c67d44456 100644 --- a/src/mpid/ch4/src/mpidig_recv.h +++ b/src/mpid/ch4/src/mpidig_recv.h @@ -7,7 +7,7 @@ #define MPIDIG_RECV_H_INCLUDED #include "ch4_impl.h" -#include "ch4r_proc.h" +#include "ch4_proc.h" MPL_STATIC_INLINE_PREFIX void MPIDIG_prepare_recv_req(int rank, int tag, MPIR_Context_id_t context_id, void *buf, From 3ba828c1e0f54c55e53e803654b130cf9c80fe24 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 3 Oct 2021 08:43:07 -0500 Subject: [PATCH 004/607] mpir: add MPIR_Assert_error Instead of MPIR_Assert(0), use MPIR_Assert_error(errmsg). This always gives a error message, and it also avoids warnings on Intel compilers, e.g. warning #279: controlling expression is constant --- src/include/mpir_assert.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/include/mpir_assert.h b/src/include/mpir_assert.h index ed0b98a1182..56832ae7a41 100644 --- a/src/include/mpir_assert.h +++ b/src/include/mpir_assert.h @@ -20,6 +20,10 @@ int MPIR_Assert_fail(const char *cond, const char *file_name, int line_num); int MPIR_Assert_fail_fmt(const char *cond, const char *file_name, int line_num, const char *fmt, ...); +/* Instead of "MPIR_Assert(0)", use "MPIR_Assert_error(error_msg)" */ +#define MPIR_Assert_error(errmsg) \ + MPIR_Assert_fail(errmsg, __FILE__, __LINE__) + /* * MPIR_Assert() * From ca06735cdf323c8301bf892e09909adc9414a979 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 3 Oct 2021 08:53:00 -0500 Subject: [PATCH 005/607] misc: use MPIR_Assert_error To replace MPIR_Assert(0 && errmsg). This removes warnings on intel compiler. --- maint/gen_coll.py | 4 ++-- src/mpi/datatype/typerep/dataloop/looputil.c | 6 +++--- src/mpi/datatype/typerep/src/typerep_dataloop_commit.c | 2 +- src/mpi/errhan/errhan_impl.c | 2 +- src/mpi/request/request_impl.c | 2 +- src/mpid/common/genq/mpidu_genq_shmem_queue.c | 2 +- src/mpid/common/genq/mpidu_genq_shmem_queue.h | 4 ++-- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/maint/gen_coll.py b/maint/gen_coll.py index 77eb2c4e308..f90b13491e8 100644 --- a/maint/gen_coll.py +++ b/maint/gen_coll.py @@ -288,7 +288,7 @@ def dump_cases(commkind): dump_close("}") dump_else() if re.match(r'(scan|exscan|neighbor_)', name): - G.out.append("MPIR_Assert(0 && \"Only intra-communicator allowed\");") + G.out.append("MPIR_Assert_error(\"Only intra-communicator allowed\");") else: dump_open("switch (MPIR_CVAR_%s_INTER_ALGORITHM) {" % NAME) dump_cases("inter") @@ -371,7 +371,7 @@ def dump_cases(commkind): dump_close("}") dump_else() if re.match(r'(scan|exscan|neighbor_)', name): - G.out.append("MPIR_Assert(0 && \"Only intra-communicator allowed\");") + G.out.append("MPIR_Assert_error(\"Only intra-communicator allowed\");") else: dump_open("switch (MPIR_CVAR_%s_INTER_ALGORITHM) {" % NAME) dump_cases("inter") diff --git a/src/mpi/datatype/typerep/dataloop/looputil.c b/src/mpi/datatype/typerep/dataloop/looputil.c index e26c34464ba..44b7ece3b1e 100644 --- a/src/mpi/datatype/typerep/dataloop/looputil.c +++ b/src/mpi/datatype/typerep/dataloop/looputil.c @@ -155,7 +155,7 @@ static int external32_basic_convert(char *dest_buf, * range. It won't work if value overflow anyway. */ *(int64_t *) dest_ptr = (int32_t) tmp; } else { - MPIR_Assert(0 && "Unhandled conversion of unequal size"); + MPIR_Assert_error("Unhandled conversion of unequal size"); } src_ptr += src_el_size; @@ -169,14 +169,14 @@ static int external32_basic_convert(char *dest_buf, tmp = (int32_t) (*(const int64_t *) src_ptr); BASIC_convert32(tmp, *(uint32_t *) dest_ptr); } else { - MPIR_Assert(0 && "Unhandled conversion of unequal size"); + MPIR_Assert_error("Unhandled conversion of unequal size"); } src_ptr += src_el_size; dest_ptr += dest_el_size; } } else { - MPIR_Assert(0 && "Unhandled conversion of unequal size"); + MPIR_Assert_error("Unhandled conversion of unequal size"); } } return 0; diff --git a/src/mpi/datatype/typerep/src/typerep_dataloop_commit.c b/src/mpi/datatype/typerep/src/typerep_dataloop_commit.c index 8bdfd88e5b3..c0c2d1a77bd 100644 --- a/src/mpi/datatype/typerep/src/typerep_dataloop_commit.c +++ b/src/mpi/datatype/typerep/src/typerep_dataloop_commit.c @@ -144,7 +144,7 @@ void MPIR_Typerep_commit(MPI_Datatype type) case MPI_COMBINER_HVECTOR_INTEGER: case MPI_COMBINER_HINDEXED_INTEGER: case MPI_COMBINER_STRUCT_INTEGER: - MPIR_Assert(0 && "wrong combiner"); + MPIR_Assert_error("wrong combiner"); break; default: break; diff --git a/src/mpi/errhan/errhan_impl.c b/src/mpi/errhan/errhan_impl.c index 80bafb422bc..4d44e8e8075 100644 --- a/src/mpi/errhan/errhan_impl.c +++ b/src/mpi/errhan/errhan_impl.c @@ -300,7 +300,7 @@ static int call_errhandler(MPIR_Errhandler * errhandler, int errorcode, int hand } else if (kind == MPIR_WIN) { cxx_kind = 2; } else { - MPIR_Assert(0 && "not supported"); + MPIR_Assert_error("kind not supported"); } MPIR_Process.cxx_call_errfn(cxx_kind, &handle, &errorcode, (void (*)(void)) errhandler->errfn.C_Comm_Handler_function); diff --git a/src/mpi/request/request_impl.c b/src/mpi/request/request_impl.c index 0b60f1a5b4e..28cbe39624f 100644 --- a/src/mpi/request/request_impl.c +++ b/src/mpi/request/request_impl.c @@ -76,7 +76,7 @@ int MPIR_Cancel_impl(MPIR_Request * request_ptr) case MPIR_REQUEST_KIND__PREQUEST_COLL: { if (request_ptr->u.persist_coll.real_request != NULL) { - MPIR_Assert(0 && "Not supported"); + MPIR_Assert_error("Cancel persistent collective not supported"); } else { MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_REQUEST, "**requestpersistactive"); } diff --git a/src/mpid/common/genq/mpidu_genq_shmem_queue.c b/src/mpid/common/genq/mpidu_genq_shmem_queue.c index 8559a012b0b..757d9c98f5f 100644 --- a/src/mpid/common/genq/mpidu_genq_shmem_queue.c +++ b/src/mpid/common/genq/mpidu_genq_shmem_queue.c @@ -23,7 +23,7 @@ int MPIDU_genq_shmem_queue_init(MPIDU_genq_shmem_queue_t queue, int flags) } else if (flags == MPIDU_GENQ_SHMEM_QUEUE_TYPE__NEM_MPSC) { rc = MPIDU_genqi_nem_mpsc_init(queue_obj); } else { - MPIR_Assert(0 && "Invalid GenQ flag"); + MPIR_Assert_error("Invalid GenQ flag"); } MPIR_FUNC_EXIT; diff --git a/src/mpid/common/genq/mpidu_genq_shmem_queue.h b/src/mpid/common/genq/mpidu_genq_shmem_queue.h index d488361b17c..c666001fa94 100644 --- a/src/mpid/common/genq/mpidu_genq_shmem_queue.h +++ b/src/mpid/common/genq/mpidu_genq_shmem_queue.h @@ -232,7 +232,7 @@ static inline int MPIDU_genq_shmem_queue_dequeue(MPIDU_genq_shmem_pool_t pool, } else if (flags == MPIDU_GENQ_SHMEM_QUEUE_TYPE__NEM_MPSC) { rc = MPIDU_genqi_nem_mpsc_dequeue(pool_obj, queue_obj, cell); } else { - MPIR_Assert(0 && "Invalid GenQ flag"); + MPIR_Assert_error("Invalid GenQ flag"); } MPIR_FUNC_EXIT; @@ -255,7 +255,7 @@ static inline int MPIDU_genq_shmem_queue_enqueue(MPIDU_genq_shmem_pool_t pool, } else if (flags == MPIDU_GENQ_SHMEM_QUEUE_TYPE__NEM_MPSC) { rc = MPIDU_genqi_nem_mpsc_enqueue(pool_obj, queue_obj, cell); } else { - MPIR_Assert(0 && "Invalid GenQ flag"); + MPIR_Assert_error("Invalid GenQ flag"); } MPIR_FUNC_EXIT; From 027e74ac2030f3e58c29c23cfbbe08f10e2d7584 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 3 Oct 2021 09:17:26 -0500 Subject: [PATCH 006/607] ch4: fixup alignment on per_vci structures Adding alignment attribute on flexible array member, while works, it is warned by intel compiler as a non-standard usage. Use an extra char member in stead. Add debug summary so we can double check the structure sizes. --- src/mpid/ch4/netmod/ofi/ofi_init.c | 1 + src/mpid/ch4/netmod/ofi/ofi_types.h | 2 +- src/mpid/ch4/shm/posix/posix_types.h | 1 + src/mpid/ch4/src/ch4_init.c | 9 +++++---- src/mpid/ch4/src/ch4_types.h | 2 +- 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_init.c b/src/mpid/ch4/netmod/ofi/ofi_init.c index ab1ff239774..02e57eea4be 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_init.c +++ b/src/mpid/ch4/netmod/ofi/ofi_init.c @@ -1480,6 +1480,7 @@ static void dump_global_settings(void) fprintf(stdout, "MPIDI_OFI_MAX_AM_HDR_SIZE: %d\n", (int) MPIDI_OFI_MAX_AM_HDR_SIZE); fprintf(stdout, "sizeof(MPIDI_OFI_am_request_header_t): %d\n", (int) sizeof(MPIDI_OFI_am_request_header_t)); + fprintf(stdout, "sizeof(MPIDI_OFI_per_vni_t): %d\n", (int) sizeof(MPIDI_OFI_per_vni_t)); fprintf(stdout, "MPIDI_OFI_AM_HDR_POOL_CELL_SIZE: %d\n", (int) MPIDI_OFI_AM_HDR_POOL_CELL_SIZE); fprintf(stdout, "MPIDI_OFI_DEFAULT_SHORT_SEND_SIZE: %d\n", (int) MPIDI_OFI_DEFAULT_SHORT_SEND_SIZE); diff --git a/src/mpid/ch4/netmod/ofi/ofi_types.h b/src/mpid/ch4/netmod/ofi/ofi_types.h index c108be25146..a3a7448e6c1 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_types.h +++ b/src/mpid/ch4/netmod/ofi/ofi_types.h @@ -243,7 +243,7 @@ typedef struct { int cq_buffered_static_tail; MPIDI_OFI_cq_list_t *cq_buffered_dynamic_head, *cq_buffered_dynamic_tail; - char pad[] MPL_ATTR_ALIGNED(MPL_CACHELINE_SIZE); + char pad MPL_ATTR_ALIGNED(MPL_CACHELINE_SIZE); } MPIDI_OFI_per_vni_t; typedef struct { diff --git a/src/mpid/ch4/shm/posix/posix_types.h b/src/mpid/ch4/shm/posix/posix_types.h index 000c31364be..91a6b31adfa 100644 --- a/src/mpid/ch4/shm/posix/posix_types.h +++ b/src/mpid/ch4/shm/posix/posix_types.h @@ -28,6 +28,7 @@ typedef struct { MPIDU_genq_private_pool_t am_hdr_buf_pool; MPIDI_POSIX_am_request_header_t *postponed_queue; MPIR_Request **active_rreq; + char pad MPL_ATTR_ALIGNED(MPL_CACHELINE_SIZE); } MPIDI_POSIX_per_vsi_t; typedef struct { diff --git a/src/mpid/ch4/src/ch4_init.c b/src/mpid/ch4/src/ch4_init.c index c8e3dd55f38..d5701979538 100644 --- a/src/mpid/ch4/src/ch4_init.c +++ b/src/mpid/ch4/src/ch4_init.c @@ -357,12 +357,13 @@ int MPID_Init(int requested, int *provided) if (mpi_errno != MPI_SUCCESS) return mpi_errno; + if (MPIR_CVAR_DEBUG_SUMMARY && MPIR_Process.rank == 0) { #ifdef MPIDI_CH4_USE_MT_RUNTIME - int rank = MPIR_Process.rank; - if (MPIR_CVAR_CH4_RUNTIME_CONF_DEBUG && rank == 0) print_runtime_configurations(); -#endif /* #ifdef MPIDI_CH4_USE_MT_RUNTIME */ - +#endif + fprintf(stdout, "==== Various sizes and limits ====\n"); + fprintf(stdout, "sizeof(MPIDI_per_vci_t): %d\n", (int) sizeof(MPIDI_per_vci_t)); + } #ifdef MPIDI_CH4_USE_WORK_QUEUES MPIDI_workq_init(&MPIDI_global.workqueue); #endif /* #ifdef MPIDI_CH4_USE_WORK_QUEUES */ diff --git a/src/mpid/ch4/src/ch4_types.h b/src/mpid/ch4/src/ch4_types.h index 3389a2356ac..fb4027d042a 100644 --- a/src/mpid/ch4/src/ch4_types.h +++ b/src/mpid/ch4/src/ch4_types.h @@ -254,7 +254,7 @@ typedef struct MPIDI_per_vci { MPL_atomic_uint64_t exp_seq_no; MPL_atomic_uint64_t nxt_seq_no; - char pad[] MPL_ATTR_ALIGNED(MPL_CACHELINE_SIZE); + char pad MPL_ATTR_ALIGNED(MPL_CACHELINE_SIZE); } MPIDI_per_vci_t; #define MPIDI_VCI(i) MPIDI_global.per_vci[i] From 36f33260beb19efcf13eb4189bbb99c8c0cb717a Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 3 Oct 2021 13:29:30 -0500 Subject: [PATCH 007/607] coll: use enum type MPIR_Sched_kind Intel compiler warns if we pass an int to a enum parameter. --- src/mpi/coll/include/coll_impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mpi/coll/include/coll_impl.h b/src/mpi/coll/include/coll_impl.h index bb71e52f7a5..1b7c25c4c51 100644 --- a/src/mpi/coll/include/coll_impl.h +++ b/src/mpi/coll/include/coll_impl.h @@ -64,7 +64,7 @@ int MPII_Coll_finalize(void); #define MPII_SCHED_CREATE_SCHED_P() \ do { \ MPIR_Sched_t s = MPIR_SCHED_NULL; \ - int sched_kind = MPIR_SCHED_KIND_REGULAR; \ + enum MPIR_Sched_kind sched_kind = MPIR_SCHED_KIND_REGULAR; \ if (is_persistent) { \ sched_kind = MPIR_SCHED_KIND_PERSISTENT; \ } \ From 385a3a36a7f2107d188722ee8af1f162db7578e3 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 3 Oct 2021 16:39:04 -0500 Subject: [PATCH 008/607] maint: filter interl compiler remarks Remarks are not errors or warnings. --- maint/clmake.in | 1 + 1 file changed, 1 insertion(+) diff --git a/maint/clmake.in b/maint/clmake.in index 955c39f7913..87b3ddf1684 100644 --- a/maint/clmake.in +++ b/maint/clmake.in @@ -90,6 +90,7 @@ $rootSrcDir = ""; 'copying python', 'LOOP WAS VECTORIZED', 'Using variables ', + 'remark #\d+: .*', # intel compiler ); # In the past, we also needed # WARNING 84.*not used for resolving any symbol From 4b4a33a3fccf94200aab2d537459fbf69f4c58cb Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 3 Oct 2021 17:16:40 -0500 Subject: [PATCH 009/607] util: fix enumerated type mixed with integer This fixes warning by some compilers, e.g. intel compiler. --- src/util/mpir_hwtopo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/mpir_hwtopo.c b/src/util/mpir_hwtopo.c index e7123d95ed9..1f7d128b9ab 100644 --- a/src/util/mpir_hwtopo.c +++ b/src/util/mpir_hwtopo.c @@ -135,7 +135,7 @@ static hwloc_obj_type_t get_hwloc_obj_type(MPIR_hwtopo_type_e type) hwloc_obj_type = HWLOC_OBJ_PCI_DEVICE; break; default: - hwloc_obj_type = -1; + hwloc_obj_type = (hwloc_obj_type_t) (-1); } return hwloc_obj_type; @@ -517,7 +517,7 @@ int MPIR_hwtopo_mem_bind(void *baseaddr, size_t len, MPIR_hwtopo_gid_t gid) hwloc_bitmap_or(bitmap, bitmap, hwloc_obj->nodeset); if (hwloc_obj->type == HWLOC_OBJ_NUMANODE) { - flags |= HWLOC_MEMBIND_BYNODESET; + flags = (hwloc_membind_flags_t) ((int) flags | (int) HWLOC_MEMBIND_BYNODESET); } else { #ifdef HAVE_ERROR_CHECKING ret = From d394dacdac3ec397fc139a651534643d28dbd87e Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 3 Oct 2021 17:20:08 -0500 Subject: [PATCH 010/607] ch4/ofi: suppress warning of use before set The warning is false positive but some compiler, e.g. intel compiler, cannot tell. Add initializer to suppress the warnings. --- src/mpid/ch4/netmod/ofi/ofi_nic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_nic.c b/src/mpid/ch4/netmod/ofi/ofi_nic.c index 3c71d7078cb..b7c23c5bf08 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_nic.c +++ b/src/mpid/ch4/netmod/ofi/ofi_nic.c @@ -174,7 +174,7 @@ static int setup_single_nic(void) static int setup_multi_nic(int nic_count) { int mpi_errno = MPI_SUCCESS; - MPIR_hwtopo_gid_t parents[MPIDI_OFI_MAX_NICS]; + MPIR_hwtopo_gid_t parents[MPIDI_OFI_MAX_NICS] = { 0 }; int num_parents = 0; int local_rank = MPIR_Process.local_rank; MPIDI_OFI_nic_info_t *nics = MPIDI_OFI_global.nic_info; From 96bacc826dbcbd89581f3989df7eac8985cfaf63 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 3 Oct 2021 20:55:41 -0500 Subject: [PATCH 011/607] build: fix parsing hwloc_embedded_libs The `$4` is eaten by M4 in autoconf. We need play some quoting trick to pass it to shell. --- confdb/aclocal_modules.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/confdb/aclocal_modules.m4 b/confdb/aclocal_modules.m4 index 174b77defd3..ab07c80acce 100644 --- a/confdb/aclocal_modules.m4 +++ b/confdb/aclocal_modules.m4 @@ -79,7 +79,7 @@ AC_DEFUN([PAC_CONFIG_HWLOC],[ PAC_APPEND_FLAG([-I${main_top_builddir}/modules/hwloc/include],[CPPFLAGS]) # capture the line -- S["HWLOC_EMBEDDED_LIBS"]="-lm " - hwloc_embedded_libs=$(awk -F'"' '/^S."HWLOC_EMBEDDED_LIBS"/ {print $4}' modules/hwloc/config.status) + hwloc_embedded_libs=$(awk -F'"' '/^S."HWLOC_EMBEDDED_LIBS"/ {print $[]4}' modules/hwloc/config.status) echo "hwloc_embedded_libs = $hwloc_embedded_libs" if test -n "$hwloc_embedded_libs" ; then dnl TODO: split and add individual lib From 9e9484ed032ea151c0d55ac514509d68989b735d Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 3 Oct 2021 21:14:51 -0500 Subject: [PATCH 012/607] ch4/ipc: fix bug in ipc_send We can't recursively getting combiner once it hit a predefined datatype. --- src/mpid/ch4/shm/ipc/src/ipc_send.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mpid/ch4/shm/ipc/src/ipc_send.h b/src/mpid/ch4/shm/ipc/src/ipc_send.h index fd4eb32297e..e5d8dec2b1e 100644 --- a/src/mpid/ch4/shm/ipc/src/ipc_send.h +++ b/src/mpid/ch4/shm/ipc/src/ipc_send.h @@ -48,6 +48,9 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_IPCI_try_lmt_isend(const void *buf, MPI_Aint MPI_Datatype *types; MPIR_Datatype_access_contents(tmp_dtp->contents, &ints, &aints, &counts, &types); MPIR_Datatype_get_ptr(types[0], tmp_dtp); + if (!tmp_dtp || !tmp_dtp->contents) { + break; + } combiner = tmp_dtp->contents->combiner; } switch (combiner) { From 6c7188d4cfaa4fbd7c616fd82b9980c5f024ee82 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 3 Oct 2021 13:56:59 -0500 Subject: [PATCH 013/607] test: lower the iterations for rma_contig test This test used have 720s time limit. Lowering the iteration count serves the same testing purpose as increasing the time limit, and it is cleaner to just lower the iteration count. This fixes the current ch3 timeout failure on rma_contig. --- test/mpi/rma/testlist.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/mpi/rma/testlist.in b/test/mpi/rma/testlist.in index 84f2dd7c401..f87da3b6ac5 100644 --- a/test/mpi/rma/testlist.in +++ b/test/mpi/rma/testlist.in @@ -132,7 +132,7 @@ mutex_bench_shared 4 mutex_bench_shm 4 mutex_bench_shm_ordered 4 rma_contig 2 arg=-iter=10 -rma_contig 2 arg=-iter=32768 +rma_contig 2 arg=-iter=10000 badrma 2 acc_loc 4 acc_ordering 2 From d91115fcd66a5337d6dd3c232967a228349d3751 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 20 Sep 2021 10:36:22 -0500 Subject: [PATCH 014/607] test/xfail: remove multi-thread huge send xfails --- test/mpi/maint/jenkins/xfail.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/test/mpi/maint/jenkins/xfail.conf b/test/mpi/maint/jenkins/xfail.conf index dc2c31b6148..09ad90d5a8c 100644 --- a/test/mpi/maint/jenkins/xfail.conf +++ b/test/mpi/maint/jenkins/xfail.conf @@ -35,7 +35,6 @@ * * * ch4:ofi * /^idup_nb/ xfail=ticket3794 test/mpi/threads/comm/testlist * * * ch4:ucx * /^idup_comm_gen/ xfail=ticket3794 test/mpi/threads/comm/testlist * * * ch4:ucx * /^idup_nb/ xfail=ticket3794 test/mpi/threads/comm/testlist -* * * ch4:ofi * /^mt_.*_huge.* env=MPIR_CVAR_CH4_OFI_EAGER_MAX_MSG_SIZE=16384/ xfail=ticket5359 test/mpi/threads/pt2pt/testlist ################################################################################ # misc special build * * nofast * * /^large_acc_flush_local/ xfail=issue4663 test/mpi/rma/testlist From bfd68e60a85545ae221d3f97b935260daa787eaa Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 22 Sep 2021 17:23:02 -0500 Subject: [PATCH 015/607] test: add more tests for sending huge message --- test/mpi/errors/pt2pt/testlist | 1 + test/mpi/errors/pt2pt/truncmsg1.c | 8 ++++++++ test/mpi/pt2pt/testlist.in | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/test/mpi/errors/pt2pt/testlist b/test/mpi/errors/pt2pt/testlist index 4e1e629b5a1..e21ed1fd68b 100644 --- a/test/mpi/errors/pt2pt/testlist +++ b/test/mpi/errors/pt2pt/testlist @@ -1,5 +1,6 @@ proberank 1 truncmsg1 2 +truncmsg1 2 env=MPIR_CVAR_CH4_OFI_EAGER_MAX_MSG_SIZE=16384 truncmsg2 2 truncmsg_mrecv 2 mpiversion=3.0 # multiple completion ests diff --git a/test/mpi/errors/pt2pt/truncmsg1.c b/test/mpi/errors/pt2pt/truncmsg1.c index 7ebe7402808..2328a27bb83 100644 --- a/test/mpi/errors/pt2pt/truncmsg1.c +++ b/test/mpi/errors/pt2pt/truncmsg1.c @@ -83,6 +83,14 @@ int main(int argc, char *argv[]) err = MPI_Recv(buf, LongLen - 1, MPI_INT, source, 0, MPI_COMM_WORLD, &status); errs += checkTruncError(err, "long"); } + /* Test when the receive buffer is much shorter */ + if (rank == source) { + err = MPI_Send(buf, LongLen, MPI_INT, dest, 0, MPI_COMM_WORLD); + errs += checkOk(err, "long"); + } else if (rank == dest) { + err = MPI_Recv(buf, ShortLen, MPI_INT, source, 0, MPI_COMM_WORLD, &status); + errs += checkTruncError(err, "long-receive-short"); + } } free(buf); diff --git a/test/mpi/pt2pt/testlist.in b/test/mpi/pt2pt/testlist.in index 66656e5c02f..9f713342e95 100644 --- a/test/mpi/pt2pt/testlist.in +++ b/test/mpi/pt2pt/testlist.in @@ -52,10 +52,14 @@ waitany_null 1 # perhaps disable in the release tarball large_message 3 mem=6.5 mprobe 2 +mprobe 2 env=MPIR_CVAR_CH4_OFI_EAGER_MAX_MSG_SIZE=16384 +mprobe 2 env=MPIR_CVAR_CH4_OFI_AM_LONG_FORCE_PIPELINE=true big_count_status 1 many_isend 3 manylmt 2 huge_underflow 2 +huge_underflow 2 env=MPIR_CVAR_CH4_OFI_EAGER_MAX_MSG_SIZE=16384 +huge_underflow 2 env=MPIR_CVAR_CH4_OFI_AM_LONG_FORCE_PIPELINE=true huge_anysrc 2 huge_dupcomm 2 huge_ssend 2 From 873acf951f97bf1fe02e94276301b4f015bfb09d Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 27 Sep 2021 00:17:21 -0500 Subject: [PATCH 016/607] test: enhance test/mpi/pt2pt/probe_unexp.c Enhance the test by test multiple communicators. This catches the current ofi huge path's incorrect context_id handling. --- test/mpi/pt2pt/probe_unexp.c | 190 ++++++++++++++++++----------------- 1 file changed, 99 insertions(+), 91 deletions(-) diff --git a/test/mpi/pt2pt/probe_unexp.c b/test/mpi/pt2pt/probe_unexp.c index 0dda3336b61..3e867f15d4f 100644 --- a/test/mpi/pt2pt/probe_unexp.c +++ b/test/mpi/pt2pt/probe_unexp.c @@ -17,8 +17,10 @@ char buf[1 << MAX_BUF_SIZE_LG]; * been called. This program may hang if MPI_Probe() does not return when the * message finally arrives (see req #375). */ + int main(int argc, char **argv) { + MPI_Comm comm; int p_size; int p_rank; int msg_size_lg; @@ -27,115 +29,121 @@ int main(int argc, char **argv) MTest_Init(&argc, &argv); - MPI_Comm_size(MPI_COMM_WORLD, &p_size); - MPI_Comm_rank(MPI_COMM_WORLD, &p_rank); - /* To improve reporting of problems about operations, we - * change the error handler to errors return */ - MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN); - - - for (msg_size_lg = 0; msg_size_lg <= MAX_BUF_SIZE_LG; msg_size_lg++) { - const int msg_size = 1 << msg_size_lg; - int msg_cnt; + while (MTestGetIntracommGeneral(&comm, 2, 1)) { + if (comm == MPI_COMM_NULL) { + continue; + } - MTestPrintfMsg(2, "testing messages of size %d\n", msg_size); - for (msg_cnt = 0; msg_cnt < NUM_MSGS_PER_BUF_SIZE; msg_cnt++) { - MPI_Status status; - const int tag = msg_size_lg * NUM_MSGS_PER_BUF_SIZE + msg_cnt; + MPI_Comm_size(comm, &p_size); + MPI_Comm_rank(comm, &p_rank); + /* To improve reporting of problems about operations, we + * change the error handler to errors return */ + MPI_Comm_set_errhandler(comm, MPI_ERRORS_RETURN); + + + for (msg_size_lg = 0; msg_size_lg <= MAX_BUF_SIZE_LG; msg_size_lg++) { + const int msg_size = 1 << msg_size_lg; + int msg_cnt; + + MTestPrintfMsg(2, "testing messages of size %d\n", msg_size); + for (msg_cnt = 0; msg_cnt < NUM_MSGS_PER_BUF_SIZE; msg_cnt++) { + MPI_Status status; + const int tag = msg_size_lg * NUM_MSGS_PER_BUF_SIZE + msg_cnt; + + MTestPrintfMsg(2, "Message count %d\n", msg_cnt); + if (p_rank == 0) { + int p; + + for (p = 1; p < p_size; p++) { + /* Wait for synchronization message */ + mpi_errno = MPI_Recv(NULL, 0, MPI_BYTE, MPI_ANY_SOURCE, tag, comm, &status); + if (mpi_errno != MPI_SUCCESS && errs++ < 10) { + MTestPrintError(mpi_errno); + } + + if (status.MPI_TAG != tag && errs++ < 10) { + printf + ("ERROR: unexpected message tag from MPI_Recv(): lp=0, rp=%d, expected=%d, actual=%d, count=%d\n", + status.MPI_SOURCE, status.MPI_TAG, tag, msg_cnt); + } +# if defined(VERBOSE) + { + printf("sending message: p=%d s=%d c=%d\n", + status.MPI_SOURCE, msg_size, msg_cnt); + } +# endif - MTestPrintfMsg(2, "Message count %d\n", msg_cnt); - if (p_rank == 0) { - int p; + /* Send unexpected message which hopefully MPI_Probe() is + * already waiting for at the remote process */ + mpi_errno = MPI_Send(buf, msg_size, MPI_BYTE, + status.MPI_SOURCE, status.MPI_TAG, comm); + if (mpi_errno != MPI_SUCCESS && errs++ < 10) { + MTestPrintError(mpi_errno); + } + } + } else { + int incoming_msg_size; - for (p = 1; p < p_size; p++) { - /* Wait for synchronization message */ - mpi_errno = MPI_Recv(NULL, 0, MPI_BYTE, MPI_ANY_SOURCE, - tag, MPI_COMM_WORLD, &status); + /* Send synchronization message */ + mpi_errno = MPI_Send(NULL, 0, MPI_BYTE, 0, tag, comm); if (mpi_errno != MPI_SUCCESS && errs++ < 10) { MTestPrintError(mpi_errno); } + /* Perform probe, hopefully before the main process can + * send its reply */ + mpi_errno = MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, comm, &status); + if (mpi_errno != MPI_SUCCESS && errs++ < 10) { + MTestPrintError(mpi_errno); + } + mpi_errno = MPI_Get_count(&status, MPI_BYTE, &incoming_msg_size); + if (mpi_errno != MPI_SUCCESS && errs++ < 10) { + MTestPrintError(mpi_errno); + } + if (status.MPI_SOURCE != 0 && errs++ < 10) { + printf + ("ERROR: unexpected message source from MPI_Probe(): p=%d, expected=0, actual=%d, count=%d\n", + p_rank, status.MPI_SOURCE, msg_cnt); + } if (status.MPI_TAG != tag && errs++ < 10) { printf - ("ERROR: unexpected message tag from MPI_Recv(): lp=0, rp=%d, expected=%d, actual=%d, count=%d\n", - status.MPI_SOURCE, status.MPI_TAG, tag, msg_cnt); + ("ERROR: unexpected message tag from MPI_Probe(): p=%d, expected=%d, actual=%d, count=%d\n", + p_rank, tag, status.MPI_TAG, msg_cnt); } -# if defined(VERBOSE) - { - printf("sending message: p=%d s=%d c=%d\n", - status.MPI_SOURCE, msg_size, msg_cnt); + if (incoming_msg_size != msg_size && errs++ < 10) { + printf + ("ERROR: unexpected message size from MPI_Probe(): p=%d, expected=%d, actual=%d, count=%d\n", + p_rank, msg_size, incoming_msg_size, msg_cnt); } -# endif - /* Send unexpected message which hopefully MPI_Probe() is - * already waiting for at the remote process */ - mpi_errno = MPI_Send(buf, msg_size, MPI_BYTE, - status.MPI_SOURCE, status.MPI_TAG, MPI_COMM_WORLD); + /* Receive the probed message from the main process */ + mpi_errno = MPI_Recv(buf, msg_size, MPI_BYTE, 0, tag, comm, &status); if (mpi_errno != MPI_SUCCESS && errs++ < 10) { MTestPrintError(mpi_errno); } - } - } else { - int incoming_msg_size; - - /* Send synchronization message */ - mpi_errno = MPI_Send(NULL, 0, MPI_BYTE, 0, tag, MPI_COMM_WORLD); - if (mpi_errno != MPI_SUCCESS && errs++ < 10) { - MTestPrintError(mpi_errno); - } - - /* Perform probe, hopefully before the main process can - * send its reply */ - mpi_errno = MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); - if (mpi_errno != MPI_SUCCESS && errs++ < 10) { - MTestPrintError(mpi_errno); - } - mpi_errno = MPI_Get_count(&status, MPI_BYTE, &incoming_msg_size); - if (mpi_errno != MPI_SUCCESS && errs++ < 10) { - MTestPrintError(mpi_errno); - } - if (status.MPI_SOURCE != 0 && errs++ < 10) { - printf - ("ERROR: unexpected message source from MPI_Probe(): p=%d, expected=0, actual=%d, count=%d\n", - p_rank, status.MPI_SOURCE, msg_cnt); - } - if (status.MPI_TAG != tag && errs++ < 10) { - printf - ("ERROR: unexpected message tag from MPI_Probe(): p=%d, expected=%d, actual=%d, count=%d\n", - p_rank, tag, status.MPI_TAG, msg_cnt); - } - if (incoming_msg_size != msg_size && errs++ < 10) { - printf - ("ERROR: unexpected message size from MPI_Probe(): p=%d, expected=%d, actual=%d, count=%d\n", - p_rank, msg_size, incoming_msg_size, msg_cnt); - } - - /* Receive the probed message from the main process */ - mpi_errno = MPI_Recv(buf, msg_size, MPI_BYTE, 0, tag, MPI_COMM_WORLD, &status); - if (mpi_errno != MPI_SUCCESS && errs++ < 10) { - MTestPrintError(mpi_errno); - } - mpi_errno = MPI_Get_count(&status, MPI_BYTE, &incoming_msg_size); - if (mpi_errno != MPI_SUCCESS && errs++ < 10) { - MTestPrintError(mpi_errno); - } - if (status.MPI_SOURCE != 0 && errs++ < 10) { - printf - ("ERROR: unexpected message source from MPI_Recv(): p=%d, expected=0, actual=%d, count=%d\n", - p_rank, status.MPI_SOURCE, msg_cnt); - } - if (status.MPI_TAG != tag && errs++ < 10) { - printf - ("ERROR: unexpected message tag from MPI_Recv(): p=%d, expected=%d, actual=%d, count=%d\n", - p_rank, tag, status.MPI_TAG, msg_cnt); - } - if (incoming_msg_size != msg_size && errs++ < 10) { - printf - ("ERROR: unexpected message size from MPI_Recv(): p=%d, expected=%d, actual=%d, count=%d\n", - p_rank, msg_size, incoming_msg_size, msg_cnt); + mpi_errno = MPI_Get_count(&status, MPI_BYTE, &incoming_msg_size); + if (mpi_errno != MPI_SUCCESS && errs++ < 10) { + MTestPrintError(mpi_errno); + } + if (status.MPI_SOURCE != 0 && errs++ < 10) { + printf + ("ERROR: unexpected message source from MPI_Recv(): p=%d, expected=0, actual=%d, count=%d\n", + p_rank, status.MPI_SOURCE, msg_cnt); + } + if (status.MPI_TAG != tag && errs++ < 10) { + printf + ("ERROR: unexpected message tag from MPI_Recv(): p=%d, expected=%d, actual=%d, count=%d\n", + p_rank, tag, status.MPI_TAG, msg_cnt); + } + if (incoming_msg_size != msg_size && errs++ < 10) { + printf + ("ERROR: unexpected message size from MPI_Recv(): p=%d, expected=%d, actual=%d, count=%d\n", + p_rank, msg_size, incoming_msg_size, msg_cnt); + } } } } + MTestFreeComm(&comm); } MTest_Finalize(errs); From e9140b87a34427ec46f6b0c353cdb3d1620fdd14 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 24 Sep 2021 10:29:56 -0500 Subject: [PATCH 017/607] ch4/ofi: remove done_fn in MPIDI_OFI_huge_recv_t Since we always call MPIDI_OFI_recv_event at completion of huge message, we do not need the indirect function pointer. Remove for cleaner code. --- src/mpid/ch4/netmod/ofi/ofi_events.c | 6 ++---- src/mpid/ch4/netmod/ofi/ofi_types.h | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_events.c b/src/mpid/ch4/netmod/ofi/ofi_events.c index 366893a7abf..da0737ea742 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_events.c +++ b/src/mpid/ch4/netmod/ofi/ofi_events.c @@ -78,7 +78,6 @@ static int peek_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * rre recv_elem->remote_info.tag = huge_list_ptr->tag = MPIDI_OFI_TAG_MASK & wc->tag; recv_elem->localreq = huge_list_ptr->rreq = rreq; recv_elem->event_id = MPIDI_OFI_EVENT_GET_HUGE; - recv_elem->done_fn = MPIDI_OFI_recv_event; recv_elem->wc = *wc; if (MPIDI_OFI_COMM(comm_ptr).enable_striping) { recv_elem->cur_offset = MPIDI_OFI_STRIPE_CHUNK_SIZE; @@ -220,7 +219,6 @@ static int recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request recv_elem->peek = false; recv_elem->comm_ptr = comm_ptr; recv_elem->localreq = rreq; - recv_elem->done_fn = MPIDI_OFI_recv_event; recv_elem->wc = *wc; if (MPIDI_OFI_COMM(comm_ptr).enable_striping) { recv_elem->cur_offset = MPIDI_OFI_STRIPE_CHUNK_SIZE; @@ -358,11 +356,11 @@ int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reques } if (bytesToGet == 0ULL && recv_elem->chunks_outstanding == 0) { MPIDI_OFI_send_control_t ctrl; - /* recv_elem->localreq may be freed during done_fn. + /* recv_elem->localreq may be freed during MPIDI_OFI_recv_event. * Need to backup the handle here for later use with MPIDIU_map_erase. */ uint64_t key_to_erase = recv_elem->localreq->handle; recv_elem->wc.len = recv_elem->cur_offset; - recv_elem->done_fn(vni, &recv_elem->wc, recv_elem->localreq, recv_elem->event_id); + MPIDI_OFI_recv_event(vni, &recv_elem->wc, recv_elem->localreq, recv_elem->event_id); ctrl.type = MPIDI_OFI_CTRL_HUGEACK; mpi_errno = MPIDI_OFI_do_control_send(&ctrl, NULL, 0, recv_elem->remote_info.origin_rank, diff --git a/src/mpid/ch4/netmod/ofi/ofi_types.h b/src/mpid/ch4/netmod/ofi/ofi_types.h index a3a7448e6c1..a981f877999 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_types.h +++ b/src/mpid/ch4/netmod/ofi/ofi_types.h @@ -491,7 +491,6 @@ typedef struct MPIDI_OFI_huge_recv { char pad[MPIDI_REQUEST_HDR_SIZE]; struct fi_context context[MPIDI_OFI_CONTEXT_STRUCTS]; /* fixed field, do not move */ int event_id; /* fixed field, do not move */ - int (*done_fn) (int vni, struct fi_cq_tagged_entry * wc, MPIR_Request * req, int event_id); MPIDI_OFI_send_control_t remote_info; bool peek; /* Flag to indicate whether this struct has been created to track an uncompleted peek * operation. */ From cfc5054fcb275b93c98a2ae009c433c6905285c3 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 24 Sep 2021 11:32:18 -0500 Subject: [PATCH 018/607] ch4/ofi: refactor sending ctrl messages Make MPIDI_OFI_send_control_t internally a union to reflect the general control semantics. Replace MPIDI_OFI_do_control_send with MPIDI_NM_am_send_hdr. --- src/mpid/ch4/netmod/ofi/ofi_control.h | 35 -------------------------- src/mpid/ch4/netmod/ofi/ofi_events.c | 12 ++++++--- src/mpid/ch4/netmod/ofi/ofi_events.h | 1 - src/mpid/ch4/netmod/ofi/ofi_send.h | 36 ++++++++++++++++----------- src/mpid/ch4/netmod/ofi/ofi_types.h | 16 +++++++++--- src/mpid/ch4/netmod/ofi/util.c | 15 ++++------- 6 files changed, 47 insertions(+), 68 deletions(-) delete mode 100644 src/mpid/ch4/netmod/ofi/ofi_control.h diff --git a/src/mpid/ch4/netmod/ofi/ofi_control.h b/src/mpid/ch4/netmod/ofi/ofi_control.h deleted file mode 100644 index 60d8539dbde..00000000000 --- a/src/mpid/ch4/netmod/ofi/ofi_control.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) by Argonne National Laboratory - * See COPYRIGHT in top-level directory - */ - -#ifndef OFI_CONTROL_H_INCLUDED -#define OFI_CONTROL_H_INCLUDED - -#include "ofi_am_impl.h" - -MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_do_control_send(MPIDI_OFI_send_control_t * control, - char *send_buf, - size_t msgsize, - int rank, MPIR_Comm * comm_ptr, - MPIR_Request * ackreq) -{ - int mpi_errno = MPI_SUCCESS; - MPIR_FUNC_ENTER; - - control->origin_rank = comm_ptr->rank; - control->send_buf = (uintptr_t) send_buf; - control->msgsize = msgsize; - control->comm_id = comm_ptr->context_id; - control->ackreq = ackreq; - - mpi_errno = MPIDI_OFI_do_inject(rank, comm_ptr, - MPIDI_OFI_INTERNAL_HANDLER_CONTROL, - (void *) control, sizeof(*control), 0, 0); - - MPIR_FUNC_EXIT; - return mpi_errno; -} - - -#endif /* OFI_CONTROL_H_INCLUDED */ diff --git a/src/mpid/ch4/netmod/ofi/ofi_events.c b/src/mpid/ch4/netmod/ofi/ofi_events.c index da0737ea742..74a978bc498 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_events.c +++ b/src/mpid/ch4/netmod/ofi/ofi_events.c @@ -309,7 +309,7 @@ static uintptr_t recv_rbase(MPIDI_OFI_huge_recv_t * recv_elem) if (!MPIDI_OFI_ENABLE_MR_VIRT_ADDRESS) { return 0; } else { - return recv_elem->remote_info.send_buf; + return (uintptr_t) recv_elem->remote_info.send_buf; } } @@ -362,9 +362,13 @@ int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reques recv_elem->wc.len = recv_elem->cur_offset; MPIDI_OFI_recv_event(vni, &recv_elem->wc, recv_elem->localreq, recv_elem->event_id); ctrl.type = MPIDI_OFI_CTRL_HUGEACK; - mpi_errno = - MPIDI_OFI_do_control_send(&ctrl, NULL, 0, recv_elem->remote_info.origin_rank, - recv_elem->comm_ptr, recv_elem->remote_info.ackreq); + ctrl.u.huge_ack.ackreq = recv_elem->remote_info.ackreq; + /* note: it's receiver ack sender */ + int vni_remote = recv_elem->remote_info.vni_src; + int vni_local = recv_elem->remote_info.vni_dst; + mpi_errno = MPIDI_NM_am_send_hdr(recv_elem->remote_info.origin_rank, recv_elem->comm_ptr, + MPIDI_OFI_INTERNAL_HANDLER_CONTROL, + &ctrl, sizeof(ctrl), vni_local, vni_remote); MPIR_ERR_CHECK(mpi_errno); MPIDIU_map_erase(MPIDI_OFI_global.huge_recv_counters, key_to_erase); diff --git a/src/mpid/ch4/netmod/ofi/ofi_events.h b/src/mpid/ch4/netmod/ofi/ofi_events.h index 79f31916591..ec6dc1f27c5 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_events.h +++ b/src/mpid/ch4/netmod/ofi/ofi_events.h @@ -9,7 +9,6 @@ #include "ofi_impl.h" #include "ofi_am_impl.h" #include "ofi_am_events.h" -#include "ofi_control.h" #include "utlist.h" int MPIDI_OFI_rma_done_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * in_req); diff --git a/src/mpid/ch4/netmod/ofi/ofi_send.h b/src/mpid/ch4/netmod/ofi/ofi_send.h index 124cd8cbe3c..ea2412cef7a 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_send.h +++ b/src/mpid/ch4/netmod/ofi/ofi_send.h @@ -278,8 +278,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_send_normal(const void *buf, MPI_Aint cou tsenddata, FALSE /* eagain */); MPIR_T_PVAR_COUNTER_INC(MULTINIC, nic_sent_bytes_count[sender_nic], data_sz); } else if (unlikely(1)) { - MPIDI_OFI_send_control_t ctrl; - int i, num_nics = MPIDI_OFI_global.num_nics; + int num_nics = MPIDI_OFI_global.num_nics; uint64_t rma_keys[MPIDI_OFI_MAX_NICS]; struct fid_mr **huge_send_mrs; uint64_t msg_size = MPIDI_OFI_STRIPE_CHUNK_SIZE; @@ -295,18 +294,17 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_send_normal(const void *buf, MPI_Aint cou (struct fid_mr **) MPL_malloc((num_nics * sizeof(struct fid_mr *)), MPL_MEM_BUFFER); if (!MPIDI_OFI_ENABLE_MR_PROV_KEY) { /* Set up a memory region for the lmt data transfer */ - for (i = 0; i < num_nics; i++) { - ctrl.rma_keys[i] = + for (int i = 0; i < num_nics; i++) { + rma_keys[i] = MPIDI_OFI_mr_key_alloc(MPIDI_OFI_LOCAL_MR_KEY, MPIDI_OFI_INVALID_MR_KEY); - rma_keys[i] = ctrl.rma_keys[i]; } } else { /* zero them to avoid warnings */ - for (i = 0; i < num_nics; i++) { + for (int i = 0; i < num_nics; i++) { rma_keys[i] = 0; } } - for (i = 0; i < num_nics; i++) { + for (int i = 0; i < num_nics; i++) { MPIDI_OFI_CALL(fi_mr_reg(MPIDI_OFI_global.ctx[MPIDI_OFI_get_ctx_index(comm, vni_local, i)].domain, /* In: Domain Object */ send_buf, /* In: Lower memory address */ data_sz, /* In: Length */ @@ -322,8 +320,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_send_normal(const void *buf, MPI_Aint cou MPL_MEM_BUFFER); if (MPIDI_OFI_ENABLE_MR_PROV_KEY) { /* MR_BASIC */ - for (i = 0; i < num_nics; i++) { - ctrl.rma_keys[i] = fi_mr_key(huge_send_mrs[i]); + for (int i = 0; i < num_nics; i++) { + rma_keys[i] = fi_mr_key(huge_send_mrs[i]); } } @@ -346,14 +344,24 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_send_normal(const void *buf, MPI_Aint cou vni_local, tsenddata, FALSE /* eagain */); MPIR_T_PVAR_COUNTER_INC(MULTINIC, nic_sent_bytes_count[sender_nic], msg_size); MPIR_T_PVAR_COUNTER_INC(MULTINIC, striped_nic_sent_bytes_count[sender_nic], msg_size); + + MPIDI_OFI_send_control_t ctrl; ctrl.type = MPIDI_OFI_CTRL_HUGE; - ctrl.seqno = 0; - ctrl.tag = tag; - ctrl.vni_src = vni_src; - ctrl.vni_dst = vni_dst; + for (int i = 0; i < num_nics; i++) { + ctrl.u.huge.rma_keys[i] = rma_keys[i]; + } + ctrl.u.huge.tag = tag; + ctrl.u.huge.vni_src = vni_src; + ctrl.u.huge.vni_dst = vni_dst; + ctrl.u.huge.origin_rank = comm->rank; + ctrl.u.huge.send_buf = send_buf; + ctrl.u.huge.msgsize = data_sz; + ctrl.u.huge.comm_id = comm->context_id; + ctrl.u.huge.ackreq = sreq; /* Send information about the memory region here to get the lmt going. */ - mpi_errno = MPIDI_OFI_do_control_send(&ctrl, send_buf, data_sz, dst_rank, comm, sreq); + mpi_errno = MPIDI_NM_am_send_hdr(dst_rank, comm, MPIDI_OFI_INTERNAL_HANDLER_CONTROL, + &ctrl, sizeof(ctrl), vni_src, vni_dst); MPIR_ERR_CHECK(mpi_errno); } diff --git a/src/mpid/ch4/netmod/ofi/ofi_types.h b/src/mpid/ch4/netmod/ofi/ofi_types.h index a981f877999..946040d0098 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_types.h +++ b/src/mpid/ch4/netmod/ofi/ofi_types.h @@ -384,17 +384,25 @@ typedef struct { } MPIDI_OFI_global_t; typedef struct { - int16_t type; - int16_t seqno; int origin_rank; MPIR_Request *ackreq; - uintptr_t send_buf; + void *send_buf; size_t msgsize; int comm_id; uint64_t rma_keys[MPIDI_OFI_MAX_NICS]; int tag; int vni_src; int vni_dst; +} MPIDI_OFI_huge_remote_info_t; + +typedef struct { + int16_t type; + union { + MPIDI_OFI_huge_remote_info_t huge; + struct { + MPIR_Request *ackreq; + } huge_ack; + } u; } MPIDI_OFI_send_control_t; typedef struct MPIDI_OFI_win_acc_hint { @@ -491,7 +499,7 @@ typedef struct MPIDI_OFI_huge_recv { char pad[MPIDI_REQUEST_HDR_SIZE]; struct fi_context context[MPIDI_OFI_CONTEXT_STRUCTS]; /* fixed field, do not move */ int event_id; /* fixed field, do not move */ - MPIDI_OFI_send_control_t remote_info; + MPIDI_OFI_huge_remote_info_t remote_info; bool peek; /* Flag to indicate whether this struct has been created to track an uncompleted peek * operation. */ size_t cur_offset; diff --git a/src/mpid/ch4/netmod/ofi/util.c b/src/mpid/ch4/netmod/ofi/util.c index 955e88e7860..3521b455060 100644 --- a/src/mpid/ch4/netmod/ofi/util.c +++ b/src/mpid/ch4/netmod/ofi/util.c @@ -152,7 +152,7 @@ void MPIDI_OFI_mr_key_allocator_destroy(void) /* Translate the control message to get a huge message into a request to * actually perform the data transfer. */ -static int MPIDI_OFI_get_huge(int vni, MPIDI_OFI_send_control_t * info) +static int MPIDI_OFI_get_huge(int vni, MPIDI_OFI_huge_remote_info_t * info) { MPIDI_OFI_huge_recv_t *recv_elem = NULL; int mpi_errno = MPI_SUCCESS; @@ -242,17 +242,12 @@ int MPIDI_OFI_control_handler(void *am_hdr, void *data, MPI_Aint data_sz, } switch (ctrlsend->type) { - case MPIDI_OFI_CTRL_HUGEACK:{ - /* FIXME: need vni from the callback parameters */ - mpi_errno = MPIDI_OFI_dispatch_function(0, NULL, ctrlsend->ackreq); - goto fn_exit; - } + case MPIDI_OFI_CTRL_HUGEACK: + mpi_errno = MPIDI_OFI_dispatch_function(0, NULL, ctrlsend->u.huge_ack.ackreq); break; - case MPIDI_OFI_CTRL_HUGE:{ - mpi_errno = MPIDI_OFI_get_huge(0, ctrlsend); - goto fn_exit; - } + case MPIDI_OFI_CTRL_HUGE: + mpi_errno = MPIDI_OFI_get_huge(0, &(ctrlsend->u.huge)); break; default: From 43cffb4efbb9480294a07a0cf2789772e903299c Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 24 Sep 2021 12:12:22 -0500 Subject: [PATCH 019/607] ch4/ofi: refactor huge functions to separate file It is not critical to inline functions related to huge messages as they are bandwidth dominated. Move them into ofi_huge.c for better context. --- src/mpid/ch4/netmod/ofi/Makefile.mk | 1 + src/mpid/ch4/netmod/ofi/ofi_events.c | 301 +-------------------- src/mpid/ch4/netmod/ofi/ofi_events.h | 1 - src/mpid/ch4/netmod/ofi/ofi_huge.c | 388 +++++++++++++++++++++++++++ src/mpid/ch4/netmod/ofi/ofi_impl.h | 4 + src/mpid/ch4/netmod/ofi/util.c | 86 +----- 6 files changed, 405 insertions(+), 376 deletions(-) create mode 100644 src/mpid/ch4/netmod/ofi/ofi_huge.c diff --git a/src/mpid/ch4/netmod/ofi/Makefile.mk b/src/mpid/ch4/netmod/ofi/Makefile.mk index 490aa18e0f4..6b107f60921 100644 --- a/src/mpid/ch4/netmod/ofi/Makefile.mk +++ b/src/mpid/ch4/netmod/ofi/Makefile.mk @@ -16,6 +16,7 @@ mpi_core_sources += src/mpid/ch4/netmod/ofi/func_table.c \ src/mpid/ch4/netmod/ofi/ofi_win.c \ src/mpid/ch4/netmod/ofi/ofi_part.c \ src/mpid/ch4/netmod/ofi/ofi_events.c \ + src/mpid/ch4/netmod/ofi/ofi_huge.c \ src/mpid/ch4/netmod/ofi/ofi_progress.c \ src/mpid/ch4/netmod/ofi/ofi_am_events.c \ src/mpid/ch4/netmod/ofi/ofi_nic.c \ diff --git a/src/mpid/ch4/netmod/ofi/ofi_events.c b/src/mpid/ch4/netmod/ofi/ofi_events.c index 74a978bc498..17d48bed5e6 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_events.c +++ b/src/mpid/ch4/netmod/ofi/ofi_events.c @@ -14,10 +14,8 @@ static int peek_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * rreq); static int peek_empty_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * rreq); -static int recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * rreq); static int send_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * sreq); static int ssend_ack_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * sreq); -static uintptr_t recv_rbase(MPIDI_OFI_huge_recv_t * recv); static int chunk_done_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * req); static int inject_emu_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * req); static int accept_probe_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * rreq); @@ -32,76 +30,25 @@ static int am_read_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * static int peek_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * rreq) { int mpi_errno = MPI_SUCCESS; - size_t count = 0; MPIR_FUNC_ENTER; - rreq->status.MPI_SOURCE = MPIDI_OFI_cqe_get_source(wc, false); - rreq->status.MPI_TAG = MPIDI_OFI_init_get_tag(wc->tag); - rreq->status.MPI_ERROR = MPI_SUCCESS; if (MPIDI_OFI_HUGE_SEND & wc->tag) { - MPIDI_OFI_huge_recv_t *list_ptr; - bool found_msg = false; - - /* If this is a huge message, find the control message on the unexpected list that matches - * with this and return the size in that. */ - LL_FOREACH(MPIDI_unexp_huge_recv_head, list_ptr) { - uint64_t context_id = MPIDI_OFI_CONTEXT_MASK & wc->tag; - uint64_t tag = MPIDI_OFI_TAG_MASK & wc->tag; - if (list_ptr->remote_info.comm_id == context_id && - list_ptr->remote_info.origin_rank == MPIDI_OFI_cqe_get_source(wc, false) && - list_ptr->remote_info.tag == tag) { - count = list_ptr->remote_info.msgsize; - found_msg = true; - } - } - if (!found_msg) { - MPIDI_OFI_huge_recv_t *recv_elem; - MPIDI_OFI_huge_recv_list_t *huge_list_ptr; - - /* Create an element in the posted list that only indicates a peek and will be - * deleted as soon as it's fulfilled without being matched. */ - recv_elem = (MPIDI_OFI_huge_recv_t *) MPL_calloc(sizeof(*recv_elem), 1, MPL_MEM_COMM); - MPIR_ERR_CHKANDJUMP(recv_elem == NULL, mpi_errno, MPI_ERR_OTHER, "**nomem"); - recv_elem->peek = true; - MPIR_Comm *comm_ptr = rreq->comm; - recv_elem->comm_ptr = comm_ptr; - MPIDIU_map_set(MPIDI_OFI_global.huge_recv_counters, rreq->handle, recv_elem, - MPL_MEM_BUFFER); - - huge_list_ptr = - (MPIDI_OFI_huge_recv_list_t *) MPL_calloc(sizeof(*huge_list_ptr), 1, MPL_MEM_COMM); - MPIR_ERR_CHKANDJUMP(huge_list_ptr == NULL, mpi_errno, MPI_ERR_OTHER, "**nomem"); - recv_elem->remote_info.comm_id = huge_list_ptr->comm_id = - MPIDI_OFI_CONTEXT_MASK & wc->tag; - recv_elem->remote_info.origin_rank = huge_list_ptr->rank = - MPIDI_OFI_cqe_get_source(wc, false); - recv_elem->remote_info.tag = huge_list_ptr->tag = MPIDI_OFI_TAG_MASK & wc->tag; - recv_elem->localreq = huge_list_ptr->rreq = rreq; - recv_elem->event_id = MPIDI_OFI_EVENT_GET_HUGE; - recv_elem->wc = *wc; - if (MPIDI_OFI_COMM(comm_ptr).enable_striping) { - recv_elem->cur_offset = MPIDI_OFI_STRIPE_CHUNK_SIZE; - } else { - recv_elem->cur_offset = MPIDI_OFI_global.max_msg_size; - } - - LL_APPEND(MPIDI_posted_huge_recv_head, MPIDI_posted_huge_recv_tail, huge_list_ptr); - goto fn_exit; - } - } else { - /* Otherwise just get the size of the message we've already received. */ - count = wc->len; + mpi_errno = MPIDI_OFI_peek_huge_event(vni, wc, rreq); + goto fn_exit; } - MPIR_STATUS_SET_COUNT(rreq->status, count); + + rreq->status.MPI_SOURCE = MPIDI_OFI_cqe_get_source(wc, false); + rreq->status.MPI_TAG = MPIDI_OFI_init_get_tag(wc->tag); + rreq->status.MPI_ERROR = MPI_SUCCESS; + MPIR_STATUS_SET_COUNT(rreq->status, wc->len); /* util_id should be the last thing to change in rreq. Reason is * we use util_id to indicate peek_event has completed and all the * relevant values have been copied to rreq. */ MPL_atomic_release_store_int(&(MPIDI_OFI_REQUEST(rreq, util_id)), MPIDI_OFI_PEEK_FOUND); + fn_exit: MPIR_FUNC_EXIT; return mpi_errno; - fn_fail: - goto fn_exit; } static int peek_empty_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * rreq) @@ -133,109 +80,6 @@ static int peek_empty_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request return MPI_SUCCESS; } -/* If we posted a huge receive, this event gets called to translate the - * completion queue entry into a get huge event */ -static int recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * rreq) -{ - int mpi_errno = MPI_SUCCESS; - MPIDI_OFI_huge_recv_t *recv_elem = NULL; - MPIR_Comm *comm_ptr; - MPIR_FUNC_ENTER; - - bool ready_to_get = false; - /* Check that the sender didn't underflow the message by sending less than - * the huge message threshold. When striping is enabled underflow occurs if - * the sender sends < MPIDI_OFI_STRIPE_CHUNK_SIZE through the huge message protocol - * or < MPIDI_OFI_global.stripe_threshold through normal send */ - if (((wc->len < MPIDI_OFI_STRIPE_CHUNK_SIZE || - (wc->len > MPIDI_OFI_STRIPE_CHUNK_SIZE && wc->len < MPIDI_OFI_global.stripe_threshold)) && - MPIDI_OFI_COMM(rreq->comm).enable_striping) || - (wc->len < MPIDI_OFI_global.max_msg_size && !MPIDI_OFI_COMM(rreq->comm).enable_striping)) { - return MPIDI_OFI_recv_event(vni, wc, rreq, MPIDI_OFI_REQUEST(rreq, event_id)); - } - - comm_ptr = rreq->comm; - MPIR_T_PVAR_COUNTER_INC(MULTINIC, nic_recvd_bytes_count[MPIDI_OFI_REQUEST(rreq, nic_num)], - wc->len); - /* Check to see if the tracker is already in the unexpected list. - * Otherwise, allocate one. */ - { - MPIDI_OFI_huge_recv_t *list_ptr; - - MPL_DBG_MSG_FMT(MPIR_DBG_PT2PT, VERBOSE, - (MPL_DBG_FDEST, "SEARCHING HUGE UNEXPECTED LIST: (%d, %d, %llu)", - comm_ptr->context_id, MPIDI_OFI_cqe_get_source(wc, false), - (MPIDI_OFI_TAG_MASK & wc->tag))); - - LL_FOREACH(MPIDI_unexp_huge_recv_head, list_ptr) { - if (list_ptr->remote_info.comm_id == comm_ptr->context_id && - list_ptr->remote_info.origin_rank == MPIDI_OFI_cqe_get_source(wc, false) && - list_ptr->remote_info.tag == (MPIDI_OFI_TAG_MASK & wc->tag)) { - MPL_DBG_MSG_FMT(MPIR_DBG_PT2PT, VERBOSE, - (MPL_DBG_FDEST, "MATCHED HUGE UNEXPECTED LIST: (%d, %d, %llu, %d)", - comm_ptr->context_id, MPIDI_OFI_cqe_get_source(wc, false), - (MPIDI_OFI_TAG_MASK & wc->tag), rreq->handle)); - - LL_DELETE(MPIDI_unexp_huge_recv_head, MPIDI_unexp_huge_recv_tail, list_ptr); - - recv_elem = list_ptr; - MPIDIU_map_set(MPIDI_OFI_global.huge_recv_counters, rreq->handle, recv_elem, - MPL_MEM_COMM); - break; - } - } - } - - if (recv_elem) { - ready_to_get = true; - } else { - MPIDI_OFI_huge_recv_list_t *list_ptr; - - MPL_DBG_MSG_FMT(MPIR_DBG_PT2PT, VERBOSE, - (MPL_DBG_FDEST, "CREATING HUGE POSTED ENTRY: (%d, %d, %llu)", - comm_ptr->context_id, MPIDI_OFI_cqe_get_source(wc, false), - (MPIDI_OFI_TAG_MASK & wc->tag))); - - recv_elem = (MPIDI_OFI_huge_recv_t *) MPL_calloc(sizeof(*recv_elem), 1, MPL_MEM_BUFFER); - MPIR_ERR_CHKANDJUMP(recv_elem == NULL, mpi_errno, MPI_ERR_OTHER, "**nomem"); - MPIDIU_map_set(MPIDI_OFI_global.huge_recv_counters, rreq->handle, recv_elem, - MPL_MEM_BUFFER); - - list_ptr = (MPIDI_OFI_huge_recv_list_t *) MPL_calloc(sizeof(*list_ptr), 1, MPL_MEM_BUFFER); - if (!list_ptr) - MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nomem"); - - list_ptr->comm_id = comm_ptr->context_id; - list_ptr->rank = MPIDI_OFI_cqe_get_source(wc, false); - list_ptr->tag = (MPIDI_OFI_TAG_MASK & wc->tag); - list_ptr->rreq = rreq; - - LL_APPEND(MPIDI_posted_huge_recv_head, MPIDI_posted_huge_recv_tail, list_ptr); - } - - /* Plug the information for the huge event into the receive request and go - * to the MPIDI_OFI_get_huge_event function. */ - recv_elem->event_id = MPIDI_OFI_EVENT_GET_HUGE; - recv_elem->peek = false; - recv_elem->comm_ptr = comm_ptr; - recv_elem->localreq = rreq; - recv_elem->wc = *wc; - if (MPIDI_OFI_COMM(comm_ptr).enable_striping) { - recv_elem->cur_offset = MPIDI_OFI_STRIPE_CHUNK_SIZE; - } else { - recv_elem->cur_offset = MPIDI_OFI_global.max_msg_size; - } - if (ready_to_get) { - MPIDI_OFI_get_huge_event(vni, NULL, (MPIR_Request *) recv_elem); - } - - fn_exit: - MPIR_FUNC_EXIT; - return mpi_errno; - fn_fail: - goto fn_exit; -} - static int send_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * sreq) { int mpi_errno = MPI_SUCCESS; @@ -304,133 +148,6 @@ static int ssend_ack_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request return mpi_errno; } -static uintptr_t recv_rbase(MPIDI_OFI_huge_recv_t * recv_elem) -{ - if (!MPIDI_OFI_ENABLE_MR_VIRT_ADDRESS) { - return 0; - } else { - return (uintptr_t) recv_elem->remote_info.send_buf; - } -} - -/* Note: MPIDI_OFI_get_huge_event is invoked from three places -- - * 1. In recv_huge_event, when recv buffer is matched and first chunk received, and - * when control message (with remote info) has also been received. - * 2. In MPIDI_OFI_get_huge, as a callback when control message is received, and - * when first chunk has been matched and received. - * - * recv_huge_event will fill the local request information, and the control message - * callback will fill the remote (sender) information. Lastly -- - * - * 3. As the event function when RDMA read (issued here) completes. - */ -int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * req) -{ - int mpi_errno = MPI_SUCCESS; - MPIDI_OFI_huge_recv_t *recv_elem = (MPIDI_OFI_huge_recv_t *) req; - uint64_t remote_key; - size_t bytesLeft, bytesToGet; - MPIR_FUNC_ENTER; - - void *recv_buf = MPIDI_OFI_REQUEST(recv_elem->localreq, util.iov.iov_base); - - if (MPIDI_OFI_COMM(recv_elem->comm_ptr).enable_striping) { - /* Subtract one stripe_chunk_size because we send the first chunk via a regular message - * instead of the memory region */ - recv_elem->stripe_size = (recv_elem->remote_info.msgsize - MPIDI_OFI_STRIPE_CHUNK_SIZE) - / MPIDI_OFI_global.num_nics; /* striping */ - - if (recv_elem->stripe_size > MPIDI_OFI_global.max_msg_size) { - recv_elem->stripe_size = MPIDI_OFI_global.max_msg_size; - } - if (recv_elem->chunks_outstanding) - recv_elem->chunks_outstanding--; - bytesLeft = recv_elem->remote_info.msgsize - recv_elem->cur_offset; - bytesToGet = (bytesLeft <= recv_elem->stripe_size) ? bytesLeft : recv_elem->stripe_size; - } else { - /* Subtract one max_msg_size because we send the first chunk via a regular message - * instead of the memory region */ - bytesLeft = recv_elem->remote_info.msgsize - recv_elem->cur_offset; - bytesToGet = (bytesLeft <= MPIDI_OFI_global.max_msg_size) ? - bytesLeft : MPIDI_OFI_global.max_msg_size; - } - if (bytesToGet == 0ULL && recv_elem->chunks_outstanding == 0) { - MPIDI_OFI_send_control_t ctrl; - /* recv_elem->localreq may be freed during MPIDI_OFI_recv_event. - * Need to backup the handle here for later use with MPIDIU_map_erase. */ - uint64_t key_to_erase = recv_elem->localreq->handle; - recv_elem->wc.len = recv_elem->cur_offset; - MPIDI_OFI_recv_event(vni, &recv_elem->wc, recv_elem->localreq, recv_elem->event_id); - ctrl.type = MPIDI_OFI_CTRL_HUGEACK; - ctrl.u.huge_ack.ackreq = recv_elem->remote_info.ackreq; - /* note: it's receiver ack sender */ - int vni_remote = recv_elem->remote_info.vni_src; - int vni_local = recv_elem->remote_info.vni_dst; - mpi_errno = MPIDI_NM_am_send_hdr(recv_elem->remote_info.origin_rank, recv_elem->comm_ptr, - MPIDI_OFI_INTERNAL_HANDLER_CONTROL, - &ctrl, sizeof(ctrl), vni_local, vni_remote); - MPIR_ERR_CHECK(mpi_errno); - - MPIDIU_map_erase(MPIDI_OFI_global.huge_recv_counters, key_to_erase); - MPL_free(recv_elem); - - goto fn_exit; - } - - int nic = 0; - int vni_src = recv_elem->remote_info.vni_src; - int vni_dst = recv_elem->remote_info.vni_dst; - if (MPIDI_OFI_COMM(recv_elem->comm_ptr).enable_striping) { /* if striping enabled */ - MPIDI_OFI_cntr_incr(recv_elem->comm_ptr, vni_src, nic); - if (recv_elem->cur_offset >= MPIDI_OFI_STRIPE_CHUNK_SIZE && bytesLeft > 0) { - for (nic = 0; nic < MPIDI_OFI_global.num_nics; nic++) { - int ctx_idx = MPIDI_OFI_get_ctx_index(recv_elem->comm_ptr, vni_dst, nic); - remote_key = recv_elem->remote_info.rma_keys[nic]; - - bytesLeft = recv_elem->remote_info.msgsize - recv_elem->cur_offset; - if (bytesLeft <= 0) { - break; - } - bytesToGet = - (bytesLeft <= recv_elem->stripe_size) ? bytesLeft : recv_elem->stripe_size; - - MPIDI_OFI_CALL_RETRY(fi_read(MPIDI_OFI_global.ctx[ctx_idx].tx, (void *) ((char *) recv_buf + recv_elem->cur_offset), /* local buffer */ - bytesToGet, /* bytes */ - NULL, /* descriptor */ - MPIDI_OFI_comm_to_phys(recv_elem->comm_ptr, recv_elem->remote_info.origin_rank, nic, vni_dst, vni_src), recv_rbase(recv_elem) + recv_elem->cur_offset, /* remote maddr */ - remote_key, /* Key */ - (void *) &recv_elem->context), nic, /* Context */ - rdma_readfrom, FALSE); - MPIR_T_PVAR_COUNTER_INC(MULTINIC, nic_recvd_bytes_count[nic], bytesToGet); - MPIR_T_PVAR_COUNTER_INC(MULTINIC, striped_nic_recvd_bytes_count[nic], bytesToGet); - recv_elem->cur_offset += bytesToGet; - recv_elem->chunks_outstanding++; - } - } - } else { - int ctx_idx = MPIDI_OFI_get_ctx_index(recv_elem->comm_ptr, vni_src, nic); - remote_key = recv_elem->remote_info.rma_keys[nic]; - MPIDI_OFI_cntr_incr(recv_elem->comm_ptr, vni_src, nic); - MPIDI_OFI_CALL_RETRY(fi_read(MPIDI_OFI_global.ctx[ctx_idx].tx, /* endpoint */ - (void *) ((char *) recv_buf + recv_elem->cur_offset), /* local buffer */ - bytesToGet, /* bytes */ - NULL, /* descriptor */ - MPIDI_OFI_comm_to_phys(recv_elem->comm_ptr, recv_elem->remote_info.origin_rank, nic, vni_src, vni_dst), /* Destination */ - recv_rbase(recv_elem) + recv_elem->cur_offset, /* remote maddr */ - remote_key, /* Key */ - (void *) &recv_elem->context), vni_src, rdma_readfrom, /* Context */ - FALSE); - MPIR_T_PVAR_COUNTER_INC(MULTINIC, nic_recvd_bytes_count[nic], bytesToGet); - recv_elem->cur_offset += bytesToGet; - } - - fn_exit: - MPIR_FUNC_EXIT; - return mpi_errno; - fn_fail: - goto fn_exit; -} - static int chunk_done_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * req) { int c; @@ -771,7 +488,7 @@ int MPIDI_OFI_dispatch_function(int vni, struct fi_cq_tagged_entry *wc, MPIR_Req break; case MPIDI_OFI_EVENT_RECV_HUGE: - mpi_errno = recv_huge_event(vni, wc, req); + mpi_errno = MPIDI_OFI_recv_huge_event(vni, wc, req); break; case MPIDI_OFI_EVENT_RECV_PACK: diff --git a/src/mpid/ch4/netmod/ofi/ofi_events.h b/src/mpid/ch4/netmod/ofi/ofi_events.h index ec6dc1f27c5..b4b00230e37 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_events.h +++ b/src/mpid/ch4/netmod/ofi/ofi_events.h @@ -12,7 +12,6 @@ #include "utlist.h" int MPIDI_OFI_rma_done_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * in_req); -int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * req); int MPIDI_OFI_dispatch_function(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * req); MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_cqe_get_source(struct fi_cq_tagged_entry *wc, bool has_err) diff --git a/src/mpid/ch4/netmod/ofi/ofi_huge.c b/src/mpid/ch4/netmod/ofi/ofi_huge.c new file mode 100644 index 00000000000..a3fa2ea2713 --- /dev/null +++ b/src/mpid/ch4/netmod/ofi/ofi_huge.c @@ -0,0 +1,388 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include +#include "ofi_impl.h" +#include "ofi_events.h" + +/* this function called by recv event of a huge message */ +int MPIDI_OFI_recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * rreq) +{ + int mpi_errno = MPI_SUCCESS; + MPIDI_OFI_huge_recv_t *recv_elem = NULL; + MPIR_Comm *comm_ptr; + MPIR_FUNC_ENTER; + + bool ready_to_get = false; + /* Check that the sender didn't underflow the message by sending less than + * the huge message threshold. When striping is enabled underflow occurs if + * the sender sends < MPIDI_OFI_STRIPE_CHUNK_SIZE through the huge message protocol + * or < MPIDI_OFI_global.stripe_threshold through normal send */ + if (((wc->len < MPIDI_OFI_STRIPE_CHUNK_SIZE || + (wc->len > MPIDI_OFI_STRIPE_CHUNK_SIZE && wc->len < MPIDI_OFI_global.stripe_threshold)) && + MPIDI_OFI_COMM(rreq->comm).enable_striping) || + (wc->len < MPIDI_OFI_global.max_msg_size && !MPIDI_OFI_COMM(rreq->comm).enable_striping)) { + return MPIDI_OFI_recv_event(vni, wc, rreq, MPIDI_OFI_REQUEST(rreq, event_id)); + } + + comm_ptr = rreq->comm; + MPIR_T_PVAR_COUNTER_INC(MULTINIC, nic_recvd_bytes_count[MPIDI_OFI_REQUEST(rreq, nic_num)], + wc->len); + /* Check to see if the tracker is already in the unexpected list. + * Otherwise, allocate one. */ + { + MPIDI_OFI_huge_recv_t *list_ptr; + + MPL_DBG_MSG_FMT(MPIR_DBG_PT2PT, VERBOSE, + (MPL_DBG_FDEST, "SEARCHING HUGE UNEXPECTED LIST: (%d, %d, %llu)", + comm_ptr->context_id, MPIDI_OFI_cqe_get_source(wc, false), + (MPIDI_OFI_TAG_MASK & wc->tag))); + + LL_FOREACH(MPIDI_unexp_huge_recv_head, list_ptr) { + if (list_ptr->remote_info.comm_id == comm_ptr->context_id && + list_ptr->remote_info.origin_rank == MPIDI_OFI_cqe_get_source(wc, false) && + list_ptr->remote_info.tag == (MPIDI_OFI_TAG_MASK & wc->tag)) { + MPL_DBG_MSG_FMT(MPIR_DBG_PT2PT, VERBOSE, + (MPL_DBG_FDEST, "MATCHED HUGE UNEXPECTED LIST: (%d, %d, %llu, %d)", + comm_ptr->context_id, MPIDI_OFI_cqe_get_source(wc, false), + (MPIDI_OFI_TAG_MASK & wc->tag), rreq->handle)); + + LL_DELETE(MPIDI_unexp_huge_recv_head, MPIDI_unexp_huge_recv_tail, list_ptr); + + recv_elem = list_ptr; + MPIDIU_map_set(MPIDI_OFI_global.huge_recv_counters, rreq->handle, recv_elem, + MPL_MEM_COMM); + break; + } + } + } + + if (recv_elem) { + ready_to_get = true; + } else { + MPIDI_OFI_huge_recv_list_t *list_ptr; + + MPL_DBG_MSG_FMT(MPIR_DBG_PT2PT, VERBOSE, + (MPL_DBG_FDEST, "CREATING HUGE POSTED ENTRY: (%d, %d, %llu)", + comm_ptr->context_id, MPIDI_OFI_cqe_get_source(wc, false), + (MPIDI_OFI_TAG_MASK & wc->tag))); + + recv_elem = (MPIDI_OFI_huge_recv_t *) MPL_calloc(sizeof(*recv_elem), 1, MPL_MEM_BUFFER); + MPIR_ERR_CHKANDJUMP(recv_elem == NULL, mpi_errno, MPI_ERR_OTHER, "**nomem"); + MPIDIU_map_set(MPIDI_OFI_global.huge_recv_counters, rreq->handle, recv_elem, + MPL_MEM_BUFFER); + + list_ptr = (MPIDI_OFI_huge_recv_list_t *) MPL_calloc(sizeof(*list_ptr), 1, MPL_MEM_BUFFER); + if (!list_ptr) + MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nomem"); + + list_ptr->comm_id = comm_ptr->context_id; + list_ptr->rank = MPIDI_OFI_cqe_get_source(wc, false); + list_ptr->tag = (MPIDI_OFI_TAG_MASK & wc->tag); + list_ptr->rreq = rreq; + + LL_APPEND(MPIDI_posted_huge_recv_head, MPIDI_posted_huge_recv_tail, list_ptr); + } + + /* Plug the information for the huge event into the receive request and go + * to the MPIDI_OFI_get_huge_event function. */ + recv_elem->event_id = MPIDI_OFI_EVENT_GET_HUGE; + recv_elem->peek = false; + recv_elem->comm_ptr = comm_ptr; + recv_elem->localreq = rreq; + recv_elem->wc = *wc; + if (MPIDI_OFI_COMM(comm_ptr).enable_striping) { + recv_elem->cur_offset = MPIDI_OFI_STRIPE_CHUNK_SIZE; + } else { + recv_elem->cur_offset = MPIDI_OFI_global.max_msg_size; + } + if (ready_to_get) { + MPIDI_OFI_get_huge_event(vni, NULL, (MPIR_Request *) recv_elem); + } + + fn_exit: + MPIR_FUNC_EXIT; + return mpi_errno; + fn_fail: + goto fn_exit; +} + +/* This function is called when we receive a huge control message */ +int MPIDI_OFI_recv_huge_control(MPIDI_OFI_huge_remote_info_t * info) +{ + MPIDI_OFI_huge_recv_t *recv_elem = NULL; + int mpi_errno = MPI_SUCCESS; + MPIR_FUNC_ENTER; + + bool ready_to_get = false; + + /* If there has been a posted receive, search through the list of unmatched + * receives to find the one that goes with the incoming message. */ + { + MPIDI_OFI_huge_recv_list_t *list_ptr; + + MPL_DBG_MSG_FMT(MPIR_DBG_PT2PT, VERBOSE, + (MPL_DBG_FDEST, "SEARCHING POSTED LIST: (%d, %d, %d)", info->comm_id, + info->origin_rank, info->tag)); + + LL_FOREACH(MPIDI_posted_huge_recv_head, list_ptr) { + if (list_ptr->comm_id == info->comm_id && + list_ptr->rank == info->origin_rank && list_ptr->tag == info->tag) { + MPL_DBG_MSG_FMT(MPIR_DBG_PT2PT, VERBOSE, + (MPL_DBG_FDEST, "MATCHED POSTED LIST: (%d, %d, %d, %d)", + info->comm_id, info->origin_rank, info->tag, + list_ptr->rreq->handle)); + + LL_DELETE(MPIDI_posted_huge_recv_head, MPIDI_posted_huge_recv_tail, list_ptr); + + recv_elem = (MPIDI_OFI_huge_recv_t *) + MPIDIU_map_lookup(MPIDI_OFI_global.huge_recv_counters, list_ptr->rreq->handle); + + /* If this is a "peek" element for an MPI_Probe, it shouldn't be matched. Grab the + * important information and remove the element from the list. */ + if (recv_elem->peek) { + MPIR_STATUS_SET_COUNT(recv_elem->localreq->status, info->msgsize); + MPL_atomic_release_store_int(&(MPIDI_OFI_REQUEST(recv_elem->localreq, util_id)), + MPIDI_OFI_PEEK_FOUND); + MPIDIU_map_erase(MPIDI_OFI_global.huge_recv_counters, + recv_elem->localreq->handle); + MPL_free(recv_elem); + recv_elem = NULL; + } + + MPL_free(list_ptr); + break; + } + } + } + + if (recv_elem) { + ready_to_get = true; + } else { + /* Put the struct describing the transfer on an unexpected list to be retrieved later */ + MPL_DBG_MSG_FMT(MPIR_DBG_PT2PT, VERBOSE, + (MPL_DBG_FDEST, "CREATING UNEXPECTED HUGE RECV: (%d, %d, %d)", + info->comm_id, info->origin_rank, info->tag)); + + /* If this is unexpected, create a new tracker and put it in the unexpected list. */ + recv_elem = (MPIDI_OFI_huge_recv_t *) MPL_calloc(sizeof(*recv_elem), 1, MPL_MEM_COMM); + if (!recv_elem) + MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nomem"); + + LL_APPEND(MPIDI_unexp_huge_recv_head, MPIDI_unexp_huge_recv_tail, recv_elem); + } + + recv_elem->event_id = MPIDI_OFI_EVENT_GET_HUGE; + recv_elem->remote_info = *info; + recv_elem->next = NULL; + if (ready_to_get) { + MPIDI_OFI_get_huge_event(info->vni_dst, NULL, (MPIR_Request *) recv_elem); + } + + fn_exit: + MPIR_FUNC_EXIT; + return mpi_errno; + fn_fail: + goto fn_exit; +} + +int MPIDI_OFI_peek_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * rreq) +{ + int mpi_errno = MPI_SUCCESS; + MPIR_FUNC_ENTER; + + MPI_Aint count = 0; + MPIDI_OFI_huge_recv_t *list_ptr; + bool found_msg = false; + + /* If this is a huge message, find the control message on the unexpected list that matches + * with this and return the size in that. */ + LL_FOREACH(MPIDI_unexp_huge_recv_head, list_ptr) { + uint64_t context_id = MPIDI_OFI_CONTEXT_MASK & wc->tag; + uint64_t tag = MPIDI_OFI_TAG_MASK & wc->tag; + if (list_ptr->remote_info.comm_id == context_id && + list_ptr->remote_info.origin_rank == MPIDI_OFI_cqe_get_source(wc, false) && + list_ptr->remote_info.tag == tag) { + count = list_ptr->remote_info.msgsize; + found_msg = true; + } + } + if (!found_msg) { + /* FIXME: the count is wrong in this case. We need progress until the control message is received */ + MPIDI_OFI_huge_recv_t *recv_elem; + MPIDI_OFI_huge_recv_list_t *huge_list_ptr; + + /* Create an element in the posted list that only indicates a peek and will be + * deleted as soon as it's fulfilled without being matched. */ + recv_elem = (MPIDI_OFI_huge_recv_t *) MPL_calloc(sizeof(*recv_elem), 1, MPL_MEM_COMM); + MPIR_ERR_CHKANDJUMP(recv_elem == NULL, mpi_errno, MPI_ERR_OTHER, "**nomem"); + recv_elem->peek = true; + MPIR_Comm *comm_ptr = rreq->comm; + recv_elem->comm_ptr = comm_ptr; + MPIDIU_map_set(MPIDI_OFI_global.huge_recv_counters, rreq->handle, recv_elem, + MPL_MEM_BUFFER); + + huge_list_ptr = + (MPIDI_OFI_huge_recv_list_t *) MPL_calloc(sizeof(*huge_list_ptr), 1, MPL_MEM_COMM); + MPIR_ERR_CHKANDJUMP(huge_list_ptr == NULL, mpi_errno, MPI_ERR_OTHER, "**nomem"); + recv_elem->remote_info.comm_id = huge_list_ptr->comm_id = MPIDI_OFI_CONTEXT_MASK & wc->tag; + recv_elem->remote_info.origin_rank = huge_list_ptr->rank = + MPIDI_OFI_cqe_get_source(wc, false); + recv_elem->remote_info.tag = huge_list_ptr->tag = MPIDI_OFI_TAG_MASK & wc->tag; + recv_elem->localreq = huge_list_ptr->rreq = rreq; + recv_elem->event_id = MPIDI_OFI_EVENT_GET_HUGE; + recv_elem->wc = *wc; + if (MPIDI_OFI_COMM(comm_ptr).enable_striping) { + recv_elem->cur_offset = MPIDI_OFI_STRIPE_CHUNK_SIZE; + } else { + recv_elem->cur_offset = MPIDI_OFI_global.max_msg_size; + } + + LL_APPEND(MPIDI_posted_huge_recv_head, MPIDI_posted_huge_recv_tail, huge_list_ptr); + } + + rreq->status.MPI_SOURCE = MPIDI_OFI_cqe_get_source(wc, false); + rreq->status.MPI_TAG = MPIDI_OFI_init_get_tag(wc->tag); + rreq->status.MPI_ERROR = MPI_SUCCESS; + MPIR_STATUS_SET_COUNT(rreq->status, count); + /* util_id should be the last thing to change in rreq. Reason is + * we use util_id to indicate peek_event has completed and all the + * relevant values have been copied to rreq. */ + MPL_atomic_release_store_int(&(MPIDI_OFI_REQUEST(rreq, util_id)), MPIDI_OFI_PEEK_FOUND); + + fn_exit: + MPIR_FUNC_EXIT; + return mpi_errno; + fn_fail: + goto fn_exit; +} + +static uintptr_t recv_rbase(MPIDI_OFI_huge_recv_t * recv_elem) +{ + if (!MPIDI_OFI_ENABLE_MR_VIRT_ADDRESS) { + return 0; + } else { + return (uintptr_t) recv_elem->remote_info.send_buf; + } +} + +/* Note: MPIDI_OFI_get_huge_event is invoked from three places -- + * 1. In MPIDI_OFI_recv_huge_event, when recv buffer is matched and first chunk received, and + * when control message (with remote info) has also been received. + * 2. In MPIDI_OFI_recv_huge_control, as a callback when control message is received, and + * when first chunk has been matched and received. + * + * MPIDI_OFI_recv_huge_event will fill the local request information, and + * MPIDI_OFI_recv_huge_control will fill the remote (sender) information. Lastly -- + * + * 3. As the event function when RDMA read (issued here) completes. + */ +int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * req) +{ + int mpi_errno = MPI_SUCCESS; + MPIDI_OFI_huge_recv_t *recv_elem = (MPIDI_OFI_huge_recv_t *) req; + uint64_t remote_key; + size_t bytesLeft, bytesToGet; + MPIR_FUNC_ENTER; + + void *recv_buf = MPIDI_OFI_REQUEST(recv_elem->localreq, util.iov.iov_base); + + if (MPIDI_OFI_COMM(recv_elem->comm_ptr).enable_striping) { + /* Subtract one stripe_chunk_size because we send the first chunk via a regular message + * instead of the memory region */ + recv_elem->stripe_size = (recv_elem->remote_info.msgsize - MPIDI_OFI_STRIPE_CHUNK_SIZE) + / MPIDI_OFI_global.num_nics; /* striping */ + + if (recv_elem->stripe_size > MPIDI_OFI_global.max_msg_size) { + recv_elem->stripe_size = MPIDI_OFI_global.max_msg_size; + } + if (recv_elem->chunks_outstanding) + recv_elem->chunks_outstanding--; + bytesLeft = recv_elem->remote_info.msgsize - recv_elem->cur_offset; + bytesToGet = (bytesLeft <= recv_elem->stripe_size) ? bytesLeft : recv_elem->stripe_size; + } else { + /* Subtract one max_msg_size because we send the first chunk via a regular message + * instead of the memory region */ + bytesLeft = recv_elem->remote_info.msgsize - recv_elem->cur_offset; + bytesToGet = (bytesLeft <= MPIDI_OFI_global.max_msg_size) ? + bytesLeft : MPIDI_OFI_global.max_msg_size; + } + if (bytesToGet == 0ULL && recv_elem->chunks_outstanding == 0) { + MPIDI_OFI_send_control_t ctrl; + /* recv_elem->localreq may be freed during MPIDI_OFI_recv_event. + * Need to backup the handle here for later use with MPIDIU_map_erase. */ + uint64_t key_to_erase = recv_elem->localreq->handle; + recv_elem->wc.len = recv_elem->cur_offset; + MPIDI_OFI_recv_event(recv_elem->remote_info.vni_dst, &recv_elem->wc, recv_elem->localreq, + recv_elem->event_id); + ctrl.type = MPIDI_OFI_CTRL_HUGEACK; + ctrl.u.huge_ack.ackreq = recv_elem->remote_info.ackreq; + /* note: it's receiver ack sender */ + int vni_remote = recv_elem->remote_info.vni_src; + int vni_local = recv_elem->remote_info.vni_dst; + mpi_errno = MPIDI_NM_am_send_hdr(recv_elem->remote_info.origin_rank, recv_elem->comm_ptr, + MPIDI_OFI_INTERNAL_HANDLER_CONTROL, + &ctrl, sizeof(ctrl), vni_local, vni_remote); + MPIR_ERR_CHECK(mpi_errno); + + MPIDIU_map_erase(MPIDI_OFI_global.huge_recv_counters, key_to_erase); + MPL_free(recv_elem); + + goto fn_exit; + } + + int nic = 0; + int vni_src = recv_elem->remote_info.vni_src; + int vni_dst = recv_elem->remote_info.vni_dst; + if (MPIDI_OFI_COMM(recv_elem->comm_ptr).enable_striping) { /* if striping enabled */ + MPIDI_OFI_cntr_incr(recv_elem->comm_ptr, vni_src, nic); + if (recv_elem->cur_offset >= MPIDI_OFI_STRIPE_CHUNK_SIZE && bytesLeft > 0) { + for (nic = 0; nic < MPIDI_OFI_global.num_nics; nic++) { + int ctx_idx = MPIDI_OFI_get_ctx_index(recv_elem->comm_ptr, vni_dst, nic); + remote_key = recv_elem->remote_info.rma_keys[nic]; + + bytesLeft = recv_elem->remote_info.msgsize - recv_elem->cur_offset; + if (bytesLeft <= 0) { + break; + } + bytesToGet = + (bytesLeft <= recv_elem->stripe_size) ? bytesLeft : recv_elem->stripe_size; + + MPIDI_OFI_CALL_RETRY(fi_read(MPIDI_OFI_global.ctx[ctx_idx].tx, (void *) ((char *) recv_buf + recv_elem->cur_offset), /* local buffer */ + bytesToGet, /* bytes */ + NULL, /* descriptor */ + MPIDI_OFI_comm_to_phys(recv_elem->comm_ptr, recv_elem->remote_info.origin_rank, nic, vni_dst, vni_src), recv_rbase(recv_elem) + recv_elem->cur_offset, /* remote maddr */ + remote_key, /* Key */ + (void *) &recv_elem->context), nic, /* Context */ + rdma_readfrom, FALSE); + MPIR_T_PVAR_COUNTER_INC(MULTINIC, nic_recvd_bytes_count[nic], bytesToGet); + MPIR_T_PVAR_COUNTER_INC(MULTINIC, striped_nic_recvd_bytes_count[nic], bytesToGet); + recv_elem->cur_offset += bytesToGet; + recv_elem->chunks_outstanding++; + } + } + } else { + int ctx_idx = MPIDI_OFI_get_ctx_index(recv_elem->comm_ptr, vni_src, nic); + remote_key = recv_elem->remote_info.rma_keys[nic]; + MPIDI_OFI_cntr_incr(recv_elem->comm_ptr, vni_src, nic); + MPIDI_OFI_CALL_RETRY(fi_read(MPIDI_OFI_global.ctx[ctx_idx].tx, /* endpoint */ + (void *) ((char *) recv_buf + recv_elem->cur_offset), /* local buffer */ + bytesToGet, /* bytes */ + NULL, /* descriptor */ + MPIDI_OFI_comm_to_phys(recv_elem->comm_ptr, recv_elem->remote_info.origin_rank, nic, vni_src, vni_dst), /* Destination */ + recv_rbase(recv_elem) + recv_elem->cur_offset, /* remote maddr */ + remote_key, /* Key */ + (void *) &recv_elem->context), vni_src, rdma_readfrom, /* Context */ + FALSE); + MPIR_T_PVAR_COUNTER_INC(MULTINIC, nic_recvd_bytes_count[nic], bytesToGet); + recv_elem->cur_offset += bytesToGet; + } + + fn_exit: + MPIR_FUNC_EXIT; + return mpi_errno; + fn_fail: + goto fn_exit; +} diff --git a/src/mpid/ch4/netmod/ofi/ofi_impl.h b/src/mpid/ch4/netmod/ofi/ofi_impl.h index 40f39c8f751..b1d7af73d66 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_impl.h +++ b/src/mpid/ch4/netmod/ofi/ofi_impl.h @@ -307,6 +307,10 @@ MPL_STATIC_INLINE_PREFIX void MPIDI_OFI_cntr_set(int ctx_idx, int val) #define MPIDI_OFI_COLL_MR_KEY 1 #define MPIDI_OFI_INVALID_MR_KEY 0xFFFFFFFFFFFFFFFFULL int MPIDI_OFI_retry_progress(void); +int MPIDI_OFI_recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * rreq); +int MPIDI_OFI_recv_huge_control(MPIDI_OFI_huge_remote_info_t * info); +int MPIDI_OFI_peek_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * rreq); +int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * req); int MPIDI_OFI_control_handler(void *am_hdr, void *data, MPI_Aint data_sz, uint32_t attr, MPIR_Request ** req); int MPIDI_OFI_am_rdma_read_ack_handler(void *am_hdr, void *data, diff --git a/src/mpid/ch4/netmod/ofi/util.c b/src/mpid/ch4/netmod/ofi/util.c index 3521b455060..ed2f77dd2ef 100644 --- a/src/mpid/ch4/netmod/ofi/util.c +++ b/src/mpid/ch4/netmod/ofi/util.c @@ -150,87 +150,6 @@ void MPIDI_OFI_mr_key_allocator_destroy(void) MPL_free(mr_key_allocator.bitmask); } -/* Translate the control message to get a huge message into a request to - * actually perform the data transfer. */ -static int MPIDI_OFI_get_huge(int vni, MPIDI_OFI_huge_remote_info_t * info) -{ - MPIDI_OFI_huge_recv_t *recv_elem = NULL; - int mpi_errno = MPI_SUCCESS; - MPIR_FUNC_ENTER; - - bool ready_to_get = false; - - /* If there has been a posted receive, search through the list of unmatched - * receives to find the one that goes with the incoming message. */ - { - MPIDI_OFI_huge_recv_list_t *list_ptr; - - MPL_DBG_MSG_FMT(MPIR_DBG_PT2PT, VERBOSE, - (MPL_DBG_FDEST, "SEARCHING POSTED LIST: (%d, %d, %d)", info->comm_id, - info->origin_rank, info->tag)); - - LL_FOREACH(MPIDI_posted_huge_recv_head, list_ptr) { - if (list_ptr->comm_id == info->comm_id && - list_ptr->rank == info->origin_rank && list_ptr->tag == info->tag) { - MPL_DBG_MSG_FMT(MPIR_DBG_PT2PT, VERBOSE, - (MPL_DBG_FDEST, "MATCHED POSTED LIST: (%d, %d, %d, %d)", - info->comm_id, info->origin_rank, info->tag, - list_ptr->rreq->handle)); - - LL_DELETE(MPIDI_posted_huge_recv_head, MPIDI_posted_huge_recv_tail, list_ptr); - - recv_elem = (MPIDI_OFI_huge_recv_t *) - MPIDIU_map_lookup(MPIDI_OFI_global.huge_recv_counters, list_ptr->rreq->handle); - - /* If this is a "peek" element for an MPI_Probe, it shouldn't be matched. Grab the - * important information and remove the element from the list. */ - if (recv_elem->peek) { - MPIR_STATUS_SET_COUNT(recv_elem->localreq->status, info->msgsize); - MPL_atomic_release_store_int(&(MPIDI_OFI_REQUEST(recv_elem->localreq, util_id)), - MPIDI_OFI_PEEK_FOUND); - MPIDIU_map_erase(MPIDI_OFI_global.huge_recv_counters, - recv_elem->localreq->handle); - MPL_free(recv_elem); - recv_elem = NULL; - } - - MPL_free(list_ptr); - break; - } - } - } - - if (recv_elem) { - ready_to_get = true; - } else { - /* Put the struct describing the transfer on an unexpected list to be retrieved later */ - MPL_DBG_MSG_FMT(MPIR_DBG_PT2PT, VERBOSE, - (MPL_DBG_FDEST, "CREATING UNEXPECTED HUGE RECV: (%d, %d, %d)", - info->comm_id, info->origin_rank, info->tag)); - - /* If this is unexpected, create a new tracker and put it in the unexpected list. */ - recv_elem = (MPIDI_OFI_huge_recv_t *) MPL_calloc(sizeof(*recv_elem), 1, MPL_MEM_COMM); - if (!recv_elem) - MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nomem"); - - LL_APPEND(MPIDI_unexp_huge_recv_head, MPIDI_unexp_huge_recv_tail, recv_elem); - } - - recv_elem->event_id = MPIDI_OFI_EVENT_GET_HUGE; - recv_elem->remote_info = *info; - recv_elem->next = NULL; - if (ready_to_get) { - MPIDI_OFI_get_huge_event(vni, NULL, (MPIR_Request *) recv_elem); - } - - MPIR_FUNC_EXIT; - - fn_exit: - return mpi_errno; - fn_fail: - goto fn_exit; -} - int MPIDI_OFI_control_handler(void *am_hdr, void *data, MPI_Aint data_sz, uint32_t attr, MPIR_Request ** req) { @@ -241,13 +160,14 @@ int MPIDI_OFI_control_handler(void *am_hdr, void *data, MPI_Aint data_sz, *req = NULL; } + int local_vci = MPIDIG_AM_ATTR_DST_VCI(attr); switch (ctrlsend->type) { case MPIDI_OFI_CTRL_HUGEACK: - mpi_errno = MPIDI_OFI_dispatch_function(0, NULL, ctrlsend->u.huge_ack.ackreq); + mpi_errno = MPIDI_OFI_dispatch_function(local_vci, NULL, ctrlsend->u.huge_ack.ackreq); break; case MPIDI_OFI_CTRL_HUGE: - mpi_errno = MPIDI_OFI_get_huge(0, &(ctrlsend->u.huge)); + mpi_errno = MPIDI_OFI_recv_huge_control(&(ctrlsend->u.huge)); break; default: From 4341feb0935dd5e8b00675b02eab311f642cd84a Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 27 Sep 2021 22:51:49 -0500 Subject: [PATCH 020/607] ch4/ofi: fix fi_read in enable_striping The counter was not incremented for the correct nic. Add FIXME to note potential issues with multiple simultaneous fi_read. --- src/mpid/ch4/netmod/ofi/ofi_huge.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_huge.c b/src/mpid/ch4/netmod/ofi/ofi_huge.c index a3fa2ea2713..4e017fe0f69 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_huge.c +++ b/src/mpid/ch4/netmod/ofi/ofi_huge.c @@ -333,13 +333,11 @@ int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reques goto fn_exit; } - int nic = 0; int vni_src = recv_elem->remote_info.vni_src; int vni_dst = recv_elem->remote_info.vni_dst; if (MPIDI_OFI_COMM(recv_elem->comm_ptr).enable_striping) { /* if striping enabled */ - MPIDI_OFI_cntr_incr(recv_elem->comm_ptr, vni_src, nic); if (recv_elem->cur_offset >= MPIDI_OFI_STRIPE_CHUNK_SIZE && bytesLeft > 0) { - for (nic = 0; nic < MPIDI_OFI_global.num_nics; nic++) { + for (int nic = 0; nic < MPIDI_OFI_global.num_nics; nic++) { int ctx_idx = MPIDI_OFI_get_ctx_index(recv_elem->comm_ptr, vni_dst, nic); remote_key = recv_elem->remote_info.rma_keys[nic]; @@ -350,6 +348,8 @@ int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reques bytesToGet = (bytesLeft <= recv_elem->stripe_size) ? bytesLeft : recv_elem->stripe_size; + /* FIXME: Can we issue concurrent fi_read with the same context? */ + MPIDI_OFI_cntr_incr(recv_elem->comm_ptr, vni_src, nic); MPIDI_OFI_CALL_RETRY(fi_read(MPIDI_OFI_global.ctx[ctx_idx].tx, (void *) ((char *) recv_buf + recv_elem->cur_offset), /* local buffer */ bytesToGet, /* bytes */ NULL, /* descriptor */ @@ -364,6 +364,7 @@ int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reques } } } else { + int nic = 0; int ctx_idx = MPIDI_OFI_get_ctx_index(recv_elem->comm_ptr, vni_src, nic); remote_key = recv_elem->remote_info.rma_keys[nic]; MPIDI_OFI_cntr_incr(recv_elem->comm_ptr, vni_src, nic); From 050a35293a3f78cb0ddafb4358f666ce74dcd311 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 26 Sep 2021 14:50:43 -0500 Subject: [PATCH 021/607] ch4/ofi: detect normal send in event loop Rather than check and fallback in MPIDI_OFI_recv_huge_event, check whether it's a huge message in event loop and dispatch accordingly. --- src/mpid/ch4/netmod/ofi/ofi_events.c | 6 +++++- src/mpid/ch4/netmod/ofi/ofi_huge.c | 13 ++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_events.c b/src/mpid/ch4/netmod/ofi/ofi_events.c index 17d48bed5e6..cdb68932725 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_events.c +++ b/src/mpid/ch4/netmod/ofi/ofi_events.c @@ -488,7 +488,11 @@ int MPIDI_OFI_dispatch_function(int vni, struct fi_cq_tagged_entry *wc, MPIR_Req break; case MPIDI_OFI_EVENT_RECV_HUGE: - mpi_errno = MPIDI_OFI_recv_huge_event(vni, wc, req); + if (wc->tag & MPIDI_OFI_HUGE_SEND) { + mpi_errno = MPIDI_OFI_recv_huge_event(vni, wc, req); + } else { + mpi_errno = MPIDI_OFI_recv_event(vni, wc, req, MPIDI_OFI_EVENT_RECV_HUGE); + } break; case MPIDI_OFI_EVENT_RECV_PACK: diff --git a/src/mpid/ch4/netmod/ofi/ofi_huge.c b/src/mpid/ch4/netmod/ofi/ofi_huge.c index 4e017fe0f69..b41235ccbd9 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_huge.c +++ b/src/mpid/ch4/netmod/ofi/ofi_huge.c @@ -16,15 +16,10 @@ int MPIDI_OFI_recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque MPIR_FUNC_ENTER; bool ready_to_get = false; - /* Check that the sender didn't underflow the message by sending less than - * the huge message threshold. When striping is enabled underflow occurs if - * the sender sends < MPIDI_OFI_STRIPE_CHUNK_SIZE through the huge message protocol - * or < MPIDI_OFI_global.stripe_threshold through normal send */ - if (((wc->len < MPIDI_OFI_STRIPE_CHUNK_SIZE || - (wc->len > MPIDI_OFI_STRIPE_CHUNK_SIZE && wc->len < MPIDI_OFI_global.stripe_threshold)) && - MPIDI_OFI_COMM(rreq->comm).enable_striping) || - (wc->len < MPIDI_OFI_global.max_msg_size && !MPIDI_OFI_COMM(rreq->comm).enable_striping)) { - return MPIDI_OFI_recv_event(vni, wc, rreq, MPIDI_OFI_REQUEST(rreq, event_id)); + if (MPIDI_OFI_COMM(rreq->comm).enable_striping) { + MPIR_Assert(wc->len == MPIDI_OFI_STRIPE_CHUNK_SIZE); + } else { + MPIR_Assert(wc->len == MPIDI_OFI_global.max_msg_size); } comm_ptr = rreq->comm; From dddcf07eaeeb94da7ef7251679bb029b8bd37107 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 24 Sep 2021 14:37:42 -0500 Subject: [PATCH 022/607] ch4/ofi: detect huge message data truncation This partially fixes test/mpi/errors/pt2pt/truncmsg1 when set MPIR_CVAR_CH4_OFI_EAGER_MAX_MSG_SIZE=16384. We still need fix the case when huge message sent but small buffer is posted. --- src/mpid/ch4/netmod/ofi/ofi_events.c | 2 +- src/mpid/ch4/netmod/ofi/ofi_events.h | 5 +++-- src/mpid/ch4/netmod/ofi/ofi_huge.c | 5 +++++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_events.c b/src/mpid/ch4/netmod/ofi/ofi_events.c index cdb68932725..ea66ed4ec54 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_events.c +++ b/src/mpid/ch4/netmod/ofi/ofi_events.c @@ -585,10 +585,10 @@ int MPIDI_OFI_handle_cq_error(int vni, int nic, ssize_t ret) break; case MPIR_REQUEST_KIND__RECV: + req->status.MPI_ERROR = MPI_ERR_TRUNCATE; mpi_errno = MPIDI_OFI_dispatch_function(vni, (struct fi_cq_tagged_entry *) &e, req); - req->status.MPI_ERROR = MPI_ERR_TRUNCATE; break; default: diff --git a/src/mpid/ch4/netmod/ofi/ofi_events.h b/src/mpid/ch4/netmod/ofi/ofi_events.h index b4b00230e37..faacbeb9b9f 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_events.h +++ b/src/mpid/ch4/netmod/ofi/ofi_events.h @@ -54,7 +54,9 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_recv_event(int vni, struct fi_cq_tagged_e MPIR_FUNC_ENTER; rreq->status.MPI_SOURCE = MPIDI_OFI_cqe_get_source(wc, true); - rreq->status.MPI_ERROR = MPIDI_OFI_idata_get_error_bits(wc->data); + if (!rreq->status.MPI_ERROR) { + rreq->status.MPI_ERROR = MPIDI_OFI_idata_get_error_bits(wc->data); + } rreq->status.MPI_TAG = MPIDI_OFI_init_get_tag(wc->tag); count = wc->len; MPIR_STATUS_SET_COUNT(rreq->status, count); @@ -129,7 +131,6 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_recv_event(int vni, struct fi_cq_tagged_e MPIDIU_request_complete(rreq); - /* Polling loop will check for truncation */ fn_exit: MPIR_FUNC_EXIT; return mpi_errno; diff --git a/src/mpid/ch4/netmod/ofi/ofi_huge.c b/src/mpid/ch4/netmod/ofi/ofi_huge.c index b41235ccbd9..1b77040385c 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_huge.c +++ b/src/mpid/ch4/netmod/ofi/ofi_huge.c @@ -283,6 +283,11 @@ int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reques MPIR_FUNC_ENTER; void *recv_buf = MPIDI_OFI_REQUEST(recv_elem->localreq, util.iov.iov_base); + MPI_Aint data_sz = MPIDI_OFI_REQUEST(recv_elem->localreq, util.iov.iov_len); + if (recv_elem->remote_info.msgsize > data_sz) { + recv_elem->localreq->status.MPI_ERROR = MPI_ERR_TRUNCATE; + recv_elem->remote_info.msgsize = data_sz; + } if (MPIDI_OFI_COMM(recv_elem->comm_ptr).enable_striping) { /* Subtract one stripe_chunk_size because we send the first chunk via a regular message From f0c31f1c07e495f7840351fe1744620b765057bc Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 24 Sep 2021 14:47:43 -0500 Subject: [PATCH 023/607] ch4/ofi: swap order of sending huge ctrl The progress of huge message will depend on receiving the ctrl message. Send it first to promote the likelihood of ctrl header not arriving too much behind the message body. --- src/mpid/ch4/netmod/ofi/ofi_send.h | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_send.h b/src/mpid/ch4/netmod/ofi/ofi_send.h index ea2412cef7a..56a2cb8334f 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_send.h +++ b/src/mpid/ch4/netmod/ofi/ofi_send.h @@ -283,8 +283,6 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_send_normal(const void *buf, MPI_Aint cou struct fid_mr **huge_send_mrs; uint64_t msg_size = MPIDI_OFI_STRIPE_CHUNK_SIZE; - MPIDI_OFI_REQUEST(sreq, event_id) = MPIDI_OFI_EVENT_SEND_HUGE; - MPIR_cc_inc(sreq->cc_ptr); if (!MPIDI_OFI_COMM(comm).enable_striping) { num_nics = 1; @@ -333,18 +331,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_send_normal(const void *buf, MPI_Aint cou MPIR_Comm_add_ref(comm); /* Store ordering unnecessary for dst_rank, so use relaxed store */ MPL_atomic_relaxed_store_int(&MPIDI_OFI_REQUEST(sreq, util_id), dst_rank); - match_bits |= MPIDI_OFI_HUGE_SEND; /* Add the bit for a huge message */ - MPIDI_OFI_CALL_RETRY(fi_tsenddata(MPIDI_OFI_global.ctx[ctx_idx].tx, - send_buf, msg_size, NULL /* desc */ , - cq_data, - MPIDI_OFI_av_to_phys(addr, receiver_nic, vni_local, - vni_remote), - match_bits, - (void *) &(MPIDI_OFI_REQUEST(sreq, context))), - vni_local, tsenddata, FALSE /* eagain */); - MPIR_T_PVAR_COUNTER_INC(MULTINIC, nic_sent_bytes_count[sender_nic], msg_size); - MPIR_T_PVAR_COUNTER_INC(MULTINIC, striped_nic_sent_bytes_count[sender_nic], msg_size); + /* send ctrl message first */ MPIDI_OFI_send_control_t ctrl; ctrl.type = MPIDI_OFI_CTRL_HUGE; for (int i = 0; i < num_nics; i++) { @@ -359,10 +347,24 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_send_normal(const void *buf, MPI_Aint cou ctrl.u.huge.comm_id = comm->context_id; ctrl.u.huge.ackreq = sreq; - /* Send information about the memory region here to get the lmt going. */ mpi_errno = MPIDI_NM_am_send_hdr(dst_rank, comm, MPIDI_OFI_INTERNAL_HANDLER_CONTROL, &ctrl, sizeof(ctrl), vni_src, vni_dst); MPIR_ERR_CHECK(mpi_errno); + + /* send main native message next */ + MPIDI_OFI_REQUEST(sreq, event_id) = MPIDI_OFI_EVENT_SEND_HUGE; + + match_bits |= MPIDI_OFI_HUGE_SEND; /* Add the bit for a huge message */ + MPIDI_OFI_CALL_RETRY(fi_tsenddata(MPIDI_OFI_global.ctx[ctx_idx].tx, + send_buf, msg_size, NULL /* desc */ , + cq_data, + MPIDI_OFI_av_to_phys(addr, receiver_nic, vni_local, + vni_remote), + match_bits, + (void *) &(MPIDI_OFI_REQUEST(sreq, context))), + vni_local, tsenddata, FALSE /* eagain */); + MPIR_T_PVAR_COUNTER_INC(MULTINIC, nic_sent_bytes_count[sender_nic], msg_size); + MPIR_T_PVAR_COUNTER_INC(MULTINIC, striped_nic_sent_bytes_count[sender_nic], msg_size); } fn_exit: From c240db244ed0213a8e93dd0ea2eb2a54a72a0f9b Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 26 Sep 2021 09:24:45 -0500 Subject: [PATCH 024/607] ch4/ofi: remove debug messages from huge path The debug messages are temporary and should be removed after debugging. --- src/mpid/ch4/netmod/ofi/ofi_huge.c | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_huge.c b/src/mpid/ch4/netmod/ofi/ofi_huge.c index 1b77040385c..c669163460f 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_huge.c +++ b/src/mpid/ch4/netmod/ofi/ofi_huge.c @@ -30,20 +30,10 @@ int MPIDI_OFI_recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque { MPIDI_OFI_huge_recv_t *list_ptr; - MPL_DBG_MSG_FMT(MPIR_DBG_PT2PT, VERBOSE, - (MPL_DBG_FDEST, "SEARCHING HUGE UNEXPECTED LIST: (%d, %d, %llu)", - comm_ptr->context_id, MPIDI_OFI_cqe_get_source(wc, false), - (MPIDI_OFI_TAG_MASK & wc->tag))); - LL_FOREACH(MPIDI_unexp_huge_recv_head, list_ptr) { if (list_ptr->remote_info.comm_id == comm_ptr->context_id && list_ptr->remote_info.origin_rank == MPIDI_OFI_cqe_get_source(wc, false) && list_ptr->remote_info.tag == (MPIDI_OFI_TAG_MASK & wc->tag)) { - MPL_DBG_MSG_FMT(MPIR_DBG_PT2PT, VERBOSE, - (MPL_DBG_FDEST, "MATCHED HUGE UNEXPECTED LIST: (%d, %d, %llu, %d)", - comm_ptr->context_id, MPIDI_OFI_cqe_get_source(wc, false), - (MPIDI_OFI_TAG_MASK & wc->tag), rreq->handle)); - LL_DELETE(MPIDI_unexp_huge_recv_head, MPIDI_unexp_huge_recv_tail, list_ptr); recv_elem = list_ptr; @@ -59,11 +49,6 @@ int MPIDI_OFI_recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque } else { MPIDI_OFI_huge_recv_list_t *list_ptr; - MPL_DBG_MSG_FMT(MPIR_DBG_PT2PT, VERBOSE, - (MPL_DBG_FDEST, "CREATING HUGE POSTED ENTRY: (%d, %d, %llu)", - comm_ptr->context_id, MPIDI_OFI_cqe_get_source(wc, false), - (MPIDI_OFI_TAG_MASK & wc->tag))); - recv_elem = (MPIDI_OFI_huge_recv_t *) MPL_calloc(sizeof(*recv_elem), 1, MPL_MEM_BUFFER); MPIR_ERR_CHKANDJUMP(recv_elem == NULL, mpi_errno, MPI_ERR_OTHER, "**nomem"); MPIDIU_map_set(MPIDI_OFI_global.huge_recv_counters, rreq->handle, recv_elem, @@ -118,18 +103,9 @@ int MPIDI_OFI_recv_huge_control(MPIDI_OFI_huge_remote_info_t * info) { MPIDI_OFI_huge_recv_list_t *list_ptr; - MPL_DBG_MSG_FMT(MPIR_DBG_PT2PT, VERBOSE, - (MPL_DBG_FDEST, "SEARCHING POSTED LIST: (%d, %d, %d)", info->comm_id, - info->origin_rank, info->tag)); - LL_FOREACH(MPIDI_posted_huge_recv_head, list_ptr) { if (list_ptr->comm_id == info->comm_id && list_ptr->rank == info->origin_rank && list_ptr->tag == info->tag) { - MPL_DBG_MSG_FMT(MPIR_DBG_PT2PT, VERBOSE, - (MPL_DBG_FDEST, "MATCHED POSTED LIST: (%d, %d, %d, %d)", - info->comm_id, info->origin_rank, info->tag, - list_ptr->rreq->handle)); - LL_DELETE(MPIDI_posted_huge_recv_head, MPIDI_posted_huge_recv_tail, list_ptr); recv_elem = (MPIDI_OFI_huge_recv_t *) @@ -157,11 +133,6 @@ int MPIDI_OFI_recv_huge_control(MPIDI_OFI_huge_remote_info_t * info) ready_to_get = true; } else { /* Put the struct describing the transfer on an unexpected list to be retrieved later */ - MPL_DBG_MSG_FMT(MPIR_DBG_PT2PT, VERBOSE, - (MPL_DBG_FDEST, "CREATING UNEXPECTED HUGE RECV: (%d, %d, %d)", - info->comm_id, info->origin_rank, info->tag)); - - /* If this is unexpected, create a new tracker and put it in the unexpected list. */ recv_elem = (MPIDI_OFI_huge_recv_t *) MPL_calloc(sizeof(*recv_elem), 1, MPL_MEM_COMM); if (!recv_elem) MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nomem"); From 00d7eaa7cf95127bd88c0fdc2637cc770e670120 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 26 Sep 2021 14:00:53 -0500 Subject: [PATCH 025/607] ch4/ofi: differentiate probe and mprobe of huge messages When probing huge messages and control is missing, we should handle probe and mprobe differently. With probe, we can simply return not found. With mprobe, we can enqueue the rreq since the entry is guaranteed not to be double matched. --- src/mpid/ch4/netmod/ofi/ofi_huge.c | 34 ++++++++++++++++++++--------- src/mpid/ch4/netmod/ofi/ofi_pre.h | 6 +++++ src/mpid/ch4/netmod/ofi/ofi_probe.h | 16 +++++++++----- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_huge.c b/src/mpid/ch4/netmod/ofi/ofi_huge.c index c669163460f..73e632c7471 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_huge.c +++ b/src/mpid/ch4/netmod/ofi/ofi_huge.c @@ -175,8 +175,20 @@ int MPIDI_OFI_peek_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque found_msg = true; } } - if (!found_msg) { - /* FIXME: the count is wrong in this case. We need progress until the control message is received */ + if (found_msg) { + rreq->status.MPI_SOURCE = MPIDI_OFI_cqe_get_source(wc, false); + rreq->status.MPI_TAG = MPIDI_OFI_init_get_tag(wc->tag); + rreq->status.MPI_ERROR = MPI_SUCCESS; + MPIR_STATUS_SET_COUNT(rreq->status, count); + /* util_id should be the last thing to change in rreq. Reason is + * we use util_id to indicate peek_event has completed and all the + * relevant values have been copied to rreq. */ + MPL_atomic_release_store_int(&(MPIDI_OFI_REQUEST(rreq, util_id)), MPIDI_OFI_PEEK_FOUND); + } else if (MPIDI_OFI_REQUEST(rreq, kind) == MPIDI_OFI_req_kind__probe) { + /* return not found for this probe. User can probe again. */ + MPL_atomic_release_store_int(&(MPIDI_OFI_REQUEST(rreq, util_id)), MPIDI_OFI_PEEK_NOT_FOUND); + } else if (MPIDI_OFI_REQUEST(rreq, kind) == MPIDI_OFI_req_kind__mprobe) { + /* post the rreq to list and let control handler handle it */ MPIDI_OFI_huge_recv_t *recv_elem; MPIDI_OFI_huge_recv_list_t *huge_list_ptr; @@ -207,16 +219,18 @@ int MPIDI_OFI_peek_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque } LL_APPEND(MPIDI_posted_huge_recv_head, MPIDI_posted_huge_recv_tail, huge_list_ptr); + + /* FIXME: we don't have the correct count so it wrong to return FOUND here */ + rreq->status.MPI_SOURCE = MPIDI_OFI_cqe_get_source(wc, false); + rreq->status.MPI_TAG = MPIDI_OFI_init_get_tag(wc->tag); + rreq->status.MPI_ERROR = MPI_SUCCESS; + MPIR_STATUS_SET_COUNT(rreq->status, count); + /* util_id should be the last thing to change in rreq. Reason is + * we use util_id to indicate peek_event has completed and all the + * relevant values have been copied to rreq. */ + MPL_atomic_release_store_int(&(MPIDI_OFI_REQUEST(rreq, util_id)), MPIDI_OFI_PEEK_FOUND); } - rreq->status.MPI_SOURCE = MPIDI_OFI_cqe_get_source(wc, false); - rreq->status.MPI_TAG = MPIDI_OFI_init_get_tag(wc->tag); - rreq->status.MPI_ERROR = MPI_SUCCESS; - MPIR_STATUS_SET_COUNT(rreq->status, count); - /* util_id should be the last thing to change in rreq. Reason is - * we use util_id to indicate peek_event has completed and all the - * relevant values have been copied to rreq. */ - MPL_atomic_release_store_int(&(MPIDI_OFI_REQUEST(rreq, util_id)), MPIDI_OFI_PEEK_FOUND); fn_exit: MPIR_FUNC_EXIT; diff --git a/src/mpid/ch4/netmod/ofi/ofi_pre.h b/src/mpid/ch4/netmod/ofi/ofi_pre.h index c7db0e5833e..f2c6834951a 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_pre.h +++ b/src/mpid/ch4/netmod/ofi/ofi_pre.h @@ -185,6 +185,11 @@ typedef struct { MPI_Aint data_sz; /* save data_sz to avoid double checking */ } MPIDI_OFI_am_request_t; +enum MPIDI_OFI_req_kind { + MPIDI_OFI_req_kind__any, + MPIDI_OFI_req_kind__probe, + MPIDI_OFI_req_kind__mprobe, +}; typedef struct { struct fi_context context[MPIDI_OFI_CONTEXT_STRUCTS]; /* fixed field, do not move */ @@ -193,6 +198,7 @@ typedef struct { MPI_Datatype datatype; int nic_num; /* Store the nic number so we can use it to cancel a request later * if needed. */ + enum MPIDI_OFI_req_kind kind; union { struct { void *buf; diff --git a/src/mpid/ch4/netmod/ofi/ofi_probe.h b/src/mpid/ch4/netmod/ofi/ofi_probe.h index 14181444b55..60b1ed16ac9 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_probe.h +++ b/src/mpid/ch4/netmod/ofi/ofi_probe.h @@ -15,7 +15,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_do_iprobe(int source, MPIDI_av_entry_t * addr, int vni_src, int vni_dst, int *flag, MPI_Status * status, - MPIR_Request ** message, uint64_t peek_flags) + MPIR_Request ** message, + enum MPIDI_OFI_req_kind probe_kind) { int mpi_errno = MPI_SUCCESS; fi_addr_t remote_proc; @@ -41,6 +42,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_do_iprobe(int source, } else { rreq = &r; } + MPIDI_OFI_REQUEST(rreq, kind) = probe_kind; rreq->comm = comm; MPIR_Comm_add_ref(comm); @@ -58,8 +60,11 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_do_iprobe(int source, msg.context = (void *) &(MPIDI_OFI_REQUEST(rreq, context)); msg.data = 0; - MPIDI_OFI_CALL_RETURN(fi_trecvmsg(MPIDI_OFI_global.ctx[ctx_idx].rx, &msg, - peek_flags | FI_PEEK | FI_COMPLETION), ofi_err); + uint64_t recv_flags = FI_PEEK | FI_COMPLETION; + if (probe_kind == MPIDI_OFI_req_kind__mprobe) { + recv_flags |= FI_CLAIM; + } + MPIDI_OFI_CALL_RETURN(fi_trecvmsg(MPIDI_OFI_global.ctx[ctx_idx].rx, &msg, recv_flags), ofi_err); if (ofi_err == -FI_ENOMSG) { *flag = 0; if (message) @@ -138,7 +143,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_NM_mpi_improbe(int source, MPIDI_OFI_THREAD_CS_ENTER_VCI_OPTIONAL(vni_dst); /* Set flags for mprobe peek, when ready */ mpi_errno = MPIDI_OFI_do_iprobe(source, tag, comm, context_offset, addr, vni_src, vni_dst, - flag, status, message, FI_CLAIM | FI_COMPLETION); + flag, status, message, MPIDI_OFI_req_kind__mprobe); MPIDI_OFI_THREAD_CS_EXIT_VCI_OPTIONAL(vni_dst); if (mpi_errno != MPI_SUCCESS) @@ -166,7 +171,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_NM_mpi_iprobe(int source, } else { MPIDI_OFI_THREAD_CS_ENTER_VCI_OPTIONAL(vni_dst); mpi_errno = MPIDI_OFI_do_iprobe(source, tag, comm, context_offset, addr, - vni_src, vni_dst, flag, status, NULL, 0ULL); + vni_src, vni_dst, flag, status, NULL, + MPIDI_OFI_req_kind__probe); MPIDI_OFI_THREAD_CS_EXIT_VCI_OPTIONAL(vni_dst); } From 1ef1a7ac506993dd4112ce29c10b783e4aba5428 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 26 Sep 2021 15:04:28 -0500 Subject: [PATCH 026/607] ch4/ofi: remove MPIDI_OFI_global.huge_send_counters Store huge_send_mrs in the sreq so we don't need the extra global map. --- src/mpid/ch4/netmod/ofi/ofi_events.c | 12 +----------- src/mpid/ch4/netmod/ofi/ofi_init.c | 2 -- src/mpid/ch4/netmod/ofi/ofi_pre.h | 4 ++++ src/mpid/ch4/netmod/ofi/ofi_send.h | 4 +--- src/mpid/ch4/netmod/ofi/ofi_types.h | 1 - 5 files changed, 6 insertions(+), 17 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_events.c b/src/mpid/ch4/netmod/ofi/ofi_events.c index ea66ed4ec54..0518209c248 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_events.c +++ b/src/mpid/ch4/netmod/ofi/ofi_events.c @@ -90,21 +90,11 @@ static int send_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request if (c == 0) { MPIR_Comm *comm; - void *ptr; struct fid_mr **huge_send_mrs; comm = sreq->comm; num_nics = MPIDI_OFI_COMM(comm).enable_striping ? MPIDI_OFI_global.num_nics : 1; - /* Look for the memory region using the sreq handle */ - ptr = MPIDIU_map_lookup(MPIDI_OFI_global.huge_send_counters, sreq->handle); - MPIR_Assert(ptr != MPIDIU_MAP_NOT_FOUND); - - huge_send_mrs = (struct fid_mr **) ptr; - - /* Send a cleanup message to the receivier and clean up local - * resources. */ - /* Clean up the local counter */ - MPIDIU_map_erase(MPIDI_OFI_global.huge_send_counters, sreq->handle); + huge_send_mrs = MPIDI_OFI_REQUEST(sreq, huge_info.huge_send_mrs); /* Clean up the memory region */ if (!MPIDI_OFI_ENABLE_MR_PROV_KEY) { diff --git a/src/mpid/ch4/netmod/ofi/ofi_init.c b/src/mpid/ch4/netmod/ofi/ofi_init.c index 02e57eea4be..da7f16598b2 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_init.c +++ b/src/mpid/ch4/netmod/ofi/ofi_init.c @@ -559,7 +559,6 @@ int MPIDI_OFI_init_local(int *tag_bits) MPIDIU_map_create(&MPIDI_OFI_global.req_map, MPL_MEM_OTHER); /* Create huge protocol maps */ - MPIDIU_map_create(&MPIDI_OFI_global.huge_send_counters, MPL_MEM_COMM); MPIDIU_map_create(&MPIDI_OFI_global.huge_recv_counters, MPL_MEM_COMM); /* Initialize RMA keys allocator */ @@ -904,7 +903,6 @@ int MPIDI_OFI_mpi_finalize_hook(void) MPIDIU_map_destroy(MPIDI_OFI_global.win_map); MPIDIU_map_destroy(MPIDI_OFI_global.req_map); - MPIDIU_map_destroy(MPIDI_OFI_global.huge_send_counters); MPIDIU_map_destroy(MPIDI_OFI_global.huge_recv_counters); if (MPIDI_OFI_ENABLE_AM) { diff --git a/src/mpid/ch4/netmod/ofi/ofi_pre.h b/src/mpid/ch4/netmod/ofi/ofi_pre.h index f2c6834951a..5adf2c5bb64 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_pre.h +++ b/src/mpid/ch4/netmod/ofi/ofi_pre.h @@ -199,6 +199,10 @@ typedef struct { int nic_num; /* Store the nic number so we can use it to cancel a request later * if needed. */ enum MPIDI_OFI_req_kind kind; + union { + struct fid_mr **huge_send_mrs; + MPIDI_OFI_huge_remote_info_t *info; + } huge_info; union { struct { void *buf; diff --git a/src/mpid/ch4/netmod/ofi/ofi_send.h b/src/mpid/ch4/netmod/ofi/ofi_send.h index 56a2cb8334f..2f6f189d9d0 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_send.h +++ b/src/mpid/ch4/netmod/ofi/ofi_send.h @@ -313,9 +313,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_send_normal(const void *buf, MPI_Aint cou &huge_send_mrs[i], /* Out: memregion object */ NULL), mr_reg); /* In: context */ } - /* Create map to the memory region */ - MPIDIU_map_set(MPIDI_OFI_global.huge_send_counters, sreq->handle, huge_send_mrs, - MPL_MEM_BUFFER); + MPIDI_OFI_REQUEST(sreq, huge_info.huge_send_mrs) = huge_send_mrs; if (MPIDI_OFI_ENABLE_MR_PROV_KEY) { /* MR_BASIC */ for (int i = 0; i < num_nics; i++) { diff --git a/src/mpid/ch4/netmod/ofi/ofi_types.h b/src/mpid/ch4/netmod/ofi/ofi_types.h index 946040d0098..cf02e1a5809 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_types.h +++ b/src/mpid/ch4/netmod/ofi/ofi_types.h @@ -360,7 +360,6 @@ typedef struct { MPIDI_OFI_atomic_valid_t win_op_table[MPIR_DATATYPE_N_PREDEFINED][MPIDIG_ACCU_NUM_OP]; /* huge protocol globals */ - void *huge_send_counters; void *huge_recv_counters; /* Active Message Globals */ From 66707b0c0a8c1609926c6071fbdc01423a51620a Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 26 Sep 2021 15:49:23 -0500 Subject: [PATCH 027/607] ch4/ofi: remove huge_recv_counters Store the recv_elem pointer with rreq, so we don't need extra huge_recv_counters map. --- src/mpid/ch4/netmod/ofi/ofi_huge.c | 15 ++++----------- src/mpid/ch4/netmod/ofi/ofi_init.c | 5 ----- src/mpid/ch4/netmod/ofi/ofi_pre.h | 2 +- src/mpid/ch4/netmod/ofi/ofi_types.h | 3 --- 4 files changed, 5 insertions(+), 20 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_huge.c b/src/mpid/ch4/netmod/ofi/ofi_huge.c index 73e632c7471..0e2d97e63b7 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_huge.c +++ b/src/mpid/ch4/netmod/ofi/ofi_huge.c @@ -37,8 +37,7 @@ int MPIDI_OFI_recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque LL_DELETE(MPIDI_unexp_huge_recv_head, MPIDI_unexp_huge_recv_tail, list_ptr); recv_elem = list_ptr; - MPIDIU_map_set(MPIDI_OFI_global.huge_recv_counters, rreq->handle, recv_elem, - MPL_MEM_COMM); + MPIDI_OFI_REQUEST(rreq, huge_info.recv_elem) = recv_elem; break; } } @@ -51,8 +50,7 @@ int MPIDI_OFI_recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque recv_elem = (MPIDI_OFI_huge_recv_t *) MPL_calloc(sizeof(*recv_elem), 1, MPL_MEM_BUFFER); MPIR_ERR_CHKANDJUMP(recv_elem == NULL, mpi_errno, MPI_ERR_OTHER, "**nomem"); - MPIDIU_map_set(MPIDI_OFI_global.huge_recv_counters, rreq->handle, recv_elem, - MPL_MEM_BUFFER); + MPIDI_OFI_REQUEST(rreq, huge_info.recv_elem) = recv_elem; list_ptr = (MPIDI_OFI_huge_recv_list_t *) MPL_calloc(sizeof(*list_ptr), 1, MPL_MEM_BUFFER); if (!list_ptr) @@ -108,8 +106,7 @@ int MPIDI_OFI_recv_huge_control(MPIDI_OFI_huge_remote_info_t * info) list_ptr->rank == info->origin_rank && list_ptr->tag == info->tag) { LL_DELETE(MPIDI_posted_huge_recv_head, MPIDI_posted_huge_recv_tail, list_ptr); - recv_elem = (MPIDI_OFI_huge_recv_t *) - MPIDIU_map_lookup(MPIDI_OFI_global.huge_recv_counters, list_ptr->rreq->handle); + recv_elem = MPIDI_OFI_REQUEST(rreq, huge_info.recv_elem); /* If this is a "peek" element for an MPI_Probe, it shouldn't be matched. Grab the * important information and remove the element from the list. */ @@ -117,8 +114,6 @@ int MPIDI_OFI_recv_huge_control(MPIDI_OFI_huge_remote_info_t * info) MPIR_STATUS_SET_COUNT(recv_elem->localreq->status, info->msgsize); MPL_atomic_release_store_int(&(MPIDI_OFI_REQUEST(recv_elem->localreq, util_id)), MPIDI_OFI_PEEK_FOUND); - MPIDIU_map_erase(MPIDI_OFI_global.huge_recv_counters, - recv_elem->localreq->handle); MPL_free(recv_elem); recv_elem = NULL; } @@ -199,8 +194,7 @@ int MPIDI_OFI_peek_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque recv_elem->peek = true; MPIR_Comm *comm_ptr = rreq->comm; recv_elem->comm_ptr = comm_ptr; - MPIDIU_map_set(MPIDI_OFI_global.huge_recv_counters, rreq->handle, recv_elem, - MPL_MEM_BUFFER); + MPIDI_OFI_REQUEST(rreq, huge_info.recv_elem) = recv_elem; huge_list_ptr = (MPIDI_OFI_huge_recv_list_t *) MPL_calloc(sizeof(*huge_list_ptr), 1, MPL_MEM_COMM); @@ -312,7 +306,6 @@ int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reques &ctrl, sizeof(ctrl), vni_local, vni_remote); MPIR_ERR_CHECK(mpi_errno); - MPIDIU_map_erase(MPIDI_OFI_global.huge_recv_counters, key_to_erase); MPL_free(recv_elem); goto fn_exit; diff --git a/src/mpid/ch4/netmod/ofi/ofi_init.c b/src/mpid/ch4/netmod/ofi/ofi_init.c index da7f16598b2..ba95cbd7cb9 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_init.c +++ b/src/mpid/ch4/netmod/ofi/ofi_init.c @@ -558,9 +558,6 @@ int MPIDI_OFI_init_local(int *tag_bits) MPIDIU_map_create(&MPIDI_OFI_global.win_map, MPL_MEM_RMA); MPIDIU_map_create(&MPIDI_OFI_global.req_map, MPL_MEM_OTHER); - /* Create huge protocol maps */ - MPIDIU_map_create(&MPIDI_OFI_global.huge_recv_counters, MPL_MEM_COMM); - /* Initialize RMA keys allocator */ MPIDI_OFI_mr_key_allocator_init(); @@ -903,8 +900,6 @@ int MPIDI_OFI_mpi_finalize_hook(void) MPIDIU_map_destroy(MPIDI_OFI_global.win_map); MPIDIU_map_destroy(MPIDI_OFI_global.req_map); - MPIDIU_map_destroy(MPIDI_OFI_global.huge_recv_counters); - if (MPIDI_OFI_ENABLE_AM) { for (int vni = 0; vni < MPIDI_OFI_global.num_vnis; vni++) { while (MPIDI_OFI_global.per_vni[vni].am_unordered_msgs) { diff --git a/src/mpid/ch4/netmod/ofi/ofi_pre.h b/src/mpid/ch4/netmod/ofi/ofi_pre.h index 5adf2c5bb64..e85ecfe0a09 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_pre.h +++ b/src/mpid/ch4/netmod/ofi/ofi_pre.h @@ -201,7 +201,7 @@ typedef struct { enum MPIDI_OFI_req_kind kind; union { struct fid_mr **huge_send_mrs; - MPIDI_OFI_huge_remote_info_t *info; + MPIDI_OFI_huge_recv_t *recv_elem; } huge_info; union { struct { diff --git a/src/mpid/ch4/netmod/ofi/ofi_types.h b/src/mpid/ch4/netmod/ofi/ofi_types.h index cf02e1a5809..f77cf4997e8 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_types.h +++ b/src/mpid/ch4/netmod/ofi/ofi_types.h @@ -359,9 +359,6 @@ typedef struct { * OFI provider at MPI initialization.*/ MPIDI_OFI_atomic_valid_t win_op_table[MPIR_DATATYPE_N_PREDEFINED][MPIDIG_ACCU_NUM_OP]; - /* huge protocol globals */ - void *huge_recv_counters; - /* Active Message Globals */ MPL_atomic_int_t am_inflight_inject_emus; MPL_atomic_int_t am_inflight_rma_send_mrs; From 99cf7b2a2d3460ae1e0f1da0dc08fa8685c6d5c2 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 26 Sep 2021 10:01:58 -0500 Subject: [PATCH 028/607] ch4/ofi: revamp huge message handling Clean up the data structure to be more specific. Differentiate probe and mprobe. The former can be discarded when the control isn't ready. If we don't discard unsuccessful probe and put it in a queue, it can cause issues when another probe or recv come to interfere. Mprobe, on the other hand, is guaranteed to match once, so there is no issue. Persist the remote info with the original rreq. This avoids the use of separate hash maps to look up. It is also cleaner to track. --- src/mpid/ch4/netmod/ofi/globals.c | 8 +- src/mpid/ch4/netmod/ofi/ofi_events.c | 2 +- src/mpid/ch4/netmod/ofi/ofi_huge.c | 287 +++++++++++++-------------- src/mpid/ch4/netmod/ofi/ofi_impl.h | 3 +- src/mpid/ch4/netmod/ofi/ofi_pre.h | 6 +- src/mpid/ch4/netmod/ofi/ofi_probe.h | 18 +- src/mpid/ch4/netmod/ofi/ofi_recv.h | 4 + src/mpid/ch4/netmod/ofi/ofi_send.h | 20 +- src/mpid/ch4/netmod/ofi/ofi_types.h | 27 ++- src/mpid/ch4/netmod/ofi/util.c | 5 +- 10 files changed, 191 insertions(+), 189 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/globals.c b/src/mpid/ch4/netmod/ofi/globals.c index 67ea56bf50a..40f534b9697 100644 --- a/src/mpid/ch4/netmod/ofi/globals.c +++ b/src/mpid/ch4/netmod/ofi/globals.c @@ -7,10 +7,10 @@ #include "ofi_impl.h" MPIDI_OFI_global_t MPIDI_OFI_global; -MPIDI_OFI_huge_recv_t *MPIDI_unexp_huge_recv_head = NULL; -MPIDI_OFI_huge_recv_t *MPIDI_unexp_huge_recv_tail = NULL; -MPIDI_OFI_huge_recv_list_t *MPIDI_posted_huge_recv_head = NULL; -MPIDI_OFI_huge_recv_list_t *MPIDI_posted_huge_recv_tail = NULL; +MPIDI_OFI_huge_recv_list_t *MPIDI_huge_ctrl_head = NULL; +MPIDI_OFI_huge_recv_list_t *MPIDI_huge_ctrl_tail = NULL; +MPIDI_OFI_huge_recv_list_t *MPIDI_huge_recv_head = NULL; +MPIDI_OFI_huge_recv_list_t *MPIDI_huge_recv_tail = NULL; unsigned long long PVAR_COUNTER_nic_sent_bytes_count[MPIDI_OFI_MAX_NICS] ATTRIBUTE((unused)); unsigned long long PVAR_COUNTER_nic_recvd_bytes_count[MPIDI_OFI_MAX_NICS] ATTRIBUTE((unused)); diff --git a/src/mpid/ch4/netmod/ofi/ofi_events.c b/src/mpid/ch4/netmod/ofi/ofi_events.c index 0518209c248..4f9c09aab45 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_events.c +++ b/src/mpid/ch4/netmod/ofi/ofi_events.c @@ -94,7 +94,7 @@ static int send_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request comm = sreq->comm; num_nics = MPIDI_OFI_COMM(comm).enable_striping ? MPIDI_OFI_global.num_nics : 1; - huge_send_mrs = MPIDI_OFI_REQUEST(sreq, huge_info.huge_send_mrs); + huge_send_mrs = MPIDI_OFI_REQUEST(sreq, huge.send_mrs); /* Clean up the memory region */ if (!MPIDI_OFI_ENABLE_MR_PROV_KEY) { diff --git a/src/mpid/ch4/netmod/ofi/ofi_huge.c b/src/mpid/ch4/netmod/ofi/ofi_huge.c index 0e2d97e63b7..fb75af40417 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_huge.c +++ b/src/mpid/ch4/netmod/ofi/ofi_huge.c @@ -7,11 +7,33 @@ #include "ofi_impl.h" #include "ofi_events.h" +static int get_huge(MPIR_Request * rreq) +{ + int mpi_errno = MPI_SUCCESS; + MPIDI_OFI_huge_remote_info_t *info = MPIDI_OFI_REQUEST(rreq, huge.remote_info); + MPIDI_OFI_huge_recv_t *recv_elem = NULL; + + recv_elem = (MPIDI_OFI_huge_recv_t *) MPL_calloc(sizeof(*recv_elem), 1, MPL_MEM_BUFFER); + MPIR_ERR_CHKANDJUMP(recv_elem == NULL, mpi_errno, MPI_ERR_OTHER, "**nomem"); + recv_elem->event_id = MPIDI_OFI_EVENT_GET_HUGE; + recv_elem->localreq = rreq; + if (MPIDI_OFI_COMM(rreq->comm).enable_striping) { + recv_elem->cur_offset = MPIDI_OFI_STRIPE_CHUNK_SIZE; + } else { + recv_elem->cur_offset = MPIDI_OFI_global.max_msg_size; + } + MPIDI_OFI_get_huge_event(info->vni_dst, NULL, (MPIR_Request *) recv_elem); + + fn_exit: + return mpi_errno; + fn_fail: + goto fn_exit; +} + /* this function called by recv event of a huge message */ int MPIDI_OFI_recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * rreq) { int mpi_errno = MPI_SUCCESS; - MPIDI_OFI_huge_recv_t *recv_elem = NULL; MPIR_Comm *comm_ptr; MPIR_FUNC_ENTER; @@ -25,33 +47,30 @@ int MPIDI_OFI_recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque comm_ptr = rreq->comm; MPIR_T_PVAR_COUNTER_INC(MULTINIC, nic_recvd_bytes_count[MPIDI_OFI_REQUEST(rreq, nic_num)], wc->len); - /* Check to see if the tracker is already in the unexpected list. - * Otherwise, allocate one. */ - { - MPIDI_OFI_huge_recv_t *list_ptr; - - LL_FOREACH(MPIDI_unexp_huge_recv_head, list_ptr) { - if (list_ptr->remote_info.comm_id == comm_ptr->context_id && - list_ptr->remote_info.origin_rank == MPIDI_OFI_cqe_get_source(wc, false) && - list_ptr->remote_info.tag == (MPIDI_OFI_TAG_MASK & wc->tag)) { - LL_DELETE(MPIDI_unexp_huge_recv_head, MPIDI_unexp_huge_recv_tail, list_ptr); - - recv_elem = list_ptr; - MPIDI_OFI_REQUEST(rreq, huge_info.recv_elem) = recv_elem; + if (MPIDI_OFI_REQUEST(rreq, huge.remote_info)) { + /* this is mrecv, we already got remote info */ + ready_to_get = true; + } else { + /* Check for remote control info */ + MPIDI_OFI_huge_recv_list_t *list_ptr; + int comm_id = comm_ptr->context_id; + int rank = MPIDI_OFI_cqe_get_source(wc, false); + int tag = (MPIDI_OFI_TAG_MASK & wc->tag); + + LL_FOREACH(MPIDI_huge_ctrl_head, list_ptr) { + if (list_ptr->comm_id == comm_id && list_ptr->rank == rank && list_ptr->tag == tag) { + MPIDI_OFI_REQUEST(rreq, huge.remote_info) = list_ptr->u.info; + LL_DELETE(MPIDI_huge_ctrl_head, MPIDI_huge_ctrl_tail, list_ptr); + MPL_free(list_ptr); + ready_to_get = true; break; } } } - if (recv_elem) { - ready_to_get = true; - } else { + if (!ready_to_get) { MPIDI_OFI_huge_recv_list_t *list_ptr; - recv_elem = (MPIDI_OFI_huge_recv_t *) MPL_calloc(sizeof(*recv_elem), 1, MPL_MEM_BUFFER); - MPIR_ERR_CHKANDJUMP(recv_elem == NULL, mpi_errno, MPI_ERR_OTHER, "**nomem"); - MPIDI_OFI_REQUEST(rreq, huge_info.recv_elem) = recv_elem; - list_ptr = (MPIDI_OFI_huge_recv_list_t *) MPL_calloc(sizeof(*list_ptr), 1, MPL_MEM_BUFFER); if (!list_ptr) MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nomem"); @@ -59,25 +78,14 @@ int MPIDI_OFI_recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque list_ptr->comm_id = comm_ptr->context_id; list_ptr->rank = MPIDI_OFI_cqe_get_source(wc, false); list_ptr->tag = (MPIDI_OFI_TAG_MASK & wc->tag); - list_ptr->rreq = rreq; + list_ptr->u.rreq = rreq; - LL_APPEND(MPIDI_posted_huge_recv_head, MPIDI_posted_huge_recv_tail, list_ptr); - } - - /* Plug the information for the huge event into the receive request and go - * to the MPIDI_OFI_get_huge_event function. */ - recv_elem->event_id = MPIDI_OFI_EVENT_GET_HUGE; - recv_elem->peek = false; - recv_elem->comm_ptr = comm_ptr; - recv_elem->localreq = rreq; - recv_elem->wc = *wc; - if (MPIDI_OFI_COMM(comm_ptr).enable_striping) { - recv_elem->cur_offset = MPIDI_OFI_STRIPE_CHUNK_SIZE; + LL_APPEND(MPIDI_huge_recv_head, MPIDI_huge_recv_tail, list_ptr); + /* control handler will finish the recv */ } else { - recv_elem->cur_offset = MPIDI_OFI_global.max_msg_size; - } - if (ready_to_get) { - MPIDI_OFI_get_huge_event(vni, NULL, (MPIR_Request *) recv_elem); + /* proceed to get the huge message */ + mpi_errno = get_huge(rreq); + MPIR_ERR_CHECK(mpi_errno); } fn_exit: @@ -88,58 +96,55 @@ int MPIDI_OFI_recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque } /* This function is called when we receive a huge control message */ -int MPIDI_OFI_recv_huge_control(MPIDI_OFI_huge_remote_info_t * info) +int MPIDI_OFI_recv_huge_control(int comm_id, int rank, int tag, + MPIDI_OFI_huge_remote_info_t * info_ptr) { - MPIDI_OFI_huge_recv_t *recv_elem = NULL; int mpi_errno = MPI_SUCCESS; MPIR_FUNC_ENTER; - bool ready_to_get = false; + MPIDI_OFI_huge_recv_list_t *list_ptr; + MPIR_Request *rreq = NULL; + MPIDI_OFI_huge_remote_info_t *info; + + /* need persist the info. It will eventually get freed at recv completion */ + info = MPL_malloc(sizeof(MPIDI_OFI_huge_remote_info_t), MPL_MEM_OTHER); + MPIR_Assert(info); + memcpy(info, info_ptr, sizeof(*info)); /* If there has been a posted receive, search through the list of unmatched * receives to find the one that goes with the incoming message. */ - { - MPIDI_OFI_huge_recv_list_t *list_ptr; - - LL_FOREACH(MPIDI_posted_huge_recv_head, list_ptr) { - if (list_ptr->comm_id == info->comm_id && - list_ptr->rank == info->origin_rank && list_ptr->tag == info->tag) { - LL_DELETE(MPIDI_posted_huge_recv_head, MPIDI_posted_huge_recv_tail, list_ptr); - - recv_elem = MPIDI_OFI_REQUEST(rreq, huge_info.recv_elem); - - /* If this is a "peek" element for an MPI_Probe, it shouldn't be matched. Grab the - * important information and remove the element from the list. */ - if (recv_elem->peek) { - MPIR_STATUS_SET_COUNT(recv_elem->localreq->status, info->msgsize); - MPL_atomic_release_store_int(&(MPIDI_OFI_REQUEST(recv_elem->localreq, util_id)), - MPIDI_OFI_PEEK_FOUND); - MPL_free(recv_elem); - recv_elem = NULL; - } - - MPL_free(list_ptr); - break; - } + LL_FOREACH(MPIDI_huge_recv_head, list_ptr) { + if (list_ptr->comm_id == comm_id && list_ptr->rank == rank && list_ptr->tag == tag) { + rreq = list_ptr->u.rreq; + LL_DELETE(MPIDI_huge_recv_head, MPIDI_huge_recv_tail, list_ptr); + MPL_free(list_ptr); + break; } } - if (recv_elem) { - ready_to_get = true; - } else { - /* Put the struct describing the transfer on an unexpected list to be retrieved later */ - recv_elem = (MPIDI_OFI_huge_recv_t *) MPL_calloc(sizeof(*recv_elem), 1, MPL_MEM_COMM); - if (!recv_elem) + if (!rreq) { + list_ptr = (MPIDI_OFI_huge_recv_list_t *) MPL_calloc(sizeof(MPIDI_OFI_huge_recv_list_t), + 1, MPL_MEM_OTHER); + if (!list_ptr) { MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nomem"); + } + list_ptr->comm_id = comm_id; + list_ptr->rank = rank; + list_ptr->tag = tag; + list_ptr->u.info = info; - LL_APPEND(MPIDI_unexp_huge_recv_head, MPIDI_unexp_huge_recv_tail, recv_elem); - } - - recv_elem->event_id = MPIDI_OFI_EVENT_GET_HUGE; - recv_elem->remote_info = *info; - recv_elem->next = NULL; - if (ready_to_get) { - MPIDI_OFI_get_huge_event(info->vni_dst, NULL, (MPIR_Request *) recv_elem); + LL_APPEND(MPIDI_huge_ctrl_head, MPIDI_huge_ctrl_tail, list_ptr); + /* let MPIDI_OFI_recv_huge_event finish the recv */ + } else if (MPIDI_OFI_REQUEST(rreq, kind) == MPIDI_OFI_req_kind__mprobe) { + /* attach info and finish the mprobe */ + MPIDI_OFI_REQUEST(rreq, huge.remote_info) = info; + MPIR_STATUS_SET_COUNT(rreq->status, info->msgsize); + MPL_atomic_release_store_int(&(MPIDI_OFI_REQUEST(rreq, util_id)), MPIDI_OFI_PEEK_FOUND); + } else { + /* attach info and finish recv */ + MPIDI_OFI_REQUEST(rreq, huge.remote_info) = info; + mpi_errno = get_huge(rreq); + MPIR_ERR_CHECK(mpi_errno); } fn_exit: @@ -155,22 +160,28 @@ int MPIDI_OFI_peek_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque MPIR_FUNC_ENTER; MPI_Aint count = 0; - MPIDI_OFI_huge_recv_t *list_ptr; + MPIDI_OFI_huge_recv_list_t *list_ptr; bool found_msg = false; /* If this is a huge message, find the control message on the unexpected list that matches * with this and return the size in that. */ - LL_FOREACH(MPIDI_unexp_huge_recv_head, list_ptr) { + LL_FOREACH(MPIDI_huge_ctrl_head, list_ptr) { + /* FIXME: fix the type of comm_id */ uint64_t context_id = MPIDI_OFI_CONTEXT_MASK & wc->tag; - uint64_t tag = MPIDI_OFI_TAG_MASK & wc->tag; - if (list_ptr->remote_info.comm_id == context_id && - list_ptr->remote_info.origin_rank == MPIDI_OFI_cqe_get_source(wc, false) && - list_ptr->remote_info.tag == tag) { - count = list_ptr->remote_info.msgsize; + int rank = MPIDI_OFI_cqe_get_source(wc, false); + int tag = (int) (MPIDI_OFI_TAG_MASK & wc->tag); + if (list_ptr->comm_id == context_id && list_ptr->rank == rank && list_ptr->tag == tag) { + count = list_ptr->u.info->msgsize; found_msg = true; + break; } } if (found_msg) { + if (MPIDI_OFI_REQUEST(rreq, kind) == MPIDI_OFI_req_kind__mprobe) { + MPIDI_OFI_REQUEST(rreq, huge.remote_info) = list_ptr->u.info; + LL_DELETE(MPIDI_huge_ctrl_head, MPIDI_huge_ctrl_tail, list_ptr); + MPL_free(list_ptr); + } rreq->status.MPI_SOURCE = MPIDI_OFI_cqe_get_source(wc, false); rreq->status.MPI_TAG = MPIDI_OFI_init_get_tag(wc->tag); rreq->status.MPI_ERROR = MPI_SUCCESS; @@ -183,46 +194,24 @@ int MPIDI_OFI_peek_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque /* return not found for this probe. User can probe again. */ MPL_atomic_release_store_int(&(MPIDI_OFI_REQUEST(rreq, util_id)), MPIDI_OFI_PEEK_NOT_FOUND); } else if (MPIDI_OFI_REQUEST(rreq, kind) == MPIDI_OFI_req_kind__mprobe) { + /* fill the status with wc info. Count is still missing */ + rreq->status.MPI_SOURCE = MPIDI_OFI_cqe_get_source(wc, false); + rreq->status.MPI_TAG = MPIDI_OFI_init_get_tag(wc->tag); + rreq->status.MPI_ERROR = MPI_SUCCESS; + /* post the rreq to list and let control handler handle it */ - MPIDI_OFI_huge_recv_t *recv_elem; MPIDI_OFI_huge_recv_list_t *huge_list_ptr; - /* Create an element in the posted list that only indicates a peek and will be - * deleted as soon as it's fulfilled without being matched. */ - recv_elem = (MPIDI_OFI_huge_recv_t *) MPL_calloc(sizeof(*recv_elem), 1, MPL_MEM_COMM); - MPIR_ERR_CHKANDJUMP(recv_elem == NULL, mpi_errno, MPI_ERR_OTHER, "**nomem"); - recv_elem->peek = true; - MPIR_Comm *comm_ptr = rreq->comm; - recv_elem->comm_ptr = comm_ptr; - MPIDI_OFI_REQUEST(rreq, huge_info.recv_elem) = recv_elem; - huge_list_ptr = (MPIDI_OFI_huge_recv_list_t *) MPL_calloc(sizeof(*huge_list_ptr), 1, MPL_MEM_COMM); MPIR_ERR_CHKANDJUMP(huge_list_ptr == NULL, mpi_errno, MPI_ERR_OTHER, "**nomem"); - recv_elem->remote_info.comm_id = huge_list_ptr->comm_id = MPIDI_OFI_CONTEXT_MASK & wc->tag; - recv_elem->remote_info.origin_rank = huge_list_ptr->rank = - MPIDI_OFI_cqe_get_source(wc, false); - recv_elem->remote_info.tag = huge_list_ptr->tag = MPIDI_OFI_TAG_MASK & wc->tag; - recv_elem->localreq = huge_list_ptr->rreq = rreq; - recv_elem->event_id = MPIDI_OFI_EVENT_GET_HUGE; - recv_elem->wc = *wc; - if (MPIDI_OFI_COMM(comm_ptr).enable_striping) { - recv_elem->cur_offset = MPIDI_OFI_STRIPE_CHUNK_SIZE; - } else { - recv_elem->cur_offset = MPIDI_OFI_global.max_msg_size; - } - LL_APPEND(MPIDI_posted_huge_recv_head, MPIDI_posted_huge_recv_tail, huge_list_ptr); + huge_list_ptr->comm_id = MPIDI_OFI_CONTEXT_MASK & wc->tag; + huge_list_ptr->rank = MPIDI_OFI_cqe_get_source(wc, false); + huge_list_ptr->tag = MPIDI_OFI_TAG_MASK & wc->tag; + huge_list_ptr->u.rreq = rreq; - /* FIXME: we don't have the correct count so it wrong to return FOUND here */ - rreq->status.MPI_SOURCE = MPIDI_OFI_cqe_get_source(wc, false); - rreq->status.MPI_TAG = MPIDI_OFI_init_get_tag(wc->tag); - rreq->status.MPI_ERROR = MPI_SUCCESS; - MPIR_STATUS_SET_COUNT(rreq->status, count); - /* util_id should be the last thing to change in rreq. Reason is - * we use util_id to indicate peek_event has completed and all the - * relevant values have been copied to rreq. */ - MPL_atomic_release_store_int(&(MPIDI_OFI_REQUEST(rreq, util_id)), MPIDI_OFI_PEEK_FOUND); + LL_APPEND(MPIDI_huge_recv_head, MPIDI_huge_recv_tail, huge_list_ptr); } @@ -233,12 +222,12 @@ int MPIDI_OFI_peek_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque goto fn_exit; } -static uintptr_t recv_rbase(MPIDI_OFI_huge_recv_t * recv_elem) +static uintptr_t recv_rbase(MPIDI_OFI_huge_remote_info_t * remote_info) { if (!MPIDI_OFI_ENABLE_MR_VIRT_ADDRESS) { return 0; } else { - return (uintptr_t) recv_elem->remote_info.send_buf; + return (uintptr_t) remote_info->send_buf; } } @@ -257,21 +246,23 @@ int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reques { int mpi_errno = MPI_SUCCESS; MPIDI_OFI_huge_recv_t *recv_elem = (MPIDI_OFI_huge_recv_t *) req; + MPIDI_OFI_huge_remote_info_t *info = MPIDI_OFI_REQUEST(recv_elem->localreq, huge.remote_info); + MPIR_Comm *comm = recv_elem->localreq->comm; uint64_t remote_key; size_t bytesLeft, bytesToGet; MPIR_FUNC_ENTER; void *recv_buf = MPIDI_OFI_REQUEST(recv_elem->localreq, util.iov.iov_base); MPI_Aint data_sz = MPIDI_OFI_REQUEST(recv_elem->localreq, util.iov.iov_len); - if (recv_elem->remote_info.msgsize > data_sz) { + if (info->msgsize > data_sz) { recv_elem->localreq->status.MPI_ERROR = MPI_ERR_TRUNCATE; - recv_elem->remote_info.msgsize = data_sz; + info->msgsize = data_sz; } - if (MPIDI_OFI_COMM(recv_elem->comm_ptr).enable_striping) { + if (MPIDI_OFI_COMM(comm).enable_striping) { /* Subtract one stripe_chunk_size because we send the first chunk via a regular message * instead of the memory region */ - recv_elem->stripe_size = (recv_elem->remote_info.msgsize - MPIDI_OFI_STRIPE_CHUNK_SIZE) + recv_elem->stripe_size = (info->msgsize - MPIDI_OFI_STRIPE_CHUNK_SIZE) / MPIDI_OFI_global.num_nics; /* striping */ if (recv_elem->stripe_size > MPIDI_OFI_global.max_msg_size) { @@ -279,47 +270,49 @@ int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reques } if (recv_elem->chunks_outstanding) recv_elem->chunks_outstanding--; - bytesLeft = recv_elem->remote_info.msgsize - recv_elem->cur_offset; + bytesLeft = info->msgsize - recv_elem->cur_offset; bytesToGet = (bytesLeft <= recv_elem->stripe_size) ? bytesLeft : recv_elem->stripe_size; } else { /* Subtract one max_msg_size because we send the first chunk via a regular message * instead of the memory region */ - bytesLeft = recv_elem->remote_info.msgsize - recv_elem->cur_offset; + bytesLeft = info->msgsize - recv_elem->cur_offset; bytesToGet = (bytesLeft <= MPIDI_OFI_global.max_msg_size) ? bytesLeft : MPIDI_OFI_global.max_msg_size; } if (bytesToGet == 0ULL && recv_elem->chunks_outstanding == 0) { + int vni = info->vni_dst; + struct fi_cq_tagged_entry wc; + wc.len = recv_elem->cur_offset; + wc.data = info->origin_rank; + wc.tag = info->tag; + MPIDI_OFI_recv_event(vni, &wc, recv_elem->localreq, recv_elem->event_id); + MPIDI_OFI_send_control_t ctrl; - /* recv_elem->localreq may be freed during MPIDI_OFI_recv_event. - * Need to backup the handle here for later use with MPIDIU_map_erase. */ - uint64_t key_to_erase = recv_elem->localreq->handle; - recv_elem->wc.len = recv_elem->cur_offset; - MPIDI_OFI_recv_event(recv_elem->remote_info.vni_dst, &recv_elem->wc, recv_elem->localreq, - recv_elem->event_id); ctrl.type = MPIDI_OFI_CTRL_HUGEACK; - ctrl.u.huge_ack.ackreq = recv_elem->remote_info.ackreq; + ctrl.u.huge_ack.ackreq = info->ackreq; /* note: it's receiver ack sender */ - int vni_remote = recv_elem->remote_info.vni_src; - int vni_local = recv_elem->remote_info.vni_dst; - mpi_errno = MPIDI_NM_am_send_hdr(recv_elem->remote_info.origin_rank, recv_elem->comm_ptr, + int vni_remote = info->vni_src; + int vni_local = info->vni_dst; + mpi_errno = MPIDI_NM_am_send_hdr(info->origin_rank, comm, MPIDI_OFI_INTERNAL_HANDLER_CONTROL, &ctrl, sizeof(ctrl), vni_local, vni_remote); MPIR_ERR_CHECK(mpi_errno); + MPL_free(info); MPL_free(recv_elem); goto fn_exit; } - int vni_src = recv_elem->remote_info.vni_src; - int vni_dst = recv_elem->remote_info.vni_dst; - if (MPIDI_OFI_COMM(recv_elem->comm_ptr).enable_striping) { /* if striping enabled */ + int vni_src = info->vni_src; + int vni_dst = info->vni_dst; + if (MPIDI_OFI_COMM(comm).enable_striping) { /* if striping enabled */ if (recv_elem->cur_offset >= MPIDI_OFI_STRIPE_CHUNK_SIZE && bytesLeft > 0) { for (int nic = 0; nic < MPIDI_OFI_global.num_nics; nic++) { - int ctx_idx = MPIDI_OFI_get_ctx_index(recv_elem->comm_ptr, vni_dst, nic); - remote_key = recv_elem->remote_info.rma_keys[nic]; + int ctx_idx = MPIDI_OFI_get_ctx_index(comm, vni_dst, nic); + remote_key = info->rma_keys[nic]; - bytesLeft = recv_elem->remote_info.msgsize - recv_elem->cur_offset; + bytesLeft = info->msgsize - recv_elem->cur_offset; if (bytesLeft <= 0) { break; } @@ -331,7 +324,7 @@ int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reques MPIDI_OFI_CALL_RETRY(fi_read(MPIDI_OFI_global.ctx[ctx_idx].tx, (void *) ((char *) recv_buf + recv_elem->cur_offset), /* local buffer */ bytesToGet, /* bytes */ NULL, /* descriptor */ - MPIDI_OFI_comm_to_phys(recv_elem->comm_ptr, recv_elem->remote_info.origin_rank, nic, vni_dst, vni_src), recv_rbase(recv_elem) + recv_elem->cur_offset, /* remote maddr */ + MPIDI_OFI_comm_to_phys(comm, info->origin_rank, nic, vni_dst, vni_src), recv_rbase(info) + recv_elem->cur_offset, /* remote maddr */ remote_key, /* Key */ (void *) &recv_elem->context), nic, /* Context */ rdma_readfrom, FALSE); @@ -343,15 +336,15 @@ int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reques } } else { int nic = 0; - int ctx_idx = MPIDI_OFI_get_ctx_index(recv_elem->comm_ptr, vni_src, nic); - remote_key = recv_elem->remote_info.rma_keys[nic]; - MPIDI_OFI_cntr_incr(recv_elem->comm_ptr, vni_src, nic); + int ctx_idx = MPIDI_OFI_get_ctx_index(comm, vni_src, nic); + remote_key = info->rma_keys[nic]; + MPIDI_OFI_cntr_incr(comm, vni_src, nic); MPIDI_OFI_CALL_RETRY(fi_read(MPIDI_OFI_global.ctx[ctx_idx].tx, /* endpoint */ (void *) ((char *) recv_buf + recv_elem->cur_offset), /* local buffer */ bytesToGet, /* bytes */ NULL, /* descriptor */ - MPIDI_OFI_comm_to_phys(recv_elem->comm_ptr, recv_elem->remote_info.origin_rank, nic, vni_src, vni_dst), /* Destination */ - recv_rbase(recv_elem) + recv_elem->cur_offset, /* remote maddr */ + MPIDI_OFI_comm_to_phys(comm, info->origin_rank, nic, vni_src, vni_dst), /* Destination */ + recv_rbase(info) + recv_elem->cur_offset, /* remote maddr */ remote_key, /* Key */ (void *) &recv_elem->context), vni_src, rdma_readfrom, /* Context */ FALSE); diff --git a/src/mpid/ch4/netmod/ofi/ofi_impl.h b/src/mpid/ch4/netmod/ofi/ofi_impl.h index b1d7af73d66..fac32e0508a 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_impl.h +++ b/src/mpid/ch4/netmod/ofi/ofi_impl.h @@ -308,7 +308,8 @@ MPL_STATIC_INLINE_PREFIX void MPIDI_OFI_cntr_set(int ctx_idx, int val) #define MPIDI_OFI_INVALID_MR_KEY 0xFFFFFFFFFFFFFFFFULL int MPIDI_OFI_retry_progress(void); int MPIDI_OFI_recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * rreq); -int MPIDI_OFI_recv_huge_control(MPIDI_OFI_huge_remote_info_t * info); +int MPIDI_OFI_recv_huge_control(int comm_id, int rank, int tag, + MPIDI_OFI_huge_remote_info_t * info); int MPIDI_OFI_peek_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * rreq); int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * req); int MPIDI_OFI_control_handler(void *am_hdr, void *data, MPI_Aint data_sz, diff --git a/src/mpid/ch4/netmod/ofi/ofi_pre.h b/src/mpid/ch4/netmod/ofi/ofi_pre.h index e85ecfe0a09..39c6663c74d 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_pre.h +++ b/src/mpid/ch4/netmod/ofi/ofi_pre.h @@ -200,9 +200,9 @@ typedef struct { * if needed. */ enum MPIDI_OFI_req_kind kind; union { - struct fid_mr **huge_send_mrs; - MPIDI_OFI_huge_recv_t *recv_elem; - } huge_info; + struct fid_mr **send_mrs; + void *remote_info; + } huge; union { struct { void *buf; diff --git a/src/mpid/ch4/netmod/ofi/ofi_probe.h b/src/mpid/ch4/netmod/ofi/ofi_probe.h index 60b1ed16ac9..cae8b5fc38f 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_probe.h +++ b/src/mpid/ch4/netmod/ofi/ofi_probe.h @@ -14,9 +14,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_do_iprobe(int source, int context_offset, MPIDI_av_entry_t * addr, int vni_src, int vni_dst, int *flag, - MPI_Status * status, - MPIR_Request ** message, - enum MPIDI_OFI_req_kind probe_kind) + MPI_Status * status, MPIR_Request ** message) { int mpi_errno = MPI_SUCCESS; fi_addr_t remote_proc; @@ -42,7 +40,12 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_do_iprobe(int source, } else { rreq = &r; } - MPIDI_OFI_REQUEST(rreq, kind) = probe_kind; + if (message) { + MPIDI_OFI_REQUEST(rreq, kind) = MPIDI_OFI_req_kind__mprobe; + } else { + MPIDI_OFI_REQUEST(rreq, kind) = MPIDI_OFI_req_kind__probe; + } + MPIDI_OFI_REQUEST(rreq, huge.remote_info) = NULL; rreq->comm = comm; MPIR_Comm_add_ref(comm); @@ -61,7 +64,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_do_iprobe(int source, msg.data = 0; uint64_t recv_flags = FI_PEEK | FI_COMPLETION; - if (probe_kind == MPIDI_OFI_req_kind__mprobe) { + if (message) { recv_flags |= FI_CLAIM; } MPIDI_OFI_CALL_RETURN(fi_trecvmsg(MPIDI_OFI_global.ctx[ctx_idx].rx, &msg, recv_flags), ofi_err); @@ -143,7 +146,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_NM_mpi_improbe(int source, MPIDI_OFI_THREAD_CS_ENTER_VCI_OPTIONAL(vni_dst); /* Set flags for mprobe peek, when ready */ mpi_errno = MPIDI_OFI_do_iprobe(source, tag, comm, context_offset, addr, vni_src, vni_dst, - flag, status, message, MPIDI_OFI_req_kind__mprobe); + flag, status, message); MPIDI_OFI_THREAD_CS_EXIT_VCI_OPTIONAL(vni_dst); if (mpi_errno != MPI_SUCCESS) @@ -171,8 +174,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_NM_mpi_iprobe(int source, } else { MPIDI_OFI_THREAD_CS_ENTER_VCI_OPTIONAL(vni_dst); mpi_errno = MPIDI_OFI_do_iprobe(source, tag, comm, context_offset, addr, - vni_src, vni_dst, flag, status, NULL, - MPIDI_OFI_req_kind__probe); + vni_src, vni_dst, flag, status, NULL); MPIDI_OFI_THREAD_CS_EXIT_VCI_OPTIONAL(vni_dst); } diff --git a/src/mpid/ch4/netmod/ofi/ofi_recv.h b/src/mpid/ch4/netmod/ofi/ofi_recv.h index 40049aa2dc5..ea58cf6624b 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_recv.h +++ b/src/mpid/ch4/netmod/ofi/ofi_recv.h @@ -156,6 +156,10 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_do_irecv(void *buf, } *request = rreq; + MPIDI_OFI_REQUEST(rreq, kind) = MPIDI_OFI_req_kind__any; + if (!flags) { + MPIDI_OFI_REQUEST(rreq, huge.remote_info) = NULL; /* for huge recv remote info */ + } /* Calculate the correct NICs. */ sender_nic = MPIDI_OFI_multx_sender_nic_index(comm, comm->recvcontext_id, MPIR_Process.rank, diff --git a/src/mpid/ch4/netmod/ofi/ofi_send.h b/src/mpid/ch4/netmod/ofi/ofi_send.h index 2f6f189d9d0..406c11502a3 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_send.h +++ b/src/mpid/ch4/netmod/ofi/ofi_send.h @@ -313,7 +313,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_send_normal(const void *buf, MPI_Aint cou &huge_send_mrs[i], /* Out: memregion object */ NULL), mr_reg); /* In: context */ } - MPIDI_OFI_REQUEST(sreq, huge_info.huge_send_mrs) = huge_send_mrs; + MPIDI_OFI_REQUEST(sreq, huge.send_mrs) = huge_send_mrs; if (MPIDI_OFI_ENABLE_MR_PROV_KEY) { /* MR_BASIC */ for (int i = 0; i < num_nics; i++) { @@ -334,16 +334,16 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_send_normal(const void *buf, MPI_Aint cou MPIDI_OFI_send_control_t ctrl; ctrl.type = MPIDI_OFI_CTRL_HUGE; for (int i = 0; i < num_nics; i++) { - ctrl.u.huge.rma_keys[i] = rma_keys[i]; + ctrl.u.huge.info.rma_keys[i] = rma_keys[i]; } - ctrl.u.huge.tag = tag; - ctrl.u.huge.vni_src = vni_src; - ctrl.u.huge.vni_dst = vni_dst; - ctrl.u.huge.origin_rank = comm->rank; - ctrl.u.huge.send_buf = send_buf; - ctrl.u.huge.msgsize = data_sz; - ctrl.u.huge.comm_id = comm->context_id; - ctrl.u.huge.ackreq = sreq; + ctrl.u.huge.info.comm_id = comm->context_id; + ctrl.u.huge.info.tag = tag; + ctrl.u.huge.info.origin_rank = comm->rank; + ctrl.u.huge.info.vni_src = vni_src; + ctrl.u.huge.info.vni_dst = vni_dst; + ctrl.u.huge.info.send_buf = send_buf; + ctrl.u.huge.info.msgsize = data_sz; + ctrl.u.huge.info.ackreq = sreq; mpi_errno = MPIDI_NM_am_send_hdr(dst_rank, comm, MPIDI_OFI_INTERNAL_HANDLER_CONTROL, &ctrl, sizeof(ctrl), vni_src, vni_dst); diff --git a/src/mpid/ch4/netmod/ofi/ofi_types.h b/src/mpid/ch4/netmod/ofi/ofi_types.h index f77cf4997e8..4803adb6f1a 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_types.h +++ b/src/mpid/ch4/netmod/ofi/ofi_types.h @@ -380,13 +380,13 @@ typedef struct { } MPIDI_OFI_global_t; typedef struct { + int comm_id; int origin_rank; + int tag; MPIR_Request *ackreq; void *send_buf; size_t msgsize; - int comm_id; uint64_t rma_keys[MPIDI_OFI_MAX_NICS]; - int tag; int vni_src; int vni_dst; } MPIDI_OFI_huge_remote_info_t; @@ -394,7 +394,9 @@ typedef struct { typedef struct { int16_t type; union { - MPIDI_OFI_huge_remote_info_t huge; + struct { + MPIDI_OFI_huge_remote_info_t info; + } huge; struct { MPIR_Request *ackreq; } huge_ack; @@ -495,17 +497,11 @@ typedef struct MPIDI_OFI_huge_recv { char pad[MPIDI_REQUEST_HDR_SIZE]; struct fi_context context[MPIDI_OFI_CONTEXT_STRUCTS]; /* fixed field, do not move */ int event_id; /* fixed field, do not move */ - MPIDI_OFI_huge_remote_info_t remote_info; - bool peek; /* Flag to indicate whether this struct has been created to track an uncompleted peek - * operation. */ size_t cur_offset; size_t stripe_size; int chunks_outstanding; MPIR_Comm *comm_ptr; MPIR_Request *localreq; - struct fi_cq_tagged_entry wc; - struct MPIDI_OFI_huge_recv *next; /* Points to the next entry in the unexpected list - * (when in the unexpected list) */ } MPIDI_OFI_huge_recv_t; /* The list of posted huge receives that haven't been matched yet. These need @@ -516,16 +512,19 @@ typedef struct MPIDI_OFI_huge_recv_list { int comm_id; int rank; int tag; - MPIR_Request *rreq; + union { + MPIDI_OFI_huge_remote_info_t *info; /* ctrl list */ + MPIR_Request *rreq; /* recv list */ + } u; struct MPIDI_OFI_huge_recv_list *next; } MPIDI_OFI_huge_recv_list_t; /* Externs */ extern MPIDI_OFI_global_t MPIDI_OFI_global; -extern MPIDI_OFI_huge_recv_t *MPIDI_unexp_huge_recv_head; -extern MPIDI_OFI_huge_recv_t *MPIDI_unexp_huge_recv_tail; -extern MPIDI_OFI_huge_recv_list_t *MPIDI_posted_huge_recv_head; -extern MPIDI_OFI_huge_recv_list_t *MPIDI_posted_huge_recv_tail; +extern MPIDI_OFI_huge_recv_list_t *MPIDI_huge_ctrl_head; +extern MPIDI_OFI_huge_recv_list_t *MPIDI_huge_ctrl_tail; +extern MPIDI_OFI_huge_recv_list_t *MPIDI_huge_recv_head; +extern MPIDI_OFI_huge_recv_list_t *MPIDI_huge_recv_tail; extern MPIDI_OFI_capabilities_t MPIDI_OFI_caps_list[MPIDI_OFI_NUM_SETS]; diff --git a/src/mpid/ch4/netmod/ofi/util.c b/src/mpid/ch4/netmod/ofi/util.c index ed2f77dd2ef..a574ae3d328 100644 --- a/src/mpid/ch4/netmod/ofi/util.c +++ b/src/mpid/ch4/netmod/ofi/util.c @@ -167,7 +167,10 @@ int MPIDI_OFI_control_handler(void *am_hdr, void *data, MPI_Aint data_sz, break; case MPIDI_OFI_CTRL_HUGE: - mpi_errno = MPIDI_OFI_recv_huge_control(&(ctrlsend->u.huge)); + mpi_errno = MPIDI_OFI_recv_huge_control(ctrlsend->u.huge.info.comm_id, + ctrlsend->u.huge.info.origin_rank, + ctrlsend->u.huge.info.tag, + &(ctrlsend->u.huge.info)); break; default: From 79ea2af9be9ba3989233573018e23e160d4edf14 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 26 Sep 2021 20:42:49 -0500 Subject: [PATCH 029/607] ch4/ofi: split get_huge_complete Split the huge recv completion into static function. --- src/mpid/ch4/netmod/ofi/ofi_huge.c | 54 +++++++++++++++++++----------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_huge.c b/src/mpid/ch4/netmod/ofi/ofi_huge.c index fb75af40417..23ca888be07 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_huge.c +++ b/src/mpid/ch4/netmod/ofi/ofi_huge.c @@ -30,6 +30,40 @@ static int get_huge(MPIR_Request * rreq) goto fn_exit; } +static int get_huge_complete(MPIDI_OFI_huge_recv_t * recv_elem) +{ + int mpi_errno = MPI_SUCCESS; + MPIR_FUNC_ENTER; + + MPIDI_OFI_huge_remote_info_t *info = MPIDI_OFI_REQUEST(recv_elem->localreq, huge.remote_info); + + /* note: it's receiver ack sender */ + int vni_remote = info->vni_src; + int vni_local = info->vni_dst; + + struct fi_cq_tagged_entry wc; + wc.len = recv_elem->cur_offset; + wc.data = info->origin_rank; + wc.tag = info->tag; + MPIDI_OFI_recv_event(vni_local, &wc, recv_elem->localreq, MPIDI_OFI_EVENT_GET_HUGE); + + MPIDI_OFI_send_control_t ctrl; + ctrl.type = MPIDI_OFI_CTRL_HUGEACK; + ctrl.u.huge_ack.ackreq = info->ackreq; + mpi_errno = MPIDI_NM_am_send_hdr(info->origin_rank, comm, + MPIDI_OFI_INTERNAL_HANDLER_CONTROL, + &ctrl, sizeof(ctrl), vni_local, vni_remote); + MPIR_ERR_CHECK(mpi_errno); + + MPL_free(info); + + fn_exit: + MPIR_FUNC_EXIT; + return mpi_errno; + fn_fail: + goto fn_exit; +} + /* this function called by recv event of a huge message */ int MPIDI_OFI_recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * rreq) { @@ -280,27 +314,9 @@ int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reques bytesLeft : MPIDI_OFI_global.max_msg_size; } if (bytesToGet == 0ULL && recv_elem->chunks_outstanding == 0) { - int vni = info->vni_dst; - struct fi_cq_tagged_entry wc; - wc.len = recv_elem->cur_offset; - wc.data = info->origin_rank; - wc.tag = info->tag; - MPIDI_OFI_recv_event(vni, &wc, recv_elem->localreq, recv_elem->event_id); - - MPIDI_OFI_send_control_t ctrl; - ctrl.type = MPIDI_OFI_CTRL_HUGEACK; - ctrl.u.huge_ack.ackreq = info->ackreq; - /* note: it's receiver ack sender */ - int vni_remote = info->vni_src; - int vni_local = info->vni_dst; - mpi_errno = MPIDI_NM_am_send_hdr(info->origin_rank, comm, - MPIDI_OFI_INTERNAL_HANDLER_CONTROL, - &ctrl, sizeof(ctrl), vni_local, vni_remote); + mpi_errno = get_huge_complete(recv_elem); MPIR_ERR_CHECK(mpi_errno); - - MPL_free(info); MPL_free(recv_elem); - goto fn_exit; } From d53725474a0bec560b5fafee334e3ec4ab374008 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 26 Sep 2021 21:06:11 -0500 Subject: [PATCH 030/607] ch4/ofi: handle when huge message sent to small buffer We need handle this case the the sender still receives the ack message. --- src/mpid/ch4/netmod/ofi/ofi_events.h | 4 +++ src/mpid/ch4/netmod/ofi/ofi_huge.c | 54 ++++++++++++++++++---------- 2 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_events.h b/src/mpid/ch4/netmod/ofi/ofi_events.h index faacbeb9b9f..f88a3060cdb 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_events.h +++ b/src/mpid/ch4/netmod/ofi/ofi_events.h @@ -53,6 +53,10 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_recv_event(int vni, struct fi_cq_tagged_e size_t count; MPIR_FUNC_ENTER; + if (wc->tag & MPIDI_OFI_HUGE_SEND) { + mpi_errno = MPIDI_OFI_recv_huge_event(vni, wc, rreq); + goto fn_exit; + } rreq->status.MPI_SOURCE = MPIDI_OFI_cqe_get_source(wc, true); if (!rreq->status.MPI_ERROR) { rreq->status.MPI_ERROR = MPIDI_OFI_idata_get_error_bits(wc->data); diff --git a/src/mpid/ch4/netmod/ofi/ofi_huge.c b/src/mpid/ch4/netmod/ofi/ofi_huge.c index 23ca888be07..04ca13a2f1e 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_huge.c +++ b/src/mpid/ch4/netmod/ofi/ofi_huge.c @@ -7,21 +7,42 @@ #include "ofi_impl.h" #include "ofi_events.h" +static int get_huge(MPIR_Request * rreq); +static int get_huge_complete(MPIR_Request * rreq); + static int get_huge(MPIR_Request * rreq) { int mpi_errno = MPI_SUCCESS; MPIDI_OFI_huge_remote_info_t *info = MPIDI_OFI_REQUEST(rreq, huge.remote_info); - MPIDI_OFI_huge_recv_t *recv_elem = NULL; + MPI_Aint cur_offset; + if (MPIDI_OFI_COMM(rreq->comm).enable_striping) { + cur_offset = MPIDI_OFI_STRIPE_CHUNK_SIZE; + } else { + cur_offset = MPIDI_OFI_global.max_msg_size; + } + + MPI_Aint data_sz = MPIDI_OFI_REQUEST(rreq, util.iov.iov_len); + + if (data_sz < info->msgsize) { + rreq->status.MPI_ERROR = MPI_ERR_TRUNCATE; + info->msgsize = data_sz; + } + + if (data_sz < cur_offset) { + /* huge message sent to small recv buffer */ + mpi_errno = get_huge_complete(rreq); + MPIR_ERR_CHECK(mpi_errno); + goto fn_exit; + } + + MPIDI_OFI_huge_recv_t *recv_elem = NULL; recv_elem = (MPIDI_OFI_huge_recv_t *) MPL_calloc(sizeof(*recv_elem), 1, MPL_MEM_BUFFER); MPIR_ERR_CHKANDJUMP(recv_elem == NULL, mpi_errno, MPI_ERR_OTHER, "**nomem"); recv_elem->event_id = MPIDI_OFI_EVENT_GET_HUGE; recv_elem->localreq = rreq; - if (MPIDI_OFI_COMM(rreq->comm).enable_striping) { - recv_elem->cur_offset = MPIDI_OFI_STRIPE_CHUNK_SIZE; - } else { - recv_elem->cur_offset = MPIDI_OFI_global.max_msg_size; - } + recv_elem->cur_offset = cur_offset; + MPIDI_OFI_get_huge_event(info->vni_dst, NULL, (MPIR_Request *) recv_elem); fn_exit: @@ -30,27 +51,27 @@ static int get_huge(MPIR_Request * rreq) goto fn_exit; } -static int get_huge_complete(MPIDI_OFI_huge_recv_t * recv_elem) +static int get_huge_complete(MPIR_Request * rreq) { int mpi_errno = MPI_SUCCESS; MPIR_FUNC_ENTER; - MPIDI_OFI_huge_remote_info_t *info = MPIDI_OFI_REQUEST(recv_elem->localreq, huge.remote_info); + MPIDI_OFI_huge_remote_info_t *info = MPIDI_OFI_REQUEST(rreq, huge.remote_info); /* note: it's receiver ack sender */ int vni_remote = info->vni_src; int vni_local = info->vni_dst; struct fi_cq_tagged_entry wc; - wc.len = recv_elem->cur_offset; + wc.len = info->msgsize; wc.data = info->origin_rank; wc.tag = info->tag; - MPIDI_OFI_recv_event(vni_local, &wc, recv_elem->localreq, MPIDI_OFI_EVENT_GET_HUGE); + MPIDI_OFI_recv_event(vni_local, &wc, rreq, MPIDI_OFI_EVENT_GET_HUGE); MPIDI_OFI_send_control_t ctrl; ctrl.type = MPIDI_OFI_CTRL_HUGEACK; ctrl.u.huge_ack.ackreq = info->ackreq; - mpi_errno = MPIDI_NM_am_send_hdr(info->origin_rank, comm, + mpi_errno = MPIDI_NM_am_send_hdr(info->origin_rank, rreq->comm, MPIDI_OFI_INTERNAL_HANDLER_CONTROL, &ctrl, sizeof(ctrl), vni_local, vni_remote); MPIR_ERR_CHECK(mpi_errno); @@ -72,7 +93,9 @@ int MPIDI_OFI_recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque MPIR_FUNC_ENTER; bool ready_to_get = false; - if (MPIDI_OFI_COMM(rreq->comm).enable_striping) { + if (MPIDI_OFI_REQUEST(rreq, event_id) != MPIDI_OFI_EVENT_RECV_HUGE) { + /* huge send recved by a small buffer */ + } else if (MPIDI_OFI_COMM(rreq->comm).enable_striping) { MPIR_Assert(wc->len == MPIDI_OFI_STRIPE_CHUNK_SIZE); } else { MPIR_Assert(wc->len == MPIDI_OFI_global.max_msg_size); @@ -287,11 +310,6 @@ int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reques MPIR_FUNC_ENTER; void *recv_buf = MPIDI_OFI_REQUEST(recv_elem->localreq, util.iov.iov_base); - MPI_Aint data_sz = MPIDI_OFI_REQUEST(recv_elem->localreq, util.iov.iov_len); - if (info->msgsize > data_sz) { - recv_elem->localreq->status.MPI_ERROR = MPI_ERR_TRUNCATE; - info->msgsize = data_sz; - } if (MPIDI_OFI_COMM(comm).enable_striping) { /* Subtract one stripe_chunk_size because we send the first chunk via a regular message @@ -314,7 +332,7 @@ int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reques bytesLeft : MPIDI_OFI_global.max_msg_size; } if (bytesToGet == 0ULL && recv_elem->chunks_outstanding == 0) { - mpi_errno = get_huge_complete(recv_elem); + mpi_errno = get_huge_complete(recv_elem->localreq); MPIR_ERR_CHECK(mpi_errno); MPL_free(recv_elem); goto fn_exit; From bc898774f102dcf136f5ef59b14fd61ece1f763c Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 26 Sep 2021 22:10:19 -0500 Subject: [PATCH 031/607] ch4/ofi: add vni assertions in control handler Add safety assertions to ensure consistentcy. --- src/mpid/ch4/netmod/ofi/util.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mpid/ch4/netmod/ofi/util.c b/src/mpid/ch4/netmod/ofi/util.c index a574ae3d328..870e1a2362e 100644 --- a/src/mpid/ch4/netmod/ofi/util.c +++ b/src/mpid/ch4/netmod/ofi/util.c @@ -161,12 +161,15 @@ int MPIDI_OFI_control_handler(void *am_hdr, void *data, MPI_Aint data_sz, } int local_vci = MPIDIG_AM_ATTR_DST_VCI(attr); + MPIR_AssertDeclValue(int remote_vci, MPIDIG_AM_ATTR_SRC_VCI(attr)); switch (ctrlsend->type) { case MPIDI_OFI_CTRL_HUGEACK: mpi_errno = MPIDI_OFI_dispatch_function(local_vci, NULL, ctrlsend->u.huge_ack.ackreq); break; case MPIDI_OFI_CTRL_HUGE: + MPIR_Assert(local_vci == ctrlsend->u.huge.info.vni_dst); + MPIR_Assert(remote_vci == ctrlsend->u.huge.info.vni_src); mpi_errno = MPIDI_OFI_recv_huge_control(ctrlsend->u.huge.info.comm_id, ctrlsend->u.huge.info.origin_rank, ctrlsend->u.huge.info.tag, From 64278d7c32e29291cc1561118bccaf3636e8b5c8 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 26 Sep 2021 22:46:44 -0500 Subject: [PATCH 032/607] ch4/ofi: set recv data_sz correctly in the huge path The huge recv modifies the data_sz. Thus we need set MPIDI_OFI_REQUEST(rreq, util.iov.iov_len) earlier to prevent setting the wrong size. --- src/mpid/ch4/netmod/ofi/ofi_recv.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_recv.h b/src/mpid/ch4/netmod/ofi/ofi_recv.h index ea58cf6624b..3a4d389af96 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_recv.h +++ b/src/mpid/ch4/netmod/ofi/ofi_recv.h @@ -230,6 +230,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_do_irecv(void *buf, } /* Read ordering unnecessary for context_id, so use relaxed load */ MPL_atomic_relaxed_store_int(&MPIDI_OFI_REQUEST(rreq, util_id), context_id); + MPIDI_OFI_REQUEST(rreq, util.iov.iov_base) = recv_buf; + MPIDI_OFI_REQUEST(rreq, util.iov.iov_len) = data_sz; if (unlikely(data_sz >= MPIDI_OFI_global.max_msg_size) && !MPIDI_OFI_COMM(comm).enable_striping) { MPIDI_OFI_REQUEST(rreq, event_id) = MPIDI_OFI_EVENT_RECV_HUGE; @@ -244,8 +246,6 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_do_irecv(void *buf, } else if (MPIDI_OFI_REQUEST(rreq, event_id) != MPIDI_OFI_EVENT_RECV_PACK) MPIDI_OFI_REQUEST(rreq, event_id) = MPIDI_OFI_EVENT_RECV; - MPIDI_OFI_REQUEST(rreq, util.iov.iov_base) = recv_buf; - MPIDI_OFI_REQUEST(rreq, util.iov.iov_len) = data_sz; if (!flags) { MPIDI_OFI_CALL_RETRY(fi_trecv(MPIDI_OFI_global.ctx[ctx_idx].rx, recv_buf, From fb31562e232edfb9b79f69d14898eb3f603782a0 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 27 Sep 2021 00:11:12 -0500 Subject: [PATCH 033/607] ch4/ofi: fix usage of comm_id The comm_id in huge message path is, in fact, context_id of the communicator. We need use MPIR_Context_id_t as type. Direct applying mask to wc->tag won't get the corresponding context_id due to missing shift. Fix it by directly using rreq->comm->recvcontext_id. --- src/mpid/ch4/netmod/ofi/ofi_huge.c | 12 ++++++------ src/mpid/ch4/netmod/ofi/ofi_impl.h | 2 +- src/mpid/ch4/netmod/ofi/ofi_types.h | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_huge.c b/src/mpid/ch4/netmod/ofi/ofi_huge.c index 04ca13a2f1e..ef227f73681 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_huge.c +++ b/src/mpid/ch4/netmod/ofi/ofi_huge.c @@ -110,7 +110,7 @@ int MPIDI_OFI_recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque } else { /* Check for remote control info */ MPIDI_OFI_huge_recv_list_t *list_ptr; - int comm_id = comm_ptr->context_id; + MPIR_Context_id_t comm_id = comm_ptr->recvcontext_id; int rank = MPIDI_OFI_cqe_get_source(wc, false); int tag = (MPIDI_OFI_TAG_MASK & wc->tag); @@ -132,7 +132,7 @@ int MPIDI_OFI_recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque if (!list_ptr) MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nomem"); - list_ptr->comm_id = comm_ptr->context_id; + list_ptr->comm_id = comm_ptr->recvcontext_id; list_ptr->rank = MPIDI_OFI_cqe_get_source(wc, false); list_ptr->tag = (MPIDI_OFI_TAG_MASK & wc->tag); list_ptr->u.rreq = rreq; @@ -153,7 +153,7 @@ int MPIDI_OFI_recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque } /* This function is called when we receive a huge control message */ -int MPIDI_OFI_recv_huge_control(int comm_id, int rank, int tag, +int MPIDI_OFI_recv_huge_control(MPIR_Context_id_t comm_id, int rank, int tag, MPIDI_OFI_huge_remote_info_t * info_ptr) { int mpi_errno = MPI_SUCCESS; @@ -224,10 +224,10 @@ int MPIDI_OFI_peek_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque * with this and return the size in that. */ LL_FOREACH(MPIDI_huge_ctrl_head, list_ptr) { /* FIXME: fix the type of comm_id */ - uint64_t context_id = MPIDI_OFI_CONTEXT_MASK & wc->tag; + MPIR_Context_id_t comm_id = rreq->comm->recvcontext_id; int rank = MPIDI_OFI_cqe_get_source(wc, false); int tag = (int) (MPIDI_OFI_TAG_MASK & wc->tag); - if (list_ptr->comm_id == context_id && list_ptr->rank == rank && list_ptr->tag == tag) { + if (list_ptr->comm_id == comm_id && list_ptr->rank == rank && list_ptr->tag == tag) { count = list_ptr->u.info->msgsize; found_msg = true; break; @@ -263,7 +263,7 @@ int MPIDI_OFI_peek_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque (MPIDI_OFI_huge_recv_list_t *) MPL_calloc(sizeof(*huge_list_ptr), 1, MPL_MEM_COMM); MPIR_ERR_CHKANDJUMP(huge_list_ptr == NULL, mpi_errno, MPI_ERR_OTHER, "**nomem"); - huge_list_ptr->comm_id = MPIDI_OFI_CONTEXT_MASK & wc->tag; + huge_list_ptr->comm_id = rreq->comm->recvcontext_id; huge_list_ptr->rank = MPIDI_OFI_cqe_get_source(wc, false); huge_list_ptr->tag = MPIDI_OFI_TAG_MASK & wc->tag; huge_list_ptr->u.rreq = rreq; diff --git a/src/mpid/ch4/netmod/ofi/ofi_impl.h b/src/mpid/ch4/netmod/ofi/ofi_impl.h index fac32e0508a..23a712c2976 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_impl.h +++ b/src/mpid/ch4/netmod/ofi/ofi_impl.h @@ -308,7 +308,7 @@ MPL_STATIC_INLINE_PREFIX void MPIDI_OFI_cntr_set(int ctx_idx, int val) #define MPIDI_OFI_INVALID_MR_KEY 0xFFFFFFFFFFFFFFFFULL int MPIDI_OFI_retry_progress(void); int MPIDI_OFI_recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * rreq); -int MPIDI_OFI_recv_huge_control(int comm_id, int rank, int tag, +int MPIDI_OFI_recv_huge_control(MPIR_Context_id_t comm_id, int rank, int tag, MPIDI_OFI_huge_remote_info_t * info); int MPIDI_OFI_peek_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * rreq); int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * req); diff --git a/src/mpid/ch4/netmod/ofi/ofi_types.h b/src/mpid/ch4/netmod/ofi/ofi_types.h index 4803adb6f1a..2d7ab332c57 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_types.h +++ b/src/mpid/ch4/netmod/ofi/ofi_types.h @@ -380,7 +380,7 @@ typedef struct { } MPIDI_OFI_global_t; typedef struct { - int comm_id; + MPIR_Context_id_t comm_id; int origin_rank; int tag; MPIR_Request *ackreq; @@ -509,7 +509,7 @@ typedef struct MPIDI_OFI_huge_recv { * data from the remote memory region and we need a way of matching up the * control messages with the "real" requests. */ typedef struct MPIDI_OFI_huge_recv_list { - int comm_id; + MPIR_Context_id_t comm_id; int rank; int tag; union { From eccc6e237f08c8b738c644b666f6bb418f9454c5 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 28 Sep 2021 18:04:17 -0500 Subject: [PATCH 034/607] ch4/ofi: remove sync flag for huge send Huge send will always be ack'ed at completion, thus additional sync ack is not necessary. This fixes ssend huge messages due to the sync flag in the wc entry was not saved. This was broken in the commit "revamp huge message handling". --- src/mpid/ch4/netmod/ofi/ofi_send.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_send.h b/src/mpid/ch4/netmod/ofi/ofi_send.h index 406c11502a3..51df6d52dd7 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_send.h +++ b/src/mpid/ch4/netmod/ofi/ofi_send.h @@ -170,6 +170,19 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_send_normal(const void *buf, MPI_Aint cou MPIR_Request *sreq = *request; + bool is_huge_send = false; + MPI_Aint huge_thresh; + if (MPIDI_OFI_COMM(comm).enable_striping) { + huge_thresh = MPIDI_OFI_global.stripe_threshold; + } else { + huge_thresh = MPIDI_OFI_global.max_msg_size; + } + if (data_sz >= huge_thresh) { + is_huge_send = true; + /* huge send will always be synchronized */ + type = 0; + } + match_bits = MPIDI_OFI_init_sendtag(comm->context_id + context_offset, tag, type); MPIDI_OFI_REQUEST(sreq, event_id) = MPIDI_OFI_EVENT_SEND; MPIDI_OFI_REQUEST(sreq, datatype) = datatype; @@ -266,9 +279,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_send_normal(const void *buf, MPI_Aint cou vni_local, tinjectdata, FALSE /* eagain */); MPIR_T_PVAR_COUNTER_INC(MULTINIC, nic_sent_bytes_count[sender_nic], data_sz); MPIDI_OFI_send_event(vni_src, NULL, sreq, MPIDI_OFI_REQUEST(sreq, event_id)); - } else if ((data_sz < MPIDI_OFI_global.max_msg_size && !MPIDI_OFI_COMM(comm).enable_striping) - || (data_sz < MPIDI_OFI_global.stripe_threshold && - MPIDI_OFI_COMM(comm).enable_striping)) { + } else if (!is_huge_send) { MPIDI_OFI_CALL_RETRY(fi_tsenddata(MPIDI_OFI_global.ctx[ctx_idx].tx, send_buf, data_sz, NULL /* desc */ , cq_data, From b827064d764f8bc9ab1cc1b42c0e591631564dce Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 28 Sep 2021 18:30:51 -0500 Subject: [PATCH 035/607] ch4/ofi: move huge message queues into per_vni It is necessary to move the global queues into per_vni structure for multi-vci thread safety and performance. --- src/mpid/ch4/netmod/ofi/globals.c | 5 ----- src/mpid/ch4/netmod/ofi/ofi_huge.c | 26 ++++++++++++++++---------- src/mpid/ch4/netmod/ofi/ofi_impl.h | 2 +- src/mpid/ch4/netmod/ofi/ofi_types.h | 10 ++++++---- src/mpid/ch4/netmod/ofi/util.c | 3 ++- 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/globals.c b/src/mpid/ch4/netmod/ofi/globals.c index 40f534b9697..874d157a288 100644 --- a/src/mpid/ch4/netmod/ofi/globals.c +++ b/src/mpid/ch4/netmod/ofi/globals.c @@ -7,11 +7,6 @@ #include "ofi_impl.h" MPIDI_OFI_global_t MPIDI_OFI_global; -MPIDI_OFI_huge_recv_list_t *MPIDI_huge_ctrl_head = NULL; -MPIDI_OFI_huge_recv_list_t *MPIDI_huge_ctrl_tail = NULL; -MPIDI_OFI_huge_recv_list_t *MPIDI_huge_recv_head = NULL; -MPIDI_OFI_huge_recv_list_t *MPIDI_huge_recv_tail = NULL; - unsigned long long PVAR_COUNTER_nic_sent_bytes_count[MPIDI_OFI_MAX_NICS] ATTRIBUTE((unused)); unsigned long long PVAR_COUNTER_nic_recvd_bytes_count[MPIDI_OFI_MAX_NICS] ATTRIBUTE((unused)); unsigned long long PVAR_COUNTER_striped_nic_sent_bytes_count[MPIDI_OFI_MAX_NICS] diff --git a/src/mpid/ch4/netmod/ofi/ofi_huge.c b/src/mpid/ch4/netmod/ofi/ofi_huge.c index ef227f73681..5d05f4f87e8 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_huge.c +++ b/src/mpid/ch4/netmod/ofi/ofi_huge.c @@ -114,10 +114,11 @@ int MPIDI_OFI_recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque int rank = MPIDI_OFI_cqe_get_source(wc, false); int tag = (MPIDI_OFI_TAG_MASK & wc->tag); - LL_FOREACH(MPIDI_huge_ctrl_head, list_ptr) { + LL_FOREACH(MPIDI_OFI_global.per_vni[vni].huge_ctrl_head, list_ptr) { if (list_ptr->comm_id == comm_id && list_ptr->rank == rank && list_ptr->tag == tag) { MPIDI_OFI_REQUEST(rreq, huge.remote_info) = list_ptr->u.info; - LL_DELETE(MPIDI_huge_ctrl_head, MPIDI_huge_ctrl_tail, list_ptr); + LL_DELETE(MPIDI_OFI_global.per_vni[vni].huge_ctrl_head, + MPIDI_OFI_global.per_vni[vni].huge_ctrl_tail, list_ptr); MPL_free(list_ptr); ready_to_get = true; break; @@ -137,7 +138,8 @@ int MPIDI_OFI_recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque list_ptr->tag = (MPIDI_OFI_TAG_MASK & wc->tag); list_ptr->u.rreq = rreq; - LL_APPEND(MPIDI_huge_recv_head, MPIDI_huge_recv_tail, list_ptr); + LL_APPEND(MPIDI_OFI_global.per_vni[vni].huge_recv_head, + MPIDI_OFI_global.per_vni[vni].huge_recv_tail, list_ptr); /* control handler will finish the recv */ } else { /* proceed to get the huge message */ @@ -153,7 +155,7 @@ int MPIDI_OFI_recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque } /* This function is called when we receive a huge control message */ -int MPIDI_OFI_recv_huge_control(MPIR_Context_id_t comm_id, int rank, int tag, +int MPIDI_OFI_recv_huge_control(int vni, MPIR_Context_id_t comm_id, int rank, int tag, MPIDI_OFI_huge_remote_info_t * info_ptr) { int mpi_errno = MPI_SUCCESS; @@ -170,10 +172,11 @@ int MPIDI_OFI_recv_huge_control(MPIR_Context_id_t comm_id, int rank, int tag, /* If there has been a posted receive, search through the list of unmatched * receives to find the one that goes with the incoming message. */ - LL_FOREACH(MPIDI_huge_recv_head, list_ptr) { + LL_FOREACH(MPIDI_OFI_global.per_vni[vni].huge_recv_head, list_ptr) { if (list_ptr->comm_id == comm_id && list_ptr->rank == rank && list_ptr->tag == tag) { rreq = list_ptr->u.rreq; - LL_DELETE(MPIDI_huge_recv_head, MPIDI_huge_recv_tail, list_ptr); + LL_DELETE(MPIDI_OFI_global.per_vni[vni].huge_recv_head, + MPIDI_OFI_global.per_vni[vni].huge_recv_tail, list_ptr); MPL_free(list_ptr); break; } @@ -190,7 +193,8 @@ int MPIDI_OFI_recv_huge_control(MPIR_Context_id_t comm_id, int rank, int tag, list_ptr->tag = tag; list_ptr->u.info = info; - LL_APPEND(MPIDI_huge_ctrl_head, MPIDI_huge_ctrl_tail, list_ptr); + LL_APPEND(MPIDI_OFI_global.per_vni[vni].huge_ctrl_head, + MPIDI_OFI_global.per_vni[vni].huge_ctrl_tail, list_ptr); /* let MPIDI_OFI_recv_huge_event finish the recv */ } else if (MPIDI_OFI_REQUEST(rreq, kind) == MPIDI_OFI_req_kind__mprobe) { /* attach info and finish the mprobe */ @@ -222,7 +226,7 @@ int MPIDI_OFI_peek_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque /* If this is a huge message, find the control message on the unexpected list that matches * with this and return the size in that. */ - LL_FOREACH(MPIDI_huge_ctrl_head, list_ptr) { + LL_FOREACH(MPIDI_OFI_global.per_vni[vni].huge_ctrl_head, list_ptr) { /* FIXME: fix the type of comm_id */ MPIR_Context_id_t comm_id = rreq->comm->recvcontext_id; int rank = MPIDI_OFI_cqe_get_source(wc, false); @@ -236,7 +240,8 @@ int MPIDI_OFI_peek_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque if (found_msg) { if (MPIDI_OFI_REQUEST(rreq, kind) == MPIDI_OFI_req_kind__mprobe) { MPIDI_OFI_REQUEST(rreq, huge.remote_info) = list_ptr->u.info; - LL_DELETE(MPIDI_huge_ctrl_head, MPIDI_huge_ctrl_tail, list_ptr); + LL_DELETE(MPIDI_OFI_global.per_vni[vni].huge_ctrl_head, + MPIDI_OFI_global.per_vni[vni].huge_ctrl_tail, list_ptr); MPL_free(list_ptr); } rreq->status.MPI_SOURCE = MPIDI_OFI_cqe_get_source(wc, false); @@ -268,7 +273,8 @@ int MPIDI_OFI_peek_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque huge_list_ptr->tag = MPIDI_OFI_TAG_MASK & wc->tag; huge_list_ptr->u.rreq = rreq; - LL_APPEND(MPIDI_huge_recv_head, MPIDI_huge_recv_tail, huge_list_ptr); + LL_APPEND(MPIDI_OFI_global.per_vni[vni].huge_recv_head, + MPIDI_OFI_global.per_vni[vni].huge_recv_tail, huge_list_ptr); } diff --git a/src/mpid/ch4/netmod/ofi/ofi_impl.h b/src/mpid/ch4/netmod/ofi/ofi_impl.h index 23a712c2976..95761dc0126 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_impl.h +++ b/src/mpid/ch4/netmod/ofi/ofi_impl.h @@ -308,7 +308,7 @@ MPL_STATIC_INLINE_PREFIX void MPIDI_OFI_cntr_set(int ctx_idx, int val) #define MPIDI_OFI_INVALID_MR_KEY 0xFFFFFFFFFFFFFFFFULL int MPIDI_OFI_retry_progress(void); int MPIDI_OFI_recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * rreq); -int MPIDI_OFI_recv_huge_control(MPIR_Context_id_t comm_id, int rank, int tag, +int MPIDI_OFI_recv_huge_control(int vni, MPIR_Context_id_t comm_id, int rank, int tag, MPIDI_OFI_huge_remote_info_t * info); int MPIDI_OFI_peek_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * rreq); int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * req); diff --git a/src/mpid/ch4/netmod/ofi/ofi_types.h b/src/mpid/ch4/netmod/ofi/ofi_types.h index 2d7ab332c57..e399ae91f6d 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_types.h +++ b/src/mpid/ch4/netmod/ofi/ofi_types.h @@ -243,6 +243,12 @@ typedef struct { int cq_buffered_static_tail; MPIDI_OFI_cq_list_t *cq_buffered_dynamic_head, *cq_buffered_dynamic_tail; + /* queues to matching huge recv and control message */ + struct MPIDI_OFI_huge_recv_list *huge_ctrl_head; + struct MPIDI_OFI_huge_recv_list *huge_ctrl_tail; + struct MPIDI_OFI_huge_recv_list *huge_recv_head; + struct MPIDI_OFI_huge_recv_list *huge_recv_tail; + char pad MPL_ATTR_ALIGNED(MPL_CACHELINE_SIZE); } MPIDI_OFI_per_vni_t; @@ -521,10 +527,6 @@ typedef struct MPIDI_OFI_huge_recv_list { /* Externs */ extern MPIDI_OFI_global_t MPIDI_OFI_global; -extern MPIDI_OFI_huge_recv_list_t *MPIDI_huge_ctrl_head; -extern MPIDI_OFI_huge_recv_list_t *MPIDI_huge_ctrl_tail; -extern MPIDI_OFI_huge_recv_list_t *MPIDI_huge_recv_head; -extern MPIDI_OFI_huge_recv_list_t *MPIDI_huge_recv_tail; extern MPIDI_OFI_capabilities_t MPIDI_OFI_caps_list[MPIDI_OFI_NUM_SETS]; diff --git a/src/mpid/ch4/netmod/ofi/util.c b/src/mpid/ch4/netmod/ofi/util.c index 870e1a2362e..d94fbd43eff 100644 --- a/src/mpid/ch4/netmod/ofi/util.c +++ b/src/mpid/ch4/netmod/ofi/util.c @@ -170,7 +170,8 @@ int MPIDI_OFI_control_handler(void *am_hdr, void *data, MPI_Aint data_sz, case MPIDI_OFI_CTRL_HUGE: MPIR_Assert(local_vci == ctrlsend->u.huge.info.vni_dst); MPIR_Assert(remote_vci == ctrlsend->u.huge.info.vni_src); - mpi_errno = MPIDI_OFI_recv_huge_control(ctrlsend->u.huge.info.comm_id, + mpi_errno = MPIDI_OFI_recv_huge_control(local_vci, + ctrlsend->u.huge.info.comm_id, ctrlsend->u.huge.info.origin_rank, ctrlsend->u.huge.info.tag, &(ctrlsend->u.huge.info)); From ce2c8505fc0b384ffafe035e80a297df440ae29d Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 1 Oct 2021 12:41:50 -0500 Subject: [PATCH 036/607] mpl: add macro MPL_DIV_ROUNDUP We often need calculate number of chunks that need division to round up to the next integer. Add a macro facilitate. --- src/mpl/include/mpl_math.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mpl/include/mpl_math.h b/src/mpl/include/mpl_math.h index 3caf55f41d5..7d19653c486 100644 --- a/src/mpl/include/mpl_math.h +++ b/src/mpl/include/mpl_math.h @@ -12,6 +12,8 @@ extern "C" { #endif /* *INDENT-OFF* */ +#define MPL_DIV_ROUNDUP(total, chunk) ((total + (chunk - 1)) / chunk) + /* Returns the nearest (smaller than or equal to) power of two of a number*/ static inline int MPL_pof2(int number) { From f121a65bb8676a9d12960cf52616a52179788352 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 1 Oct 2021 12:43:43 -0500 Subject: [PATCH 037/607] ch4/ofi: refactor and fix issuing huge reads In the stripping path, we issue multiple fi_read with the same context. This is not safe. Due to critical sections, the access to the context in current code and common providers are serialized, thus the data race issue may not be readily manifested in tests. However, the data will get corrupted if the access is out-of-order, which can happen when the event completion happens in-between issuing. In addition, future provider updates may allow out-of-order progressing. This commit issues multiple fi_read with separately malloc'ed MPIDI_OFI_read_chunk_t, and uses atomic chunk.chunks_outstanding to track completion. With that, we can safely issuing multiple fi_read for non-striping huge message as well, allowing us to unify the two paths. --- src/mpid/ch4/netmod/ofi/ofi_events.c | 8 +- src/mpid/ch4/netmod/ofi/ofi_huge.c | 173 ++++++++++++++------------- src/mpid/ch4/netmod/ofi/ofi_impl.h | 1 + src/mpid/ch4/netmod/ofi/ofi_init.c | 2 +- src/mpid/ch4/netmod/ofi/ofi_recv.h | 2 - src/mpid/ch4/netmod/ofi/ofi_types.h | 10 +- 6 files changed, 99 insertions(+), 97 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_events.c b/src/mpid/ch4/netmod/ofi/ofi_events.c index 4f9c09aab45..8e6ac44cbf3 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_events.c +++ b/src/mpid/ch4/netmod/ofi/ofi_events.c @@ -509,14 +509,14 @@ int MPIDI_OFI_dispatch_function(int vni, struct fi_cq_tagged_entry *wc, MPIR_Req mpi_errno = ssend_ack_event(vni, wc, req); break; - case MPIDI_OFI_EVENT_GET_HUGE: - mpi_errno = MPIDI_OFI_get_huge_event(vni, wc, req); - break; - case MPIDI_OFI_EVENT_CHUNK_DONE: mpi_errno = chunk_done_event(vni, wc, req); break; + case MPIDI_OFI_EVENT_HUGE_CHUNK_DONE: + mpi_errno = MPIDI_OFI_huge_chunk_done_event(vni, wc, req); + break; + case MPIDI_OFI_EVENT_INJECT_EMU: mpi_errno = inject_emu_event(vni, wc, req); break; diff --git a/src/mpid/ch4/netmod/ofi/ofi_huge.c b/src/mpid/ch4/netmod/ofi/ofi_huge.c index 5d05f4f87e8..25e26fe6b62 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_huge.c +++ b/src/mpid/ch4/netmod/ofi/ofi_huge.c @@ -29,21 +29,14 @@ static int get_huge(MPIR_Request * rreq) info->msgsize = data_sz; } - if (data_sz < cur_offset) { + if (info->msgsize <= cur_offset) { /* huge message sent to small recv buffer */ mpi_errno = get_huge_complete(rreq); MPIR_ERR_CHECK(mpi_errno); goto fn_exit; } - MPIDI_OFI_huge_recv_t *recv_elem = NULL; - recv_elem = (MPIDI_OFI_huge_recv_t *) MPL_calloc(sizeof(*recv_elem), 1, MPL_MEM_BUFFER); - MPIR_ERR_CHKANDJUMP(recv_elem == NULL, mpi_errno, MPI_ERR_OTHER, "**nomem"); - recv_elem->event_id = MPIDI_OFI_EVENT_GET_HUGE; - recv_elem->localreq = rreq; - recv_elem->cur_offset = cur_offset; - - MPIDI_OFI_get_huge_event(info->vni_dst, NULL, (MPIR_Request *) recv_elem); + MPIDI_OFI_get_huge_event(info->vni_dst, NULL, rreq); fn_exit: return mpi_errno; @@ -305,96 +298,108 @@ static uintptr_t recv_rbase(MPIDI_OFI_huge_remote_info_t * remote_info) * * 3. As the event function when RDMA read (issued here) completes. */ -int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * req) +int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * rreq) { int mpi_errno = MPI_SUCCESS; - MPIDI_OFI_huge_recv_t *recv_elem = (MPIDI_OFI_huge_recv_t *) req; - MPIDI_OFI_huge_remote_info_t *info = MPIDI_OFI_REQUEST(recv_elem->localreq, huge.remote_info); - MPIR_Comm *comm = recv_elem->localreq->comm; - uint64_t remote_key; - size_t bytesLeft, bytesToGet; + MPIDI_OFI_huge_remote_info_t *info = MPIDI_OFI_REQUEST(rreq, huge.remote_info); + MPIR_Comm *comm = rreq->comm; MPIR_FUNC_ENTER; - void *recv_buf = MPIDI_OFI_REQUEST(recv_elem->localreq, util.iov.iov_base); + MPI_Aint cur_offset, bytesLeft; + if (MPIDI_OFI_COMM(rreq->comm).enable_striping) { + cur_offset = MPIDI_OFI_STRIPE_CHUNK_SIZE; + } else { + cur_offset = MPIDI_OFI_global.max_msg_size; + } + bytesLeft = info->msgsize - cur_offset; + + void *recv_buf = MPIDI_OFI_REQUEST(rreq, util.iov.iov_base); + MPI_Aint chunk_size; if (MPIDI_OFI_COMM(comm).enable_striping) { - /* Subtract one stripe_chunk_size because we send the first chunk via a regular message - * instead of the memory region */ - recv_elem->stripe_size = (info->msgsize - MPIDI_OFI_STRIPE_CHUNK_SIZE) - / MPIDI_OFI_global.num_nics; /* striping */ - - if (recv_elem->stripe_size > MPIDI_OFI_global.max_msg_size) { - recv_elem->stripe_size = MPIDI_OFI_global.max_msg_size; - } - if (recv_elem->chunks_outstanding) - recv_elem->chunks_outstanding--; - bytesLeft = info->msgsize - recv_elem->cur_offset; - bytesToGet = (bytesLeft <= recv_elem->stripe_size) ? bytesLeft : recv_elem->stripe_size; + chunk_size = (info->msgsize - MPIDI_OFI_STRIPE_CHUNK_SIZE) / MPIDI_OFI_global.num_nics; + chunk_size = MPL_MIN(chunk_size, MPIDI_OFI_global.max_msg_size); } else { - /* Subtract one max_msg_size because we send the first chunk via a regular message - * instead of the memory region */ - bytesLeft = info->msgsize - recv_elem->cur_offset; - bytesToGet = (bytesLeft <= MPIDI_OFI_global.max_msg_size) ? - bytesLeft : MPIDI_OFI_global.max_msg_size; - } - if (bytesToGet == 0ULL && recv_elem->chunks_outstanding == 0) { - mpi_errno = get_huge_complete(recv_elem->localreq); - MPIR_ERR_CHECK(mpi_errno); - MPL_free(recv_elem); - goto fn_exit; + chunk_size = MPIDI_OFI_global.max_msg_size; } - int vni_src = info->vni_src; - int vni_dst = info->vni_dst; - if (MPIDI_OFI_COMM(comm).enable_striping) { /* if striping enabled */ - if (recv_elem->cur_offset >= MPIDI_OFI_STRIPE_CHUNK_SIZE && bytesLeft > 0) { - for (int nic = 0; nic < MPIDI_OFI_global.num_nics; nic++) { - int ctx_idx = MPIDI_OFI_get_ctx_index(comm, vni_dst, nic); - remote_key = info->rma_keys[nic]; - - bytesLeft = info->msgsize - recv_elem->cur_offset; - if (bytesLeft <= 0) { - break; - } - bytesToGet = - (bytesLeft <= recv_elem->stripe_size) ? bytesLeft : recv_elem->stripe_size; - - /* FIXME: Can we issue concurrent fi_read with the same context? */ - MPIDI_OFI_cntr_incr(recv_elem->comm_ptr, vni_src, nic); - MPIDI_OFI_CALL_RETRY(fi_read(MPIDI_OFI_global.ctx[ctx_idx].tx, (void *) ((char *) recv_buf + recv_elem->cur_offset), /* local buffer */ - bytesToGet, /* bytes */ - NULL, /* descriptor */ - MPIDI_OFI_comm_to_phys(comm, info->origin_rank, nic, vni_dst, vni_src), recv_rbase(info) + recv_elem->cur_offset, /* remote maddr */ - remote_key, /* Key */ - (void *) &recv_elem->context), nic, /* Context */ - rdma_readfrom, FALSE); - MPIR_T_PVAR_COUNTER_INC(MULTINIC, nic_recvd_bytes_count[nic], bytesToGet); - MPIR_T_PVAR_COUNTER_INC(MULTINIC, striped_nic_recvd_bytes_count[nic], bytesToGet); - recv_elem->cur_offset += bytesToGet; - recv_elem->chunks_outstanding++; - } - } - } else { - int nic = 0; - int ctx_idx = MPIDI_OFI_get_ctx_index(comm, vni_src, nic); - remote_key = info->rma_keys[nic]; - MPIDI_OFI_cntr_incr(comm, vni_src, nic); - MPIDI_OFI_CALL_RETRY(fi_read(MPIDI_OFI_global.ctx[ctx_idx].tx, /* endpoint */ - (void *) ((char *) recv_buf + recv_elem->cur_offset), /* local buffer */ - bytesToGet, /* bytes */ - NULL, /* descriptor */ - MPIDI_OFI_comm_to_phys(comm, info->origin_rank, nic, vni_src, vni_dst), /* Destination */ - recv_rbase(info) + recv_elem->cur_offset, /* remote maddr */ - remote_key, /* Key */ - (void *) &recv_elem->context), vni_src, rdma_readfrom, /* Context */ - FALSE); + int num_chunks = MPL_DIV_ROUNDUP(bytesLeft, chunk_size); + + /* note: this is receiver read from sender */ + int vni_remote = info->vni_src; + int vni_local = info->vni_dst; + + /* We'll issue multiple fi_read for every chunks. All the chunks will be tracked by a + * chunks_outstanding counter. */ + /* NOTE: there is a possibility completion happens in between issuing fi_read (due to + * MPIDI_OFI_CALL_RETRY). Thus we need initialize chunks_outstanding before issuing any + * chunk */ + /* allocate and initialize cc_ptr. It will be freed by event completion when it reaches 0 */ + MPIR_cc_t *cc_ptr; + cc_ptr = MPL_malloc(sizeof(MPIR_cc_t), MPL_MEM_OTHER); + MPIR_cc_set(cc_ptr, num_chunks); + + int issued_chunks = 0; + + int nic = 0; + while (bytesLeft > 0) { + int ctx_idx = MPIDI_OFI_get_ctx_index(comm, vni_local, nic); + fi_addr_t addr = + MPIDI_OFI_comm_to_phys(comm, info->origin_rank, nic, vni_local, vni_remote); + uint64_t remote_key = info->rma_keys[nic]; + + MPI_Aint bytesToGet = MPL_MIN(chunk_size, bytesLeft); + + MPIDI_OFI_read_chunk_t *chunk = MPL_malloc(sizeof(MPIDI_OFI_read_chunk_t), MPL_MEM_OTHER); + chunk->event_id = MPIDI_OFI_EVENT_HUGE_CHUNK_DONE; + chunk->localreq = rreq; + chunk->chunks_outstanding = cc_ptr; + + MPIDI_OFI_cntr_incr(comm, vni_local, nic); + MPIDI_OFI_CALL_RETRY(fi_read(MPIDI_OFI_global.ctx[ctx_idx].tx, + (void *) ((char *) recv_buf + cur_offset), + bytesToGet, NULL, addr, recv_rbase(info) + cur_offset, + remote_key, (void *) &chunk->context), + vni_local, rdma_readfrom, FALSE); MPIR_T_PVAR_COUNTER_INC(MULTINIC, nic_recvd_bytes_count[nic], bytesToGet); - recv_elem->cur_offset += bytesToGet; + if (MPIDI_OFI_COMM(comm).enable_striping) { + MPIR_T_PVAR_COUNTER_INC(MULTINIC, striped_nic_recvd_bytes_count[nic], bytesToGet); + /* round-robin to next nic */ + nic = (nic + 1) % MPIDI_OFI_global.num_nics; + } + + issued_chunks++; + cur_offset += bytesToGet; + bytesLeft -= bytesToGet; } + MPIR_Assert(issued_chunks == num_chunks); + fn_exit: MPIR_FUNC_EXIT; return mpi_errno; fn_fail: goto fn_exit; } + +int MPIDI_OFI_huge_chunk_done_event(int vni, struct fi_cq_tagged_entry *wc, void *req) +{ + int mpi_errno = MPI_SUCCESS; + MPIDI_OFI_read_chunk_t *chunk_req = (MPIDI_OFI_read_chunk_t *) req; + + int c; + MPIR_cc_decr(chunk_req->chunks_outstanding, &c); + + if (c == 0) { + MPL_free(chunk_req->chunks_outstanding); + mpi_errno = get_huge_complete(chunk_req->localreq); + MPIR_ERR_CHECK(mpi_errno); + } + + MPL_free(chunk_req); + + fn_exit: + return mpi_errno; + fn_fail: + goto fn_exit; +} diff --git a/src/mpid/ch4/netmod/ofi/ofi_impl.h b/src/mpid/ch4/netmod/ofi/ofi_impl.h index 95761dc0126..9897350762b 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_impl.h +++ b/src/mpid/ch4/netmod/ofi/ofi_impl.h @@ -312,6 +312,7 @@ int MPIDI_OFI_recv_huge_control(int vni, MPIR_Context_id_t comm_id, int rank, in MPIDI_OFI_huge_remote_info_t * info); int MPIDI_OFI_peek_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * rreq); int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * req); +int MPIDI_OFI_huge_chunk_done_event(int vni, struct fi_cq_tagged_entry *wc, void *req); int MPIDI_OFI_control_handler(void *am_hdr, void *data, MPI_Aint data_sz, uint32_t attr, MPIR_Request ** req); int MPIDI_OFI_am_rdma_read_ack_handler(void *am_hdr, void *data, diff --git a/src/mpid/ch4/netmod/ofi/ofi_init.c b/src/mpid/ch4/netmod/ofi/ofi_init.c index ba95cbd7cb9..51f8451e8a7 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_init.c +++ b/src/mpid/ch4/netmod/ofi/ofi_init.c @@ -528,7 +528,7 @@ int MPIDI_OFI_init_local(int *tag_bits) MPL_COMPILE_TIME_ASSERT(offsetof(struct MPIR_Request, dev.ch4.netmod) == offsetof(MPIDI_OFI_chunk_request, context)); MPL_COMPILE_TIME_ASSERT(offsetof(struct MPIR_Request, dev.ch4.netmod) == - offsetof(MPIDI_OFI_huge_recv_t, context)); + offsetof(MPIDI_OFI_read_chunk_t, context)); MPL_COMPILE_TIME_ASSERT(offsetof(struct MPIR_Request, dev.ch4.netmod) == offsetof(MPIDI_OFI_am_repost_request_t, context)); MPL_COMPILE_TIME_ASSERT(offsetof(struct MPIR_Request, dev.ch4.netmod) == diff --git a/src/mpid/ch4/netmod/ofi/ofi_recv.h b/src/mpid/ch4/netmod/ofi/ofi_recv.h index 3a4d389af96..769baabcefe 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_recv.h +++ b/src/mpid/ch4/netmod/ofi/ofi_recv.h @@ -238,8 +238,6 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_do_irecv(void *buf, data_sz = MPIDI_OFI_global.max_msg_size; } else if (MPIDI_OFI_COMM(comm).enable_striping && (data_sz >= MPIDI_OFI_global.stripe_threshold)) { - MPIDI_OFI_huge_recv_t *huge_recv = (MPIDI_OFI_huge_recv_t *) rreq; - huge_recv->chunks_outstanding = 0; MPIDI_OFI_REQUEST(rreq, event_id) = MPIDI_OFI_EVENT_RECV_HUGE; /* Receive has to be posted with size MPIDI_OFI_global.stripe_threshold to handle underflow */ data_sz = MPIDI_OFI_global.stripe_threshold; diff --git a/src/mpid/ch4/netmod/ofi/ofi_types.h b/src/mpid/ch4/netmod/ofi/ofi_types.h index e399ae91f6d..f04c685a8df 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_types.h +++ b/src/mpid/ch4/netmod/ofi/ofi_types.h @@ -148,6 +148,7 @@ enum { MPIDI_OFI_EVENT_SSEND_ACK, MPIDI_OFI_EVENT_GET_HUGE, MPIDI_OFI_EVENT_CHUNK_DONE, + MPIDI_OFI_EVENT_HUGE_CHUNK_DONE, MPIDI_OFI_EVENT_INJECT_EMU, MPIDI_OFI_EVENT_DYNPROC_DONE, MPIDI_OFI_EVENT_ACCEPT_PROBE @@ -499,16 +500,13 @@ typedef struct MPIDI_OFI_target_mr { uint64_t mr_key; } MPIDI_OFI_target_mr_t; -typedef struct MPIDI_OFI_huge_recv { +typedef struct MPIDI_OFI_read_chunk { char pad[MPIDI_REQUEST_HDR_SIZE]; struct fi_context context[MPIDI_OFI_CONTEXT_STRUCTS]; /* fixed field, do not move */ int event_id; /* fixed field, do not move */ - size_t cur_offset; - size_t stripe_size; - int chunks_outstanding; - MPIR_Comm *comm_ptr; MPIR_Request *localreq; -} MPIDI_OFI_huge_recv_t; + MPIR_cc_t *chunks_outstanding; +} MPIDI_OFI_read_chunk_t; /* The list of posted huge receives that haven't been matched yet. These need * to get matched up when handling the control message that starts transferring From ee4ae82526754c3492410ff045150075335b9cf9 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 1 Oct 2021 16:16:32 -0500 Subject: [PATCH 038/607] ch4/ofi: rename and move MPIDI_OFI_get_huge_event Rename MPIDI_OFI_get_huge_event info static function get_huge_issue_read now that this function only issues fi_read. Move the static functions together for better code organization. --- src/mpid/ch4/netmod/ofi/ofi_huge.c | 200 ++++++++++++++--------------- src/mpid/ch4/netmod/ofi/ofi_impl.h | 1 - 2 files changed, 95 insertions(+), 106 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_huge.c b/src/mpid/ch4/netmod/ofi/ofi_huge.c index 25e26fe6b62..631da654656 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_huge.c +++ b/src/mpid/ch4/netmod/ofi/ofi_huge.c @@ -8,6 +8,7 @@ #include "ofi_events.h" static int get_huge(MPIR_Request * rreq); +static int get_huge_issue_read(MPIR_Request * rreq); static int get_huge_complete(MPIR_Request * rreq); static int get_huge(MPIR_Request * rreq) @@ -36,7 +37,7 @@ static int get_huge(MPIR_Request * rreq) goto fn_exit; } - MPIDI_OFI_get_huge_event(info->vni_dst, NULL, rreq); + get_huge_issue_read(rreq); fn_exit: return mpi_errno; @@ -44,6 +45,99 @@ static int get_huge(MPIR_Request * rreq) goto fn_exit; } +static uintptr_t recv_rbase(MPIDI_OFI_huge_remote_info_t * remote_info) +{ + if (!MPIDI_OFI_ENABLE_MR_VIRT_ADDRESS) { + return 0; + } else { + return (uintptr_t) remote_info->send_buf; + } +} + +static int get_huge_issue_read(MPIR_Request * rreq) +{ + int mpi_errno = MPI_SUCCESS; + MPIDI_OFI_huge_remote_info_t *info = MPIDI_OFI_REQUEST(rreq, huge.remote_info); + MPIR_Comm *comm = rreq->comm; + MPIR_FUNC_ENTER; + + MPI_Aint cur_offset, bytesLeft; + if (MPIDI_OFI_COMM(rreq->comm).enable_striping) { + cur_offset = MPIDI_OFI_STRIPE_CHUNK_SIZE; + } else { + cur_offset = MPIDI_OFI_global.max_msg_size; + } + bytesLeft = info->msgsize - cur_offset; + + void *recv_buf = MPIDI_OFI_REQUEST(rreq, util.iov.iov_base); + + MPI_Aint chunk_size; + if (MPIDI_OFI_COMM(comm).enable_striping) { + chunk_size = (info->msgsize - MPIDI_OFI_STRIPE_CHUNK_SIZE) / MPIDI_OFI_global.num_nics; + chunk_size = MPL_MIN(chunk_size, MPIDI_OFI_global.max_msg_size); + } else { + chunk_size = MPIDI_OFI_global.max_msg_size; + } + + int num_chunks = MPL_DIV_ROUNDUP(bytesLeft, chunk_size); + + /* note: this is receiver read from sender */ + int vni_remote = info->vni_src; + int vni_local = info->vni_dst; + + /* We'll issue multiple fi_read for every chunks. All the chunks will be tracked by a + * chunks_outstanding counter. */ + /* NOTE: there is a possibility completion happens in between issuing fi_read (due to + * MPIDI_OFI_CALL_RETRY). Thus we need initialize chunks_outstanding before issuing any + * chunk */ + /* allocate and initialize cc_ptr. It will be freed by event completion when it reaches 0 */ + MPIR_cc_t *cc_ptr; + cc_ptr = MPL_malloc(sizeof(MPIR_cc_t), MPL_MEM_OTHER); + MPIR_cc_set(cc_ptr, num_chunks); + + int issued_chunks = 0; + + int nic = 0; + while (bytesLeft > 0) { + int ctx_idx = MPIDI_OFI_get_ctx_index(comm, vni_local, nic); + fi_addr_t addr = + MPIDI_OFI_comm_to_phys(comm, info->origin_rank, nic, vni_local, vni_remote); + uint64_t remote_key = info->rma_keys[nic]; + + MPI_Aint bytesToGet = MPL_MIN(chunk_size, bytesLeft); + + MPIDI_OFI_read_chunk_t *chunk = MPL_malloc(sizeof(MPIDI_OFI_read_chunk_t), MPL_MEM_OTHER); + chunk->event_id = MPIDI_OFI_EVENT_HUGE_CHUNK_DONE; + chunk->localreq = rreq; + chunk->chunks_outstanding = cc_ptr; + + MPIDI_OFI_cntr_incr(comm, vni_local, nic); + MPIDI_OFI_CALL_RETRY(fi_read(MPIDI_OFI_global.ctx[ctx_idx].tx, + (void *) ((char *) recv_buf + cur_offset), + bytesToGet, NULL, addr, recv_rbase(info) + cur_offset, + remote_key, (void *) &chunk->context), + vni_local, rdma_readfrom, FALSE); + MPIR_T_PVAR_COUNTER_INC(MULTINIC, nic_recvd_bytes_count[nic], bytesToGet); + if (MPIDI_OFI_COMM(comm).enable_striping) { + MPIR_T_PVAR_COUNTER_INC(MULTINIC, striped_nic_recvd_bytes_count[nic], bytesToGet); + /* round-robin to next nic */ + nic = (nic + 1) % MPIDI_OFI_global.num_nics; + } + + issued_chunks++; + cur_offset += bytesToGet; + bytesLeft -= bytesToGet; + } + + MPIR_Assert(issued_chunks == num_chunks); + + fn_exit: + MPIR_FUNC_EXIT; + return mpi_errno; + fn_fail: + goto fn_exit; +} + static int get_huge_complete(MPIR_Request * rreq) { int mpi_errno = MPI_SUCCESS; @@ -278,110 +372,6 @@ int MPIDI_OFI_peek_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque goto fn_exit; } -static uintptr_t recv_rbase(MPIDI_OFI_huge_remote_info_t * remote_info) -{ - if (!MPIDI_OFI_ENABLE_MR_VIRT_ADDRESS) { - return 0; - } else { - return (uintptr_t) remote_info->send_buf; - } -} - -/* Note: MPIDI_OFI_get_huge_event is invoked from three places -- - * 1. In MPIDI_OFI_recv_huge_event, when recv buffer is matched and first chunk received, and - * when control message (with remote info) has also been received. - * 2. In MPIDI_OFI_recv_huge_control, as a callback when control message is received, and - * when first chunk has been matched and received. - * - * MPIDI_OFI_recv_huge_event will fill the local request information, and - * MPIDI_OFI_recv_huge_control will fill the remote (sender) information. Lastly -- - * - * 3. As the event function when RDMA read (issued here) completes. - */ -int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * rreq) -{ - int mpi_errno = MPI_SUCCESS; - MPIDI_OFI_huge_remote_info_t *info = MPIDI_OFI_REQUEST(rreq, huge.remote_info); - MPIR_Comm *comm = rreq->comm; - MPIR_FUNC_ENTER; - - MPI_Aint cur_offset, bytesLeft; - if (MPIDI_OFI_COMM(rreq->comm).enable_striping) { - cur_offset = MPIDI_OFI_STRIPE_CHUNK_SIZE; - } else { - cur_offset = MPIDI_OFI_global.max_msg_size; - } - bytesLeft = info->msgsize - cur_offset; - - void *recv_buf = MPIDI_OFI_REQUEST(rreq, util.iov.iov_base); - - MPI_Aint chunk_size; - if (MPIDI_OFI_COMM(comm).enable_striping) { - chunk_size = (info->msgsize - MPIDI_OFI_STRIPE_CHUNK_SIZE) / MPIDI_OFI_global.num_nics; - chunk_size = MPL_MIN(chunk_size, MPIDI_OFI_global.max_msg_size); - } else { - chunk_size = MPIDI_OFI_global.max_msg_size; - } - - int num_chunks = MPL_DIV_ROUNDUP(bytesLeft, chunk_size); - - /* note: this is receiver read from sender */ - int vni_remote = info->vni_src; - int vni_local = info->vni_dst; - - /* We'll issue multiple fi_read for every chunks. All the chunks will be tracked by a - * chunks_outstanding counter. */ - /* NOTE: there is a possibility completion happens in between issuing fi_read (due to - * MPIDI_OFI_CALL_RETRY). Thus we need initialize chunks_outstanding before issuing any - * chunk */ - /* allocate and initialize cc_ptr. It will be freed by event completion when it reaches 0 */ - MPIR_cc_t *cc_ptr; - cc_ptr = MPL_malloc(sizeof(MPIR_cc_t), MPL_MEM_OTHER); - MPIR_cc_set(cc_ptr, num_chunks); - - int issued_chunks = 0; - - int nic = 0; - while (bytesLeft > 0) { - int ctx_idx = MPIDI_OFI_get_ctx_index(comm, vni_local, nic); - fi_addr_t addr = - MPIDI_OFI_comm_to_phys(comm, info->origin_rank, nic, vni_local, vni_remote); - uint64_t remote_key = info->rma_keys[nic]; - - MPI_Aint bytesToGet = MPL_MIN(chunk_size, bytesLeft); - - MPIDI_OFI_read_chunk_t *chunk = MPL_malloc(sizeof(MPIDI_OFI_read_chunk_t), MPL_MEM_OTHER); - chunk->event_id = MPIDI_OFI_EVENT_HUGE_CHUNK_DONE; - chunk->localreq = rreq; - chunk->chunks_outstanding = cc_ptr; - - MPIDI_OFI_cntr_incr(comm, vni_local, nic); - MPIDI_OFI_CALL_RETRY(fi_read(MPIDI_OFI_global.ctx[ctx_idx].tx, - (void *) ((char *) recv_buf + cur_offset), - bytesToGet, NULL, addr, recv_rbase(info) + cur_offset, - remote_key, (void *) &chunk->context), - vni_local, rdma_readfrom, FALSE); - MPIR_T_PVAR_COUNTER_INC(MULTINIC, nic_recvd_bytes_count[nic], bytesToGet); - if (MPIDI_OFI_COMM(comm).enable_striping) { - MPIR_T_PVAR_COUNTER_INC(MULTINIC, striped_nic_recvd_bytes_count[nic], bytesToGet); - /* round-robin to next nic */ - nic = (nic + 1) % MPIDI_OFI_global.num_nics; - } - - issued_chunks++; - cur_offset += bytesToGet; - bytesLeft -= bytesToGet; - } - - MPIR_Assert(issued_chunks == num_chunks); - - fn_exit: - MPIR_FUNC_EXIT; - return mpi_errno; - fn_fail: - goto fn_exit; -} - int MPIDI_OFI_huge_chunk_done_event(int vni, struct fi_cq_tagged_entry *wc, void *req) { int mpi_errno = MPI_SUCCESS; diff --git a/src/mpid/ch4/netmod/ofi/ofi_impl.h b/src/mpid/ch4/netmod/ofi/ofi_impl.h index 9897350762b..397aade7adf 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_impl.h +++ b/src/mpid/ch4/netmod/ofi/ofi_impl.h @@ -311,7 +311,6 @@ int MPIDI_OFI_recv_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Reque int MPIDI_OFI_recv_huge_control(int vni, MPIR_Context_id_t comm_id, int rank, int tag, MPIDI_OFI_huge_remote_info_t * info); int MPIDI_OFI_peek_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * rreq); -int MPIDI_OFI_get_huge_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * req); int MPIDI_OFI_huge_chunk_done_event(int vni, struct fi_cq_tagged_entry *wc, void *req); int MPIDI_OFI_control_handler(void *am_hdr, void *data, MPI_Aint data_sz, uint32_t attr, MPIR_Request ** req); From bc542b5ca25ee4434894cdbc633ff9ef4898d655 Mon Sep 17 00:00:00 2001 From: Rob Latham Date: Tue, 5 Oct 2021 16:02:40 -0500 Subject: [PATCH 039/607] FFLAGS no longer used gcc-10 wants '-fallow-mismatched-args'. Stop telling users to pass that through an env variable MPICH will ignore. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index c9d1ca0946c..9bd7b309cec 100644 --- a/configure.ac +++ b/configure.ac @@ -1989,7 +1989,7 @@ if test "$enable_f77" = "yes" ; then # that turns off checking for *everything* is not something that # configure should do - if the user wants this, they can follow # the instructions in the following error message. - AC_MSG_ERROR([The Fortran compiler $F77 does not accept programs that call the same routine with arguments of different types without the option $addarg. Rerun configure with FFLAGS=$addarg]) + AC_MSG_ERROR([The Fortran compiler $FC does not accept programs that call the same routine with arguments of different types without the option $addarg. Rerun configure with FCFLAGS=$addarg]) fi bindings="$bindings f77" From 61f68af3d9bceab11aabefe64560c4d5b3def779 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 3 Oct 2021 15:29:40 -0500 Subject: [PATCH 040/607] misc: suppress ubsan warnings in calc contig buffer We calculates contig datatype's buffer using (char *) buf + dt_true_lb. However, on 32-bit system and when buf is MPI_BOTTOM, the dt_true_lb may overflow the assumed type, ptrdiff_t, causing ubsan test failures. Add a macro to fix this case. --- src/include/mpir_misc.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/include/mpir_misc.h b/src/include/mpir_misc.h index 11578ac9c21..b95d9c36103 100644 --- a/src/include/mpir_misc.h +++ b/src/include/mpir_misc.h @@ -66,6 +66,14 @@ int MPIR_Ilocalcopy(const void *sendbuf, MPI_Aint sendcount, MPI_Datatype sendty void *recvbuf, MPI_Aint recvcount, MPI_Datatype recvtype, MPIR_Typerep_req * typereq_req); +/* Contiguous datatype calculates buffer address with `(char *) buf + dt_true_lb`. + * However, dt_true_lb is treated as ptrdiff_t (signed), and when buf is MPI_BOTTOM + * and on 32-bit systems, ubsan will warn the latter overflow. Cast to uintptr_t + * to work around. + */ +#define MPIR_get_contig_ptr(buf, true_lb) \ + (void *) ((uintptr_t) buf + (uintptr_t) (true_lb)) + /*@ MPIR_Add_finalize - Add a routine to be called when MPI_Finalize is invoked + routine - Routine to call From fc7f806be96c01bd2b2a759ff67d0afd2f304605 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 3 Oct 2021 15:50:06 -0500 Subject: [PATCH 041/607] mpir: use MPIR_get_contig_ptr To suppress ubsan warnings on 32-bit systems. --- ...ntra_scatter_recursive_doubling_allgather.c | 2 +- .../bcast/bcast_intra_scatter_ring_allgather.c | 2 +- ...ched_scatter_recursive_doubling_allgather.c | 2 +- ...ibcast_intra_sched_scatter_ring_allgather.c | 2 +- .../ibcast/ibcast_tsp_scatterv_allgatherv.c | 2 +- .../typerep/src/typerep_dataloop_pack.c | 4 ++-- .../datatype/typerep/src/typerep_yaksa_pack.c | 12 ++++++------ src/mpi/misc/utils.c | 18 ++++++++++-------- 8 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/mpi/coll/bcast/bcast_intra_scatter_recursive_doubling_allgather.c b/src/mpi/coll/bcast/bcast_intra_scatter_recursive_doubling_allgather.c index 64173eab7f3..911855a5194 100644 --- a/src/mpi/coll/bcast/bcast_intra_scatter_recursive_doubling_allgather.c +++ b/src/mpi/coll/bcast/bcast_intra_scatter_recursive_doubling_allgather.c @@ -67,7 +67,7 @@ int MPIR_Bcast_intra_scatter_recursive_doubling_allgather(void *buffer, /* contiguous. no need to pack. */ MPIR_Type_get_true_extent_impl(datatype, &true_lb, &true_extent); - tmp_buf = (char *) buffer + true_lb; + tmp_buf = MPIR_get_contig_ptr(buffer, true_lb); } else { MPIR_CHKLMEM_MALLOC(tmp_buf, void *, nbytes, mpi_errno, "tmp_buf", MPL_MEM_BUFFER); diff --git a/src/mpi/coll/bcast/bcast_intra_scatter_ring_allgather.c b/src/mpi/coll/bcast/bcast_intra_scatter_ring_allgather.c index de426824b70..8db01feb366 100644 --- a/src/mpi/coll/bcast/bcast_intra_scatter_ring_allgather.c +++ b/src/mpi/coll/bcast/bcast_intra_scatter_ring_allgather.c @@ -59,7 +59,7 @@ int MPIR_Bcast_intra_scatter_ring_allgather(void *buffer, /* contiguous. no need to pack. */ MPIR_Type_get_true_extent_impl(datatype, &true_lb, &true_extent); - tmp_buf = (char *) buffer + true_lb; + tmp_buf = MPIR_get_contig_ptr(buffer, true_lb); } else { MPIR_CHKLMEM_MALLOC(tmp_buf, void *, nbytes, mpi_errno, "tmp_buf", MPL_MEM_BUFFER); diff --git a/src/mpi/coll/ibcast/ibcast_intra_sched_scatter_recursive_doubling_allgather.c b/src/mpi/coll/ibcast/ibcast_intra_sched_scatter_recursive_doubling_allgather.c index fa5bfa303e6..6359dad81fa 100644 --- a/src/mpi/coll/ibcast/ibcast_intra_sched_scatter_recursive_doubling_allgather.c +++ b/src/mpi/coll/ibcast/ibcast_intra_sched_scatter_recursive_doubling_allgather.c @@ -100,7 +100,7 @@ int MPIR_Ibcast_intra_sched_scatter_recursive_doubling_allgather(void *buffer, M /* contiguous. no need to pack. */ MPIR_Type_get_true_extent_impl(datatype, &true_lb, &true_extent); - tmp_buf = (char *) buffer + true_lb; + tmp_buf = MPIR_get_contig_ptr(buffer, true_lb); } else { if (rank == root) { mpi_errno = MPIR_Sched_copy(buffer, count, datatype, tmp_buf, nbytes, MPI_BYTE, s); diff --git a/src/mpi/coll/ibcast/ibcast_intra_sched_scatter_ring_allgather.c b/src/mpi/coll/ibcast/ibcast_intra_sched_scatter_ring_allgather.c index fbcddb81c38..3572b97326c 100644 --- a/src/mpi/coll/ibcast/ibcast_intra_sched_scatter_ring_allgather.c +++ b/src/mpi/coll/ibcast/ibcast_intra_sched_scatter_ring_allgather.c @@ -69,7 +69,7 @@ int MPIR_Ibcast_intra_sched_scatter_ring_allgather(void *buffer, MPI_Aint count, /* contiguous, no need to pack. */ MPIR_Type_get_true_extent_impl(datatype, &true_lb, &true_extent); - tmp_buf = (char *) buffer + true_lb; + tmp_buf = MPIR_get_contig_ptr(buffer, true_lb); } else { if (rank == root) { mpi_errno = MPIR_Sched_copy(buffer, count, datatype, tmp_buf, nbytes, MPI_BYTE, s); diff --git a/src/mpi/coll/ibcast/ibcast_tsp_scatterv_allgatherv.c b/src/mpi/coll/ibcast/ibcast_tsp_scatterv_allgatherv.c index 93dd0d60460..edb72de0852 100644 --- a/src/mpi/coll/ibcast/ibcast_tsp_scatterv_allgatherv.c +++ b/src/mpi/coll/ibcast/ibcast_tsp_scatterv_allgatherv.c @@ -74,7 +74,7 @@ int MPIR_TSP_Ibcast_sched_intra_scatterv_allgatherv(void *buffer, MPI_Aint count if (is_contig) { /* contiguous. no need to pack. */ - tmp_buf = (char *) buffer + true_lb; + tmp_buf = MPIR_get_contig_ptr(buffer, true_lb); } else { tmp_buf = (void *) MPIR_TSP_sched_malloc(nbytes, sched); diff --git a/src/mpi/datatype/typerep/src/typerep_dataloop_pack.c b/src/mpi/datatype/typerep/src/typerep_dataloop_pack.c index 898dc189dfa..81d29002dfd 100644 --- a/src/mpi/datatype/typerep/src/typerep_dataloop_pack.c +++ b/src/mpi/datatype/typerep/src/typerep_dataloop_pack.c @@ -59,7 +59,7 @@ int MPIR_Typerep_ipack(const void *inbuf, MPI_Aint incount, MPI_Datatype datatyp /* Handle contig case quickly */ if (contig) { - MPIR_Memcpy(outbuf, (char *) inbuf + dt_true_lb + inoffset, data_sz); + MPIR_Memcpy(outbuf, MPIR_get_contig_ptr(inbuf, dt_true_lb + inoffset), data_sz); *actual_pack_bytes = data_sz; } else { segp = MPIR_Segment_alloc(inbuf, incount, datatype); @@ -126,7 +126,7 @@ int MPIR_Typerep_iunpack(const void *inbuf, MPI_Aint insize, /* Handle contig case quickly */ if (contig) { - MPIR_Memcpy((char *) outbuf + dt_true_lb + outoffset, inbuf, data_sz); + MPIR_Memcpy(MPIR_get_contig_ptr(outbuf, dt_true_lb + outoffset), inbuf, data_sz); *actual_unpack_bytes = data_sz; } else { segp = MPIR_Segment_alloc(outbuf, outcount, datatype); diff --git a/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c b/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c index 8ce53f7b8b4..e05b3d77adb 100644 --- a/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c +++ b/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c @@ -139,7 +139,7 @@ static int typerep_do_pack(const void *inbuf, MPI_Aint incount, MPI_Datatype dat MPIR_Datatype *dtp; MPIR_Datatype_get_ptr(datatype, dtp); is_contig = dtp->is_contig; - inbuf_ptr = (const char *) inbuf + dtp->true_lb; + inbuf_ptr = MPIR_get_contig_ptr(inbuf, dtp->true_lb); total_size = incount * dtp->size; } @@ -153,7 +153,7 @@ static int typerep_do_pack(const void *inbuf, MPI_Aint incount, MPI_Datatype dat (outattr.type == MPL_GPU_POINTER_UNREGISTERED_HOST || outattr.type == MPL_GPU_POINTER_REGISTERED_HOST)) { *actual_pack_bytes = MPL_MIN(total_size - inoffset, max_pack_bytes); - MPIR_Memcpy(outbuf, (const char *) inbuf_ptr + inoffset, *actual_pack_bytes); + MPIR_Memcpy(outbuf, MPIR_get_contig_ptr(inbuf_ptr, inoffset), *actual_pack_bytes); goto fn_exit; } @@ -262,7 +262,7 @@ static int typerep_do_unpack(const void *inbuf, MPI_Aint insize, void *outbuf, M MPIR_Datatype *dtp; MPIR_Datatype_get_ptr(datatype, dtp); is_contig = dtp->is_contig; - outbuf_ptr = (char *) outbuf + dtp->true_lb; + outbuf_ptr = MPIR_get_contig_ptr(outbuf, dtp->true_lb); total_size = outcount * dtp->size; } @@ -276,7 +276,7 @@ static int typerep_do_unpack(const void *inbuf, MPI_Aint insize, void *outbuf, M (outattr.type == MPL_GPU_POINTER_UNREGISTERED_HOST || outattr.type == MPL_GPU_POINTER_REGISTERED_HOST)) { *actual_unpack_bytes = MPL_MIN(total_size - outoffset, insize); - MPIR_Memcpy((char *) outbuf_ptr + outoffset, inbuf, *actual_unpack_bytes); + MPIR_Memcpy(MPIR_get_contig_ptr(outbuf_ptr, outoffset), inbuf, *actual_unpack_bytes); goto fn_exit; } @@ -467,12 +467,12 @@ int MPIR_Typerep_op(void *source_buf, MPI_Aint source_count, MPI_Datatype source op, mapped_device); } else if (source_is_contig) { MPIR_Type_get_true_extent_impl(source_dtp, &true_lb, &true_extent); - void *addr = (char *) source_buf + true_lb; + void *addr = MPIR_get_contig_ptr(source_buf, true_lb); mpi_errno = typerep_op_unpack(addr, target_buf, target_count, target_dtp, op, mapped_device); } else if (target_is_contig) { MPIR_Type_get_true_extent_impl(target_dtp, &true_lb, &true_extent); - void *addr = (char *) target_buf + true_lb; + void *addr = MPIR_get_contig_ptr(target_buf, true_lb); mpi_errno = typerep_op_pack(source_buf, addr, source_count, source_dtp, op, mapped_device); } else { diff --git a/src/mpi/misc/utils.c b/src/mpi/misc/utils.c index 72044442296..ebd435c7251 100644 --- a/src/mpi/misc/utils.c +++ b/src/mpi/misc/utils.c @@ -58,22 +58,24 @@ static int do_localcopy(const void *sendbuf, MPI_Aint sendcount, MPI_Datatype se if (sendtype_iscontig) { MPI_Aint actual_unpack_bytes; if (typereq_req) { - MPIR_Typerep_iunpack((char *) sendbuf + sendtype_true_lb, copy_sz, recvbuf, recvcount, - recvtype, 0, &actual_unpack_bytes, typereq_req); + MPIR_Typerep_iunpack(MPIR_get_contig_ptr(sendbuf, sendtype_true_lb), copy_sz, recvbuf, + recvcount, recvtype, 0, &actual_unpack_bytes, typereq_req); } else { - MPIR_Typerep_unpack((char *) sendbuf + sendtype_true_lb, copy_sz, recvbuf, recvcount, - recvtype, 0, &actual_unpack_bytes); + MPIR_Typerep_unpack(MPIR_get_contig_ptr(sendbuf, sendtype_true_lb), copy_sz, recvbuf, + recvcount, recvtype, 0, &actual_unpack_bytes); } MPIR_ERR_CHKANDJUMP(actual_unpack_bytes != copy_sz, mpi_errno, MPI_ERR_TYPE, "**dtypemismatch"); } else if (recvtype_iscontig) { MPI_Aint actual_pack_bytes; if (typereq_req) { - MPIR_Typerep_ipack(sendbuf, sendcount, sendtype, 0, (char *) recvbuf + recvtype_true_lb, - copy_sz, &actual_pack_bytes, typereq_req); + MPIR_Typerep_ipack(sendbuf, sendcount, sendtype, 0, + MPIR_get_contig_ptr(recvbuf, recvtype_true_lb), copy_sz, + &actual_pack_bytes, typereq_req); } else { - MPIR_Typerep_pack(sendbuf, sendcount, sendtype, 0, (char *) recvbuf + recvtype_true_lb, - copy_sz, &actual_pack_bytes); + MPIR_Typerep_pack(sendbuf, sendcount, sendtype, 0, + MPIR_get_contig_ptr(recvbuf, recvtype_true_lb), copy_sz, + &actual_pack_bytes); } MPIR_ERR_CHKANDJUMP(actual_pack_bytes != copy_sz, mpi_errno, MPI_ERR_TYPE, "**dtypemismatch"); From 635755f09a8bd0a687d15846c62db546ef7a3178 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 3 Oct 2021 15:44:52 -0500 Subject: [PATCH 042/607] ch3: use MPIR_get_contig_ptr This suppresses ubsan errors on 32-bit system when buf is 0. --- src/mpi/datatype/typerep/dataloop/looputil.c | 8 ++++---- .../ch3/channels/nemesis/netmod/ofi/ofi_tagged_template.c | 6 +++--- src/mpid/ch3/include/mpid_rma_issue.h | 6 ++---- src/mpid/ch3/include/mpid_rma_shm.h | 2 +- src/mpid/ch3/src/ch3u_buffer.c | 8 +++----- src/mpid/ch3/src/ch3u_eager.c | 4 +--- src/mpid/ch3/src/ch3u_eagersync.c | 2 +- src/mpid/ch3/src/ch3u_handle_recv_pkt.c | 8 +++----- src/mpid/ch3/src/ch3u_handle_recv_req.c | 4 ++-- src/mpid/ch3/src/ch3u_request.c | 2 +- src/mpid/ch3/src/ch3u_rma_ops.c | 8 ++++---- src/mpid/ch3/src/ch3u_rndv.c | 2 +- src/mpid/ch3/src/mpid_irsend.c | 2 +- src/mpid/ch3/src/mpid_isend.c | 2 +- src/mpid/ch3/src/mpid_rsend.c | 2 +- src/mpid/ch3/src/mpid_send.c | 4 ++-- 16 files changed, 31 insertions(+), 39 deletions(-) diff --git a/src/mpi/datatype/typerep/dataloop/looputil.c b/src/mpi/datatype/typerep/dataloop/looputil.c index 44b7ece3b1e..670b8bff9e9 100644 --- a/src/mpi/datatype/typerep/dataloop/looputil.c +++ b/src/mpi/datatype/typerep/dataloop/looputil.c @@ -451,9 +451,9 @@ static int contig_m2m(MPI_Aint * blocks_p, #endif if (paramp->direction == M2M_TO_USERBUF) { - MPIR_Memcpy((char *) paramp->userbuf + rel_off, paramp->streambuf, size); + MPIR_Memcpy(MPIR_get_contig_ptr(paramp->userbuf, rel_off), paramp->streambuf, size); } else { - MPIR_Memcpy(paramp->streambuf, (char *) paramp->userbuf + rel_off, size); + MPIR_Memcpy(paramp->streambuf, MPIR_get_contig_ptr(paramp->userbuf, rel_off), size); } paramp->streambuf += size; return 0; @@ -562,7 +562,7 @@ static int blkidx_m2m(MPI_Aint * blocks_p, MPIR_Assert(curblock < count); - cbufp = (char *) paramp->userbuf + rel_off + offsetarray[curblock]; + cbufp = MPIR_get_contig_ptr(paramp->userbuf, rel_off + offsetarray[curblock]); /* there was some casting going on here at one time but now all types * are promoted to big values */ @@ -620,7 +620,7 @@ static int index_m2m(MPI_Aint * blocks_p, MPIR_Assert(curblock < count); cur_block_sz = blockarray[curblock]; - cbufp = (char *) paramp->userbuf + rel_off + offsetarray[curblock]; + cbufp = MPIR_get_contig_ptr(paramp->userbuf, rel_off + offsetarray[curblock]); if (cur_block_sz > blocks_left) cur_block_sz = blocks_left; diff --git a/src/mpid/ch3/channels/nemesis/netmod/ofi/ofi_tagged_template.c b/src/mpid/ch3/channels/nemesis/netmod/ofi/ofi_tagged_template.c index 79ebad1f4e8..9e92c3858fd 100644 --- a/src/mpid/ch3/channels/nemesis/netmod/ofi/ofi_tagged_template.c +++ b/src/mpid/ch3/channels/nemesis/netmod/ofi/ofi_tagged_template.c @@ -130,7 +130,7 @@ static inline int ADD_SUFFIX(send_normal) (struct MPIDI_VC * vc, #endif sreq->dev.match.parts.tag = match_bits; - send_buffer = (char *) buf + dt_true_lb; + send_buffer = MPIR_get_contig_ptr(buf, dt_true_lb); if (!dt_contig) { send_buffer = (char *) MPL_malloc(data_sz, MPL_MEM_BUFFER); MPIR_ERR_CHKANDJUMP1(send_buffer == NULL, mpi_errno, @@ -263,7 +263,7 @@ ADD_SUFFIX(do_isend) (struct MPIDI_VC * vc, if (should_create_req == MPID_CREATE_REQ) MPID_nem_ofi_create_req_lw(request, 1); - mpi_errno = ADD_SUFFIX(send_lightweight) (vc, (char *) buf + dt_true_lb, data_sz, + mpi_errno = ADD_SUFFIX(send_lightweight) (vc, MPIR_get_contig_ptr(buf, dt_true_lb), data_sz, dest, tag, comm, context_offset); } else mpi_errno = ADD_SUFFIX(send_normal) (vc, buf, count, datatype, dest, tag, comm, @@ -380,7 +380,7 @@ int ADD_SUFFIX(MPID_nem_ofi_recv_posted) (struct MPIDI_VC * vc, struct MPIR_Requ MPIDI_Datatype_get_info(rreq->dev.user_count, rreq->dev.datatype, dt_contig, data_sz, dt_ptr, dt_true_lb); if (dt_contig) { - recv_buffer = (char *) rreq->dev.user_buf + dt_true_lb; + recv_buffer = MPIR_get_contig_ptr(rreq->dev.user_buf, dt_true_lb); } else { recv_buffer = (char *) MPL_malloc(data_sz, MPL_MEM_BUFFER); MPIR_ERR_CHKANDJUMP1(recv_buffer == NULL, mpi_errno, MPI_ERR_OTHER, diff --git a/src/mpid/ch3/include/mpid_rma_issue.h b/src/mpid/ch3/include/mpid_rma_issue.h index 8d531692aae..e0d84f2150e 100644 --- a/src/mpid/ch3/include/mpid_rma_issue.h +++ b/src/mpid/ch3/include/mpid_rma_issue.h @@ -188,8 +188,7 @@ static int issue_from_origin_buffer(MPIDI_RMA_Op_t * rma_op, MPIDI_VC_t * vc, */ if (is_empty_origin == FALSE) { - iov[iovcnt].iov_base = - (void *) ((char *) rma_op->origin_addr + dt_true_lb + stream_offset); + iov[iovcnt].iov_base = MPIR_get_contig_ptr(rma_op->origin_addr, dt_true_lb + stream_offset); iov[iovcnt].iov_len = stream_size; iovcnt++; } @@ -242,8 +241,7 @@ static int issue_from_origin_buffer(MPIDI_RMA_Op_t * rma_op, MPIDI_VC_t * vc, if (is_origin_contig) { /* origin data is contiguous */ if (is_empty_origin == FALSE) { - iov[iovcnt].iov_base = - (void *) ((char *) rma_op->origin_addr + dt_true_lb + stream_offset); + iov[iovcnt].iov_base = MPIR_get_contig_ptr(rma_op->origin_addr, dt_true_lb + stream_offset); iov[iovcnt].iov_len = stream_size; iovcnt++; } diff --git a/src/mpid/ch3/include/mpid_rma_shm.h b/src/mpid/ch3/include/mpid_rma_shm.h index 04234c1f437..95b950f237e 100644 --- a/src/mpid/ch3/include/mpid_rma_shm.h +++ b/src/mpid/ch3/include/mpid_rma_shm.h @@ -311,7 +311,7 @@ static inline int MPIDI_CH3I_Shm_acc_op(const void *origin_addr, int origin_coun MPIDI_CH3I_SHM_MUTEX_LOCK(win_ptr); } mpi_errno = do_accumulate_op((void *) origin_addr, origin_count, origin_datatype, - (void *) ((char *) base + disp_unit * target_disp), + MPIR_get_contig_ptr(base, disp_unit * target_disp), target_count, target_datatype, 0, op, MPIDI_RMA_ACC_SRCBUF_DEFAULT); if (shm_op) { diff --git a/src/mpid/ch3/src/ch3u_buffer.c b/src/mpid/ch3/src/ch3u_buffer.c index 36c42a698c3..d581b914d24 100644 --- a/src/mpid/ch3/src/ch3u_buffer.c +++ b/src/mpid/ch3/src/ch3u_buffer.c @@ -66,15 +66,13 @@ void MPIDI_CH3U_Buffer_copy( if (sdt_contig && rdt_contig) { - MPIR_FUNC_ENTER; - MPIR_Memcpy((char *)rbuf + rdt_true_lb, (const char *)sbuf + sdt_true_lb, sdata_sz); - MPIR_FUNC_EXIT; + MPIR_Memcpy(MPIR_get_contig_ptr(rbuf, rdt_true_lb), MPIR_get_contig_ptr(sbuf, sdt_true_lb), sdata_sz); *rsz = sdata_sz; } else if (sdt_contig) { MPI_Aint actual_unpack_bytes; - MPIR_Typerep_unpack((char*) sbuf + sdt_true_lb, sdata_sz, rbuf, rcount, rdt, 0, &actual_unpack_bytes); + MPIR_Typerep_unpack(MPIR_get_contig_ptr(sbuf, sdt_true_lb), sdata_sz, rbuf, rcount, rdt, 0, &actual_unpack_bytes); /* --BEGIN ERROR HANDLING-- */ if (actual_unpack_bytes != sdata_sz) { @@ -86,7 +84,7 @@ void MPIDI_CH3U_Buffer_copy( else if (rdt_contig) { MPI_Aint actual_pack_bytes; - MPIR_Typerep_pack(sbuf, scount, sdt, 0, (char*)rbuf + rdt_true_lb, sdata_sz, &actual_pack_bytes); + MPIR_Typerep_pack(sbuf, scount, sdt, 0, MPIR_get_contig_ptr(rbuf, rdt_true_lb), sdata_sz, &actual_pack_bytes); /* --BEGIN ERROR HANDLING-- */ if (actual_pack_bytes != sdata_sz) { diff --git a/src/mpid/ch3/src/ch3u_eager.c b/src/mpid/ch3/src/ch3u_eager.c index 02fb78cd61a..0a1be3798fb 100644 --- a/src/mpid/ch3/src/ch3u_eager.c +++ b/src/mpid/ch3/src/ch3u_eager.c @@ -373,9 +373,7 @@ int MPIDI_CH3_PktHandler_EagerShortSend( MPIDI_VC_t *vc, MPIDI_CH3_Pkt_t *pkt, v { unsigned char const * restrict p = (unsigned char *)eagershort_pkt->data; - unsigned char * restrict bufp = - (unsigned char *)(char*)(rreq->dev.user_buf) + - dt_true_lb; + unsigned char * restrict bufp = MPIR_get_contig_ptr(rreq->dev.user_buf, dt_true_lb); int i; for (i=0; ipobj_mutex); diff --git a/src/mpid/ch3/src/ch3u_handle_recv_pkt.c b/src/mpid/ch3/src/ch3u_handle_recv_pkt.c index d17e285caac..73ad88144b0 100644 --- a/src/mpid/ch3/src/ch3u_handle_recv_pkt.c +++ b/src/mpid/ch3/src/ch3u_handle_recv_pkt.c @@ -138,7 +138,7 @@ int MPIDI_CH3U_Receive_data_found(MPIR_Request *rreq, void *buf, intptr_t *bufle MPL_DBG_MSG(MPIDI_CH3_DBG_OTHER,VERBOSE,"Copying contiguous data to user buffer"); /* copy data out of the receive buffer */ if (rreq->dev.drop_data == FALSE) { - MPIR_Memcpy((char*)(rreq->dev.user_buf) + dt_true_lb, buf, data_sz); + MPIR_Memcpy(MPIR_get_contig_ptr(rreq->dev.user_buf, dt_true_lb), buf, data_sz); } *buflen = data_sz; *complete = TRUE; @@ -147,8 +147,7 @@ int MPIDI_CH3U_Receive_data_found(MPIR_Request *rreq, void *buf, intptr_t *bufle { MPL_DBG_MSG(MPIDI_CH3_DBG_OTHER,VERBOSE,"IOV loaded for contiguous read"); - rreq->dev.iov[0].iov_base = - (void *)((char*)(rreq->dev.user_buf) + dt_true_lb); + rreq->dev.iov[0].iov_base = MPIR_get_contig_ptr(rreq->dev.user_buf, dt_true_lb); rreq->dev.iov[0].iov_len = data_sz; rreq->dev.iov_count = 1; *buflen = 0; @@ -307,8 +306,7 @@ int MPIDI_CH3U_Post_data_receive_found(MPIR_Request * rreq) entire message. However, we haven't yet *read* the data (this code describes how to read the data into the destination) */ MPL_DBG_MSG(MPIDI_CH3_DBG_OTHER,VERBOSE,"IOV loaded for contiguous read"); - rreq->dev.iov[0].iov_base = - (void *)((char*)(rreq->dev.user_buf) + dt_true_lb); + rreq->dev.iov[0].iov_base = MPIR_get_contig_ptr(rreq->dev.user_buf, dt_true_lb); rreq->dev.iov[0].iov_len = data_sz; rreq->dev.iov_count = 1; /* FIXME: We want to set the OnDataAvail to the appropriate diff --git a/src/mpid/ch3/src/ch3u_handle_recv_req.c b/src/mpid/ch3/src/ch3u_handle_recv_req.c index d06558e6869..55abb64d1b4 100644 --- a/src/mpid/ch3/src/ch3u_handle_recv_req.c +++ b/src/mpid/ch3/src/ch3u_handle_recv_req.c @@ -302,8 +302,8 @@ int MPIDI_CH3_ReqHandler_GaccumRecvComplete(MPIDI_VC_t * vc, MPIR_Request * rreq if (is_contig) { MPIR_Memcpy(resp_req->dev.user_buf, - (void *) ((char *) rreq->dev.real_user_buf + dt_true_lb + - stream_offset), stream_data_len); + MPIR_get_contig_ptr(rreq->dev.real_user_buf, dt_true_lb + stream_offset), + stream_data_len); } else { MPI_Aint actual_pack_bytes; diff --git a/src/mpid/ch3/src/ch3u_request.c b/src/mpid/ch3/src/ch3u_request.c index 987e8c00c52..60d1a1e1179 100644 --- a/src/mpid/ch3/src/ch3u_request.c +++ b/src/mpid/ch3/src/ch3u_request.c @@ -519,7 +519,7 @@ int MPIDI_CH3U_Request_unpack_uebuf(MPIR_Request * rreq) datatype. If not we should return an error (unless configured with --enable-fast) */ MPIR_FUNC_ENTER; - MPIR_Memcpy((char *)rreq->dev.user_buf + dt_true_lb, rreq->dev.tmpbuf, + MPIR_Memcpy(MPIR_get_contig_ptr(rreq->dev.user_buf, dt_true_lb), rreq->dev.tmpbuf, unpack_sz); MPIR_FUNC_EXIT; } diff --git a/src/mpid/ch3/src/ch3u_rma_ops.c b/src/mpid/ch3/src/ch3u_rma_ops.c index 21888c1b4cd..0f12ba3d65c 100644 --- a/src/mpid/ch3/src/ch3u_rma_ops.c +++ b/src/mpid/ch3/src/ch3u_rma_ops.c @@ -309,8 +309,8 @@ int MPIDI_CH3I_Get(void *origin_addr, int origin_count, MPI_Datatype get_pkt = &(op_ptr->pkt.get); MPIDI_Pkt_init(get_pkt, MPIDI_CH3_PKT_GET); - get_pkt->addr = (char *) win_ptr->basic_info_table[target_rank].base_addr + - win_ptr->basic_info_table[target_rank].disp_unit * target_disp; + get_pkt->addr = MPIR_get_contig_ptr(win_ptr->basic_info_table[target_rank].base_addr, + win_ptr->basic_info_table[target_rank].disp_unit * target_disp); get_pkt->count = target_count; get_pkt->datatype = target_datatype; get_pkt->info.flattened_type_size = 0; @@ -498,8 +498,8 @@ int MPIDI_CH3I_Accumulate(const void *origin_addr, int origin_count, MPI_Datatyp MPIDI_Pkt_init(accum_pkt, MPIDI_CH3_PKT_ACCUMULATE); } - accum_pkt->addr = (char *) win_ptr->basic_info_table[target_rank].base_addr + - win_ptr->basic_info_table[target_rank].disp_unit * target_disp; + accum_pkt->addr = MPIR_get_contig_ptr(win_ptr->basic_info_table[target_rank].base_addr, + win_ptr->basic_info_table[target_rank].disp_unit * target_disp); accum_pkt->count = target_count; accum_pkt->datatype = target_datatype; accum_pkt->info.flattened_type_size = 0; diff --git a/src/mpid/ch3/src/ch3u_rndv.c b/src/mpid/ch3/src/ch3u_rndv.c index 3beca07e12d..aa81314d4bc 100644 --- a/src/mpid/ch3/src/ch3u_rndv.c +++ b/src/mpid/ch3/src/ch3u_rndv.c @@ -235,7 +235,7 @@ int MPIDI_CH3_PktHandler_RndvClrToSend( MPIDI_VC_t *vc, MPIDI_CH3_Pkt_t *pkt, vo iov[0].iov_base = (void *)rs_pkt; iov[0].iov_len = sizeof(*rs_pkt); - iov[1].iov_base = (void *)((char *)sreq->dev.user_buf + dt_true_lb); + iov[1].iov_base = MPIR_get_contig_ptr(sreq->dev.user_buf, dt_true_lb); iov[1].iov_len = data_sz; MPID_THREAD_CS_ENTER(POBJ, vc->pobj_mutex); diff --git a/src/mpid/ch3/src/mpid_irsend.c b/src/mpid/ch3/src/mpid_irsend.c index 4d918f9a510..735a827d5df 100644 --- a/src/mpid/ch3/src/mpid_irsend.c +++ b/src/mpid/ch3/src/mpid_irsend.c @@ -95,7 +95,7 @@ int MPID_Irsend(const void * buf, int count, MPI_Datatype datatype, int rank, in if (dt_contig) { mpi_errno = MPIDI_CH3_EagerContigIsend( &sreq, MPIDI_CH3_PKT_READY_SEND, - (char*)buf + dt_true_lb, + MPIR_get_contig_ptr(buf, dt_true_lb), data_sz, rank, tag, comm, context_offset ); diff --git a/src/mpid/ch3/src/mpid_isend.c b/src/mpid/ch3/src/mpid_isend.c index 908151431e6..802c05e272c 100644 --- a/src/mpid/ch3/src/mpid_isend.c +++ b/src/mpid/ch3/src/mpid_isend.c @@ -120,7 +120,7 @@ int MPID_Isend(const void * buf, MPI_Aint count, MPI_Datatype datatype, int rank { mpi_errno = MPIDI_CH3_EagerContigIsend( &sreq, MPIDI_CH3_PKT_EAGER_SEND, - (char*)buf + dt_true_lb, + MPIR_get_contig_ptr(buf, dt_true_lb), data_sz, rank, tag, comm, context_offset ); } diff --git a/src/mpid/ch3/src/mpid_rsend.c b/src/mpid/ch3/src/mpid_rsend.c index c19ccdb3af0..cbb738e375a 100644 --- a/src/mpid/ch3/src/mpid_rsend.c +++ b/src/mpid/ch3/src/mpid_rsend.c @@ -100,7 +100,7 @@ int MPID_Rsend(const void * buf, int count, MPI_Datatype datatype, int rank, int { mpi_errno = MPIDI_CH3_EagerContigSend( &sreq, MPIDI_CH3_PKT_READY_SEND, - (char *)buf + dt_true_lb, + MPIR_get_contig_ptr(buf, dt_true_lb), data_sz, rank, tag, comm, context_offset ); } diff --git a/src/mpid/ch3/src/mpid_send.c b/src/mpid/ch3/src/mpid_send.c index 5073f0f4c7f..45d5d21a66a 100644 --- a/src/mpid/ch3/src/mpid_send.c +++ b/src/mpid/ch3/src/mpid_send.c @@ -117,7 +117,7 @@ int MPID_Send(const void * buf, MPI_Aint count, MPI_Datatype datatype, int rank, if (dt_contig && data_sz <= MPIDI_EAGER_SHORT_SIZE) { mpi_errno = MPIDI_CH3_EagerContigShortSend( &sreq, MPIDI_CH3_PKT_EAGERSHORT_SEND, - (char *)buf + dt_true_lb, + MPIR_get_contig_ptr(buf, dt_true_lb), data_sz, rank, tag, comm, context_offset ); } @@ -130,7 +130,7 @@ int MPID_Send(const void * buf, MPI_Aint count, MPI_Datatype datatype, int rank, { mpi_errno = MPIDI_CH3_EagerContigSend( &sreq, MPIDI_CH3_PKT_EAGER_SEND, - (char *)buf + dt_true_lb, + MPIR_get_contig_ptr(buf, dt_true_lb), data_sz, rank, tag, comm, context_offset ); } From f74069606415cb478e4407392aa1244b228d2173 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 3 Oct 2021 15:53:38 -0500 Subject: [PATCH 043/607] ch4: use MPIR_get_contig_ptr To suppress ubsan warnings on 32-bit systems when buf is 0. --- src/mpid/ch4/netmod/ofi/ofi_am_impl.h | 2 +- src/mpid/ch4/netmod/ofi/ofi_recv.h | 2 +- src/mpid/ch4/netmod/ofi/ofi_rma.h | 17 +++++++++-------- src/mpid/ch4/netmod/ofi/ofi_send.h | 4 ++-- src/mpid/ch4/netmod/ucx/ucx_am.h | 2 +- src/mpid/ch4/netmod/ucx/ucx_recv.h | 4 ++-- src/mpid/ch4/netmod/ucx/ucx_rma.h | 12 ++++++------ src/mpid/ch4/netmod/ucx/ucx_send.h | 2 +- src/mpid/ch4/shm/ipc/src/ipc_send.h | 2 +- .../ch4/shm/posix/posix_coll_release_gather.h | 2 +- src/mpid/ch4/shm/posix/posix_rma.h | 2 +- src/mpid/ch4/src/mpidig_recv.h | 2 +- src/mpid/ch4/src/mpidig_recv_utils.h | 2 +- src/mpid/ch4/src/mpidig_rma_callbacks.c | 5 +++-- 14 files changed, 31 insertions(+), 29 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_am_impl.h b/src/mpid/ch4/netmod/ofi/ofi_am_impl.h index d20ace505a5..ee65179a551 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_am_impl.h +++ b/src/mpid/ch4/netmod/ofi/ofi_am_impl.h @@ -766,7 +766,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_do_am_isend_rdma_read(int rank, MPIR_Comm MPIDI_OFI_AM_SREQ_HDR(sreq, pack_buffer) = send_buf; } else { MPIDI_Datatype_check_lb(datatype, dt_true_lb); - send_buf = (char *) buf + dt_true_lb; + send_buf = MPIR_get_contig_ptr(buf, dt_true_lb); } MPL_DBG_MSG_FMT(MPIDI_CH4_DBG_GENERAL, VERBOSE, diff --git a/src/mpid/ch4/netmod/ofi/ofi_recv.h b/src/mpid/ch4/netmod/ofi/ofi_recv.h index 769baabcefe..473e3f4d15c 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_recv.h +++ b/src/mpid/ch4/netmod/ofi/ofi_recv.h @@ -174,7 +174,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_do_irecv(void *buf, MPIDI_OFI_REQUEST(rreq, datatype) = datatype; MPIR_Datatype_add_ref_if_not_builtin(datatype); - recv_buf = (char *) buf + dt_true_lb; + recv_buf = MPIR_get_contig_ptr(buf, dt_true_lb); MPL_pointer_attr_t attr; MPIR_GPU_query_pointer_attr(recv_buf, &attr); if (data_sz && attr.type == MPL_GPU_POINTER_DEV) { diff --git a/src/mpid/ch4/netmod/ofi/ofi_rma.h b/src/mpid/ch4/netmod/ofi/ofi_rma.h index 77f6bf6782d..b5aaf8b3306 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_rma.h +++ b/src/mpid/ch4/netmod/ofi/ofi_rma.h @@ -232,7 +232,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_do_put(const void *origin_addr, MPID_THREAD_CS_ENTER(VCI, MPIDI_VCI(vni).lock); MPIDI_OFI_win_cntr_incr(win); MPIDI_OFI_CALL_RETRY(fi_inject_write(MPIDI_OFI_WIN(win).ep, - (char *) origin_addr + origin_true_lb, target_bytes, + MPIR_get_contig_ptr(origin_addr, origin_true_lb), + target_bytes, MPIDI_OFI_av_to_phys(addr, nic, vni, vni), target_mr.addr + target_true_lb, target_mr.mr_key), vni, rdma_inject_write, FALSE); @@ -264,7 +265,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_do_put(const void *origin_addr, msg.iov_count = 1; msg.rma_iov = &riov; msg.rma_iov_count = 1; - iov.iov_base = (char *) origin_addr + origin_true_lb; + iov.iov_base = MPIR_get_contig_ptr(origin_addr, origin_true_lb); iov.iov_len = target_bytes; riov.addr = target_mr.addr + target_true_lb; riov.len = target_bytes; @@ -439,7 +440,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_do_get(void *origin_addr, msg.rma_iov_count = 1; msg.context = NULL; msg.data = 0; - iov.iov_base = (char *) origin_addr + origin_true_lb; + iov.iov_base = MPIR_get_contig_ptr(origin_addr, origin_true_lb); iov.iov_len = target_bytes; riov.addr = target_mr.addr + target_true_lb; riov.len = target_bytes; @@ -626,8 +627,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_NM_mpi_compare_and_swap(const void *origin_ad if (unlikely(!target_mr_found)) goto am_fallback; - buffer = (char *) origin_addr + true_lb; - rbuffer = (char *) result_addr + true_lb; + buffer = MPIR_get_contig_ptr(origin_addr, true_lb); + rbuffer = MPIR_get_contig_ptr(result_addr, true_lb); MPIDI_OFI_query_acc_atomic_support(datatype, MPIDI_OFI_QUERY_COMPARE_ATOMIC_COUNT, MPI_OP_NULL, win, winattr, &fi_dt, &fi_op, &max_count, &dt_size); @@ -774,7 +775,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_do_accumulate(const void *origin_addr, struct fi_rma_ioc targetv; struct fi_msg_atomic msg; - originv.addr = (char *) origin_addr + origin_true_lb; + originv.addr = MPIR_get_contig_ptr(origin_addr, origin_true_lb); originv.count = basic_count; targetv.addr = target_mr.addr + target_true_lb; targetv.count = basic_count; @@ -918,9 +919,9 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_do_get_accumulate(const void *origin_addr struct fi_rma_ioc targetv; struct fi_msg_atomic msg; - originv.addr = (char *) origin_addr + origin_true_lb; + originv.addr = MPIR_get_contig_ptr(origin_addr, origin_true_lb); originv.count = basic_count; - resultv.addr = (char *) result_addr + result_true_lb; + resultv.addr = MPIR_get_contig_ptr(result_addr, result_true_lb); resultv.count = basic_count; targetv.addr = target_mr.addr + target_true_lb; targetv.count = basic_count; diff --git a/src/mpid/ch4/netmod/ofi/ofi_send.h b/src/mpid/ch4/netmod/ofi/ofi_send.h index 51df6d52dd7..d0d95962005 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_send.h +++ b/src/mpid/ch4/netmod/ofi/ofi_send.h @@ -216,7 +216,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_send_normal(const void *buf, MPI_Aint cou (void *) &(ackreq->context)), vni_local, trecvsync, FALSE); } - send_buf = (char *) buf + dt_true_lb; + send_buf = MPIR_get_contig_ptr(buf, dt_true_lb); MPL_pointer_attr_t attr; MPIR_GPU_query_pointer_attr(send_buf, &attr); if (data_sz && attr.type == MPL_GPU_POINTER_DEV) { @@ -404,7 +404,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_send(const void *buf, MPI_Aint count, MPI if (likely(!syncflag && dt_contig && (data_sz <= MPIDI_OFI_global.max_buffered_send))) { MPI_Aint actual_pack_bytes = 0; - void *send_buf = (char *) buf + dt_true_lb; + void *send_buf = MPIR_get_contig_ptr(buf, dt_true_lb); MPL_pointer_attr_t attr; MPIR_GPU_query_pointer_attr(send_buf, &attr); if (attr.type == MPL_GPU_POINTER_DEV) { diff --git a/src/mpid/ch4/netmod/ucx/ucx_am.h b/src/mpid/ch4/netmod/ucx/ucx_am.h index 12af99a69c0..4bc1a092a68 100644 --- a/src/mpid/ch4/netmod/ucx/ucx_am.h +++ b/src/mpid/ch4/netmod/ucx/ucx_am.h @@ -89,7 +89,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_NM_am_isend(int rank, ucp_dt_iov_t *iov = sreq->dev.ch4.am.netmod_am.ucx.iov; iov[0].buffer = send_buf; iov[0].length = sizeof(ucx_hdr) + am_hdr_sz; - iov[1].buffer = (char *) data + dt_true_lb; + iov[1].buffer = MPIR_get_contig_ptr(data, dt_true_lb); iov[1].length = data_sz; send_buf_p = iov; diff --git a/src/mpid/ch4/netmod/ucx/ucx_recv.h b/src/mpid/ch4/netmod/ucx/ucx_recv.h index 4ea4a144051..04ebf130a20 100644 --- a/src/mpid/ch4/netmod/ucx/ucx_recv.h +++ b/src/mpid/ch4/netmod/ucx/ucx_recv.h @@ -106,7 +106,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_UCX_recv(void *buf, void *recv_buf; size_t recv_count; if (dt_contig) { - recv_buf = (char *) buf + dt_true_lb; + recv_buf = MPIR_get_contig_ptr(buf, dt_true_lb); recv_count = data_sz; } else { recv_buf = buf; @@ -160,7 +160,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_NM_mpi_imrecv(void *buf, void *recv_buf; size_t recv_count; if (dt_contig) { - recv_buf = (char *) buf + dt_true_lb; + recv_buf = MPIR_get_contig_ptr(buf, dt_true_lb); recv_count = data_sz; } else { recv_buf = buf; diff --git a/src/mpid/ch4/netmod/ucx/ucx_rma.h b/src/mpid/ch4/netmod/ucx/ucx_rma.h index bc24f8f0df5..b5d581d8496 100644 --- a/src/mpid/ch4/netmod/ucx/ucx_rma.h +++ b/src/mpid/ch4/netmod/ucx/ucx_rma.h @@ -220,9 +220,9 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_UCX_do_put(const void *origin_addr, if (origin_contig && target_contig) { int vni = MPIDI_UCX_get_win_vni(win); MPID_THREAD_CS_ENTER(VCI, MPIDI_VCI(vni).lock); - mpi_errno = MPIDI_UCX_contig_put((char *) origin_addr + origin_true_lb, origin_bytes, - target_rank, target_disp, target_true_lb, win, addr, - reqptr, vni); + mpi_errno = + MPIDI_UCX_contig_put(MPIR_get_contig_ptr(origin_addr, origin_true_lb), origin_bytes, + target_rank, target_disp, target_true_lb, win, addr, reqptr, vni); MPID_THREAD_CS_EXIT(VCI, MPIDI_VCI(vni).lock); } else if (target_contig) { int vni = MPIDI_UCX_get_win_vni(win); @@ -281,9 +281,9 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_UCX_do_get(void *origin_addr, if (origin_contig && target_contig) { int vni = MPIDI_UCX_get_win_vni(win); MPID_THREAD_CS_ENTER(VCI, MPIDI_VCI(vni).lock); - mpi_errno = MPIDI_UCX_contig_get((char *) origin_addr + origin_true_lb, origin_bytes, - target_rank, target_disp, target_true_lb, win, addr, - reqptr, vni); + mpi_errno = + MPIDI_UCX_contig_get(MPIR_get_contig_ptr(origin_addr, origin_true_lb), origin_bytes, + target_rank, target_disp, target_true_lb, win, addr, reqptr, vni); MPID_THREAD_CS_EXIT(VCI, MPIDI_VCI(vni).lock); } else { mpi_errno = MPIDIG_mpi_get(origin_addr, origin_count, origin_datatype, target_rank, diff --git a/src/mpid/ch4/netmod/ucx/ucx_send.h b/src/mpid/ch4/netmod/ucx/ucx_send.h index 3a6ca095df2..c1038929eed 100644 --- a/src/mpid/ch4/netmod/ucx/ucx_send.h +++ b/src/mpid/ch4/netmod/ucx/ucx_send.h @@ -62,7 +62,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_UCX_send(const void *buf, const void *send_buf; size_t send_count; if (dt_contig) { - send_buf = (char *) buf + dt_true_lb; + send_buf = MPIR_get_contig_ptr(buf, dt_true_lb); send_count = data_sz; } else { send_buf = buf; diff --git a/src/mpid/ch4/shm/ipc/src/ipc_send.h b/src/mpid/ch4/shm/ipc/src/ipc_send.h index e5d8dec2b1e..dbef8a85c57 100644 --- a/src/mpid/ch4/shm/ipc/src/ipc_send.h +++ b/src/mpid/ch4/shm/ipc/src/ipc_send.h @@ -68,7 +68,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_IPCI_try_lmt_isend(const void *buf, MPI_Aint MPI_Aint mem_size; void *mem_addr; if (dt_contig) { - mem_addr = (char *) buf + true_lb; + mem_addr = MPIR_get_contig_ptr(buf, true_lb); mem_size = data_sz; } else { mem_addr = (char *) buf; diff --git a/src/mpid/ch4/shm/posix/posix_coll_release_gather.h b/src/mpid/ch4/shm/posix/posix_coll_release_gather.h index 3184d1381fd..fc6e92af33c 100644 --- a/src/mpid/ch4/shm/posix/posix_coll_release_gather.h +++ b/src/mpid/ch4/shm/posix/posix_coll_release_gather.h @@ -131,7 +131,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_mpi_bcast_release_gather(void *buffer, MPI_Aint chunk_count = (i == 0) ? chunk_count_floor : chunk_count_ceil; mpi_errno = - MPIDI_POSIX_mpi_release_gather_release((char *) buffer + offset + true_lb, + MPIDI_POSIX_mpi_release_gather_release(MPIR_get_contig_ptr(buffer, offset + true_lb), chunk_count, MPI_BYTE, root, comm_ptr, errflag, MPIDI_POSIX_RELEASE_GATHER_OPCODE_BCAST); diff --git a/src/mpid/ch4/shm/posix/posix_rma.h b/src/mpid/ch4/shm/posix/posix_rma.h index cca1d91e873..e30dd816863 100644 --- a/src/mpid/ch4/shm/posix/posix_rma.h +++ b/src/mpid/ch4/shm/posix/posix_rma.h @@ -305,7 +305,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_do_accumulate(const void *origin_addr, } mpi_errno = MPIDI_POSIX_compute_accumulate((void *) origin_addr, origin_count, origin_datatype, - (char *) base + disp_unit * target_disp, + MPIR_get_contig_ptr(base, disp_unit * target_disp), target_count, target_datatype, op, mapped_device); if (winattr & MPIDI_WINATTR_SHM_ALLOCATED) { MPIDI_POSIX_RMA_MUTEX_UNLOCK(posix_win->shm_mutex_ptr); diff --git a/src/mpid/ch4/src/mpidig_recv.h b/src/mpid/ch4/src/mpidig_recv.h index 48c67d44456..787818b6095 100644 --- a/src/mpid/ch4/src/mpidig_recv.h +++ b/src/mpid/ch4/src/mpidig_recv.h @@ -84,7 +84,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_copy_from_unexp_req(MPIR_Request * req, void * the one used in MPI_Barrier. In another case, the datatype can specify * the absolute address of the buffer (e.g. buf == MPI_BOTTOM). */ - char *addr = (char *) user_buf + dt_true_lb; + char *addr = MPIR_get_contig_ptr(user_buf, dt_true_lb); MPIR_Typerep_copy(addr, MPIDIG_REQUEST(req, buffer), nbytes); } } diff --git a/src/mpid/ch4/src/mpidig_recv_utils.h b/src/mpid/ch4/src/mpidig_recv_utils.h index 070816b6cdc..239ec0b525d 100644 --- a/src/mpid/ch4/src/mpidig_recv_utils.h +++ b/src/mpid/ch4/src/mpidig_recv_utils.h @@ -349,7 +349,7 @@ MPL_STATIC_INLINE_PREFIX void MPIDIG_convert_datatype(MPIR_Request * rreq) MPIDIG_rreq_async_t *p = &(MPIDIG_REQUEST(rreq, req->recv_async)); if (dt_contig) { p->recv_type = MPIDIG_RECV_CONTIG; - p->iov_one.iov_base = (char *) MPIDIG_REQUEST(rreq, buffer) + dt_true_lb; + p->iov_one.iov_base = MPIR_get_contig_ptr(MPIDIG_REQUEST(rreq, buffer), dt_true_lb); p->iov_one.iov_len = data_sz; } else { struct iovec *iov; diff --git a/src/mpid/ch4/src/mpidig_rma_callbacks.c b/src/mpid/ch4/src/mpidig_rma_callbacks.c index be7e8a9c1a8..a51bdb3d425 100644 --- a/src/mpid/ch4/src/mpidig_rma_callbacks.c +++ b/src/mpid/ch4/src/mpidig_rma_callbacks.c @@ -1480,7 +1480,7 @@ int MPIDIG_put_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, MPIDIG_REQUEST(rreq, req->preq.flattened_dt) = NULL; MPIDIG_REQUEST(rreq, req->preq.dt) = NULL; - MPIDIG_REQUEST(rreq, buffer) = (void *) (base + offset + msg_hdr->target_true_lb); + MPIDIG_REQUEST(rreq, buffer) = MPIR_get_contig_ptr(base, offset + msg_hdr->target_true_lb); MPIDIG_REQUEST(rreq, count) = msg_hdr->target_count; MPIDIG_REQUEST(rreq, datatype) = msg_hdr->target_datatype; MPIDIG_recv_type_init(msg_hdr->origin_data_sz, rreq); @@ -2104,7 +2104,8 @@ int MPIDIG_get_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, } else { MPIR_Assert(!in_data_sz || in_data_sz == 0); MPIDIG_recv_init(1, 0, NULL, 0, rreq); - MPIDIG_REQUEST(rreq, req->greq.addr) = (char *) base + offset + msg_hdr->target_true_lb; + MPIDIG_REQUEST(rreq, req->greq.addr) = + MPIR_get_contig_ptr(base, offset + msg_hdr->target_true_lb); } if (attr & MPIDIG_AM_ATTR__IS_ASYNC) { From f07b09780b270546d146eb6e8108d81d295ce63f Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 3 Oct 2021 23:38:52 -0500 Subject: [PATCH 044/607] datatype/dataloop: avoid overflow in calculating ub In creating vector datatype, we only need calculate eff_stride if count is greater than 0, or the stride will be unused. Avoid calculating it unnecessarily and potentially trigger data overflow in 32-bit systems. --- .../datatype/typerep/src/typerep_dataloop_create.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/mpi/datatype/typerep/src/typerep_dataloop_create.c b/src/mpi/datatype/typerep/src/typerep_dataloop_create.c index 725f92e284c..5cd0d416c1b 100644 --- a/src/mpi/datatype/typerep/src/typerep_dataloop_create.c +++ b/src/mpi/datatype/typerep/src/typerep_dataloop_create.c @@ -13,7 +13,9 @@ static void update_type_vector(MPI_Aint count, MPI_Aint blocklength, MPI_Aint st { int old_is_contig; MPI_Aint old_sz; - MPI_Aint old_lb, old_ub, old_extent, old_true_lb, old_true_ub, eff_stride; + MPI_Aint old_lb, old_ub, old_extent, old_true_lb, old_true_ub; + /* we only need calc eff_stride if count > 1 */ + MPI_Aint eff_stride = 0; if (HANDLE_IS_BUILTIN(oldtype)) { MPI_Aint el_sz = (MPI_Aint) MPIR_Datatype_get_basic_size(oldtype); @@ -33,7 +35,9 @@ static void update_type_vector(MPI_Aint count, MPI_Aint blocklength, MPI_Aint st newtype->builtin_element_size = el_sz; newtype->basic_type = oldtype; - eff_stride = (strideinbytes) ? stride : (stride * el_sz); + if (count > 1) { + eff_stride = (strideinbytes) ? stride : (stride * el_sz); + } } else { /* user-defined base type (oldtype) */ MPIR_Datatype *old_dtp; @@ -55,7 +59,9 @@ static void update_type_vector(MPI_Aint count, MPI_Aint blocklength, MPI_Aint st newtype->builtin_element_size = old_dtp->builtin_element_size; newtype->basic_type = old_dtp->basic_type; - eff_stride = (strideinbytes) ? stride : (stride * old_dtp->extent); + if (count > 1) { + eff_stride = (strideinbytes) ? stride : (stride * old_dtp->extent); + } } MPII_DATATYPE_VECTOR_LB_UB(count, eff_stride, blocklength, From b09f4aa9e6f0e5c4e24bfb5acbfd98ce9f9082f2 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 3 Oct 2021 19:00:09 -0500 Subject: [PATCH 045/607] dtpools: avoid signed integer overflow The arithmetic on 32-bit system can easily overflow. Cast to int64_t to prevent it. --- test/mpi/dtpools/src/dtpools_attr.c | 103 ++++++++++++++-------------- 1 file changed, 53 insertions(+), 50 deletions(-) diff --git a/test/mpi/dtpools/src/dtpools_attr.c b/test/mpi/dtpools/src/dtpools_attr.c index 937ab09c853..dab6b6c50e7 100644 --- a/test/mpi/dtpools/src/dtpools_attr.c +++ b/test/mpi/dtpools/src/dtpools_attr.c @@ -30,7 +30,7 @@ static int construct_contig(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * a MPI_Aint count = 0; DTPI_pool_s *dtpi = dtp.priv; int rc = DTP_SUCCESS; - uint64_t extent; + int64_t extent; /* setup the child type first */ rc = DTPI_construct_datatype(dtp, attr_tree_depth - 1, &attr->child, &type, &count); @@ -196,7 +196,7 @@ static int construct_vector(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * a MPI_Aint count = 0; DTPI_pool_s *dtpi = dtp.priv; int rc = DTP_SUCCESS; - uint64_t extent; + int64_t extent; /* setup the child type first */ rc = DTPI_construct_datatype(dtp, attr_tree_depth - 1, &attr->child, &type, &count); @@ -272,8 +272,8 @@ static int construct_vector(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * a min_displ_idx = i; } - extent *= attr->u.vector.stride * max_displ_idx - - attr->u.vector.stride * min_displ_idx + attr->u.vector.blklen; + extent *= (int64_t) attr->u.vector.stride * max_displ_idx - + (int64_t) attr->u.vector.stride * min_displ_idx + attr->u.vector.blklen; if (VALUE_FITS_IN_AINT(extent * count)) break; @@ -304,7 +304,7 @@ static int construct_hvector(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * MPI_Aint count = 0; DTPI_pool_s *dtpi = dtp.priv; int rc = DTP_SUCCESS; - uint64_t extent; + int64_t extent; /* setup the child type first */ rc = DTPI_construct_datatype(dtp, attr_tree_depth - 1, &attr->child, &type, &count); @@ -383,9 +383,9 @@ static int construct_hvector(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * min_displ_idx = i; } - extent = attr->u.hvector.stride * max_displ_idx - - attr->u.hvector.stride * min_displ_idx + - attr->u.hvector.blklen * attr->child_type_extent; + extent = (int64_t) attr->u.hvector.stride * max_displ_idx - + (int64_t) attr->u.hvector.stride * min_displ_idx + + (int64_t) attr->u.hvector.blklen * attr->child_type_extent; if (VALUE_FITS_IN_AINT(extent * count)) break; @@ -416,7 +416,7 @@ static int construct_blkindx(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * MPI_Aint count = 0; DTPI_pool_s *dtpi = dtp.priv; int rc = DTP_SUCCESS; - uint64_t extent; + int64_t extent; /* setup the child type first */ rc = DTPI_construct_datatype(dtp, attr_tree_depth - 1, &attr->child, &type, &count); @@ -467,19 +467,19 @@ static int construct_blkindx(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * DTPI_ALLOC_OR_FAIL(attr->u.blkindx.array_of_displs, attr->u.blkindx.numblks * sizeof(int), rc); - uint64_t total_displ = 0; + int64_t total_displ = 0; int displs_attr = DTPI_rand(dtpi) % DTPI_ATTR_BLKINDX_DISPLS__LAST; if (displs_attr == DTPI_ATTR_BLKINDX_DISPLS__SMALL) { for (int i = 0; i < attr->u.blkindx.numblks; i++) { attr->u.blkindx.array_of_displs[i] = (int) total_displ; - total_displ += attr->u.blkindx.blklen + 1; + total_displ += (int64_t) attr->u.blkindx.blklen + 1; if (!VALUE_FITS_IN_INT(total_displ)) goto retry; } } else if (displs_attr == DTPI_ATTR_BLKINDX_DISPLS__LARGE) { for (int i = 0; i < attr->u.blkindx.numblks; i++) { attr->u.blkindx.array_of_displs[i] = (int) total_displ; - total_displ += attr->u.blkindx.blklen * 4; + total_displ += (int64_t) attr->u.blkindx.blklen * 4; if (!VALUE_FITS_IN_INT(total_displ)) goto retry; } @@ -487,14 +487,14 @@ static int construct_blkindx(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * for (int i = 0; i < attr->u.blkindx.numblks; i++) { int idx = attr->u.blkindx.numblks - i - 1; attr->u.blkindx.array_of_displs[idx] = (int) total_displ; - total_displ += attr->u.blkindx.blklen + 1; + total_displ += (int64_t) attr->u.blkindx.blklen + 1; if (!VALUE_FITS_IN_INT(total_displ)) goto retry; } } else if (displs_attr == DTPI_ATTR_BLKINDX_DISPLS__UNEVEN) { for (int i = 0; i < attr->u.blkindx.numblks; i++) { attr->u.blkindx.array_of_displs[i] = (int) total_displ; - total_displ += attr->u.blkindx.blklen + i; + total_displ += (int64_t) attr->u.blkindx.blklen + i; if (!VALUE_FITS_IN_INT(total_displ)) goto retry; } @@ -520,8 +520,8 @@ static int construct_blkindx(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * min_displ_idx = i; } - extent *= attr->u.blkindx.array_of_displs[max_displ_idx] - - attr->u.blkindx.array_of_displs[min_displ_idx] + attr->u.blkindx.blklen; + extent *= (int64_t) attr->u.blkindx.array_of_displs[max_displ_idx] - + (int64_t) attr->u.blkindx.array_of_displs[min_displ_idx] + attr->u.blkindx.blklen; if (VALUE_FITS_IN_AINT(extent * count)) break; @@ -553,7 +553,7 @@ static int construct_blkhindx(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * MPI_Aint count = 0; DTPI_pool_s *dtpi = dtp.priv; int rc = DTP_SUCCESS; - uint64_t extent; + int64_t extent; /* setup the child type first */ rc = DTPI_construct_datatype(dtp, attr_tree_depth - 1, &attr->child, &type, &count); @@ -606,19 +606,19 @@ static int construct_blkhindx(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * /* FIXME: we should detect the maximum alignment needed by the * compiler instead of arbitrarily incrementing the stride by * a constant value. */ - uint64_t total_displ = 8; + int64_t total_displ = 8; int displs_attr = DTPI_rand(dtpi) % DTPI_ATTR_BLKHINDX_DISPLS__LAST; if (displs_attr == DTPI_ATTR_BLKHINDX_DISPLS__SMALL) { for (int i = 0; i < attr->u.blkhindx.numblks; i++) { attr->u.blkhindx.array_of_displs[i] = (MPI_Aint) total_displ; - total_displ += (uint64_t) (attr->u.blkhindx.blklen + 1) * attr->child_type_extent; + total_displ += ((int64_t) attr->u.blkhindx.blklen + 1) * attr->child_type_extent; if (!VALUE_FITS_IN_AINT(total_displ)) goto retry; } } else if (displs_attr == DTPI_ATTR_BLKHINDX_DISPLS__LARGE) { for (int i = 0; i < attr->u.blkhindx.numblks; i++) { attr->u.blkhindx.array_of_displs[i] = (MPI_Aint) total_displ; - total_displ += (attr->u.blkhindx.blklen * 4) * attr->child_type_extent; + total_displ += ((int64_t) attr->u.blkhindx.blklen * 4) * attr->child_type_extent; if (!VALUE_FITS_IN_AINT(total_displ)) goto retry; } @@ -626,14 +626,14 @@ static int construct_blkhindx(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * for (int i = 0; i < attr->u.blkhindx.numblks; i++) { int idx = attr->u.blkhindx.numblks - i - 1; attr->u.blkhindx.array_of_displs[idx] = (MPI_Aint) total_displ; - total_displ += (attr->u.blkhindx.blklen + 1) * attr->child_type_extent; + total_displ += ((int64_t) attr->u.blkhindx.blklen + 1) * attr->child_type_extent; if (!VALUE_FITS_IN_AINT(total_displ)) goto retry; } } else if (displs_attr == DTPI_ATTR_BLKHINDX_DISPLS__UNEVEN) { for (int i = 0; i < attr->u.blkhindx.numblks; i++) { attr->u.blkhindx.array_of_displs[i] = (MPI_Aint) total_displ; - total_displ += (attr->u.blkhindx.blklen + i) * attr->child_type_extent; + total_displ += ((int64_t) attr->u.blkhindx.blklen + i) * attr->child_type_extent; if (!VALUE_FITS_IN_AINT(total_displ)) goto retry; } @@ -659,9 +659,9 @@ static int construct_blkhindx(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * min_displ_idx = i; } - extent = attr->u.blkhindx.array_of_displs[max_displ_idx] - - attr->u.blkhindx.array_of_displs[min_displ_idx] + - attr->u.blkindx.blklen * attr->child_type_extent; + extent = (int64_t) attr->u.blkhindx.array_of_displs[max_displ_idx] - + (int64_t) attr->u.blkhindx.array_of_displs[min_displ_idx] + + (int64_t) attr->u.blkindx.blklen * attr->child_type_extent; if (VALUE_FITS_IN_AINT(extent * count)) break; @@ -693,7 +693,7 @@ static int construct_indexed(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * MPI_Aint count = 0; DTPI_pool_s *dtpi = dtp.priv; int rc = DTP_SUCCESS; - uint64_t extent; + int64_t extent; /* setup the child type first */ rc = DTPI_construct_datatype(dtp, attr_tree_depth - 1, &attr->child, &type, &count); @@ -734,7 +734,7 @@ static int construct_indexed(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * DTPI_ALLOC_OR_FAIL(attr->u.indexed.array_of_blklens, attr->u.indexed.numblks * sizeof(int), rc); - int total_blklen = 0; + int64_t total_blklen = 0; int blklen_attr = DTPI_rand(dtpi) % DTPI_ATTR_INDEXED_BLKLEN__LAST; if (blklen_attr == DTPI_ATTR_INDEXED_BLKLEN__ONE) { for (int i = 0; i < attr->u.indexed.numblks; i++) { @@ -775,7 +775,7 @@ static int construct_indexed(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * DTPI_ALLOC_OR_FAIL(attr->u.indexed.array_of_displs, attr->u.indexed.numblks * sizeof(int), rc); - uint64_t total_displ = 0; + int64_t total_displ = 0; int displs_attr = DTPI_rand(dtpi) % DTPI_ATTR_INDEXED_DISPLS__LAST; if (displs_attr == DTPI_ATTR_INDEXED_DISPLS__SMALL) { for (int i = 0; i < attr->u.indexed.numblks; i++) { @@ -830,9 +830,9 @@ static int construct_indexed(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * } } - extent *= attr->u.indexed.array_of_displs[max_displ_idx] - - attr->u.indexed.array_of_displs[min_displ_idx] + - attr->u.indexed.array_of_blklens[max_displ_idx]; + extent *= (int64_t) attr->u.indexed.array_of_displs[max_displ_idx] - + (int64_t) attr->u.indexed.array_of_displs[min_displ_idx] + + (int64_t) attr->u.indexed.array_of_blklens[max_displ_idx]; if (VALUE_FITS_IN_AINT(extent * count)) break; @@ -864,7 +864,7 @@ static int construct_hindexed(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * MPI_Aint count = 0; DTPI_pool_s *dtpi = dtp.priv; int rc = DTP_SUCCESS; - uint64_t extent; + int64_t extent; /* setup the child type first */ rc = DTPI_construct_datatype(dtp, attr_tree_depth - 1, &attr->child, &type, &count); @@ -949,13 +949,13 @@ static int construct_hindexed(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * /* FIXME: we should detect the maximum alignment needed by the * compiler instead of arbitrarily incrementing the stride by * a constant value. */ - uint64_t total_displ = 8; + int64_t total_displ = 8; int displs_attr = DTPI_rand(dtpi) % DTPI_ATTR_HINDEXED_DISPLS__LAST; if (displs_attr == DTPI_ATTR_HINDEXED_DISPLS__SMALL) { for (int i = 0; i < attr->u.hindexed.numblks; i++) { attr->u.hindexed.array_of_displs[i] = (MPI_Aint) total_displ; total_displ += - (uint64_t) attr->child_type_extent * (attr->u.hindexed.array_of_blklens[i] + 1); + (int64_t) attr->child_type_extent * (attr->u.hindexed.array_of_blklens[i] + 1); if (!VALUE_FITS_IN_AINT(total_displ)) goto retry; } @@ -963,7 +963,7 @@ static int construct_hindexed(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * for (int i = 0; i < attr->u.hindexed.numblks; i++) { attr->u.hindexed.array_of_displs[i] = (MPI_Aint) total_displ; total_displ += - (uint64_t) attr->child_type_extent * (attr->u.hindexed.array_of_blklens[i] * 4); + (int64_t) attr->child_type_extent * (attr->u.hindexed.array_of_blklens[i] * 4); if (!VALUE_FITS_IN_AINT(total_displ)) goto retry; } @@ -972,14 +972,16 @@ static int construct_hindexed(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * int idx = attr->u.hindexed.numblks - i - 1; attr->u.hindexed.array_of_displs[idx] = (MPI_Aint) total_displ; total_displ += - attr->child_type_extent * (attr->u.hindexed.array_of_blklens[idx] + 1); + (int64_t) attr->child_type_extent * (attr->u.hindexed.array_of_blklens[idx] + + 1); if (!VALUE_FITS_IN_AINT(total_displ)) goto retry; } } else if (displs_attr == DTPI_ATTR_HINDEXED_DISPLS__UNEVEN) { for (int i = 0; i < attr->u.hindexed.numblks; i++) { attr->u.hindexed.array_of_displs[i] = (MPI_Aint) total_displ; - total_displ += attr->child_type_extent * (attr->u.hindexed.array_of_blklens[i] + i); + total_displ += + (int64_t) attr->child_type_extent * (attr->u.hindexed.array_of_blklens[i] + i); if (!VALUE_FITS_IN_AINT(total_displ)) goto retry; } @@ -1007,9 +1009,9 @@ static int construct_hindexed(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * } } - extent = attr->u.hindexed.array_of_displs[max_displ_idx] - - attr->u.hindexed.array_of_displs[min_displ_idx] + - attr->u.hindexed.array_of_blklens[max_displ_idx] * extent; + extent = (int64_t) attr->u.hindexed.array_of_displs[max_displ_idx] - + (int64_t) attr->u.hindexed.array_of_displs[min_displ_idx] + + (int64_t) attr->u.hindexed.array_of_blklens[max_displ_idx] * extent; if (VALUE_FITS_IN_AINT(extent * count)) break; @@ -1041,7 +1043,7 @@ static int construct_subarray(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * MPI_Aint count; DTPI_pool_s *dtpi = dtp.priv; int rc = DTP_SUCCESS; - uint64_t extent; + int64_t extent; /* setup the child type first */ rc = DTPI_construct_datatype(dtp, attr_tree_depth - 1, &attr->child, &type, &count); @@ -1158,7 +1160,7 @@ static int construct_struct(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * a MPI_Aint count = 0; DTPI_pool_s *dtpi = dtp.priv; int rc = DTP_SUCCESS; - uint64_t extent; + int64_t extent; /* setup the child type first */ rc = DTPI_construct_datatype(dtp, attr_tree_depth - 1, &attr->child, &type, &count); @@ -1243,13 +1245,13 @@ static int construct_struct(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * a /* FIXME: we should detect the maximum alignment needed by the * compiler instead of arbitrarily incrementing the stride by * a constant value. */ - uint64_t total_displ = 8; + int64_t total_displ = 8; int displs_attr = DTPI_rand(dtpi) % DTPI_ATTR_STRUCTURE_DISPLS__LAST; if (displs_attr == DTPI_ATTR_STRUCTURE_DISPLS__SMALL) { for (int i = 0; i < attr->u.structure.numblks; i++) { attr->u.structure.array_of_displs[i] = (MPI_Aint) total_displ; total_displ += - attr->child_type_extent * (attr->u.structure.array_of_blklens[i] + 1); + (int64_t) attr->child_type_extent * (attr->u.structure.array_of_blklens[i] + 1); if (!VALUE_FITS_IN_AINT(total_displ)) goto retry; } @@ -1257,7 +1259,7 @@ static int construct_struct(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * a for (int i = 0; i < attr->u.structure.numblks; i++) { attr->u.structure.array_of_displs[i] = (MPI_Aint) total_displ; total_displ += - attr->child_type_extent * (attr->u.structure.array_of_blklens[i] * 4); + (int64_t) attr->child_type_extent * (attr->u.structure.array_of_blklens[i] * 4); if (!VALUE_FITS_IN_AINT(total_displ)) goto retry; } @@ -1266,7 +1268,8 @@ static int construct_struct(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * a int idx = attr->u.structure.numblks - i - 1; attr->u.structure.array_of_displs[idx] = (MPI_Aint) total_displ; total_displ += - attr->child_type_extent * (attr->u.structure.array_of_blklens[idx] + 1); + (int64_t) attr->child_type_extent * (attr->u.structure.array_of_blklens[idx] + + 1); if (!VALUE_FITS_IN_AINT(total_displ)) goto retry; } @@ -1274,7 +1277,7 @@ static int construct_struct(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * a for (int i = 0; i < attr->u.structure.numblks; i++) { attr->u.structure.array_of_displs[i] = (MPI_Aint) total_displ; total_displ += - attr->child_type_extent * (attr->u.structure.array_of_blklens[i] + i); + (int64_t) attr->child_type_extent * (attr->u.structure.array_of_blklens[i] + i); if (!VALUE_FITS_IN_AINT(total_displ)) goto retry; } @@ -1303,9 +1306,9 @@ static int construct_struct(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * a } extent = - attr->u.structure.array_of_displs[max_displ_idx] - - attr->u.structure.array_of_displs[min_displ_idx] + - attr->u.structure.array_of_blklens[max_displ_idx] * extent; + (int64_t) attr->u.structure.array_of_displs[max_displ_idx] - + (int64_t) attr->u.structure.array_of_displs[min_displ_idx] + + (int64_t) attr->u.structure.array_of_blklens[max_displ_idx] * extent; if (VALUE_FITS_IN_AINT(extent * count)) break; From a03c51b3efac024c985fe544f8c1bed73e493441 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 3 Oct 2021 23:49:58 -0500 Subject: [PATCH 046/607] dtpools: check overflow in resized datatype We need also check the ub in addition to extent. --- test/mpi/dtpools/src/dtpools_attr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/mpi/dtpools/src/dtpools_attr.c b/test/mpi/dtpools/src/dtpools_attr.c index dab6b6c50e7..c5f1e3234fb 100644 --- a/test/mpi/dtpools/src/dtpools_attr.c +++ b/test/mpi/dtpools/src/dtpools_attr.c @@ -170,6 +170,9 @@ static int construct_resized(DTP_pool_s dtp, int attr_tree_depth, DTPI_Attr_s * if (!VALUE_FITS_IN_AINT(e * count)) continue; + if (!VALUE_FITS_IN_AINT(e + attr->u.resized.lb)) + continue; + attr->u.resized.extent = (MPI_Aint) e; break; } From 184a037727775c95d89bb11f26921bc4d2016f4e Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 4 Oct 2021 14:04:06 -0500 Subject: [PATCH 047/607] test: fix debug message in part/pingping.c Had an extra multiply of sendcnt. --- test/mpi/part/pingping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/mpi/part/pingping.c b/test/mpi/part/pingping.c index 8950e811806..a366035d23a 100644 --- a/test/mpi/part/pingping.c +++ b/test/mpi/part/pingping.c @@ -152,7 +152,7 @@ int main(int argc, char *argv[]) MTestPrintfMsg(1, "Sending partitions = %d, count = %ld (total size %d bytes) of datatype %s", - partitions, partition_count, nbytes * sendcnt, + partitions, partition_count, nbytes, DTP_obj_get_description(send.dtp_obj)); for (nmsg = 1; nmsg < maxmsg; nmsg++) From b56b5a87972d02504d6f58f1dc24cf57767ebb08 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 4 Oct 2021 18:36:19 -0500 Subject: [PATCH 048/607] ch4: fix MPIDIG_do_put In the old code, we set target_count to either the actual count or data_sz, and then adjust if it is actually a flattened datatype. This is very confusing. In fact, it misses the case when the flattened type is sent within the header and the callback neglected to adjust the count. In stead, we should set target_count individually in each branch. In the case we are sending flattened datatype, the target_count should be the original count, thus avoiding latter adjusting the count in callbacks. --- src/mpid/ch4/src/mpidig_rma.h | 20 +++++++++++++------- src/mpid/ch4/src/mpidig_rma_callbacks.c | 1 - 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/mpid/ch4/src/mpidig_rma.h b/src/mpid/ch4/src/mpidig_rma.h index 30a8e8be5be..4b385e58643 100644 --- a/src/mpid/ch4/src/mpidig_rma.h +++ b/src/mpid/ch4/src/mpidig_rma.h @@ -64,13 +64,6 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_put(const void *origin_addr, int origin_c MPIR_T_PVAR_TIMER_START(RMA, rma_amhdr_set); am_hdr.src_rank = win->comm_ptr->rank; am_hdr.target_disp = target_disp; - if (MPIR_DATATYPE_IS_PREDEFINED(target_datatype)) { - am_hdr.target_count = target_count; - am_hdr.target_datatype = target_datatype; - } else { - am_hdr.target_count = target_data_sz; - am_hdr.target_datatype = MPI_BYTE; - } am_hdr.preq_ptr = sreq; am_hdr.win_id = MPIDIG_WIN(win, win_id); am_hdr.origin_data_sz = origin_data_sz; @@ -83,6 +76,13 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_put(const void *origin_addr, int origin_c int is_contig; MPIR_Datatype_is_contig(target_datatype, &is_contig); if (MPIR_DATATYPE_IS_PREDEFINED(target_datatype) || is_contig) { + if (MPIR_DATATYPE_IS_PREDEFINED(target_datatype)) { + am_hdr.target_count = target_count; + am_hdr.target_datatype = target_datatype; + } else { + am_hdr.target_count = target_data_sz; + am_hdr.target_datatype = MPI_BYTE; + } am_hdr.flattened_sz = 0; MPIR_Datatype_get_true_lb(target_datatype, &am_hdr.target_true_lb); MPIR_T_PVAR_TIMER_END(RMA, rma_amhdr_set); @@ -94,6 +94,12 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_put(const void *origin_addr, int origin_c goto fn_exit; } + /* sending flattened datatype. We'll send MPIDIG_PUT_REQ or MPIDIG_PUT_DT_REQ + * depending on whether flattened_sz fits in the header. + */ + am_hdr.target_count = target_count; + am_hdr.target_datatype = MPI_DATATYPE_NULL; + int flattened_sz; void *flattened_dt; MPIR_Datatype_get_flattened(target_datatype, &flattened_dt, &flattened_sz); diff --git a/src/mpid/ch4/src/mpidig_rma_callbacks.c b/src/mpid/ch4/src/mpidig_rma_callbacks.c index a51bdb3d425..19a0496af17 100644 --- a/src/mpid/ch4/src/mpidig_rma_callbacks.c +++ b/src/mpid/ch4/src/mpidig_rma_callbacks.c @@ -1714,7 +1714,6 @@ int MPIDIG_put_data_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, MPIR_Typerep_unflatten(dt, MPIDIG_REQUEST(rreq, req->preq.flattened_dt)); MPIDIG_REQUEST(rreq, req->preq.dt) = dt; MPIDIG_REQUEST(rreq, datatype) = dt->handle; - MPIDIG_REQUEST(rreq, count) /= dt->size; MPIDIG_REQUEST(rreq, req->target_cmpl_cb) = put_target_cmpl_cb; MPIDIG_recv_type_init(MPIDIG_REQUEST(rreq, req->preq.origin_data_sz), rreq); From 074646e82373fd5d039b691d8bbe77293fddcd99 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 4 Oct 2021 21:58:55 -0500 Subject: [PATCH 049/607] typerep: fix error in using num_contig_blocks With an unflattened datatype, on 32-bit system, num_contig_blocks is 0. --- src/mpi/datatype/typerep/src/typerep_yaksa_pack.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c b/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c index e05b3d77adb..fa28c22edb7 100644 --- a/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c +++ b/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c @@ -635,8 +635,9 @@ static int typerep_op_fallback(void *source_buf, MPI_Aint source_count, MPI_Data MPIR_Assert(dtp->basic_type == source_dtp); MPIR_Assert(dtp->basic_type != MPI_DATATYPE_NULL); - /* +1 needed because Rob says so */ - vec_len = dtp->typerep.num_contig_blocks * target_count + 1; + mpi_errno = MPIR_Typerep_iov_len(target_count, target_dtp, + source_dtp_size * source_count, &vec_len); + MPIR_ERR_CHECK(mpi_errno); typerep_vec = (struct iovec *) MPL_malloc(vec_len * sizeof(struct iovec), MPL_MEM_OTHER); MPIR_ERR_CHKANDJUMP(!typerep_vec, mpi_errno, MPI_ERR_OTHER, "**nomem"); From 72413d5bc67b96370e43b5034b21ec170302cd28 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 5 Oct 2021 07:36:31 -0500 Subject: [PATCH 050/607] datatype: use precise type for typerep handle Yaksa and dataloop use different handle types and potentially can't fit in void *, e.g. on 32-bit. Use precise type and avoid casting. --- src/include/mpir_datatype.h | 2 +- src/mpi/datatype/type_create.c | 2 +- src/mpi/datatype/type_create_pairtype.c | 2 +- .../typerep/src/typerep_dataloop_commit.c | 2 +- .../typerep/src/typerep_dataloop_create.c | 2 +- .../datatype/typerep/src/typerep_flatten.c | 6 ++--- src/mpi/datatype/typerep/src/typerep_pre.h | 4 ++++ .../typerep/src/typerep_yaksa_commit.c | 12 +++++----- .../typerep/src/typerep_yaksa_create.c | 22 +++++++++---------- .../datatype/typerep/src/typerep_yaksa_init.c | 2 +- src/mpi/datatype/typeutil.c | 2 +- 11 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/include/mpir_datatype.h b/src/include/mpir_datatype.h index 7b7542d4b32..90b38483374 100644 --- a/src/include/mpir_datatype.h +++ b/src/include/mpir_datatype.h @@ -134,7 +134,7 @@ struct MPIR_Datatype { /* handle to the backend datatype engine + some content that we * query from it and cache over here for performance reasons */ struct { - void *handle; + MPIR_TYPEREP_HANDLE_TYPE handle; MPI_Aint num_contig_blocks; /* contig blocks in one datatype element */ } typerep; diff --git a/src/mpi/datatype/type_create.c b/src/mpi/datatype/type_create.c index c275454cfae..022c9b63816 100644 --- a/src/mpi/datatype/type_create.c +++ b/src/mpi/datatype/type_create.c @@ -34,7 +34,7 @@ new_dtp->name[0] = 0; \ new_dtp->contents = NULL; \ new_dtp->flattened = NULL; \ - new_dtp->typerep.handle = NULL; \ + new_dtp->typerep.handle = MPIR_TYPEREP_HANDLE_NULL; \ } while (0) int MPIR_Type_contiguous(MPI_Aint count, MPI_Datatype oldtype, MPI_Datatype * newtype) diff --git a/src/mpi/datatype/type_create_pairtype.c b/src/mpi/datatype/type_create_pairtype.c index c41a6b9cf63..4401bab9968 100644 --- a/src/mpi/datatype/type_create_pairtype.c +++ b/src/mpi/datatype/type_create_pairtype.c @@ -71,7 +71,7 @@ int MPIR_Type_create_pairtype(MPI_Datatype type, MPIR_Datatype * new_dtp) new_dtp->contents = NULL; new_dtp->flattened = NULL; - new_dtp->typerep.handle = NULL; + new_dtp->typerep.handle = MPIR_TYPEREP_HANDLE_NULL; switch (type) { case MPI_FLOAT_INT: diff --git a/src/mpi/datatype/typerep/src/typerep_dataloop_commit.c b/src/mpi/datatype/typerep/src/typerep_dataloop_commit.c index c0c2d1a77bd..1bcfe530bd7 100644 --- a/src/mpi/datatype/typerep/src/typerep_dataloop_commit.c +++ b/src/mpi/datatype/typerep/src/typerep_dataloop_commit.c @@ -429,5 +429,5 @@ static void create_named(MPI_Datatype type) void MPIR_Typerep_free(MPIR_Datatype * typeptr) { - MPIR_Dataloop_free(&typeptr->typerep.handle); + MPIR_Dataloop_free((void **) &typeptr->typerep.handle); } diff --git a/src/mpi/datatype/typerep/src/typerep_dataloop_create.c b/src/mpi/datatype/typerep/src/typerep_dataloop_create.c index 5cd0d416c1b..a74127905be 100644 --- a/src/mpi/datatype/typerep/src/typerep_dataloop_create.c +++ b/src/mpi/datatype/typerep/src/typerep_dataloop_create.c @@ -425,7 +425,7 @@ int MPIR_Typerep_create_dup(MPI_Datatype oldtype, MPIR_Datatype * newtype) MPIR_Datatype_get_ptr(oldtype, dtp); if (dtp->is_committed) - MPIR_Dataloop_dup(dtp->typerep.handle, &newtype->typerep.handle); + MPIR_Dataloop_dup(dtp->typerep.handle, (void **) &newtype->typerep.handle); newtype->is_contig = dtp->is_contig; newtype->size = dtp->size; diff --git a/src/mpi/datatype/typerep/src/typerep_flatten.c b/src/mpi/datatype/typerep/src/typerep_flatten.c index 32fcc13bcca..8519d61c7bd 100644 --- a/src/mpi/datatype/typerep/src/typerep_flatten.c +++ b/src/mpi/datatype/typerep/src/typerep_flatten.c @@ -35,7 +35,7 @@ int MPIR_Typerep_flatten_size(MPIR_Datatype * datatype_ptr, int *flattened_type_ #if (MPICH_DATATYPE_ENGINE == MPICH_DATATYPE_ENGINE_YAKSA) uintptr_t size; - int rc = yaksa_flatten_size((yaksa_type_t) (intptr_t) datatype_ptr->typerep.handle, &size); + int rc = yaksa_flatten_size(datatype_ptr->typerep.handle, &size); MPIR_ERR_CHKANDJUMP(rc, mpi_errno, MPI_ERR_INTERN, "**yaksa"); assert(size <= INT_MAX); flattened_loop_size = (int) size; @@ -76,7 +76,7 @@ int MPIR_Typerep_flatten(MPIR_Datatype * datatype_ptr, void *flattened_type) flatten_hdr->num_contig_blocks = datatype_ptr->typerep.num_contig_blocks; #if (MPICH_DATATYPE_ENGINE == MPICH_DATATYPE_ENGINE_YAKSA) - int rc = yaksa_flatten((yaksa_type_t) (intptr_t) datatype_ptr->typerep.handle, + int rc = yaksa_flatten(datatype_ptr->typerep.handle, flattened_typerep); MPIR_ERR_CHKANDJUMP(rc, mpi_errno, MPI_ERR_INTERN, "**yaksa"); #else @@ -120,7 +120,7 @@ int MPIR_Typerep_unflatten(MPIR_Datatype * datatype_ptr, void *flattened_type) datatype_ptr->flattened = NULL; #if (MPICH_DATATYPE_ENGINE == MPICH_DATATYPE_ENGINE_YAKSA) - int rc = yaksa_unflatten((yaksa_type_t *) & datatype_ptr->typerep.handle, flattened_typerep); + int rc = yaksa_unflatten(&datatype_ptr->typerep.handle, flattened_typerep); MPIR_ERR_CHKANDJUMP(rc, mpi_errno, MPI_ERR_INTERN, "**yaksa"); #else mpi_errno = MPIR_Dataloop_unflatten(datatype_ptr, flattened_typerep); diff --git a/src/mpi/datatype/typerep/src/typerep_pre.h b/src/mpi/datatype/typerep/src/typerep_pre.h index 13d919b94c1..1031a15493a 100644 --- a/src/mpi/datatype/typerep/src/typerep_pre.h +++ b/src/mpi/datatype/typerep/src/typerep_pre.h @@ -13,9 +13,13 @@ #include "yaksa.h" typedef yaksa_request_t MPIR_Typerep_req; #define MPIR_TYPEREP_REQ_NULL YAKSA_REQUEST__NULL +#define MPIR_TYPEREP_HANDLE_TYPE yaksa_type_t +#define MPIR_TYPEREP_HANDLE_NULL YAKSA_TYPE__NULL #else typedef int MPIR_Typerep_req; /* unused in dataloop */ #define MPIR_TYPEREP_REQ_NULL 0 +#define MPIR_TYPEREP_HANDLE_TYPE struct MPII_Dataloop * +#define MPIR_TYPEREP_HANDLE_NULL NULL #endif #endif /* TYPEREP_PRE_H_INCLUDED */ diff --git a/src/mpi/datatype/typerep/src/typerep_yaksa_commit.c b/src/mpi/datatype/typerep/src/typerep_yaksa_commit.c index cbed49b307a..9cc69800e67 100644 --- a/src/mpi/datatype/typerep/src/typerep_yaksa_commit.c +++ b/src/mpi/datatype/typerep/src/typerep_yaksa_commit.c @@ -16,31 +16,31 @@ void MPIR_Typerep_commit(MPI_Datatype type) uintptr_t num_contig_blocks; switch (type) { case MPI_FLOAT_INT: - typeptr->typerep.handle = (void *) YAKSA_TYPE__FLOAT_INT; + typeptr->typerep.handle = YAKSA_TYPE__FLOAT_INT; yaksa_iov_len(1, YAKSA_TYPE__FLOAT_INT, &num_contig_blocks); typeptr->typerep.num_contig_blocks = (MPI_Aint) num_contig_blocks; break; case MPI_DOUBLE_INT: - typeptr->typerep.handle = (void *) YAKSA_TYPE__DOUBLE_INT; + typeptr->typerep.handle = YAKSA_TYPE__DOUBLE_INT; yaksa_iov_len(1, YAKSA_TYPE__DOUBLE_INT, &num_contig_blocks); typeptr->typerep.num_contig_blocks = (MPI_Aint) num_contig_blocks; break; case MPI_LONG_INT: - typeptr->typerep.handle = (void *) YAKSA_TYPE__LONG_INT; + typeptr->typerep.handle = YAKSA_TYPE__LONG_INT; yaksa_iov_len(1, YAKSA_TYPE__LONG_INT, &num_contig_blocks); typeptr->typerep.num_contig_blocks = (MPI_Aint) num_contig_blocks; break; case MPI_SHORT_INT: - typeptr->typerep.handle = (void *) YAKSA_TYPE__SHORT_INT; + typeptr->typerep.handle = YAKSA_TYPE__SHORT_INT; yaksa_iov_len(1, YAKSA_TYPE__SHORT_INT, &num_contig_blocks); typeptr->typerep.num_contig_blocks = (MPI_Aint) num_contig_blocks; break; case MPI_LONG_DOUBLE_INT: - typeptr->typerep.handle = (void *) YAKSA_TYPE__LONG_DOUBLE_INT; + typeptr->typerep.handle = YAKSA_TYPE__LONG_DOUBLE_INT; yaksa_iov_len(1, YAKSA_TYPE__DOUBLE_INT, &num_contig_blocks); typeptr->typerep.num_contig_blocks = (MPI_Aint) num_contig_blocks; break; @@ -57,7 +57,7 @@ void MPIR_Typerep_free(MPIR_Datatype * typeptr) { MPIR_FUNC_ENTER; - yaksa_type_t type = (yaksa_type_t) (intptr_t) typeptr->typerep.handle; + yaksa_type_t type = typeptr->typerep.handle; if (type != YAKSA_TYPE__FLOAT_INT && type != YAKSA_TYPE__DOUBLE_INT && type != YAKSA_TYPE__LONG_INT && type != YAKSA_TYPE__SHORT_INT && diff --git a/src/mpi/datatype/typerep/src/typerep_yaksa_create.c b/src/mpi/datatype/typerep/src/typerep_yaksa_create.c index aeb444a1023..c7d7929ca88 100644 --- a/src/mpi/datatype/typerep/src/typerep_yaksa_create.c +++ b/src/mpi/datatype/typerep/src/typerep_yaksa_create.c @@ -18,7 +18,7 @@ static int update_yaksa_type(MPIR_Datatype * newtype, MPI_Datatype oldtype, MPI_ { int mpi_errno = MPI_SUCCESS; int rc; - yaksa_type_t dt = (yaksa_type_t) (intptr_t) newtype->typerep.handle; + yaksa_type_t dt = newtype->typerep.handle; uintptr_t num_contig_blocks; int cnt = 2; @@ -76,7 +76,7 @@ int MPIR_Typerep_create_vector(MPI_Aint count, MPI_Aint blocklength, MPI_Aint st yaksa_type_t type = MPII_Typerep_get_yaksa_type(oldtype); int rc = yaksa_type_create_vector(count, blocklength, stride, type, - NULL, (yaksa_type_t *) & newtype->typerep.handle); + NULL, &newtype->typerep.handle); MPIR_ERR_CHKANDJUMP(rc, mpi_errno, MPI_ERR_INTERN, "**yaksa"); mpi_errno = update_yaksa_type(newtype, oldtype, count * blocklength); @@ -99,7 +99,7 @@ int MPIR_Typerep_create_hvector(MPI_Aint count, MPI_Aint blocklength, MPI_Aint s yaksa_type_t type = MPII_Typerep_get_yaksa_type(oldtype); int rc = yaksa_type_create_hvector(count, blocklength, stride, type, - NULL, (yaksa_type_t *) & newtype->typerep.handle); + NULL, &newtype->typerep.handle); MPIR_ERR_CHKANDJUMP(rc, mpi_errno, MPI_ERR_INTERN, "**yaksa"); mpi_errno = update_yaksa_type(newtype, oldtype, count * blocklength); @@ -121,7 +121,7 @@ int MPIR_Typerep_create_contig(MPI_Aint count, MPI_Datatype oldtype, MPIR_Dataty yaksa_type_t type = MPII_Typerep_get_yaksa_type(oldtype); int rc = yaksa_type_create_contig(count, type, - NULL, (yaksa_type_t *) & newtype->typerep.handle); + NULL, &newtype->typerep.handle); MPIR_ERR_CHKANDJUMP(rc, mpi_errno, MPI_ERR_INTERN, "**yaksa"); mpi_errno = update_yaksa_type(newtype, oldtype, count); @@ -142,7 +142,7 @@ int MPIR_Typerep_create_dup(MPI_Datatype oldtype, MPIR_Datatype * newtype) yaksa_type_t type = MPII_Typerep_get_yaksa_type(oldtype); - int rc = yaksa_type_create_dup(type, NULL, (yaksa_type_t *) & newtype->typerep.handle); + int rc = yaksa_type_create_dup(type, NULL, &newtype->typerep.handle); MPIR_ERR_CHKANDJUMP(rc, mpi_errno, MPI_ERR_INTERN, "**yaksa"); mpi_errno = update_yaksa_type(newtype, oldtype, 1); @@ -168,7 +168,7 @@ int MPIR_Typerep_create_indexed_block(MPI_Aint count, MPI_Aint blocklength, int rc = yaksa_type_create_indexed_block(count, blocklength, (const intptr_t *) array_of_displacements, type, NULL, - (yaksa_type_t *) & newtype->typerep.handle); + &newtype->typerep.handle); MPIR_ERR_CHKANDJUMP(rc, mpi_errno, MPI_ERR_INTERN, "**yaksa"); mpi_errno = update_yaksa_type(newtype, oldtype, count * blocklength); @@ -193,7 +193,7 @@ int MPIR_Typerep_create_hindexed_block(MPI_Aint count, MPI_Aint blocklength, int rc = yaksa_type_create_hindexed_block(count, blocklength, (const intptr_t *) array_of_displacements, type, NULL, - (yaksa_type_t *) & newtype->typerep.handle); + &newtype->typerep.handle); MPIR_ERR_CHKANDJUMP(rc, mpi_errno, MPI_ERR_INTERN, "**yaksa"); mpi_errno = update_yaksa_type(newtype, oldtype, count * blocklength); @@ -218,7 +218,7 @@ int MPIR_Typerep_create_indexed(MPI_Aint count, const MPI_Aint * array_of_blockl int rc = yaksa_type_create_indexed(count, (const intptr_t *) array_of_blocklengths, (const intptr_t *) array_of_displacements, - type, NULL, (yaksa_type_t *) & newtype->typerep.handle); + type, NULL, &newtype->typerep.handle); MPIR_ERR_CHKANDJUMP(rc, mpi_errno, MPI_ERR_INTERN, "**yaksa"); MPI_Aint old_ct = 0; @@ -247,7 +247,7 @@ int MPIR_Typerep_create_hindexed(MPI_Aint count, const MPI_Aint * array_of_block int rc = yaksa_type_create_hindexed(count, (const intptr_t *) array_of_blocklengths, (const intptr_t *) array_of_displacements, - type, NULL, (yaksa_type_t *) & newtype->typerep.handle); + type, NULL, &newtype->typerep.handle); MPIR_ERR_CHKANDJUMP(rc, mpi_errno, MPI_ERR_INTERN, "**yaksa"); MPI_Aint old_ct = 0; @@ -274,7 +274,7 @@ int MPIR_Typerep_create_resized(MPI_Datatype oldtype, MPI_Aint lb, MPI_Aint exte yaksa_type_t type = MPII_Typerep_get_yaksa_type(oldtype); int rc = yaksa_type_create_resized(type, lb, extent, NULL, - (yaksa_type_t *) & newtype->typerep.handle); + &newtype->typerep.handle); MPIR_ERR_CHKANDJUMP(rc, mpi_errno, MPI_ERR_INTERN, "**yaksa"); mpi_errno = update_yaksa_type(newtype, oldtype, 1); @@ -304,7 +304,7 @@ int MPIR_Typerep_create_struct(MPI_Aint count, const MPI_Aint * array_of_blockle int rc = yaksa_type_create_struct(count, (const intptr_t *) array_of_blocklengths, (const intptr_t *) array_of_displacements, array_of_yaksa_types, NULL, - (yaksa_type_t *) & newtype->typerep.handle); + &newtype->typerep.handle); MPIR_ERR_CHKANDJUMP(rc, mpi_errno, MPI_ERR_INTERN, "**yaksa"); mpi_errno = update_yaksa_type(newtype, MPI_DATATYPE_NULL, 0); diff --git a/src/mpi/datatype/typerep/src/typerep_yaksa_init.c b/src/mpi/datatype/typerep/src/typerep_yaksa_init.c index 4873c2132cb..0c4fbd334cb 100644 --- a/src/mpi/datatype/typerep/src/typerep_yaksa_init.c +++ b/src/mpi/datatype/typerep/src/typerep_yaksa_init.c @@ -346,7 +346,7 @@ yaksa_type_t MPII_Typerep_get_yaksa_type(MPI_Datatype type) MPIR_Datatype *typeptr; MPIR_Datatype_get_ptr(type, typeptr); MPIR_Assert(typeptr != NULL); - yaksa_type = ((yaksa_type_t) (intptr_t) typeptr->typerep.handle); + yaksa_type = typeptr->typerep.handle; } } break; diff --git a/src/mpi/datatype/typeutil.c b/src/mpi/datatype/typeutil.c index bd1d48c6b6d..28b2f402ff3 100644 --- a/src/mpi/datatype/typeutil.c +++ b/src/mpi/datatype/typeutil.c @@ -427,7 +427,7 @@ int MPII_Type_zerolen(MPI_Datatype * newtype) new_dtp->contents = NULL; new_dtp->flattened = NULL; - new_dtp->typerep.handle = NULL; + new_dtp->typerep.handle = MPIR_TYPEREP_HANDLE_NULL; new_dtp->size = 0; new_dtp->lb = 0; From a686507696b852d082ab3df68760e2ffcd2546ec Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 5 Oct 2021 16:04:17 -0500 Subject: [PATCH 051/607] ch4/ofi: fix mpi_to_ofi The old code converting from MPI predefined datatypes to libfabric types using assumed datatype sizes. This is not robust for different platforms. For example, assuming MPI_LONG, MPI_AINT, and MPI_OFFSET are 8 bytes is wrong on 32-bit platforms. Revise the conversion using the actual datatype size instead. --- src/mpid/ch4/netmod/ofi/util.c | 109 ++++++++++++++++----------------- 1 file changed, 52 insertions(+), 57 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/util.c b/src/mpid/ch4/netmod/ofi/util.c index d94fbd43eff..f3451761d85 100644 --- a/src/mpid/ch4/netmod/ofi/util.c +++ b/src/mpid/ch4/netmod/ofi/util.c @@ -188,33 +188,9 @@ int MPIDI_OFI_control_handler(void *am_hdr, void *data, MPI_Aint data_sz, /* MPI Datatype Processing for RMA */ -#define isS_INT(x) ((x)==MPI_INTEGER || \ - (x) == MPI_INT32_T || (x) == MPI_INTEGER4 || \ - (x) == MPI_INT) -#define isUS_INT(x) ((x) == MPI_UINT32_T || (x) == MPI_UNSIGNED) -#define isS_SHORT(x) ((x) == MPI_SHORT || (x) == MPI_INT16_T || \ - (x) == MPI_INTEGER2) -#define isUS_SHORT(x) ((x) == MPI_UNSIGNED_SHORT || (x) == MPI_UINT16_T) -#define isS_CHAR(x) ((x) == MPI_SIGNED_CHAR || (x) == MPI_INT8_T || \ - (x) == MPI_INTEGER1 || (x) == MPI_CHAR) -#define isUS_CHAR(x) ((x) == MPI_BYTE || \ - (x) == MPI_UNSIGNED_CHAR || (x) == MPI_UINT8_T) -#define isS_LONG(x) ((x) == MPI_LONG || (x) == MPI_AINT) -#define isUS_LONG(x) ((x) == MPI_UNSIGNED_LONG) -#define isS_LONG_LONG(x) ((x) == MPI_INT64_T || (x) == MPI_OFFSET || \ - (x) == MPI_INTEGER8 || (x) == MPI_LONG_LONG || \ - (x) == MPI_LONG_LONG_INT || (x) == MPI_COUNT) -#define isUS_LONG_LONG(x) ((x) == MPI_UINT64_T || (x) == MPI_UNSIGNED_LONG_LONG) #define isFLOAT(x) ((x) == MPI_FLOAT || (x) == MPI_REAL) #define isDOUBLE(x) ((x) == MPI_DOUBLE || (x) == MPI_DOUBLE_PRECISION) #define isLONG_DOUBLE(x) ((x) == MPI_LONG_DOUBLE) -#define isLOC_TYPE(x) ((x) == MPI_2REAL || (x) == MPI_2DOUBLE_PRECISION || \ - (x) == MPI_2INTEGER || (x) == MPI_FLOAT_INT || \ - (x) == MPI_DOUBLE_INT || (x) == MPI_LONG_INT || \ - (x) == MPI_2INT || (x) == MPI_SHORT_INT || \ - (x) == MPI_LONG_DOUBLE_INT) -#define isBOOL(x) ((x) == MPI_C_BOOL) -#define isLOGICAL(x) ((x) == MPI_LOGICAL) #define isSINGLE_COMPLEX(x) ((x) == MPI_COMPLEX || (x) == MPI_C_FLOAT_COMPLEX) #define isDOUBLE_COMPLEX(x) ((x) == MPI_DOUBLE_COMPLEX || (x) == MPI_COMPLEX8 || \ (x) == MPI_C_DOUBLE_COMPLEX) @@ -247,45 +223,64 @@ static int mpi_to_ofi(MPI_Datatype dt, enum fi_datatype *fi_dt, MPI_Op op, enum *fi_dt = FI_DATATYPE_LAST; *fi_op = FI_ATOMIC_OP_LAST; - if (isS_INT(dt)) - *fi_dt = FI_INT32; - else if (isUS_INT(dt)) - *fi_dt = FI_UINT32; - else if (isFLOAT(dt)) + int dt_size; + MPIR_Datatype_get_size_macro(dt, dt_size); + + if (dt == MPI_CHAR || dt == MPI_SIGNED_CHAR || dt == MPI_SHORT || + dt == MPI_INT || dt == MPI_LONG || dt == MPI_LONG_LONG || + dt == MPI_INT8_T || dt == MPI_INT16_T || dt == MPI_INT32_T || dt == MPI_INT64_T || + dt == MPI_INTEGER || dt == MPI_INTEGER1 || dt == MPI_INTEGER2 || + dt == MPI_INTEGER4 || dt == MPI_INTEGER8 || + dt == MPI_AINT || dt == MPI_COUNT || dt == MPI_OFFSET) { + switch (dt_size) { + case 1: + *fi_dt = FI_INT8; + break; + case 2: + *fi_dt = FI_INT16; + break; + case 4: + *fi_dt = FI_INT32; + break; + case 8: + *fi_dt = FI_INT64; + break; + default: + goto fn_fail; + } + } else if (dt == MPI_UNSIGNED_CHAR || dt == MPI_UNSIGNED_SHORT || dt == MPI_UNSIGNED || + dt == MPI_UNSIGNED_LONG || dt == MPI_UNSIGNED_LONG_LONG || + dt == MPI_UINT8_T || dt == MPI_UINT16_T || dt == MPI_UINT32_T || + dt == MPI_UINT64_T || dt == MPI_C_BOOL || dt == MPI_LOGICAL) { + switch (dt_size) { + case 1: + *fi_dt = FI_UINT8; + break; + case 2: + *fi_dt = FI_UINT16; + break; + case 4: + *fi_dt = FI_UINT32; + break; + case 8: + *fi_dt = FI_UINT64; + break; + default: + goto fn_fail; + } + } else if (isFLOAT(dt)) { *fi_dt = FI_FLOAT; - else if (isDOUBLE(dt)) + } else if (isDOUBLE(dt)) { *fi_dt = FI_DOUBLE; - else if (isLONG_DOUBLE(dt)) + } else if (isLONG_DOUBLE(dt)) { *fi_dt = FI_LONG_DOUBLE; - else if (isS_CHAR(dt)) - *fi_dt = FI_INT8; - else if (isUS_CHAR(dt)) - *fi_dt = FI_UINT8; - else if (isS_SHORT(dt)) - *fi_dt = FI_INT16; - else if (isUS_SHORT(dt)) - *fi_dt = FI_UINT16; - else if (isS_LONG(dt)) - *fi_dt = FI_INT64; - else if (isUS_LONG(dt)) - *fi_dt = FI_UINT64; - else if (isS_LONG_LONG(dt)) - *fi_dt = FI_INT64; - else if (isUS_LONG_LONG(dt)) - *fi_dt = FI_UINT64; - else if (isSINGLE_COMPLEX(dt)) + } else if (isSINGLE_COMPLEX(dt)) { *fi_dt = FI_FLOAT_COMPLEX; - else if (isDOUBLE_COMPLEX(dt)) + } else if (isDOUBLE_COMPLEX(dt)) { *fi_dt = FI_DOUBLE_COMPLEX; - else if (isLOC_TYPE(dt)) - *fi_dt = FI_DATATYPE_LAST; - else if (isLOGICAL(dt)) - *fi_dt = FI_UINT32; - else if (isBOOL(dt)) - *fi_dt = FI_UINT8; - - if (*fi_dt == FI_DATATYPE_LAST) + } else { goto fn_fail; + } *fi_op = FI_ATOMIC_OP_LAST; From 2d8187b970f03f2dcf7df3d12a9b667486fbb35d Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 6 Oct 2021 13:31:13 -0500 Subject: [PATCH 052/607] mpif_h: always check MPIR_F_NeedInit Since now we remove the mpirinitf_ symbol from libmpi.so -- it's in libmpifort.so -- we need always check MPIR_F_NeedInit and do the lazy init. This is because application may call MPI_Init from the C side, thus never call mpirinitf_() during init. --- src/binding/fortran/mpif_h/buildiface | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/binding/fortran/mpif_h/buildiface b/src/binding/fortran/mpif_h/buildiface index d02528dcb2d..544a0c83e58 100755 --- a/src/binding/fortran/mpif_h/buildiface +++ b/src/binding/fortran/mpif_h/buildiface @@ -96,16 +96,8 @@ our $prototype_file_b = "../../../include/mpi_proto.h"; # Fortran runtime. Thus, we must check whether the values are initialized # before any use in any routine. # -# Having said the above, however, if the environment (specifically, the -# C and Fortran compilers) makes it easy for the C init routines to initialize -# the Fortran environment, then we should make that easy. This is indicated -# by the CPP name HAVE_MPI_F_INIT_WORKS_WITH_C. If that is defined, then -# there is no lazy initialization of these values. $specialInitAdded = 0; -$specialInitString = "\ -#ifndef HAVE_MPI_F_INIT_WORKS_WITH_C - if (MPIR_F_NeedInit){ mpirinitf_(); MPIR_F_NeedInit = 0; } -#endif"; +$specialInitString = "if (MPIR_F_NeedInit){ mpirinitf_(); MPIR_F_NeedInit = 0;}"; # Process arguments # From b8167e6273c9fb819756baeabe48134d15dd70fb Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 11 Oct 2021 22:30:50 -0500 Subject: [PATCH 053/607] typerep/yaksa: suppress warnings on used variable The dtp variable is only used when error checking is enabled. --- src/mpi/datatype/typerep/src/typerep_yaksa_pack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c b/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c index fa28c22edb7..23748b14c5e 100644 --- a/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c +++ b/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c @@ -629,7 +629,7 @@ static int typerep_op_fallback(void *source_buf, MPI_Aint source_count, MPI_Data MPI_Aint vec_len; struct iovec *typerep_vec = NULL; { - MPIR_Datatype *dtp; + MPIR_Datatype *dtp ATTRIBUTE((unused)); MPIR_Datatype_get_ptr(target_dtp, dtp); MPIR_Assert(dtp != NULL); MPIR_Assert(dtp->basic_type == source_dtp); From cf988915db26ade622f280bcc08d462d67747972 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 5 Oct 2021 23:26:08 -0500 Subject: [PATCH 054/607] test: update xfail entry on rma/rma_contig We need update the xfail regex since we changed the iteration count. --- test/mpi/maint/jenkins/xfail.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/mpi/maint/jenkins/xfail.conf b/test/mpi/maint/jenkins/xfail.conf index 09ad90d5a8c..b7dbac1fe40 100644 --- a/test/mpi/maint/jenkins/xfail.conf +++ b/test/mpi/maint/jenkins/xfail.conf @@ -106,7 +106,7 @@ * * debug ch3:tcp freebsd64 /^comm_create_group_threads/ xfail=issue4372 test/mpi/threads/comm/testlist # timeout due to lack of passive progress -* * vci ch4:ofi * /^rma_contig.*iter=32768/ xfail=issue5565 test/mpi/rma/testlist +* * vci ch4:ofi * /^rma_contig.*iter=10000/ xfail=issue5565 test/mpi/rma/testlist # Job-sepecific xfails # Our Arm servers are too slow for some tests From de13716d67358fd856da7d106bcdd1fcfb7c8f2a Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 13 Oct 2021 09:18:29 -0500 Subject: [PATCH 055/607] ch4/ofi: add missing MPI_BYTE in mpi_to_ofi MPI_BYTE was neglected in PR #5582. --- src/mpid/ch4/netmod/ofi/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mpid/ch4/netmod/ofi/util.c b/src/mpid/ch4/netmod/ofi/util.c index f3451761d85..0acadbda78a 100644 --- a/src/mpid/ch4/netmod/ofi/util.c +++ b/src/mpid/ch4/netmod/ofi/util.c @@ -226,7 +226,7 @@ static int mpi_to_ofi(MPI_Datatype dt, enum fi_datatype *fi_dt, MPI_Op op, enum int dt_size; MPIR_Datatype_get_size_macro(dt, dt_size); - if (dt == MPI_CHAR || dt == MPI_SIGNED_CHAR || dt == MPI_SHORT || + if (dt == MPI_BYTE || dt == MPI_CHAR || dt == MPI_SIGNED_CHAR || dt == MPI_SHORT || dt == MPI_INT || dt == MPI_LONG || dt == MPI_LONG_LONG || dt == MPI_INT8_T || dt == MPI_INT16_T || dt == MPI_INT32_T || dt == MPI_INT64_T || dt == MPI_INTEGER || dt == MPI_INTEGER1 || dt == MPI_INTEGER2 || From 4fb2dd752bd7d8c5ffec39afa3cc63487e45a3eb Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 5 Oct 2021 11:02:34 -0500 Subject: [PATCH 056/607] spawn: add MPIR_FUNC_ENTER/EXIT in spawn_impl.c Add the missing function logging and mpi_errno return. --- src/mpi/spawn/spawn_impl.c | 50 ++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/src/mpi/spawn/spawn_impl.c b/src/mpi/spawn/spawn_impl.c index e892c613400..e2a45b50071 100644 --- a/src/mpi/spawn/spawn_impl.c +++ b/src/mpi/spawn/spawn_impl.c @@ -22,8 +22,11 @@ static int MPIR_fd_send(int fd, void *buffer, int length) { + int mpi_errno = MPI_SUCCESS; int result, num_bytes; + MPIR_FUNC_ENTER; + while (length) { /* The expectation is that the length of a join message will fit * in an int. For Unixes that define send as returning ssize_t, @@ -36,10 +39,12 @@ static int MPIR_fd_send(int fd, void *buffer, int length) #else result = errno; #endif - if (result == SOCKET_EINTR) + if (result == SOCKET_EINTR) { continue; - else - return result; + } else { + MPIR_ERR_SET1(mpi_errno, MPI_ERR_INTERN, "**join_send", "**join_send %d", result); + goto fn_fail; + } } /* --END ERROR HANDLING-- */ else { @@ -47,13 +52,21 @@ static int MPIR_fd_send(int fd, void *buffer, int length) buffer = (char *) buffer + num_bytes; } } - return 0; + + fn_exit: + MPIR_FUNC_EXIT; + return mpi_errno; + fn_fail: + goto fn_exit; } static int MPIR_fd_recv(int fd, void *buffer, int length) { + int mpi_errno = MPI_SUCCESS; int result, num_bytes; + MPIR_FUNC_ENTER; + while (length) { /* See discussion on send above for the cast to int. */ num_bytes = (int) recv(fd, buffer, length, 0); @@ -64,10 +77,12 @@ static int MPIR_fd_recv(int fd, void *buffer, int length) #else result = errno; #endif - if (result == SOCKET_EINTR) + if (result == SOCKET_EINTR) { continue; - else - return result; + } else { + MPIR_ERR_SET1(mpi_errno, MPI_ERR_INTERN, "**join_recv", "**join_recv %d", result); + goto fn_fail; + } } /* --END ERROR HANDLING-- */ else { @@ -75,17 +90,23 @@ static int MPIR_fd_recv(int fd, void *buffer, int length) buffer = (char *) buffer + num_bytes; } } - return 0; + + fn_exit: + MPIR_FUNC_EXIT; + return mpi_errno; + fn_fail: + goto fn_exit; } int MPIR_Comm_join_impl(int fd, MPIR_Comm ** p_intercomm_ptr) { int mpi_errno = MPI_SUCCESS; - int err; MPIR_Comm *intercomm_ptr; char *local_port, *remote_port; MPIR_CHKLMEM_DECL(2); + MPIR_FUNC_ENTER; + MPIR_CHKLMEM_MALLOC(local_port, char *, MPI_MAX_PORT_NAME, mpi_errno, "local port name", MPL_MEM_DYNAMIC); MPIR_CHKLMEM_MALLOC(remote_port, char *, MPI_MAX_PORT_NAME, mpi_errno, "remote port name", @@ -96,13 +117,11 @@ int MPIR_Comm_join_impl(int fd, MPIR_Comm ** p_intercomm_ptr) mpi_errno = MPIR_Open_port_impl(NULL, local_port); MPIR_ERR_CHKANDJUMP((mpi_errno != MPI_SUCCESS), mpi_errno, MPI_ERR_OTHER, "**openportfailed"); - err = MPIR_fd_send(fd, local_port, MPI_MAX_PORT_NAME); - MPIR_ERR_CHKANDJUMP1((err != 0), mpi_errno, MPI_ERR_INTERN, "**join_send", "**join_send %d", - err); + mpi_errno = MPIR_fd_send(fd, local_port, MPI_MAX_PORT_NAME); + MPIR_ERR_CHECK(mpi_errno); - err = MPIR_fd_recv(fd, remote_port, MPI_MAX_PORT_NAME); - MPIR_ERR_CHKANDJUMP1((err != 0), mpi_errno, MPI_ERR_INTERN, "**join_recv", "**join_recv %d", - err); + mpi_errno = MPIR_fd_recv(fd, remote_port, MPI_MAX_PORT_NAME); + MPIR_ERR_CHECK(mpi_errno); MPIR_ERR_CHKANDJUMP2((strcmp(local_port, remote_port) == 0), mpi_errno, MPI_ERR_INTERN, "**join_portname", "**join_portname %s %s", local_port, remote_port); @@ -126,6 +145,7 @@ int MPIR_Comm_join_impl(int fd, MPIR_Comm ** p_intercomm_ptr) fn_exit: MPIR_CHKLMEM_FREEALL(); + MPIR_FUNC_EXIT; return mpi_errno; fn_fail: goto fn_exit; From 7cbcadc1f11f747cd12af5bf22300b379ceaa4ba Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 5 Oct 2021 11:03:54 -0500 Subject: [PATCH 057/607] spawn: use nonblocking recv and poll global progress It is not safe to use blocking `recv` in MPIR_Comm_join_impl because the sender may be stuck in a barrier that is waiting for the injected send issued by this process. Use nonblocking recv and poll global progress in-between. --- src/mpi/spawn/spawn_impl.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/mpi/spawn/spawn_impl.c b/src/mpi/spawn/spawn_impl.c index e2a45b50071..34ca5b07dab 100644 --- a/src/mpi/spawn/spawn_impl.c +++ b/src/mpi/spawn/spawn_impl.c @@ -69,7 +69,7 @@ static int MPIR_fd_recv(int fd, void *buffer, int length) while (length) { /* See discussion on send above for the cast to int. */ - num_bytes = (int) recv(fd, buffer, length, 0); + num_bytes = (int) recv(fd, buffer, length, MSG_DONTWAIT); /* --BEGIN ERROR HANDLING-- */ if (num_bytes == -1) { #ifdef HAVE_WINDOWS_H @@ -77,7 +77,11 @@ static int MPIR_fd_recv(int fd, void *buffer, int length) #else result = errno; #endif - if (result == SOCKET_EINTR) { + if (result == SOCKET_EINTR || result == EAGAIN || result == EWOULDBLOCK) { + /* poll global progress. This is necessary in case the sender is stuck in a barrier + * which is waiting for an injected send from this process */ + mpi_errno = MPID_Progress_test(NULL); + MPIR_ERR_CHECK(mpi_errno); continue; } else { MPIR_ERR_SET1(mpi_errno, MPI_ERR_INTERN, "**join_recv", "**join_recv %d", result); From 9d9d1c52fc36dc2764800dae614eeaf6a694134e Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Wed, 29 Sep 2021 15:35:38 -0500 Subject: [PATCH 058/607] submodule: Update UCX to v1.11.2 --- modules/ucx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ucx b/modules/ucx index 38e773e538c..ef0e0fe320f 160000 --- a/modules/ucx +++ b/modules/ucx @@ -1 +1 @@ -Subproject commit 38e773e538c776691d21f11896ec8cceaa80e03b +Subproject commit ef0e0fe320fb67088b8d6ca67b584af5214b8a92 From 28813dbfaaa9edd79192dfab3e713d019a785f55 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Thu, 7 Oct 2021 13:21:02 -0500 Subject: [PATCH 059/607] ch4/ofi: Remove unnecessary brackets Brackets are not needed for case clauses, and they are not consistently applied in this instance. --- src/mpid/ch4/netmod/ofi/util.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/util.c b/src/mpid/ch4/netmod/ofi/util.c index 0acadbda78a..1ab5039d97c 100644 --- a/src/mpid/ch4/netmod/ofi/util.c +++ b/src/mpid/ch4/netmod/ofi/util.c @@ -335,20 +335,17 @@ static int mpi_to_ofi(MPI_Datatype dt, enum fi_datatype *fi_dt, MPI_Op op, enum *fi_op = FI_LXOR; goto fn_exit; - case MPI_REPLACE:{ - *fi_op = FI_ATOMIC_WRITE; - goto fn_exit; - } + case MPI_REPLACE: + *fi_op = FI_ATOMIC_WRITE; + goto fn_exit; - case MPI_NO_OP:{ - *fi_op = FI_ATOMIC_READ; - goto fn_exit; - } + case MPI_NO_OP: + *fi_op = FI_ATOMIC_READ; + goto fn_exit; - case MPI_OP_NULL:{ - *fi_op = FI_CSWAP; - goto fn_exit; - } + case MPI_OP_NULL: + *fi_op = FI_CSWAP; + goto fn_exit; default: goto fn_fail; From f6215f637a486eee4bf1459d602a329f10096b28 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Thu, 14 Oct 2021 10:49:35 -0500 Subject: [PATCH 060/607] ch4/ofi: Remove never checked return code The caller of this function never checks the return code. Any "error" was just treated as an unsupported operation as conveyed through the output parameters. Change the function to return void and remove the fn_fail label. Add comments to indicate no matching datatype or op was found. --- src/mpid/ch4/netmod/ofi/util.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/util.c b/src/mpid/ch4/netmod/ofi/util.c index 1ab5039d97c..618f28de813 100644 --- a/src/mpid/ch4/netmod/ofi/util.c +++ b/src/mpid/ch4/netmod/ofi/util.c @@ -218,7 +218,7 @@ static bool check_mpi_acc_valid(MPI_Datatype dtype, MPI_Op op) return valid_flag; } -static int mpi_to_ofi(MPI_Datatype dt, enum fi_datatype *fi_dt, MPI_Op op, enum fi_op *fi_op) +static void mpi_to_ofi(MPI_Datatype dt, enum fi_datatype *fi_dt, MPI_Op op, enum fi_op *fi_op) { *fi_dt = FI_DATATYPE_LAST; *fi_op = FI_ATOMIC_OP_LAST; @@ -246,7 +246,8 @@ static int mpi_to_ofi(MPI_Datatype dt, enum fi_datatype *fi_dt, MPI_Op op, enum *fi_dt = FI_INT64; break; default: - goto fn_fail; + /* no matching type */ + goto fn_exit; } } else if (dt == MPI_UNSIGNED_CHAR || dt == MPI_UNSIGNED_SHORT || dt == MPI_UNSIGNED || dt == MPI_UNSIGNED_LONG || dt == MPI_UNSIGNED_LONG_LONG || @@ -266,7 +267,8 @@ static int mpi_to_ofi(MPI_Datatype dt, enum fi_datatype *fi_dt, MPI_Op op, enum *fi_dt = FI_UINT64; break; default: - goto fn_fail; + /* no matching type */ + goto fn_exit; } } else if (isFLOAT(dt)) { *fi_dt = FI_FLOAT; @@ -279,7 +281,8 @@ static int mpi_to_ofi(MPI_Datatype dt, enum fi_datatype *fi_dt, MPI_Op op, enum } else if (isDOUBLE_COMPLEX(dt)) { *fi_dt = FI_DOUBLE_COMPLEX; } else { - goto fn_fail; + /* no matching type */ + goto fn_exit; } *fi_op = FI_ATOMIC_OP_LAST; @@ -316,21 +319,21 @@ static int mpi_to_ofi(MPI_Datatype dt, enum fi_datatype *fi_dt, MPI_Op op, enum case MPI_LAND: if (isLONG_DOUBLE(dt)) - goto fn_fail; + goto fn_exit; *fi_op = FI_LAND; goto fn_exit; case MPI_LOR: if (isLONG_DOUBLE(dt)) - goto fn_fail; + goto fn_exit; *fi_op = FI_LOR; goto fn_exit; case MPI_LXOR: if (isLONG_DOUBLE(dt)) - goto fn_fail; + goto fn_exit; *fi_op = FI_LXOR; goto fn_exit; @@ -348,13 +351,12 @@ static int mpi_to_ofi(MPI_Datatype dt, enum fi_datatype *fi_dt, MPI_Op op, enum goto fn_exit; default: - goto fn_fail; + /* no matching op */ + goto fn_exit; } fn_exit: - return MPI_SUCCESS; - fn_fail: - return -1; + return; } #define _TBL MPIDI_OFI_global.win_op_table[i][j] From 71af40f447ef6684f491a980fab12504a49ed440 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Thu, 14 Oct 2021 10:54:41 -0500 Subject: [PATCH 061/607] ch4/ofi: Simplify logic for logical operation mapping Instead of using a goto within a case clause, just use a regular branch to skip any unsupported types for logical operations. --- src/mpid/ch4/netmod/ofi/util.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/util.c b/src/mpid/ch4/netmod/ofi/util.c index 618f28de813..80dbeb84de2 100644 --- a/src/mpid/ch4/netmod/ofi/util.c +++ b/src/mpid/ch4/netmod/ofi/util.c @@ -318,24 +318,21 @@ static void mpi_to_ofi(MPI_Datatype dt, enum fi_datatype *fi_dt, MPI_Op op, enum break; case MPI_LAND: - if (isLONG_DOUBLE(dt)) - goto fn_exit; - - *fi_op = FI_LAND; + if (!isLONG_DOUBLE(dt)) { + *fi_op = FI_LAND; + } goto fn_exit; case MPI_LOR: - if (isLONG_DOUBLE(dt)) - goto fn_exit; - - *fi_op = FI_LOR; + if (!isLONG_DOUBLE(dt)) { + *fi_op = FI_LOR; + } goto fn_exit; case MPI_LXOR: - if (isLONG_DOUBLE(dt)) - goto fn_exit; - - *fi_op = FI_LXOR; + if (!isLONG_DOUBLE(dt)) { + *fi_op = FI_LXOR; + } goto fn_exit; case MPI_REPLACE: From 1f12e239e85e84191e7671db2cb9377144cae814 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Thu, 14 Oct 2021 11:00:26 -0500 Subject: [PATCH 062/607] ch4/ofi: Use break instead of goto in case clause break is more conventional to end case clauses, and is functionally the same in this instance. --- src/mpid/ch4/netmod/ofi/util.c | 40 +++++++++++----------------------- 1 file changed, 13 insertions(+), 27 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/util.c b/src/mpid/ch4/netmod/ofi/util.c index 80dbeb84de2..402be41f7e4 100644 --- a/src/mpid/ch4/netmod/ofi/util.c +++ b/src/mpid/ch4/netmod/ofi/util.c @@ -290,66 +290,52 @@ static void mpi_to_ofi(MPI_Datatype dt, enum fi_datatype *fi_dt, MPI_Op op, enum switch (op) { case MPI_SUM: *fi_op = FI_SUM; - goto fn_exit; - + break; case MPI_PROD: *fi_op = FI_PROD; - goto fn_exit; - + break; case MPI_MAX: *fi_op = FI_MAX; - goto fn_exit; - + break; case MPI_MIN: *fi_op = FI_MIN; - goto fn_exit; - + break; case MPI_BAND: *fi_op = FI_BAND; - goto fn_exit; - + break; case MPI_BOR: *fi_op = FI_BOR; - goto fn_exit; - + break; case MPI_BXOR: *fi_op = FI_BXOR; - goto fn_exit; break; - case MPI_LAND: if (!isLONG_DOUBLE(dt)) { *fi_op = FI_LAND; } - goto fn_exit; - + break; case MPI_LOR: if (!isLONG_DOUBLE(dt)) { *fi_op = FI_LOR; } - goto fn_exit; - + break; case MPI_LXOR: if (!isLONG_DOUBLE(dt)) { *fi_op = FI_LXOR; } - goto fn_exit; - + break; case MPI_REPLACE: *fi_op = FI_ATOMIC_WRITE; - goto fn_exit; - + break; case MPI_NO_OP: *fi_op = FI_ATOMIC_READ; - goto fn_exit; - + break; case MPI_OP_NULL: *fi_op = FI_CSWAP; - goto fn_exit; - + break; default: /* no matching op */ - goto fn_exit; + break; } fn_exit: From 639ef6e87c398252bc0d2c124d4329eb231b7669 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Thu, 14 Oct 2021 11:01:40 -0500 Subject: [PATCH 063/607] ch4/ofi: Add FIXME for skipping logical floating point operators Right now we do not setup libfabric logical operators for long double types. We may want to consider doing the same for other floating point types. --- src/mpid/ch4/netmod/ofi/util.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mpid/ch4/netmod/ofi/util.c b/src/mpid/ch4/netmod/ofi/util.c index 402be41f7e4..c35f3de4caa 100644 --- a/src/mpid/ch4/netmod/ofi/util.c +++ b/src/mpid/ch4/netmod/ofi/util.c @@ -310,16 +310,19 @@ static void mpi_to_ofi(MPI_Datatype dt, enum fi_datatype *fi_dt, MPI_Op op, enum *fi_op = FI_BXOR; break; case MPI_LAND: + /* FIXME: ignore all fp types? */ if (!isLONG_DOUBLE(dt)) { *fi_op = FI_LAND; } break; case MPI_LOR: + /* FIXME: ignore all fp types? */ if (!isLONG_DOUBLE(dt)) { *fi_op = FI_LOR; } break; case MPI_LXOR: + /* FIXME: ignore all fp types? */ if (!isLONG_DOUBLE(dt)) { *fi_op = FI_LXOR; } From 0b1f858a95e37829934cfa539ef555f1ca86d54a Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 4 Oct 2021 10:16:35 -0500 Subject: [PATCH 064/607] fortran: allow build with long fortran integer --- configure.ac | 6 +----- src/binding/fortran/mpif_h/buildiface | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 9bd7b309cec..4288360d57c 100644 --- a/configure.ac +++ b/configure.ac @@ -3770,11 +3770,7 @@ dnl Removed MPI_2COMPLEX and MPI_2DOUBLE_COMPLEX, leaving comments to explain th # interface (was error) # Check to see if the f77 binding has enabled the code to support # the case of int != fint. - if grep HAVE_FINT_IS_INT $main_top_srcdir/src/binding/fortran/mpif_h/testf.c 2>&1 1>/dev/null ; then - AC_MSG_WARN([Fortran integers and C ints are not the same size. Support for this case is experimental; use at your own risk]) - else - AC_MSG_ERROR([Fortran integers and C ints are not the same size. The current Fortran binding does not support this case. Either force the Fortran compiler to use integers of $ac_cv_sizeof_int bytes, or use --disable-fortran on the configure line for MPICH.]) - fi + AC_MSG_WARN([Fortran integers and C ints are not the same size. Support for this case is experimental; use at your own risk]) fi # We must convert all hex values to decimal (!). diff --git a/src/binding/fortran/mpif_h/buildiface b/src/binding/fortran/mpif_h/buildiface index 544a0c83e58..6ff4d67aaf8 100755 --- a/src/binding/fortran/mpif_h/buildiface +++ b/src/binding/fortran/mpif_h/buildiface @@ -44,7 +44,7 @@ my @out_prefixes = qw(mpi_ mpix_); $header_file = "mpi_fortimpl.h"; $debug = 0; $writeRoutineList = 0; # Set to 1 to get a list of MPI routines -$do_fint = 0; # Set to 1 to support C and Fortran integers of a +$do_fint = 1; # Set to 1 to support C and Fortran integers of a # different size $within_fint = 0; # This is set to 1 while generating code for the # do_fint branch From 45719e8ebbc5f4c7fec5aa3c72c55943a0dcf775 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 11 Oct 2021 19:49:34 -0500 Subject: [PATCH 065/607] fortran: add string util functions in mpi_fortimpl.h Rather than generate the string conversion functions, add them in mpi_fortimpl.h. Even though we are going to replace the buildiface script, it is updated in the commit to use the new string functions, so we can test it. Instead of initiating MPI_F_ARGV_NULL with empty string, it is more reliable to check for the address explicitly, the same way as we do for all other builtin names. --- src/binding/fortran/mpif_h/buildiface | 210 +++------------------- src/binding/fortran/mpif_h/mpi_fortimpl.h | 143 +++++++++++++++ src/binding/fortran/mpif_h/setbot.c.in | 23 +-- src/binding/fortran/mpif_h/setbotf.f.in | 3 +- 4 files changed, 173 insertions(+), 206 deletions(-) diff --git a/src/binding/fortran/mpif_h/buildiface b/src/binding/fortran/mpif_h/buildiface index 6ff4d67aaf8..e2629cead33 100755 --- a/src/binding/fortran/mpif_h/buildiface +++ b/src/binding/fortran/mpif_h/buildiface @@ -3163,9 +3163,8 @@ sub blankpad_ctof { $cvar =~ s/^v/p/; # Only execute this code if there was no error print $OUTFD "\ - if (!$errparmrval) {char *p = $outvar, *pc=$cvar; - while (*pc) {*p++ = *pc++;} - while ((p-$outvar) < $strlen) { *p++ = ' '; } + if (!$errparmrval) { + MPIR_fort_copy_str_from_c($outvar, $strlen, $cvar); } "; $clean_up .= " free( $cvar );\n"; @@ -3253,22 +3252,7 @@ sub addnull_in_arg { sub addnull_ftoc { my $count = $_[0]; - # Working backwards from the length argument, find the first - # nonblank character - # end of the string. The declared length is given by a variable - # whose name is derived from outvar - $strlen = "v$count"; - $strlen =~ s/^v/d/; - print $OUTFD "\ - {char *p = v$count + $strlen - 1; - int li; - while (*p == ' ' && p > v$count) p--; - p++; - p$count = (char *)malloc(p-v$count + 1); - for (li=0; li<(p-v$count); li++) { p$count\[li\] = v$count\[li\]; } - p$count\[li\] = 0; - } -"; + print $OUTFD " p$count = MPIR_fort_dup_str(v$count, d$count);\n"; $clean_up .= " free( p$count );\n"; } # ---------------------------------------------------------------------------- @@ -3287,24 +3271,7 @@ sub addnullandtrim_in_arg { sub addnullandtrim_ftoc { my $count = $_[0]; - # Working backwards from the length argument, find the first - # nonblank character - # end of the string. The declared length is given by a variable - # whose name is derived from outvar - $strlen = "v$count"; - $strlen =~ s/^v/d/; - print $OUTFD "\ - {char *p = v$count + $strlen - 1; - char *pin = v$count; - int li; - while (*p == ' ' && p > v$count) p--; - p++; - while (*pin == ' ' && pin < p) pin++; - p$count = (char *)malloc(p-pin + 1); - for (li=0; li<(p-pin); li++) { p$count\[li\] = pin\[li\]; } - p$count\[li\] = 0; - } -"; + print $OUTFD " p$count = MPIR_fort_dup_str(v$count, d$count);\n"; $clean_up .= " free( p$count );\n"; } @@ -3315,9 +3282,6 @@ sub addnullandtrim_ftoc { sub chararray_in_decl { my $count = $_[0]; print $OUTFD " char **p$count;\n"; - if (!$Array_size) { print $OUTFD " char *pcpy$count;\n"; } - # pcpy is used for the case where the array length is not known - print $OUTFD " int asize$count=0;\n"; } sub chararray_in_arg { my $count = $_[0]; @@ -3326,54 +3290,19 @@ sub chararray_in_arg { sub chararray_ftoc { my $count = $_[0]; - # There is a special case - the input is MPI_ARGV_NULL. We - # detect this by checking for a null string (all blanks). - # The initialization of MPI_ARGV_NULL is done in the special - #init setup - &specialInitStatement( $OUTFD ); - # First, compute the number of elements. In Fortran, a null - # string terminates the array. The array is stored as - # a two-dimensional field of fixed-length characters. - # Then copy the strings into the new storage, appending the - # null at the end - print $OUTFD "\ - { int i; - char *ptmp = NULL;\n"; + my $asize = 0; if ($Array_size) { - print $OUTFD "\ - asize$count = (int)$Array_size + 1;\n"; - } - else { - print $OUTFD "\ - /* Compute the size of the array by looking for an all-blank line */ - pcpy$count = v$count; - for (asize$count=1; 1; asize$count++) { - char *pt = pcpy$count + d$count - 1; - while (*pt == ' ' && pt > pcpy$count) pt--; - if (*pt == ' ') break; - pcpy$count += d$count; - }\n"; + $asize = $Array_size; } - print $OUTFD "\ - p$count = (char **)malloc( asize$count * sizeof(char *)); - if (asize$count-1 > 0) ptmp = (char *)malloc(asize$count * (d$count + 1)); - for (i=0; i p) pin--; - /* Copy and then null terminate */ - for (j=0; j<(pin-p)+1; j++) { pdest\[j\] = p\[j\]; } - pdest\[j\] = 0; - } - /* Null terminate the array */ - p$count\[asize$count-1\] = 0; + print $OUTFD " if (v$count == MPI_F_ARGV_NULL) {\n"; + print $OUTFD " p$count = MPI_ARGV_NULL;\n"; + print $OUTFD " } else {\n"; + print $OUTFD " p$count = MPIR_fort_dup_str_array(v$count, d$count, d$count, $asize);\n"; + print $OUTFD " }\n"; + + $clean_up .= " if (v$count != MPI_F_ARGV_NULL) { + MPIR_fort_free_str_array(p$count); }\n"; - $clean_up .= " if (asize$count-1 > 0) free( p$count\[0\] );\n free( p$count );\n"; } # Add null to 2-dimensional arrays of input strings. Used only @@ -3396,111 +3325,14 @@ sub chararray2_ftoc { return 1; } - # First, compute the number of elements. In Fortran, a null - # string terminates the array. The array is stored as - # a two-dimensional field of fixed-length characters. - # Then copy the strings into the new storage, appending the - # null at the end - # Since this is a 2-d array, we always know the first dimension, - # the second dimension must be computed, this is asize$count. - # The first dimension is Array_size. - &specialInitStatement( $OUTFD ); - print $OUTFD "\ - /* Check for the special case of a the null args case. */ - if (v$count == MPI_F_ARGVS_NULL) { v$count = (char *)MPI_ARGVS_NULL; } - else { - /* We must convert from the 2-dimensional Fortran array of - fixed length strings to a C variable-sized array (really an - array of pointers for each command of pointers to each - argument, which is null terminated.*/\n"; - - # We must be careful. A blank line is ALL blank, not just leading blank - # We must also be careful allocating the array, as C and Fortran - # arrays are not the same. In C, for a two dimensional array - # sized at run time, we must - # allocate an array of pointers to arrays. - # p = (char ***) malloc( nrows * sizeof(char **) ) - # where we are letting using p[nrows][colindex]. - # For MPI_Comm_spawn_multiple, each of these rows is for one command. - # Each p[k] is a pointer to an array of character strings. - # For MPI_Comm_spawn_multiple, all we know is that in the - # corresponding Fortran code, the two-dimensional character array - # contains an all-blank entry as the terminating element; the - # corresponding C array must have a null entry (pointer) in - # the corresponding position. - # Thus, the C code must make several allocations: - # p = nrows * sizeof(char **) - # for p[k], (ncols + 1) * sizeof(char *) - # for p[k][i], space for the ith input argument. - # To reduce the number of allocations, we allocate space for all - # elements on a row at one time. - - # Purely local variables don't need $count - print $OUTFD "\ - int k; - - /* Allocate the array of pointers for the commands */ - p$count = (char ***)malloc($Array_size * sizeof(char **)); - - for (k=0; k<$Array_size; k++) { - /* For each command, find the number of command-line arguments. - They are terminated by an empty entry. */ - /* Find the first entry in the Fortran array for this row */ - char *p = v$count + k * d$count; - ssize_t arglen = 0; - int argcnt=0, i; - char **pargs, *pdata; - for (argcnt=0; 1; argcnt ++) { - char *pin = p + d$count - 1; /* Move to the end of the - current Fortran string */ - while (*pin == ' ' && pin > p) pin--; /* Move backwards until - we find a non-blank - (Fortran is blank padded)*/ - if (pin == p && *pin == ' ') { - /* found the terminating empty arg */ - break; - } - /* Keep track of the amount of space needed */ - arglen += (pin - p) + 2; /* add 1 for the null */ - /* Advance to the next entry in the array */ - p += ($Array_size) * d$count; - } - - /* argcnt is the number of provided arguments. - Allocate the necessary elements and copy, null terminating copies */ - pargs = (char **)malloc((argcnt+1)*sizeof(char *)); - pdata = (char *)malloc(arglen); - p$count\[k\] = pargs; - pargs\[argcnt\] = 0; /* Null terminate end */ - /* Copy each argument to consecutive locations in pdata, - and set the corresponding pointer entry */ - p = v$count + k * d$count; - for (i=0; i p) pin--; - /* Copy and then null terminate */ - for (j=0; j<(pin-p)+1; j++) { *pdata++ = p\[j\]; } - *pdata++ = 0; - /* Advance to the next entry in the array */ - p += ($Array_size) * d$count; - } - /* Set the terminator */ - p3[k][i] = 0; - } - }\n"; + print $OUTFD " if (v$count == MPI_F_ARGVS_NULL) {\n"; + print $OUTFD " p$count = MPI_ARGVS_NULL;\n"; + print $OUTFD " } else {\n"; + print $OUTFD " p$count = MPIR_fort_dup_str_2d_array(v$count, d$count, $Array_size);\n"; + print $OUTFD " }\n"; - $clean_up .= " if (v$count != (char *)MPI_ARGVS_NULL) { - int i; - for (i=0; i <$Array_size; i++) { - free( p$count\[i\]\[0\] ); /* Free space allocated to args */ - free( p$count\[i\] ); /* Free space allocated to arg array */ - } - /* Free the array of arrays */ - free( p$count ); + $clean_up .= " if (v$count != MPI_F_ARGVS_NULL) { + MPIR_fort_free_str_2d_array(p$count, $Array_size); }\n"; } diff --git a/src/binding/fortran/mpif_h/mpi_fortimpl.h b/src/binding/fortran/mpif_h/mpi_fortimpl.h index bb9f2feeab5..ca21be81af2 100644 --- a/src/binding/fortran/mpif_h/mpi_fortimpl.h +++ b/src/binding/fortran/mpif_h/mpi_fortimpl.h @@ -11,6 +11,9 @@ #include "mpir_attr_generic.h" #include "mpii_f77interface.h" #include /* for ssize_t */ +#include +#include +#include /* Handle different mechanisms for passing Fortran CHARACTER to routines. * @@ -51,6 +54,145 @@ #define FORT_END_LEN(a) , FORT_SIZE_INT a #endif +/* NOTE: both leading and trailing spaces are not counted */ +static inline int get_fort_str_len(char *s, int len) +{ + char *p = s + len - 1; + while (*p == ' ' && p > s) { + p--; + } + while (s < p && *s == ' ') { + s++; + } + + if (p == s && *s == ' ') { + return 0; + } else { + return (int) (p + 1 - s); + } +} + +/* NOTE: n is returned from get_fort_str_len. + * s may include leading spaces that will be removed. + */ +static inline void copy_fort_str_to_c(char *c_str, char *s, int n) +{ + if (n > 0) { + while (*s == ' ') { + s++; + } + memcpy(c_str, s, n); + } + c_str[n] = '\0'; +} + +/* duplicate fortran string to a C string */ +static inline char *MPIR_fort_dup_str(char *s, int len) +{ + int n = get_fort_str_len(s, len); + char *c_str = (char *) malloc(n + 1); + copy_fort_str_to_c(c_str, s, n); + + return c_str; +} + +/* duplicate fortran string array (e.g. argv in MPI_Comm_spawn) + * + * If count > 0, we have count strings, e.g. array_of_commands. + * Otherwise, the array is terminated by an empty/NULL string. + * + * When we assume the array is NULL terminated, user mistakes can easily become + * undefined behavior. But I guess that is not much we can do. + */ +static inline char **MPIR_fort_dup_str_array(char *s, int len, int stride, int count) +{ + int num_strs; + + if (count > 0) { + num_strs = count; + } else { + /* Compute the size of the array by looking for an all-blank line */ + num_strs = 0; + char *p = s; + while (1) { + int n = get_fort_str_len(p, len); + if (n == 0) { + break; + } + num_strs++; + p += stride; + } + count = num_strs; + /* add terminating string */ + num_strs++; + } + + char **strs = (char **) malloc(num_strs * sizeof(char *)); + + if (count > 0) { + char *str = (char *) malloc(num_strs * (len + 1)); + + for (int i = 0; i < count; i++) { + char *p1 = s + i * stride; + char *p2 = str + i * (len + 1); + + int n = get_fort_str_len(p1, len); + copy_fort_str_to_c(p2, p1, n); + + strs[i] = p2; + } + } + + if (num_strs > count) { + /* Null terminate the array */ + strs[count] = NULL; + } + + return strs; +} + +static inline void MPIR_fort_free_str_array(char **strs) +{ + if (strs[0]) { + free(strs[0]); + } + free(strs); +} + +/* duplicate fortran string 2d array (e.g. array_of_argv in MPI_Comm_spawn_multiple) */ +static inline char ***MPIR_fort_dup_str_2d_array(char *s, int len, int count) +{ + char ***str_2d_array = malloc(count * sizeof(char **)); + for (int k = 0; k < count; k++) { + char *p = s + k * len; /* NOTE: column-major */ + + str_2d_array[k] = MPIR_fort_dup_str_array(p, len, count * len, 0); + } + + return str_2d_array; +} + +static inline void MPIR_fort_free_str_2d_array(char ***str_2d_array, int count) +{ + for (int i = 0; i < count; i++) { + MPIR_fort_free_str_array(str_2d_array[i]); + } + free(str_2d_array); +} + +static inline void MPIR_fort_copy_str_from_c(char *s, int len, char *c_str) +{ + int n = strlen(c_str); + if (n > len) { + n = len; + } + + memcpy(s, c_str, n); + for (int i = n; i < len; i++) { + s[i] = ' '; + } +} + /* ------------------------------------------------------------------------- */ /* The following definitions are used to support the Microsoft compilers @@ -156,6 +298,7 @@ extern FORT_DLL_SPEC MPI_Fint *MPI_F_STATUSES_IGNORE; /* MPI_F_ERRCODES_IGNORE is defined as a Fortran INTEGER type, so must be declared as MPI_Fint */ extern FORT_DLL_SPEC MPI_Fint *MPI_F_ERRCODES_IGNORE; +extern FORT_DLL_SPEC void *MPI_F_ARGV_NULL; extern FORT_DLL_SPEC void *MPI_F_ARGVS_NULL; /* MPIR_F_PTR checks for the Fortran MPI_BOTTOM and provides the value MPI_BOTTOM if found diff --git a/src/binding/fortran/mpif_h/setbot.c.in b/src/binding/fortran/mpif_h/setbot.c.in index ce3c9d03975..0b279a114c9 100644 --- a/src/binding/fortran/mpif_h/setbot.c.in +++ b/src/binding/fortran/mpif_h/setbot.c.in @@ -8,12 +8,10 @@ #ifdef F77_NAME_UPPER #define mpirinitc_ MPIRINITC -#define mpirinitc2_ MPIRINITC2 #elif defined(F77_NAME_LOWER_2USCORE) || defined(F77_NAME_LOWER_USCORE) /* leave name alone */ #else #define mpirinitc_ mpirinitc -#define mpirinitc2_ mpirinitc2 #endif /* These functions are called from Fortran so only need prototypes in this file. Note that the second-to-last argument is a character array, so @@ -22,8 +20,9 @@ FORT_DLL_SPEC void FORT_CALL mpirinitc_(void *si, void *ssi, void *bt, void *ip, void *uw, void *ecsi, - void *asn FORT_MIXED_LEN(d1), void *we FORT_END_LEN(d1)); -FORT_DLL_SPEC void FORT_CALL mpirinitc2_(char *FORT_MIXED_LEN_DECL FORT_END_LEN_DECL); + void *an FORT_MIXED_LEN(d1), + void *asn FORT_MIXED_LEN(d1), + void *we FORT_END_LEN(d1) FORT_END_LEN(d2)); /* # MPI-2, section 4.12.5, on the declaration of MPI_F_STATUS_IGNORE @@ -40,13 +39,16 @@ void *MPI_F_STATUS_IGNORE = 0; void *MPI_F_STATUSES_IGNORE = 0; */ MPI_Fint *MPI_F_ERRCODES_IGNORE = 0; +void *MPI_F_ARGV_NULL = 0; void *MPI_F_ARGVS_NULL = 0; void *MPIR_F_MPI_WEIGHTS_EMPTY = 0; FORT_DLL_SPEC void FORT_CALL mpirinitc_(void *si, void *ssi, void *bt, void *ip, void *uw, void *ecsi, - void *asn FORT_MIXED_LEN(d1), void *we FORT_END_LEN(d1)) + void *an FORT_MIXED_LEN(d1), + void *asn FORT_MIXED_LEN(d1), + void *we FORT_END_LEN(d1) FORT_END_LEN(d2)) { MPI_F_STATUS_IGNORE = (MPI_Fint *) si; MPI_F_STATUSES_IGNORE = (MPI_Fint *) ssi; @@ -54,20 +56,11 @@ FORT_DLL_SPEC void FORT_CALL mpirinitc_(void *si, void *ssi, MPIR_F_MPI_IN_PLACE = ip; MPIR_F_MPI_UNWEIGHTED = uw; MPI_F_ERRCODES_IGNORE = (MPI_Fint *) ecsi; + MPI_F_ARGV_NULL = an; MPI_F_ARGVS_NULL = asn; MPIR_F_MPI_WEIGHTS_EMPTY = we; } -/* Initialize the Fortran ARGV_NULL to a blank. Using this routine - avoids potential problems with string manipulation routines that - exist in the Fortran runtime but not in the C runtime libraries */ -FORT_DLL_SPEC void FORT_CALL mpirinitc2_(char *an FORT_MIXED_LEN(d1) FORT_END_LEN(d1)) -{ - *an = ' '; -} - - - /* Enable all known common block symbols mangling to be alias to each other, i.e. [_C]mpifcmb*[_]to one symbol, mpifcmb*r. diff --git a/src/binding/fortran/mpif_h/setbotf.f.in b/src/binding/fortran/mpif_h/setbotf.f.in index 2e1b8d228af..a880c795bec 100644 --- a/src/binding/fortran/mpif_h/setbotf.f.in +++ b/src/binding/fortran/mpif_h/setbotf.f.in @@ -22,7 +22,6 @@ save /MPIPRIVC/ ! MPI_ARGVS_NULL ! (Fortran requires character data in a separate common block) - call mpirinitc(si, ssi, bt, ip, uw, ecsi, asn, we) - call mpirinitc2(an) + call mpirinitc(si, ssi, bt, ip, uw, ecsi, an, asn, we) return end From b29b9e9f8d245a564a523bd97c87d02f2aa49900 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 12 Oct 2021 22:40:00 -0500 Subject: [PATCH 066/607] test: fix fortran spawnargvf tests The test tests an input argument with leading spaces. MPI-4.0 chapter 11.8 page 524, under "the argv argument", quote -- > In Fortran, leading and trailing spaces are always stripped, so ... Thus, we are required to strip leading spaces in parsing argv. --- test/mpi/f77/spawn/spawnargvf.f | 2 +- test/mpi/f90/spawn/spawnargvf03.f90 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/mpi/f77/spawn/spawnargvf.f b/test/mpi/f77/spawn/spawnargvf.f index 41bde111ec0..245ab1a009b 100644 --- a/test/mpi/f77/spawn/spawnargvf.f +++ b/test/mpi/f77/spawn/spawnargvf.f @@ -20,7 +20,7 @@ program main character*(80) argv(64) integer argc data inargv /"a", "b=c", "d e", "-pf", " Ss", " " / - data outargv /"a", "b=c", "d e", "-pf", " Ss", " " / + data outargv /"a", "b=c", "d e", "-pf", "Ss", " " / integer ierr integer can_spawn diff --git a/test/mpi/f90/spawn/spawnargvf03.f90 b/test/mpi/f90/spawn/spawnargvf03.f90 index 9afb1392bcb..7ecd36cefc4 100644 --- a/test/mpi/f90/spawn/spawnargvf03.f90 +++ b/test/mpi/f90/spawn/spawnargvf03.f90 @@ -19,7 +19,7 @@ program main character*(80) argv(64) integer argc data inargv /"a", "b=c", "d e", "-pf", " Ss", " " / - data outargv /"a", "b=c", "d e", "-pf", " Ss", " " / + data outargv /"a", "b=c", "d e", "-pf", "Ss", " " / integer ierr integer comm_size integer can_spawn From 5d6dd9b4e9915a7eafc1c9ae5545dd2d703420b6 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 12 Oct 2021 16:43:11 -0500 Subject: [PATCH 067/607] fortran: manually maintain statusc2f.c and statusf2c.c These two functions are not fortran bindings. It is much easier to directly maintain them. TODO: generate these fortran related C bindings with maint/gen_binding_c.py. --- .gitignore | 2 + src/binding/fortran/mpif_h/buildiface | 146 ------------------------- src/binding/fortran/mpif_h/statusc2f.c | 52 +++++++++ src/binding/fortran/mpif_h/statusf2c.c | 54 +++++++++ 4 files changed, 108 insertions(+), 146 deletions(-) create mode 100644 src/binding/fortran/mpif_h/statusc2f.c create mode 100644 src/binding/fortran/mpif_h/statusf2c.c diff --git a/.gitignore b/.gitignore index 5d42746ab16..c441c8409ba 100644 --- a/.gitignore +++ b/.gitignore @@ -414,6 +414,8 @@ Makefile.am-stamp /src/binding/fortran/mpif_h/mpif77 /src/binding/fortran/mpif_h/*.c !/src/binding/fortran/mpif_h/attr_proxy.c +!/src/binding/fortran/mpif_h/statusf2c.c +!/src/binding/fortran/mpif_h/statusc2f.c /src/binding/fortran/mpif_h/fproto.h /src/binding/fortran/mpif_h/mpif.h /src/binding/fortran/mpif_h/mpif.h.in diff --git a/src/binding/fortran/mpif_h/buildiface b/src/binding/fortran/mpif_h/buildiface index e2629cead33..d6612617bb8 100755 --- a/src/binding/fortran/mpif_h/buildiface +++ b/src/binding/fortran/mpif_h/buildiface @@ -4325,152 +4325,6 @@ sub build_specials { # &AddPrototype( $out_prefix, "conversion_fn_null", $args ); - # The status conversion functions. - # These are a little different because they are routines that - # are called from C. - # Also note that we must exclude them from the routines that - # are generated for Fortran. These are here because they need to - # know how Fortran stores a status (e.g., if C and Fortran integers - # are the same size). - $OUTFD = "STATUSF2C"; - $filename = "statusf2c.c"; - open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n"; - # Status_f2c and c2f will need to have const added before the input - # argument for MPI 2.2 - print $OUTFD " -/* - * Copyright (C) by Argonne National Laboratory - * See COPYRIGHT in top-level directory - * - * This file is automatically generated by buildiface - * DO NOT EDIT - */ -#include \"mpi_fortimpl.h\" -/* mpir_err.h for the error code creation */ -#include \"mpir_err.h\" -#include - -/* -- Begin Profiling Symbol Block for routine MPI_Status_f2c */ -#if defined(USE_WEAK_SYMBOLS) && !defined(USE_ONLY_MPI_NAMES) -#if defined(HAVE_PRAGMA_WEAK) -#pragma weak MPI_Status_f2c = PMPI_Status_f2c -#elif defined(HAVE_PRAGMA_HP_SEC_DEF) -#pragma _HP_SECONDARY_DEF PMPI_Status_f2c MPI_Status_f2c -#elif defined(HAVE_PRAGMA_CRI_DUP) -#pragma _CRI duplicate MPI_Status_f2c as PMPI_Status_f2c -#endif -#endif -/* -- End Profiling Symbol Block */ - -/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build - the MPI routines */ -#ifndef MPICH_MPI_FROM_PMPI -#undef MPI_Status_f2c -#define MPI_Status_f2c PMPI_Status_f2c -#endif - - -int MPI_Status_f2c( const MPI_Fint *f_status, MPI_Status *c_status ) -{ - int mpi_errno = MPI_SUCCESS;\n"; - &specialInitStatement( $OUTFD ); -print $OUTFD "\ - if (f_status == MPI_F_STATUS_IGNORE) { - /* The call is erroneous (see 4.12.5 in MPI-2) */ - mpi_errno = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, - \"MPI_Status_f2c\", __LINE__, MPI_ERR_OTHER, \"**notfstatignore\", 0 ); - return MPIR_Err_return_comm( 0, \"MPI_Status_f2c\", mpi_errno ); - }\n"; - if ($do_fint) { - print $OUTFD "\ -#ifdef HAVE_FINT_IS_INT - *c_status = *(MPI_Status *) f_status; -#else - c_status->count_lo = (int)f_status\[0\]; - c_status->count_hi_and_cancelled = (int)f_status\[1\]; - c_status->MPI_SOURCE = (int)f_status\[2\]; - c_status->MPI_TAG = (int)f_status\[3\]; - c_status->MPI_ERROR = (int)f_status\[4\]; - /* no need to copy abi_slush_fund field */ -#endif\n"; - } - else { - print $OUTFD "\ - *c_status = *(MPI_Status *) f_status;\n"; - } - print $OUTFD " - return MPI_SUCCESS; -}\n"; - close ($OUTFD); - &ReplaceIfDifferent( $filename, $filename . ".new" ); - - $OUTFD = "STATUSC2F"; - $filename = "statusc2f.c"; - open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n"; - print $OUTFD " -/* - * Copyright (C) by Argonne National Laboratory - * See COPYRIGHT in top-level directory - * - * This file is automatically generated by buildiface - * DO NOT EDIT - */ -#include \"mpi_fortimpl.h\" -/* mpir_err.h for the error code creation */ -#include \"mpir_err.h\" -#include - -/* -- Begin Profiling Symbol Block for routine MPI_Status_c2f */ -#if defined(USE_WEAK_SYMBOLS) && !defined(USE_ONLY_MPI_NAMES) -#if defined(HAVE_PRAGMA_WEAK) -#pragma weak MPI_Status_c2f = PMPI_Status_c2f -#elif defined(HAVE_PRAGMA_HP_SEC_DEF) -#pragma _HP_SECONDARY_DEF PMPI_Status_c2f MPI_Status_c2f -#elif defined(HAVE_PRAGMA_CRI_DUP) -#pragma _CRI duplicate MPI_Status_c2f as PMPI_Status_c2f -#endif -#endif -/* -- End Profiling Symbol Block */ - -/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build - the MPI routines */ -#ifndef MPICH_MPI_FROM_PMPI -#undef MPI_Status_c2f -#define MPI_Status_c2f PMPI_Status_c2f -#endif - - -int MPI_Status_c2f( const MPI_Status *c_status, MPI_Fint *f_status ) -{ - int mpi_errno = MPI_SUCCESS; - if (c_status == MPI_STATUS_IGNORE || - c_status == MPI_STATUSES_IGNORE) { - /* The call is erroneous (see 4.12.5 in MPI-2) */ - mpi_errno = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, - \"MPI_Status_c2f\", __LINE__, MPI_ERR_OTHER, \"**notcstatignore\", 0 ); - return MPIR_Err_return_comm( 0, \"MPI_Status_c2f\", mpi_errno ); - }\n"; - if ($do_fint) { - print $OUTFD "\ -#ifdef HAVE_FINT_IS_INT - *(MPI_Status *)f_status = *c_status; -#else - f_status\[0\] = (MPI_Fint)c_status->count_lo; - f_status\[1\] = (MPI_Fint)c_status->count_hi_and_cancelled; - f_status\[2\] = (MPI_Fint)c_status->MPI_SOURCE; - f_status\[3\] = (MPI_Fint)c_status->MPI_TAG; - f_status\[4\] = (MPI_Fint)c_status->MPI_ERROR; -#endif\n"; - } - else { - print $OUTFD " *(MPI_Status *)f_status = *c_status;\n"; - } - print $OUTFD " - return MPI_SUCCESS; -}\n"; - close ($OUTFD); - &ReplaceIfDifferent( $filename, $filename . ".new" ); - my $uc_prefix = uc($out_prefix); $OUTFD = "INFOCRENV"; diff --git a/src/binding/fortran/mpif_h/statusc2f.c b/src/binding/fortran/mpif_h/statusc2f.c new file mode 100644 index 00000000000..d829f97979b --- /dev/null +++ b/src/binding/fortran/mpif_h/statusc2f.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpi_fortimpl.h" +/* mpir_err.h for the error code creation */ +#include "mpir_err.h" +#include + +/* -- Begin Profiling Symbol Block for routine MPI_Status_c2f */ +#if defined(USE_WEAK_SYMBOLS) && !defined(USE_ONLY_MPI_NAMES) +#if defined(HAVE_PRAGMA_WEAK) +#pragma weak MPI_Status_c2f = PMPI_Status_c2f +#elif defined(HAVE_PRAGMA_HP_SEC_DEF) +#pragma _HP_SECONDARY_DEF PMPI_Status_c2f MPI_Status_c2f +#elif defined(HAVE_PRAGMA_CRI_DUP) +#pragma _CRI duplicate MPI_Status_c2f as PMPI_Status_c2f +#endif +#endif +/* -- End Profiling Symbol Block */ + +/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build + the MPI routines */ +#ifndef MPICH_MPI_FROM_PMPI +#undef MPI_Status_c2f +#define MPI_Status_c2f PMPI_Status_c2f +#endif + + +int MPI_Status_c2f(const MPI_Status * c_status, MPI_Fint * f_status) +{ + int mpi_errno = MPI_SUCCESS; + if (c_status == MPI_STATUS_IGNORE || c_status == MPI_STATUSES_IGNORE) { + /* The call is erroneous (see 4.12.5 in MPI-2) */ + mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, + "MPI_Status_c2f", __LINE__, MPI_ERR_OTHER, + "**notcstatignore", 0); + return MPIR_Err_return_comm(0, "MPI_Status_c2f", mpi_errno); + } +#ifdef HAVE_FINT_IS_INT + *(MPI_Status *) f_status = *c_status; +#else + f_status[0] = (MPI_Fint) c_status->count_lo; + f_status[1] = (MPI_Fint) c_status->count_hi_and_cancelled; + f_status[2] = (MPI_Fint) c_status->MPI_SOURCE; + f_status[3] = (MPI_Fint) c_status->MPI_TAG; + f_status[4] = (MPI_Fint) c_status->MPI_ERROR; +#endif + + return MPI_SUCCESS; +} diff --git a/src/binding/fortran/mpif_h/statusf2c.c b/src/binding/fortran/mpif_h/statusf2c.c new file mode 100644 index 00000000000..76e6e244b92 --- /dev/null +++ b/src/binding/fortran/mpif_h/statusf2c.c @@ -0,0 +1,54 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpi_fortimpl.h" +/* mpir_err.h for the error code creation */ +#include "mpir_err.h" +#include + +/* -- Begin Profiling Symbol Block for routine MPI_Status_f2c */ +#if defined(USE_WEAK_SYMBOLS) && !defined(USE_ONLY_MPI_NAMES) +#if defined(HAVE_PRAGMA_WEAK) +#pragma weak MPI_Status_f2c = PMPI_Status_f2c +#elif defined(HAVE_PRAGMA_HP_SEC_DEF) +#pragma _HP_SECONDARY_DEF PMPI_Status_f2c MPI_Status_f2c +#elif defined(HAVE_PRAGMA_CRI_DUP) +#pragma _CRI duplicate MPI_Status_f2c as PMPI_Status_f2c +#endif +#endif +/* -- End Profiling Symbol Block */ + +/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build + the MPI routines */ +#ifndef MPICH_MPI_FROM_PMPI +#undef MPI_Status_f2c +#define MPI_Status_f2c PMPI_Status_f2c +#endif + + +int MPI_Status_f2c(const MPI_Fint * f_status, MPI_Status * c_status) +{ + int mpi_errno = MPI_SUCCESS; + + if (f_status == MPI_F_STATUS_IGNORE) { + /* The call is erroneous (see 4.12.5 in MPI-2) */ + mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, + "MPI_Status_f2c", __LINE__, MPI_ERR_OTHER, + "**notfstatignore", 0); + return MPIR_Err_return_comm(0, "MPI_Status_f2c", mpi_errno); + } +#ifdef HAVE_FINT_IS_INT + *c_status = *(MPI_Status *) f_status; +#else + c_status->count_lo = (int) f_status[0]; + c_status->count_hi_and_cancelled = (int) f_status[1]; + c_status->MPI_SOURCE = (int) f_status[2]; + c_status->MPI_TAG = (int) f_status[3]; + c_status->MPI_ERROR = (int) f_status[4]; + /* no need to copy abi_slush_fund field */ +#endif + + return MPI_SUCCESS; +} From 827e545fdc859af8e49cf6d4d29b9fcac2d57d51 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 13 Oct 2021 13:41:38 -0500 Subject: [PATCH 068/607] fortran: fix profiling in statusf2c and statusc2f Both routines failed to support weak attributes. --- src/binding/fortran/mpif_h/statusc2f.c | 5 +++-- src/binding/fortran/mpif_h/statusf2c.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/binding/fortran/mpif_h/statusc2f.c b/src/binding/fortran/mpif_h/statusc2f.c index d829f97979b..686dd8477ee 100644 --- a/src/binding/fortran/mpif_h/statusc2f.c +++ b/src/binding/fortran/mpif_h/statusc2f.c @@ -9,14 +9,15 @@ #include /* -- Begin Profiling Symbol Block for routine MPI_Status_c2f */ -#if defined(USE_WEAK_SYMBOLS) && !defined(USE_ONLY_MPI_NAMES) #if defined(HAVE_PRAGMA_WEAK) #pragma weak MPI_Status_c2f = PMPI_Status_c2f #elif defined(HAVE_PRAGMA_HP_SEC_DEF) #pragma _HP_SECONDARY_DEF PMPI_Status_c2f MPI_Status_c2f #elif defined(HAVE_PRAGMA_CRI_DUP) #pragma _CRI duplicate MPI_Status_c2f as PMPI_Status_c2f -#endif +#elif defined(HAVE_WEAK_ATTRIBUTE) +int MPI_Status_c2f(const MPI_Status * c_status, MPI_Fint * f_status) + __attribute__ ((weak, alias("PMPI_Status_c2f"))); #endif /* -- End Profiling Symbol Block */ diff --git a/src/binding/fortran/mpif_h/statusf2c.c b/src/binding/fortran/mpif_h/statusf2c.c index 76e6e244b92..efaf36b0e1e 100644 --- a/src/binding/fortran/mpif_h/statusf2c.c +++ b/src/binding/fortran/mpif_h/statusf2c.c @@ -9,14 +9,15 @@ #include /* -- Begin Profiling Symbol Block for routine MPI_Status_f2c */ -#if defined(USE_WEAK_SYMBOLS) && !defined(USE_ONLY_MPI_NAMES) #if defined(HAVE_PRAGMA_WEAK) #pragma weak MPI_Status_f2c = PMPI_Status_f2c #elif defined(HAVE_PRAGMA_HP_SEC_DEF) #pragma _HP_SECONDARY_DEF PMPI_Status_f2c MPI_Status_f2c #elif defined(HAVE_PRAGMA_CRI_DUP) #pragma _CRI duplicate MPI_Status_f2c as PMPI_Status_f2c -#endif +#elif defined(HAVE_WEAK_ATTRIBUTE) +int MPI_Status_f2c(const MPI_Fint * f_status, MPI_Status * c_status) + __attribute__ ((weak, alias("PMPI_Status_f2c"))); #endif /* -- End Profiling Symbol Block */ From 71761c861423d60e48007b19a17cd95f931cf5bf Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 13 Oct 2021 08:21:08 -0500 Subject: [PATCH 069/607] fortran: manually maintain mpif_h/Makefile.mk Move the stable part of Makefile to static file so we don't need rely on the script to understand the build logic. --- .gitignore | 2 +- src/binding/fortran/mpif_h/Makefile.mk | 44 ++++++++++++++++++ src/binding/fortran/mpif_h/buildiface | 62 +------------------------- 3 files changed, 47 insertions(+), 61 deletions(-) create mode 100644 src/binding/fortran/mpif_h/Makefile.mk diff --git a/.gitignore b/.gitignore index c441c8409ba..8ae4077e462 100644 --- a/.gitignore +++ b/.gitignore @@ -223,7 +223,7 @@ Makefile.am-stamp /src/pm/mpd/aclocal.m4 /src/pm/gforker/mpiexec.gforker /maint/Version -/src/binding/fortran/mpif_h/Makefile.mk +/src/binding/fortran/mpif_h/Makefile_wrappers.mk /src/binding/fortran/use_mpi/Makefile.mk /src/binding/fortran/use_mpi_f08/Makefile.mk diff --git a/src/binding/fortran/mpif_h/Makefile.mk b/src/binding/fortran/mpif_h/Makefile.mk new file mode 100644 index 00000000000..d3f14ea5811 --- /dev/null +++ b/src/binding/fortran/mpif_h/Makefile.mk @@ -0,0 +1,44 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +# ensure that the buildiface script ends up in the release tarball +EXTRA_DIST += src/binding/fortran/mpif_h/buildiface + +# FIXME need to add proper rules to rebuild the fortran sources generated by +# buildiface when buildiface is updated +if MAINTAINER_MODE +$(top_srcdir)/src/binding/fortran/mpif_h/Makefile.mk: src/binding/fortran/mpif_h/buildiface-stamp + +src/binding/fortran/mpif_h/buildiface-stamp: $(top_srcdir)/src/binding/fortran/mpif_h/buildiface $(top_srcdir)/src/include/mpi_proto.h + ( cd $(top_srcdir)/src/binding/fortran/mpif_h && ./buildiface ) +endif MAINTAINER_MODE + +mpi_f77_sources += src/binding/fortran/mpif_h/attr_proxy.c + +include $(top_srcdir)/src/binding/fortran/mpif_h/Makefile_wrappers.mk + +if BUILD_F77_BINDING +mpi_f77_sources += src/binding/fortran/mpif_h/fdebug.c \ + src/binding/fortran/mpif_h/setbot.c \ + src/binding/fortran/mpif_h/setbotf.f +mpi_sources += src/binding/fortran/mpif_h/statusf2c.c src/binding/fortran/mpif_h/statusc2f.c + +# FIXME does AM_CPPFLAGS need to be included elsewhere somehow in the +# target-specific variable? +AM_CPPFLAGS += -I${main_top_srcdir}/src/binding/fortran/mpif_h + + +noinst_HEADERS += src/binding/fortran/mpif_h/fproto.h src/binding/fortran/mpif_h/mpi_fortimpl.h + +# config.status copies src/binding/fortran/mpif_h/mpif.h to src/include (see the relevant +# AC_CONFIG_COMMANDS in configure.ac), so we need to delete it at distclean time +# too. More work is needed in this Makefile.mk to keep src/include/mpif.h up to +# date w.r.t. the src/binding/fortran/mpif_h version. +DISTCLEANFILES += src/binding/fortran/mpif_h/mpif.h src/include/mpif.h +nodist_include_HEADERS += src/binding/fortran/mpif_h/mpif.h + + +endif BUILD_F77_BINDING + diff --git a/src/binding/fortran/mpif_h/buildiface b/src/binding/fortran/mpif_h/buildiface index d6612617bb8..f78d44ae231 100755 --- a/src/binding/fortran/mpif_h/buildiface +++ b/src/binding/fortran/mpif_h/buildiface @@ -1016,7 +1016,7 @@ if ("$buildMakefile") { open STAMPFD, '>', 'buildiface-stamp'; close STAMPFD; - open ( MAKEFD, ">Makefile.mk.new" ) || die "Cannot create Makefile.mk.new"; + open ( MAKEFD, ">Makefile_wrappers.mk.new" ) || die "Cannot create Makefile_wrappers.mk.new"; print MAKEFD < Date: Wed, 13 Oct 2021 08:27:06 -0500 Subject: [PATCH 070/607] fortran: remove MAINTAINER_MODE for buildiface The interface generation are carried out in autogen stage and it is easy to simply re-run the script if necessary. The MAINTAINER_MODE adds complexity without much benefit. And it is fragile as we make changes to the generation mechanism. Remove for now. --- .gitignore | 1 - src/binding/fortran/mpif_h/Makefile.mk | 9 --------- src/binding/fortran/mpif_h/buildiface | 4 ---- 3 files changed, 14 deletions(-) diff --git a/.gitignore b/.gitignore index 8ae4077e462..b7f4086a073 100644 --- a/.gitignore +++ b/.gitignore @@ -152,7 +152,6 @@ Makefile.am-stamp # random stuff /maint/gcovmerge -/src/binding/fortran/mpif_h/buildiface-stamp /src/binding/fortran/use_mpi/buildiface-stamp /src/binding/cxx/buildiface-stamp diff --git a/src/binding/fortran/mpif_h/Makefile.mk b/src/binding/fortran/mpif_h/Makefile.mk index d3f14ea5811..8feef401fe5 100644 --- a/src/binding/fortran/mpif_h/Makefile.mk +++ b/src/binding/fortran/mpif_h/Makefile.mk @@ -6,15 +6,6 @@ # ensure that the buildiface script ends up in the release tarball EXTRA_DIST += src/binding/fortran/mpif_h/buildiface -# FIXME need to add proper rules to rebuild the fortran sources generated by -# buildiface when buildiface is updated -if MAINTAINER_MODE -$(top_srcdir)/src/binding/fortran/mpif_h/Makefile.mk: src/binding/fortran/mpif_h/buildiface-stamp - -src/binding/fortran/mpif_h/buildiface-stamp: $(top_srcdir)/src/binding/fortran/mpif_h/buildiface $(top_srcdir)/src/include/mpi_proto.h - ( cd $(top_srcdir)/src/binding/fortran/mpif_h && ./buildiface ) -endif MAINTAINER_MODE - mpi_f77_sources += src/binding/fortran/mpif_h/attr_proxy.c include $(top_srcdir)/src/binding/fortran/mpif_h/Makefile_wrappers.mk diff --git a/src/binding/fortran/mpif_h/buildiface b/src/binding/fortran/mpif_h/buildiface index f78d44ae231..44a4161b19f 100755 --- a/src/binding/fortran/mpif_h/buildiface +++ b/src/binding/fortran/mpif_h/buildiface @@ -1012,10 +1012,6 @@ if ($build_prototypes) { # # This block can be used to create the Makefile if ("$buildMakefile") { - # create a stamp file for use by Makefile.mk rebuild make logic - open STAMPFD, '>', 'buildiface-stamp'; - close STAMPFD; - open ( MAKEFD, ">Makefile_wrappers.mk.new" ) || die "Cannot create Makefile_wrappers.mk.new"; print MAKEFD < Date: Wed, 13 Oct 2021 14:08:45 -0500 Subject: [PATCH 071/607] fortran: remove use_mpi_f08/Makefile.mk from gitignore We neglected to remove the entry since we separated the makefile for use_mpi_f08. --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index b7f4086a073..bafff93c527 100644 --- a/.gitignore +++ b/.gitignore @@ -224,7 +224,6 @@ Makefile.am-stamp /maint/Version /src/binding/fortran/mpif_h/Makefile_wrappers.mk /src/binding/fortran/use_mpi/Makefile.mk -/src/binding/fortran/use_mpi_f08/Makefile.mk # MPICH2 parameter handling /src/include/mpir_cvars.h From ca9afa20dc4cdd7b34832a6c3b87dce08f469f34 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 13 Oct 2021 14:02:38 -0500 Subject: [PATCH 072/607] fortran: separate use_mpi/Makefile.mk from buildiface There is no benefit to use script to generate the Makefile since it just prints out the content verbosely. --- .gitignore | 3 - src/binding/fortran/use_mpi/Makefile.mk | 251 ++++++++++++++++++++++++ src/binding/fortran/use_mpi/buildiface | 214 -------------------- 3 files changed, 251 insertions(+), 217 deletions(-) create mode 100644 src/binding/fortran/use_mpi/Makefile.mk diff --git a/.gitignore b/.gitignore index bafff93c527..cc5e80d21a8 100644 --- a/.gitignore +++ b/.gitignore @@ -152,7 +152,6 @@ Makefile.am-stamp # random stuff /maint/gcovmerge -/src/binding/fortran/use_mpi/buildiface-stamp /src/binding/cxx/buildiface-stamp # script-generated f90 test files @@ -189,7 +188,6 @@ Makefile.am-stamp /src/mpi/coll/src/csel_json_autogen.c # stamp "witness" files from the new build system -/src/binding/fortran/use_mpi/buildiface.stamp /src/binding/fortran/use_mpi/mpi.mod-stamp /src/binding/fortran/use_mpi/mpi_base.mod-stamp /src/binding/fortran/use_mpi/mpi_constants.mod-stamp @@ -223,7 +221,6 @@ Makefile.am-stamp /src/pm/gforker/mpiexec.gforker /maint/Version /src/binding/fortran/mpif_h/Makefile_wrappers.mk -/src/binding/fortran/use_mpi/Makefile.mk # MPICH2 parameter handling /src/include/mpir_cvars.h diff --git a/src/binding/fortran/use_mpi/Makefile.mk b/src/binding/fortran/use_mpi/Makefile.mk new file mode 100644 index 00000000000..b26da3bf6ed --- /dev/null +++ b/src/binding/fortran/use_mpi/Makefile.mk @@ -0,0 +1,251 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +MOD = @FCMODEXT@ +MPIMOD = @MPIMODNAME@ +MPICONSTMOD = @MPICONSTMODNAME@ +MPISIZEOFMOD = @MPISIZEOFMODNAME@ +MPIBASEMOD = @MPIBASEMODNAME@ +FC_COMPILE_MODS = $(LTFCCOMPILE) + +# ensure that the buildiface script ends up in the release tarball +EXTRA_DIST += src/binding/fortran/use_mpi/buildiface + +# additional perl files that are "require"d by use_mpi/buildiface and +# mpif_h/buildiface, respectively +EXTRA_DIST += src/binding/fortran/use_mpi/binding.sub src/binding/fortran/use_mpi/cf90tdefs + +# variables for custom "silent-rules" for F90 modules +mod_verbose = $(mod_verbose_$(V)) +mod_verbose_ = $(mod_verbose_$(AM_DEFAULT_VERBOSITY)) +mod_verbose_0 = @echo " MOD " $@; + +if BUILD_FC_BINDING + +# We need to tell some compilers (e.g., Solaris f90) to look for modules in the +# current directory when the source file is not in the working directory (i.e., +# in a VPATH build) +AM_FCFLAGS += @FCINCFLAG@src/binding/fortran/use_mpi + +# C source that implements both the C and the Fortran bindings for the type +# creation routines. These go into libmpi.la and will be built a second time +# for inclusion in libpmpi.la on platforms that do not support weak symbols. +# If shared libraries are enabled then the compilation space doubles again. +mpi_sources += \ + src/binding/fortran/use_mpi/create_f90_int.c \ + src/binding/fortran/use_mpi/create_f90_real.c \ + src/binding/fortran/use_mpi/create_f90_complex.c + +# utility code that has no PMPI equivalent +mpi_core_sources += src/binding/fortran/use_mpi/create_f90_util.c +AM_CPPFLAGS += -Isrc/binding/fortran/use_mpi +noinst_HEADERS += \ + src/binding/fortran/use_mpi/create_f90_util.h \ + src/binding/fortran/use_mpi/cf90t.h \ + src/binding/fortran/use_mpi/mpif90type.h \ + src/binding/fortran/use_mpi/mpifnoext.h + +nodist_noinst_HEADERS += \ + src/binding/fortran/use_mpi/mpif90model.h + +# cause any .$(MOD) files to be output in the f90 bindings directory instead of +# the current directory +FC_COMPILE_MODS += $(FCMODOUTFLAG)src/binding/fortran/use_mpi + +mpi_fc_sources += \ + src/binding/fortran/use_mpi/typef90cmplxf.c \ + src/binding/fortran/use_mpi/typef90realf.c \ + src/binding/fortran/use_mpi/typef90intf.c \ + src/binding/fortran/use_mpi/mpi.f90 \ + src/binding/fortran/use_mpi/mpi_constants.f90 \ + src/binding/fortran/use_mpi/mpi_sizeofs.f90 \ + src/binding/fortran/use_mpi/mpi_base.f90 + +# FIXME: We may want to edit the mpif.h to convert Fortran77-specific +# items (such as an integer*8 used for file offsets) into the +# corresponding Fortran 90 KIND type, to accommodate compilers that +# reject non-standard features such as integer*8 (such as the Intel +# Fortran compiler with -std95). +# We need the MPI constants in a separate module for some of the +# interface definitions (the ones that need MPI_ADDRESS_KIND or +# MPI_OFFSET_KIND) +src/binding/fortran/use_mpi/mpi.$(MOD)-stamp: src/binding/fortran/use_mpi/$(MPICONSTMOD).$(MOD) src/binding/fortran/use_mpi/$(MPISIZEOFMOD).$(MOD) src/binding/fortran/use_mpi/$(MPIBASEMOD).$(MOD) $(srcdir)/src/binding/fortran/use_mpi/mpi.f90 src/binding/fortran/use_mpi/mpifnoext.h + @rm -f src/binding/fortran/use_mpi/mpi-tmp + @touch src/binding/fortran/use_mpi/mpi-tmp + @( cd src/binding/fortran/use_mpi && \ + if [ "$(FCEXT)" != "f90" ] || [ ! -f mpi.$(FCEXT) ] ; then \ + rm -f mpi.$(FCEXT) ; \ + $(LN_S) $(abs_top_srcdir)/src/binding/fortran/use_mpi/mpi.f90 mpi.$(FCEXT) ; \ + fi ) + $(mod_verbose)$(FC_COMPILE_MODS) -c src/binding/fortran/use_mpi/mpi.$(FCEXT) -o src/binding/fortran/use_mpi/mpi.lo + @( cd src/binding/fortran/use_mpi && \ + if [ "$(FCEXT)" != "f90" ] || [ ! -f mpi.$(FCEXT) ] ; then \ + rm -f mpi.$(FCEXT) ; \ + fi ) + @mv src/binding/fortran/use_mpi/mpi-tmp src/binding/fortran/use_mpi/mpi.$(MOD)-stamp + +src/binding/fortran/use_mpi/mpi.lo src/binding/fortran/use_mpi/$(MPIMOD).$(MOD): src/binding/fortran/use_mpi/mpi.$(MOD)-stamp +## Recover from the removal of $@ + @if test -f $@; then :; else \ + trap 'rm -rf src/binding/fortran/use_mpi/mpi-lock src/binding/fortran/use_mpi/mpi.$(MOD)-stamp' 1 2 13 15; \ + if mkdir src/binding/fortran/use_mpi/mpi-lock 2>/dev/null; then \ +## This code is being executed by the first process. + rm -f src/binding/fortran/use_mpi/mpi.$(MOD)-stamp; \ + $(MAKE) $(AM_MAKEFLAGS) src/binding/fortran/use_mpi/mpi.$(MOD)-stamp; \ + rmdir src/binding/fortran/use_mpi/mpi-lock; \ + else \ +## This code is being executed by the follower processes. +## Wait until the first process is done. + while test -d src/binding/fortran/use_mpi/mpi-lock; do sleep 1; done; \ +## Succeed if and only if the first process succeeded. + test -f src/binding/fortran/use_mpi/mpi.$(MOD)-stamp; exit $$?; \ + fi; \ + fi + +CLEANFILES += src/binding/fortran/use_mpi/mpi.$(MOD)-stamp src/binding/fortran/use_mpi/$(MPIMOD).$(MOD) src/binding/fortran/use_mpi/mpi.lo src/binding/fortran/use_mpi/mpi-tmp + + +src/binding/fortran/use_mpi/mpi_constants.$(MOD)-stamp: src/binding/fortran/use_mpi/mpi_constants.f90 src/binding/fortran/use_mpi/mpifnoext.h + @rm -f src/binding/fortran/use_mpi/mpi_constants-tmp + @touch src/binding/fortran/use_mpi/mpi_constants-tmp + @( cd src/binding/fortran/use_mpi && \ + if [ "$(FCEXT)" != "f90" ] || [ ! -f mpi_constants.$(FCEXT) ] ; then \ + rm -f mpi_constants.$(FCEXT) ; \ + $(LN_S) $(abs_top_srcdir)/src/binding/fortran/use_mpi/mpi_constants.f90 mpi_constants.$(FCEXT) ; \ + fi ) + $(mod_verbose)$(FC_COMPILE_MODS) -c src/binding/fortran/use_mpi/mpi_constants.$(FCEXT) -o src/binding/fortran/use_mpi/mpi_constants.lo + @( cd src/binding/fortran/use_mpi && \ + if [ "$(FCEXT)" != "f90" ] || [ ! -f mpi_constants.$(FCEXT) ] ; then \ + rm -f mpi_constants.$(FCEXT) ; \ + fi ) + @mv src/binding/fortran/use_mpi/mpi_constants-tmp src/binding/fortran/use_mpi/mpi_constants.$(MOD)-stamp + +src/binding/fortran/use_mpi/mpi_constants.lo src/binding/fortran/use_mpi/$(MPICONSTMOD).$(MOD): src/binding/fortran/use_mpi/mpi_constants.$(MOD)-stamp +## Recover from the removal of $@ + @if test -f $@; then :; else \ + trap 'rm -rf src/binding/fortran/use_mpi/mpi_constants-lock src/binding/fortran/use_mpi/mpi_constants.$(MOD)-stamp' 1 2 13 15; \ + if mkdir src/binding/fortran/use_mpi/mpi_constants-lock 2>/dev/null; then \ +## This code is being executed by the first process. + rm -f src/binding/fortran/use_mpi/mpi_constants.$(MOD)-stamp; \ + $(MAKE) $(AM_MAKEFLAGS) src/binding/fortran/use_mpi/mpi_constants.$(MOD)-stamp; \ + rmdir src/binding/fortran/use_mpi/mpi_constants-lock; \ + else \ +## This code is being executed by the follower processes. +## Wait until the first process is done. + while test -d src/binding/fortran/use_mpi/mpi_constants-lock; do sleep 1; done; \ +## Succeed if and only if the first process succeeded. + test -f src/binding/fortran/use_mpi/mpi_constants.$(MOD)-stamp; exit $$?; \ + fi; \ + fi + +CLEANFILES += src/binding/fortran/use_mpi/mpi_constants.$(MOD)-stamp src/binding/fortran/use_mpi/$(MPICONSTMOD).$(MOD) src/binding/fortran/use_mpi/mpi_constants.lo src/binding/fortran/use_mpi/mpi_constants-tmp + + +src/binding/fortran/use_mpi/mpi_sizeofs.$(MOD)-stamp: src/binding/fortran/use_mpi/mpi_sizeofs.f90 src/binding/fortran/use_mpi/mpifnoext.h + @rm -f src/binding/fortran/use_mpi/mpi_sizeofs-tmp + @touch src/binding/fortran/use_mpi/mpi_sizeofs-tmp + @( cd src/binding/fortran/use_mpi && \ + if [ "$(FCEXT)" != "f90" ] ; then \ + rm -f mpi_sizeofs.$(FCEXT) ; \ + $(LN_S) mpi_sizeofs.f90 mpi_sizeofs.$(FCEXT) ; \ + fi ) + $(mod_verbose)$(FC_COMPILE_MODS) -c src/binding/fortran/use_mpi/mpi_sizeofs.$(FCEXT) -o src/binding/fortran/use_mpi/mpi_sizeofs.lo + @( cd src/binding/fortran/use_mpi && \ + if [ "$(FCEXT)" != "f90" ] ; then \ + rm -f mpi_sizeofs.$(FCEXT) ; \ + fi ) + @mv src/binding/fortran/use_mpi/mpi_sizeofs-tmp src/binding/fortran/use_mpi/mpi_sizeofs.$(MOD)-stamp + +src/binding/fortran/use_mpi/mpi_sizeofs.lo src/binding/fortran/use_mpi/$(MPISIZEOFMOD).$(MOD): src/binding/fortran/use_mpi/mpi_sizeofs.$(MOD)-stamp +## Recover from the removal of $@ + @if test -f $@; then :; else \ + trap 'rm -rf src/binding/fortran/use_mpi/mpi_sizeofs-lock src/binding/fortran/use_mpi/mpi_sizeofs.$(MOD)-stamp' 1 2 13 15; \ + if mkdir src/binding/fortran/use_mpi/mpi_sizeofs-lock 2>/dev/null; then \ +## This code is being executed by the first process. + rm -f src/binding/fortran/use_mpi/mpi_sizeofs.$(MOD)-stamp; \ + $(MAKE) $(AM_MAKEFLAGS) src/binding/fortran/use_mpi/mpi_sizeofs.$(MOD)-stamp; \ + rmdir src/binding/fortran/use_mpi/mpi_sizeofs-lock; \ + else \ +## This code is being executed by the follower processes. +## Wait until the first process is done. + while test -d src/binding/fortran/use_mpi/mpi_sizeofs-lock; do sleep 1; done; \ +## Succeed if and only if the first process succeeded. + test -f src/binding/fortran/use_mpi/mpi_sizeofs.$(MOD)-stamp; exit $$?; \ + fi; \ + fi + +CLEANFILES += src/binding/fortran/use_mpi/mpi_sizeofs.$(MOD)-stamp src/binding/fortran/use_mpi/$(MPISIZEOFMOD).$(MOD) src/binding/fortran/use_mpi/mpi_sizeofs.lo src/binding/fortran/use_mpi/mpi_sizeofs-tmp + + +src/binding/fortran/use_mpi/mpi_base.$(MOD)-stamp: src/binding/fortran/use_mpi/mpi_base.f90 src/binding/fortran/use_mpi/$(MPICONSTMOD).$(MOD) + @rm -f src/binding/fortran/use_mpi/mpi_base-tmp + @touch src/binding/fortran/use_mpi/mpi_base-tmp + @( cd src/binding/fortran/use_mpi && \ + if [ "$(FCEXT)" != "f90" ] ; then \ + rm -f mpi_base.$(FCEXT) ; \ + $(LN_S) mpi_base.f90 mpi_base.$(FCEXT) ; \ + fi ) + $(mod_verbose)$(FC_COMPILE_MODS) -c src/binding/fortran/use_mpi/mpi_base.$(FCEXT) -o src/binding/fortran/use_mpi/mpi_base.lo + @( cd src/binding/fortran/use_mpi && \ + if [ "$(FCEXT)" != "f90" ] ; then \ + rm -f mpi_base.$(FCEXT) ; \ + fi ) + @mv src/binding/fortran/use_mpi/mpi_base-tmp src/binding/fortran/use_mpi/mpi_base.$(MOD)-stamp + +src/binding/fortran/use_mpi/mpi_base.lo src/binding/fortran/use_mpi/$(MPIBASEMOD).$(MOD): src/binding/fortran/use_mpi/mpi_base.$(MOD)-stamp +## Recover from the removal of $@ + @if test -f $@; then :; else \ + trap 'rm -rf src/binding/fortran/use_mpi/mpi_base-lock src/binding/fortran/use_mpi/mpi_base.$(MOD)-stamp' 1 2 13 15; \ + if mkdir src/binding/fortran/use_mpi/mpi_base-lock 2>/dev/null; then \ +## This code is being executed by the first process. + rm -f src/binding/fortran/use_mpi/mpi_base.$(MOD)-stamp; \ + $(MAKE) $(AM_MAKEFLAGS) src/binding/fortran/use_mpi/mpi_base.$(MOD)-stamp; \ + rmdir src/binding/fortran/use_mpi/mpi_base-lock; \ + else \ +## This code is being executed by the follower processes. +## Wait until the first process is done. + while test -d src/binding/fortran/use_mpi/mpi_base-lock; do sleep 1; done; \ +## Succeed if and only if the first process succeeded. + test -f src/binding/fortran/use_mpi/mpi_base.$(MOD)-stamp; exit $$?; \ + fi; \ + fi + +CLEANFILES += src/binding/fortran/use_mpi/mpi_base.$(MOD)-stamp src/binding/fortran/use_mpi/$(MPIBASEMOD).$(MOD) src/binding/fortran/use_mpi/mpi_base.lo src/binding/fortran/use_mpi/mpi_base-tmp + + + +mpi_fc_modules += \ + src/binding/fortran/use_mpi/$(MPIMOD).$(MOD) \ + src/binding/fortran/use_mpi/$(MPISIZEOFMOD).$(MOD) \ + src/binding/fortran/use_mpi/$(MPICONSTMOD).$(MOD) \ + src/binding/fortran/use_mpi/$(MPIBASEMOD).$(MOD) + +# We need a free-format version of mpif.h with no external commands, +# including no wtime/wtick (removing MPI_WTICK also removes MPI_WTIME, +# but leave MPI_WTIME_IS_GLOBAL). +# Also allow REAL*8 or DOUBLE PRECISION for the MPI_WTIME/MPI_WTICK +# declarations +src/binding/fortran/use_mpi/mpifnoext.h: src/binding/fortran/mpif_h/mpif.h + rm -f $@ + sed -e 's/^C/\!/g' -e '/EXTERNAL/d' \ + -e '/REAL\*8/d' \ + -e '/DOUBLE PRECISION/d' \ + -e '/MPI_WTICK/d' src/binding/fortran/mpif_h/mpif.h > $@ + +CLEANFILES += src/binding/fortran/use_mpi/mpifnoext.h + +MAINTAINERCLEANFILES += $(mpi_sources) fproto.h +CLEANFILES += $(mpi_fc_modules) + +# Documentation sources +# FIXME disabled for now until we sort out how to handle docs correctly in the +# new build system +#doc_sources = +#DOCDESTDIRS = html:www/www1,man:man/man1,latex:doc/refman +#doc_HTML_SOURCES = ${doc_sources} +#doc_MAN_SOURCES = ${doc_sources} +#doc_LATEX_SOURCES = ${doc_sources} + +endif BUILD_FC_BINDING diff --git a/src/binding/fortran/use_mpi/buildiface b/src/binding/fortran/use_mpi/buildiface index f1cff323f33..c3346ced803 100755 --- a/src/binding/fortran/use_mpi/buildiface +++ b/src/binding/fortran/use_mpi/buildiface @@ -936,220 +936,6 @@ print MPIFD " END MODULE ${ucoutfile_prefix}_t1_s\n"; close MPIFD; &ReplaceIfDifferent("${outfile_prefix}_t1.f90", "${outfile_prefix}_t1.f90.new"); -# ----------------------------------------------------------------------------- -# This block can be used to create the Makefile -if ($is_MPI) { - - # create a stamp file for use by Makefile.mk rebuild make logic - open STAMPFD, '>', 'buildiface-stamp'; - close STAMPFD; - - open(MAKEFD, ">Makefile.mk.new") || die "Cannot create Makefile.mk.new"; - print MAKEFD < \$@ - -CLEANFILES += src/binding/fortran/use_mpi/mpifnoext.h - -EOT - - print MAKEFD "MAINTAINERCLEANFILES += \$(mpi_sources) fproto.h\n"; - print MAKEFD "CLEANFILES += \$(mpi_fc_modules)\n"; - print MAKEFD "\n"; - - #print MAKEFD "install_BIN = mpifort\n"; - #print MAKEFD "install_ETC = mpifort.conf\n"; - - # Add the documentation - #doc_sources = mpifort.txt manfort.txt - print MAKEFD "# Documentation sources -# FIXME disabled for now until we sort out how to handle docs correctly in the -# new build system -#doc_sources = -#DOCDESTDIRS = html:www/www1,man:man/man1,latex:doc/refman -#doc_HTML_SOURCES = \${doc_sources} -#doc_MAN_SOURCES = \${doc_sources} -#doc_LATEX_SOURCES = \${doc_sources} -"; - - # ---------------------------------------------------------------------------- - # FIXME: Add the steps to handle the choice arguments. They should be - # selected by configure from a list of possible choices, with an - # enable switch used to bypass the checks. In addition, we need a way to - # dynamically create subsets, given a list of routines and types/dimensions - # to include. This allows users to build precisely tailored Fortran90 modules. - # ---------------------------------------------------------------------------- - - print MAKEFD "\n"; - print MAKEFD "endif BUILD_FC_BINDING\n"; - - close(MAKEFD); - &ReplaceIfDifferent("Makefile.mk", "Makefile.mk.new"); -} - # # Still to do # make sure that we fit within the Fortran line length rules From 672e90b8d82cf4751eca8bafc6e0ed742be3564f Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 12 Oct 2021 08:54:00 -0500 Subject: [PATCH 073/607] hydra: fix segfaults in argument parsing Add checks for missing argument. As a TODO, we should enhance the error reporting to make it more user friendly. But we should prevent segfault for now at least. --- src/pm/hydra/ui/mpich/utils.c | 9 +++++++++ src/pm/hydra/utils/alloc/alloc.c | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/src/pm/hydra/ui/mpich/utils.c b/src/pm/hydra/ui/mpich/utils.c index 39f4456a482..b4d69d3f923 100644 --- a/src/pm/hydra/ui/mpich/utils.c +++ b/src/pm/hydra/ui/mpich/utils.c @@ -15,6 +15,14 @@ static char **config_argv = NULL; static int reading_config_file = 0; static struct HYD_arg_match_table match_table[]; +#define ASSERT_ARGV \ + do { \ + if (!**argv) { \ + status = HYD_FAILURE; \ + HYDU_ERR_POP(status, "missing command line argument, add -h for help\n"); \ + }\ + } while (0) + static void init_ui_mpich_info(void) { HYD_ui_mpich_info.ppn = -1; @@ -777,6 +785,7 @@ static HYD_status np_fn(char *arg, char ***argv) status = get_current_exec(&exec); HYDU_ERR_POP(status, "get_current_exec returned error\n"); + ASSERT_ARGV; status = HYDU_set_int(arg, &exec->proc_count, atoi(**argv)); HYDU_ERR_POP(status, "error getting executable process count\n"); diff --git a/src/pm/hydra/utils/alloc/alloc.c b/src/pm/hydra/utils/alloc/alloc.c index 2b1110af7e0..fe0214deb0d 100644 --- a/src/pm/hydra/utils/alloc/alloc.c +++ b/src/pm/hydra/utils/alloc/alloc.c @@ -431,6 +431,10 @@ HYD_status HYDU_create_proxy_list(struct HYD_exec *exec_list, struct HYD_node *n pg->proxy_list->next = NULL; HYDU_free_proxy_list(pg->proxy_list); pg->proxy_list = tmp; + if (pg->proxy_list == NULL) { + status = HYD_FAILURE; + HYDU_ERR_POP(status, "Missing executable.\n"); + } } for (proxy = pg->proxy_list; proxy->next;) { if (proxy->next->exec_list == NULL) { From c735d442e9d7d82314fd681a99f4739045e4f88e Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 14 Oct 2021 17:38:35 -0500 Subject: [PATCH 074/607] modules: upgrade hwloc to v2.5.0 --- modules/hwloc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/hwloc b/modules/hwloc index 15a78849f7e..89470e32bfb 160000 --- a/modules/hwloc +++ b/modules/hwloc @@ -1 +1 @@ -Subproject commit 15a78849f7ea56942fee86cb3e9015ab0973ab54 +Subproject commit 89470e32bfb7b9420ab91d4e5fc3fc3bf25feb77 From 55614a4e9ad524c0ae215640826a33130c3cd3e7 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Wed, 20 Oct 2021 11:20:15 -0500 Subject: [PATCH 075/607] bsend: Add dummy var to MPII_Bsend_data to restore ABI [efb8d24a9] removed a field from this structure, which in turn modified the value of MPI_BSEND_OVERHEAD and the MPICH ABI. This was unintended. Add a dummy variable to the struct to restore the ABI. Long-term, we may want to hardcode an upper limit for MPI_BSEND_OVERHEAD for various architectures, and use a configure check to ensure this structure fits within that limit. This discovery was made with the help of ABI Compliance Checker. https://github.com/lvc/abi-compliance-checker. --- src/include/mpir_bsend.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/include/mpir_bsend.h b/src/include/mpir_bsend.h index 627a31f99ae..8d1e9f6cce4 100644 --- a/src/include/mpir_bsend.h +++ b/src/include/mpir_bsend.h @@ -49,11 +49,14 @@ typedef struct MPII_Bsend_msg { } MPII_Bsend_msg_t; /* BsendData describes a bsend request */ +/* NOTE: The size of this structure determines the value of + * MPI_BSEND_OVERHEAD in mpi.h, which is part of the MPICH ABI. */ typedef struct MPII_Bsend_data { size_t size; /* size that is available for data */ size_t total_size; /* total size of this segment, * including all headers */ struct MPII_Bsend_data *next, *prev; + int dummy; /* dummy var to preserve ABI compatibility */ struct MPIR_Request *request; MPII_Bsend_msg_t msg; double alignpad; /* make sure that the struct From 53644b49c8bc32d270f32f2aac0548d69422bab7 Mon Sep 17 00:00:00 2001 From: Sriraj Date: Thu, 16 Sep 2021 17:25:54 -0500 Subject: [PATCH 076/607] ch4/stub: remove including mpl.h which is already added in mpidimpl.h From mpiimpl.h: pmix.h contains inline functions that calls malloc, calloc, and free, and it will break with MPL's memory tracing when enabled. So we need to make sure mpiimpl.h is included before mpl.h. --- maint/gen_ch4_api.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/maint/gen_ch4_api.py b/maint/gen_ch4_api.py index 0ad0b71473a..652432fe68e 100644 --- a/maint/gen_ch4_api.py +++ b/maint/gen_ch4_api.py @@ -280,13 +280,11 @@ def dump_func_table_c(c_file, mod): print(" --> [%s]" % c_file) with open(c_file, "w") as Out: dump_copyright(Out) - print("#include \"mpl.h\"", file=Out) - print("", file=Out) - print("MPL_SUPPRESS_OSX_HAS_NO_SYMBOLS_WARNING;", file=Out) - print("", file=Out) print("#ifndef NETMOD_INLINE", file=Out) print("#define NETMOD_DISABLE_INLINES", file=Out) print("#include ", file=Out) + print("MPL_SUPPRESS_OSX_HAS_NO_SYMBOLS_WARNING;", file=Out) + print("", file=Out) print("#include \"netmod_inline.h\"", file=Out) print("MPIDI_NM_funcs_t MPIDI_NM_%s_funcs = {" % mod, file=Out) for a in G.apis: From 9f11d4fe03fa88e5321b15fdc5db0f336baba95b Mon Sep 17 00:00:00 2001 From: Sagar Thapaliya Date: Tue, 19 Oct 2021 16:40:44 -0500 Subject: [PATCH 077/607] ofi: use correct request pool idx in emulated inject This fixes failure of probe_unexp under multi vci. The pool idx was hard-coded to 0, which was incorrect. As a request, an expected mutex locking would be missing if vni_src != 0. Reason is: the upper layer takes lock with vni_src, not with pool idx. --- src/mpid/ch4/netmod/ofi/ofi_am_impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_am_impl.h b/src/mpid/ch4/netmod/ofi/ofi_am_impl.h index ee65179a551..482686fadd3 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_am_impl.h +++ b/src/mpid/ch4/netmod/ofi/ofi_am_impl.h @@ -536,7 +536,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_do_emulated_inject(MPIR_Comm * comm, fi_a int nic = 0; int ctx_idx = MPIDI_OFI_get_ctx_index(comm, vni_src, nic); - MPIDI_CH4_REQUEST_CREATE(sreq, MPIR_REQUEST_KIND__SEND, 0, 1); + MPIDI_CH4_REQUEST_CREATE(sreq, MPIR_REQUEST_KIND__SEND, vni_src, 1); MPIR_ERR_CHKANDSTMT((sreq) == NULL, mpi_errno, MPIX_ERR_NOREQ, goto fn_fail, "**nomemreq"); len = am_hdr_sz + sizeof(*msg_hdrp); ibuf = (char *) MPL_malloc(len, MPL_MEM_BUFFER); From 9cd61f138dc884b8f8bc100f7e7e72e8968fc188 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 20 Oct 2021 18:41:22 -0500 Subject: [PATCH 078/607] ch4/ofi: fix bug in get_huge_complete We need save the comm_ptr before calling MPIDI_OFI_recv_event because it may free the request pointer and make rreq->comm inaccessible. This is especially true when the receive is an any source receive, when the user visible request is the shm request, and the netmod request will get freed after copied over. Fixes pmodels/mpich#5607. --- src/mpid/ch4/netmod/ofi/ofi_huge.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_huge.c b/src/mpid/ch4/netmod/ofi/ofi_huge.c index 631da654656..8f70eb176e9 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_huge.c +++ b/src/mpid/ch4/netmod/ofi/ofi_huge.c @@ -149,6 +149,9 @@ static int get_huge_complete(MPIR_Request * rreq) int vni_remote = info->vni_src; int vni_local = info->vni_dst; + /* important: save comm_ptr because MPIDI_OFI_recv_event may free the request. */ + MPIR_Comm *comm_ptr = rreq->comm; + struct fi_cq_tagged_entry wc; wc.len = info->msgsize; wc.data = info->origin_rank; @@ -158,7 +161,7 @@ static int get_huge_complete(MPIR_Request * rreq) MPIDI_OFI_send_control_t ctrl; ctrl.type = MPIDI_OFI_CTRL_HUGEACK; ctrl.u.huge_ack.ackreq = info->ackreq; - mpi_errno = MPIDI_NM_am_send_hdr(info->origin_rank, rreq->comm, + mpi_errno = MPIDI_NM_am_send_hdr(info->origin_rank, comm_ptr, MPIDI_OFI_INTERNAL_HANDLER_CONTROL, &ctrl, sizeof(ctrl), vni_local, vni_remote); MPIR_ERR_CHECK(mpi_errno); From da178d006555d57b70374fbae07e123e713be1e9 Mon Sep 17 00:00:00 2001 From: Sagar Thapaliya Date: Tue, 26 Feb 2019 15:57:04 -0600 Subject: [PATCH 079/607] mtest: add testcases for comm hints guided vci assignment Addition includes testcases for the standard comm hints: mpi_assert_no_any_tag, mpi_assert_no_any_source, and mpi_assert_allow_overtaking. --- .../mpich/threads/pt2pt/sendrecv_vci_hint.c | 58 ++++++++++++++++--- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/test/mpi/impls/mpich/threads/pt2pt/sendrecv_vci_hint.c b/test/mpi/impls/mpich/threads/pt2pt/sendrecv_vci_hint.c index ef9468a5d31..95c4a8f7496 100644 --- a/test/mpi/impls/mpich/threads/pt2pt/sendrecv_vci_hint.c +++ b/test/mpi/impls/mpich/threads/pt2pt/sendrecv_vci_hint.c @@ -28,6 +28,7 @@ struct thread_param { MPI_Comm comm; int tag; int result; + bool maintain_msg_order; /* Useful for the hint allow overtaking */ }; /* A simple send recv test that is used by the test threads */ @@ -43,12 +44,21 @@ MTEST_THREAD_RETURN_TYPE run_send_recv_test(void *arg) MPI_Comm_rank(p->comm, &rank); for (i = 0; i < p->iter; i++) { if (rank == 0) { - buff[i] = i + (thread_id_mult * p->id); + buff[i] = (thread_id_mult * p->id); + /* If the hint mpi_assert_allow_overtaking is present, msg from + * the different iterations can match in any order. So, we keep + * the data value same across the iterations. That way the data + * validation in this test after the recv will not pick it as + error */ + if (p->maintain_msg_order) + buff[i] += i; MPI_Send(&buff[i], 1, MPI_INT, 1, p->tag, p->comm); } else { buff[i] = -1; MPI_Recv(&buff[i], 1, MPI_INT, 0, p->tag, p->comm, &status[i]); - if (buff[i] != i + thread_id_mult * p->id) { + /* Data validation */ + if ((p->maintain_msg_order && buff[i] != i + thread_id_mult * p->id) + || !p->maintain_msg_order && buff[i] != thread_id_mult * p->id) { errs++; } } @@ -60,7 +70,7 @@ MTEST_THREAD_RETURN_TYPE run_send_recv_test(void *arg) /* Launch multiple threads, apply provided comm hints, run send/recv */ int comm_hint_test(const char **comm_hints, const char **comm_hints_vals, int n_hints, - bool test_set_value) + bool test_set_value, bool maintain_msg_order) { int i, j, errs = 0, nprocs, rank, flag; struct thread_param params[NTHREADS]; @@ -111,6 +121,7 @@ int comm_hint_test(const char **comm_hints, const char **comm_hints_vals, int n_ params[i].tag = i; /* Set tag = thread id */ params[i].iter = ITERATIONS; params[i].id = i; + params[i].maintain_msg_order = maintain_msg_order; if (i == NTHREADS - 1) run_send_recv_test(¶ms[i]); else @@ -159,10 +170,41 @@ int main(int argc, char **argv) * Perform send/recv with no comm hint applied. Just for * sanity check. */ - errs += comm_hint_test(NULL, NULL, 0, false); + errs += comm_hint_test(NULL, NULL, 0, false, false); MPI_Barrier(MPI_COMM_WORLD); - /* TODO: Standard comm hints tests. */ + /* Standard comm hints tests. + * The following standard comm hints are expected to guide how + * vci_idx are chosen for both sender and receiver. So, this test + * aims to trigger the vci_idx selection. After applying this hint, + * we expect send-recv to run without any crash or hangup. + */ + + /* Test : hints assert_no_any_tag */ + hints_1[0] = "mpi_assert_no_any_tag"; + hints_1_vals[0] = "true"; + errs += comm_hint_test(hints_1, hints_1_vals, 1, true, true); + MPI_Barrier(MPI_COMM_WORLD); + + /* Test : hints assert_no_any_tag and assert_no_any_source */ + hints_1[0] = "mpi_assert_no_any_source"; + hints_1_vals[0] = "true"; + errs += comm_hint_test(hints_1, hints_1_vals, 1, true, true); + MPI_Barrier(MPI_COMM_WORLD); + + /* Test : hints assert_no_any_tag and assert_no_any_source */ + hints_1[0] = "mpi_assert_no_any_tag"; + hints_1[1] = "mpi_assert_no_any_source"; + hints_1_vals[0] = "true"; + hints_1_vals[1] = "true"; + errs += comm_hint_test(hints_1, hints_1_vals, 2, true, true); + MPI_Barrier(MPI_COMM_WORLD); + + /* Test : hint assert_allow_overtaking */ + hints_1[0] = "mpi_assert_allow_overtaking"; + hints_1_vals[0] = "true"; + errs += comm_hint_test(hints_1, hints_1_vals, 1, true, false); + MPI_Barrier(MPI_COMM_WORLD); /* Non-standard comm hints tests. * The following non-standard hints allow user to directly @@ -178,7 +220,7 @@ int main(int argc, char **argv) hints_1[1] = "receiver_vci"; hints_1_vals[0] = "2"; hints_1_vals[1] = "3"; - errs += comm_hint_test(hints_1, hints_1_vals, 2, false); + errs += comm_hint_test(hints_1, hints_1_vals, 2, false, true); MPI_Barrier(MPI_COMM_WORLD); /* Test : sender_vci and receiver_vci with potential invalid values @@ -190,7 +232,7 @@ int main(int argc, char **argv) hints_1[1] = "receiver_vci"; hints_1_vals[0] = "99999"; hints_1_vals[1] = "99999"; - errs += comm_hint_test(hints_1, hints_1_vals, 2, false); + errs += comm_hint_test(hints_1, hints_1_vals, 2, false, true); MPI_Barrier(MPI_COMM_WORLD); /* Test : vci hint. @@ -199,7 +241,7 @@ int main(int argc, char **argv) */ hints_1[0] = "vci"; hints_1_vals[0] = "2"; - errs += comm_hint_test(hints_1, hints_1_vals, 1, false); + errs += comm_hint_test(hints_1, hints_1_vals, 1, false, true); MPI_Barrier(MPI_COMM_WORLD); MTest_Finalize(errs); From 7669ba60d51b93619c3dfd6939b8ffffa40fa19a Mon Sep 17 00:00:00 2001 From: Sagar Thapaliya Date: Fri, 6 Aug 2021 13:06:13 -0500 Subject: [PATCH 080/607] ch4: implement hash functions for implicit vci selection Implicit hashing utilizes (comm, rank, tag) and user hints to select vci. In a general situation, sender vci is chosen using comm, rank, and tag. Receiver vci is chosen using comm. This helps maintain message ordering that is required by MPI. Optimization can be added to allow improved distribution of the traffic across more vcis, while still maintainint the message ordering requirement, if we know about certain behavior of the application. In this patch, we utilize the following comm hints from MPI 4.0 standard. User can apply thse hints on a communicator to express known behavior of an application: - mpi_assert_no_any_source: Set this info hint if the application does not use the wildcard MPI_ANY_SOURCE on the given communicator. - mpi_assert_no_any_tag: Set this hint if the application does not use MPI_ANY_TAG on the given communciator. --- src/mpid/ch4/src/ch4_vci.h | 59 +++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/src/mpid/ch4/src/ch4_vci.h b/src/mpid/ch4/src/ch4_vci.h index 72f4c487d99..9e3667e2600 100644 --- a/src/mpid/ch4/src/ch4_vci.h +++ b/src/mpid/ch4/src/ch4_vci.h @@ -71,6 +71,31 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_get_vci(int flag, MPIR_Comm * comm_ptr, #elif MPIDI_CH4_VCI_METHOD == MPICH_VCI__IMPLICIT +/* Map comm to vci_idx */ +MPL_STATIC_INLINE_PREFIX int MPIDI_map_contextid_to_vci(MPIR_Context_id_t context_id) +{ + return (MPIR_CONTEXT_READ_FIELD(PREFIX, context_id)) % MPIDI_global.n_vcis; +} + +/* Map comm and rank to vci_idx */ +MPL_STATIC_INLINE_PREFIX int MPIDI_map_contextid_rank_to_vci(MPIR_Context_id_t context_id, int rank) +{ + return (MPIR_CONTEXT_READ_FIELD(PREFIX, context_id) + rank) % MPIDI_global.n_vcis; +} + +/* Map comm and tag to vci_idx */ +MPL_STATIC_INLINE_PREFIX int MPIDI_map_contextid_tag_to_vci(MPIR_Context_id_t context_id, int tag) +{ + return (MPIR_CONTEXT_READ_FIELD(PREFIX, context_id) + tag) % MPIDI_global.n_vcis;; +} + +/* Map comm, rank, and tag to vci_idx */ +MPL_STATIC_INLINE_PREFIX int MPIDI_map_contextid_rank_tag_to_vci(MPIR_Context_id_t context_id, + int rank, int tag) +{ + return (MPIR_CONTEXT_READ_FIELD(PREFIX, context_id) + rank + tag) % MPIDI_global.n_vcis;; +} + static bool is_vci_restricted_to_zero(MPIR_Comm * comm) { bool vci_restricted = false; @@ -106,13 +131,19 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_get_sender_vci(MPIR_Comm * comm, MPIR_Assert(comm); int vci_idx = MPIDI_VCI_INVALID; bool use_user_defined_vci = (comm->hints[MPIR_COMM_HINT_SENDER_VCI] != MPIDI_VCI_INVALID); + bool use_tag = comm->hints[MPIR_COMM_HINT_NO_ANY_TAG]; + if (is_vci_restricted_to_zero(comm)) { vci_idx = 0; } else if (use_user_defined_vci) { vci_idx = comm->hints[MPIR_COMM_HINT_SENDER_VCI]; } else { - /* TODO: implement implicit hashing using other parameters */ - vci_idx = comm->seq; + if (use_tag) { + vci_idx = MPIDI_map_contextid_rank_tag_to_vci(ctxid_in_effect, receiver_rank, tag); + } else { + /* General unoptimized case */ + vci_idx = MPIDI_map_contextid_rank_to_vci(ctxid_in_effect, receiver_rank); + } } return vci_idx; #else @@ -142,13 +173,33 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_get_receiver_vci(MPIR_Comm * comm, MPIR_Assert(comm); int vci_idx = MPIDI_VCI_INVALID; bool use_user_defined_vci = (comm->hints[MPIR_COMM_HINT_RECEIVER_VCI] != MPIDI_VCI_INVALID); + bool use_tag = comm->hints[MPIR_COMM_HINT_NO_ANY_TAG]; + bool use_source = comm->hints[MPIR_COMM_HINT_NO_ANY_SOURCE]; + if (is_vci_restricted_to_zero(comm)) { vci_idx = 0; } else if (use_user_defined_vci) { vci_idx = comm->hints[MPIR_COMM_HINT_RECEIVER_VCI]; } else { - /* TODO: implement implicit hashing using other parameters */ - vci_idx = comm->seq; + /* If mpi_any_tag and mpi_any_source can be used for recv, all messages + * should be received on a single vci. Otherwise, messages sent from a + * rank can concurrently match at different vcis. This can allow a + * mesasge to be received in different order than it was sent. We + * should avoid this. + * However, if we know mpi_any_source and MPI_any_tag are absent, we + * don't have this risk and hence we can utilize multiple vcis on the + * receive side. + */ + if (use_tag && use_source) { + vci_idx = MPIDI_map_contextid_rank_tag_to_vci(ctxid_in_effect, sender_rank, tag); + } else if (use_source) { + vci_idx = MPIDI_map_contextid_rank_to_vci(ctxid_in_effect, sender_rank); + } else if (use_tag) { + vci_idx = MPIDI_map_contextid_tag_to_vci(ctxid_in_effect, tag); + } else { + /* General unoptimized case */ + vci_idx = MPIDI_map_contextid_to_vci(ctxid_in_effect); + } } return vci_idx; #else From f963bb0bcf32fc3f3aafafdd92aa4b93d7174c8f Mon Sep 17 00:00:00 2001 From: Sagar Thapaliya Date: Fri, 6 Aug 2021 13:15:32 -0500 Subject: [PATCH 081/607] ch4: use vci 0 during init for multiple domains case When using multiple-domains (in contrast to scalable endpoints), only single domain and single vci is enabled during the init time. Other vcis are not usable yet. So we disable them. --- src/mpid/ch4/src/ch4_vci.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mpid/ch4/src/ch4_vci.h b/src/mpid/ch4/src/ch4_vci.h index 9e3667e2600..e985af1ce73 100644 --- a/src/mpid/ch4/src/ch4_vci.h +++ b/src/mpid/ch4/src/ch4_vci.h @@ -102,6 +102,11 @@ static bool is_vci_restricted_to_zero(MPIR_Comm * comm) if (!(comm->comm_kind == MPIR_COMM_KIND__INTRACOMM && !comm->tainted)) { vci_restricted |= true; } +#ifdef MPIDI_OFI_VNI_USE_DOMAIN + if (!MPIDI_global.is_initialized) { + vci_restricted |= true; + } +#endif /* ifdef MPIDI_OFI_VNI_USE_DOMAIN */ return vci_restricted; } From 0c362f8e45b0e62393e1146929c746924ab37cc9 Mon Sep 17 00:00:00 2001 From: Sagar Thapaliya Date: Mon, 24 May 2021 16:04:26 -0500 Subject: [PATCH 082/607] ch4/ofi: add barrier during vni address exchange Ranks should wait until address exchange is complete and the av table is setup in all the ranks. Otherwise, some processes may try to access the av table prematurely, e.g., when different ranks exit address exchange at different times. Such problem was observed with the sockets provider. One rank was still under address exchange, when it received an incoming communication from a rank that already completed its address exchange steps. Then libfabric processed this communication for the first rank, and tried to to an av lookup for the remote rank, but before that address added to the av. This resulted in test failures. --- src/mpid/ch4/netmod/ofi/init_addrxchg.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mpid/ch4/netmod/ofi/init_addrxchg.c b/src/mpid/ch4/netmod/ofi/init_addrxchg.c index 776c0edd9df..57782fa83c3 100644 --- a/src/mpid/ch4/netmod/ofi/init_addrxchg.c +++ b/src/mpid/ch4/netmod/ofi/init_addrxchg.c @@ -293,6 +293,8 @@ int MPIDI_OFI_addr_exchange_all_ctx(void) } } } + mpi_errno = MPIR_Barrier_fallback(comm, &errflag); + MPIR_ERR_CHECK(mpi_errno); fn_check: if (MPIDI_OFI_ENABLE_AV_TABLE) { From ed7c93e6706f5b3cecd91eb5dcc7d4f784cbb6d9 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 11 Oct 2021 19:44:50 -0500 Subject: [PATCH 083/607] maint: add scripts for generating f77 binding These scripts will generate the C wrapping functions for mpif.h Fortran binding. It is more systematic than the old buildiface since it derives parameter interface from standard interface rather than mpi.h. --- maint/gen_binding_f77.py | 52 ++ maint/local_python/binding_common.py | 12 + maint/local_python/binding_f77.py | 1130 ++++++++++++++++++++++++++ maint/local_python/mpi_api.py | 18 + 4 files changed, 1212 insertions(+) create mode 100644 maint/gen_binding_f77.py create mode 100644 maint/local_python/binding_f77.py diff --git a/maint/gen_binding_f77.py b/maint/gen_binding_f77.py new file mode 100644 index 00000000000..374ad60e400 --- /dev/null +++ b/maint/gen_binding_f77.py @@ -0,0 +1,52 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +from local_python import MPI_API_Global as G +from local_python.mpi_api import * +from local_python.binding_common import * +from local_python.binding_f77 import * +from local_python import RE +import os + +def main(): + # currently support -no-real128, -no-mpiio, -aint-is-int + G.parse_cmdline() + + binding_dir = G.get_srcdir_path("src/binding") + f77_dir = "src/binding/fortran/mpif_h" + + func_list = load_C_func_list(binding_dir, True) # suppress noise + + if "no-mpiio" in G.opts: + # a few MPI_File_xxx functions are already in (MPI_File_xxx_errhandler) + func_list = [f for f in func_list if not f['name'].startswith('MPI_File_')] + else: + # FIXME: until romio interface is generated + func_list.extend(get_mpiio_func_list()) + func_list.extend(get_f77_dummy_func_list()) + func_list.extend(get_type_create_f90_func_list()) + + # preprocess + for func in func_list: + check_func_directives(func) + func_list = [f for f in func_list if '_skip_fortran' not in f] + + # fortran_binding.c + G.out = [] + G.profile_out = [] + for func in func_list: + G.out.append("") + dump_f77_c_func(func) + + f = "%s/fortran_binding.c" % f77_dir + dump_f77_c_file(f, G.out) + + f = "%s/fortran_profile.h" % f77_dir + dump_f77_c_file(f, G.profile_out) + +# --------------------------------------------------------- +if __name__ == "__main__": + main() + diff --git a/maint/local_python/binding_common.py b/maint/local_python/binding_common.py index 5fb99f873c4..542d1c38e4a 100644 --- a/maint/local_python/binding_common.py +++ b/maint/local_python/binding_common.py @@ -188,6 +188,18 @@ def is_pointer_type(param): else: return 0 +def param_is_in(p): + if p['param_direction'] == 'in' or p['param_direction'] == 'inout': + return True + else: + return False + +def param_is_out(p): + if p['param_direction'] == 'out' or p['param_direction'] == 'inout': + return True + else: + return False + def get_userbuffer_group(func_name, parameters, i): """internal function used by process_func_parameters""" p = parameters[i] diff --git a/maint/local_python/binding_f77.py b/maint/local_python/binding_f77.py new file mode 100644 index 00000000000..fa53a4b8e80 --- /dev/null +++ b/maint/local_python/binding_f77.py @@ -0,0 +1,1130 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +from local_python import MPI_API_Global as G +from local_python.binding_common import * +from local_python import RE + +import re + +def get_f77_name(func): + name = func['name'] + return name + +def dump_f77_c_func(func): + name = get_f77_name(func).lower() + f_mapping = get_kind_map('F90') + c_mapping = get_kind_map('C') + + c_param_list = [] + c_param_list_end = [] # for string args, ref: FORT_END_LEN + code_list_common = [] + end_list_common = [] + + # code for HAVE_FINT_IS_INT + c_arg_list_A = [] + code_list_A = [] + end_list_A = [] + + # code for #!defined HAVE_FINT_IS_INT + c_arg_list_B = [] + code_list_B = [] + end_list_B = [] + + need_ATTR_AINT = False + is_custom_fn = False # custom function body + need_skip_ierr = False + + if re.match(r'MPI_((\w+)_(get|set)_attr|Attr_(put|get))', func['name'], re.IGNORECASE): + need_ATTR_AINT = True + elif re.match(r'MPI.*_(DUP|DELETE|COPY)_FN|MPI_CONVERSION_FN_NULL', func['name'], re.IGNORECASE): + is_custom_fn = True + + if len(func['parameters']) > 0: + last_p = func['parameters'][-1] + if last_p['kind'] == 'ERROR_CODE' and re.search(r'c_parameter', last_p['suppress']): + need_skip_ierr = True + if re.match(r'MPI_Pcontrol', func['name'], re.IGNORECASE): + need_skip_ierr = True + + # ---- internal functions -------------------- + # input as MPI_Fint + def dump_p(p): + c_type = c_mapping[p['kind']] + if "length" in p and p['length']: + if re.match(r'mpi_i?neighbor_', func['name'], re.IGNORECASE): + if p['kind'] == "DISPLACEMENT": + # neighbor_alltoallw - sdispls and rdispls + dump_direct_pointer(p['name'], "MPI_Aint") + elif re.search(r'_allgatherv', func['name'], re.IGNORECASE): + dump_array_in(p['name'], c_type, "indegree") + elif re.match(r'(sendcounts|sdispls|sendtypes)', p['name'], re.IGNORECASE): + dump_array_in(p['name'], c_type, "indegree") + else: + dump_array_in(p['name'], c_type, "outdegree") + elif re.match(r'mpi_.*(gatherv|scatterv|alltoall[vw]|reduce_scatter)', func['name'], re.IGNORECASE): + dump_array_in(p['name'], c_type, "comm_size") + else: + raise Exception("Unhandled: %s - %s, length=%s" % (func['name'], p['name'], p['length'])) + else: + c_param_list.append("MPI_Fint *" + p['name']) + c_arg_list_A.append("(%s) (*%s)" % (c_type, p['name'])) + c_arg_list_B.append("(%s) (*%s)" % (c_type, p['name'])) + + def dump_scalar_out(v, f_type, c_type): + c_param_list.append("%s *%s" % (f_type, v)) + c_arg_list_A.append("&%s_i" % v) + c_arg_list_B.append("&%s_i" % v) + code_list_common.append("%s %s_i;" % (c_type, v)) + end_list_common.append("*%s = (%s) %s_i;" % (v, f_type, v)) + + # void * + def dump_buf(buf, check_in_place): + # void * + c_param_list.append("void *%s" % buf) + + c_arg_list_A.append(buf) + c_arg_list_B.append(buf) + code_list_common.append("if (%s == MPIR_F_MPI_BOTTOM) {" % buf) + code_list_common.append(" %s = MPI_BOTTOM;" % buf) + if check_in_place: + code_list_common.append("} else if (%s == MPIR_F_MPI_IN_PLACE) {" % buf) + code_list_common.append(" %s = MPI_IN_PLACE;" % buf) + code_list_common.append("}") + code_list_common.append("") + + # MPI_Status + def dump_status(v, is_in, is_out): + c_param_list.append("MPI_Fint *%s" % v) + + def dump_FINT_is_INT_pre(): + c_arg_list_A.append("(MPI_Status *) %s" % v) + if is_out: + code_list_A.append("if (%s == MPI_F_STATUS_IGNORE) {" % v) + code_list_A.append(" %s = (MPI_Fint *) MPI_STATUS_IGNORE;" % v) + code_list_A.append("}") + + def dump_FINT_not_INT_pre(): + c_arg_list_B.append("status_arg") + code_list_B.append("MPI_Status * status_arg;") + code_list_B.append("int status_i[MPI_F_STATUS_SIZE];") + if is_out: + code_list_B.append("if (%s == MPI_F_STATUS_IGNORE) {" % v) + code_list_B.append(" status_arg = MPI_STATUS_IGNORE;") + code_list_B.append("} else {") + # NOTE: always copy in because some fields (e.g. MPI_ERROR) may need be untouched + code_list_B.append("INDENT") + copy_status_in() + code_list_B.append("DEDENT") + code_list_B.append("}") + if is_in: + copy_status_in() + def dump_FINT_not_INT_post(): + if is_out: + end_list_B.append("if (%s != MPI_F_STATUS_IGNORE) {" % v) + code_list_B.append("INDENT") + copy_status_out() + code_list_B.append("DEDENT") + end_list_B.append("}") + def copy_status_in(): + code_list_B.append("status_arg = (MPI_Status *) status_i;") + code_list_B.append("for (int i = 0; i < MPI_F_STATUS_SIZE; i++) {") + code_list_B.append(" status_i[i] = (int) %s[i];" % v) + code_list_B.append("}") + def copy_status_out(): + end_list_B.append("for (int i = 0; i < MPI_F_STATUS_SIZE; i++) {") + end_list_B.append(" %s[i] = (MPI_Fint) status_i[i];" % v) + end_list_B.append("}") + + dump_FINT_is_INT_pre() + dump_FINT_not_INT_pre() + dump_FINT_not_INT_post() + + # e.g. MPI_Status array_of_statuses[] + def dump_statuses(v, incount, outcount, is_in, is_out): + c_param_list.append("MPI_Fint *%s" % v) + + def dump_FINT_is_INT_pre(): + c_arg_list_A.append("(MPI_Status *) %s" % v) + if is_out: + code_list_A.append("if (%s == MPI_F_STATUSES_IGNORE) {" % v) + code_list_A.append(" %s = (MPI_Fint *) MPI_STATUSES_IGNORE;" % v) + code_list_A.append("}") + + def dump_FINT_not_INT_pre(): + c_arg_list_B.append("statuses_i") + code_list_B.append("MPI_Status *statuses_i;") + if is_out: + code_list_B.append("if (%s == MPI_F_STATUSES_IGNORE) {" % v) + code_list_B.append(" statuses_i = MPI_STATUS_IGNORE;") + code_list_B.append("} else {") + else: + code_list_B.append("{") + code_list_B.append("INDENT") + copy_statuses_in() + code_list_B.append("DEDENT") + code_list_B.append("}") + def dump_FINT_not_INT_post(): + if is_out: + end_list_B.append("if (%s != MPI_F_STATUSES_IGNORE) {" % v) + end_list_B.append("INDENT") + copy_statuses_out() + end_list_B.append("DEDENT") + end_list_B.append("}") + else: + end_list_B.append("free(statuses_i);") + + def copy_statuses_in(): + code_list_B.append("statuses_i = malloc(%s * sizeof(MPI_Status));" % incount) + code_list_B.append("int *p = (int *) statuses_i;") + code_list_B.append("for (int i = 0; i < %s * MPI_F_STATUS_SIZE; i++) {" % incount) + code_list_B.append(" p[i] = (int) %s[i];" % v) + code_list_B.append("}") + def copy_statuses_out(): + end_list_B.append("int *p = (int *) statuses_i;") + end_list_B.append("for (int i = 0; i < %s * MPI_F_STATUS_SIZE; i++) {" % outcount) + end_list_B.append(" %s[i] = (MPI_Fint) p[i];" % v) + end_list_B.append("}") + end_list_B.append("free(statuses_i);") + + + dump_FINT_is_INT_pre() + dump_FINT_not_INT_pre() + dump_FINT_not_INT_post() + + # scalar int output, e.g. MPI_Request *req_out + def dump_int_out(v, c_type, is_inout): + c_param_list.append("MPI_Fint *%s" % v) + + def dump_FINT_is_INT_pre(): + c_arg_list_A.append("(%s *) %s" % (c_type, v)) + + def dump_FINT_not_INT_pre(): + c_arg_list_B.append("&%s_i" % v) + code_list_B.append("%s %s_i;" % (c_type, v)) + if is_inout: + code_list_B.append("%s_i = (%s) *%s;" % (v, c_type, v)) + def dump_FINT_not_INT_post(): + end_list_B.append("*%s = (MPI_Fint) %s_i;" % (v, v)) + + dump_FINT_is_INT_pre() + dump_FINT_not_INT_pre() + dump_FINT_not_INT_post() + + # scalar integer input, but we assume Fortran use the same c_type + def dump_c_type_in(v, c_type): + c_param_list.append("%s *%s" % (c_type, v)) + c_arg_list_A.append('*' + v) + c_arg_list_B.append('*' + v) + + # e.g. MPI_Address + def dump_aint_out_check(v): + c_param_list.append("MPI_Fint *%s" % v) + c_arg_list_A.append("&%s_i" % v) + c_arg_list_B.append("&%s_i" % v) + code_list_common.append("MPI_Aint %s_i;" % v) + end_list_common.append("*%s = (MPI_Fint) %s_i;" % (v, v)) + end_list_common.append("if ((MPI_Aint) (*%s) != %s_i) {" % (v, v)) + end_list_common.append(" /* Unfortunately, there isn't an easy way to invoke error handler */") + end_list_common.append(" *ierr = MPI_ERR_OTHER;") + end_list_common.append("}") + + # arrays, e.g. MPI_Request array_of_reqs[] + # NOTE: we also handle MPI_UNWEIGHTED, MPI_WEIGHTS_EMPTY + + def dump_array_in(v, c_type, count): + dump_array(v, c_type, count, count, True, False) + + def dump_array_out(v, c_type, count): + dump_array(v, c_type, count, count, False, True) + + def dump_array_special_in(v, c_type, count): + dump_array(v, c_type, count, count, True, False, True) + + def dump_array_special_out(v, c_type, count): + dump_array(v, c_type, count, count, False, True, True) + + def dump_array(v, c_type, incount, outcount, is_in=True, is_out=False, has_special=False): + c_param_list.append("MPI_Fint *%s" % v) + + def dump_FINT_is_INT_pre(): + c_arg_list_A.append("(int *) %s" % v) + dump_check_special(True) + + def dump_FINT_not_INT_pre(): + c_arg_list_B.append("%s_i" % v) + code_list_B.append("%s *%s_i;" % (c_type, v)) + dump_check_special(False) + + dump_check_special_begin(code_list_B) + code_list_B.append("%s_i = malloc(sizeof(%s) * %s);" % (v, c_type, incount)) + if is_in: + code_list_B.append("for (int i = 0; i < %s; i++) {" % incount) + code_list_B.append(" %s_i[i] = (%s) %s[i];" % (v, c_type, v)) + code_list_B.append("}") + dump_check_special_end(code_list_B) + def dump_FINT_not_INT_post(): + dump_check_special_begin(end_list_B) + if is_out: + end_list_B.append("for (int i = 0; i < %s; i++) {" % outcount) + if v == 'periods': + # hack for logical + end_list_B.append(" %s[i] = MPII_TO_FLOG(%s_i[i]);" % (v, v)) + else: + end_list_B.append(" %s[i] = (MPI_Fint) %s_i[i];" % (v, v)) + end_list_B.append("}") + end_list_B.append("free(%s_i);" % v) + dump_check_special_end(end_list_B) + + def dump_check_special(FINT_is_INT): + def check_weights(): + if FINT_is_INT: + code_list_A.append("if (%s == MPIR_F_MPI_UNWEIGHTED) {" % v) + code_list_A.append(" %s = (MPI_Fint *) MPI_UNWEIGHTED;" % v) + code_list_A.append("} else if (%s == MPIR_F_MPI_WEIGHTS_EMPTY) {" % v) + code_list_A.append(" %s = (MPI_Fint *) MPI_WEIGHTS_EMPTY;" % v) + code_list_A.append("}") + else: + code_list_B.append("int %s_is_special = 0;" % v) + code_list_B.append("if (%s == MPIR_F_MPI_UNWEIGHTED) {" % v) + code_list_B.append(" %s_i = MPI_UNWEIGHTED;" % v) + code_list_B.append(" %s_is_special = 1;" % v) + code_list_B.append("} else if (%s == MPIR_F_MPI_WEIGHTS_EMPTY) {" % v) + code_list_B.append(" %s_i = MPI_WEIGHTS_EMPTY;" % v) + code_list_B.append(" %s_is_special = 1;" % v) + code_list_B.append("}") + def check_errcodes(): + if FINT_is_INT: + code_list_A.append("if (%s == MPI_F_ERRCODES_IGNORE) {" % v) + code_list_A.append(" %s = (MPI_Fint *) MPI_ERRCODES_IGNORE;" % v) + code_list_A.append("}") + else: + code_list_B.append("int %s_is_special = 0;" % v) + code_list_B.append("if (%s == MPI_F_ERRCODES_IGNORE) {" % v) + code_list_B.append(" %s_i = MPI_ERRCODES_IGNORE;" % v) + code_list_B.append(" %s_is_special = 1;" % v) + code_list_B.append("}") + + if has_special: + if is_in and re.match(r'(source|dest)?weights$', v): + check_weights() + elif is_out and re.match(r'.*_errcodes$', v): + check_errcodes() + else: + raise Exception("Unhandled special parameter: %s - %s" % (func['name'], v)) + + def dump_check_special_begin(code_list): + if has_special: + code_list.append("if (!%s_is_special) {" % v) + code_list.append("INDENT") + def dump_check_special_end(code_list): + if has_special: + code_list.append("DEDENT") + code_list.append("}") + + dump_FINT_is_INT_pre() + dump_FINT_not_INT_pre() + dump_FINT_not_INT_post() + + def dump_array_int_to_aint(v, count): + c_param_list.append("MPI_Fint *%s" % v) + c_arg_list_A.append("%s_i" % v) + c_arg_list_B.append("%s_i" % v) + code_list_common.append("MPI_Aint *%s_i;" % v) + code_list_common.append("#ifdef HAVE_AINT_DIFFERENT_THAN_FINT") + code_list_common.append("%s_i = malloc(%s * sizeof(MPI_Aint));" % (v, count)) + code_list_common.append("for (int i = 0; i < %s; i++) {" % count) + code_list_common.append(" %s_i[i] = (MPI_Aint) %s[i];" % (v, v)) + code_list_common.append("}") + code_list_common.append("#else") + code_list_common.append("%s_i = %s;" % (v, v)) + code_list_common.append("#endif") + end_list_common.append("#ifdef HAVE_AINT_DIFFERENT_THAN_FINT") + end_list_common.append("free(%s_i);" % v) + end_list_common.append("#endif") + + def dump_string_in(v): + c_param_list.append("char *%s FORT_MIXED_LEN(%s_len)" % (v, v)) + c_param_list_end.append("FORT_END_LEN(%s_len)" % v) + c_arg_list_A.append("%s_i" % v) + c_arg_list_B.append("%s_i" % v) + code_list_common.append("char *%s_i = MPIR_fort_dup_str(%s, %s_len);" % (v, v, v)) + end_list_common.append("free(%s_i);" % (v)) + + def dump_string_out(v, flag=None): + c_param_list.append("char *%s FORT_MIXED_LEN(%s_len)" % (v, v)) + c_param_list_end.append("FORT_END_LEN(%s_len)" % v) + c_arg_list_A.append("%s_i" % v) + c_arg_list_B.append("%s_i" % v) + code_list_common.append("char *%s_i = malloc(%s_len + 1);" % (v, v)) + + flag_cond = "*ierr == MPI_SUCCESS" + if flag: + flag_cond += " && " + flag + end_list_common.append("if (%s) {" % flag_cond) + end_list_common.append("INDENT") + end_list_common.append("MPIR_fort_copy_str_from_c(%s, %s_len, %s_i);" % (v, v, v)) + end_list_common.append("DEDENT") + end_list_common.append("}") + end_list_common.append("free(%s_i);" % v) + + def dump_string_array(v, count="0"): + c_param_list.append("char *%s FORT_MIXED_LEN(%s_len)" % (v, v)) + c_param_list_end.append("FORT_END_LEN(%s_len)" % v) + c_arg_list_A.append("%s_i" % v) + c_arg_list_B.append("%s_i" % v) + code_list_common.append("char **%s_i;" % v) + code_list_common.append("if (%s == MPI_F_ARGV_NULL) {" % v) + code_list_common.append(" %s_i = MPI_ARGV_NULL;" % v) + code_list_common.append("} else {") + code_list_common.append(" %s_i = MPIR_fort_dup_str_array(%s, %s_len, %s_len, %s);" % (v, v, v, v, count)) + code_list_common.append("}") + end_list_common.append("if (%s != MPI_F_ARGV_NULL) {" % v) + end_list_common.append(" MPIR_fort_free_str_array(%s_i);" % v) + end_list_common.append("}") + + def dump_string_2darray(v, count): + c_param_list.append("char *%s FORT_MIXED_LEN(%s_len)" % (v, v)) + c_param_list_end.append("FORT_END_LEN(%s_len)" % v) + c_arg_list_A.append("%s_i" % v) + c_arg_list_B.append("%s_i" % v) + code_list_common.append("char ***%s_i;" % v) + code_list_common.append("if (%s == MPI_F_ARGVS_NULL) {" % v) + code_list_common.append(" %s_i = MPI_ARGVS_NULL;" % v) + code_list_common.append("} else {") + code_list_common.append(" %s_i = MPIR_fort_dup_str_2d_array(%s, %s_len, %s);" % (v, v, v, count)) + code_list_common.append("}") + end_list_common.append("if (%s != MPI_F_ARGVS_NULL) {" % v) + end_list_common.append(" MPIR_fort_free_str_2d_array(%s_i, %s);" % (v, count)) + end_list_common.append("}") + + def dump_file_in(v): + c_param_list.append("MPI_Fint *%s" % v) + c_arg_list_A.append("MPI_File_f2c(*%s)" % v) + c_arg_list_B.append("MPI_File_f2c(*%s)" % v) + + def dump_file_out(v, is_inout): + c_param_list.append("MPI_Fint *%s" % v) + c_arg_list_A.append("&%s_i" % v) + c_arg_list_B.append("&%s_i" % v) + if is_inout: + code_list_common.append("MPI_File %s_i = MPI_File_f2c(*%s);" % (v, v)) + else: + code_list_common.append("MPI_File %s_i;" % v) + end_list_common.append("*%s = MPI_File_c2f(%s_i);" % (v, v)) + + def dump_logical_in(v): + c_param_list.append("MPI_Fint *%s" % v) + c_arg_list_A.append("*%s" % v) + c_arg_list_B.append("*%s" % v) + + def dump_logical_out(v): + c_param_list.append("MPI_Fint *%s" % v) + c_arg_list_A.append("&%s_i" % v) + c_arg_list_B.append("&%s_i" % v) + code_list_common.append("int %s_i;" % v) + end_list_common.append("if (*ierr == MPI_SUCCESS) {") + end_list_common.append(" *%s = MPII_TO_FLOG(%s_i);" % (v, v)) + end_list_common.append("}") + + def dump_index_in(v): + c_param_list.append("MPI_Fint *%s" % v) + c_arg_list_A.append("(int) (*%s - 1)" % v) + c_arg_list_B.append("(int) (*%s - 1)" % v) + + def dump_index_out(v): + c_param_list.append("MPI_Fint *%s" % v) + c_arg_list_A.append("&%s_i" % v) + c_arg_list_B.append("&%s_i" % v) + code_list_common.append("int %s_i;" % v) + end_list_common.append("if (*ierr == MPI_SUCCESS) {") + end_list_common.append(" *%s = %s_i + 1;" % (v, v)) + end_list_common.append("}") + + def dump_string_len_inout(v): + # only used in MPI_Info_get_string + c_param_list.append("MPI_Fint *%s" % v) + c_arg_list_A.append("&%s_i" % v) + c_arg_list_B.append("&%s_i" % v) + code_list_common.append("int %s_i = (*%s > 0) ? (int) (*%s + 1) : 0;" % (v, v, v)) + end_list_common.append("*%s = (%s_i > 0) ? (MPI_Fint) (%s_i - 1) : 0;" % (v, v, v)) + + def dump_index_array_out(v, incount, outcount): + dump_array(v, 'int', incount, outcount, False, True) + end_list_common.append("for (int i = 0; i < %s; i++) {" % outcount) + end_list_common.append(" %s[i] += 1;" % v) + end_list_common.append("}") + + def dump_function(v, func_type): + c_param_list.append("%s %s" % (func_type, v)) + c_arg_list_A.append(v) + c_arg_list_B.append(v) + if func_type == "MPI_Datarep_conversion_function": + # FIXME: check name mangling + code_list_common.append("if (%s == (MPI_Datarep_conversion_function *) mpi_conversion_fn_null_) {" % v) + code_list_common.append(" %s = NULL;" % v) + code_list_common.append("}") + + def dump_direct_pointer(v, c_type): + c_param_list.append("%s *%s" % (c_type, v)) + c_arg_list_A.append(v) + c_arg_list_B.append(v) + + def dump_attr_in(v, c_type): + c_param_list.append("%s *%s" % (c_type, v)) + c_arg_list_A.append("(void *) (intptr_t) (*%s)" % v) + c_arg_list_B.append("(void *) (intptr_t) (*%s)" % v) + + def dump_attr_out(v, c_type, flag): + c_param_list.append("%s *%s" % (c_type, v)) + c_arg_list_A.append("&%s_i" % v) + c_arg_list_B.append("&%s_i" % v) + code_list_common.append("void *%s_i;" % v) + end_list_common.append("if (*ierr || !%s) {" % flag) + end_list_common.append(" *%s = 0;" % v) + end_list_common.append("} else {") + end_list_common.append(" *%s = (MPI_Aint) %s_i;" % (v, v)) + end_list_common.append("}") + + def dump_handle_create(v, c_type): + c_param_list.append("MPI_Fint *%s" % v) + # note: when fint is int, both the handle and the handler interface are compatible with C + c_arg_list_A.append("(%s *) %s" % (c_type, v)) + c_arg_list_B.append("&%s_i" % v) + code_list_B.append("int %s_i;" % v) + end_list_B.append("if (!*ierr) {") + if c_type == "MPI_Errhandler": + end_list_B.append(" MPII_Errhandler_set_fc(%s_i);" % v) + elif c_type == "MPI_Op": + end_list_B.append(" MPII_Op_set_fc(%s_i);" % v) + end_list_B.append(" *%s = (MPI_Fint) %s_i;" % (v, v)) + end_list_B.append("}") + + def dump_sum(codelist, sum_v, sum_n, array): + codelist.append("int %s = 0;" % sum_v) + codelist.append("for (int i = 0; i < *%s; i++) {" % sum_n) + codelist.append(" %s += (int) %s[i];" % (sum_v, array)) + codelist.append("}") + + def dump_mpi_decl_begin(name, param_str, return_type): + G.out.append("FORT_DLL_SPEC %s FORT_CALL %s(%s) {" % (return_type, name, param_str)) + G.out.append("INDENT") + if re.match(r'MPI_File_|MPI_Register_datarep', func['name'], re.IGNORECASE): + G.out.append("#ifndef MPI_MODE_RDONLY") + G.out.append("*ierr = MPI_ERR_INTERN;") + G.out.append("#else") + + def dump_mpi_decl_end(): + if re.match(r'MPI_File_|MPI_Register_datarep', func['name'], re.IGNORECASE): + G.out.append("#endif") + G.out.append("DEDENT") + G.out.append("}") + + def dump_custom_functions(func): + # assume the last parameter is ierror -- forum don't name it consistently + err = func['parameters'][-1]['name'] + if re.match(r'MPI_CONVERSION_FN_NULL', func['name'], re.IGNORECASE): + G.out.append("/* dummy function, not callable */") + elif re.match(r'MPI.*_DUP_FN', func['name'], re.IGNORECASE): + G.out.append("* (MPI_Aint *) attribute_val_out = * (MPI_Aint *) attribute_val_in;") + G.out.append("*flag = MPII_TO_FLOG(1);") + G.out.append("*%s = MPI_SUCCESS;" % err) + elif re.match(r'MPI.*_NULL_COPY_FN', func['name'], re.IGNORECASE): + G.out.append("*flag = MPII_TO_FLOG(0);") + G.out.append("*%s = MPI_SUCCESS;" % err) + elif re.match(r'MPI.*_NULL_DELETE_FN', func['name'], re.IGNORECASE): + G.out.append("*%s = MPI_SUCCESS;" % err) + else: + raise Exception("Unhandled dummy function - %s" % func['name']) + + # ---------------------------------- + def process_func_parameters(): + n = len(func['parameters']) + i = 0 + while i < n: + p = func['parameters'][i] + if p['large_only']: + i += 1 + continue + + (group_kind, group_count) = ("", 0) + if i + 3 <= n and RE.search(r'BUFFER', p['kind']): + group_kind, group_count = get_userbuffer_group(func['name'], func['parameters'], i) + + if group_count > 0: + p2 = func['parameters'][i + 1] + p3 = func['parameters'][i + 2] + if group_count == 3: + dump_buf(p['name'], re.search('-inplace', group_kind)) + dump_p(p2) + dump_p(p3) + elif group_count == 4: + # e.g. Alltoallv + p4 = func['parameters'][i + 3] + dump_buf(p['name'], re.search('-inplace', group_kind)) + dump_p(p2) + dump_p(p3) + dump_p(p4) + elif group_count == 5: + # reduce + p4 = func['parameters'][i + 3] + p5 = func['parameters'][i + 4] + dump_buf(p['name'], True) + dump_buf(p2['name'], False) + dump_p(p3) + dump_p(p4) + dump_p(p5) + + i += group_count + continue + else: + i += 1 + + if f90_param_need_skip(p): + pass; + + elif p['kind'] == "BUFFER": + dump_buf(p['name'], False) + + elif p['kind'] == "STRING": + if p['param_direction'] == 'out': + if re.match(r'MPI_Info_get$', func['name'], re.IGNORECASE): + dump_string_out(p['name'], '*flag') + elif re.match(r'MPI_Info_get_string$', func['name'], re.IGNORECASE): + code_list_common.append("int buflen_nonzero = (*buflen > 0);") + dump_string_out(p['name'], '(*flag && buflen_nonzero)') + else: + dump_string_out(p['name']) + else: + dump_string_in(p['name']) + + elif p['kind'] == "STRING_ARRAY": + if p['name'] == 'array_of_commands': + dump_string_array(p['name'], "*count") + else: + dump_string_array(p['name']) + + elif p['kind'] == "STRING_2DARRAY": + if re.match(r'MPI_Comm_spawn_multiple$', func['name'], re.IGNORECASE): + dump_string_2darray(p['name'], "*count") + else: + raise Exception("Not expected: %s - %s" % (func['name'], p['name'])) + + elif p['kind'] == "STATUS": + if p['param_direction'] == 'out': + if p['length'] is None: + dump_status(p['name'], False, True) + elif RE.match(r'mpi_(wait|test)all', func['name'], re.IGNORECASE): + dump_statuses(p['name'], "(*count)", "(*count)", False, True) + elif RE.match(r'mpi_(wait|test)some', func['name'], re.IGNORECASE): + dump_statuses(p['name'], "(*incount)", "(*outcount)", False, True) + else: + raise Exception("Unhandled: %s - %s" % (func['name'], p['name'])) + else: + if p['length'] is None: + dump_status(p['name'], True, False) + else: + raise Exception("Unhandled: %s - %s" % (func['name'], p['name'])) + + elif RE.match(r'(source|dest)?weights$', p['name']): + if RE.match(r'MPI_Dist_graph_create$', func['name'], re.IGNORECASE): + # NOTE: total_degrees is pre-calculated + dump_array_special_in(p['name'], "int", "total_degrees") + elif RE.match(r'MPI_Dist_graph_create_adjacent$', func['name'], re.IGNORECASE): + if p['name'] == 'sourceweights': + dump_array_special_in(p['name'], "int", "(*indegree)") + else: + dump_array_special_in(p['name'], "int", "(*outdegree)") + elif RE.match(r'mpi_dist_graph_neighbors$', func['name'], re.IGNORECASE): + if p['name'] == 'sourceweights': + dump_array_out(p['name'], "int", "(*maxindegree)") + else: + dump_array_out(p['name'], "int", "(*maxoutdegree)") + else: + raise Exception("Not handled: %s - %s" % (func['name'], p['name'])) + + elif RE.match(r'array_of_errcodes', p['name']): + if re.match(r'MPI_Comm_spawn$', func['name'], re.IGNORECASE): + dump_array_special_out(p['name'], "int", "(*maxprocs)") + elif re.match(r'MPI_Comm_spawn_multiple$', func['name'], re.IGNORECASE): + # NOTE: total_procs is pre-calculated + dump_array_special_out(p['name'], "int", "total_procs") + else: + raise Exception("Not handled: %s - %s" % (func['name'], p['name'])) + + elif p['kind'] == "FILE": + if p['param_direction'] == 'out': + dump_file_out(p['name'], False) + elif p['param_direction'] == 'inout': + dump_file_out(p['name'], True) + else: + dump_file_in(p['name']) + elif p['kind'] == "LOGICAL": + + if re.match(r'MPI_Cart_sub$', func['name'], re.IGNORECASE): + # remain_dims + dump_array_in(p['name'], 'int', "maxdims") + elif p['length']: + # assume input (MPI_Cart_create - periods) + if p['length'] == '*': + raise Exception("Unhandled: %s - %s" % (func['name'], p['name'])) + count = "(*%s)" % p['length'] + dump_array(p['name'], 'int', count, count, param_is_in(p), param_is_out(p)) + elif p['param_direction'] == 'out': + dump_logical_out(p['name']) + else: + dump_logical_in(p['name']) + elif p['kind'] == "INDEX": + # tricky, not all need to be 1-based + if p['length']: + if re.match(r'MPI_(Test|Wait)some', func['name'], re.IGNORECASE): + dump_index_array_out(p['name'], '(*incount)', '(*outcount)') + elif re.match(r'MPI_Graph_get', func['name'], re.IGNORECASE): + dump_array_out(p['name'], 'int', '(*maxindex)') + elif re.match(r'MPI_Graph_(create|map)', func['name'], re.IGNORECASE): + dump_array_in(p['name'], 'int', "(*%s)" % p['length']) + else: + raise Exception("Unhandled: %s - %s" % (func['name'], p['name'])) + elif p['param_direction'] == 'out': + dump_index_out(p['name']) + elif p['name'] == "direction": # MPI_Cart_shift + dump_p(p) + else: + dump_index_in(p['name']) + elif re.match(r'FUNCTION|FUNCTION_SMALL|POLYFUNCTION', p['kind']): + dump_function(p['name'], p['func_type']) + elif re.match(r'EXTRA_STATE|C_BUFFER2|C_BUFFER', p['kind']): + if p['param_direction'] == 'out': + dump_scalar_out(p['name'], "MPI_Aint", "void *") + elif p['param_direction'] != "inout": + dump_direct_pointer(p['name'], "void") + else: + raise Exception("Unhandled: %s - %s" % (func['name'], p['name'])) + elif re.match(r'ATTRIBUTE_VAL', p['kind']): + if re.match(r'MPI_((Comm|Type|Win)_get_attr)', func['name'], re.IGNORECASE): + dump_attr_out(p['name'], "MPI_Aint", "flag_i") + elif re.match(r'MPI_((Comm|Type|Win)_set_attr)', func['name'], re.IGNORECASE): + dump_attr_in(p['name'], "MPI_Aint") + elif re.match(r'MPI_Attr_get', func['name'], re.IGNORECASE): + dump_attr_out(p['name'], "MPI_Fint", "flag_i") + elif re.match(r'MPI_Attr_put', func['name'], re.IGNORECASE): + dump_attr_in(p['name'], "MPI_Fint") + elif is_custom_fn: + # Must be e.g. MPI_DUP_FN. We'll special treat them + c_param_list.append("void *%s" % p['name']) + pass + else: + raise Exception("Unhandled: func %s - %s" % (func['name'], p['name'])) + elif re.match(r'MPI_(Aint|Count|Offset)', c_mapping[p['kind']]): + c_type = c_mapping[p['kind']] + if re.match(r'MPI_Type_(extent|lb|ub)', func['name'], re.IGNORECASE): + # old function, output as INTEGER + dump_scalar_out(p['name'], "MPI_Fint", "MPI_Aint") + elif re.match(r'MPI_Type_hvector', func['name'], re.IGNORECASE): + # old function, input as INTEGER + dump_p(p) + elif re.match(r'MPI_Type_(hindexed|struct)', func['name'], re.IGNORECASE): + # old function, input as INTEGER array + dump_array_int_to_aint(p['name'], '(*count)') + elif p['length']: + dump_direct_pointer(p['name'], c_type) + elif p['param_direction'] == 'out' or p['param_direction'] == 'inout': + if re.match(r'MPI_Address', func['name'], re.IGNORECASE): + dump_aint_out_check(p['name']) + else: + dump_direct_pointer(p['name'], c_type) + else: + dump_c_type_in(p['name'], c_type) + + elif p['kind'] == "ERRHANDLER" and re.match(r'.*_create_errhandler', func['name'], re.IGNORECASE): + dump_handle_create(p['name'], "MPI_Errhandler") + elif p['kind'] == "OPERATION" and re.match(r'.*_op_create$', func['name'], re.IGNORECASE): + dump_handle_create(p['name'], "MPI_Op") + elif p['kind'] in G.handle_mpir_types or c_mapping[p['kind']] == "int": + c_type = c_mapping[p['kind']] + if p['length'] is None: + if p['param_direction'] == 'out': + dump_int_out(p['name'], c_type, False) + if p['kind'] == "KEYVAL": + end_list_common.append("if (!*ierr) {") + end_list_common.append(" MPII_Keyval_set_f90_proxy((int) *%s);" % p['name']) + end_list_common.append("}") + elif re.match(r'MPI_Grequest_start', func['name'], re.IGNORECASE): + end_list_common.append("if (!*ierr) {") + end_list_common.append(" MPII_Grequest_set_lang_f77((int) *%s);" % p['name']) + end_list_common.append("}") + elif p['param_direction'] == 'inout' or p['pointer']: + if re.match(r'MPI_Info_get_string$', func['name'], re.IGNORECASE): + dump_string_len_inout(p['name']) + else: + dump_int_out(p['name'], c_type, True) + else: + dump_p(p) + elif isinstance(p['length'], list): + if re.match(r'MPI_Group_range_(incl|excl)', func['name'], re.IGNORECASE): + c_param_list.append("MPI_Fint *%s" % p['name']) + c_arg_list_A.append("(int (*)[3]) %s" % p['name']) + c_arg_list_B.append("(int (*)[3]) %s" % p['name']) + else: + raise Exception("unhandled length: %s - %s" % (func['name'], p['name'])) + else: + # FIXME: find length + count = p['length'] + if count == '*': + if re.match(r'MPI_Dist_graph_create$', func['name'], re.IGNORECASE): + count = "total_degrees" + elif re.match(r'MPI_Cart_rank$', func['name'], re.IGNORECASE): + count = "maxdims" + elif re.match(r'MPI_Graph_(create|map)$', func['name'], re.IGNORECASE): + count = "indx[*nnodes - 1]" + elif re.match(r'MPI_(Wait|Test)some$', func['name'], re.IGNORECASE): + count = "(*incount)" + else: + raise Exception("Unhandled array[*]: %s - %s" % (func['name'], p['name'])) + else: + count = "(*%s)" % count + + if p['param_direction'] == 'out': + dump_array_out(p['name'], c_type, count) + elif p['param_direction'] == 'inout': + dump_array(p['name'], c_type, count, count, True, True) + else: + dump_array_in(p['name'], c_type, count) + + else: + raise Exception("Unhandled: func %s - %s, kind = %s" % (func['name'], p['name'], p['kind'])) + + # ----------------------------------------------------------- + # pre-process, such as pre-calculate total dimensions + if re.match(r'MPI_Dist_graph_create$', func['name'], re.IGNORECASE): + dump_sum(code_list_B, "total_degrees", "n", "degrees") + elif re.match(r'MPI_Comm_spawn_multiple$', func['name'], re.IGNORECASE): + dump_sum(code_list_B, "total_procs", "count", "array_of_maxprocs") + elif re.match(r'MPI_Cart_(rank|sub)$', func['name'], re.IGNORECASE): + code_list_B.append("int maxdims;") + code_list_B.append("MPI_Cartdim_get((MPI_Comm) (*comm), &maxdims);") + elif re.match(r'mpi_i?neighbor_(.*[vw])(_init)?$', func['name'], re.IGNORECASE): + code_list_B.append("int indegree, outdegree, weighted;") + code_list_B.append("MPI_Dist_graph_neighbors_count((MPI_Comm) (*comm), &indegree, &outdegree, &weighted);") + elif re.match(r'mpi_.*(reduce_scatter)', func['name'], re.IGNORECASE): + code_list_B.append("int comm_size;") + code_list_B.append("MPI_Comm_size((MPI_Comm) (*comm), &comm_size);") + elif re.match(r'mpi_.*(gatherv|scatterv|alltoall[vw])', func['name'], re.IGNORECASE): + code_list_B.append("int is_inter;") + code_list_B.append("int comm_size;") + code_list_B.append("MPI_Comm_test_inter((MPI_Comm) (*comm), &is_inter);") + code_list_B.append("if (is_inter) {") + code_list_B.append(" MPI_Comm_remote_size((MPI_Comm) (*comm), &comm_size);") + code_list_B.append("} else {") + code_list_B.append(" MPI_Comm_size((MPI_Comm) (*comm), &comm_size);") + code_list_B.append("}") + + process_func_parameters() + + c_func_name = func['name'] + if need_ATTR_AINT: + if RE.match(r'MPI_Attr_(get|put)', func['name'], re.IGNORECASE): + if RE.m.group(1) == 'put': + c_func_name = "MPII_Comm_set_attr" + else: + c_func_name = "MPII_Comm_get_attr" + c_arg_list_A.append("MPIR_ATTR_INT") + c_arg_list_B.append("MPIR_ATTR_INT") + else: + c_func_name = re.sub(r'MPI_', 'MPII_', func['name']) + c_arg_list_A.append("MPIR_ATTR_AINT") + c_arg_list_B.append("MPIR_ATTR_AINT") + elif re.match(r'MPI_(Init|Init_thread|Info_create_env)$', func['name'], re.IGNORECASE): + # argc, argv + c_arg_list_A.insert(0, "0, 0") + c_arg_list_B.insert(0, "0, 0") + + if 'return' not in func: + if not need_skip_ierr: + if c_param_list: + param_str = ', '.join(c_param_list) + ", MPI_Fint *ierr" + else: + param_str = "MPI_Fint *ierr" + else: + param_str = ', '.join(c_param_list) + return_type = "void" + else: + if not c_param_list: + param_str = "void" + else: + param_str = ', '.join(c_param_list) + return_type = c_mapping[func['return']] + + if c_param_list_end: + param_str += ' ' + ' '.join(c_param_list_end) + + use_name = dump_profiling(name, param_str, return_type) + G.out.append("") + dump_mpi_decl_begin(use_name, param_str, return_type) + + if is_custom_fn: + dump_custom_functions(func) + elif re.match(r'MPI_Pcontrol', func['name'], re.IGNORECASE): + G.out.append("%s(%s);" % (c_func_name, ', '.join(c_arg_list_A))) + elif return_type != "void": + # these are all special functions, e.g. MPI_Wtime, MPI_Wtick, MPI_Aint_add, MPI_Aint_diff + G.out.append("return %s(%s);" % (c_func_name, ', '.join(c_arg_list_A))) + else: + # FIXME: need check name mangling before call mpirinitf_() + G.out.append("if (MPIR_F_NeedInit) {mpirinitf_(); MPIR_F_NeedInit = 0;}") + G.out.append("") + + for l in code_list_common: + G.out.append(l) + + if code_list_B: + G.out.append("#ifdef HAVE_FINT_IS_INT") + + for l in code_list_A: + G.out.append(l) + G.out.append("*ierr = %s(%s);" % (c_func_name, ', '.join(c_arg_list_A))) + for l in end_list_A: + G.out.append(l) + + if code_list_B: + G.out.append("") + G.out.append("#else /* ! HAVE_FINT_IS_INT */") + + for l in code_list_B: + G.out.append(l) + G.out.append("*ierr = %s(%s);" % (c_func_name, ', '.join(c_arg_list_B))) + for l in end_list_B: + G.out.append(l) + + G.out.append("#endif") + + for l in end_list_common: + G.out.append(l) + + dump_mpi_decl_end() + +def dump_f77_c_file(f, lines): + print(" --> [%s]" % f) + with open(f, "w") as Out: + for l in G.copyright_c: + print(l, file=Out) + if f.endswith('.c'): + print("#include \"mpi_fortimpl.h\"", file=Out) + print("#include \"fortran_profile.h\"", file=Out) + print("", file=Out) + indent = 0 + for l in lines: + if RE.match(r'#(if|elif|else|endif|define)', l): + print(l, file=Out) + elif RE.match(r'INDENT', l): + indent += 1 + elif RE.match(r'DEDENT', l): + indent -= 1 + else: + if indent > 0: + print(" " * indent, end='', file=Out) + print(l, file=Out) + +#---------------------------------------- +def dump_profiling(name, param_str, return_type): + pname = "P" + name + defines = ["F77_NAME_UPPER", "F77_NAME_LOWER", "F77_NAME_LOWER_USCORE", "F77_NAME_LOWER_2USCORE"] + names = [name.upper(), name.lower(), name.lower() + "_", name.lower() + "__"] + pnames = [pname.upper(), pname.lower(), pname.lower() + "_", pname.lower() + "__"] + # use e.g. mpi_send_ to define the function + use_idx = 2 + + def dump_multiple_pragma_weak(use_only_mpi_names): + for nm in names: + dump_mpi_decl(nm, param_str) + G.profile_out.append("") + for i in range(len(names)): + G.profile_out.append("#%s defined(%s)" % (get_if_or_elif(i), defines[i])) + for j in range(len(names)): + if use_only_mpi_names: + if i == j: + continue + G.profile_out.append("#pragma weak %s = %s" % (names[j], names[i])) + else: + G.profile_out.append("#pragma weak %s = %s" % (names[j], pnames[i])) + G.profile_out.append("#else") + G.profile_out.append("#error missing F77 name mangling") + G.profile_out.append("#endif") + + def dump_elif_pragma_weak(have_pragma): + G.profile_out.append("#elif defined(%s)" % have_pragma) + + for i in range(len(names)): + G.profile_out.append("#%s defined(%s)" % (get_if_or_elif(i), defines[i])) + dump_mpi_decl(names[i], param_str) + if have_pragma == "HAVE_PRAGMA_WEAK": + G.profile_out.append("#pragma weak %s = %s" % (names[i], pnames[i])) + elif have_pragma == "HAVE_PRAGMA_HP_SEC_DEF": + G.profile_out.append("#pragma _HP_SECONDARY_DEF %s %s" % (pnames[i], names[i])) + elif have_pragma == "HAVE_PRAGMA_CRI_DUP": + G.profile_out.append("#pragma _CRI duplicate %s as %s" % (names[i], pnames[i])) + G.profile_out.append("#endif") + + def dump_weak_attibute(use_only_mpi_names): + for i in range(len(names)): + G.profile_out.append("#%s defined(%s)" % (get_if_or_elif(i), defines[i])) + for j in range(len(names)): + if use_only_mpi_names: + if i == j: + dump_mpi_decl(names[i], param_str) + else: + dump_mpi_decl_weak_attr(names[j], param_str, names[i]) + else: + dump_mpi_decl_weak_attr(pnames[j], param_str, pnames[i]) + G.profile_out.append("#else") + G.profile_out.append("#error missing F77 name mangling") + G.profile_out.append("#endif") + + def dump_pmpi_decl_multiple_pragma_weak(): + for i in range(len(names)): + G.profile_out.append("#ifndef %s" % defines[i]) + dump_mpi_decl(pnames[i], param_str) + G.profile_out.append("#endif") + + for i in range(len(names)): + G.profile_out.append("#%s defined(%s)" % (get_if_or_elif(i), defines[i])) + for j in range(len(names)): + if i != j: + G.profile_out.append("#pragma weak %s = %s" % (pnames[j], pnames[i])) + G.profile_out.append("#else") + G.profile_out.append("#error missing F77 name mangling") + G.profile_out.append("#endif") + + def dump_pmpi_decl_weak_attribute(): + for i in range(len(names)): + G.profile_out.append("#%s defined(%s)" % (get_if_or_elif(i), defines[i])) + for j in range(len(names)): + if i != j: + dump_mpi_decl_weak_attr(pnames[i], param_str, pnames[j]) + G.profile_out.append("#else") + G.profile_out.append("#error missing F77 name mangling") + G.profile_out.append("#endif") + + def dump_define_mpi_as_pmpi(): + for i in range(len(names)): + G.profile_out.append("#%s defined(%s)" % (get_if_or_elif(i), defines[i])) + G.profile_out.append("#define %s %s" % (names[use_idx], pnames[i])) + G.profile_out.append("#endif") + + # This defines the routine that we call, which must be the PMPI version + # since we're renaming the Fortran entry as the pmpi version. The MPI name + # must be undefined first to prevent any conflicts with previous renamings. + G.profile_out.append("#ifdef F77_USE_PMPI") + G.profile_out.append("#undef %s" % name) + G.profile_out.append("#define %s P%s" % (name, name)) + G.profile_out.append("#endif") + + def dump_define_mpi_as_mangle(): + for i in range(len(names)): + if i != use_idx: + G.profile_out.append("#%s defined(%s)" % (get_if_or_elif(i), defines[i])) + G.profile_out.append("#define %s %s" % (names[use_idx], names[i])) + G.profile_out.append("#endif") + + # ---- general util ---- + def get_if_or_elif(i): + if i == 0: + return "if" + else: + return "elif" + + def dump_mpi_decl(name, param_str): + G.profile_out.append("extern FORT_DLL_SPEC %s FORT_CALL %s(%s);" % (return_type, name, param_str)) + + def dump_mpi_decl_weak_attr(name, param_str, weak_name): + G.profile_out.append("extern FORT_DLL_SPEC %s FORT_CALL %s(%s) __attribute__((weak,alias(\"%s\")));" % (return_type, name, param_str, weak_name)) + + # --------- + G.profile_out.append("") + G.profile_out.append("/* ---- %s ---- */" % name) + G.profile_out.append("#if defined(USE_WEAK_SYMBOLS) && !defined(USE_ONLY_MPI_NAMES)") + G.profile_out.append("#if defined(HAVE_MULTIPLE_PRAGMA_WEAK)") + dump_multiple_pragma_weak(False) + G.profile_out.append("") + dump_elif_pragma_weak("HAVE_PRAGMA_WEAK") + G.profile_out.append("") + G.profile_out.append("#elif defined(HAVE_WEAK_ATTRIBUTE)") + dump_weak_attibute(False) + G.profile_out.append("") + G.profile_out.append("#endif /* HAVE_MULTIPLE_PRAGMA_WEAK, HAVE_PRAGMA_WEAK, HAVE_WEAK_ATTRIBUTE */") + G.profile_out.append("#endif /* USE_WEAK_SYMBOLS && !USE_ONLY_MPI_NAMES */") + G.profile_out.append("") + + G.profile_out.append("#if defined(USE_WEAK_SYMBOLS) && defined(USE_ONLY_MPI_NAMES)") + G.profile_out.append("#if defined(HAVE_MULTIPLE_PRAGMA_WEAK)") + dump_multiple_pragma_weak(True) + G.profile_out.append("") + dump_elif_pragma_weak("HAVE_PRAGMA_WEAK") + G.profile_out.append("") + G.profile_out.append("#elif defined(HAVE_WEAK_ATTRIBUTE)") + dump_weak_attibute(True) + G.profile_out.append("") + G.profile_out.append("#endif /* HAVE_MULTIPLE_PRAGMA_WEAK, HAVE_PRAGMA_WEAK, HAVE_WEAK_ATTRIBUTE */") + G.profile_out.append("#endif /* USE_WEAK_SYMBOLS && USE_ONLY_MPI_NAMES */") + G.profile_out.append("") + + G.profile_out.append("#ifndef MPICH_MPI_FROM_PMPI") + + G.profile_out.append("#if defined(USE_WEAK_SYMBOLS)") + G.profile_out.append("#if defined(HAVE_MULTIPLE_PRAGMA_WEAK)") + G.profile_out.append("") + dump_pmpi_decl_multiple_pragma_weak() + G.profile_out.append("") + G.profile_out.append("#elif defined(HAVE_WEAK_ATTRIBUTE)") + dump_pmpi_decl_weak_attribute() + G.profile_out.append("") + G.profile_out.append("#endif") + G.profile_out.append("#endif /* USE_WEAK_SYMBOLS */") + dump_define_mpi_as_pmpi() + G.profile_out.append("") + + G.profile_out.append("#else /* MPICH_MPI_FROM_PMPI */") + dump_define_mpi_as_mangle() + G.profile_out.append("") + + G.profile_out.append("#endif /* MPICH_MPI_FROM_PMPI */") + + # prototype + G.profile_out.append("") + G.profile_out.append("FORT_DLL_SPEC %s FORT_CALL %s(%s);" % (return_type, names[use_idx], param_str)) + + # return the name to be used to define the function + return names[use_idx] + +# ------------------------------- +def dump_fortran_line(s): + tlist = split_line_with_break(s, '', 100) + n = len(tlist) + if n > 1: + for i in range(n-1): + tlist[i] = tlist[i] + ' &' + G.out.extend(tlist) + +# ------------------------------- +def check_func_directives(func): + if 'dir' in func and func['dir'] == "mpit": + func['_skip_fortran'] = 1 + elif 'mpix' in func: + func['_skip_fortran'] = 1 + elif RE.match(r'mpix_grequest_', func['name'], re.IGNORECASE): + func['_skip_fortran'] = 1 + elif RE.match(r'mpi_\w+_(f|f08|c)2(f|f08|c)$', func['name'], re.IGNORECASE): + # implemented in mpi_f08_types.f90 + func['_skip_fortran'] = 1 + elif RE.match(r'mpi_.*_function$', func['name'], re.IGNORECASE): + # defined in mpi_f08_callbacks.f90 + func['_skip_fortran'] = 1 + +def f90_param_need_skip(p): + if RE.search(r'suppress=.*f90_parameter', p['t']): + return True + if p['kind'] == 'VARARGS': + return True + return False diff --git a/maint/local_python/mpi_api.py b/maint/local_python/mpi_api.py index 3893ee64616..b1b05f03d71 100644 --- a/maint/local_python/mpi_api.py +++ b/maint/local_python/mpi_api.py @@ -317,3 +317,21 @@ def get_type_create_f90_func_list(): "MPI_Type_create_f90_complex", ] return [G.FUNCS[a.lower()] for a in type_func_name_list] + +def get_f77_dummy_func_list(): + dummy_func_name_list = [ + "MPI_DUP_FN", + "MPI_NULL_COPY_FN", + "MPI_NULL_DELETE_FN", + "MPI_COMM_DUP_FN", + "MPI_COMM_NULL_COPY_FN", + "MPI_COMM_NULL_DELETE_FN", + "MPI_TYPE_DUP_FN", + "MPI_TYPE_NULL_COPY_FN", + "MPI_TYPE_NULL_DELETE_FN", + "MPI_WIN_DUP_FN", + "MPI_WIN_NULL_COPY_FN", + "MPI_WIN_NULL_DELETE_FN", + "MPI_CONVERSION_FN_NULL", + ] + return [G.FUNCS[a.lower()] for a in dummy_func_name_list] From 8f0c54bef32b5a95e87732dc54a9ca76ddd6bbd5 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 11 Oct 2021 22:18:13 -0500 Subject: [PATCH 084/607] fortran: remove interface generation buildiface We'll generate the wrapper functions using the new Python scripts. --- src/binding/fortran/mpif_h/buildiface | 4606 +------------------------ 1 file changed, 60 insertions(+), 4546 deletions(-) diff --git a/src/binding/fortran/mpif_h/buildiface b/src/binding/fortran/mpif_h/buildiface index 44a4161b19f..ae957800542 100755 --- a/src/binding/fortran/mpif_h/buildiface +++ b/src/binding/fortran/mpif_h/buildiface @@ -4,3512 +4,81 @@ ## See COPYRIGHT in top-level directory ## -# This file builds candidate interface files from the descriptions in -# mpi.h -# -# Here are the steps: -# 1) Find the prototypes in mpi.h.in (Look for *Begin Prototypes*) -# 2) For each function, match the name and args: -# int MPI_xxxx( ... ) -# 3) Create a new file with the name lc(xxxx)f.c (lowercase of name), -# containing -# Copyright -# Profiling block indicator -# Fortran name version of function, with MPI objects replaced by -# MPI_Fint etc. as appropriate -# -# - -use warnings; - -# Setup global variables -%CtoFName = (); -@ExtraRoutines = (); - -$buildfiles = 1; -$build_prototypes = 1; -$buildMakefile = 1; -$prototype_header_file = "fproto.h"; -$build_io = 1; -$print_line_len = 0; -$write_mpif = 1; -$is_MPI = 1; -$do_profiling = 1; -$routine_pattern = "[A-Z][a-z0-9_]*"; - -# these two arrays must be kept in sync -my @routine_prefixes = qw(MPI_ MPIX_); -my @out_prefixes = qw(mpi_ mpix_); - -$header_file = "mpi_fortimpl.h"; -$debug = 0; -$writeRoutineList = 0; # Set to 1 to get a list of MPI routines -$do_fint = 1; # Set to 1 to support C and Fortran integers of a - # different size -$within_fint = 0; # This is set to 1 while generating code for the - # do_fint branch -%fintToHandle = ( 'int' => 1, 'MPI_Request' => 1, 'MPI_Group' => 1, - 'MPI_Win' => 1, 'MPI_Info' => 1, 'MPI_Errhandler' => 1, - 'MPI_File' => 1, 'MPI_Op' => 1, 'MPI_Message' => 1 ); - -@arg_addresses = (); -# -# Error return handling -$errparmtype = "MPI_Fint *"; -$errparm = "MPI_Fint *ierr"; -$errparmlval = "*ierr"; -$errparmrval = "*ierr"; -$returnErrval = 0; -$returnType = "void"; - -%altweak = (); # Alternate weak declarations -%altweakrtype = (); - -#feature variables -$do_logical = 1; -$do_weak = 1; -$do_subdecls = 1; -$do_bufptr = 1; -our $prototype_file_a = "../../../include/mpi.h.in"; -our $prototype_file_b = "../../../include/mpi_proto.h"; - -# Global hashes used for definitions and to record the locations of the -# definitions. -%mpidef = (); -%mpidefFile = (); -%mpiRoutinesFile = (); - -# Handle special initializations -# -# Notes on this string. Some symbols need to be initialized at runtime. -# These are typically the addresses of the "special" Fortran symbols, -# such as MPIR_F_MPI_BOTTOM. Because MPI-2 requires that MPI_Init and -# MPI_Init_thread, called in *any* language, initialize MPI for *all* -# languages, we can't depend on having the Fortran versions of MPI_Init or -# MPI_Init_thread called before these values might be used in a Fortran -# wrapper function. -# We also cannot have the C version of MPI_Init and MPI_Init_thread call -# the initialization routine, because some Fortran compilers will require -# special routines from that particular vendors Fortran runtime library for -# any executable that uses routines that are compiled with the Fortran -# compiler, forcing user programs that are entirely C to link with the -# Fortran runtime. Thus, we must check whether the values are initialized -# before any use in any routine. -# -$specialInitAdded = 0; -$specialInitString = "if (MPIR_F_NeedInit){ mpirinitf_(); MPIR_F_NeedInit = 0;}"; - -# Process arguments -# -# Args -# -feature={logical,fint,subdecls,weak,bufptr}, separated by :, value given -# by =on or =off, eg -# -feature=logical=on:fint=off -# The feature names mean: -# logical - Fortran logicals are converted to/from C -# fint - Fortran integers and C ints are different size (not implemented) -# subdecls - Declarations for PC-Fortran compilers added -# weak - Use weak symbols -# bufptr - Check for MPI_BOTTOM as a special address. This is -# not needed if a POINTER declaration is available. -foreach $_ (@ARGV) { - if (/-noprototypes/) { $build_prototypes = 0; } - elsif (/-infile=(.*)/) { - # Special arg to help with debugging - $prototype_file_a = $1; - $prototype_file_b = $1; - $write_mpif = 0; - $build_prototypes = 0; - $do_weak = 0; - } - elsif (/-noromio/) { $build_io = 0; } - elsif (/-debug/) { - $debug = 1; - } - elsif (/-prefix=(.*)/) { - @routine_prefixes = ($1); - $is_MPI = 0; - } - elsif (/-pattern=(.*)/) { - $routine_pattern = $1; - } - elsif (/-feature=(.*)/) { - foreach $feature (split(/:/,$1)) { - print STDERR "Processing feature $feature\n" if $debug; - # Feature values are foo=on,off - ($name,$value) = split(/=/,$feature); - # Default if feature is selected is to enable it. - if (!defined($value)) { $value = 1; } - else { - if ($value eq "on") { $value = 1; } - elsif ($value eq "off") { $value = 0; } - } - # Set the variable based on the string - $varname = "do_$name"; - $$varname = $value; - } - } - elsif (/deffile=(.*)/) { - $definition_file = $1; - $is_MPI = 0; - } - else { - print STDERR "Unrecognized argument $_\n"; - } -} - -# Note that the code that looks up values strips blanks out of the type name -# No blanks should be used in the key. -%tof77 = ( 'MPI_Datatype' => 'MPI_Fint *', - 'MPI_Comm' => 'MPI_Fint *', -#MPI_File must be handled specially, since ROMIO still uses pointers - 'MPI_File' => 'MPI_Fint *', - 'MPI_Win' => 'MPI_Fint *', - 'MPI_Request' => 'MPI_Fint *', - 'MPI_Group' => 'MPI_Fint *', - 'MPI_Op' => 'MPI_Fint *', - 'MPI_Info' => 'MPI_Fint *', - 'MPI_Errhandler' => 'MPI_Fint *', - 'MPI_Message' => 'MPI_Fint *', - 'MPI_Aint' => 'MPI_Fint *', # Should be MPIR_FAint - 'MPI_FAintp' => 'MPI_Aint *', # Used to force an MPI_Aint* - 'MPI_Offset' => 'MPI_Offset *', # Should be MPIR_FOint - 'MPI_Count' => 'MPI_Count *', # Should be MPIR_FCint? - 'MPI_Count*' => 'MPI_Count *', # Should be MPIR_FCint? - 'int' => 'MPI_Fint *', - 'int[]' => 'MPI_Fint', # no * because we'll use array form - 'int[][3]' => 'MPI_Fint', # no * because we'll use array form - 'MPI_Datatype*' => 'MPI_Fint *', - 'MPI_Datatype[]' => 'MPI_Fint', # no * because we'll use array form - 'MPI_Comm*' => 'MPI_Fint *', - 'MPI_File*' => 'MPI_Fint *', - 'MPI_Win*' => 'MPI_Fint *', - 'MPI_Group*' => 'MPI_Fint *', - 'MPI_Request*' => 'MPI_Fint *', - 'MPI_Request[]' => 'MPI_Fint', - 'MPI_Message*' => 'MPI_Fint *', - 'MPI_Aint*' => 'MPI_Fint *', # Should be MPIR_FAint - 'MPI_Count*' => 'MPI_Count *', - 'int *' => 'MPI_Fint *', - 'int*' => 'MPI_Fint *', # Catch missing space - 'MPI_Op*' => 'MPI_Fint *', - 'MPI_Status*' => 'MPI_Fint *', - 'MPI_Status[]' => 'MPI_Fint', - 'MPI_Info*' => 'MPI_Fint *', - 'MPI_Info[]' => 'MPI_Fint', - 'MPI_Errhandler*' => 'MPI_Fint *', - ); - -# declarg is special parameters for certain routines -%declarg = ( 'type_extent-2' => 'MPI_Fint *', - 'type_lb-2' => 'MPI_Fint *', - 'type_ub-2' => 'MPI_Fint *', - 'type_struct-3' => 'MPI_Fint *', # Really [], but * is easier - 'type_hindexed-3' => 'MPI_Fint *', # As above - 'type_hvector-3' => 'MPI_Fint *', - # The following are MPI-2 routines with address args. - # For these, the user must pass in the correct arguments - 'file_get_type_extent-3' => 'MPI_FAint *', - 'pack_external-6' => 'MPI_Aint *', # Value in C call - 'pack_external-7' => 'MPI_Aint *', - 'pack_external_size-4' => 'MPI_Aint *', - 'type_create_hvector-3' => 'MPI_Aint *', # Value in C call - 'type_create_hindexed-3' => 'MPI_Aint *', - 'type_create_struct-3' => 'MPI_Aint *', - 'type_get_contents-6' => 'MPI_Aint *', - 'type_get_extent-2' => 'MPI_Aint *', - 'type_get_extent-3' => 'MPI_Aint *', - 'type_get_true_extent-2' => 'MPI_Aint *', - 'type_get_true_extent-3' => 'MPI_Aint *', - 'type_create_resized-2' => 'MPI_Aint *', # Value in C call - 'type_create_resized-3' => 'MPI_Aint *', # Value in C call - 'unpack_external-3' => 'MPI_Aint *', # Value in C call - 'unpack_external-4' => 'MPI_Aint *', - 'win_create-2' => 'MPI_Aint *', - 'accumulate-5' => 'MPI_Aint *', - 'put-5' => 'MPI_Aint *', - 'get-5' => 'MPI_Aint *', - 'alloc_mem-1' => 'MPI_Aint *', - 'win_shared_query-3' => 'MPI_Aint *', - 'compare_and_swap-6' => 'MPI_Aint *', - 'fetch_and_op-5' => 'MPI_Aint *', - 'get_accumulate-8' => 'MPI_Aint *', - 'rput-5' => 'MPI_Aint *', - 'rget-5' => 'MPI_Aint *', - 'raccumulate-5' => 'MPI_Aint *', - 'rget_accumulate-8' => 'MPI_Aint *', - 'win_attach-3' => 'MPI_Aint *', - 'win_allocate-1' => 'MPI_Aint *', - 'win_allocate_shared-1' => 'MPI_Aint *', - #'status_set_elements_x-3' => 'MPI_Count *', - ); - -%argsneedcast = ( 'MPI_Request *' => '(MPI_Request *)(ARG)', - 'MPI_Status *' => '(MPI_Status *)(ARG)', - 'MPI_Status []' => '(MPI_Status [])(ARG)', - 'MPI_File' => 'MPI_File_f2c(ARG)', - 'MPI_Comm' => '(MPI_Comm)(ARG)', - 'MPI_Comm *' => '(MPI_Comm *)(ARG)', - 'MPI_Datatype' => '(MPI_Datatype)(ARG)', - 'MPI_Datatype *' => '(MPI_Datatype *)(ARG)', - 'MPI_Info *' => '(MPI_Info *)(ARG)', - 'MPI_Info' => '(MPI_Info)(ARG)', - 'MPI_Message *' => '(MPI_Message *)(ARG)', - 'int [][3]' => '(int (*)[3])(ARG)' -); - -## -## For implementations other than MPICH, we'll need to consider using -## MPI_C2f_ and MPI_F2c_, as in -## 'MPI_Info' => 'MPI_F2c_info(ARG)' -## -# name_map maps the filenames. Most filenames are created automatically -# from the routine name, but some names have too many characters (15, -# including the extension(.o) is a limit for ar in some systems). -%name_map = ( 'add_error_class' => 'adderrclass', - 'add_error_code' => 'adderrcode', - 'add_error_string' => 'adderrstring', - 'buffer_attach' => 'bufattach', - 'buffer_detach' => 'bufdetach', - 'comm_call_errhandler' => 'commcallerr', - 'comm_create_errhandler' => 'commcreerr', - 'comm_create_keyval' => 'commnewkey', - 'comm_delete_attr' => 'commdelattr', - 'comm_disconnect' => 'commdisc', - 'comm_free_keyval' => 'commfreekey', - 'comm_get_errhandler' => 'commgeterr', - 'comm_get_name' => 'commgetnam', - 'comm_get_parent' => 'commparent', - 'comm_remote_group' => 'commrgroup', - 'comm_remote_size' => 'commrsize', - 'comm_set_errhandler' => 'commseterr', - 'comm_spawn_multiple' => 'spawnmult', - 'comm_test_inter' => 'commtestic', - 'errhandler_create' => 'errhcreate', - 'errhandler_free' => 'errhfree', - 'errhandler_get' => 'errhget', - 'errhandler_set' => 'errhset', - 'file_call_errhandler' => 'filecallerr', - 'file_create_errhandler' => 'filecreerr', - 'file_get_errhandler' => 'filegeterr', - 'file_set_errhandler' => 'fileseterr', - 'get_processor_name' => 'getpname', - 'graph_neighbors_count' => 'grfnbcount', - 'graph_neighbors' => 'grfnbrs', - 'grequest_complete' => 'greqcomplete', - 'grequest_start' => 'greqstart', - 'group_difference' => 'groupdiff', - 'group_intersection' => 'groupinter', - 'group_range_excl' => 'grouprexcl', - 'group_range_incl' => 'grouprincl', - 'group_translate_ranks' => 'grouptranks', - 'info_get_nkeys' => 'infognk', - 'info_get_nthkey' => 'infognthk', - 'info_get_valuelen' => 'infovallen', - 'info_get_string' => 'infogetstr', - 'intercomm_create' => 'iccreate', - 'intercomm_merge' => 'icmerge', - 'is_thread_main' => 'isthrmain', - 'pack_external_size' => 'packesize', - 'reduce_scatter' => 'redscat', - 'request_get_status' => 'reqgetstat', - 'sendrecv_replace' => 'sndrcvrpl', - 'status_set_cancelled' => 'statgetcl', - 'status_set_elements' => 'statsetel', - 'test_cancelled' => 'testcancel', - 'type_contiguous' => 'typecontig', - 'type_create_darray' => 'typedarray', - 'type_create_f90_integer' => 'typef90int', - 'type_create_f90_real' => 'typef90real', - 'type_create_f90_complex' => 'typef90cmplx', - 'type_create_hindexed' => 'typechind', - 'type_create_hvector' => 'typechvec', - 'type_create_indexed_block' => 'typecindb', - 'type_create_keyval' => 'typenewkey', - 'type_create_resized' => 'typecresize', - 'type_create_struct' => 'typecstruct', - 'type_create_subarray' => 'typecsubarr', - 'type_delete_attr' => 'typedelattr', - 'type_free_keyval' => 'typefreekey', - 'type_get_contents' => 'typegetcnts', - 'type_get_envelope' => 'typegetenv', - 'type_get_extent' => 'typegetextent', # there is already a type_extent - 'type_get_name' => 'typegname', - 'type_get_true_extent' => 'typegtext', - 'type_set_attr' => 'typesetattr', - 'type_set_name' => 'typesetname', - 'unpack_external' => 'unpackext', - 'unpublish_name' => 'unpubname', - 'win_call_errhandler' => 'wincallerr', - 'win_create_errhandler' => 'wincreerr', - 'win_create_keyval' => 'winnewkey', - 'win_delete_attr' => 'windelattr', - 'win_free_keyval' => 'winfreekey', - 'win_get_errhandler' => 'wingeterr', - 'win_set_errhandler' => 'winseterr', -); - -# -# Special routines have very different calling sequences in C and Fortran -# or different behavior. -# Init and Init thread have different arg lists (no argc, argv) -# Pcontrol has no varargs -# Address and Get_address require special integer types and -# possibly handling for MPI_BOTTOM -# Keyval routines require setting the language to Fortran (Attribute -# routines are handled with the special argument processing) -# -# The Type_create_f90_xxx routines are only available as part of the -# extended Fortran support, and are excluded from the f77 routines. -# Aint_add/diff do not have the ierror argument -%special_routines = ( 'Init' => 1, 'Init_thread' => 1, 'Pcontrol' => '1', - 'Address' => 1, 'Get_address' => 1, - 'Keyval_create' => 1, 'Status_f2c' => 1, - 'Status_c2f' => 1, - 'Status_c2f08' => 1, - 'Status_f082c' => 1, - 'Status_f2f08' => 1, - 'Status_f082f' => 1, - 'Type_create_f90_integer' => 1, - 'Type_create_f90_real' => 1, - 'Type_create_f90_complex' => 1, - 'Aint_add' => 1, - 'Aint_diff' => 1, - 'Info_create_env' => 1, - ); - -# Some routines have special needs and must call a different routine. For -# similicity, we make the requirement that the replacement routine take -# all of the arguments of the original routine, but all additional arguments -# at the end. This is used with the attribute routines which must -# pass an additional argument to a special attribute routine that handles -# the differences between C and Fortran attributes. -%ChangeCall = ( 'Comm_get_attr' => 'MPII_Comm_get_attr:!MPIR_ATTR_AINT' , - 'Type_get_attr' => 'MPII_Type_get_attr:!MPIR_ATTR_AINT', - 'Win_get_attr' => 'MPII_Win_get_attr:!MPIR_ATTR_AINT', - 'Attr_get' => 'MPII_Comm_get_attr:!MPIR_ATTR_INT', - 'Comm_set_attr' => 'MPII_Comm_set_attr:!MPIR_ATTR_AINT', - 'Type_set_attr' => 'MPII_Type_set_attr:!MPIR_ATTR_AINT', - 'Win_set_attr' => 'MPII_Win_set_attr:!MPIR_ATTR_AINT', - 'Attr_put' => 'MPII_Comm_set_attr:!MPIR_ATTR_INT', - ); -# -# Note that wtime and wtick aren't found because they don't match the -# int MPI_xxx format. They're handled directly by the special routine -# code below - -# -# Most routines can be processed automatically. However, some -# require some special processing. For example, those routines with -# LOGICAL arguments need some special handling. To detect this, there -# are two entries in a %special_args hash: the routine name, and the routine -# name -arg#. E.g., for MPI_Test, the hash has keys -# "Test" and "Test-2". The value for "Test-2" is "out:logical"; this -# indicates that the variable is an out variable with logical type. -# Processing types (the second field after the :) are -# logical: convert to/from Fortran and C representations of logical -# index: convert to/from Fortran (1-based) and C (0-based) origins -# array: handle arrays of items that may have different lengths -# in C and Fortran because the integer types have -# different sizes. The term has an additional :expression, -# the third term give the array size. -# addnull: Add a null character to a *copy* of the input string, -# after trimming any blanks. -# blankpad: Add blanks and remove nulls. Only used for out args; -# must use an allocated space to provide room for the null -# that the C routines may require -# bufptr: Detect MPI_BOTTOM. Note that a better alternative is to -# use MPI_Address and MPI_Get_address to make addresses -# relative to the Fortran MPI_BOTTOM. The lines that -# define this are commented out below. -# addrint: Given the address of an int, provide the int. Used -# for attr_put/set routines -# attrint: Convert an attribute value to an int. -# addraint: Given the address of an address-sized int, provide the -# value of that item. Used for the MPI-2 versions of the -# attribute caching routines -# bufaddr: Argument is *output* as a buffer address. Discarded before -# passing to Fortran. -# For MPI-2 routines that take MPI_Aints even in Fortran, we need a -# special mapping when the value is passed to c -# aintToVal: Given the address of an Aint, pass the value to the C routine -# (This should really be done by not applying the Aint->int mapping -# for MPI-2 routines. But for now, this hack will work) -%special_args = ( -# 'Allreduce' => '1:2', 'Allreduce-1' => 'in:bufptr', -# 'Allreduce-2' => 'in:bufptr', -# 'Bcast' => '1', 'Bcast-1' => 'in:bufptr', -# 'Gather' => '1:4', 'Gather-1' => 'in:bufptr', 'Gather-4' => 'in:bufptr', -# 'Gatherv' => '1:4', 'Gatherv-1' => 'in:bufptr', 'Gatherv-4' => 'in:bufptr', -# 'Scatter' => '1:4', 'Scatter-1' => 'in:bufptr', 'Scatter-4' => 'in:bufptr', -# 'Scatterv' => '1:5', 'Scatterv-1' => 'in:bufptr', 'Scatterv-5' => 'in:bufptr', -# 'Allgather' => '1:4', 'Allgather-1' => 'in:bufptr', 'Allgather-4' => 'in:bufptr', -# 'Allgatherv' => '1:4', 'Allgatherv-1' => 'in:bufptr', 'Allgatherv-4' => 'in:bufptr', -# 'Alltoall' => '1:4', 'Alltoall-1' => 'in:bufptr', 'Alltoall-4' => 'in:bufptr', -# 'Alltoallv' => '1:5', 'Alltoallv-1' => 'in:bufptr', 'Alltoallv-5' => 'in:bufptr', -# 'Reduce' => '1:2', 'Reduce-1' => 'in:bufptr', 'Reduce-2' => 'in:bufptr', -# 'Reduce_scatter' => '1:2', 'Reduce_scatter-1' => 'in:bufptr', -# 'Reduce_scatter-2' => 'in:bufptr', -# 'Scan' => '1:2', 'Scan-1' => 'in:bufptr', 'Scan-2' => 'in:bufptr', -# - 'Gather' => '1', 'Gather-1' => 'in:inplace', - 'Gatherv' => '1:5:6', 'Gatherv-1' => 'in:inplace', - 'Gatherv-5' => 'in:fint2int_array:_commsize(*v9)', - 'Gatherv-6' => 'in:fint2int_array:_commsize', - 'Scatter' => '4', 'Scatter-4' => 'in:inplace', - 'Scatterv' => '2:3:5', - 'Scatterv-2' => 'in:fint2int_array:_commsize(*v9)', - 'Scatterv-3' => 'in:fint2int_array:_commsize', - 'Scatterv-5' => 'in:inplace', - 'Allgather' => '1', 'Allgather-1' => 'in:inplace', - 'Allgatherv' => '1:5:6', 'Allgatherv-1' => 'in:inplace', - 'Allgatherv-5' => 'in:fint2int_array:_commsize(*v8)', - 'Allgatherv-6' => 'in:fint2int_array:_commsize', - 'Reduce' => '1', 'Reduce-1' => 'in:inplace', - 'Allreduce' => '1', 'Allreduce-1' => 'in:inplace', - 'Reduce_scatter' => '1:3', - 'Reduce_scatter-1' => 'in:inplace', - 'Reduce_scatter-3' => 'in:fint2int_array:_commsize(*v6)', - 'Reduce_scatter_block' => '1', - 'Reduce_scatter_block-1' => 'in:inplace', - 'Scan' => '1', 'Scan-1' => 'in:inplace', - 'Exscan' => '1', 'Exscan-1' => 'in:inplace', - 'Alltoall' => '1', - 'Alltoall-1' => 'in:inplace', - 'Alltoallv' => '1:2:3:6:7', - 'Alltoallv-1' => 'in:inplace', - 'Alltoallv-2' => 'in:fint2intinplace_array:_commsize(*v9)', - 'Alltoallv-3' => 'in:fint2intinplace_array:_commsize', - 'Alltoallv-6' => 'in:fint2int_array:_commsize', - 'Alltoallv-7' => 'in:fint2int_array:_commsize', - 'Alltoallw' => '1:2:3:4:6:7:8', - 'Alltoallw-1' => 'in:inplace', - 'Alltoallw-2' => 'in:fint2intinplace_array:_commsize(*v9)', - 'Alltoallw-3' => 'in:fint2intinplace_array:_commsize', - 'Alltoallw-6' => 'in:fint2int_array:_commsize', - 'Alltoallw-7' => 'in:fint2int_array:_commsize', -# FIXME: -4 needs inplace - 'Alltoallw-4' => 'in:handle_array:_commsize:MPI_Datatype', - 'Alltoallw-8' => 'in:handle_array:_commsize:MPI_Datatype', - - 'Add_error_string' => '2', 'Add_error_string-2' => 'in:addnull', - 'Attr_put' => '3', 'Attr_put-3' => 'in:addrint', - 'Attr_get' => '3:4', 'Attr_get-4' => 'out:logical', - 'Attr_get-3' => 'out:attrint:4', - 'Comm_set_attr' => '3', 'Comm_set_attr-3' => 'in:addraint', - 'Type_set_attr' => '3', 'Type_set_attr-3' => 'in:addraint', - 'Win_set_attr' => '3', 'Win_set_attr-3' => 'in:addraint', - 'Comm_get_attr' => '3:4', 'Comm_get_attr-4' => 'out:logical', - 'Comm_get_attr-3' => 'out:attraint:4', - 'Type_get_attr' => '3:4', 'Type_get_attr-4' => 'out:logical', - 'Type_get_attr-3' => 'out:attraint:4', - 'Win_get_attr' => '3:4', 'Win_get_attr-4' => 'out:logical', - 'Win_get_attr-3' => 'out:attraint:4', - 'Buffer_detach' => '1', 'Buffer_detach-1' => 'out:bufaddr', - 'Cart_create' => '3:4:5:6', - 'Cart_create-3' => 'in:fint2int_array:*v2', - 'Cart_create-4' => 'in:logical_array:*v2', - 'Cart_create-5' => 'in:logical', - 'Cart_create-6' => 'out:handle::MPI_Comm', - 'Cart_get' => '3:4:5', - 'Cart_get-3' => 'out:fint2int_array:*v2', - 'Cart_get-4' => 'out:logical_array:*v2', - 'Cart_get-5' => 'out:fint2int_array:*v2', - 'Cart_sub' => '2:3', - 'Cart_sub-2' => 'in:logical_array:_cartdim', - 'Cart_sub-3' => 'out:handle::MPI_Comm', - 'Cart_coords' => '4', - 'Cart_coords-4' => 'out:fint2int_array:*v3', - 'Cart_map' => '3:4', - 'Cart_map-3' => 'in:fint2int_array:*v2', - 'Cart_map-4' => 'in:logical_array:*v2', - 'Cart_rank' => '2', - 'Cart_rank-2' => ,'in:fint2int_array:_cartdim', - # FIXME: For cart_sub, need to update arg 2, in:finttoint_array, but - # size is size of input cart - 'Dims_create' => '3', - 'Dims_create-3' => 'inout:fint2int_array:*v2', - 'Graph_create' => '3:4:5:6', - 'Graph_create-3' => 'in:fint2int_array:*v2', - 'Graph_create-4' => 'in:fint2int_array:v3[*v2-1]', - 'Graph_create-5' => 'in:logical', - 'Graph_create-6' => 'out:handle::MPI_Comm', - 'Graph_get' => '4:5', 'Graph_get-4' => 'out:fint2int_array:*v2', - 'Graph_get-5' => 'out:fint2int_array:*v3', - 'Graph_map' => '3:4', 'Graph_map-3' => 'in:fint2int_array:*v2', - 'Graph_map-4' => 'in:fint2int_array:*v2', - 'Graph_neighbors' => '4', - 'Graph_neighbors-4' => 'out:fint2int_array:*v3', - 'Comm_create' => '3', 'Comm_create-3' => 'out:handle::MPI_Comm', - 'Comm_create_group' => '4', 'Comm_create_group-4' => 'out:handle::MPI_Comm', - 'Comm_dup' => '2', 'Comm_dup-2' => 'out:handle::MPI_Comm', - 'Comm_dup_with_info' => '3', - 'Comm_dup_with_info-3' => 'out:handle::MPI_Comm', - 'Comm_idup' => '2', 'Comm_idup-2' => 'out:handle::MPI_Comm', - 'Comm_split' => '4', 'Comm_split-4' => 'out:handle::MPI_Comm', - 'Comm_split_type' => '5', 'Comm_split_type-5' => 'out:handle::MPI_Comm', - 'Comm_free' => '1', 'Comm_free-1' => 'inout:handle::MPI_Comm', - 'Comm_accept' => '1:5', 'Comm_accept-1' => 'in:addnull', - 'Comm_accept-5' => 'out:handle::MPI_Comm', - 'Comm_connect' => '1:5', 'Comm_connect-1' => 'in:addnull', - 'Comm_connect-5' => 'out:handle::MPI_Comm', - 'Comm_disconnect' => '1', 'Comm_disconnect-1' => 'inout:handle::MPI_Comm', - 'Comm_join' => '2', 'Comm_join-2' => 'out:handle::MPI_Comm', - 'Comm_get_name' => '2', 'Comm_get_name-2' => 'out:blankpad', - 'Comm_set_name' => '2', 'Comm_set_name-2' => 'in:addnull', - 'Comm_spawn' => '1:2:7:8', 'Comm_spawn-1' => 'in:addnull', - 'Comm_spawn-2' => 'in:chararray', - 'Comm_spawn-7' => 'out:handle::MPI_Comm', - 'Comm_spawn-8' => 'out:errcodesignore:*v3', - 'Comm_get_parent' => '1', - 'Comm_get_parent-1' => 'out:handle::MPI_Comm', - 'Comm_test_inter' => '2', 'Comm_test_inter-2' => 'out:logical', - 'Group_incl' => '3:4', 'Group_incl-3' => 'in:fint2int_array:*v2', - 'Group_incl-4' => 'out:handle::MPI_Group', - 'Group_excl' => '3:4', 'Group_excl-3' => 'in:fint2int_array:*v2', - 'Group_excl-4' => 'out:handle::MPI_Group', - 'Group_range_incl' => '3:4', - 'Group_range_incl-3' => 'in:fint2int_rangearray:(*v2*3)', - 'Group_range_incl-4' => 'out:handle::MPI_Group', - 'Group_range_excl' => '3:4', - 'Group_range_excl-3' => 'in:fint2int_rangearray:(*v2*3)', - 'Group_range_excl-4' => 'out:handle::MPI_Group', - 'Group_translate_ranks' => '3:5', - 'Group_translate_ranks-3' => 'in:fint2int_array:*v2', - 'Group_translate_ranks-5' => 'out:fint2int_array:*v2', - 'Get_processor_name' => '1', 'Get_processor_name-1' => 'out:blankpad', - 'Get_library_version' => '1', 'Get_library_version-1' => 'out:blankpad', - 'Error_string' => '2', 'Error_string-2' => 'out:blankpad', - 'Errhandler_free' => '1', - 'Errhandler_free-1' => 'inout:handle::MPI_Errhandler', - 'Keyval_free' => '1', - 'Keyval_free-1' => 'inout:fint2int', - 'Intercomm_merge' => '2:3', 'Intercomm_merge-2' => 'in:logical', - 'Intercomm_merge-3' => 'out:handle::MPI_Comm', - 'Intercomm_create' => '6', 'Intercomm_create-6' => 'out:handle::MPI_Comm', - 'Info_get' => '2:4:5', 'Info_get-2' => 'in:addnull', - 'Info_get-4' => 'out:blankpadonflag:l5', - 'Info_get-5' => 'out:logical', - 'Info_set' => '2:3', 'Info_set-2' => 'in:addnullandtrim', - 'Info_set-3' => 'in:addnullandtrim', - 'Info_get_nthkey' => '3', 'Info_get_nthkey-3' => 'out:blankpad', - 'Info_get_valuelen' => '2:4', 'Info_get_valuelen-2' => 'in:addnull', - 'Info_get_valuelen-4' => 'out:logical', - 'Info_get_string' => '2:3:4:5', - 'Info_get_string-2' => 'in:addnull', - 'Info_get_string-3' => 'inout:addsubone', - 'Info_get_string-4' => 'out:blankpadonflag:(l5 && x3 > 0)', - 'Info_get_string-5' => 'out:logical', - 'Info_delete' => '2', 'Info_delete-2' => 'in:addnull', - 'Lookup_name' => '1:3', 'Lookup_name-1' => 'in:addnull', - 'Lookup_name-3' => 'out:blankpad', - 'Open_port' => '2', 'Open_port-2' => 'out:blankpad', - 'Close_port' => '1', 'Close_port-1' => 'in:addnull', - 'Pack_external' => '1:6', 'Pack_external-1' => 'in:addnull', - 'Pack_external-6' => 'in:aintToVal', - 'Pack_external_size' => '1', 'Pack_external_size-1' => 'in:addnull', - 'Publish_name' => '1:3', 'Publish_name-1' => 'in:addnull', - 'Publish_name-3' => 'in:addnull', -# comm spawn multiple needs slightly different routines - 'Comm_spawn_multiple' => '2:3:4:5:8:9', - 'Comm_spawn_multiple-2' => 'in:chararray:*v1', - 'Comm_spawn_multiple-3' => 'in:chararray2:*v1', - 'Comm_spawn_multiple-9' => 'out:errcodesignore:_sum(v4,*v1)', - 'Comm_spawn_multiple-4' => 'in:fint2int_array:*v1', - 'Comm_spawn_multiple-5' => 'in:handle_array:*v1:MPI_Info', - 'Comm_spawn_multiple-8' => 'out:handle::MPI_Comm', - 'Initialized' => '1', 'Initialized-1' => 'out:logical', - 'Finalized' => '1', 'Finalized-1' => 'out:logical', - 'Is_thread_main' => '1', 'Is_thread_main-1' => 'out:logical', - 'Op_create' => '2', 'Op_create-2' => 'in:logical', - 'Op_free' => '1', 'Op_free-1' => 'inout:handle::MPI_Op', - 'Iprobe' => '4:5', 'Iprobe-4' => 'out:logical', - 'Iprobe-5' => 'out:status::l4', - 'Probe' => '4', 'Probe-4' => 'out:status', - 'Recv' => '7', 'Recv-7' => 'out:status', - 'Mprobe' => '5', 'Mprobe-5' => 'out:status', - 'Mrecv' => '5', 'Mrecv-5' => 'out:status', - 'Improbe' => '4:6', 'Improbe-4' => 'out:logical', - 'Improbe-6' => 'out:status', - 'Sendrecv' => '12', 'Sendrecv-12' => 'out:status', - 'Sendrecv_replace' => '9', 'Sendrecv_replace-9' => 'out:status', -# 'Send' => '1', 'Send-1' => 'in:bufptr', -# 'Ssend' => '1', 'Ssend-1' => 'in:bufptr', -# 'Rsend' => '1', 'Rsend-1' => 'in:bufptr', -# 'Bsend' => '1', 'Bsend-1' => 'in:bufptr', -# 'Isend' => '1', 'Isend-1' => 'in:bufptr', -# 'Issend' => '1', 'Issend-1' => 'in:bufptr', -# 'Irsend' => '1', 'Irsend-1' => 'in:bufptr', -# 'Ibsend' => '1', 'Ibsend-1' => 'in:bufptr', -# 'Irecv' => '1', 'Irecv-1' => 'in:bufptr', -# 'Recv' => '1', 'Recv-1' => 'in:bufptr', -# 'Send_init' => '1', 'Send_init-1' => 'in:bufptr', -# 'Bsend_init' => '1', 'Bsend_init-1' => 'in:bufptr', -# 'Ssend_init' => '1', 'Ssend_init-1' => 'in:bufptr', -# 'Rsend_init' => '1', 'Rsend_init-1' => 'in:bufptr', -# 'Recv_init' => '1', 'Recv_init-1' => 'in:bufptr', -# 'Sendrecv' => '1:6', 'Sendrecv-1' => 'in:bufptr', 'Sendrecv-6' => 'in:bufptr', -# 'Sendrecv_replace' => '1', 'Sendrecv_replace-1' => 'in:bufptr', - 'Test_cancelled' => '1:2', - 'Test_cancelled-1' => 'in:status', - 'Test_cancelled-2' => 'out:logical', - 'Test' => '1:2:3', 'Test-1' => 'inout:handle::MPI_Request', - 'Test-2' => 'out:logical', - 'Test-3' => 'out:status:::l2', - 'Testall' => '2:3:4', 'Testall-2' => 'inout:handle_array:*v1:MPI_Request', - 'Testall-3' => 'out:logical', - 'Testall-4' => 'out:status_array:*v1::l3', - 'Testany' => '2:3:4:5', 'Testany-2' => 'inout:handle_array:*v1:MPI_Request', - 'Testany-4' => 'out:logical', - 'Testany-3' => 'out:index', - 'Testany-5' => 'out:status:::l4', - 'Testsome' => '2:3:4:5', - 'Testsome-2' => 'inout:handle_array:*v1:MPI_Request', - 'Testsome-3' => 'out:fint2int', - 'Testsome-4' => 'out:index_array:*v1:*v3', - 'Testsome-5' => 'out:status_array:*v1:*v3:l3>0', - 'Get_count' => '1', 'Get_count-1' => 'in:status', - 'Request_get_status' => '2:3', - 'Request_get_status-2' => 'out:logical', - 'Request_get_status-3' => 'out:status', - 'Status_set_cancelled' => '1:2', - 'Status_set_cancelled-1' => 'in:status', - 'Status_set_cancelled-2' => 'in:logical', - 'Status_set_elements' => '1', - 'Status_set_elements-1' => 'out:status', - 'Status_set_elements_x' => '1', - 'Status_set_elements_x-1' => 'out:status', - 'Type_contiguous' => '2:3', - 'Type_contiguous-2' => 'in:handle::MPI_Datatype', - 'Type_contiguous-3' => 'out:handle::MPI_Datatype', - 'Type_vector' => '4:5', - 'Type_vector-4' => 'in:handle::MPI_Datatype', - 'Type_vector-5' => 'out:handle::MPI_Datatype', - 'Type_hvector' => '3:4:5', - 'Type_hvector-3' => 'in:intToAint', - 'Type_hvector-4' => 'in:handle::MPI_Datatype', - 'Type_hvector-5' => 'out:handle::MPI_Datatype', - 'Type_indexed' => '2:3:4:5', - 'Type_indexed-2' => 'in:fint2int_array:*v1', - 'Type_indexed-3' => 'in:fint2int_array:*v1', - 'Type_indexed-4' => 'in:handle::MPI_Datatype', - 'Type_indexed-5' => 'out:handle::MPI_Datatype', - 'Type_hindexed' => '2:3:4:5', - 'Type_hindexed-2' => 'in:fint2int_array:*v1', - 'Type_hindexed-3' => 'in:intToAintArr:*v1', - 'Type_hindexed-4' => 'in:handle::MPI_Datatype', - 'Type_hindexed-5' => 'out:handle::MPI_Datatype', - 'Type_struct' => '2:3:4:5', - 'Type_struct-2' => 'in:fint2int_array:*v1', - 'Type_struct-3' => 'in:intToAintArr:*v1', - 'Type_struct-4' => 'in:handle_array:*v1:MPI_Datatype', - 'Type_struct-5' => 'out:handle::MPI_Datatype', - - 'Type_commit' => '1', - 'Type_commit-1' => 'inout:handle::MPI_Datatype', - 'Type_free' => '1', - 'Type_free-1' => 'inout:handle::MPI_Datatype', - 'Type_dup' => '2', - 'Type_dup-2' => 'out:handle::MPI_Datatype', - 'Type_match_size' => '3', 'Type_match_size-3' => 'out:handle::MPI_Datatype', - 'Get_elements' => 1, - 'Get_elements-1' => 'in:status', - 'Get_elements_x' => 1, - 'Get_elements_x-1' => 'in:status', - - 'Type_create_hvector' => '3:5', 'Type_create_hvector-3' => 'in:aintToVal', - 'Type_create_hvector-5' => 'out:handle::MPI_Datatype', - 'Type_create_hindexed' => '2:4:5', - 'Type_create_hindexed-2' => 'in:fint2int_array:*v1', - 'Type_create_hindexed-4' => 'in:handle::MPI_Datatype', - 'Type_create_hindexed-5' => 'out:handle::MPI_Datatype', - 'Type_create_indexed_block' => '3:4:5', - 'Type_create_indexed_block-3' => 'in:fint2int_array:*v1', - 'Type_create_indexed_block-4' => 'in:handle::MPI_Datatype', - 'Type_create_indexed_block-5' => 'out:handle::MPI_Datatype', - 'Type_create_resized' => '2:3:4', - 'Type_create_resized-2' => 'in:aintToVal', - 'Type_create_resized-3' => 'in:aintToVal', - 'Type_create_resized-4' => 'out:handle::MPI_Datatype', - 'Type_create_struct' => '2:4:5', - 'Type_create_struct-2' => 'in:fint2int_array:*v1', - 'Type_create_struct-4' => 'in:handle_array:*v1:MPI_Datatype', - 'Type_create_struct-5' => 'out:handle::MPI_Datatype', - 'Type_create_subarray' => '2:3:4:7', - 'Type_create_subarray-2' => 'in:fint2int_array:*v1', - 'Type_create_subarray-3' => 'in:fint2int_array:*v1', - 'Type_create_subarray-4' => 'in:fint2int_array:*v1', - 'Type_create_subarray-7' => 'out:handle::MPI_Datatype', - 'Type_create_darray' => '4:5:6:7:10', - 'Type_create_darray-4' => 'in:fint2int_array:*v3', - 'Type_create_darray-5' => 'in:fint2int_array:*v3', - 'Type_create_darray-6' => 'in:fint2int_array:*v3', - 'Type_create_darray-7' => 'in:fint2int_array:*v3', - 'Type_create_darray-10' => 'out:handle::MPI_Datatype', - 'Type_get_name' => '2', 'Type_get_name-2' => 'out:blankpad', - 'Type_set_name' => '2', 'Type_set_name-2' => 'in:addnull', - 'Type_get_contents' => '5:7', - 'Type_get_contents-5' => 'out:fint2int_array:*v2', - 'Type_get_contents-7' => 'out:handle_array:*v4:MPI_Datatype', - 'Type_extent' => '2', 'Type_extent-2' => 'out:aintToInt', - 'Type_lb' => '2', 'Type_lb-2' => 'out:aintToInt', - 'Type_ub' => '2', 'Type_ub-2' => 'out:aintToInt', -# also need - 'Unpack_external' => '1:3', 'Unpack_external-1' => 'in:addnull', - 'Unpack_external-3' => 'in:aintToVal', - 'Unpublish_name' => '1:3', 'Unpublish_name-1' => 'in:addnull', - 'Unpublish_name-3' => 'in:addnull', - 'Win_create' => '2', 'Win_create-2' => 'in:aintToVal', - 'Accumulate' => '5', 'Accumulate-5' => 'in:aintToVal', - 'Put' => '5', 'Put-5' => 'in:aintToVal', - 'Get' => '5', 'Get-5' => 'in:aintToVal', - 'Alloc_mem' => '1', 'Alloc_mem-1' => 'in:aintToVal', - 'Compare_and_swap' => '6', 'Compare_and_swap-6' => 'in:aintToVal', - 'Fetch_and_op' => '5', 'Fetch_and_op-5' => 'in:aintToVal', - 'Get_accumulate' => '8', 'Get_accumulate-8' => 'in:aintToVal', - 'Rput' => '5', 'Rput-5' => 'in:aintToVal', - 'Rget' => '5', 'Rget-5' => 'in:aintToVal', - 'Raccumulate' => '5', 'Raccumulate-5' => 'in:aintToVal', - 'Rget_accumulate' => '8', 'Rget_accumulate-8' => 'in:aintToVal', - 'Win_attach' => '3', 'Win_attach-3' => 'in:aintToVal', - 'Win_allocate' => '1', 'Win_allocate-1' => 'in:aintToVal', - 'Win_allocate_shared' => '1', 'Win_allocate_shared-1' => 'in:aintToVal', - 'Win_get_name' => '2', 'Win_get_name-2' => 'out:blankpad', - 'Win_set_name' => '2', 'Win_set_name-2' => 'in:addnull', - 'Win_test' => '2', 'Win_test-2' => 'out:logical', - 'Wait' => '1:2', 'Wait-1' => 'inout:handle::MPI_Request', - 'Wait-2' => 'out:status', - 'Waitall' => '2:3', 'Waitall-2' => 'inout:handle_array:*v1:MPI_Request', - 'Waitall-3' => 'out:status_array:*v1', - 'Waitany' => '2:3:4', 'Waitany-2' => 'inout:handle_array:*v1:MPI_Request', - 'Waitany-3' => 'out:index', - 'Waitany-4' => 'out:status', - 'Waitsome' => '2:3:4:5', - 'Waitsome-2' => 'inout:handle_array:*v1:MPI_Request', - 'Waitsome-3' => 'out:fint2int', - 'Waitsome-4' => 'out:index_array:*v1:*v3', - 'Waitsome-5' => 'out:status_array:*v1:*v3', - 'Startall' => '2', - 'Startall-2' => 'in:handle_array:*v1:MPI_Request', -# File routines are separate - 'File_open' => '2:5', 'File_open-2' => 'in:addnull', - 'File_open-5' => 'out:FileToFint', - 'File_close' => '1', 'File_close-1', 'inout:FileToFint', - 'File_delete' => '1', 'File_delete-1' => 'in:addnull', - 'File_set_view' => '5', 'File_set_view-5' => 'in:addnull', - 'File_get_view' => '3:4:5', - 'File_get_view-3' => 'out:handle::MPI_Datatype', - 'File_get_view-4' => 'out:handle::MPI_Datatype', - 'File_get_view-5' => 'out:blankpad', - 'File_set_atomicity' => '2', 'File_set_atomicity-2' => 'in:logical', - 'File_get_atomicity' => '2', 'File_get_atomicity-2' => 'out:logical', - 'File_read' => '5', - 'File_read-5' => 'out:status', - 'File_read_shared' => '5', - 'File_read_shared-5' => 'out:status', - 'File_read_ordered' => '5', - 'File_read_ordered-5' => 'out:status', - 'File_read_ordered_end' => '3', - 'File_read_ordered_end-3' => 'out:status', - 'File_read_at' => '6', - 'File_read_at-6' => 'out:status', - 'File_read_all' => '5', - 'File_read_all-5' => 'out:status', - 'File_read_at_all' => '6', - 'File_read_at_all-6' => 'out:status', - 'File_read_at_all_end' => '3', - 'File_read_at_all_end-3' => 'out:status', - 'File_read_all_end' => '3', - 'File_read_all_end-3' => 'out:status', - 'File_write' => '5', - 'File_write-5' => 'out:status', - 'File_write_shared' => '5', - 'File_write_shared-5' => 'out:status', - 'File_write_ordered' => '5', - 'File_write_ordered-5' => 'out:status', - 'File_write_ordered_end' => '3', - 'File_write_ordered_end-3' => 'out:status', - 'File_write_at' => '6', - 'File_write_at-6' => 'out:status', - 'File_write_all' => '5', - 'File_write_all-5' => 'out:status', - 'File_write_at_all' => '6', - 'File_write_at_all-6' => 'out:status', - 'File_write_at_all_end' => '3', - 'File_write_at_all_end-3' => 'out:status', - 'File_write_all_end' => '3', - 'File_write_all_end-3' => 'out:status', - 'Register_datarep' => '1:2:3', 'Register_datarep-1' => 'in:addnull', - 'Register_datarep-2' => 'in:checkdatarep', - 'Register_datarep-3' => 'in:checkdatarep', -# MPI-2.2 Functions - 'Op_commutative' => '2', 'Op_commutative-2' => 'out:logical', - 'Dist_graph_create_adjacent' => '3:4:6:7:9:10', - 'Dist_graph_create_adjacent-3' => 'in:fint2int_array:*v2', - 'Dist_graph_create_adjacent-4' => 'in:unweighted:*v2', - 'Dist_graph_create_adjacent-6' => 'in:fint2int_array:*v5', - 'Dist_graph_create_adjacent-7' => 'in:unweighted:*v5', - 'Dist_graph_create_adjacent-9' => 'in:logical', - 'Dist_graph_create_adjacent-10' => 'out:handle::MPI_Comm', - 'Dist_graph_create' => '3:4:5:6:8:9', - 'Dist_graph_create-3' => 'in:fint2int_array:*v2', - 'Dist_graph_create-4' => 'in:fint2int_array:*v2', - 'Dist_graph_create-5' => 'in:fint2int_array:_sum(v4,*v2)', - 'Dist_graph_create-6' => 'in:unweighted:_ssize', - 'Dist_graph_create-8' => 'in:logical', - 'Dist_graph_create-9' => 'out:handle::MPI_Comm', - 'Dist_graph_neighbors_count' => '4', - 'Dist_graph_neighbors_count-4' => 'out:logical', - 'Dist_graph_neighbors' => '3:4:6:7', - 'Dist_graph_neighbors-3' => 'out:fint2int_array:*v2', - 'Dist_graph_neighbors-4' => 'out:unweighted:*v2', - 'Dist_graph_neighbors-6' => 'out:fint2int_array:*v5', - 'Dist_graph_neighbors-7' => 'out:unweighted:*v5', -# MPI 3.0 functions - 'Igather' => '1', 'Igather-1' => 'in:inplace', - 'Igatherv' => '1:5:6', 'Igatherv-1' => 'in:inplace', - 'Igatherv-5' => 'in:fint2int_array:_commsize(*v9)', - 'Igatherv-6' => 'in:fint2int_array:_commsize', - 'Iscatter' => '4', 'Iscatter-4' => 'in:inplace', - 'Iscatterv' => '2:3:5', - 'Iscatterv-2' => 'in:fint2int_array:_commsize(*v9)', - 'Iscatterv-3' => 'in:fint2int_array:_commsize', - 'Iscatterv-5' => 'in:inplace', - 'Iallgather' => '1', 'Iallgather-1' => 'in:inplace', - 'Iallgatherv' => '1:5:6', 'Iallgatherv-1' => 'in:inplace', - 'Iallgatherv-5' => 'in:fint2int_array:_commsize(*v8)', - 'Iallgatherv-6' => 'in:fint2int_array:_commsize', - 'Ireduce' => '1', 'Ireduce-1' => 'in:inplace', - 'Iallreduce' => '1', 'Iallreduce-1' => 'in:inplace', - 'Ireduce_scatter' => '1:3', - 'Ireduce_scatter-1' => 'in:inplace', - 'Ireduce_scatter-3' => 'in:fint2int_array:_commsize(*v6)', - 'Ireduce_scatter_block' => '1', - 'Ireduce_scatter_block-1' => 'in:inplace', - 'Iscan' => '1', 'Iscan-1' => 'in:inplace', - 'Ialltoall' => '1', - 'Ialltoall-1' => 'in:inplace', - 'Ialltoallv' => '1:2:3:6:7', - 'Ialltoallv-1' => 'in:inplace', - 'Ialltoallv-2' => 'in:fint2int_array:_commsize(*v9)', - 'Ialltoallv-3' => 'in:fint2int_array:_commsize', - 'Ialltoallv-6' => 'in:fint2int_array:_commsize', - 'Ialltoallv-7' => 'in:fint2int_array:_commsize', - 'Ialltoallw' => '1:2:3:4:6:7:8', - 'Ialltoallw-1' => 'in:inplace', - 'Ialltoallw-2' => 'in:fint2int_array:_commsize(*v9)', - 'Ialltoallw-3' => 'in:fint2int_array:_commsize', - 'Ialltoallw-6' => 'in:fint2int_array:_commsize', - 'Ialltoallw-7' => 'in:fint2int_array:_commsize', - 'Ialltoallw-4' => 'in:handle_array:_commsize:MPI_Datatype', - 'Ialltoallw-8' => 'in:handle_array:_commsize:MPI_Datatype', - 'Neighbor_allgatherv' => '5:6', - 'Neighbor_allgatherv-5' => 'in:fint2int_array:_commsize(*v8)', - 'Neighbor_allgatherv-6' => 'in:fint2int_array:_commsize', - 'Neighbor_alltoallv' => '2:3:6:7', - 'Neighbor_alltoallv-2' => 'in:fint2int_array:_commsize(*v9)', - 'Neighbor_alltoallv-3' => 'in:fint2int_array:_commsize', - 'Neighbor_alltoallv-6' => 'in:fint2int_array:_commsize', - 'Neighbor_alltoallv-7' => 'in:fint2int_array:_commsize', - 'Neighbor_alltoallw' => '2:4:6:8', - 'Neighbor_alltoallw-2' => 'in:fint2int_array:_commsize(*v9)', - 'Neighbor_alltoallw-4' => 'in:handle_array:_commsize:MPI_Datatype', - 'Neighbor_alltoallw-6' => 'in:fint2int_array:_commsize', - 'Neighbor_alltoallw-8' => 'in:handle_array:_commsize:MPI_Datatype', - 'Ineighbor_allgatherv' => '5:6', - 'Ineighbor_allgatherv-5' => 'in:fint2int_array:_commsize(*v8)', - 'Ineighbor_allgatherv-6' => 'in:fint2int_array:_commsize', - 'Ineighbor_alltoallv' => '2:3:6:7', - 'Ineighbor_alltoallv-2' => 'in:fint2int_array:_commsize(*v9)', - 'Ineighbor_alltoallv-3' => 'in:fint2int_array:_commsize', - 'Ineighbor_alltoallv-6' => 'in:fint2int_array:_commsize', - 'Ineighbor_alltoallv-7' => 'in:fint2int_array:_commsize', - 'Ineighbor_alltoallw' => '2:4:6:8', - 'Ineighbor_alltoallw-2' => 'in:fint2int_array:_commsize(*v9)', - 'Ineighbor_alltoallw-4' => 'in:handle_array:_commsize:MPI_Datatype', - 'Ineighbor_alltoallw-6' => 'in:fint2int_array:_commsize', - 'Ineighbor_alltoallw-8' => 'in:handle_array:_commsize:MPI_Datatype', - 'Type_create_hindexed_block' => '4:5', - 'Type_create_hindexed_block-4' => 'in:handle::MPI_Datatype', - 'Type_create_hindexed_block-5' => 'out:handle::MPI_Datatype', - - ); - -# -# These give special post processing after the MPI routine is called. -# The named routine is invoked with the argument number, e.g., -# &"setF90keyval"( FD, 1 ); -# -%specialPost = ( - 'Type_create_keyval' => 3, - 'Type_create_keyval-3' => 'setF90Type_keyval', - 'Comm_create_keyval' => 3, - 'Comm_create_keyval-3' => 'setF90Comm_keyval', - 'Win_create_keyval' => 3, - 'Win_create_keyval-3' => 'setF90Win_keyval', - 'Grequest_start' => 5, - 'Grequest_start-5' => 'setF77greq', - ); - -# -# Load any definition file -if ($definition_file) { - require $definition_file; -} - -$arg_string = join( ' ', @ARGV ); -if ($build_prototypes) { - open( PROTOFD, ">$prototype_header_file.new" ) || die "Cannot open $prototype_header_file.new\n"; - print PROTOFD "/*\ - * Copyright (C) by Argonne National Laboratory\ - * See COPYRIGHT in top-level directory\ - *\ - * This file is automatically generated by buildiface $arg_string\ - * DO NOT EDIT\ - */\ -/* Prototypes for Fortran Interface Functions */ -\n"; -} - -%skipBlocks = (); -&ReadAndProcessInterface( $prototype_file_b, 0 ); - -# if doing MPI2, we also need to read the MPI-2 protottypes -if ( -s "../../../mpi/romio/include/mpio.h.in" && $build_io) { - %skipBlocks = ( 'HAVE_MPI_DARRAY_SUBARRAY' => 1, - 'HAVE_MPI_INFO' => 1, - 'MPICH' => 1 ); - &ReadAndProcessInterface( "../../../mpi/romio/include/mpio.h.in", 1 ); - %skipBlocks = (); -} - -# Write a list of the routines that we've found. -if ($writeRoutineList) { - open LFD, ">mpi.dat" || die "Cannot open mpi.dat\n"; - foreach my $name (sort(keys(%mpi_routines))) { - print LFD "$name\n"; - } - close LFD; -} - -if ($is_MPI) { - # Build the special routines - &build_specials; -} -else { - for ($i=0; $i<=$#ExtraRoutines; $i++) { - $r = $ExtraRoutines[$i]; - &$r; - } -} - -if ($build_prototypes) { - close PROTOFD; - &ReplaceIfDifferent( $prototype_header_file, - $prototype_header_file . ".new" ); -} - -# -# This block can be used to create the Makefile -if ("$buildMakefile") { - open ( MAKEFD, ">Makefile_wrappers.mk.new" ) || die "Cannot create Makefile_wrappers.mk.new"; - print MAKEFD < count, output continue string and -# continue. Use print_endline to finish a line -sub print_line { - my $FD = $_[0]; - my $line = $_[1]; - my $count = $_[2]; - my $continue = $_[3]; - my $continue_len = $_[4]; - - $linelen = length( $line ); - #print "linelen = $linelen, print_line_len = $print_line_len\n"; - if ($print_line_len + $linelen > $count) { - print $FD $continue; - $print_line_len = $continue_len; - } - print $FD $line; - $print_line_len += $linelen; -} -sub print_endline { - my $FD = $_[0]; - print $FD "\n"; - $print_line_len = 0; -} - -# Print the header of the file, containing the definitions etc. -sub print_header { - my $out_prefix = shift; - my $routine_name = shift; - my $lcname = shift; - my $args = shift; - my $extra = shift; - - &print_copyright( ); - if ($extra) { - print $OUTFD $extra; - } - &print_profiling_block( $out_prefix, $routine_name, $lcname, $args ); - &print_name_map_block( $out_prefix, $routine_name, $lcname, $args ); - - my $fn = "HelperFor" . $routine_name ; - if (defined(&$fn)) { - &$fn( $OUTFD ); - } -} - -sub print_copyright { - print $OUTFD "/*\ - * Copyright (C) by Argonne National Laboratory\ - * See COPYRIGHT in top-level directory\ - *\ - * This file is automatically generated by buildiface $arg_string\ - * DO NOT EDIT\ - */\ -#include \"${header_file}\"\n\n"; -} - -# -# Print the (ugly) profiling name definition block. -# This is made more complex by the need, new with gcc 3.2, to -# generate an extern declaration of the routine *before* the pragma -# -sub print_profiling_block { - my $out_prefix = shift; - my $routine_name = shift; - my $lcname = shift; - my $args = shift; - my $ucname = uc($lcname); - my $ucprefix = uc($out_prefix); - my $lcprefix = lc($out_prefix); - - if ($do_weak) { - print $OUTFD "\ -/* Begin MPI profiling block */\ -#if defined(USE_WEAK_SYMBOLS) && !defined(USE_ONLY_MPI_NAMES) \ -#if defined(HAVE_MULTIPLE_PRAGMA_WEAK)\n"; - &print_weak_decl( $OUTFD, "${ucprefix}$ucname", $args, $lcname ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}__", $args, $lcname ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}", $args, $lcname ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}_", $args, $lcname ); - print $OUTFD "\ -#if defined(F77_NAME_UPPER) -#pragma weak ${ucprefix}$ucname = P${ucprefix}${ucname} -#pragma weak ${lcprefix}${lcname}__ = P${ucprefix}${ucname} -#pragma weak ${lcprefix}${lcname}_ = P${ucprefix}${ucname} -#pragma weak ${lcprefix}${lcname} = P${ucprefix}${ucname} -#elif defined(F77_NAME_LOWER_2USCORE) -#pragma weak ${ucprefix}$ucname = p${lcprefix}${lcname}__ -#pragma weak ${lcprefix}${lcname}__ = p${lcprefix}${lcname}__ -#pragma weak ${lcprefix}${lcname}_ = p${lcprefix}${lcname}__ -#pragma weak ${lcprefix}${lcname} = p${lcprefix}${lcname}__ -#elif defined(F77_NAME_LOWER_USCORE) -#pragma weak ${ucprefix}$ucname = p${lcprefix}${lcname}_ -#pragma weak ${lcprefix}${lcname}__ = p${lcprefix}${lcname}_ -#pragma weak ${lcprefix}${lcname}_ = p${lcprefix}${lcname}_ -#pragma weak ${lcprefix}${lcname} = p${lcprefix}${lcname}_ -#else -#pragma weak ${ucprefix}$ucname = p${lcprefix}${lcname} -#pragma weak ${lcprefix}${lcname}__ = p${lcprefix}${lcname} -#pragma weak ${lcprefix}${lcname}_ = p${lcprefix}${lcname} -#pragma weak ${lcprefix}${lcname} = p${lcprefix}${lcname} -#endif -\n\n"; - - print $OUTFD "\ -#elif defined(HAVE_PRAGMA_WEAK)\ - -#if defined(F77_NAME_UPPER)\n"; - &print_weak_decl( $OUTFD, "${ucprefix}$ucname", $args, $lcname ); - print $OUTFD "\ -#pragma weak ${ucprefix}$ucname = P${ucprefix}$ucname\ -#elif defined(F77_NAME_LOWER_2USCORE)\n"; - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}__", $args, $lcname ); - print $OUTFD "\ -#pragma weak ${lcprefix}${lcname}__ = p${lcprefix}${lcname}__\ -#elif !defined(F77_NAME_LOWER_USCORE)\n"; - &print_weak_decl( $OUTFD, "${lcprefix}$lcname", $args, $lcname ); - print $OUTFD "\ -#pragma weak ${lcprefix}$lcname = p${lcprefix}$lcname\ -#else\n"; - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}_", $args, $lcname ); - print $OUTFD "\ -#pragma weak ${lcprefix}${lcname}_ = p${lcprefix}${lcname}_\ -#endif\ -\ -#elif defined(HAVE_PRAGMA_HP_SEC_DEF)\ -#if defined(F77_NAME_UPPER)\ -#pragma _HP_SECONDARY_DEF P${ucprefix}$ucname ${ucprefix}$ucname\ -#elif defined(F77_NAME_LOWER_2USCORE)\ -#pragma _HP_SECONDARY_DEF p${lcprefix}${lcname}__ ${lcprefix}${lcname}__\ -#elif !defined(F77_NAME_LOWER_USCORE)\ -#pragma _HP_SECONDARY_DEF p${lcprefix}$lcname ${lcprefix}$lcname\ -#else\ -#pragma _HP_SECONDARY_DEF p${lcprefix}${lcname}_ ${lcprefix}${lcname}_\ -#endif\ -\ -#elif defined(HAVE_PRAGMA_CRI_DUP)\ -#if defined(F77_NAME_UPPER)\ -#pragma _CRI duplicate ${ucprefix}$ucname as P${ucprefix}$ucname\ -#elif defined(F77_NAME_LOWER_2USCORE)\ -#pragma _CRI duplicate ${lcprefix}${lcname}__ as p${lcprefix}${lcname}__\ -#elif !defined(F77_NAME_LOWER_USCORE)\ -#pragma _CRI duplicate ${lcprefix}${lcname} as p${lcprefix}${lcname}\ -#else\ -#pragma _CRI duplicate ${lcprefix}${lcname}_ as p${lcprefix}${lcname}_\ -#endif\ -\ -#elif defined(HAVE_WEAK_ATTRIBUTE) -#if defined(F77_NAME_UPPER)\n"; - &print_weak_decl( $OUTFD, "${ucprefix}$ucname", $args, $lcname, "P${ucprefix}${ucname}" ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}__", $args, $lcname, "P${ucprefix}${ucname}" ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}_", $args, $lcname, "P${ucprefix}${ucname}" ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}", $args, $lcname, "P${ucprefix}${ucname}" ); - print $OUTFD " -#elif defined(F77_NAME_LOWER_2USCORE)\n"; - &print_weak_decl( $OUTFD, "${ucprefix}$ucname", $args, $lcname, "p${lcprefix}${lcname}__" ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}__", $args, $lcname, "p${lcprefix}${lcname}__" ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}_", $args, $lcname, "p${lcprefix}${lcname}__" ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}", $args, $lcname, "p${lcprefix}${lcname}__" ); - print $OUTFD " -#elif defined(F77_NAME_LOWER_USCORE)\n"; - &print_weak_decl( $OUTFD, "${ucprefix}$ucname", $args, $lcname, "p${lcprefix}${lcname}_" ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}__", $args, $lcname, "p${lcprefix}${lcname}_" ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}_", $args, $lcname, "p${lcprefix}${lcname}_" ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}", $args, $lcname, "p${lcprefix}${lcname}_" ); - print $OUTFD " -#else\n"; - &print_weak_decl( $OUTFD, "${ucprefix}$ucname", $args, $lcname, "p${lcprefix}${lcname}" ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}__", $args, $lcname, "p${lcprefix}${lcname}" ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}_", $args, $lcname, "p${lcprefix}${lcname}" ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}", $args, $lcname, "p${lcprefix}${lcname}" ); - print $OUTFD " -#endif -#endif /* HAVE_PRAGMA_WEAK */\ -#endif /* USE_WEAK_SYMBOLS */\ -/* End MPI profiling block */\n\n"; - - &AddFwrapWeakName( $out_prefix, $lcname, $ucname, $args ); - } -} - -# -# Print the code that modifies the name -# The function prototypes must be loaded *after* the name block so that the -# name used in the function prototypes will match the one that is declared -# in this file. -sub print_name_map_block { - my $out_prefix = shift; - my $routine_name = shift; - my $lcname = shift; - my $args = shift; - my $ucname = uc($lcname); - my $lcprefix = lc($out_prefix); - my $ucprefix = uc($out_prefix); - - # This include the code to map names for the profiling interface, - # using the same macro as for the rest of the MPI code - if ($do_profiling) { - # Remove the leading MPI_ if the name has it. - if ($routine_name =~ /^$ucprefix/) { - $routine_name =~ s/^$ucprefix//; - } - print $OUTFD " -/* Map the name to the correct form */ -#ifndef MPICH_MPI_FROM_PMPI -#if defined(USE_WEAK_SYMBOLS) -#if defined(HAVE_MULTIPLE_PRAGMA_WEAK) -/* Define the weak versions of the PMPI routine*/ -#ifndef F77_NAME_UPPER\n"; - &print_weak_decl( $OUTFD, "P${ucprefix}$ucname", $args, $lcname ); - print $OUTFD "#endif\n#ifndef F77_NAME_LOWER_2USCORE\n"; - &print_weak_decl( $OUTFD, "p${lcprefix}${lcname}__", $args, $lcname ); - print $OUTFD "#endif\n#ifndef F77_NAME_LOWER_USCORE\n"; - &print_weak_decl( $OUTFD, "p${lcprefix}${lcname}_", $args, $lcname ); - print $OUTFD "#endif\n#ifndef F77_NAME_LOWER\n"; - &print_weak_decl( $OUTFD, "p${lcprefix}${lcname}", $args, $lcname ); - print $OUTFD " -#endif - -#if defined(F77_NAME_UPPER) -#pragma weak p${lcprefix}${lcname}__ = P${ucprefix}${ucname} -#pragma weak p${lcprefix}${lcname}_ = P${ucprefix}${ucname} -#pragma weak p${lcprefix}${lcname} = P${ucprefix}${ucname} -#elif defined(F77_NAME_LOWER_2USCORE) -#pragma weak P${ucprefix}$ucname = p${lcprefix}${lcname}__ -#pragma weak p${lcprefix}${lcname}_ = p${lcprefix}${lcname}__ -#pragma weak p${lcprefix}${lcname} = p${lcprefix}${lcname}__ -#elif defined(F77_NAME_LOWER_USCORE) -#pragma weak P${ucprefix}$ucname = p${lcprefix}${lcname}_ -#pragma weak p${lcprefix}${lcname}__ = p${lcprefix}${lcname}_ -#pragma weak p${lcprefix}${lcname} = p${lcprefix}${lcname}_ -#else -#pragma weak P${ucprefix}$ucname = p${lcprefix}${lcname} -#pragma weak p${lcprefix}${lcname}__ = p${lcprefix}${lcname} -#pragma weak p${lcprefix}${lcname}_ = p${lcprefix}${lcname} -#endif /* Test on name mapping */ - -#elif defined(HAVE_WEAK_ATTRIBUTE) -#if defined(F77_NAME_UPPER)\n"; - &print_weak_decl( $OUTFD, "p${lcprefix}${lcname}__", $args, $lcname, "P${ucprefix}${ucname}" ); - &print_weak_decl( $OUTFD, "p${lcprefix}${lcname}_", $args, $lcname, "P${ucprefix}${ucname}" ); - &print_weak_decl( $OUTFD, "p${lcprefix}${lcname}", $args, $lcname, "P${ucprefix}${ucname}" ); - print $OUTFD " -#elif defined(F77_NAME_LOWER_2USCORE)\n"; - &print_weak_decl( $OUTFD, "P${ucprefix}$ucname", $args, $lcname, "p${lcprefix}${lcname}__" ); - &print_weak_decl( $OUTFD, "p${lcprefix}${lcname}_", $args, $lcname, "p${lcprefix}${lcname}__" ); - &print_weak_decl( $OUTFD, "p${lcprefix}${lcname}", $args, $lcname, "p${lcprefix}${lcname}__" ); - print $OUTFD " -#elif defined(F77_NAME_LOWER_USCORE)\n"; - &print_weak_decl( $OUTFD, "P${ucprefix}$ucname", $args, $lcname, "p${lcprefix}${lcname}_" ); - &print_weak_decl( $OUTFD, "p${lcprefix}${lcname}__", $args, $lcname, "p${lcprefix}${lcname}_" ); - &print_weak_decl( $OUTFD, "p${lcprefix}${lcname}", $args, $lcname, "p${lcprefix}${lcname}_" ); - print $OUTFD " -#else\n"; - &print_weak_decl( $OUTFD, "P${ucprefix}$ucname", $args, $lcname, "p${lcprefix}${lcname}" ); - &print_weak_decl( $OUTFD, "p${lcprefix}${lcname}__", $args, $lcname, "p${lcprefix}${lcname}" ); - &print_weak_decl( $OUTFD, "p${lcprefix}${lcname}_", $args, $lcname, "p${lcprefix}${lcname}" ); - print $OUTFD " -#endif /* Test on name mapping */ -#endif /* HAVE_MULTIPLE_PRAGMA_WEAK */ -#endif /* USE_WEAK_SYMBOLS */ - -#ifdef F77_NAME_UPPER -#define ${lcprefix}${lcname}_ P${ucprefix}${ucname} -#elif defined(F77_NAME_LOWER_2USCORE) -#define ${lcprefix}${lcname}_ p${lcprefix}${lcname}__ -#elif !defined(F77_NAME_LOWER_USCORE) -#define ${lcprefix}${lcname}_ p${lcprefix}${lcname} -#else -#define ${lcprefix}${lcname}_ p${lcprefix}${lcname}_ -#endif /* Test on name mapping */ - -#ifdef F77_USE_PMPI -/* This defines the routine that we call, which must be the PMPI version - since we're renaming the Fortran entry as the pmpi version. The MPI name - must be undefined first to prevent any conflicts with previous renamings. */ -#undef ${ucprefix}${routine_name} -#define ${ucprefix}${routine_name} P${ucprefix}${routine_name} -#endif - -#else -"; - } - print $OUTFD " -#ifdef F77_NAME_UPPER -#define ${lcprefix}${lcname}_ ${ucprefix}${ucname} -#elif defined(F77_NAME_LOWER_2USCORE) -#define ${lcprefix}${lcname}_ ${lcprefix}${lcname}__ -#elif !defined(F77_NAME_LOWER_USCORE) -#define ${lcprefix}${lcname}_ ${lcprefix}${lcname} -/* Else leave name alone */ -#endif - -"; - if ($do_profiling) { - print $OUTFD " -#endif /* MPICH_MPI_FROM_PMPI */ -"; - } - if ($build_prototypes) { - print $OUTFD " -/* Prototypes for the Fortran interfaces */ -#include \"$prototype_header_file\" -"; - } -} - -# Print the arguments for the routine DEFINITION. -sub print_args { - my @parms = split(/\s*,\s*/, $_[1] ); - my $OUTFD = $_[0]; - my $count = 1; - my $last_args = ""; - my $prototype_only = $_[2]; - my $routine = $_[3]; - - # Clear the @arg_addresses and $arg_qualifiers array. - $#arg_addresses = -1; - $#arg_qualifiers = -1; - - # Special case: if the only parm is "void", remove it from the list - print STDERR "Nparms = $#parms, parms = " . join(',',@parms) . "\n" if $debug; - if ($#parms == 0 && $parms[0] eq "void") { - $#parms = -1; - } - # argsep is used to add a comma before every argument, except for the - # first - $argsep = ""; - print $OUTFD "( "; - foreach $parm (@parms) { - # Match type to replacement - print "parm = :$parm:\n" if $debug; - # Remove qualifiers from the parm - $arg_qualifiers[$count] = ""; - if ($parm =~ /^const\s+/) { - $parm =~ s/^const\s+//; - $arg_qualifiers[$count] .= "const "; - } - if ($parm =~ /^restrict\s+/) { - $parm =~ s/restrict\s+//; - $arg_qualifiers[$count] .= "restrict "; - } - # Remove arg names from array types - if ($parm =~ /(\w+)\s+(\w+)\s*\[\]/) { - # Assume that this is []; convert to - # [] - print " Removing argname $2 from parm array $parm\n" if $debug; - $parm = "$1" . "[]"; - } - # Remove arg names from pointer types - elsif ($parm =~ /(.*\*)\s+(\w+)/) { - print " Removing argname $2 from parm pointer\n" if $debug; - $parm = $1; - } - # Remove blanks from the parm - $parm =~ s/\s+//; - $arg_addresses[$count] = 0; - - # This handles routines that have special declaration requirements - # for particular arguments - if (defined($declarg{"$routine-$count"})) { - print " Using declarg{$routine-$count} for this parameter ($parm)\n" if $debug; - $parm = $declarg{"$routine-$count"}; - if ($prototype_only) { - print $OUTFD "$argsep$parm"; - } - else { - print $OUTFD "$argsep$parm v$count"; - } - } - elsif ($parm =~ /char\s*\*/ || $parm =~ /char\s*\[\s*\]/) { - # char's go out at char *v FORT_MIXED_LEN(d) - # and FORT_END_LEN(d) at the end - # (even if an array, because at the Fortran level, it - # is still a pointer to a character variable; the length - # of each entry in the array is the "d" value). - # FORT_END_LEN and FORT_MIXED_LEN contain the necessary command - # if they are prsent at all. - print " parm is a character string\n" if $debug; - if ($prototype_only) { - print $OUTFD "${argsep}char * FORT_MIXED_LEN_DECL"; - $last_args .= "FORT_END_LEN_DECL "; - } - else { - print $OUTFD "${argsep}char *v$count FORT_MIXED_LEN(d$count)"; - $last_args .= "FORT_END_LEN(d$count) "; - } - } - elsif ($parm =~/\[/) { - # Argument type is array, so we need to - # a) mark as containing a star - # b) place parameter correctly - $star_count = 1; - $arg_addresses[$count] = $star_count; - # Split into raw type and [] - # Use \S* instead of the equivalent [^\s]*. - # (\S is not-a-space) - # perl 5.8 is known to mishandle the latter, leading to - # an empty basetype - if ($parm =~ /\s*(\S*)\s*(\[\s*\])/) { - $basetype = $1; - } - else { - print STDERR "Internal error. Could not find basetype\n"; - print STDERR "This may be a bug in perl in the handling of certain expressions\n"; - } - print "\tparm $parm is array of >$basetype<\n" if $debug; - #$foundbrack = $2; - if (defined($tof77{$parm})) { - # This is a special case; the full type is defined. - # This is used, for example, for int [][3] in the - # routines that specify a range. - print "Matched to full type $parm with replacement $tof77{$parm}\n" if $debug; - # We use the replacement type - $basetype = $tof77{$parm}; - $star_count = 0; - $arg_addresses[$count] = $star_count; - } - elsif ($basetype eq "int") { - # Do nothing because the [] added to the arg below - # is all that is necessary. - $star_count = 0; - $arg_addresses[$count] = $star_count; - } - elsif (defined($tof77{"$basetype\[\]"})) { - # Use the code for handling array parameters if - # mapping code is provided. - print "Match to array type $basetype\[\]\n" if $debug; - $star_count = 0; - $arg_addresses[$count] = $star_count; - $basetype = $tof77{"$basetype\[\]"}; - } - elsif (defined($tof77{$basetype})) { - # FIXME: This code (now commented out) is not correct - print STDERR "Using fall through for $basetype in $routine\n" if $debug; -# if ($useOldCode eq "yes") { -# $nstar_before = ($basetype =~ /\*/); -# $basetype = $tof77{$basetype}; -# # The following fixes the case where the underlying type -# # is a simple int. -# if ($basetype eq "int") { -# $arg_addresses[$count] = 0; -# } -# print "\tparm has defined type of $basetype\n" if $debug; -# $nstar_after = ($basetype =~ /\*/); -# if ($nstar_before != $nstar_after) { -# $star_count++; -# } - # If we have an array, and a type mapping to fortran - # we want to simply pretend that all is well (like int - # above) - $star_count = 0; - $arg_addresses[$count] = $star_count; - } - if ($prototype_only) { - print $OUTFD "$argsep$basetype \[\]"; - } - else { - print $OUTFD "$argsep$basetype v$count\[\]"; - } - } - else { - $nstar_before = ($parm =~ /\*/); - $nstar_after = $nstar_before; - print "Nstar = $nstar_after\n" if $debug; - if (defined($tof77{$parm})) { - $parm = $tof77{$parm}; - $nstar_after = ($parm =~ /\*/); - } - $leadspace = ""; - if ($parm =~ /\w$/) { - $leadspace = " "; - } - if ($prototype_only) { - print $OUTFD "${argsep}${parm}"; - } - else { - print $OUTFD "${argsep}${parm}${leadspace}v$count"; - } - $star_count = 0; - if ($nstar_before != $nstar_after) { - $star_count = 1; - } - $arg_addresses[$count] = $star_count; - } - $count++; - $argsep = ", "; - } - # Add the new error return code if necessary - $tmpargs= $errparm; - $tmpargs =~ s/\s*//g; - if ($tmpargs ne "") { - if ($prototype_only) { - print $OUTFD "$argsep$errparmtype"; - } - else { - print $OUTFD "$argsep$errparm"; - } - } - print $OUTFD " $last_args"; - print $OUTFD ")"; -} - -# Print the arguments for the routine CALL. -# Handle the special arguments -sub print_call_args { - my @parms = split(/\s*,\s*/, $_[0] ); - my $fintFix = 0; - my $count = 1; - my $first = 1; - if (defined($_[1])) { $fintFix = 1; } - print $OUTFD "( "; - # Special case: if the only parm is "void", remove it from the list - if ($#parms == 0 && $parms[0] eq "void") { - $#parms = -1; - } - - foreach $parm (@parms) { - $parm =~ s/^const\s+//; # Remove const if present - # Remove variable name if present in an array arg - if ($parm =~ /(.*)\s+(\w+)\[\]/) { - $parm = "$1 \[\]"; - } - # Compress multiple spaces - $parm =~ s/\s\s/ /g; - if (!$first) { print $OUTFD ", "; } else { $first = 0; } - - if (defined($special_args{"${routine_name}-$count"})) { - # We must handle this argument specially - &print_special_call_arg( $routine_name, $count, $parm ); - } - elsif ($parm =~ /!/) { - # This parameter is a special case; the exclamation point - # is used to say "call with this argument as is" - $parm =~ s/!//; - print $OUTFD $parm; - } - else { - print "Processing parameter $count: $parm ($fintFix)\n" if $debug; - # Convert to/from object type as required. - #print "TMP: parm = $arg_qualifiers[$count]$parm\n"; - $fullparm="$arg_qualifiers[$count]$parm"; - print "Full param is $fullparm\n" if $debug; - if (!$fintFix && defined($argsneedcast{$fullparm})) { - $argval = "v$count"; - if ($arg_addresses[$count] > 0) { - $argval = "*$argval"; - } - $callparm = $argsneedcast{$fullparm}; - $callparm =~ s/ARG/$argval/; - print $OUTFD "$callparm"; - print "Param $parm needs cast to $callparm\n" if $debug; - } - elsif ($fintFix && $parm =~ /^\s*([\w_]+)\s*\*\s*$/) { - $parmtype = $1; - print "parm = $parm and parmtype = $parmtype\n" if $debug; - if (defined($fintToHandle{$parmtype})) { - print $OUTFD "\&l$count"; - } - else { - if ($arg_addresses[$count] > 0) { - print $OUTFD "*"; - } - print $OUTFD "v$count"; - } - } - elsif ($fintFix && defined($argsneedcast{$fullparm})) { - # We expect to have only value types here - $argval = "v$count"; - if ($arg_addresses[$count] > 0) { - $argval = "*$argval"; - } - $callparm = $argsneedcast{$fullparm}; - $callparm =~ s/ARG/$argval/; - print $OUTFD "$callparm"; - print "Param $parm needs cast to $callparm\n" if $debug; - } - else { - #print "$routine_name ( $parm )\n"; - # Since MPICH objects are ints (except for MPI_File), - # we don't need to do - # anything unless MPI_Fint and int are different. - # print STDERR "XXX $count $#arg_addresses XXX\n"; - print "Parm = :$parm:\n" if $debug; - if ($parm =~ /^MPI_File$/) { - print $OUTFD "MPI_File_f2c(*v$count)"; - } - else { - if ($parm =~ /^MPI_Aint$/) { - print STDERR "Warning: Found a cast to MPI_Aint in $routine_name\n"; - print STDERR "This usually means that a conversion from MPI_Aint* to an MPI_Aint value is missing\n"; - } - if ($arg_addresses[$count] > 0) { - print "Adding ($parm) for $parm\n" if $debug; - print $OUTFD "($parm)"; - print $OUTFD "*"; - } - print $OUTFD "v$count"; - } - } - } - $count++; - } - print $OUTFD " );\n"; -} - -# Print the option function attribute; this supports GCC, particularly -# the __atribute__ ((weak)) option. Unfortunately, the name must be -# made into a string and inserted into the attribute list. -sub print_attr { - my $OUTFD = $_[0]; - my $name = $_[1]; - if ($do_weak) { - print $OUTFD " FUNC_ATTRIBUTES($name)"; - } -} - -# -# We allow a routine to specify an alternate weak decl by name -sub set_weak_decl { - my $name = $_[0]; - my $decl = $_[1]; - my $rtype = $_[2]; - $name = lc($name); - $altweak{$name} = $decl; - $altweakrtype{$name} = $rtype; -} -sub print_weak_decl { - my $OUTFD = $_[0]; - my $name = $_[1]; - my $args = $_[2]; - my $lcname = $_[3]; - my $weak_alias = $_[4]; - - my $basename = lc($name); - $basename =~ s/_*$//; - if (defined($altweak{$basename})) { - print $OUTFD "extern FORT_DLL_SPEC $altweakrtype{$basename} FORT_CALL $name($altweak{$basename})"; - } - else { - print $OUTFD "extern FORT_DLL_SPEC $returnType FORT_CALL $name"; - &print_args( $OUTFD, $args, 1, $lcname ); - } - if (defined($weak_alias)) { - print $OUTFD " __attribute__((weak,alias(\"$weak_alias\")))"; - } - print $OUTFD ";\n"; -} -# -# -------------------------------------------------------------------------- -# Special processing -# -# Each parameter can be processed by a routine, with the suffix controlling -# the routine invoked for each step. Roughly, these are: -# -# void foo( MPI_Fint *v1, etc ) -# { -# /* Special declarations needed for the variables */ -# __decl( ) -# /* Special processing needed for in and inout variables */ -# _ftoc( ) -# /* Special processing needed for out variables that may take a null value -# E.g., converting MPI_F_STATUS_IGNORE to MPI_STATUS_IGNORE -# May also be used to allocate arrays needed for in variables -# __fnulltoc( ) -# /* Call the function. Replace special arguments with the output from */ -# __arg( ) -# /* Special post call processing (for out variables) */ -# _ctof( l$count, v$count ) /* local (C) variable name, fortran var name */ -# -# Special case: For parameters that are arrays, the size of the -# array is in $Array_size. -# The fourth argument can be used for the native type -# -# -# -------------------------------------------------------------------------- -# Buffer pointers -sub bufptr_ftoc { - my $count = $_[0]; -} -sub bufptr_in_decl { - my $count = $_[0]; -} -sub bufptr_in_arg { - my $count = $_[0]; - if ($do_bufptr) { - print $OUTFD "MPIR_F_PTR(v$count)"; - } - else { - print $OUTFD "v$count"; - } -} -# bufptr_ctof( cvar, fvar ) -sub bufptr_ctof { - my $coutvar = $_[0]; - my $outvar = $_[1]; -} -# -------------------------------------------------------------------------- -# MPI_IN_PLACE buffer pointers -sub inplace_ftoc { - my $count = $_[0]; - &specialInitStatement( $OUTFD ); - print $OUTFD " if (v$count == MPIR_F_MPI_IN_PLACE) v$count = MPI_IN_PLACE;\n"; -} -sub inplace_in_decl { - my $count = $_[0]; -} -sub inplace_in_arg { - my $count = $_[0]; - print $OUTFD "v$count"; -} -# inplace_ctof( cvar, fvar ) -sub inplace_ctof { - my $coutvar = $_[0]; - my $outvar = $_[1]; -} -# -------------------------------------------------------------------------- -# MPI_UNWEIGHTED pointers. Note that unweighted is only used to indicate -# that an array is not provided - thus, if the array is provided and MPI_Fint -# and int are not the same size, we need to include that processing as well. -sub unweighted_in_ftoc { - my $count = $_[0]; - &specialInitStatement( $OUTFD ); - if ($within_fint) { - print $OUTFD <= 0) *$outvar = *$outvar + 1;\n"; -} -sub index_out_decl { - my $count = $_[0]; - print $OUTFD " int l$count;\n"; -} -sub index_out_arg { - my $count = $_[0]; - print $OUTFD " \&l$count"; -} -# -# Index variables, but for an array. -# Array args can use the global $Array_size and $Array_typedef if necessary -sub index_array_ftoc { - my $count = $_[0]; -} -sub index_array_out_ftoc { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD " l$count = (int *)malloc($Array_size * sizeof(int));\n"; - } -} -sub index_array_ctof { - my $coutvar = $_[0]; - my $outvar = $_[1]; - my $ActSize = $Array_size; - # In the case where the input and out sizes are not the same, - # the output size is in the fourth argument. - if ($nativeType ne "") { $ActSize = $nativeType; } - if ($within_fint) { - print $OUTFD "\ - {int li; - for (li=0; li<$ActSize; li++) { - if ($coutvar\[li\] >= 0) $outvar\[li\] = (MPI_Fint)$coutvar\[li\] + 1; - } - } -"; - $clean_up .= " free( $coutvar );\n"; - } - else { - print $OUTFD "\ - {int li; - for (li=0; li<$ActSize; li++) { - if ($outvar\[li\] >= 0) $outvar\[li\] += 1; - } - } -" - } -} -sub index_array_out_decl { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD " int *l$count=0;\n"; - } -} -sub index_array_out_arg { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD "l$count"; - } - else { - print $OUTFD "v$count"; - } -} -# -------------------------------------------------------------------------- -# -# Handle variables. -# Index variables are not optional, since the values of the variable -# are changed. -sub handle_ftoc { - my $count = $_[0]; - my $parm = $_[1]; - if ($within_fint) { - my $basetype = $nativeType; - $basetype =~ s/MPI_//; - if ($basetype eq "Datatype") { $basetype = "Type"; } - print $OUTFD " l$count = MPI_".$basetype."_f2c( *v$count );\n"; - } -} -sub handle_in_ftoc { - my $count = $_[0]; - my $parm = $_[1]; - if ($within_fint) { - my $basetype = $nativeType; - $basetype =~ s/MPI_//; - if ($basetype eq "Datatype") { $basetype = "Type"; } - print $OUTFD " l$count = MPI_".$basetype."_f2c( *v$count );\n"; - } -} -sub handle_inout_ftoc { - my $count = $_[0]; - my $parm = $_[1]; - &handle_in_ftoc( $count, $parm ); -} -sub handle_out_ctof { - my $coutvar = $_[0]; - my $outvar = $_[1]; - if ($within_fint) { - print $OUTFD " if ($errparmlval==MPI_SUCCESS) *$outvar = (MPI_Fint)$coutvar;\n"; - } -} -sub handle_out_decl { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD " $nativeType l$count;\n"; - } -} -sub handle_inout_decl { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD " $nativeType l$count;\n"; - } -} -sub handle_in_decl { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD " $nativeType l$count;\n"; - } -} -sub handle_out_arg { - my $count = $_[0]; - my $parm = $_[1]; - if ($within_fint) { - print $OUTFD " \&l$count"; - } - else { - print $OUTFD "($parm)(v$count)"; - } -} -sub handle_inout_arg { - my $count = $_[0]; - my $parm = $_[1]; - &handle_out_arg( $count, $parm ); -} -sub handle_in_arg { - my $count = $_[0]; - my $parm = $_[1]; - if ($within_fint) { - print $OUTFD "l$count"; - } - else { - print $OUTFD "($parm)(*v$count)"; - } -} -# -# Index variables, but for an array. -# Array args can use the global $Array_size and $Array_typedef if necessary -sub handle_array_in_ftoc { - my $count = $_[0]; - if ($within_fint) { - my $basetype = $nativeType; - $basetype =~ s/MPI_//; - if ($basetype eq "Datatype") { $basetype = "Type"; } - my $convfunc = "MPI_" . $basetype . "_f2c"; - my $cvar = "l$count"; - my $fvar = "v$count"; - my $asize = $Array_size; - if ($Array_size =~ /_commsize/) { - $asize = "_csize"; - if ($Array_size =~ /_commsize\((.*)\)/) { - my $comm = $1; - print $OUTFD " - if (_csize < 0) { - PMPI_Comm_size( $comm, &_csize ); - }\n"; - } - } - print $OUTFD "\ - /* handle_array_ftoc( $count ); */ - {int li; - $cvar = ($nativeType *)malloc($asize * sizeof($nativeType)); - for (li=0; li<$asize; li++) { - $cvar\[li\] = $convfunc( $fvar\[li\] ); - } - } -"; - $clean_up .= " free( $cvar );\n"; - } - else { - } -} -sub handle_array_inout_ftoc { - my $count = $_[0]; - &handle_array_in_ftoc( $count ); -} - -sub handle_array_out_ftoc { - my $count = $_[0]; - if ($within_fint) { - my $basetype = $nativeType; - $basetype =~ s/MPI_//; - if ($basetype eq "Datatype") { $basetype = "Type"; } - my $convfunc = "MPI_" . $basetype . "_f2c"; - my $cvar = "l$count"; - my $fvar = "v$count"; - my $asize = $Array_size; - if ($Array_size =~ /_commsize/) { - $asize = "_csize"; - if ($Array_size =~ /_commsize\((.*)\)/) { - my $comm = $1; - print $OUTFD " - if (_csize < 0) { - PMPI_Comm_size( $comm, &_csize ); - }\n"; - } - } - print $OUTFD "\ - /* handle_array_ftoc( $count ); */ - $cvar = ($nativeType *)malloc($asize * sizeof($nativeType)); -"; - $clean_up .= " free( $cvar );\n"; - } - else { - } -} - -sub handle_array_inout_ctof { - my $coutvar = $_[0]; - my $outvar = $_[1]; - &handle_array_ctof( $coutvar, $outvar ); -} - -# Make sure that there is no output processing (other than to free the -# array) -sub handle_array_in_ctof { - my $coutvar = $_[0]; - my $outvar = $_[1]; - #&handle_array_ctof( $coutvar, $outvar ); -} - -sub handle_array_ctof { - my $coutvar = $_[0]; - my $outvar = $_[1]; - if ($within_fint) { - my $basetype = $nativeType; - $basetype =~ s/MPI_//; - if ($basetype eq "Datatype") { $basetype = "Type"; } - my $convfunc = "MPI_" . $basetype . "_c2f"; - my $asize = $Array_size; - if ($Array_size =~ /_commsize/) { - $asize = "_csize"; - } - print $OUTFD "\ - /* handle_array_ctof( $coutvar, $outvar ) */ - {int li; - for (li=0; li<$asize; li++) { - $outvar\[li\] = $convfunc( $coutvar\[li\] ); - } - } -"; - } - else { - } -} - -sub handle_array_out_decl { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD " $nativeType *l$count=0;\n"; - if ($Array_size =~ /_commsize\(/) { - print $OUTFD " int _csize=-1;\n"; - } - } -} -sub handle_array_inout_decl { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD " $nativeType *l$count=0;\n"; - if ($Array_size =~ /_commsize\(/) { - print $OUTFD " int _csize=-1;\n"; - } - } -} -sub handle_array_in_decl { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD " $nativeType *l$count=0;\n"; - if ($Array_size =~ /_commsize\(/) { - print $OUTFD " int _csize=-1;\n"; - } - } -} -sub handle_array_out_arg { - my $count = $_[0]; - my $parm = $_[1]; - if ($within_fint) { - print $OUTFD "l$count"; - } - else { - if ($parm =~ /\[\]/) { - $parm =~ s/\[\]/\*/g; - } - print $OUTFD "($parm)(v$count)"; - } -} -sub handle_array_inout_arg { - my $count = $_[0]; - my $parm = $_[1]; - if ($within_fint) { - print $OUTFD "l$count"; - } - else { - if ($parm =~ /\[\]/) { - $parm =~ s/\[\]/\*/g; - } - print $OUTFD "($parm)(v$count)"; - } -} -sub handle_array_in_arg { - my $count = $_[0]; - my $parm = $_[1]; - if ($within_fint) { - print $OUTFD "l$count"; - } - else { - if ($parm =~ /\[\]/) { - $parm =~ s/\[\]/\*/g; - } - print $OUTFD "($parm)(v$count)"; - } -} -# -------------------------------------------------------------------------- -# -# Address and attribute handling -# Note that this construction can lead to compiler warnings on systems -# where an address is larger than an MPI_Fint. This is correct; these -# routines are for the MPI-1 routines that use an MPI_Fint where the -# C code uses a void * (MPI_Aint in MPI-2). -# Instead of using MPI_Aint, we use intptr_t. This allows the MPI -# implementation to set MPI_Aint to be *larger* than a pointer-sized-int, -# which is needed (as a temporary workaround) on systems like Blue Gene, which -# have 4 byte pointers but file systems that need 8 byte datatypes (not just -# offsets). -# A possible extension is to provide an error warning (much as -# MPI_Address does) when the attribute value loses bits when assigned into -# the MPI_Fint. -#in:addrint -#out:attrint:4 -sub addrint_ftoc { - my $count = $_[0]; -} -sub addrint_in_decl { -} -sub addrint_in_arg { - my $count = $_[0]; - print $OUTFD "(void *)((intptr_t)*(MPI_Fint *)v$count)"; -} - -sub attrint_ctof { - my $fvar = $_[0]; - my $cvar = $_[1]; - my $flagarg = 4; # get from option - # The strange cast is due to the following: - # The MPICH attribute code returns an int in the void *. In - # little-endian, a cast to an int is all that's necessary. In - # big-endian, to interpret the first sizeof(int) bytes as an int, - # we must first cast as pointer to int, then dereference it. - # This has been patched to use a consistent int choice with - # what is used in comm_get_attr.c - print $OUTFD " - if ((int)*ierr || !l$flagarg) { - *(MPI_Fint*)$cvar = 0; - } - else { - *(MPI_Fint*)$cvar = (MPI_Fint)(intptr_t)attr$cvar; - }\n"; -} - -sub attrint_out_decl { - my $count = $_[0]; - print $OUTFD " void *attrv$count;\n"; - # Unfortunately, the common attribute routines in comm_get_attr.c - # assume that the output is a pointer variable; this isn't really the - # case when MPIR_ATTR_INT is the attribute type. Instead of providing - # the correct type (see the code that handles the MPIR_ATTR_INT case), - # we'll need to extract the int out of this void pointer. - # print $OUTFD " int attrv$count;\n"; -} - -sub attrint_out_arg { - my $count = $_[0]; - print $OUTFD "&attrv$count"; -} -# -------------------------------------------------------------------------- -# Address and attribute handling -# This version of attrint uses Aints instead of ints, and is appropriate -# for the MPI-2 attribute caching functions -# -# FIXME: This is no longer correct if the BlueGene definition for MPI_Aint -# is used (as an integer big enough for an MPI_Offset and larger than -# sizeof(void*), since this stores the result into the argument. The -# definitions here and in the MPICH attribute code must match. -#in:addraint -#out:attraint:4 -sub addraint_ftoc { - my $count = $_[0]; -} -sub addraint_in_decl { -} -sub addraint_in_arg { - my $count = $_[0]; - print $OUTFD "(void *)(*(MPI_Aint *)v$count)"; -} - -sub attraint_ctof { - my $fvar = $_[0]; - my $cvar = $_[1]; - my $flagarg = 4; # get from option - print $OUTFD " - if ((int)*ierr || !l$flagarg) { - *(MPI_Aint*)$cvar = 0; - } - else { - *(MPI_Aint*)$cvar = (MPI_Aint)attr$cvar; - }\n"; -} - -sub attraint_out_decl { - my $count = $_[0]; - print $OUTFD " void *attrv$count;\n"; -} - -sub attraint_out_arg { - my $count = $_[0]; - print $OUTFD "&attrv$count"; -} -# -------------------------------------------------------------------------- -# -# Buffer Address output handling (Buffer_detach) -#out:bufaddr -sub bufaddr_ftoc { -} -sub bufaddr_out_decl { - my $count =$_[0]; - print $OUTFD " void *t$count = v$count;\n"; -} -sub bufaddr_out_arg { - my $count = $_[0]; - print $OUTFD "&t$count"; -} - -sub bufaddr_ctof { - my $fvar = $_[0]; - my $cvar = $_[1]; -} -# -------------------------------------------------------------------------- -# -# Handle MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE -sub status_out_fnulltoc { - my $count = $_[0]; - # Cast MPI_STATUS_IGNORE back to an MPI_Fint (we'll re-cast it back - # to (MPI_Status *) in the call to the C version of the routine) - # MPI 3.0, page 30 states that the MPI_ERROR field is not modified - # unless there is an MPI_ERR_IN_STATUS_RETURN. This means that in the - # case where we must pass a temp for the status value, we must - # copy the ERROR value to ensure that it is not changed. Another - # option would be to specialize this update for the err_in_status - # return, but this is easier for now. - &specialInitStatement( $OUTFD ); - if ($within_fint) { - print $OUTFD "\ - if (v$count == MPI_F_STATUS_IGNORE) { l$count = MPI_STATUS_IGNORE; } - else { l$count->MPI_ERROR = (int)(v$count\[4\]); }\n"; - } - else { - print $OUTFD "\ - if (v$count == MPI_F_STATUS_IGNORE) { v$count = (MPI_Fint*)MPI_STATUS_IGNORE; }\n"; - } -} - -sub status_in_ftoc { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD " MPI_Status_f2c( v$count, l$count );\n"; - } -} - -sub status_out_ctof { - my $coutvar = $_[0]; - my $outvar = $_[1]; - if ($within_fint) { - my $testFlag = ""; - if (defined($condition) && $condition ne "") { - $testFlag = "$condition && " - } - print $OUTFD -" if ($testFlag$coutvar != MPI_STATUS_IGNORE && $errparmlval == MPI_SUCCESS) { - MPI_Status_c2f($coutvar,$outvar); - }\n" - } -} -sub status_in_decl { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD " MPI_Status vtmp$count, *l$count = &vtmp$count;\n"; - } -} -sub status_out_decl { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD " MPI_Status vtmp$count, *l$count = &vtmp$count;\n"; - } -} -sub status_out_arg { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD "l$count"; - } - else { - print $OUTFD "(MPI_Status *)v$count"; - } -} -sub status_in_arg { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD "l$count"; - } - else { - print $OUTFD "(MPI_Status *)(v$count)"; - } -} -# -------------------------------------------------------------------------- -# -# Handle MPI_ERRCODES_IGNORE -sub errcodesignore_out_fnulltoc { - my $count = $_[0]; - &specialInitStatement( $OUTFD ); - my $varname = "v"; - my $varcast = "(MPI_Fint *)"; - if ($within_fint) { $varname = "l"; $varcast = ""; } - print $OUTFD "\ - if ((MPI_Fint*)v$count == MPI_F_ERRCODES_IGNORE) { $varname$count = ${varcast}MPI_ERRCODES_IGNORE; }\n"; -} -sub errcodesignore_out_ftoc { - my $count = $_[0]; - if ($within_fint) { - my $coutvar = "l$count"; - my $outvar = "v$count"; - my $asize = $Array_size; - if ($Array_size =~ /_sum/) { - $asize = "_esize"; - if ($Array_size =~ /_sum\((.*),(.*)\)/) { - my $array = $1; - my $arrLen = $2; - print $OUTFD " - if (_esize < 0 && $coutvar != MPI_ERRCODES_IGNORE) { - int li; - _esize = 0; - for (li=0; li<$arrLen; li++) { _esize += (int)$array\[li\];} - }\n"; - } - } - print $OUTFD "\ - if ($coutvar != MPI_ERRCODES_IGNORE) { - $coutvar = (int *)malloc($asize * sizeof(int)); - } -"; - $clean_up .= " free( $coutvar );\n"; - } -} - -sub errcodesignore_out_ctof { - my $coutvar = $_[0]; - my $outvar = $_[1]; - - if ($within_fint) { - $asize = $Array_size; - if ($Array_size =~ /_sum/) { - $asize = "_esize"; - } - print $OUTFD -" if ($coutvar != MPI_ERRCODES_IGNORE) { - int li; - for (li=0; li<$asize; li++) { - $outvar\[li\] = (int)$coutvar\[li\]; - } - }\n"; - $clean_up .= " free($coutvar);\n"; - } -} -sub errcodesignore_out_decl { - my $count = $_[0]; - if ($within_fint) { - if ($Array_size =~ /_sum\(/) { - print $OUTFD " int _esize=-1;\n"; - } - print $OUTFD " int *l$count=0;\n"; - } -} -sub errcodesignore_out_arg { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD "l$count"; - } - else { - print $OUTFD "(int *)v$count"; - } -} -# -------------------------------------------------------------------------- -# -# Arrays of status -# Array args can use the global $Array_size and $Array_typedef if necessary -sub status_array_out_fnulltoc { - my $count = $_[0]; - &specialInitStatement( $OUTFD ); - my $varname = "v"; - my $varcast = "(MPI_Fint *)"; - if ($within_fint) { $varname = "l"; $varcast = ""; } - print $OUTFD "\ - if (v$count == MPI_F_STATUSES_IGNORE) { $varname$count = ${varcast}MPI_STATUSES_IGNORE; }\n"; -} -sub status_array_out_ftoc { - my $count = $_[0]; - - # See discussion of status_out_ftoc - unfortunately, we need to - # copy *just* the MPI_ERROR field - if ($within_fint) { - print $OUTFD "\ - if (l$count != MPI_STATUSES_IGNORE) { - int li; - l$count = (MPI_Status*)malloc($Array_size * sizeof(MPI_Status)); - for (li=0; li<$Array_size; li++) - l$count\[li].MPI_ERROR = ((MPI_Status*)(void*)v$count)[li].MPI_ERROR; - }\n"; - } -} - -sub status_array_ctof { - my $coutvar = $_[0]; - my $outvar = $_[1]; - - if ($within_fint) { - my $ActSize = $Array_size; - if (defined($nativeType) && $nativeType ne "") { - $ActSize = $nativeType; - } - my $testFlag = ""; - if (defined($condition) && $condition ne "") { - $testFlag = "$condition && " - } - print $OUTFD -" if ($testFlag$coutvar != MPI_STATUSES_IGNORE) { - int li; - for (li=0; li<$ActSize; li++) { - MPI_Status_c2f($coutvar+li,$outvar+li*MPI_F_STATUS_SIZE); - } - }\n"; - $clean_up .= " if ($coutvar != MPI_STATUSES_IGNORE) { free($coutvar); }\n"; - } -} -sub status_array_out_decl { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD " MPI_Status *l$count=0;\n"; - } -} -sub status_array_out_arg { - my $count = $_[0]; - - if ($within_fint) { - print $OUTFD "l$count"; - } - else { - print $OUTFD "(MPI_Status *)v$count"; - } -} -# -------------------------------------------------------------------------- -# aintToint -sub aintToInt_ctof { - my $coutvar = $_[0]; - my $outvar = $_[1]; - print $OUTFD " if ($errparmlval == MPI_SUCCESS) *$outvar = (MPI_Fint)($coutvar);\n"; -} -sub aintToInt_out_decl { - my $count = $_[0]; - print $OUTFD " MPI_Aint l$count;\n"; -} -sub aintToInt_out_arg { - my $count = $_[0]; - print $OUTFD "\&l$count"; -} -# -------------------------------------------------------------------------- -# aintToVal - Convert address of Aint to value -sub aintToVal_ftoc { - my $count = $_[0]; - my $coutvar = "l$count"; - my $outvar = "v$count"; -} -sub aintToVal_in_decl { - my $count = $_[0]; -} -sub aintToVal_in_arg { - my $count = $_[0]; - print $OUTFD "*v$count"; -} -# -------------------------------------------------------------------------- -# Fint to/from int variables -# In the case where an int is an fint, this code just generates the default -# output. If $within_fint is true (within special processing for fint to/from -# int handling), then the necessary code is generated. -sub fint2int_ftoc { - my $count = $_[0]; - if ($within_fint) { - } -} -sub fint2int_ctof { - my $coutvar = $_[0]; - my $outvar = $_[1]; - if ($within_fint) { - print $OUTFD " if ($errparmlval == MPI_SUCCESS) *$outvar = (MPI_Fint)$coutvar;\n"; - } -} -sub fint2int_out_decl { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD " int l$count;\n"; - } -} -sub fint2int_out_arg { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD " \&l$count"; - } - else { - print $OUTFD " v$count"; - } -} -sub fint2int_inout_decl { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD " int l$count = (int)*v$count;\n"; - } -} -sub fint2int_inout_arg { - fint2int_out_arg( $_[0] ); -} -# -# Array args can use the global $Array_size and $Array_typedef if necessary -sub fint2int_array_in_ftoc { - my $count = $_[0]; - if ($within_fint) { - my $coutvar = "l$count"; - my $outvar = "v$count"; - my $asize = $Array_size; - if ($Array_size =~ /_commsize/) { - $asize = "_csize"; - if ($Array_size =~ /_commsize\((.*)\)/) { - my $comm = $1; - print $OUTFD " - if (_csize < 0) { - PMPI_Comm_size( (MPI_Comm)$comm, &_csize ); - }\n"; - } - } - elsif ($Array_size =~ /_sum/) { - $asize = "_ssize"; - if ($Array_size =~ /_sum\((.*),(.*)\)/) { - my $array = $1, $arraylen = $2; - print $OUTFD " - if (_ssize < 0) { - int li; - _ssize = 0; - for (li=0; li<$arraylen; li++) _ssize += (int)$array\[li\]; - }\n"; - } - } - elsif ($Array_size =~ /_cartdim/) { - $asize = "_ctsize"; - print $OUTFD "\ - if (_ctsize < 0) { PMPI_Cartdim_get( (MPI_Comm)*v1, &_ctsize ); }\n"; - } - # Check for the special case of an array index element as the - # array size - my $extraCondition = ""; - if ($asize =~ /\[(.*)\]/) { - $extraCondition = "($1 >= 0) && "; - } - print $OUTFD "\ - if ($extraCondition$asize > 0) {int li; - $coutvar = (int *)malloc($asize * sizeof(int)); - for (li=0; li<$asize; li++) { - $coutvar\[li\] = (int)$outvar\[li\]; - } - } -"; - $clean_up .= " free( $coutvar );\n"; - } -} -sub fint2int_array_inout_ftoc { - my $count = $_[0]; - &fint2int_array_in_ftoc( $count ); -} -sub fint2int_array_out_ftoc { - my $count = $_[0]; - if ($within_fint) { - my $coutvar = "l$count"; - my $outvar = "v$count"; - my $asize = $Array_size; - if ($Array_size =~ /_commsize/) { - $asize = "_csize"; - if ($Array_size =~ /_commsize\((.*)\)/) { - my $comm = $1; - print $OUTFD " - if (_csize < 0) { - PMPI_Comm_size( $comm, &_csize ); - }\n"; - } - } - elsif ($Array_size eq "_cartdim") { - $asize = "_ctsize"; - print $OUTFD " PMPI_Cartdim_get( (MPI_Comm)*v1, &_ctsize );\n"; - } - - print $OUTFD "\ - $coutvar = (int *)malloc($asize * sizeof(int)); -"; - $clean_up .= " free( $coutvar );\n"; - } -} - -sub fint2int_array_out_ctof { - my $coutvar = $_[0]; - my $outvar = $_[1]; - if ($within_fint) { - my $asize = $Array_size; - if ($Array_size =~ /_commsize/) { - $asize = "_csize"; - if ($Array_size =~ /_commsize\((.*)\)/) { - my $comm = $1; - print $OUTFD " - if (_csize < 0) { - PMPI_Comm_size( (MPI_Comm)$comm, &_csize ); - }\n"; - } - } - print $OUTFD "\ - if ($errparmlval == MPI_SUCCESS) {int li; - for (li=0; li<$asize; li++) { - $outvar\[li\] = (int)$coutvar\[li\]; - } - }\n"; - } -} -sub fint2int_array_out_decl { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD " int *l$count=0;\n"; - if ($Array_size =~ /_commsize\(/) { - print $OUTFD " int _csize=-1;\n"; - } - elsif ($Array_size =~ /_sum\(/) { - print $OUTFD " int _ssize=-1;\n"; - } - elsif ($Array_size eq "_cartdim") { - print $OUTFD " int _ctsize=-1;\n"; - } - } -} -sub fint2int_array_in_decl { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD " int *l$count=0;\n"; - if ($Array_size =~ /_commsize\(/) { - print $OUTFD " int _csize=-1;\n"; - } - elsif ($Array_size =~ /_sum\(/) { - print $OUTFD " int _ssize=-1;\n"; - } - elsif ($Array_size eq "_cartdim") { - print $OUTFD " int _ctsize=-1;\n"; - } - } -} -sub fint2int_array_out_arg { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD "l$count"; - } - else { - print $OUTFD "v$count"; - } -} -sub fint2int_array_in_arg { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD "l$count"; - } - else { - print $OUTFD "v$count"; - } -} -sub fint2int_array_inout_decl { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD " int *l$count=0;\n"; - if ($Array_size =~ /_commsize\(/) { - print $OUTFD " int _csize=-1;\n"; - } - elsif ($Array_size =~ /_sum\(/) { - print $OUTFD " int _ssize=-1;\n"; - } - } -} -sub fint2int_array_inout_arg { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD "l$count"; - } - else { - print $OUTFD "v$count"; - } -} -# --- -# This is a special version of the fint2int array processing that -# skips if MPI_IN_PLACE selected for v1 (we assume v1 for now) -# Array args can use the global $Array_size and $Array_typedef if necessary -sub fint2intinplace_array_in_ftoc { - my $count = $_[0]; - if ($within_fint) { - my $coutvar = "l$count"; - my $outvar = "v$count"; - my $asize = $Array_size; - if ($Array_size =~ /_commsize/) { - $asize = "_csize"; - if ($Array_size =~ /_commsize\((.*)\)/) { - my $comm = $1; - print $OUTFD " - if (_csize < 0) { - PMPI_Comm_size( (MPI_Comm)$comm, &_csize ); - }\n"; - } - } - elsif ($Array_size =~ /_sum/) { - $asize = "_ssize"; - if ($Array_size =~ /_sum\((.*),(.*)\)/) { - my $array = $1, $arraylen = $2; - print $OUTFD " - if (_ssize < 0) { - int li; - _ssize = 0; - for (li=0; li<$arraylen; li++) _ssize += (int)$array\[li\]; - }\n"; - } - } - elsif ($Array_size =~ /_cartdim/) { - $asize = "_ctsize"; - print $OUTFD "\ - if (_ctsize < 0) { PMPI_Cartdim_get( (MPI_Comm)*v1, &_ctsize ); }\n"; - } - # Check for the special case of an array index element as the - # array size - my $extraCondition = ""; - if ($asize =~ /\[(.*)\]/) { - $extraCondition = "($1 >= 0) && "; - } - print $OUTFD "\ - if ($extraCondition$asize > 0 && v1 != MPI_IN_PLACE) {int li; - $coutvar = (int *)malloc($asize * sizeof(int)); - for (li=0; li<$asize; li++) { - $coutvar\[li\] = (int)$outvar\[li\]; - } - } -"; - $clean_up .= " free( $coutvar );\n"; - } -} -sub fint2intinplace_array_in_decl { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD " int *l$count=0;\n"; - if ($Array_size =~ /_commsize\(/) { - print $OUTFD " int _csize=-1;\n"; - } - elsif ($Array_size =~ /_sum\(/) { - print $OUTFD " int _ssize=-1;\n"; - } - elsif ($Array_size eq "_cartdim") { - print $OUTFD " int _ctsize=-1;\n"; - } - } -} -sub fint2intinplace_array_in_arg { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD "l$count"; - } - else { - print $OUTFD "v$count"; - } -} -# -# This is a special version for the range include/exclude arguments, -# which have a C type of int [][3]. This eliminates a warning message -# that may sometimes be issued by the compiler. -# Array args can use the global $Array_size and $Array_typedef if necessary -sub fint2int_rangearray_in_ftoc { - my $count = $_[0]; - if ($within_fint) { - my $coutvar = "l$count"; - my $outvar = "v$count"; - my $asize = $Array_size; - - # Check for the special case of an array index element as the - # array size - my $extraCondition = ""; - if ($asize =~ /\[(.*)\]/) { - $extraCondition = "($1 >= 0) && "; - } - print $OUTFD "\ - if ($extraCondition$asize > 0) {int li; - $coutvar = (int *)malloc($asize * sizeof(int)); - for (li=0; li<$asize; li++) { - $coutvar\[li\] = (int)$outvar\[li\]; - } - } -"; - $clean_up .= " free( $coutvar );\n"; - } -} -sub fint2int_rangearray_in_decl { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD " int *l$count=0;\n"; - } -} -sub fint2int_rangearray_in_arg { - my $count = $_[0]; - if ($within_fint) { - print $OUTFD "(int (*)[3]) l$count"; - } - else { - print $OUTFD "(int (*)[3]) v$count"; - } -} - - -# --------------------------------------------------------------------------- -# This is the routine that handles the post-call processing -sub print_post_call { - my $routine_name = $_[0]; - my $args = $_[1]; - if (defined($special_args{$routine_name})) { - # Erg. Special processing - foreach my $count (split(/:/,$special_args{$routine_name})) { - $rule = $special_args{"${routine_name}-$count"}; - ($direction,$method,$Array_size,$nativeType,$condition) = - split(/:/,$rule); - print STDERR "$routine_name: dir = $direction, method = $method\n" if $debug; - # FIXME: Sometimes the "inout" and "out" directions need - # different processing (no data available for just the out) - $processing_in_routine = "${method}_in_ctof"; - $processing_inout_routine = "${method}_inout_ctof"; - $processing_out_routine = "${method}_out_ctof"; - $processing_routine = "${method}_${direction}_ctof"; - # Prefer a specific choice matching the direction - if (defined(&$processing_routine)) { - &$processing_routine( "l$count", "v$count" ); - } - elsif ($direction eq "inout" && - defined(&$processing_out_routine)) { - &$processing_out_routine( "l$count", "v$count" ); - } - else { - $processing_routine = "${method}_ctof"; - if (defined(&$processing_routine)) { - &$processing_routine( "l$count", "v$count" ); - } - elsif ($direction ne "in") { - print STDERR "Missing $processing_routine for $routine_name\n"; - } - } - } - # Cleanup must happen after all ctof processing - if ($clean_up ne "") { - print $OUTFD $clean_up; - $clean_up = ""; - } - } - - # Handle here any special post-only calls - if (defined($specialPost{$routine_name})) { - my $argnum = $specialPost{$routine_name}; - my $postRoutine = $specialPost{"$routine_name-$argnum"}; - &$postRoutine( $OUTFD, $argnum ); - } -} -# -# --------------------------------------------------------------------------- -# -# Blankpad strings -# This is complicated by the fact that the Fortran strings do not contain -# null terminators and the MPI definitions of string lengths, such as -# MPI_MAX_PORT_NAME, are one smaller in Fortran than in C (see 4.12.9 -# in the MPI-2 specification). Because of this, we need to allocate a -# temporary that is one longer on -sub blankpad_out_decl { - my $count = $_[0]; - print $OUTFD " char *p$count;\n"; -} -sub blankpad_out_arg { - my $count = $_[0]; - print $OUTFD "p$count"; -} -sub blankpad_out_ftoc { - my $count = $_[0]; - - # Allocate space to hold the C version of the output - $strlen = "d$count"; - print $OUTFD " p$count = (char *)malloc($strlen + 1);\n"; -} -sub blankpad_ctof { - my $coutvar = $_[0]; - my $outvar = $_[1]; - - # find the null character. Replace with blanks from there to the - # end of the string. The declared length is given by a variable - # whose name is derived from outvar - $strlen = $outvar; - $strlen =~ s/^v/d/; - my $cvar = $outvar; - $cvar =~ s/^v/p/; - # Only execute this code if there was no error - print $OUTFD "\ - if (!$errparmrval) { - MPIR_fort_copy_str_from_c($outvar, $strlen, $cvar); - } -"; - $clean_up .= " free( $cvar );\n"; -} -# -# Blankpad strings if a flag is true (for info_get and info_get_string) -# This is complicated by the fact that the Fortran strings do not contain -# null terminators and the MPI definitions of string lengths, such as -# MPI_MAX_PORT_NAME, are one smaller in Fortran than in C (see 4.12.9 -# in the MPI-2 specification). Because of this, we need to allocate a -# temporary that is one longer on -sub blankpadonflag_out_decl { - my $count = $_[0]; - print $OUTFD " char *p$count;\n"; -} -sub blankpadonflag_out_arg { - my $count = $_[0]; - print $OUTFD "p$count"; -} -sub blankpadonflag_out_ftoc { - my $count = $_[0]; - - # Allocate space to hold the C version of the output - $strlen = "d$count"; - print $OUTFD " p$count = (char *)malloc($strlen + 1);\n"; -} -sub blankpadonflag_ctof { - my $coutvar = $_[0]; - my $outvar = $_[1]; - - # find the null character. Replace with blanks from there to the - # end of the string. The declared length is given by a variable - # whose name is derived from outvar - $strlen = $outvar; - $strlen =~ s/^v/d/; - my $cvar = $outvar; - $cvar =~ s/^v/p/; - # Only execute this code if there was no error - print $OUTFD "\ - if ($Array_size && !$errparmrval) {char *p = $outvar, *pc=$cvar; - while (*pc) {*p++ = *pc++;} - while ((p-$outvar) < $strlen) { *p++ = ' '; } - } -"; - $clean_up .= " free( $cvar );\n"; -} - -# --------------------------------------------------------------------------- -# Add 1 before the call and subtract 1 after the call if a value is positive. -# This function is required for MPI_Info_get_string() -sub addsubone_inout_decl { - my $count = $_[0]; - print $OUTFD " int p$count, x$count;\n"; -} -sub addsubone_inout_ftoc { - my $count = $_[0]; - print $OUTFD "\n"; - print $OUTFD " x$count = *v$count;\n"; - print $OUTFD " p$count = (x$count == 0) ? 0 : (x$count + 1);\n"; -} -sub addsubone_inout_arg { - my $count = $_[0]; - print $OUTFD "&p$count"; -} -sub addsubone_inout_ctof { - my $count = $_[0]; - my $pvar = $count; - $pvar =~ s/^l/p/; - my $vvar = $count; - $vvar =~ s/^l/v/; - print $OUTFD " *$vvar = (MPI_Fint)(($pvar == 0) ? 0 : ($pvar - 1));\n"; -} - -# --------------------------------------------------------------------------- -# Add null to input strings -# We must make a copy -sub addnull_in_decl { - my $count = $_[0]; - print $OUTFD " char *p$count;\n"; -} -sub addnull_in_arg { - my $count = $_[0]; - print $OUTFD "p$count"; -} -sub addnull_ftoc { - my $count = $_[0]; - - print $OUTFD " p$count = MPIR_fort_dup_str(v$count, d$count);\n"; - $clean_up .= " free( p$count );\n"; -} -# ---------------------------------------------------------------------------- -# Add null to input strings, also trim all LEADING and trailing blanks. -# This is required by Info_set (but not explicitly for the other -# routines). -# We must make a copy -sub addnullandtrim_in_decl { - my $count = $_[0]; - print $OUTFD " char *p$count;\n"; -} -sub addnullandtrim_in_arg { - my $count = $_[0]; - print $OUTFD "p$count"; -} -sub addnullandtrim_ftoc { - my $count = $_[0]; - - print $OUTFD " p$count = MPIR_fort_dup_str(v$count, d$count);\n"; - $clean_up .= " free( p$count );\n"; -} - -# ---------------------------------------------------------------------------- -# Add null to arrays of input strings -# We must make a copy -# chararray is used ONLY in comm_spawn -sub chararray_in_decl { - my $count = $_[0]; - print $OUTFD " char **p$count;\n"; -} -sub chararray_in_arg { - my $count = $_[0]; - print $OUTFD "p$count"; -} -sub chararray_ftoc { - my $count = $_[0]; - - my $asize = 0; - if ($Array_size) { - $asize = $Array_size; - } - print $OUTFD " if (v$count == MPI_F_ARGV_NULL) {\n"; - print $OUTFD " p$count = MPI_ARGV_NULL;\n"; - print $OUTFD " } else {\n"; - print $OUTFD " p$count = MPIR_fort_dup_str_array(v$count, d$count, d$count, $asize);\n"; - print $OUTFD " }\n"; - - $clean_up .= " if (v$count != MPI_F_ARGV_NULL) { - MPIR_fort_free_str_array(p$count); - }\n"; -} - -# Add null to 2-dimensional arrays of input strings. Used only -# by comm_spawn_multiple -# FIXME : THIS CODE IS NOT CORRECT YET -# Note the special handling of MPI_ARGVS_NULL -sub chararray2_in_decl { - my $count = $_[0]; - print $OUTFD " char ***p$count=0;\n"; -} -sub chararray2_in_arg { - my $count = $_[0]; - print $OUTFD "p$count"; -} -sub chararray2_ftoc { - my $count = $_[0]; - - if ($Array_size eq "") { - print STDERR "A leading array size is required for 2-d Character arrays\n"; - return 1; - } - - print $OUTFD " if (v$count == MPI_F_ARGVS_NULL) {\n"; - print $OUTFD " p$count = MPI_ARGVS_NULL;\n"; - print $OUTFD " } else {\n"; - print $OUTFD " p$count = MPIR_fort_dup_str_2d_array(v$count, d$count, $Array_size);\n"; - print $OUTFD " }\n"; - - $clean_up .= " if (v$count != MPI_F_ARGVS_NULL) { - MPIR_fort_free_str_2d_array(p$count, $Array_size); - }\n"; -} - -# --------------------------------------------------------------------------- -# Convert from an int array to an Aint array for routines taking an Aint as -# input -sub intToAintArr_in_decl { - my $count = $_[0]; - print $OUTFD " MPI_Aint *l$count;\n"; -} -sub intToAintArr_ftoc { - my $count = $_[0]; - # FIXME: aint could be *smaller* than fint! (needs fixing elsewhere?) - if ($within_fint) { - print $OUTFD " -#ifdef HAVE_AINT_DIFFERENT_THAN_FINT -"; - } - else { - print $OUTFD " -#ifdef HAVE_AINT_LARGER_THAN_FINT -"; - } - print $OUTFD " - if ($Array_size > 0) { - int li; - l$count = (MPI_Aint *)malloc($Array_size * sizeof(MPI_Aint)); - for (li=0; li<$Array_size; li++) - l$count\[li\] = v$count\[li\]; - } - else l$count = 0; -#else - l$count = v$count; -#endif\n"; -} -sub intToAintArr_in_arg { - my $count = $_[0]; - print $OUTFD "l$count"; -} -# This routine is invoked even for the in case (to free the result) -sub intToAintArr_in_ctof { - my $lname = $_[0]; - my $vname = $_[1]; - print $OUTFD " -#ifdef HAVE_AINT_LARGER_THAN_FINT - free($lname); -#endif\n"; -} -# --------------------------------------------------------------------------- -# Convert from an int to an Aint for routines taking an Aint as -# input -sub intToAint_in_decl { - my $count = $_[0]; - print $OUTFD " MPI_Aint l$count;\n"; -} -# In the in case, this is a no-op -sub intToAint_ctof { -} -sub intToAint_in_ftoc { - my $count = $_[0]; - print $OUTFD " l$count = (MPI_Aint)*v$count;\n"; -} -sub intToAint_in_arg { - my $count = $_[0]; - print $OUTFD "l$count"; -} - -# --------------------------------------------------------------------------- -# Convert from an FILE to a fortran int -# (output). -# -- temp -sub FileToFint_inout_decl { - my $count = $_[0]; - print $OUTFD " MPI_File l$count = MPI_File_f2c(*v$count);\n"; -} -sub FileToFint_inout_arg { - my $count = $_[0]; - print $OUTFD "&l$count"; -} -# -- end temp - -sub FileToFint_out_decl { - my $count = $_[0]; - print $OUTFD " MPI_File l$count;\n"; -} -sub FileToFint_ctof { - my $lvar = $_[0]; - my $gvar = $_[1]; - print $OUTFD " *$gvar = MPI_File_c2f($lvar);\n"; -} -sub FileToFint_out_arg { - my $count = $_[0]; - print $OUTFD "&l$count"; -} -# --------------------------------------------------------------------------- -# Check for the null datarep functions -sub checkdatarep_in_decl { - my $count = $_[0]; -} -sub checkdatarep_in_arg { - my $count = $_[0]; - print $OUTFD "v$count"; -} -sub checkdatarep_ftoc { - my $count = $_[0]; - - # Check to see if the pointer is the same as the null function - # We do something ugly here: we exploit the fact that we know which is - # the first argument that needs this definition - print $OUTFD "\ - if (v$count == (MPI_Datarep_conversion_function *)mpi_conversion_fn_null_){ - v$count = 0; - }\n"; -} -# --------------------------------------------------------------------------- -# Special post processing for some routines -sub setF90Type_keyval { - my $FD = $_[0]; - my $argnum = $_[1]; - - my $argname = "*v$argnum"; - if ($within_fint) { $argname = "l$argnum"; } - print $FD "\ - if (*ierr == MPI_SUCCESS) { - MPII_Keyval_set_f90_proxy( (int)$argname ); - }\n"; -} -sub setF90Comm_keyval { - my $FD = $_[0]; - my $argnum = $_[1]; - - my $argname = "*v$argnum"; - if ($within_fint) { $argname = "l$argnum"; } - print $FD "\ - if (*ierr == MPI_SUCCESS) { - MPII_Keyval_set_f90_proxy( (int)$argname ); - }\n"; -} -sub setF90Win_keyval { - my $FD = $_[0]; - my $argnum = $_[1]; +# This file builds mpif.h from mpi.h.in - my $argname = "*v$argnum"; - if ($within_fint) { $argname = "l$argnum"; } - print $FD "\ - if (*ierr == MPI_SUCCESS) { - MPII_Keyval_set_f90_proxy( (int)$argname ); - }\n"; -} -sub setF77greq { - my $FD = $_[0]; - my $argnum = $_[1]; - my $argname = "*v$argnum"; - if ($within_fint) { $argname = "l$argnum"; } - - print $FD "\ - if (*ierr == MPI_SUCCESS) { - MPII_Grequest_set_lang_f77( $argname ); - }\n"; -} +use warnings; +# Setup global variables -# --------------------------------------------------------------------------- -# This routine handles the special arguments in the *call* -sub print_special_call_arg { - my $routine_name = $_[0]; - my $count = $_[1]; - my $parm = $_[2]; +$build_io = 1; +$write_mpif = 1; - $rule = $special_args{"${routine_name}-$count"}; - ($direction,$method,$Array_size,$nativeType,$condition) = split(/:/,$rule); +$debug = 0; - $processing_routine = "${method}_${direction}_arg"; - &$processing_routine( $count, $parm ); -} +#feature variables +our $prototype_file_a = "../../../include/mpi.h.in"; -# This routine prints any declarations that are needed -sub print_special_decls { - my $routine_name = $_[0]; +# Global hashes used for definitions and to record the locations of the +# definitions. +%mpidef = (); +%mpidefFile = (); - if ($returnErrval) { - print $OUTFD " int $errparmrval;\n"; +# Process arguments +# +# Args +# -feature={logical,fint,subdecls,weak,bufptr}, separated by :, value given +# by =on or =off, eg +# -feature=logical=on:fint=off +# The feature names mean: +# logical - Fortran logicals are converted to/from C +# fint - Fortran integers and C ints are different size (not implemented) +# subdecls - Declarations for PC-Fortran compilers added +# weak - Use weak symbols +# bufptr - Check for MPI_BOTTOM as a special address. This is +# not needed if a POINTER declaration is available. +foreach $_ (@ARGV) { + if (/-infile=(.*)/) { + # Special arg to help with debugging + $prototype_file_a = $1; + $write_mpif = 0; } - if (defined($special_args{$routine_name})) { - print STDOUT "Special args for $routine_name\n" if $debug; - # First do the declarations - foreach my $count (split(/:/,$special_args{$routine_name})) { - $rule = $special_args{"${routine_name}-$count"}; - if (!defined($rule)) { - print STDERR "${routine_name}-$count has no value!\n"; - } - print STDOUT "Rules is $rule \n" if $debug; - ($direction,$method,$Array_size,$nativeType,$condition) = - split(/:/,$rule); - # Sanity check: method and direction must be nonnull - if ($method eq "" || $direction eq "") { - print STDERR "Error in special args for argument number $count of $routine_name\n"; - last; - } - $processing_routine = "${method}_${direction}_decl"; - &$processing_routine( $count ); - } + elsif (/-noromio/) { $build_io = 0; } + elsif (/-debug/) { + $debug = 1; } - if (defined($special_args{$routine_name})) { - # Then do the precall steps - foreach my $count (split(/:/,$special_args{$routine_name})) { - $rule = $special_args{"${routine_name}-$count"}; - ($direction,$method,$Array_size,$nativeType,$condition) = - split(/:/,$rule); - $processing_routine = "${method}_${direction}_fnulltoc"; - if (defined(&$processing_routine)) { - &$processing_routine( $count ); - } - if ($direction eq "in") { - $processing_routine = "${method}_ftoc"; - $processing_in_routine = "${method}_in_ftoc"; - if (defined(&$processing_in_routine)) { - &$processing_in_routine( $count ); - } - else { - &$processing_routine( $count ); - } - } + elsif (/-feature=(.*)/) { + foreach $feature (split(/:/,$1)) { + print STDERR "Processing feature $feature\n" if $debug; + # Feature values are foo=on,off + ($name,$value) = split(/=/,$feature); + # Default if feature is selected is to enable it. + if (!defined($value)) { $value = 1; } else { - $processing_routine = "${method}_out_ftoc"; - $processing_inout_routine = "${method}_inout_ftoc"; - if ($direction eq "inout" && - defined(&$processing_inout_routine)) { - &$processing_inout_routine( $count ); - } - elsif (defined(&$processing_routine)) { - # Use for both out and inout - &$processing_routine( $count ); - } + if ($value eq "on") { $value = 1; } + elsif ($value eq "off") { $value = 0; } } + # Set the variable based on the string + $varname = "do_$name"; + $$varname = $value; } } + elsif (/deffile=(.*)/) { + $definition_file = $1; + } + else { + print STDERR "Unrecognized argument $_\n"; + } } +# +# Load any definition file +if ($definition_file) { + require $definition_file; +} + +$arg_string = join( ' ', @ARGV ); + + # # -------------------------------------------------------------------------- # Create mpif.h.in from mpi.h @@ -3857,434 +426,6 @@ if ($write_mpif) { &ReplaceIfDifferent( "mpif.h.in", "mpif.h.in.new" ); } # if write_mpif -# -# Look through $args for parameter names (foo\s+name) -# and remove them -sub clean_args { - my $newargs = ""; - my $comma = ""; - for $parm (split(',',$args)) { - # Remove any leading or trailing spaces - $parm =~ s/^\s*//; - $parm =~ s/\s*$//; - # Handle parameters with parameter names - # First if handles "int foo", second handles "int *foo" - if ( ($parm =~ /^([A-Za-z0-9_]+)\s+[A-Za-z0-9_]+$/) ) { - $parm = $1; - } - elsif ( ($parm =~ /([A-Za-z0-9_]+\s*\*)\s*[A-Za-z0-9_]+$/) ) { - $parm = $1; - } - $newargs .= "$comma$parm"; - $comma = ","; - } - print STDERR "$newargs\n" if $debug; - $args = $newargs; -} - -# print_type_decl( $FD, $lcname ) - -sub print_routine_type_decl { - my $OUTFD = shift; - my $out_prefix = shift; - my $lcname = shift; - # The name "FORT_DLL_SPEC" may be use to tell the compiler that - # - if ($do_subdecls) { - print $OUTFD "FORT_DLL_SPEC $returnType FORT_CALL "; - } - else { - print $OUTFD "$returnType "; - } - print $OUTFD "${out_prefix}${lcname}_ "; -} - -# -# Build the special routines -sub build_specials { - my $filename = ""; - my $out_prefix = $out_prefixes[0]; # realistically, always "mpi_" - - # The init routine contains some configure-time values. - # We may not want to do this if we are supporting multiple - # Fortran compilers with different values for Fortran .TRUE. and - # .FALSE., but to get started, this is easiest. - $OUTFD = "INITFFD"; - $filename = "initf.c"; - open( $OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n"; - $files[$#files+1] = $filename; - &print_header( "mpi_", "MPI_Init", "init", "" ); - - &print_routine_type_decl( $OUTFD, $out_prefix, "init" ); - $args = ""; - &print_args( $OUTFD, $args, 0, "init" ); - # If an attribute can be added before the code, then do that here. - # Gcc only allows attributes on the prototypes, not the function - # definitions - print $OUTFD "{\n"; - # See the discussion on MPIR_F_NeedInit at the head of this file - print $OUTFD " mpirinitf_(); MPIR_F_NeedInit = 0;\n"; - print $OUTFD " *ierr = MPI_Init( 0, 0 );\n"; - # Still to do: - # Initialize the Fortran versions of the predefined keyvals. - # Find the value of MPI_BOTTOM. - # Call a Fortran routine that calls a C routine that is passed - # MPI_BOTTOM from the common block. - # - print $OUTFD "}\n"; - close ($OUTFD); - &ReplaceIfDifferent( $filename, $filename . ".new" ); - &AddPrototype( $out_prefix, "init", $args ); - - $OUTFD = "INITFFD"; - $filename = "initthreadf.c"; - open( $OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n"; - $files[$#files+1] = $filename; - $args = "int, int *"; - &print_header( "mpi_", "MPI_Init_thread", "init_thread", $args ); - - &print_routine_type_decl( $OUTFD, $out_prefix, "init_thread" ); - &print_args( $OUTFD, $args, 0, "init_thread" ); - print $OUTFD "{\n"; - if ($do_fint) { - print $OUTFD "\ -#ifndef HAVE_FINT_IS_INT - int l2; - mpirinitf_(); MPIR_F_NeedInit = 0; - *ierr = MPI_Init_thread( 0, 0, (int)*v1, &l2 ); - *v2 = (MPI_Fint)l2; -#else -"; - } - # See the discussion on MPIR_F_NeedInit at the head of this file - print $OUTFD " mpirinitf_(); MPIR_F_NeedInit = 0;\n"; - print $OUTFD " *ierr = MPI_Init_thread( 0, 0, (int)*v1, v2 );\n"; - if ($do_fint) { - print $OUTFD "#endif\n"; - } - print $OUTFD "}\n"; - close ($OUTFD); - &ReplaceIfDifferent( $filename, $filename . ".new" ); - &AddPrototype( $out_prefix, "init_thread", $args ); - - # MPI_Pcontrol does not have the ierror argument. - $OUTFD = "PCONTROLFFD"; - $filename = "pcontrolf.c"; - open( $OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n"; - $files[$#files+1] = $filename; - $returnType = "void"; - &set_weak_decl( "MPI_Pcontrol", "MPI_Fint *", "void" ); - &set_weak_decl( "PMPI_Pcontrol", "MPI_Fint *", "void" ); - &print_header( "mpi_", "MPI_Pcontrol", "pcontrol", ""); - &print_routine_type_decl( $OUTFD, $out_prefix, "pcontrol" ); - print $OUTFD "(MPI_Fint *v1)\n"; - print $OUTFD "{\n"; - print $OUTFD " MPI_Pcontrol( (int)*v1 );\n"; - print $OUTFD "}\n"; - close ($OUTFD); - &ReplaceIfDifferent( $filename, $filename . ".new" ); - if ($build_prototypes) { - print PROTOFD "extern "; - &print_routine_type_decl( PROTOFD, $out_prefix, "pcontrol" ); - print PROTOFD "( MPI_Fint * )"; - &print_attr( PROTOFD, $out_prefix."pcontrol_" ); - print PROTOFD ";\n"; - } - - $OUTFD = "ADDRESSFFD"; - $filename = "addressf.c"; - open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n"; - $files[$#files+1] = $filename; - $args = "void *, int *"; - &print_header( "mpi_", "MPI_Address", "address", $args ); - # Add the definitions needed for error reporting - # (We could use mpiimpl.h, but mpir_err.h should be sufficient) - print $OUTFD "#include \"mpir_err.h\"\n"; - print $OUTFD "#include \n"; - &print_routine_type_decl( $OUTFD, $out_prefix, "address" ); - &print_args( $OUTFD, $args, 0, "address" ); - #&print_attr; - print $OUTFD "{ - MPI_Aint a, b; - *ierr = MPI_Address( v1, &a );\n"; - &specialInitStatement( $OUTFD ); - print $OUTFD "\ - b = a; - *v2 = (MPI_Fint)( b ); -#ifdef HAVE_AINT_LARGER_THAN_FINT - /* Check for truncation */ - if ((MPI_Aint)*v2 - b != 0) { - *ierr = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, - \"MPI_Address\", __LINE__, MPI_ERR_ARG, \"**inttoosmall\", 0 ); - (void)MPIR_Err_return_comm( 0, \"MPI_Address\", *ierr ); - } -#endif -}\n"; - close ($OUTFD); - &ReplaceIfDifferent( $filename, $filename . ".new" ); - &AddPrototype( $out_prefix, "address", $args ); - - $OUTFD = "GETADDRESSFFD"; - $filename = "getaddressf.c"; - open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n"; - $files[$#files+1] = $filename; - $args = "void *, MPI_FAintp"; - &print_header( "mpi_", "MPI_Get_address", "get_address", $args ); - # Add the definitions needed for error reporting - # (We could use mpiimpl.h, but mpir_err.h should be sufficient) - print $OUTFD "#include \"mpir_err.h\"\n"; - print $OUTFD "#include \n"; - &print_routine_type_decl( $OUTFD, $out_prefix, "get_address" ); - &print_args( $OUTFD, $args, 0, "get_address" ); - #&print_attr; - print $OUTFD "{ - MPI_Aint a; - *ierr = MPI_Get_address( v1, &a );\n"; - &specialInitStatement( $OUTFD ); - print $OUTFD "\ - *v2 = a; -}\n"; - close ($OUTFD); - &ReplaceIfDifferent( $filename, $filename . ".new" ); - &AddPrototype( $out_prefix, "get_address", $args ); - - $OUTFD = "WTIMEFD"; - $filename = "wtimef.c"; - open( $OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n"; - $files[$#files+1] = $filename; - $returnType = "double"; - &set_weak_decl( "MPI_Wtime", "void", "double" ); - &set_weak_decl( "PMPI_Wtime", "void", "double" ); - &print_header( "mpi_", "MPI_Wtime", "wtime", "" ); - print $OUTFD "#include \"mpichconf.h\"\n"; - &print_routine_type_decl( $OUTFD, $out_prefix, "wtime" ); - print $OUTFD "( void ) "; - #&print_attr; - print $OUTFD "{\n"; - print $OUTFD "return MPI_Wtime();\n"; - print $OUTFD "}\n"; - close ($OUTFD); - &ReplaceIfDifferent( $filename, $filename . ".new" ); - - if ($build_prototypes) { - print PROTOFD "extern "; - &print_routine_type_decl( PROTOFD, $out_prefix, "wtime" ); - print PROTOFD "( void )"; - &print_attr( PROTOFD, $out_prefix."wtime_" ); - print PROTOFD ";\n"; - } - $returnType = "void"; - - $OUTFD = "WTICKFD"; - $filename = "wtickf.c"; - open( $OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n"; - $files[$#files+1] = $filename; - $returnType = "double"; - &set_weak_decl( "MPI_Wtick", "void", "double" ); - &set_weak_decl( "PMPI_Wtick", "void", "double" ); - &print_header( "mpi_", "MPI_Wtick", "wtick", "" ); - print $OUTFD "#include \"mpichconf.h\"\n"; - &print_routine_type_decl( $OUTFD, $out_prefix, "wtick" ); - print $OUTFD "( void ) "; - #&print_attr; - print $OUTFD "{\n"; - print $OUTFD "return MPI_Wtick();\n"; - print $OUTFD "}\n"; - close ($OUTFD); - &ReplaceIfDifferent( $filename, $filename . ".new" ); - - if ($build_prototypes) { - print PROTOFD "extern "; - &print_routine_type_decl( PROTOFD, $out_prefix, "wtick" ); - print PROTOFD "( void )"; - &print_attr( PROTOFD, $out_prefix."wtick_" ); - print PROTOFD ";\n"; - } - $returnType = "void"; - - # MPI_Aint_add/diff do not have the ierror argument. - $OUTFD = "AINTADD"; - $filename = "aint_addf.c"; - open( $OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n"; - $files[$#files+1] = $filename; - $returnType = "MPI_Aint"; - &set_weak_decl( "MPI_Aint_add", "MPI_Aint *, MPI_Aint *", "MPI_Aint" ); - &set_weak_decl( "PMPI_Aint_add", "MPI_Aint *, MPI_Aint *", "MPI_Aint" ); - &print_header( "mpi_", "MPI_Aint_add", "aint_add", "MPI_Aint *, MPI_Aint *"); - &print_routine_type_decl( $OUTFD, "mpi_", "aint_add" ); - print $OUTFD "(MPI_Aint *base, MPI_Aint *disp)\n"; - print $OUTFD "{\n"; - print $OUTFD " return MPI_Aint_add(*base, *disp);\n"; - print $OUTFD "}\n"; - close ($OUTFD); - &ReplaceIfDifferent( $filename, $filename . ".new" ); - if ($build_prototypes) { - print PROTOFD "extern "; - &print_routine_type_decl( PROTOFD, "mpi_", "aint_add" ); - print PROTOFD "( MPI_Aint *, MPI_Aint * )"; - &print_attr( PROTOFD, "mpi_"."aint_add_" ); - print PROTOFD ";\n"; - } - $returnType = "void"; - - $OUTFD = "AINTDIFF"; - $filename = "aint_difff.c"; - open( $OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n"; - $files[$#files+1] = $filename; - $returnType = "MPI_Aint"; - &set_weak_decl( "MPI_Aint_diff", "MPI_Aint *, MPI_Aint *", "MPI_Aint" ); - &set_weak_decl( "PMPI_Aint_diff", "MPI_Aint *, MPI_Aint *", "MPI_Aint" ); - &print_header( "mpi_", "MPI_Aint_diff", "aint_diff", "MPI_Aint *, MPI_Aint *"); - &print_routine_type_decl( $OUTFD, "mpi_", "aint_diff" ); - print $OUTFD "(MPI_Aint *addr1, MPI_Aint *addr2)\n"; - print $OUTFD "{\n"; - print $OUTFD " return MPI_Aint_diff(*addr1, *addr2);\n"; - print $OUTFD "}\n"; - close ($OUTFD); - &ReplaceIfDifferent( $filename, $filename . ".new" ); - if ($build_prototypes) { - print PROTOFD "extern "; - &print_routine_type_decl( PROTOFD, "mpi_", "aint_diff" ); - print PROTOFD "( MPI_Aint *, MPI_Aint * )"; - &print_attr( PROTOFD, "mpi_"."aint_diff_" ); - print PROTOFD ";\n"; - } - $returnType = "void"; - - $OUTFD = "KEYVALCREATEF"; - $filename = "keyval_createf.c"; - open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n"; - $files[$#files+1] = $filename; - $args = "MPI_Copy_function , MPI_Delete_function , int *, void *"; - &print_header( "mpi_", "MPI_Keyval_create", "keyval_create", $args ); - print $OUTFD " -#ifndef MPICH_MPI_FROM_PMPI -#undef MPI_Comm_create_keyval -#define MPI_Comm_create_keyval PMPI_Comm_create_keyval -#endif -"; - - &print_routine_type_decl( $OUTFD, $out_prefix, "keyval_create" ); - &print_args( $OUTFD, $args, 0, "keyval_create" ); - #&print_attr; - print $OUTFD "{ - int l3; - *ierr = MPI_Comm_create_keyval( v1, v2, &l3, v4 ); - if (!*ierr) { - *v3 = l3; - MPII_Keyval_set_f90_proxy((int)*v3); - } -}\n"; - close ($OUTFD); - &ReplaceIfDifferent( $filename, $filename . ".new" ); - &AddPrototype( $out_prefix, "keyval_create", $args ); - - # Default attribute functions. - # We must create separate functions since we cannot rely on - # using a preprocessor to alias the names. - # OPTION: we could use weak symbols where available to - # reduce the number of files. - $OUTFD = "DUPFN"; - $filename = "dup_fnf.c"; - open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n"; - $files[$#files+1] = $filename; - $args = "MPI_Fint *, MPI_Fint *, void *, void **, void **, MPI_Fint *"; - &print_header( "mpi_", "mpi_dup_fn", "dup_fn", $args ); - &print_routine_type_decl( $OUTFD, $out_prefix, "dup_fn" ); - &print_args( $OUTFD, $args, 0, "dup_fn" ); - #&print_attr; - print $OUTFD "{ - *v5 = *v4; - *v6 = MPII_TO_FLOG(1); - *ierr = MPI_SUCCESS; -}\n"; - close ($OUTFD); - &ReplaceIfDifferent( $filename, $filename . ".new" ); - &AddPrototype( $out_prefix, "dup_fn", $args ); - - $OUTFD = "NULLDELFN"; - $filename = "null_del_fnf.c"; - open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n"; - $files[$#files+1] = $filename; - $args = "MPI_Fint *, MPI_Fint *, void *, void *"; - &print_header( "mpi_", "mpi_null_delete_fn", "null_delete_fn", $args ); - &print_routine_type_decl( $OUTFD, $out_prefix, "null_delete_fn" ); - &print_args( $OUTFD, $args, 0, "null_delete_fn" ); - #&print_attr; - print $OUTFD "{ - *ierr = MPI_SUCCESS; -}\n"; - close ($OUTFD); - &ReplaceIfDifferent( $filename, $filename . ".new" ); - &AddPrototype( $out_prefix, "null_delete_fn", $args ); - - $OUTFD = "NULLCOPYFN"; - $filename = "null_copy_fnf.c"; - open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n"; - $files[$#files+1] = $filename; - $args = "MPI_Fint *, MPI_Fint *, void *, void *, void *, int *"; - &print_header( "mpi_", "mpi_null_copy_fn", "null_copy_fn", $args ); - &print_routine_type_decl( $OUTFD, $out_prefix, "null_copy_fn" ); - &print_args( $OUTFD, $args, 0, "null_copy_fn" ); - print $OUTFD "{ - *ierr = MPI_SUCCESS; - *v6 = MPII_TO_FLOG(0); -}\n"; - close ($OUTFD); - &ReplaceIfDifferent( $filename, $filename . ".new" ); - &AddPrototype( $out_prefix, "null_copy_fn", $args ); - - &WriteAttrDefaults( "comm_" ); - &WriteAttrDefaults( "win_" ); - &WriteAttrDefaults( "type_" ); - - # Datarep conversion function - # This is a special case. We need to define this function - # but it should never be called (we convert a reference to it - # to a reference to null, which is how the C version of this - # routine is defined. -# -# This is now part of the register_datarep function -# $OUTFD = "NULLCONVERSIONFN"; -# $filename = "null_conv_fnf.c"; -# $returnType = "int"; -# open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n"; -# $files[$#files+1] = $filename; -# $args = "void *, MPI_Fint *, MPI_Fint *, void *, MPI_Offset *, MPI_Aint *, MPI_Fint *"; -# &print_header( "mpi_", "mpi_conversion_fn_null", "conversion_fn_null", $args, -# "#ifdef MPI_CONVERSION_FN_NULL\n#undef MPI_CONVERSION_FN_NULL\n#endif\n" ); -# &print_routine_type_decl( $OUTFD, "conversion_fn_null" ); -# &print_args( $OUTFD, $args, 0, "conversion_fn_null" ); -# # This is tricky; we don't want to call this function at all -# # FIXME -# print $OUTFD "\n{\n return MPI_SUCCESS;\n}\n"; -# close ($OUTFD); -# &ReplaceIfDifferent( $filename, $filename . ".new" ); -# &AddPrototype( $out_prefix, "conversion_fn_null", $args ); - - - my $uc_prefix = uc($out_prefix); - - $OUTFD = "INFOCRENV"; - $filename = "infocrenv.c"; - open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n"; - $files[$#files+1] = $filename; - &print_header( $out_prefix, "MPI_Info_create_env", "info_create_env", "MPI_Fint *" ); - - &print_routine_type_decl( $OUTFD, $out_prefix, "info_create_env" ); - $args = "MPI_Fint * v1"; - &print_args( $OUTFD, $args, 0, "info_create_env" ); - # If an attribute can be added before the code, then do that here. - # Gcc only allows attributes on the prototypes, not the function - # definitions - print $OUTFD "{\n"; - print $OUTFD " *ierr = ${uc_prefix}Info_create_env( 0, 0, (MPI_Info *)(v1) );\n"; - print $OUTFD "}\n"; - close ($OUTFD); - &ReplaceIfDifferent( $filename, $filename . ".new" ); - &AddPrototype( $out_prefix, "info_create_env", $args ); -} - sub print_mpif_int { my $key = $_[0]; my $value = $mpidef{$key}; @@ -4344,228 +485,6 @@ sub print_mpif_int { print MPIFFD " PARAMETER ($key=$value)\n"; } -# Change the non-zero addressed F77/90 MPI_BOTTOM to C's MPI_BOTTOM, which -# in MPICH is (void*)0. Note that MPI_BOTTOM can only appear at choice -# buffer positions. For simplicity, we treat all void * parameters as -# possible choice buffers. It is a little bit overkilling, but never -# hurts, since if in the user's Fortran source code MPI_BOTTOM is passed -# to a non-choice buffer parameter, either the program is already wrong, -# or the parameter is non-significant. -# -# To make this adjustment work, MPI_Get_Address, MPI_Address should return -# address as if MPI_BOTTOM was at address zero. -# -# See discussion of the MPI_BOTTOM problem on p.652 of MPI-3.0 - -sub adjust_mpi_bottom { - my $OUTFD = $_[0]; - my @params = split(/\s*,\s*/, $_[1]); - my $count = 1; - foreach my $param (@params) { - if ($param =~ /void.*\*/) { - printf $OUTFD " if (v$count == MPIR_F_MPI_BOTTOM) v$count = MPI_BOTTOM;\n"; - } - $count++; - } -} - -sub ReadAndProcessInterface { - my $prototype_file = $_[0]; - my $protectMPIO = $_[1]; # Wrap MPI-IO routines in ifdefs MPI_MODE_RDONLY - my $linecount = 0; - my $newfilename = ""; - my $filename = ""; - open( FD, "<$prototype_file" ) || die "Cannot open $prototype_file\n"; - - # Skip to prototypes - while () { - $linecount ++; - if ( /\/\*\s*Begin Prototypes/ ) { last; } - } - - # Read each one - while () { - $linecount ++; - print $_ if $debug; - # In some packages (not MPI but in Parallel netCDF) not all prototypes - # have Fortran equivalents. The following lets us skip over them - # (MPI, as of MPI 3, has the MPI_T routines, which do not have - # Fortran interfaces) - if (/\/\*\s*Begin Skip Prototypes/) { - while () { - $linecount++; - if (/\/\*\s*End Skip Prototypes/) { last; } - } - } - if (/\/\*\s*End Prototypes/) { last; } - - # We should also skip #ifndef xxx, for some xxx. - if (/^#\s*ifndef\s+(\w*)/) { - $ndefname = $1; - if (defined($skipBlocks{$ndefname})) { - &SkipCPPIfdef( FD ); - } - } - # Remove any comments; check for problems - $origline = $_; - while (/(.*)\/\*(.*?)\*\/(.*)/) { - my $removed = $2; - $_ = $1.$3; - if ($2 =~ /\/\*/) { - print STDERR "Error in processing comment within interface file $prototype_file in line $origline"; - } - } - - PREFIX: - foreach my $i (0 .. $#routine_prefixes) { - my $routine_prefix = $routine_prefixes[$i]; - my $out_prefix = $out_prefixes[$i]; - if (/^int\s+$routine_prefix($routine_pattern)\s*\((.*)/) { - $routine_name = $1; - $args = $2; - while (! ($args =~ /;/)) { - $args .= ; - $linecount++; - } - $args =~ s/MPICH_ATTR[A-Z_]*\([^)]*\)//g; - $args =~ s/MPICH_API_PUBLIC//g; - $args =~ s/ROMIO_API_PUBLIC//g; - $args =~ s/\)\s*;//g; - $args =~ s/[\r\n]*//g; - $args =~ s/const\s//g; - # remove qualifiers from args - ### TEMP - REMEMBER const because we may need it later - #$args =~ s/\s*const\s+//g; - # Convert MPIO_Request to MPI_Request (temporary) - # $args =~ s/MPIO_Request/MPI_Request/g; - - ### TEMP: REMOVED const - #$args =~ s/const\s*//g; - # Get the name of the Fortran routine (without the prefix). - # Normally, the name is just the lower-case version, but - # some libraries (such as NetCDF) use "real" in Fortran - # where C uses "float". - $lcname = lc($routine_name); - if (defined($CtoFName{$lcname})) { - $lcname = $CtoFName{$lcname}; - } - # Eventually, we'll create a new file here. - # For C++, we may create similar files by looking up - # the corresponding routines. - if (defined($special_routines{$routine_name})) { - print "Skipping $routine_name\n" if $debug; - } - else { - # Check for duplicates in the list of routines - if (defined($mpi_routines{$routine_name})) { - my $found = ""; - if (defined($mpiRoutinesFile{$routine_name})) { - my $location = $mpiRoutinesFile{$routine_name}; - $found = "previous prototoype found in $location\n"; - } - print STDERR "Duplicate prototypes for $routine_name in $prototype_file:$linecount\n$found"; - next; - } - # Clear variables - &clean_args; - $mpi_routines{$routine_name} = $args; - $mpiRoutinesFile{$routine_name} = "$prototype_file:$linecount"; - - $clean_up = ""; - if ($buildfiles) { - if (defined($name_map{$lcname})) { - $filename = $name_map{$lcname} . "f.c"; - } - else { - $filename = $lcname . "f.c"; - } - $OUTFD = OUTPUTFILED; # Needed for pre 5.6 versions of perl - $newfilename = $filename . ".new"; - open ($OUTFD, ">$newfilename" ) || die "Cannot open $newfilename\n"; - # Add the name to the list of files" - $files[$#files+1] = $filename; - } - else { - $OUTFD = STDOUT; - } - &print_header( $out_prefix, $routine_name, $lcname, $args ); - if ($do_subdecls) { - print $OUTFD "FORT_DLL_SPEC $returnType FORT_CALL "; - } - else { - print $OUTFD "$returnType "; - } - print $OUTFD "${out_prefix}${lcname}_ "; - # Print args not only prints the arguments but fills the - # array @arg_addresses to indicate the number of dereference - # operations are needed to recover the original value (since - # all Fortran parameters are passed either by value-result or - # by reference, many value parameters in the C calls are - # replaced by reference parameters in the Fortran interface. - print "Printing arguments for $routine_prefix${lcname}_\n" if $debug; - &print_args( $OUTFD, $args, 0, $lcname ); - - #&print_attr; - print $OUTFD "{\n"; - &specialInitClear; - if ($protectMPIO) { - print $OUTFD "#ifdef MPI_MODE_RDONLY\n"; - } - # If enabled, generate the more complex code required to - # handle the case where MPI_Fint is not the same size - # as a C int. THIS IS EXPERIMENTAL AND SHOULD NOT BE - # RELEASED - if ($do_fint) { - &printCallForFint( $routine_prefix, $routine_name, $args ); - } - &print_special_decls( $routine_name ); - &adjust_mpi_bottom($OUTFD, $args); - if (defined($ChangeCall{$routine_name})) { - my ($newName,$extraArgs) = - split(/:/,$ChangeCall{$routine_name} ); - print $OUTFD " $errparmlval = $newName"; - my $largs = $args . "," . $extraArgs; - &print_call_args( $largs ); - } - else { - print $OUTFD " $errparmlval = $routine_prefix$routine_name"; - print "Printing call arguments for mpi_${lcname}_\n" if $debug; - &print_call_args( $args ); - } - # Print any post call processing - &print_post_call( $routine_name, $args ); - if ($do_fint) { - print $OUTFD "#endif\n" - } - if ($protectMPIO) { - print $OUTFD "#else\n$errparmlval = MPI_ERR_INTERN;\n#endif\n"; - } - if ($returnErrval) { - print $OUTFD " return $errparmrval;\n"; - } - print $OUTFD "}\n"; - if ($buildfiles) { - close ($OUTFD); - &ReplaceIfDifferent( $filename, $newfilename ); - } - if ($build_prototypes) { - if ($do_subdecls) { - print PROTOFD "extern FORT_DLL_SPEC $returnType FORT_CALL ${out_prefix}${lcname}_ "; - } - else { - print PROTOFD "extern $returnType ${out_prefix}${lcname}_ "; - } - &print_args( PROTOFD, $args, 0, $lcname ); - &print_attr( PROTOFD, "${out_prefix}${lcname}_" ); - print PROTOFD ";\n"; - } - } - last PREFIX; # bail out and start reading lines from FD again - } - } - } -} - sub ReadInterfaceForDefinitions { my $prototype_file = $_[0]; my $linecount = 0; @@ -4732,84 +651,6 @@ sub SkipCPPIfdef { return 0; } # --------------------------------------------------------------------------- -# Add a prototype for (functionname, arguments) -sub AddPrototype { - my ($out_prefix, $funcname,$args) = @_; - if ($build_prototypes) { - print PROTOFD "extern "; - &print_routine_type_decl( PROTOFD, $out_prefix, "$funcname" ); - &print_args( PROTOFD, $args, 1, "$funcname" ); - &print_attr( PROTOFD, "${out_prefix}${funcname}_" ); - print PROTOFD ";\n"; - } -} -# --------------------------------------------------------------------------- -# This function writes the attribute copy/delete/dup functions -# with a particular prefix (and a null prefix is allowed) -# WriteAttrDefaults( prefix ) -sub WriteAttrDefaults { - my $prefix =$_[0]; - my $ucprefix = uc($prefix); - my $out_prefix = $out_prefixes[0]; # realistically, always "mpi_" - - my $filename = "dup_${prefix}fnf.c"; - open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n"; - $files[$#files+1] = $filename; - # The dup functions with a prefix in Fortran take an MPI_Aint * as - # the argument, not a void *. When sizeof(MPI_Aint) > sizeof(void *), - # its important to use an MPI_Aint * instead of a void ** -# $args = "MPI_Fint, MPI_Fint *, void *, void **, void **, MPI_Fint *"; - $args = "MPI_Fint *, MPI_Fint *, void *, MPI_FAintp, MPI_FAintp, MPI_Fint *"; - &print_header( "mpi_", "mpi_${prefix}dup_fn", "${prefix}dup_fn", $args, - "#ifdef MPI_${ucprefix}DUP_FN\n#undef MPI_${ucprefix}DUP_FN\n#endif\n" ); - &print_routine_type_decl( $OUTFD, $out_prefix, "${prefix}dup_fn" ); - &print_args( $OUTFD, $args, 0, "${prefix}dup_fn" ); - #&print_attr; - print $OUTFD "{ - *v5 = *v4; - *v6 = MPII_TO_FLOG(1); - *ierr = MPI_SUCCESS; -}\n"; - close ($OUTFD); - &ReplaceIfDifferent( $filename, $filename . ".new" ); - &AddPrototype( $out_prefix, "${prefix}dup_fn", $args ); - - $OUTFD = "NULLDELFN"; - $filename = "null_${prefix}del_fnf.c"; - open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n"; - $files[$#files+1] = $filename; - $args = "MPI_Fint *, MPI_Fint *, MPI_FAintp, MPI_FAintp"; - &print_header( "mpi_", "mpi_${prefix}null_delete_fn", "${prefix}null_delete_fn", $args, - "#ifdef MPI_${ucprefix}NULL_DELETE_FN\n#undef MPI_${ucprefix}NULL_DELETE_FN\n#endif\n" ); - &print_routine_type_decl( $OUTFD, $out_prefix, "${prefix}null_delete_fn" ); - &print_args( $OUTFD, $args, 0, "${prefix}null_delete_fn" ); - #&print_attr; - print $OUTFD "{ - *ierr = MPI_SUCCESS; -}\n"; - close ($OUTFD); - &ReplaceIfDifferent( $filename, $filename . ".new" ); - &AddPrototype( $out_prefix, "${prefix}null_delete_fn", $args ); - - $OUTFD = "NULLCOPYFN"; - $filename = "null_${prefix}copy_fnf.c"; - open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n"; - $files[$#files+1] = $filename; - $args = "MPI_Fint *, MPI_Fint *, MPI_FAintp, MPI_FAintp, MPI_FAintp, int *"; - &print_header( "mpi_", "mpi_${prefix}null_copy_fn", "${prefix}null_copy_fn", $args, - "#ifdef MPI_${ucprefix}NULL_COPY_FN\n#undef MPI_${ucprefix}NULL_COPY_FN\n#endif\n" ); - &print_routine_type_decl( $OUTFD, $out_prefix, "${prefix}null_copy_fn" ); - &print_args( $OUTFD, $args, 0, "${prefix}null_copy_fn" ); - print $OUTFD "{ - *ierr = MPI_SUCCESS; - *v6 = MPII_TO_FLOG(0); -}\n"; - close ($OUTFD); - &ReplaceIfDifferent( $filename, $filename . ".new" ); - - &AddPrototype( $out_prefix, "${prefix}null_copy_fn", $args ); -} - # # Replace old file with new file only if new file is different # Otherwise, remove new filename @@ -4837,330 +678,3 @@ sub ReplaceIfDifferent { unlink $newfilename; } } -# ------------------------------------------------------------------------ -# We wish to have the option of adding a special init call for some -# variables. This lets us ensure that MPI routines that need special -# symbols (such as MPI_BOTTOM or MPI_IN_PLACE) can initialize them without -# requiring any Fortran routines be called from the C version of MPI_Init -# (this can cause problems if the Fortran object file includes references -# to compiler-specific symbols, making it difficult and inconvenient at -# best to link C programs) -# ------------------------------------------------------------------------ -sub specialInitClear { - $specialInitAdded = 0; -} -sub specialInitStatement { - my $FD = $_[0]; - - if ($specialInitAdded) { return; } - if (length($specialInitString) > 0) { - print $FD $specialInitString . "\n"; - } - $specialInitAdded = 1; -} -# ------------------------------------------------------------------------ -# Helper function entries. Only one so far -sub HelperForRegister_datarep { - my $OUTFD = $_[0]; - - my $proto_params = "void *v1, MPI_Datatype v2, int v3, void *v4, MPI_Offset v5, void *v6"; - print $OUTFD "\ - /* There is a dummy routine, mpi_conversion_fn_null, that is available - for use as the conversion function for MPI_Register_datarep. - Like the attribute null functions, we provide multiple weak versions - of this if possible */ - -#if defined(USE_WEAK_SYMBOLS) - -/* Add the prototype so the routine knows what this is */ -extern FORT_DLL_SPEC int FORT_CALL mpi_conversion_fn_null_ ( $proto_params ); - -extern FORT_DLL_SPEC int FORT_CALL mpi_conversion_fn_null__ ( $proto_params ); -extern FORT_DLL_SPEC int FORT_CALL mpi_conversion_fn_null ( $proto_params ); -extern FORT_DLL_SPEC int FORT_CALL MPI_CONVERSION_FN_NULL ( $proto_params ); - -#if defined(HAVE_MULTIPLE_PRAGMA_WEAK) && !defined(MPICH_MPI_FROM_PMPI) /* If support multiple #pragma weak */ -#pragma weak mpi_conversion_fn_null__ = mpi_conversion_fn_null_ -#pragma weak mpi_conversion_fn_null = mpi_conversion_fn_null_ -#pragma weak MPI_CONVERSION_FN_NULL = mpi_conversion_fn_null_ - -#elif defined(HAVE_PRAGMA_WEAK) && !defined(MPICH_MPI_FROM_PMPI) /* If support single #pragma weak */ -#if defined(F77_NAME_UPPER) -#pragma weak MPI_CONVERSION_FN_NULL = mpi_conversion_fn_null_ -#elif defined(F77_NAME_LOWER_2USCORE) -#pragma weak mpi_conversion_fn_null__ = mpi_conversion_fn_null_ -#elif !defined(F77_NAME_LOWER_USCORE) -#pragma weak mpi_conversion_fn_null = mpi_conversion_fn_null_ -#endif - -#elif defined(HAVE_PRAGMA_HP_SEC_DEF) && !defined(MPICH_MPI_FROM_PMPI) /* If support _HP_SECONDARY_DEF */ -#if defined(F77_NAME_UPPER) -#pragma _HP_SECONDARY_DEF MPI_CONVERSION_FN_NULL = mpi_conversion_fn_null_ -#elif defined(F77_NAME_LOWER_2USCORE) -#pragma _HP_SECONDARY_DEF mpi_conversion_fn_null__ = mpi_conversion_fn_null_ -#elif !defined(F77_NAME_LOWER_USCORE) -#pragma _HP_SECONDARY_DEF mpi_conversion_fn_null = mpi_conversion_fn_null_ -#endif - -#elif defined(HAVE_PRAGMA_CRI_DUP) && !defined(MPICH_MPI_FROM_PMPI) /* If support _CRI duplicate */ -#if defined(F77_NAME_UPPER) -#pragma _CRI duplicate MPI_CONVERSION_FN_NULL as mpi_conversion_fn_null_ -#elif defined(F77_NAME_LOWER_2USCORE) -#pragma _CRI duplicate mpi_conversion_fn_null__ as mpi_conversion_fn_null_ -#elif !defined(F77_NAME_LOWER_USCORE) -#pragma _CRI duplicate mpi_conversion_fn_null as mpi_conversion_fn_null_ -#endif - -#elif defined(HAVE_WEAK_ATTRIBUTE) /* If support weak attribute */ -extern FORT_DLL_SPEC int FORT_CALL mpi_conversion_fn_null__ ( $proto_params ) -#ifndef MPICH_MPI_FROM_PMPI -__attribute__((weak,alias(\"mpi_conversion_fn_null_\"))) -#endif -; -extern FORT_DLL_SPEC int FORT_CALL mpi_conversion_fn_null ( $proto_params ) -#ifndef MPICH_MPI_FROM_PMPI -__attribute__((weak,alias(\"mpi_conversion_fn_null_\"))) -#endif -; -extern FORT_DLL_SPEC int FORT_CALL MPI_CONVERSION_FN_NULL ( $proto_params ) -#ifndef MPICH_MPI_FROM_PMPI -__attribute__((weak,alias(\"mpi_conversion_fn_null_\"))) -#endif -; -#endif - -#else /* No weak symbol support, so simply rename the one version to match the - Fortran naming convention */ -#ifdef F77_NAME_UPPER -#define mpi_conversion_fn_null_ MPI_CONVERSION_FN_NULL -#elif defined(F77_NAME_LOWER_2USCORE) -#define mpi_conversion_fn_null_ mpi_conversion_fn_null__ -#elif !defined(F77_NAME_LOWER_USCORE) -#define mpi_conversion_fn_null_ mpi_conversion_fn_null -/* Else leave name alone */ -#endif /* End of test on name mapping without weak symbol support */ - -/* Add the prototype so the routine knows what this is */ -extern FORT_DLL_SPEC int FORT_CALL mpi_conversion_fn_null_ ( $proto_params ); - -#endif - -/* This isn't a callable function */ -FORT_DLL_SPEC int FORT_CALL mpi_conversion_fn_null_ ( $proto_params ) { - return 0; -} - -"; - -} - -# Allow multiple underscore versions of names -# but without the PMPI versions (needed for the wrapper library) -sub AddFwrapWeakName { - my ($out_prefix, $lcname, $ucname, $args) = @_; - my $ucprefix = uc($out_prefix); - my $lcprefix = lc($out_prefix); - - print $OUTFD " -/* These definitions are used only for generating the Fortran wrappers */ -#if defined(USE_WEAK_SYMBOLS) && defined(USE_ONLY_MPI_NAMES) -#if defined(HAVE_MULTIPLE_PRAGMA_WEAK)\n"; - &print_weak_decl( $OUTFD, "${ucprefix}$ucname", $args, $lcname ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}__", $args, $lcname ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}", $args, $lcname ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}_", $args, $lcname ); - print $OUTFD "\ -#if defined(F77_NAME_UPPER) -#pragma weak ${lcprefix}${lcname}__ = ${ucprefix}${ucname} -#pragma weak ${lcprefix}${lcname}_ = ${ucprefix}${ucname} -#pragma weak ${lcprefix}${lcname} = ${ucprefix}${ucname} -#elif defined(F77_NAME_LOWER_2USCORE) -#pragma weak ${ucprefix}$ucname = ${lcprefix}${lcname}__ -#pragma weak ${lcprefix}${lcname}_ = ${lcprefix}${lcname}__ -#pragma weak ${lcprefix}${lcname} = ${lcprefix}${lcname}__ -#elif defined(F77_NAME_LOWER_USCORE) -#pragma weak ${ucprefix}$ucname = ${lcprefix}${lcname}_ -#pragma weak ${lcprefix}${lcname}__ = ${lcprefix}${lcname}_ -#pragma weak ${lcprefix}${lcname} = ${lcprefix}${lcname}_ -#else -#pragma weak ${ucprefix}$ucname = ${lcprefix}${lcname} -#pragma weak ${lcprefix}${lcname}__ = ${lcprefix}${lcname} -#pragma weak ${lcprefix}${lcname}_ = ${lcprefix}${lcname} -#endif -#elif defined(HAVE_WEAK_ATTRIBUTE) -#if defined(F77_NAME_UPPER)\n"; - &print_weak_decl( $OUTFD, "${ucprefix}$ucname", $args, $lcname ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}__", $args, $lcname, "${ucprefix}${ucname}" ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}_", $args, $lcname, "${ucprefix}${ucname}" ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}", $args, $lcname, "${ucprefix}${ucname}" ); - print $OUTFD " -#elif defined(F77_NAME_LOWER_2USCORE)\n"; - &print_weak_decl( $OUTFD, "${ucprefix}$ucname", $args, $lcname, "${lcprefix}${lcname}__" ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}__", $args, $lcname ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}_", $args, $lcname, "${lcprefix}${lcname}__" ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}", $args, $lcname, "${lcprefix}${lcname}__" ); - print $OUTFD " -#elif defined(F77_NAME_LOWER_USCORE)\n"; - &print_weak_decl( $OUTFD, "${ucprefix}$ucname", $args, $lcname, "${lcprefix}${lcname}_" ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}__", $args, $lcname, "${lcprefix}${lcname}_" ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}_", $args, $lcname ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}", $args, $lcname, "${lcprefix}${lcname}_" ); - print $OUTFD " -#else\n"; - &print_weak_decl( $OUTFD, "${ucprefix}$ucname", $args, $lcname, "${lcprefix}${lcname}" ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}__", $args, $lcname, "${lcprefix}${lcname}" ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}_", $args, $lcname, "${lcprefix}${lcname}" ); - &print_weak_decl( $OUTFD, "${lcprefix}${lcname}", $args, $lcname ); - print $OUTFD " -#endif -#endif - -#endif -"; -} - -# -# For values that are MPI_Fints but need to be ints, add the declarations. -# These are: -# int, MPI_Request, MPI_Win, MPI_Info, MPI_Group, ... -sub print_fint_to_int_decls { - my @parms = split(/\s*,\s*/, $_[0] ); - my $count = 1; - - # Special case: if the only parm is "void", remove it from the list - if ($#parms == 0 && $parms[0] eq "void") { - $#parms = -1; - } - - foreach $parm (@parms) { - $parm =~ s/^const\s//; # Remove const if present - $parm =~ s/^const\s//; # Remove const if present - # Remove variable name if present in an array arg - if ($parm =~ /(.*)\s+(\w+)\[\]/) { - $parm = "$1 \[\]"; - } - # Compress multiple spaces - $parm =~ s/\s\s/ /g; - - if (defined($special_args{"${routine_name}-$count"})) { - # skip this argument - $count ++; - next; - } - elsif ($parm =~ /!/) { - # skip this case - $count ++; - next; - } - # Extract type (foo *) - elsif ($parm =~ /^\s*([\w_]+)\s*\*\s*$/) { - $parmtype = $1; - if (defined($fintToHandle{$parmtype})) { - print STDOUT "Found $parm in $routine_name\n"; - # Could use the MPI__f2c routine here - # FIXME: We only need to initialize sometimes; - # particularly for ints, rarely (int* is usually - # an output pointer, though there are exceptions, - # particularly in pack) - # FIXME: Could use MPI__f2c to perform cast, - # except for int. - print $OUTFD " int l$count=(int)*v$count;\n"; - } - } - $count++; - } -} - -sub print_int_to_fint { - my $routine_name = $_[0]; - my @parms = split(/\s*,\s*/, $_[1] ); - my $count = 1; - - # Special case: if the only parm is "void", remove it from the list - if ($#parms == 0 && $parms[0] eq "void") { - $#parms = -1; - } - - foreach $parm (@parms) { - $parm =~ s/^const\s//; # Remove const if present - $parm =~ s/^const\s+//; # Remove const if present - # Remove variable name if present in an array arg - if ($parm =~ /(.*)\s+(\w+)\[\]/) { - $parm = "$1 \[\]"; - } - # Compress multiple spaces - $parm =~ s/\s\s/ /g; - - if (defined($special_args{"${routine_name}-$count"})) { - # skip this argument - $count ++; - next; - } - elsif ($parm =~ /!/) { - # skip this case - $count ++; - next; - } - # Extract type (foo *) - elsif ($parm =~ /^\s*([\w_]+)\s*\*\s*$/) { - $parmtype = $1; - if (defined($fintToHandle{$parmtype})) { - print $OUTFD " *v$count = (MPI_Fint)l$count;\n"; - } - } - elsif ($parm =~ /^\s*([\w_]+)\s*\[\]\s*$/) { - $parmtype = $1; - print STDOUT "Found array parm $parm in $routine_name, arg # $count\n"; - if ($parmtype eq "int") { - print STDOUT "int array to fix\n"; - } - elsif (defined($fintToHandle{$parmtype})) { - print STDOUT "handle array to fix\n"; - } - } - $count++; - } -} - -# Generate a special version that handles the case where Fint is not the same -# as int. -sub printCallForFint { - my ($routine_prefix, $routine_name,$args) = @_; - - print $OUTFD "#ifndef HAVE_FINT_IS_INT\n"; - $within_fint = 1; - - # For each arg that is a pointer to integer, creates a copy; - &print_fint_to_int_decls( $args ); - &print_special_decls( $routine_name ); - if (defined($ChangeCall{$routine_name})) { - my ($newName,$extraArgs) = - split(/:/,$ChangeCall{$routine_name} ); - print $OUTFD " $errparmlval = $newName"; - my $largs = $args . "," . $extraArgs; - &print_call_args( $largs, 1 ); - } - else { - print $OUTFD " $errparmlval = $routine_prefix$routine_name"; - print "Printing call arguments for mpi_${lcname}_\n" if $debug; - &print_call_args( $args, 1 ); - } - # Print any post call processing - &print_post_call( $routine_name, $args ); - &print_int_to_fint( $routine_name, $args ); - # Hack - if ($routine_name eq "Op_create") { - print $OUTFD " MPII_Op_set_fc( l3 );\n"; - } - elsif ($routine_name eq "Comm_create_errhandler" || - $routine_name eq "Win_create_errhandler" || - $routine_name eq "File_create_errhandler" || - $routine_name eq "Errhandler_create") { - print $OUTFD " MPII_Errhandler_set_fc( l2 );\n"; - } - - $within_fint = 0; - print $OUTFD "\n#else\n"; - # Make sure the init code is present in the int==Fint branch - &specialInitClear(); -} From 495baab430c1de04ef6c37572ad74400b2b3e59f Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 11 Oct 2021 19:57:03 -0500 Subject: [PATCH 085/607] fortran: use maint/gen_binding_f77.py in autogen --- .gitignore | 11 ++--------- autogen.sh | 23 ++++------------------- src/binding/fortran/mpif_h/Makefile.mk | 16 ++++++++++------ src/binding/fortran/use_mpi/Makefile.mk | 5 ----- src/binding/fortran/use_mpi/cf90t.h | 12 ------------ 5 files changed, 16 insertions(+), 51 deletions(-) delete mode 100644 src/binding/fortran/use_mpi/cf90t.h diff --git a/.gitignore b/.gitignore index cc5e80d21a8..4a58930697d 100644 --- a/.gitignore +++ b/.gitignore @@ -220,7 +220,6 @@ Makefile.am-stamp /src/pm/mpd/aclocal.m4 /src/pm/gforker/mpiexec.gforker /maint/Version -/src/binding/fortran/mpif_h/Makefile_wrappers.mk # MPICH2 parameter handling /src/include/mpir_cvars.h @@ -407,14 +406,11 @@ Makefile.am-stamp /src/binding/fortran/mpif_h/setbot.c /src/binding/fortran/mpif_h/mpif77.conf /src/binding/fortran/mpif_h/mpif77 -/src/binding/fortran/mpif_h/*.c -!/src/binding/fortran/mpif_h/attr_proxy.c -!/src/binding/fortran/mpif_h/statusf2c.c -!/src/binding/fortran/mpif_h/statusc2f.c /src/binding/fortran/mpif_h/fproto.h /src/binding/fortran/mpif_h/mpif.h /src/binding/fortran/mpif_h/mpif.h.in -/src/binding/fortran/mpif_h/fprotos.h +/src/binding/fortran/mpif_h/fortran_profile.h +/src/binding/fortran/mpif_h/fortran_binding.c # /src/binding/fortran/use_mpi/ /src/binding/fortran/use_mpi/mpi_base.f90.orig @@ -429,9 +425,6 @@ Makefile.am-stamp /src/binding/fortran/use_mpi/mpif90model.h /src/binding/fortran/use_mpi/mpif90type.h /src/binding/fortran/use_mpi/mpi_constants.f90 -/src/binding/fortran/use_mpi/typef90intf.c -/src/binding/fortran/use_mpi/typef90realf.c -/src/binding/fortran/use_mpi/typef90cmplxf.c /src/binding/fortran/use_mpi/mpifnoext.h # generated by src/binding/fortran/use_mpi_f08/buildiface diff --git a/autogen.sh b/autogen.sh index 6aefbb76c50..6dc28cf3913 100755 --- a/autogen.sh +++ b/autogen.sh @@ -833,26 +833,16 @@ echo "done" # Create the bindings if necessary if [ $do_bindings = "yes" ] ; then - build_f77=no - build_f90=no - build_cxx=no if [ $do_f77 = "yes" ] ; then - if [ ! -s src/binding/fortran/mpif_h/abortf.c ] ; then - build_f77=yes - elif find src/binding/fortran/mpif_h -name 'buildiface' -newer 'src/binding/fortran/mpif_h/abortf.c' >/dev/null 2>&1 ; then - build_f77=yes - fi - if [ ! -s src/binding/fortran/use_mpi/mpi_base.f90 ] ; then - build_f90=yes - elif find src/binding/fortran/use_mpi -name 'buildiface' -newer 'src/binding/fortran/use_mpi/mpi_base.f90' >/dev/null 2>&1 ; then - build_f90=yes - fi + build_f77=yes + build_f90=yes build_f08=yes fi if [ $build_f77 = "yes" ] ; then echo_n "Building Fortran 77 interface... " ( cd src/binding/fortran/mpif_h && chmod a+x ./buildiface && ./buildiface ) + $PYTHON maint/gen_binding_f77.py echo "done" fi if [ $build_f90 = "yes" ] ; then @@ -861,7 +851,6 @@ if [ $do_bindings = "yes" ] ; then # Double precision vs. Real*8 option rm -f src/binding/fortran/use_mpi/mpi_base.f90.orig ( cd src/binding/fortran/use_mpi && chmod a+x ./buildiface && ./buildiface ) - ( cd src/binding/fortran/use_mpi && ../mpif_h/buildiface -infile=cf90t.h -deffile=./cf90tdefs) echo "done" fi if [ $build_f08 = "yes" ] ; then @@ -872,11 +861,7 @@ if [ $do_bindings = "yes" ] ; then echo "done" fi - if [ ! -s src/binding/cxx/mpicxx.h ] ; then - build_cxx=yes - elif find src/binding/cxx -name 'buildiface' -newer 'src/binding/cxx/mpicxx.h' >/dev/null 2>&1 ; then - build_cxx=yes - fi + build_cxx=yes if [ $build_cxx = "yes" ] ; then echo_n "Building C++ interface... " ( cd src/binding/cxx && chmod a+x ./buildiface && diff --git a/src/binding/fortran/mpif_h/Makefile.mk b/src/binding/fortran/mpif_h/Makefile.mk index 8feef401fe5..a2e2ff0a9d5 100644 --- a/src/binding/fortran/mpif_h/Makefile.mk +++ b/src/binding/fortran/mpif_h/Makefile.mk @@ -8,12 +8,14 @@ EXTRA_DIST += src/binding/fortran/mpif_h/buildiface mpi_f77_sources += src/binding/fortran/mpif_h/attr_proxy.c -include $(top_srcdir)/src/binding/fortran/mpif_h/Makefile_wrappers.mk - if BUILD_F77_BINDING -mpi_f77_sources += src/binding/fortran/mpif_h/fdebug.c \ - src/binding/fortran/mpif_h/setbot.c \ - src/binding/fortran/mpif_h/setbotf.f + +mpi_f77_sources += \ + src/binding/fortran/mpif_h/fortran_binding.c \ + src/binding/fortran/mpif_h/fdebug.c \ + src/binding/fortran/mpif_h/setbot.c \ + src/binding/fortran/mpif_h/setbotf.f + mpi_sources += src/binding/fortran/mpif_h/statusf2c.c src/binding/fortran/mpif_h/statusc2f.c # FIXME does AM_CPPFLAGS need to be included elsewhere somehow in the @@ -21,7 +23,9 @@ mpi_sources += src/binding/fortran/mpif_h/statusf2c.c src/binding/fortran/mpif_h AM_CPPFLAGS += -I${main_top_srcdir}/src/binding/fortran/mpif_h -noinst_HEADERS += src/binding/fortran/mpif_h/fproto.h src/binding/fortran/mpif_h/mpi_fortimpl.h +noinst_HEADERS += \ + src/binding/fortran/mpif_h/fortran_profile.h \ + src/binding/fortran/mpif_h/mpi_fortimpl.h # config.status copies src/binding/fortran/mpif_h/mpif.h to src/include (see the relevant # AC_CONFIG_COMMANDS in configure.ac), so we need to delete it at distclean time diff --git a/src/binding/fortran/use_mpi/Makefile.mk b/src/binding/fortran/use_mpi/Makefile.mk index b26da3bf6ed..55b18c9f516 100644 --- a/src/binding/fortran/use_mpi/Makefile.mk +++ b/src/binding/fortran/use_mpi/Makefile.mk @@ -43,8 +43,6 @@ mpi_core_sources += src/binding/fortran/use_mpi/create_f90_util.c AM_CPPFLAGS += -Isrc/binding/fortran/use_mpi noinst_HEADERS += \ src/binding/fortran/use_mpi/create_f90_util.h \ - src/binding/fortran/use_mpi/cf90t.h \ - src/binding/fortran/use_mpi/mpif90type.h \ src/binding/fortran/use_mpi/mpifnoext.h nodist_noinst_HEADERS += \ @@ -55,9 +53,6 @@ nodist_noinst_HEADERS += \ FC_COMPILE_MODS += $(FCMODOUTFLAG)src/binding/fortran/use_mpi mpi_fc_sources += \ - src/binding/fortran/use_mpi/typef90cmplxf.c \ - src/binding/fortran/use_mpi/typef90realf.c \ - src/binding/fortran/use_mpi/typef90intf.c \ src/binding/fortran/use_mpi/mpi.f90 \ src/binding/fortran/use_mpi/mpi_constants.f90 \ src/binding/fortran/use_mpi/mpi_sizeofs.f90 \ diff --git a/src/binding/fortran/use_mpi/cf90t.h b/src/binding/fortran/use_mpi/cf90t.h deleted file mode 100644 index 10e7746aaea..00000000000 --- a/src/binding/fortran/use_mpi/cf90t.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (C) by Argonne National Laboratory - * See COPYRIGHT in top-level directory - */ - -/* This is a dummy header file that is used to create the Fortran - interfaces for the Type_create_f90_xxx files */ -/* Begin Prototypes */ -int MPI_Type_create_f90_integer(int, MPI_Datatype *); -int MPI_Type_create_f90_real(int, int, MPI_Datatype *); -int MPI_Type_create_f90_complex(int, int, MPI_Datatype *); -/* End Prototypes */ From d1b322c48c287169626233b42aaee109a7ae9b52 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 14 Oct 2021 17:05:58 -0500 Subject: [PATCH 086/607] fortran: remove unused variable in use_mpi/buildiface --- src/binding/fortran/use_mpi/buildiface | 1 - 1 file changed, 1 deletion(-) diff --git a/src/binding/fortran/use_mpi/buildiface b/src/binding/fortran/use_mpi/buildiface index c3346ced803..3bdff24cbe1 100755 --- a/src/binding/fortran/use_mpi/buildiface +++ b/src/binding/fortran/use_mpi/buildiface @@ -31,7 +31,6 @@ if (!-s "binding.sub") { require "$mydir/binding.sub"; -$arg_string = join(' ', @ARGV); $gDebug = 0; $prototype_file = "../../../include/mpi_proto.h"; From 824eddec13c606ca50244d497968917d89369ee4 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 18 Oct 2021 09:45:21 -0500 Subject: [PATCH 087/607] python: allow dash in the option name Allow options such as -aint-size=x. --- maint/local_python/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maint/local_python/__init__.py b/maint/local_python/__init__.py index 0d3feb4224f..4212d8e7b2e 100644 --- a/maint/local_python/__init__.py +++ b/maint/local_python/__init__.py @@ -145,9 +145,9 @@ def check_write_path(path): def parse_cmdline(): for a in sys.argv[1:]: - if RE.match(r'--?(\w+)=(.*)', a): + if RE.match(r'--?([\w-]+)=(.*)', a): MPI_API_Global.opts[RE.m.group(1)] = RE.m.group(2) - elif RE.match(r'--?(\w.+)', a): + elif RE.match(r'--?([\w-].+)', a): MPI_API_Global.opts[RE.m.group(1)] = 1 else: MPI_API_Global.args.append(a) From 9e15e910a35f3fe4ceed22e455073d5ee716ec5f Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 18 Oct 2021 09:13:25 -0500 Subject: [PATCH 088/607] f08: accept sizes for fint/aint/count/cint A simple aint_is_int is not sufficient to check whether a POLY functions actually need different interfaces unless we check the actual integer sizes. Pass in the actual type sizes instead. This is necessary when e.g. INTEGER is 8-byte rather than 4-byte. When Fint is not the same as c_int, we can't have functions passing Fint into a c_int parameter even in a `c_int == kind(0)` branch. The compiler, e.g. gfortran, will complain and refuse to compile. Thus, we also need option for c_int size and skip generation of one branch or the other. --- configure.ac | 1 + maint/gen_binding_f08.py | 4 ++-- maint/local_python/__init__.py | 5 ++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 4288360d57c..e654d30573d 100644 --- a/configure.ac +++ b/configure.ac @@ -5216,6 +5216,7 @@ if test "$f08_works" = "yes" ; then if test "$enable_romio" = "no" ; then cmd="$cmd -no-mpiio" fi + cmd="$cmd -fint-size=$SIZEOF_F77_INTEGER -aint-size=$MPI_SIZEOF_AINT -count-size=$MPI_SIZEOF_COUNT -cint-size=$ac_cv_sizeof_int" AC_CONFIG_COMMANDS([gen_binding_f08], [$cmd_gen_binding_f08], [cmd_gen_binding_f08="$cmd"]) fi diff --git a/maint/gen_binding_f08.py b/maint/gen_binding_f08.py index f1a94e6ee7b..74706c28b96 100644 --- a/maint/gen_binding_f08.py +++ b/maint/gen_binding_f08.py @@ -11,7 +11,7 @@ import os def main(): - # currently support -no-real128, -no-mpiio, -aint-is-int + # currently support -no-real128, -no-mpiio, -fint-size, -aint-size, -count-size, -cint-size G.parse_cmdline() binding_dir = G.get_srcdir_path("src/binding") @@ -29,7 +29,7 @@ def main(): skip_large_list = [] # skip large variations because MPI_ADDRESS_KIND == MPI_COUNT_KIND - if 'aint-is-int' not in G.opts: + if G.opts['aint-size'] == G.opts['count-size']: skip_large_list.extend(["MPI_Op_create", "MPI_Register_datarep", "MPI_Type_create_resized", "MPI_Type_get_extent", "MPI_Type_get_true_extent", "MPI_File_get_type_extent", "MPI_Win_allocate", "MPI_Win_allocate_shared", "MPI_Win_create", "MPI_Win_shared_query"]) # skip File large count functions because it is not implemented yet for func in func_list: diff --git a/maint/local_python/__init__.py b/maint/local_python/__init__.py index 4212d8e7b2e..9c18cccf0e7 100644 --- a/maint/local_python/__init__.py +++ b/maint/local_python/__init__.py @@ -38,7 +38,10 @@ def check_write_path(path): os.makedirs(os.path.dirname(path), exist_ok=True) # command line options and arguments - opts = {} + # By default assumes sizes for LP64 model. + # The F08 bindings use the sizes to detect duplicate large interfaces + opts = {'fint-size':4, 'aint-size':8, 'count-size':8, 'cint-size':4} + args = [] # output out = [] From eba13c64ae8361eea553a45d1831a6827017268e Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 18 Oct 2021 09:15:08 -0500 Subject: [PATCH 089/607] f08: check effective POLY parameters Different types for a POLY parameters may not represent different integer kind under fortran. And in f08, duplicate interfaces are not allowed. Check real POLY parameters instead. --- maint/gen_binding_f08.py | 3 ++- maint/local_python/binding_f08.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/maint/gen_binding_f08.py b/maint/gen_binding_f08.py index 74706c28b96..66adf370740 100644 --- a/maint/gen_binding_f08.py +++ b/maint/gen_binding_f08.py @@ -37,11 +37,12 @@ def main(): skip_large_list.append(func['name']) # preprocess + get_real_POLY_kinds() for func in func_list: check_func_directives(func) if '_skip_fortran' in func: continue - if function_has_POLY_parameters(func) and func['name'] not in skip_large_list: + if function_has_real_POLY_parameters(func) and func['name'] not in skip_large_list: func['_need_large'] = True else: func['_need_large'] = False diff --git a/maint/local_python/binding_f08.py b/maint/local_python/binding_f08.py index ee974eedae7..7736bbcb1c4 100644 --- a/maint/local_python/binding_f08.py +++ b/maint/local_python/binding_f08.py @@ -1554,3 +1554,33 @@ def get_array_decl(): else: print("get_F_c_decl: unhandled type %s: %s - %s" % (p['name'], t_f, t_c)) return None + +#---------------------------------------- +# Depend on integer size, POLY parameters don't always end up with different interfaces +def get_real_POLY_kinds(): + G.real_poly_kinds = {} + + def get_int_type(fortran_type): + if fortran_type == "INTEGER": + return "fint" + elif "MPI_ADDRESS_KIND" in fortran_type: + return "aint" + elif "MPI_COUNT_KIND" in fortran_type: + return "count" + else: + raise Exception("Unrecognized POLY type") + + small_map = G.MAPS['SMALL_F08_KIND_MAP'] + large_map = G.MAPS['BIG_F08_KIND_MAP'] + for kind in small_map: + if small_map[kind].startswith('POLY'): + a = get_int_type(small_map[kind]) + "-size" + b = get_int_type(large_map[kind]) + "-size" + if G.opts[a] != G.opts[b]: + G.real_poly_kinds['kind'] = 1 + +def function_has_real_POLY_parameters(func): + for p in func['parameters']: + if p['kind'] in G.real_poly_kinds: + return True + return False From 9743ff1ac7545c56d237a8c72be7b746e6517c57 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 18 Oct 2021 13:05:31 -0500 Subject: [PATCH 090/607] f08: misc fixes when INTEGER is not c_int In alltoallw functions when MPI_IN_PLACE is used, we still need convert the send parameters to match the parameter types. We can't directly pass len(string) as c_int. Use an intermediate variable instead. --- maint/local_python/binding_f08.py | 54 ++++++++++++++++--------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/maint/local_python/binding_f08.py b/maint/local_python/binding_f08.py index 7736bbcb1c4..a1ea86bf79e 100644 --- a/maint/local_python/binding_f08.py +++ b/maint/local_python/binding_f08.py @@ -199,18 +199,20 @@ def dump_f08_wrappers_f(func, is_large): # alltoallw inplace hack (since it is a corner case) def dump_alltoallw_inplace(arg_list_1, arg_list_2, convert_list_2): # cannot use like sendcounts(1:length) - send_args = "sendbuf, sendcounts, sdispls, sendtypes(1:1)%MPI_VAL" - args1 = send_args + ", " + ', '.join(arg_list_1[4:]) - args2 = send_args + ", " + ', '.join(arg_list_2[4:]) - dump_F_if_open("c_int == kind(0)") - dump_fortran_line("ierror_c = %s(%s)" % (c_func_name, args1)) - dump_F_else() - G.out.append("recvcounts_c = recvcounts(1:length)") - G.out.append("rdispls_c = rdispls_c(1:length)") - G.out.append("recvtypes_c = recvtypes(1:length)%MPI_VAL") - dump_fortran_line("ierror_c = %s(%s)" % (c_func_name, args2)) - G.out.extend(convert_list_2) - dump_F_if_close() + if G.opts['fint-size'] == G.opts['cint-size']: + send_args = "sendbuf, sendcounts, sdispls, sendtypes(1:1)%MPI_VAL" + args1 = send_args + ", " + ', '.join(arg_list_1[4:]) + dump_fortran_line("ierror_c = %s(%s)" % (c_func_name, args1)) + else: + args2 = ', '.join(arg_list_2) + G.out.append("sendcounts_c = sendcounts(1:1)") + G.out.append("sdispls_c = sdispls_c(1:1)") + G.out.append("sendtypes_c = sendtypes(1:1)%MPI_VAL") + G.out.append("recvcounts_c = recvcounts(1:length)") + G.out.append("rdispls_c = rdispls_c(1:length)") + G.out.append("recvtypes_c = recvtypes(1:length)%MPI_VAL") + dump_fortran_line("ierror_c = %s(%s)" % (c_func_name, args2)) + G.out.extend(convert_list_2) # ---- def process_integer(p): @@ -573,6 +575,12 @@ def process_procedure(p): arg = "%s_c" % p['name'] return (arg, arg) + def post_string_len(v): + c_decl_list.append("INTEGER(c_int) :: %s_len" % v) + convert_list_pre.append("%s_len = len(%s)" % (v, v)) + arg_list_1.append("%s_len" % v) + arg_list_2.append("%s_len" % v) + # ---- has_attribute_val = False for p in func['parameters']: @@ -630,13 +638,10 @@ def process_procedure(p): arg_list_1.append("MPIR_ATTR_AINT") arg_list_2.append("MPIR_ATTR_AINT") elif func['name'] == "MPI_Comm_spawn": - arg_list_1.append("len(argv)") - arg_list_2.append("len(argv)") + post_string_len("argv") elif func['name'] == "MPI_Comm_spawn_multiple": - arg_list_1.append("len(array_of_commands)") - arg_list_1.append("len(array_of_argv)") - arg_list_2.append("len(array_of_commands)") - arg_list_2.append("len(array_of_argv)") + post_string_len("array_of_commands") + post_string_len("array_of_argv") # -- return if 'return' not in func: @@ -702,16 +707,13 @@ def dump_call(s, check_int_kind): dump_F_if_open("c_associated(c_loc(sendbuf), c_loc(MPI_IN_PLACE))") dump_alltoallw_inplace(arg_list_1, arg_list_2, convert_list_2) dump_F_else() - if need_check_int_kind: - dump_F_if_open("c_int == kind(0)") + if need_check_int_kind and G.opts['fint-size'] == G.opts['cint-size']: dump_call("%s = %s(%s)" % (ret, c_func_name, ', '.join(arg_list_1)), False) - dump_F_else() - G.out.extend(convert_list_1) - dump_call("%s = %s(%s)" % (ret, c_func_name, ', '.join(arg_list_2)), True) - G.out.extend(convert_list_2) + else: + G.out.extend(convert_list_1) + dump_call("%s = %s(%s)" % (ret, c_func_name, ', '.join(arg_list_2)), True) + G.out.extend(convert_list_2) - if need_check_int_kind: - dump_F_if_close() if is_alltoallw: dump_F_if_close() G.out.append("") From e3699bc50a1e656ae910518c0327045a26e26081 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 18 Oct 2021 16:09:05 -0500 Subject: [PATCH 091/607] typerep/yaksa: fix unsafe assumptions on fortran types It is not safe to assume the fortran basic type size and map to yaksa types based on the assumption. This patch fixes the integer types by checking the type size. The other Fortran types may need additional work around and are left to future TODO. --- .../datatype/typerep/src/typerep_yaksa_init.c | 31 +++++-------------- 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/src/mpi/datatype/typerep/src/typerep_yaksa_init.c b/src/mpi/datatype/typerep/src/typerep_yaksa_init.c index 0c4fbd334cb..56b9a89dedd 100644 --- a/src/mpi/datatype/typerep/src/typerep_yaksa_init.c +++ b/src/mpi/datatype/typerep/src/typerep_yaksa_init.c @@ -146,6 +146,12 @@ yaksa_type_t MPII_Typerep_get_yaksa_type(MPI_Datatype type) case MPI_C_BOOL: #ifdef HAVE_FORTRAN_BINDING case MPI_LOGICAL: + case MPI_CHARACTER: + case MPI_INTEGER: + case MPI_INTEGER1: + case MPI_INTEGER2: + case MPI_INTEGER4: + case MPI_INTEGER8: #endif /* HAVE_FORTRAN_BINDING */ #ifdef HAVE_CXX_BINDING case MPI_CXX_BOOL: @@ -173,30 +179,7 @@ yaksa_type_t MPII_Typerep_get_yaksa_type(MPI_Datatype type) break; #ifdef HAVE_FORTRAN_BINDING - case MPI_CHARACTER: - yaksa_type = YAKSA_TYPE__CHAR; - break; - - case MPI_INTEGER: - yaksa_type = YAKSA_TYPE__INT; - break; - - case MPI_INTEGER1: - yaksa_type = YAKSA_TYPE__INT8_T; - break; - - case MPI_INTEGER2: - yaksa_type = YAKSA_TYPE__INT16_T; - break; - - case MPI_INTEGER4: - yaksa_type = YAKSA_TYPE__INT32_T; - break; - - case MPI_INTEGER8: - yaksa_type = YAKSA_TYPE__INT64_T; - break; - + /* Unfortunately, some of these are more like hacks with unsafe assumptions */ case MPI_COMPLEX: yaksa_type = YAKSA_TYPE__C_COMPLEX; break; From 947b2ede68cb1a6bc4d86c8075e1298c3ba4c6ee Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 18 Oct 2021 22:10:40 -0500 Subject: [PATCH 092/607] test: amend f77/datatype/bottom The test only works when C int is the same size as Fortran INTEGER. --- test/mpi/f77/datatype/bottomc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/mpi/f77/datatype/bottomc.c b/test/mpi/f77/datatype/bottomc.c index b7096aff1a9..647d876d880 100644 --- a/test/mpi/f77/datatype/bottomc.c +++ b/test/mpi/f77/datatype/bottomc.c @@ -38,6 +38,11 @@ void c_routine_(MPI_Fint * ftype, int *errs) int buf[6]; int i, rank; + /* The test only works when MPI_INTEGER has the same size as MPI_INT */ + if (sizeof(MPI_Fint) != sizeof(int)) { + return; + } + MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Aint displs[2]; @@ -54,9 +59,7 @@ void c_routine_(MPI_Fint * ftype, int *errs) if (rank == 0) { /* the message sent contains an int count of 5, followed * by the 5 MPI_INTEGER entries of the Fortran array R. - * Here we assume MPI_INTEGER has the same size as MPI_INT */ - assert(sizeof(MPI_Fint) == sizeof(int)); MPI_Send(MPI_BOTTOM, 1, newtype, 1, 0, MPI_COMM_WORLD); } else { MPI_Recv(buf, 6, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); From a43eba230fa4c61c990f78e315be9b51e39f578d Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 20 Oct 2021 19:12:44 -0500 Subject: [PATCH 093/607] test: fix f77/profile/profile1f.f When Fortran integer is wider than C int and it tries to receive an MPI_INT into an integer, the higher bits may remain garbage, resulting in a test failure. Set the receive buffer to zero before the receive fixes the behavior. --- test/mpi/f77/profile/profile1f.f | 1 + 1 file changed, 1 insertion(+) diff --git a/test/mpi/f77/profile/profile1f.f b/test/mpi/f77/profile/profile1f.f index db1a541eec8..5dac9598d2b 100644 --- a/test/mpi/f77/profile/profile1f.f +++ b/test/mpi/f77/profile/profile1f.f @@ -20,6 +20,7 @@ program main smsg(1) = 3 call mpi_send( smsg, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, ierr ) else if (wrank .eq. 1) then + rmsg(1) = 0 call mpi_recv( rmsg, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, $ MPI_STATUS_IGNORE, ierr ) if (rmsg(1) .ne. 3) then From 6d1ca2318faede7554bdeaa722a055889dff82bc Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 20 Oct 2021 19:19:14 -0500 Subject: [PATCH 094/607] configure: fix assumption of Fortran real size We should not assume the size of Fortran REAL type is the same as INTEGER type. This is especially not true when compiler is using 8-byte INTEGER. Also len_integer was converted to hexadecimal and should be used in expr. --- configure.ac | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index e654d30573d..4c7b682dc20 100644 --- a/configure.ac +++ b/configure.ac @@ -3340,12 +3340,14 @@ if test "$enable_f77" = yes ; then len_integer="04" fi MPI_INTEGER=0x4c00${len_integer}1b - MPI_REAL=0x4c00${len_integer}1c MPI_LOGICAL=0x4c00${len_integer}1d AC_SUBST(MPI_INTEGER) - AC_SUBST(MPI_REAL) AC_SUBST(MPI_LOGICAL) + len_real=`printf "%02x" $pac_cv_f77_sizeof_real` + MPI_REAL=0x4c00${len_real}1c + AC_SUBST(MPI_REAL) + if test -z "$pac_cv_f77_sizeof_double_precision" ; then AC_MSG_ERROR([Unable to configure with Fortran support because configure could not determine the size of a Fortran DOUBLE PRECISION. Consider setting CROSS_F77_SIZEOF_DOUBLE_PRECISION to the length in bytes of a Fortran DOUBLE PRECISION]) fi @@ -3437,8 +3439,8 @@ if test "$enable_f77" = yes ; then # reals and double precision that are the same size (not valid Fortran, # but used by some applications) - len_2integer=`expr 2 \* $len_integer` - len_2real=`expr 2 \* $len_integer` + len_2integer=`expr 2 \* $pac_cv_f77_sizeof_integer` + len_2real=`expr 2 \* $pac_cv_f77_sizeof_real` len_doublecplx=`expr $pac_cv_f77_sizeof_double_precision \* 2` if test "$len_doublecplx" = 0 ; then # We have a problem From 1f8d6101e1d78f34391c13861d05ffe3694f4b9d Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 24 Oct 2021 23:16:45 -0500 Subject: [PATCH 095/607] maint: fix gen_coll.py The \S+ regex swallows the comma, breaking the code when there is multiple constant parameters. --- maint/gen_coll.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maint/gen_coll.py b/maint/gen_coll.py index f90b13491e8..abacf98043c 100644 --- a/maint/gen_coll.py +++ b/maint/gen_coll.py @@ -624,7 +624,7 @@ def get_algo_extra_args(algo, kind): def get_algo_extra_params(algo): extra_args = [] if 'extra_const_params' in algo: - t = re.sub(r'=\S+', '', algo['extra_const_params']) + t = re.sub(r'=[^,\s]+', '', algo['extra_const_params']) extra_args.extend(t.replace(' ', '').split(',')) extra_args.extend(algo['extra_params'].replace(' ', '').split(',')) extra_params = [] From d4162a5b255c03ff61eda1a68fbb0b7d5eb2d75e Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 25 Oct 2021 18:48:01 -0500 Subject: [PATCH 096/607] binding/c: fix missing error check In maint/local_python/binding_c.py when generating bindings for collective, it neglects to check the error and invoke error handler. --- maint/local_python/binding_c.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/maint/local_python/binding_c.py b/maint/local_python/binding_c.py index 85fed31962d..c9b11333b88 100644 --- a/maint/local_python/binding_c.py +++ b/maint/local_python/binding_c.py @@ -1308,10 +1308,12 @@ def dump_body_coll(func): G.out.append("*request = request_ptr->handle;") elif RE.match(r'mpi_neighbor_', func['name'], re.IGNORECASE): dump_line_with_break("mpi_errno = %s(%s);" % (mpir_name, args)) + dump_error_check("") else: # blocking collectives G.out.append("MPIR_Errflag_t errflag = MPIR_ERR_NONE;") dump_line_with_break("mpi_errno = %s(%s, &errflag);" % (mpir_name, args)) + dump_error_check("") def dump_coll_v_swap(func): # -- wrappers to make code cleaner From 6e6e65942a8d864611f9e391b6d3a8a54d0dae30 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Wed, 27 Oct 2021 10:49:26 -0500 Subject: [PATCH 097/607] mpl/ze: Fix IPC memory flags ZE_IPC_MEMORY_FLAG_TBD is no longer listed as a valid flag in the Level Zero documentation. The zeMemOpenIpcHandle documentation states that 0 is the default, so just use that. See nwchemgit/nwchem#463. --- src/mpl/src/gpu/mpl_gpu_ze.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mpl/src/gpu/mpl_gpu_ze.c b/src/mpl/src/gpu/mpl_gpu_ze.c index f3617403241..75f684d73a6 100644 --- a/src/mpl/src/gpu/mpl_gpu_ze.c +++ b/src/mpl/src/gpu/mpl_gpu_ze.c @@ -188,8 +188,7 @@ int MPL_gpu_ipc_handle_map(MPL_gpu_ipc_mem_handle_t ipc_handle, int dev_id, void ze_result_t ret; MPL_gpu_device_handle_t dev_handle = global_ze_devices_handle[dev_id]; - ret = zeMemOpenIpcHandle(global_ze_context, dev_handle, ipc_handle, - ZE_IPC_MEMORY_FLAG_TBD, ptr); + ret = zeMemOpenIpcHandle(global_ze_context, dev_handle, ipc_handle, 0, ptr); if (ret != ZE_RESULT_SUCCESS) { mpl_err = MPL_ERR_GPU_INTERNAL; goto fn_fail; From 47140f3cf1728a250757627af02dde7837fb84e7 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 26 Oct 2021 16:02:07 -0500 Subject: [PATCH 098/607] binding/f77: fix generation of profiling block There are a few negligences resulting compilations for certain compilers. For example, clang, only supports weak attributes and the block for not USE_ONLY_MPI_NAMES is wrong. --- maint/local_python/binding_f77.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/maint/local_python/binding_f77.py b/maint/local_python/binding_f77.py index fa53a4b8e80..39757620350 100644 --- a/maint/local_python/binding_f77.py +++ b/maint/local_python/binding_f77.py @@ -958,16 +958,17 @@ def dump_elif_pragma_weak(have_pragma): for i in range(len(names)): G.profile_out.append("#%s defined(%s)" % (get_if_or_elif(i), defines[i])) - dump_mpi_decl(names[i], param_str) if have_pragma == "HAVE_PRAGMA_WEAK": + dump_mpi_decl(names[i], param_str) G.profile_out.append("#pragma weak %s = %s" % (names[i], pnames[i])) elif have_pragma == "HAVE_PRAGMA_HP_SEC_DEF": G.profile_out.append("#pragma _HP_SECONDARY_DEF %s %s" % (pnames[i], names[i])) elif have_pragma == "HAVE_PRAGMA_CRI_DUP": G.profile_out.append("#pragma _CRI duplicate %s as %s" % (names[i], pnames[i])) G.profile_out.append("#endif") + G.profile_out.append("") - def dump_weak_attibute(use_only_mpi_names): + def dump_weak_attribute(use_only_mpi_names): for i in range(len(names)): G.profile_out.append("#%s defined(%s)" % (get_if_or_elif(i), defines[i])) for j in range(len(names)): @@ -977,7 +978,7 @@ def dump_weak_attibute(use_only_mpi_names): else: dump_mpi_decl_weak_attr(names[j], param_str, names[i]) else: - dump_mpi_decl_weak_attr(pnames[j], param_str, pnames[i]) + dump_mpi_decl_weak_attr(names[j], param_str, pnames[i]) G.profile_out.append("#else") G.profile_out.append("#error missing F77 name mangling") G.profile_out.append("#endif") @@ -1002,7 +1003,7 @@ def dump_pmpi_decl_weak_attribute(): G.profile_out.append("#%s defined(%s)" % (get_if_or_elif(i), defines[i])) for j in range(len(names)): if i != j: - dump_mpi_decl_weak_attr(pnames[i], param_str, pnames[j]) + dump_mpi_decl_weak_attr(pnames[j], param_str, pnames[i]) G.profile_out.append("#else") G.profile_out.append("#error missing F77 name mangling") G.profile_out.append("#endif") @@ -1012,13 +1013,15 @@ def dump_define_mpi_as_pmpi(): G.profile_out.append("#%s defined(%s)" % (get_if_or_elif(i), defines[i])) G.profile_out.append("#define %s %s" % (names[use_idx], pnames[i])) G.profile_out.append("#endif") + G.profile_out.append("") # This defines the routine that we call, which must be the PMPI version # since we're renaming the Fortran entry as the pmpi version. The MPI name # must be undefined first to prevent any conflicts with previous renamings. G.profile_out.append("#ifdef F77_USE_PMPI") - G.profile_out.append("#undef %s" % name) - G.profile_out.append("#define %s P%s" % (name, name)) + use_name = name[0:5].upper() + name[5:] + G.profile_out.append("#undef %s" % use_name) + G.profile_out.append("#define %s P%s" % (use_name, use_name)) G.profile_out.append("#endif") def dump_define_mpi_as_mangle(): @@ -1049,9 +1052,10 @@ def dump_mpi_decl_weak_attr(name, param_str, weak_name): dump_multiple_pragma_weak(False) G.profile_out.append("") dump_elif_pragma_weak("HAVE_PRAGMA_WEAK") - G.profile_out.append("") + dump_elif_pragma_weak("HAVE_PRAGMA_HP_SEC_DEF") + dump_elif_pragma_weak("HAVE_PRAGMA_CRI_DUP") G.profile_out.append("#elif defined(HAVE_WEAK_ATTRIBUTE)") - dump_weak_attibute(False) + dump_weak_attribute(False) G.profile_out.append("") G.profile_out.append("#endif /* HAVE_MULTIPLE_PRAGMA_WEAK, HAVE_PRAGMA_WEAK, HAVE_WEAK_ATTRIBUTE */") G.profile_out.append("#endif /* USE_WEAK_SYMBOLS && !USE_ONLY_MPI_NAMES */") @@ -1060,11 +1064,10 @@ def dump_mpi_decl_weak_attr(name, param_str, weak_name): G.profile_out.append("#if defined(USE_WEAK_SYMBOLS) && defined(USE_ONLY_MPI_NAMES)") G.profile_out.append("#if defined(HAVE_MULTIPLE_PRAGMA_WEAK)") dump_multiple_pragma_weak(True) - G.profile_out.append("") - dump_elif_pragma_weak("HAVE_PRAGMA_WEAK") + # no weak pragma since the names will be identical G.profile_out.append("") G.profile_out.append("#elif defined(HAVE_WEAK_ATTRIBUTE)") - dump_weak_attibute(True) + dump_weak_attribute(True) G.profile_out.append("") G.profile_out.append("#endif /* HAVE_MULTIPLE_PRAGMA_WEAK, HAVE_PRAGMA_WEAK, HAVE_WEAK_ATTRIBUTE */") G.profile_out.append("#endif /* USE_WEAK_SYMBOLS && USE_ONLY_MPI_NAMES */") From 95be0283bfb4434b9afd40ecc505247b03af6c87 Mon Sep 17 00:00:00 2001 From: Rob Latham Date: Tue, 19 Oct 2021 15:25:25 -0500 Subject: [PATCH 099/607] romio: Fix GPFS generic cases GPFS driver had a few Blue Gene and PE specific cases with side effects. Fixes: pmodels/mpich#5604 --- src/mpi/romio/adio/ad_gpfs/ad_gpfs.c | 6 +---- src/mpi/romio/adio/ad_gpfs/ad_gpfs_hints.c | 26 ++++++++++++++++++++++ src/mpi/romio/adio/common/ad_open.c | 3 ++- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/mpi/romio/adio/ad_gpfs/ad_gpfs.c b/src/mpi/romio/adio/ad_gpfs/ad_gpfs.c index 203fbdedeff..2dd54f83e89 100644 --- a/src/mpi/romio/adio/ad_gpfs/ad_gpfs.c +++ b/src/mpi/romio/adio/ad_gpfs/ad_gpfs.c @@ -22,11 +22,7 @@ struct ADIOI_Fns_struct ADIO_GPFS_operations = { ADIOI_GPFS_WriteStridedColl, /* WriteStridedColl */ ADIOI_GEN_SeekIndividual, /* SeekIndividual */ ADIOI_GEN_Fcntl, /* Fcntl */ -#if defined(BGQPLATFORM) || defined(PEPLATFORM) - ADIOI_GPFS_SetInfo, /* SetInfo for BlueGene or PE */ -#else - ADIOI_GEN_SetInfo, /* SetInfo for any platform besides BlueGene or PE */ -#endif + ADIOI_GPFS_SetInfo, /* SetInfo, including parsing environment variables for GPFS driver */ ADIOI_GEN_ReadStrided, /* ReadStrided */ ADIOI_GEN_WriteStrided, /* WriteStrided */ ADIOI_GPFS_Close, /* Close */ diff --git a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_hints.c b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_hints.c index 4b41a680eb9..6029457e5ae 100644 --- a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_hints.c +++ b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_hints.c @@ -63,6 +63,7 @@ void ADIOI_GPFS_SetInfo(ADIO_File fd, MPI_Info users_info, int *error_code) char *value; int flag, intval, nprocs = 0, nprocs_is_valid = 0; static char myname[] = "ADIOI_GPFS_SETINFO"; + size_t len; int did_anything = 0; @@ -107,7 +108,11 @@ void ADIOI_GPFS_SetInfo(ADIO_File fd, MPI_Info users_info, int *error_code) nprocs_is_valid = 1; MPL_snprintf(value, MPI_MAX_INFO_VAL + 1, "%d", nprocs); ADIOI_Info_set(info, "cb_nodes", value); +#ifdef BGQPLATFORM fd->hints->cb_nodes = -1; +#else + fd->hints->cb_nodes = nprocs; +#endif /* hint indicating that no indep. I/O will be performed on this file */ ADIOI_Info_set(info, "romio_no_indep_rw", "false"); @@ -231,6 +236,27 @@ void ADIOI_GPFS_SetInfo(ADIO_File fd, MPI_Info users_info, int *error_code) #endif } + /* note that we track i/o aggregators two ways: + * - cb_config_list is the string the user passed in to describe I/O + * aggregator locations (the node-name:nprocs syntax e.g "*:1" or "*:*") + * - the 'fd->hints->ranklist' array of MPI ranks representing aggregators. + * Some GPFS platforms have special ranklist generating code, but in the + * common case most GPFS platforms should use the generic ranklist code, + * which takes the "cb_config_list" hint as input */ + if (fd->hints->cb_config_list == NULL) { + ADIOI_Info_set(info, "cb_config_list", ADIOI_CB_CONFIG_LIST_DFLT); + len = (strlen(ADIOI_CB_CONFIG_LIST_DFLT) + 1) * sizeof(char); + fd->hints->cb_config_list = ADIOI_Malloc(len); + if (fd->hints->cb_config_list == NULL) { + ADIOI_Free(value); + *error_code = MPIO_Err_create_code(*error_code, + MPIR_ERR_RECOVERABLE, + myname, __LINE__, MPI_ERR_OTHER, "**nomem2", 0); + return; + } + ADIOI_Strncpy(fd->hints->cb_config_list, ADIOI_CB_CONFIG_LIST_DFLT, len); + } + /* special CB aggregator assignment */ if (did_anything) { #ifdef BGQPLATFORM diff --git a/src/mpi/romio/adio/common/ad_open.c b/src/mpi/romio/adio/common/ad_open.c index fb4022c9257..aaecd8989de 100644 --- a/src/mpi/romio/adio/common/ad_open.c +++ b/src/mpi/romio/adio/common/ad_open.c @@ -202,7 +202,8 @@ MPI_File ADIO_Open(MPI_Comm orig_comm, } } ADIOI_Free(fd->filename); - ADIOI_Free(fd->hints->ranklist); + if (fd->hints->ranklist != NULL) + ADIOI_Free(fd->hints->ranklist); if (fd->hints->cb_config_list != NULL) ADIOI_Free(fd->hints->cb_config_list); ADIOI_Free(fd->hints); From a14cb43fdd30625b7dddde2bfe55c8b5c1b2d641 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 29 Oct 2021 17:07:19 -0500 Subject: [PATCH 100/607] mpir: extra semicolon is defining MPIR_REQUEST_POOL It didn't cause much trouble in the current code because every usage is placing the macro at the end of a statement which just results in a extra empty statement. It needs be fixed anyway. --- src/include/mpir_request.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/mpir_request.h b/src/include/mpir_request.h index e8746dc4fa4..d3dc06edc58 100644 --- a/src/include/mpir_request.h +++ b/src/include/mpir_request.h @@ -270,7 +270,7 @@ void MPIR_Persist_coll_free_cb(MPIR_Request * request); #define MPIR_REQUEST_NUM_POOLS REQUEST_POOL_MAX #define MPIR_REQUEST_PREALLOC 8 -#define MPIR_REQUEST_POOL(req_) (((req_)->handle & REQUEST_POOL_MASK) >> REQUEST_POOL_SHIFT); +#define MPIR_REQUEST_POOL(req_) (((req_)->handle & REQUEST_POOL_MASK) >> REQUEST_POOL_SHIFT) extern MPIR_Request MPIR_Request_builtins[MPIR_REQUEST_BUILTIN_COUNT]; extern MPIR_Object_alloc_t MPIR_Request_mem[MPIR_REQUEST_NUM_POOLS]; From ed5e180527e0b8ab57436674feff323098d0433e Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 29 Oct 2021 17:09:27 -0500 Subject: [PATCH 101/607] ipc: fix missing vci in MPIDI_IPCI_handle_lmt_recv This was missed when we added the AM vci support. --- src/mpid/ch4/shm/ipc/src/ipc_p2p.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mpid/ch4/shm/ipc/src/ipc_p2p.h b/src/mpid/ch4/shm/ipc/src/ipc_p2p.h index 1f56787b30a..b8908c27982 100644 --- a/src/mpid/ch4/shm/ipc/src/ipc_p2p.h +++ b/src/mpid/ch4/shm/ipc/src/ipc_p2p.h @@ -219,8 +219,10 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_IPCI_handle_lmt_recv(MPIDI_IPC_hdr * ipc_hdr, am_hdr.ipc_type = ipc_hdr->ipc_type; am_hdr.req_ptr = sreq_ptr; + int local_vci = MPIDIG_REQUEST(rreq, req->local_vci); + int remote_vci = MPIDIG_REQUEST(rreq, req->remote_vci); CH4_CALL(am_send_hdr(MPIDIG_REQUEST(rreq, rank), rreq->comm, MPIDI_IPC_ACK, - &am_hdr, sizeof(am_hdr), 0, 0), 1, mpi_errno); + &am_hdr, sizeof(am_hdr), local_vci, remote_vci), 1, mpi_errno); MPIR_ERR_CHECK(mpi_errno); MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(rreq, datatype)); From 7f48fdad3985051384234d4b36df233e7a4dc37a Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 29 Oct 2021 10:18:35 -0500 Subject: [PATCH 102/607] spawn: set socket to nonblocking use fcntl The previous commit (PR #5586) uses per-call flag MSG_DONTWAIT to set nonblocking recv. On FreeBSD under _POSIX_SOURCE, defined with --enable-strict, MSG_DONTWAIT is hidden. To work around, use fnctl instead. Because `fnctl` affects the socket globally, we apply it to the send call and handle the EAGAIN error as well to make the code more symmetric. --- src/mpi/spawn/spawn_impl.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/mpi/spawn/spawn_impl.c b/src/mpi/spawn/spawn_impl.c index 34ca5b07dab..b212be7f5c0 100644 --- a/src/mpi/spawn/spawn_impl.c +++ b/src/mpi/spawn/spawn_impl.c @@ -27,6 +27,9 @@ static int MPIR_fd_send(int fd, void *buffer, int length) MPIR_FUNC_ENTER; + /* setting socket to nonblocking */ + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); + while (length) { /* The expectation is that the length of a join message will fit * in an int. For Unixes that define send as returning ssize_t, @@ -39,7 +42,7 @@ static int MPIR_fd_send(int fd, void *buffer, int length) #else result = errno; #endif - if (result == SOCKET_EINTR) { + if (result == SOCKET_EINTR || result == EAGAIN || result == EWOULDBLOCK) { continue; } else { MPIR_ERR_SET1(mpi_errno, MPI_ERR_INTERN, "**join_send", "**join_send %d", result); @@ -67,9 +70,12 @@ static int MPIR_fd_recv(int fd, void *buffer, int length) MPIR_FUNC_ENTER; + /* setting socket to nonblocking */ + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); + while (length) { /* See discussion on send above for the cast to int. */ - num_bytes = (int) recv(fd, buffer, length, MSG_DONTWAIT); + num_bytes = (int) recv(fd, buffer, length, 0); /* --BEGIN ERROR HANDLING-- */ if (num_bytes == -1) { #ifdef HAVE_WINDOWS_H From 69a77bbb43618525497982aef5e8c2937a75827d Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 29 Oct 2021 11:05:40 -0500 Subject: [PATCH 103/607] ch4: include strings.h to use strncasecmp On freebsd strict mode, we need explicitly include strings.h to use strcasecmp and strncasecmp. --- src/mpid/ch4/shm/posix/posix_init.c | 2 ++ src/mpid/ch4/src/ch4_init.c | 1 + 2 files changed, 3 insertions(+) diff --git a/src/mpid/ch4/shm/posix/posix_init.c b/src/mpid/ch4/shm/posix/posix_init.c index b5dec8eae72..9a4e95c9cd0 100644 --- a/src/mpid/ch4/shm/posix/posix_init.c +++ b/src/mpid/ch4/shm/posix/posix_init.c @@ -39,6 +39,8 @@ #include "posix_csel_container.h" #include "mpidu_genq.h" +#include /* for strncasecmp */ + extern MPL_atomic_uint64_t *MPIDI_POSIX_shm_limit_counter; static int choose_posix_eager(void); diff --git a/src/mpid/ch4/src/ch4_init.c b/src/mpid/ch4/src/ch4_init.c index d5701979538..f4115a5cc57 100644 --- a/src/mpid/ch4/src/ch4_init.c +++ b/src/mpid/ch4/src/ch4_init.c @@ -8,6 +8,7 @@ #include "datatype.h" #include "mpidu_init_shm.h" +#include /* for strncasecmp */ #ifdef HAVE_SIGNAL_H #include #endif From 0aaa465623e0768c101b5a9c96c47754014bd292 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 29 Oct 2021 15:10:05 -0500 Subject: [PATCH 104/607] ch4: avoid MAP_ANON in MPID_Alloc_mem To portably use mmap with MAP_ANON is tricky, especially on later OSX and FreeBSD systems. In MPID_Alloc_mem, there probably isn't much difference to use malloc instead. --- src/mpid/ch4/src/ch4_init.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/mpid/ch4/src/ch4_init.c b/src/mpid/ch4/src/ch4_init.c index f4115a5cc57..ed5965fe3df 100644 --- a/src/mpid/ch4/src/ch4_init.c +++ b/src/mpid/ch4/src/ch4_init.c @@ -664,9 +664,12 @@ void *MPID_Alloc_mem(MPI_Aint size, MPIR_Info * info_ptr) * process is bound to the corresponding device; allocate * memory and bind it to device. */ assert(mem_gid != MPIR_HWTOPO_GID_ROOT); - real_buf = - MPL_mmap(NULL, size + alignment, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, - 0, MPL_MEM_USER); +#ifdef MAP_ANON + real_buf = MPL_mmap(NULL, size + alignment, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, 0, MPL_MEM_USER); +#else + real_buf = MPL_malloc(size + alignment, MPL_MEM_USER); +#endif MPIR_hwtopo_mem_bind(real_buf, size + alignment, mem_gid); break; From 2fca1827b34abf09c6538659b395c6756e567d49 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 30 Oct 2021 15:30:42 -0500 Subject: [PATCH 105/607] ch4/ofi: use correct vni in MPIDI_OFI_do_am_rdma_read_ack MPIDI_OFI_do_am_rdma_read_ack was neglected to use the hard coded vni 0. Add the vni parameters and use the correct vnis instead. --- src/mpid/ch4/netmod/ofi/ofi_am_events.h | 6 ++++-- src/mpid/ch4/netmod/ofi/ofi_events.c | 5 ++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_am_events.h b/src/mpid/ch4/netmod/ofi/ofi_am_events.h index 15edb2942d5..61b2fff5ea1 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_am_events.h +++ b/src/mpid/ch4/netmod/ofi/ofi_am_events.h @@ -203,7 +203,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_handle_rdma_read(MPIDI_OFI_am_header_t * } MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_do_am_rdma_read_ack(int rank, MPIR_Comm * comm, - MPIR_Request * sreq_ptr) + MPIR_Request * sreq_ptr, + int local_vci, int remote_vci) { int mpi_errno = MPI_SUCCESS; MPIDI_OFI_am_rdma_read_ack_msg_t ack_msg; @@ -212,7 +213,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_do_am_rdma_read_ack(int rank, MPIR_Comm * ack_msg.sreq_ptr = sreq_ptr; mpi_errno = MPIDI_NM_am_send_hdr_reply(comm, rank, MPIDI_OFI_AM_RDMA_READ_ACK, - &ack_msg, (MPI_Aint) sizeof(ack_msg), 0, 0); + &ack_msg, (MPI_Aint) sizeof(ack_msg), + local_vci, remote_vci); MPIR_ERR_CHECK(mpi_errno); fn_exit: diff --git a/src/mpid/ch4/netmod/ofi/ofi_events.c b/src/mpid/ch4/netmod/ofi/ofi_events.c index 8e6ac44cbf3..f563cc7241c 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_events.c +++ b/src/mpid/ch4/netmod/ofi/ofi_events.c @@ -421,7 +421,10 @@ static int am_read_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * comm = rreq->comm; } MPIDI_OFI_lmt_msg_payload_t *lmt_info = (void *) MPIDI_OFI_AM_RREQ_HDR(rreq, am_hdr_buf); - mpi_errno = MPIDI_OFI_do_am_rdma_read_ack(lmt_info->src_rank, comm, lmt_info->sreq_ptr); + int local_vci = MPIDIG_REQUEST(rreq, req->local_vci); + int remote_vci = MPIDIG_REQUEST(rreq, req->remote_vci); + mpi_errno = MPIDI_OFI_do_am_rdma_read_ack(lmt_info->src_rank, comm, lmt_info->sreq_ptr, + local_vci, remote_vci); MPIR_ERR_CHECK(mpi_errno); From 1f22d99583d510aa28b8e3debb0603c1851d59ad Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 29 Oct 2021 22:52:25 -0500 Subject: [PATCH 106/607] ch4/ofi: move am inflight trackers into per_vni We need track and progress individual vni's am inflight trackers, especially during finalize. Fixes pmodels/mpich#5627 --- src/mpid/ch4/netmod/ofi/ofi_am_events.c | 3 ++- src/mpid/ch4/netmod/ofi/ofi_am_impl.h | 4 ++-- src/mpid/ch4/netmod/ofi/ofi_events.c | 2 +- src/mpid/ch4/netmod/ofi/ofi_init.c | 21 ++++++++++++++------- src/mpid/ch4/netmod/ofi/ofi_types.h | 8 ++++---- 5 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_am_events.c b/src/mpid/ch4/netmod/ofi/ofi_am_events.c index c15679c223e..9bb95c90708 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_am_events.c +++ b/src/mpid/ch4/netmod/ofi/ofi_am_events.c @@ -19,12 +19,13 @@ int MPIDI_OFI_am_rdma_read_ack_handler(void *am_hdr, void *data, ack_msg = (MPIDI_OFI_am_rdma_read_ack_msg_t *) am_hdr; sreq = ack_msg->sreq_ptr; + int vni_local = MPIDIG_AM_ATTR_DST_VCI(attr); if (!MPIDI_OFI_ENABLE_MR_PROV_KEY) { uint64_t mr_key = fi_mr_key(MPIDI_OFI_AM_SREQ_HDR(sreq, lmt_mr)); MPIDI_OFI_mr_key_free(MPIDI_OFI_LOCAL_MR_KEY, mr_key); } MPIDI_OFI_CALL(fi_close(&MPIDI_OFI_AM_SREQ_HDR(sreq, lmt_mr)->fid), mr_unreg); - MPL_atomic_fetch_sub_int(&MPIDI_OFI_global.am_inflight_rma_send_mrs, 1); + MPIDI_OFI_global.per_vni[vni_local].am_inflight_rma_send_mrs -= 1; MPIR_gpu_free_host(MPIDI_OFI_AM_SREQ_HDR(sreq, pack_buffer)); diff --git a/src/mpid/ch4/netmod/ofi/ofi_am_impl.h b/src/mpid/ch4/netmod/ofi/ofi_am_impl.h index 482686fadd3..d3e821e4ef4 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_am_impl.h +++ b/src/mpid/ch4/netmod/ofi/ofi_am_impl.h @@ -281,7 +281,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_am_isend_long(int rank, MPIR_Comm * comm, 0ULL, lmt_info->rma_key, 0ULL, &MPIDI_OFI_AM_SREQ_HDR(sreq, lmt_mr), NULL), mr_reg); - MPL_atomic_fetch_add_int(&MPIDI_OFI_global.am_inflight_rma_send_mrs, 1); + MPIDI_OFI_global.per_vni[vni_src].am_inflight_rma_send_mrs += 1; if (MPIDI_OFI_ENABLE_MR_PROV_KEY) { /* MR_BASIC */ @@ -546,7 +546,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_do_emulated_inject(MPIR_Comm * comm, fi_a MPIDI_OFI_REQUEST(sreq, event_id) = MPIDI_OFI_EVENT_INJECT_EMU; MPIDI_OFI_REQUEST(sreq, util.inject_buf) = ibuf; - MPL_atomic_fetch_add_int(&MPIDI_OFI_global.am_inflight_inject_emus, 1); + MPIDI_OFI_global.per_vni[vni_src].am_inflight_inject_emus += 1; MPIDI_OFI_CALL_RETRY_AM(fi_send(MPIDI_OFI_global.ctx[ctx_idx].tx, ibuf, len, NULL /* desc */ , addr, &(MPIDI_OFI_REQUEST(sreq, context))), diff --git a/src/mpid/ch4/netmod/ofi/ofi_events.c b/src/mpid/ch4/netmod/ofi/ofi_events.c index f563cc7241c..bef72a690db 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_events.c +++ b/src/mpid/ch4/netmod/ofi/ofi_events.c @@ -164,7 +164,7 @@ static int inject_emu_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request if (!incomplete) { MPL_free(MPIDI_OFI_REQUEST(req, util.inject_buf)); MPIDI_CH4_REQUEST_FREE(req); - MPL_atomic_fetch_sub_int(&MPIDI_OFI_global.am_inflight_inject_emus, 1); + MPIDI_OFI_global.per_vni[vni].am_inflight_inject_emus -= 1; } MPIR_FUNC_EXIT; diff --git a/src/mpid/ch4/netmod/ofi/ofi_init.c b/src/mpid/ch4/netmod/ofi/ofi_init.c index 51f8451e8a7..2c575b726c3 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_init.c +++ b/src/mpid/ch4/netmod/ofi/ofi_init.c @@ -856,8 +856,11 @@ int MPIDI_OFI_mpi_finalize_hook(void) /* Progress until we drain all inflight RMA send long buffers */ /* NOTE: am currently only use vni 0. Need update once that changes */ - while (MPL_atomic_load_int(&MPIDI_OFI_global.am_inflight_rma_send_mrs) > 0) - MPIDI_OFI_PROGRESS(0); + for (int vni = 0; vni < MPIDI_OFI_global.num_vnis; vni++) { + while (MPIDI_OFI_global.per_vni[vni].am_inflight_rma_send_mrs > 0) { + MPIDI_OFI_PROGRESS(vni); + } + } /* Destroy RMA key allocator */ MPIDI_OFI_mr_key_allocator_destroy(); @@ -877,9 +880,12 @@ int MPIDI_OFI_mpi_finalize_hook(void) /* Progress until we drain all inflight injection emulation requests */ /* NOTE: am currently only use vni 0. Need update once that changes */ - while (MPL_atomic_load_int(&MPIDI_OFI_global.am_inflight_inject_emus) > 0) - MPIDI_OFI_PROGRESS(0); - MPIR_Assert(MPL_atomic_load_int(&MPIDI_OFI_global.am_inflight_inject_emus) == 0); + for (int vni = 0; vni < MPIDI_OFI_global.num_vnis; vni++) { + while (MPIDI_OFI_global.per_vni[vni].am_inflight_inject_emus > 0) { + MPIDI_OFI_PROGRESS(vni); + } + MPIR_Assert(MPIDI_OFI_global.per_vni[vni].am_inflight_inject_emus == 0); + } /* Tearing down endpoints in reverse order they were created */ for (int nic = MPIDI_OFI_global.num_nics - 1; nic >= 0; nic--) { @@ -1520,12 +1526,13 @@ int ofi_am_init(void) MPIDI_OFI_global.per_vni[vni].am_unordered_msgs = NULL; MPIDI_OFI_global.per_vni[vni].deferred_am_isend_q = NULL; + + MPIDI_OFI_global.per_vni[vni].am_inflight_inject_emus = 0; + MPIDI_OFI_global.per_vni[vni].am_inflight_rma_send_mrs = 0; } MPIDIG_am_reg_cb(MPIDI_OFI_INTERNAL_HANDLER_CONTROL, NULL, &MPIDI_OFI_control_handler); MPIDIG_am_reg_cb(MPIDI_OFI_AM_RDMA_READ_ACK, NULL, &MPIDI_OFI_am_rdma_read_ack_handler); } - MPL_atomic_store_int(&MPIDI_OFI_global.am_inflight_inject_emus, 0); - MPL_atomic_store_int(&MPIDI_OFI_global.am_inflight_rma_send_mrs, 0); fn_exit: return mpi_errno; diff --git a/src/mpid/ch4/netmod/ofi/ofi_types.h b/src/mpid/ch4/netmod/ofi/ofi_types.h index f04c685a8df..09ff0a7ba0a 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_types.h +++ b/src/mpid/ch4/netmod/ofi/ofi_types.h @@ -235,6 +235,10 @@ typedef struct { void *am_send_seq_tracker; void *am_recv_seq_tracker; + /* active message trackers */ + int am_inflight_inject_emus; + int am_inflight_rma_send_mrs; + /* Queue (utlist) to store early-arrival active messages */ MPIDI_OFI_am_unordered_msg_t *am_unordered_msgs; @@ -366,10 +370,6 @@ typedef struct { * OFI provider at MPI initialization.*/ MPIDI_OFI_atomic_valid_t win_op_table[MPIR_DATATYPE_N_PREDEFINED][MPIDIG_ACCU_NUM_OP]; - /* Active Message Globals */ - MPL_atomic_int_t am_inflight_inject_emus; - MPL_atomic_int_t am_inflight_rma_send_mrs; - /* Process management and PMI globals */ int pname_set; int pname_len; From 9bc61afb658b31e3faaf6fc5a87afb27f064a6f7 Mon Sep 17 00:00:00 2001 From: Rob Latham Date: Tue, 5 Oct 2021 16:30:09 -0500 Subject: [PATCH 107/607] romio: synchronized flush Provide a way for users to request temporal synchronization from file sync, making it a little less onerous to ensure write visibility to all other MPI processes --- src/mpi/romio/adio/common/ad_flush.c | 9 ++++++++- src/mpi/romio/adio/common/ad_hints.c | 9 +++++++++ src/mpi/romio/adio/common/ad_open.c | 5 +++++ src/mpi/romio/adio/common/ad_opencoll.c | 3 +++ src/mpi/romio/adio/common/ad_write.c | 1 + src/mpi/romio/adio/common/hint_fns.c | 6 ++++++ src/mpi/romio/adio/include/adio.h | 1 + src/mpi/romio/adio/include/adioi.h | 1 + 8 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/mpi/romio/adio/common/ad_flush.c b/src/mpi/romio/adio/common/ad_flush.c index 276163e9ed8..d5ee07fd040 100644 --- a/src/mpi/romio/adio/common/ad_flush.c +++ b/src/mpi/romio/adio/common/ad_flush.c @@ -14,9 +14,15 @@ void ADIOI_GEN_Flush(ADIO_File fd, int *error_code) int err; static char myname[] = "ADIOI_GEN_FLUSH"; + /* If MPI_File_sync is a temporally synchronizing sync, the caller can + * avoid the 'sync/barrier/sync' process to ensure visibility and just call + * 'sync' */ + if (fd->hints->synchronizing_flush > 0) + MPI_Barrier(fd->comm); /* the deferred-open optimization may mean that a file has not been opened * on this processor */ - if (fd->is_open > 0) { + /* additionally, if this process did no writes, there is no work to be done */ + if (fd->is_open > 0 && fd->dirty_write) { err = fsync(fd->fd_sys); /* --BEGIN ERROR HANDLING-- */ if (err == -1) { @@ -27,6 +33,7 @@ void ADIOI_GEN_Flush(ADIO_File fd, int *error_code) } /* --END ERROR HANDLING-- */ } + fd->dirty_write = 0; *error_code = MPI_SUCCESS; } diff --git a/src/mpi/romio/adio/common/ad_hints.c b/src/mpi/romio/adio/common/ad_hints.c index 343e7ce21f5..2743f05db4f 100644 --- a/src/mpi/romio/adio/common/ad_hints.c +++ b/src/mpi/romio/adio/common/ad_hints.c @@ -128,6 +128,12 @@ void ADIOI_GEN_SetInfo(ADIO_File fd, MPI_Info users_info, int *error_code) fd->hints->min_fdomain_size = 0; fd->hints->striping_unit = 0; + /* temporally synchronizing flush: I think this is going to be a useful + * optimization for all users, but might have surprising hangs if + * client code incorrectly treats MPI_File_sync as independent */ + ADIOI_Info_set(info, "romio_synchronized_flush", "disabled"); + fd->hints->synchronizing_flush = 0; + fd->hints->initialized = 1; /* ADIO_Open sets up collective buffering arrays. If we are in this @@ -249,6 +255,9 @@ void ADIOI_GEN_SetInfo(ADIO_File fd, MPI_Info users_info, int *error_code) * process hints for it. */ ADIOI_Info_check_and_install_int(fd, users_info, "striping_unit", &(fd->hints->striping_unit), myname, error_code); + + ADIOI_Info_check_and_install_enabled(fd, users_info, "romio_synchronized_flush", + &(fd->hints->synchronizing_flush), myname, error_code); } /* Begin hint post-processig: some hints take precedence over or conflict diff --git a/src/mpi/romio/adio/common/ad_open.c b/src/mpi/romio/adio/common/ad_open.c index aaecd8989de..60f667d953f 100644 --- a/src/mpi/romio/adio/common/ad_open.c +++ b/src/mpi/romio/adio/common/ad_open.c @@ -91,6 +91,11 @@ MPI_File ADIO_Open(MPI_Comm orig_comm, fd->hints->initialized = 0; fd->info = MPI_INFO_NULL; + /* Some ROMIO drivers will support "write tracking": omit an fsync() call + * if no writes happened. Drivers supporting that feature will set the bit + * on write, and clear the bit on open, close, and sync. */ + fd->dirty_write = 1; + /* move system-wide hint processing *back* into open, but this time the * hintfile reader will do a scalable read-and-broadcast. The global * ADIOI_syshints will get initialized at first open. subsequent open diff --git a/src/mpi/romio/adio/common/ad_opencoll.c b/src/mpi/romio/adio/common/ad_opencoll.c index f1a12100e5c..e22b1af490f 100644 --- a/src/mpi/romio/adio/common/ad_opencoll.c +++ b/src/mpi/romio/adio/common/ad_opencoll.c @@ -179,4 +179,7 @@ void ADIOI_GEN_OpenColl(ADIO_File fd, int rank, int access_mode, int *error_code * not an aggregaor and we are doing deferred open, we returned earlier)*/ fd->is_open = 1; + /* sync optimization: we can omit the fsync() call if we do no writes */ + fd->dirty_write = 0; + } diff --git a/src/mpi/romio/adio/common/ad_write.c b/src/mpi/romio/adio/common/ad_write.c index cad116e075f..e33d306f24e 100644 --- a/src/mpi/romio/adio/common/ad_write.c +++ b/src/mpi/romio/adio/common/ad_write.c @@ -89,6 +89,7 @@ void ADIOI_GEN_WriteContig(ADIO_File fd, const void *buf, int count, bytes_xfered += err; p += err; } + fd->dirty_write = 1; #ifdef ROMIO_GPFS if (gpfsmpio_timing) diff --git a/src/mpi/romio/adio/common/hint_fns.c b/src/mpi/romio/adio/common/hint_fns.c index 714a4ce5fa7..ecad77e2a8e 100644 --- a/src/mpi/romio/adio/common/hint_fns.c +++ b/src/mpi/romio/adio/common/hint_fns.c @@ -70,6 +70,12 @@ int ADIOI_Info_check_and_install_enabled(ADIO_File fd, MPI_Info info, const char } else if (!strcmp(value, "automatic") || !strcmp(value, "AUTOMATIC")) { ADIOI_Info_set(fd->info, key, value); *local_cache = ADIOI_HINT_AUTO; + /* treat the user-provided string like "enabled": either it is a hint + * ROMIO knows about and can support it, or ROMIO will not return the + * hint at all in the MPI_File_get_info info object */ + } else if (!strcmp(value, "requested") || !strcmp(value, "REQUESTED")) { + ADIOI_Info_set(fd->info, key, "enable"); + *local_cache = ADIOI_HINT_ENABLE; } tmp_val = *local_cache; diff --git a/src/mpi/romio/adio/include/adio.h b/src/mpi/romio/adio/include/adio.h index cedce0c8703..8a7c05d83bf 100644 --- a/src/mpi/romio/adio/include/adio.h +++ b/src/mpi/romio/adio/include/adio.h @@ -239,6 +239,7 @@ typedef struct ADIOI_FileD { #ifdef ROMIO_QUOBYTEFS struct quobyte_fh *file_handle; /* file handle for quobytefs */ #endif + int dirty_write; /* this client has written data */ } ADIOI_FileD; typedef struct ADIOI_FileD *ADIO_File; diff --git a/src/mpi/romio/adio/include/adioi.h b/src/mpi/romio/adio/include/adioi.h index 01300b459ca..4b48a5cef31 100644 --- a/src/mpi/romio/adio/include/adioi.h +++ b/src/mpi/romio/adio/include/adioi.h @@ -47,6 +47,7 @@ struct ADIOI_Hints_struct { int deferred_open; int start_iodevice; int min_fdomain_size; + int synchronizing_flush; /* "romio_synchronized_flush" hint */ char *cb_config_list; int *ranklist; union { From 8bb6bc1cac5121b2dfd88ddcf4b845ea442b2251 Mon Sep 17 00:00:00 2001 From: Rob Latham Date: Mon, 18 Oct 2021 14:02:01 -0500 Subject: [PATCH 108/607] romio: only return relevant keys Revert ce9f67cab4b2b: We've thought about MPI-4 14.2.8 a while and have decided ROMIO should not return extra keys. It should return in MPI_File_get_info only the keys that it used. --- src/mpi/romio/adio/common/ad_hints.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/mpi/romio/adio/common/ad_hints.c b/src/mpi/romio/adio/common/ad_hints.c index 2743f05db4f..4b896687171 100644 --- a/src/mpi/romio/adio/common/ad_hints.c +++ b/src/mpi/romio/adio/common/ad_hints.c @@ -32,12 +32,10 @@ void ADIOI_GEN_SetInfo(ADIO_File fd, MPI_Info users_info, int *error_code) } ad_get_env_vars(); + /* Interpreting MPI-4.0 to mean ROMIO should only return hints it knows + * about when user calls MPI_File_get_info */ if (fd->info == MPI_INFO_NULL) { - if (users_info == MPI_INFO_NULL) - MPI_Info_create(&(fd->info)); - else - /* duplicate users_info to preserve hints not used in ROMIO */ - MPI_Info_dup(users_info, &(fd->info)); + MPI_Info_create(&(fd->info)); } info = fd->info; From 47390c1aa3b730a6770161e9a5b38962b3788a7e Mon Sep 17 00:00:00 2001 From: Rob Latham Date: Mon, 18 Oct 2021 14:15:45 -0500 Subject: [PATCH 109/607] romio: write visibility feature Lots of file systems implement POSIX semantics: a write on one process immediately visible on others. --- src/mpi/romio/adio/ad_nfs/ad_nfs_features.c | 2 ++ src/mpi/romio/adio/common/ad_features.c | 1 + src/mpi/romio/adio/include/adio.h | 3 +++ 3 files changed, 6 insertions(+) diff --git a/src/mpi/romio/adio/ad_nfs/ad_nfs_features.c b/src/mpi/romio/adio/ad_nfs/ad_nfs_features.c index 41edbc3d411..5a93781e9b9 100644 --- a/src/mpi/romio/adio/ad_nfs/ad_nfs_features.c +++ b/src/mpi/romio/adio/ad_nfs/ad_nfs_features.c @@ -13,10 +13,12 @@ int ADIOI_NFS_Feature(ADIO_File fd, int flag) case ADIO_LOCKS: case ADIO_SEQUENTIAL: case ADIO_DATA_SIEVING_WRITES: + case ADIO_ATOMIC_MODE: return 1; case ADIO_SCALABLE_OPEN: case ADIO_UNLINK_AFTER_CLOSE: case ADIO_SCALABLE_RESIZE: + case ADIO_IMMEDIATELY_VISIBLE: default: return 0; } diff --git a/src/mpi/romio/adio/common/ad_features.c b/src/mpi/romio/adio/common/ad_features.c index d95c70c1ef0..04534895cc5 100644 --- a/src/mpi/romio/adio/common/ad_features.c +++ b/src/mpi/romio/adio/common/ad_features.c @@ -15,6 +15,7 @@ int ADIOI_GEN_Feature(ADIO_File fd, int flag) case ADIO_UNLINK_AFTER_CLOSE: case ADIO_TWO_PHASE: case ADIO_SCALABLE_RESIZE: + case ADIO_IMMEDIATELY_VISIBLE: return 1; break; case ADIO_SCALABLE_OPEN: diff --git a/src/mpi/romio/adio/include/adio.h b/src/mpi/romio/adio/include/adio.h index 8a7c05d83bf..17a609443f0 100644 --- a/src/mpi/romio/adio/include/adio.h +++ b/src/mpi/romio/adio/include/adio.h @@ -319,6 +319,9 @@ typedef struct { #define ADIO_SCALABLE_RESIZE 307 /* file system supports resizing from one * processor (nfs, e.g. does not) */ +#define ADIO_IMMEDIATELY_VISIBLE 308 /* a write from one client immediately + * visible on other clients (POSIX semantics) */ + /* for default file permissions */ #define ADIO_PERM_NULL -1 From ffba842242b8205242cf02b98073ee4143c4298d Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 19 Oct 2021 09:35:42 -0500 Subject: [PATCH 110/607] test/io: Remove commented out error check As of MPI-4.0, info hints that are not recognized by the implementation must not be returned to the user when querying info for a given comm, win, or file. The commented out check here would have treated correct behavior as an error, so best just to remove it. --- test/mpi/io/setinfo.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/test/mpi/io/setinfo.c b/test/mpi/io/setinfo.c index 7836fc54164..17bb5c12f19 100644 --- a/test/mpi/io/setinfo.c +++ b/test/mpi/io/setinfo.c @@ -86,13 +86,7 @@ int main(int argc, char *argv[]) MPI_Info_get(infoout, (char *) "access_style", 1024, value, &flag); /* Note that an implementation is allowed to ignore the set_info, * so we'll accept either the original or the updated version */ - if (!flag) { - ; - /* - * errs++; - * printf("Access style hint not saved\n"); - */ - } else { + if (flag) { if (strcmp(value, "read_once") != 0 && strcmp(value, "write_once,random") != 0) { errs++; printf("value for access_style unexpected; is %s\n", value); From 67d7fd040d78f748846f3b2115c61ac7f58f7176 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 7 Sep 2021 17:12:47 -0500 Subject: [PATCH 111/607] ch4: Remove unused struct member --- src/mpid/ch4/include/mpidpre.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mpid/ch4/include/mpidpre.h b/src/mpid/ch4/include/mpidpre.h index 6f2ed729922..a25996e4aba 100644 --- a/src/mpid/ch4/include/mpidpre.h +++ b/src/mpid/ch4/include/mpidpre.h @@ -88,7 +88,6 @@ typedef struct MPIDIG_rreq_t { uint64_t mrcv_count; MPI_Datatype mrcv_datatype; - uint64_t ignore; MPIR_Request *peer_req_ptr; MPIR_Request *match_req; } MPIDIG_rreq_t; From 0981238adbccdc90af5ece510b553ae9ddfbc360 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 17 Sep 2019 16:23:13 -0500 Subject: [PATCH 112/607] ch4: Remove unused globals --- src/mpid/ch4/src/ch4_types.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mpid/ch4/src/ch4_types.h b/src/mpid/ch4/src/ch4_types.h index fb4027d042a..e12430eaa2e 100644 --- a/src/mpid/ch4/src/ch4_types.h +++ b/src/mpid/ch4/src/ch4_types.h @@ -260,8 +260,6 @@ typedef struct MPIDI_per_vci { #define MPIDI_VCI(i) MPIDI_global.per_vci[i] typedef struct MPIDI_CH4_Global_t { - MPIR_Request *request_test; - MPIR_Comm *comm_test; int pname_set; int pname_len; char pname[MPI_MAX_PROCESSOR_NAME]; From d51699644f6a0b55876ae2320923ffc9d4dba270 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Thu, 21 Oct 2021 16:23:58 -0500 Subject: [PATCH 113/607] comm: Fix format specifier for debug message Use PRIu64 to print a uint64_t. --- src/mpi/comm/comm_impl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mpi/comm/comm_impl.c b/src/mpi/comm/comm_impl.c index ee594aa3e53..ab7d854fc00 100644 --- a/src/mpi/comm/comm_impl.c +++ b/src/mpi/comm/comm_impl.c @@ -263,7 +263,7 @@ int MPII_Comm_create_calculate_mapping(MPIR_Group * group_ptr, /* This mapping is relative to comm world */ MPL_DBG_MSG_FMT(MPIR_DBG_COMM, VERBOSE, (MPL_DBG_FDEST, - "comm-create - mapping into world[%d] = %ld", i, g_lpid)); + "comm-create - mapping into world[%d] = %" PRIu64, i, g_lpid)); if (g_lpid < wsize) { mapping[i] = g_lpid; } else { From 5196cb6e90cd0146a25e23d6c235019d36774f4f Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 28 Oct 2021 10:36:37 -0500 Subject: [PATCH 114/607] topo: fix copying dist_graph when it is unweighted When it is unweighted, the weights pointer is NULL. --- src/mpi/topo/topoutil.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/mpi/topo/topoutil.c b/src/mpi/topo/topoutil.c index afc7dc5f913..babdcb6b4fd 100644 --- a/src/mpi/topo/topoutil.c +++ b/src/mpi/topo/topoutil.c @@ -165,10 +165,16 @@ static int MPIR_Topology_copy_fn(MPI_Comm comm ATTRIBUTE((unused)), } else if (old_topology->kind == MPI_DIST_GRAPH) { copy_topology->topo.dist_graph.indegree = old_topology->topo.dist_graph.indegree; copy_topology->topo.dist_graph.outdegree = old_topology->topo.dist_graph.outdegree; + copy_topology->topo.dist_graph.is_weighted = old_topology->topo.dist_graph.is_weighted; MPIR_ARRAY_COPY_HELPER(dist_graph, in, indegree); - MPIR_ARRAY_COPY_HELPER(dist_graph, in_weights, indegree); MPIR_ARRAY_COPY_HELPER(dist_graph, out, outdegree); - MPIR_ARRAY_COPY_HELPER(dist_graph, out_weights, outdegree); + if (old_topology->topo.dist_graph.is_weighted) { + MPIR_ARRAY_COPY_HELPER(dist_graph, in_weights, indegree); + MPIR_ARRAY_COPY_HELPER(dist_graph, out_weights, outdegree); + } else { + copy_topology->topo.dist_graph.in_weights = NULL; + copy_topology->topo.dist_graph.out_weights = NULL; + } } /* --BEGIN ERROR HANDLING-- */ else { From 66131f4dae50400a5a6195728d0ecc7c7315d9ba Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 27 Oct 2021 13:51:51 -0500 Subject: [PATCH 115/607] modules: update libfabric Pull in the commit that patches visibility leak for fi_open. --- modules/libfabric | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/libfabric b/modules/libfabric index 1e6e14fd885..b51d1f1bc87 160000 --- a/modules/libfabric +++ b/modules/libfabric @@ -1 +1 @@ -Subproject commit 1e6e14fd88518587204a13a6c9fa3acace73cdc8 +Subproject commit b51d1f1bc87dde4067f0e997f2ef1fa416c6f6cd From b43221940e420618a19315d8ebb14f02b364d30a Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 27 Oct 2021 13:53:33 -0500 Subject: [PATCH 116/607] modules: update yaksa Pull in the commits that -- * Fixes pmodels/mpich#5554 * ZE fix * Visibility fix --- modules/yaksa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/yaksa b/modules/yaksa index c4957590036..e41b372c74a 160000 --- a/modules/yaksa +++ b/modules/yaksa @@ -1 +1 @@ -Subproject commit c495759003609d867fe7b2060f7a5d3c4820779a +Subproject commit e41b372c74a45a604e8f3851a36b392fd5a06001 From 31007357ac844bdef179d2689631513691c99c58 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 27 Oct 2021 14:18:17 -0500 Subject: [PATCH 117/607] ch4/ofi: add visibility flag to libfabric configure Libfabric used add its own visibility flag. That seems have changed in the recent updates. --- src/mpid/ch4/netmod/ofi/subconfigure.m4 | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mpid/ch4/netmod/ofi/subconfigure.m4 b/src/mpid/ch4/netmod/ofi/subconfigure.m4 index ba5253e2832..71533eb2327 100644 --- a/src/mpid/ch4/netmod/ofi/subconfigure.m4 +++ b/src/mpid/ch4/netmod/ofi/subconfigure.m4 @@ -298,6 +298,7 @@ AM_COND_IF([BUILD_CH4_NETMOD_OFI],[ dnl Unset all of these env vars so they don't pollute the libfabric configuration PAC_PUSH_ALL_FLAGS() PAC_RESET_ALL_FLAGS() + CFLAGS="$CFLAGS $VISIBILITY_CFLAGS" PAC_CONFIG_SUBDIR_ARGS([modules/libfabric],[$ofi_subdir_args],[],[AC_MSG_ERROR(libfabric configure failed)]) PAC_POP_ALL_FLAGS() PAC_APPEND_FLAG([-I${main_top_builddir}/modules/libfabric/include], [CPPFLAGS]) From e9661e28d81b8ad8cd9a31d27efb335f455e9604 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 27 Oct 2021 14:23:11 -0500 Subject: [PATCH 118/607] mpl: add visibility flag The MPL functions are leaking into the mpich dynamic symbol tables. Make sure to add the visibility cflags to hide the symbols. --- confdb/aclocal_modules.m4 | 5 ++++ configure.ac | 50 +++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/confdb/aclocal_modules.m4 b/confdb/aclocal_modules.m4 index ab07c80acce..4c92ca02266 100644 --- a/confdb/aclocal_modules.m4 +++ b/confdb/aclocal_modules.m4 @@ -3,7 +3,12 @@ dnl ==== mpl ==== dnl internal routine AC_DEFUN([PAC_CONFIG_MPL_EMBEDDED],[ mpl_subdir_args="--disable-versioning --enable-embedded" + PAC_PUSH_FLAG([CFLAGS]) + if test -n "$VISIBILITY_CFLAGS" ; then + CFLAGS="$CFLAGS $VISIBILITY_CFLAGS" + fi PAC_CONFIG_SUBDIR_ARGS(mpl_embedded_dir,[$mpl_subdir_args],[],[AC_MSG_ERROR(MPL configure failed)]) + PAC_POP_FLAG([CFLAGS]) ]) AC_DEFUN([PAC_CONFIG_MPL],[ diff --git a/configure.ac b/configure.ac index 4c7b682dc20..8e3fa086dc3 100644 --- a/configure.ac +++ b/configure.ac @@ -986,6 +986,31 @@ if test "$enable_extended_context_bits" = "yes" ; then AC_DEFINE([HAVE_EXTENDED_CONTEXT_BITS],[1],[Define to enable extended context id bit space]) fi +# Set NEEDSPLIB to yes if link commands need both -l$MPILIBNAME +# and -lp$MPILIBNAME. +NEEDSPLIB=yes +if test $enable_weak_symbols = yes ; then + # Turn off weak symbols if they aren't available + PAC_PROG_C_WEAK_SYMBOLS(,enable_weak_symbols=no) +fi +if test $enable_weak_symbols = "yes" ; then + AC_DEFINE(USE_WEAK_SYMBOLS,1,[Define if weak symbols should be used]) + NEEDSPLIB=no + # Check for the ability to support multiple weak symbols + if test "$pac_cv_prog_c_weak_symbols" = "pragma weak" ; then + PAC_PROG_C_MULTIPLE_WEAK_SYMBOLS(AC_DEFINE(HAVE_MULTIPLE_PRAGMA_WEAK,1,[Define if multiple weak symbols may be defined])) + fi +fi +export NEEDSPLIB + +AM_CONDITIONAL([BUILD_PROFILING_LIB],[test "$NEEDSPLIB" = "yes"]) +PAC_CHECK_VISIBILITY +AC_SUBST(VISIBILITY_CFLAGS) +# disable visibility if building profiling library +if test "$NEEDSPLIB" = "yes" ; then + VISIBILITY_CFLAGS="" +fi + # MPL mplsrcdir="" AC_SUBST([mplsrcdir]) @@ -1033,31 +1058,6 @@ if test "$enable_izem_queue" != "no" && test "$enable_izem_queue" != "none"; the fi -# Set NEEDSPLIB to yes if link commands need both -l$MPILIBNAME -# and -lp$MPILIBNAME. -NEEDSPLIB=yes -if test $enable_weak_symbols = yes ; then - # Turn off weak symbols if they aren't available - PAC_PROG_C_WEAK_SYMBOLS(,enable_weak_symbols=no) -fi -if test $enable_weak_symbols = "yes" ; then - AC_DEFINE(USE_WEAK_SYMBOLS,1,[Define if weak symbols should be used]) - NEEDSPLIB=no - # Check for the ability to support multiple weak symbols - if test "$pac_cv_prog_c_weak_symbols" = "pragma weak" ; then - PAC_PROG_C_MULTIPLE_WEAK_SYMBOLS(AC_DEFINE(HAVE_MULTIPLE_PRAGMA_WEAK,1,[Define if multiple weak symbols may be defined])) - fi -fi -export NEEDSPLIB - -AM_CONDITIONAL([BUILD_PROFILING_LIB],[test "$NEEDSPLIB" = "yes"]) -PAC_CHECK_VISIBILITY -AC_SUBST(VISIBILITY_CFLAGS) -# disable visibility if building profiling library -if test "$NEEDSPLIB" = "yes" ; then - VISIBILITY_CFLAGS="" -fi - # json-c jsonsrcdir="" From 8090f3d03e39b3a9fbce0a2d07f34bd6234996d2 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 19 Oct 2021 11:06:47 -0500 Subject: [PATCH 119/607] configure: remove unused use_alias_types branch The branch was a left-over from MPI-1. The alternate branch is correct for MPI-1 anyway. --- configure.ac | 79 +++++++++------------------------------------------- 1 file changed, 13 insertions(+), 66 deletions(-) diff --git a/configure.ac b/configure.ac index 8e3fa086dc3..8b1f43bb4ff 100644 --- a/configure.ac +++ b/configure.ac @@ -3608,73 +3608,20 @@ dnl Removed MPI_2COMPLEX and MPI_2DOUBLE_COMPLEX, leaving comments to explain th double_mpi=${MPI_DOUBLE:-0} long_double_mpi=${MPI_LONG_DOUBLE:-0} - # - # The following code was correct for MPI-1, which allowed these datatypes - # to be an alias for another MPI type. MPI-2 requires these to - # be distinct types, so these are enumerated - if test "$use_alias_types" = yes ; then - for len in 1 2 4 8 16 ; do - eval F77_INTEGER$len=0 - #eval testval=\$"pac_cv_f77_sizeof_integer_$len" - eval testval=\$"pac_cv_fort_integer$len" - if test "$testval" = no ; then continue ; fi - testval=$len - noval="yes" - AC_MSG_CHECKING([for C type matching Fortran integer*$len]) - for c_type in char short int long "long_long" ; do - eval ctypelen=\$"ac_cv_sizeof_$c_type" - if test "$testval" = "$ctypelen" -a "$ctypelen" -gt 0 ; then - AC_MSG_RESULT($c_type) - eval F77_INTEGER$len=\$"${c_type}_mpi" - noval="no" - break - fi - done - if test "$noval" = "yes" ; then - AC_MSG_RESULT([unavailable]) - fi - done + # Simply determine which types exist. These may have been set by the + # toplevel configure + for var in INTEGER1 INTEGER2 INTEGER4 INTEGER8 INTEGER16 \ + REAL4 REAL8 REAL16 COMPLEX8 COMPLEX16 COMPLEX32 ; do + eval varname=MPI_$var + eval varvalue=\$$varname + #echo "$varname = $varvalue" + if test "$varvalue" = MPI_DATATYPE_NULL ; then + eval F77_$var=0 + else + eval F77_$var=\$$varname + fi + done - # Complex is set separately above - for len in 4 8 16 ; do - len2=`expr $len + $len` - eval F77_REAL$len=0 - #eval F77_COMPLEX$len2=0 - #eval testval=\$"pac_cv_f77_sizeof_real_$len" - eval testval=\$"pac_cv_fort_real$len" - if test "$testval" = no ; then continue ; fi - testval=$len - noval="yes" - AC_MSG_CHECKING([for C type matching Fortran real*$len]) - for c_type in float double "long_double" ; do - eval ctypelen=\$"ac_cv_sizeof_$c_type" - if test "$testval" = "$ctypelen" -a "$ctypelen" -gt 0 ; then - AC_MSG_RESULT($c_type) - eval F77_REAL$len=\$"${c_type}_mpi" - #eval F77_COMPLEX$len2=\$"${c_type}_cplx_mpi" - noval="no" - break - fi - done - if test "$noval" = "yes" ; then - AC_MSG_RESULT([unavailable]) - fi - done - else - # Simply determine which types exist. These may have been set by the - # toplevel configure - for var in INTEGER1 INTEGER2 INTEGER4 INTEGER8 INTEGER16 \ - REAL4 REAL8 REAL16 COMPLEX8 COMPLEX16 COMPLEX32 ; do - eval varname=MPI_$var - eval varvalue=\$$varname - #echo "$varname = $varvalue" - if test "$varvalue" = MPI_DATATYPE_NULL ; then - eval F77_$var=0 - else - eval F77_$var=\$$varname - fi - done - fi # We must convert all hex values to decimal (!) for var in INTEGER1 INTEGER2 INTEGER4 INTEGER8 INTEGER16 \ REAL4 REAL8 REAL16 COMPLEX8 COMPLEX16 COMPLEX32 ; do From 1cb523ffee2243ee7127723500514f8e6cce0645 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 19 Oct 2021 21:49:23 -0500 Subject: [PATCH 120/607] configure: remove F77_COMPLEX8 etc These symbols were unused. --- configure.ac | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/configure.ac b/configure.ac index 8b1f43bb4ff..87f46533349 100644 --- a/configure.ac +++ b/configure.ac @@ -3530,22 +3530,6 @@ dnl Removed MPI_2COMPLEX and MPI_2DOUBLE_COMPLEX, leaving comments to explain th # MPI_2COMPLEX=0x4c00${len_doublecplx}24 # MPI_2DOUBLE_COMPLEX=0x4c00${len_2dc}25 - # - # Temporary for the vast majority of systems that use 4 byte reals and - # 8 byte doubles - # Lengths at this point are in hex, hence "10" = 10 base 16 = 16 base 10. - if test "$len_double" = "08" ; then - F77_COMPLEX8=$MPI_COMPLEX - fi - if test "$len_doublecplx" = "10" ; then - F77_COMPLEX16=$MPI_DOUBLE_COMPLEX - fi - if test "$len_long_double" = "10" -a "$MPID_NO_LONG_DOUBLE" != "yes" ; then - F77_COMPLEX32="0x4c002025" - else - F77_COMPLEX32="MPI_DATATYPE_NULL" - fi - MPI_F77_PACKED=$MPI_PACKED MPI_F77_UB=$MPI_UB MPI_F77_LB=$MPI_LB From 615e9a512bc6f9a67f7155fe4215545438551eaf Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 18 Oct 2021 23:59:46 -0500 Subject: [PATCH 121/607] configure: refactor datatype configurations Define and use macros such as PAC_SET_MPI_TYPE to make code cleaner. Organize the code that configures MPI datatypes. Use following order -- * Check Datatype Sizes and Alignment * C types using AC_CHECK_SIZEOF * Fortran types using PAC_PROG_F77_CHECK_SIZEOF_EXT * For optional types, if not available or disabled, set sizes to 0 * Set sizes for MPI_AINT, MPI_OFFSET, and MPI_COUNT * Use PAC_SET_MPI_TYPE set basic datatype values * MPI_{TYPE} for hexadecimal values to be replaced in mpi.h.in * F77_MPI_{TYPE} for decimal values to be replaced in mpif.h.in * F08_MPI_{TYPE} for decimal values to be replaced in mpi_f08_compile_constants.f90.in --- confdb/aclocal_datatype.m4 | 183 ++++ configure.ac | 1617 ++++++++---------------------------- 2 files changed, 520 insertions(+), 1280 deletions(-) create mode 100644 confdb/aclocal_datatype.m4 diff --git a/confdb/aclocal_datatype.m4 b/confdb/aclocal_datatype.m4 new file mode 100644 index 00000000000..727e57e0aa1 --- /dev/null +++ b/confdb/aclocal_datatype.m4 @@ -0,0 +1,183 @@ +dnl Utilities in shell functions - reduces size in configure script +dnl These functions sets $pac_retval +dnl +AC_DEFUN([PAC_DATATYPE_UTILS], [ +# Take decimal and turn it into two hex digits +to_hex() { + len=$[]1 + if test $len -le 9 ; then + dnl avoid subshell for speed + pac_retval="0${len}" + elif test $len -eq 16 ; then + pac_retval="10" + elif test $len -eq 32 ; then + pac_retval="20" + else + dnl printf is portable enough + pac_retval=`printf "%02x" $len` + fi +} + +# Convert hex values in the form of 0x######## to decimal for +# datatype constants in Fortran. +to_dec() { + orig_value=$[]1 + dnl printf is portable enough + pac_retval=`printf "%d" $orig_value` +} + +# return the C type matching integer of size +get_c_int_type() { + len=$[]1 + pac_retval= + for c_type in char short int long "long_long" ; do + eval ctypelen=\$"ac_cv_sizeof_$c_type" + if test "$len" = "$ctypelen" -a "$ctypelen" -gt 0 ; then + if test "$c_type" = "long_long" ; then + pac_retval=`echo $c_type | sed -e 's/_/ /g'` + else + pac_retval=$c_type + fi + return + fi + done + pac_retval="unavailable" +} + +# return the C type matching integer of size +get_c_float_type() { + len=$[]1 + pac_retval= + for c_type in float double __float128 "long_double" ; do + eval ctypelen=\$"ac_cv_sizeof_$c_type" + if test "$len" = "$ctypelen" -a "$ctypelen" -gt 0 ; then + if test "$c_type" = "long_double" ; then + pac_retval=`echo $c_type | sed -e 's/_/ /g'` + else + pac_retval=$c_type + fi + return + fi + done + pac_retval="unavailable" +} + +# return (via $pac_retval) the C type matching integer of size +get_c_bool_type() { + len=$[]1 + pac_retval= + for c_type in _Bool unsigned_char unsigned_short unsigned_int unsigned_long unsigned_long_long ; do + eval ctypelen=\$"ac_cv_sizeof_$c_type" + if test "$len" = "$ctypelen" -a "$ctypelen" -gt 0 ; then + if test "$c_type" != "_Bool" ; then + pac_retval=`echo $c_type | sed -e 's/_/ /g'` + else + pac_retval=$c_type + fi + return + fi + done + pac_retval="unavailable" +} +]) + +dnl +dnl PAC_SET_MPI_TYPE(hexidx, name, len, [multiplier]) +dnl Defines datatype hex handle +dnl e.g. PAC_SET_MPI_TYPE(01, MPI_CHAR, 1) -> MPI_CHAR=0x4c000101 +dnl Multiplier can be used to define double types +dnl e.g. PAC_SET_MPI_TYPE(48, MPI_COMPLEX, $pac_cv_f77_sizeof_real, 2) +dnl +AC_DEFUN([PAC_SET_MPI_TYPE], [ + if test $3 = 0 ; then + $2=MPI_DATATYPE_NULL + F77_$2=MPI_DATATYPE_NULL + F08_$2=MPI_DATATYPE_NULL%MPI_VAL + else + hexidx=$1 + + if test -n "$4" ; then + len=`expr $3 \* $4` + else + len=$3 + fi + to_hex $len + + hexlen=$pac_retval + + $2="0x4c00${hexlen}${hexidx}" + to_dec $[]$2 + F77_$2=$pac_retval + F08_$2=$pac_retval + fi + AC_SUBST($2) + AC_SUBST(F77_$2) + AC_SUBST(F08_$2) +]) + +dnl +dnl PAC_SET_MPI_LBUB(hex_idx, name) +dnl e.g. PAC_SET_MPI_LBUB(10, MPI_LB) -> MPI_LB=0x4c000010 +dnl +AC_DEFUN([PAC_SET_MPI_LBUB], [ + $2="0x4c0000$1" + to_dec $[]$2 + F77_$2=$pac_retval + F08_$2=$pac_retval + AC_SUBST($2) + AC_SUBST(F77_$2) + AC_SUBST(F08_$2) +]) + +dnl +dnl PAC_SET_MPI_PAIRTYPE(hexidx, name) +dnl e.g. PAC_SET_MPI_PAIRTYPE(02, MPI_LONG_INT) -> MPI_LONG_INT=0x8c000002 +dnl +AC_DEFUN([PAC_SET_MPI_PAIRTYPE], [ + $2="0x8c0000$1" + # 0x8c000000 is -1946157056 + pac_retval=`expr $1 - 1946157056` + F77_$2=$pac_retval + F08_$2=$pac_retval + AC_SUBST($2) + AC_SUBST(F77_$2) + AC_SUBST(F08_$2) +]) + +dnl +dnl PAC_SET_MPI_DATATYPE_ALIAS(name, alias) +dnl +AC_DEFUN([PAC_SET_MPI_DATATYPE_ALIAS], [ + $1=$[]$2 + F77_$1=$F77_$2 + F08_$1=$F08_$2 + AC_SUBST($1) + AC_SUBST(F77_$1) + AC_SUBST(F08_$1) +]) + +dnl +dnl PAC_F77_CHECK_FIXED_REAL(size) and PAC_F77_CHECK_FIXED_INTEGER(size) +dnl Map fixed-size Fortran types, e.g. REAL*4, to equivallent C types. +dnl If no equivallent C types exist, set corresponding sizeof value to 0. +dnl +AC_DEFUN([PAC_F77_CHECK_FIXED_REAL], [ + get_c_float_type $1 + if test "$pac_retval" = "unavailable" ; then + eval pac_cv_f77_sizeof_real$1=0 + else + eval pac_cv_f77_sizeof_real$1=$1 + AC_DEFINE_UNQUOTED(MPIR_REAL$1_CTYPE,$pac_retval,[C type to use for MPI_REAL$1]) + fi +]) + +AC_DEFUN([PAC_F77_CHECK_FIXED_INTEGER], [ + get_c_int_type $1 + if test "$pac_retval" = "unavailable" ; then + eval pac_cv_f77_sizeof_integer$1=0 + else + eval pac_cv_f77_sizeof_integer$1=$1 + AC_DEFINE_UNQUOTED(MPIR_REAL$1_CTYPE,$pac_retval,[C type to use for MPI_INTEGER$1]) + fi +]) + diff --git a/configure.ac b/configure.ac index 87f46533349..ae60d207f7e 100644 --- a/configure.ac +++ b/configure.ac @@ -2344,18 +2344,6 @@ if test "$enable_cxx" = "yes" ; then # the CPP name space AC_SUBST(FORTRAN_BINDING) - # Special C++ datatypes. Set to DATATYPE NULL first; we'll - # replace the ones that we have later, after we have determined - # the C datatypes - MPIR_CXX_BOOL=0x0c000000 - MPIR_CXX_COMPLEX=0x0c000000 - MPIR_CXX_DOUBLE_COMPLEX=0x0c000000 - MPIR_CXX_LONG_DOUBLE_COMPLEX=0x0c000000 - AC_SUBST(MPIR_CXX_BOOL) - AC_SUBST(MPIR_CXX_COMPLEX) - AC_SUBST(MPIR_CXX_DOUBLE_COMPLEX) - AC_SUBST(MPIR_CXX_LONG_DOUBLE_COMPLEX) - # determine shared library flags for CXX cxx_shlib_conf=src/env/cxx_shlib.conf PAC_COMPILER_SHLIB_FLAGS([CXX],[$cxx_shlib_conf]) @@ -2747,6 +2735,8 @@ AC_CHECK_SIZEOF(wchar_t, 0, [ #endif ]) +AC_CHECK_SIZEOF(_BOOL, 0) + AC_CHECK_SIZEOF(__float128, 0) if test "$ac_cv_sizeof___float128" = "16" ; then AC_DEFINE(HAVE_FLOAT128, 1, [Define if __float128 is supported]) @@ -2863,365 +2853,22 @@ AS_IF([test "X$pac_cv_have_long_double" = "Xyes"],[ AC_CHECK_TYPES([long double _Complex]) ]) +dnl define shell functions e.g. to_hex, to_dec, get_c_int_type, get_c_float_type +PAC_DATATYPE_UTILS() + # Generate a hex version of the size of each type -for type in short int long long_long float double long_double wchar_t \ - float_int double_int long_int short_int two_int long_double_int \ - _Bool float__Complex double__Complex long_double__Complex \ - _Float16; do +for type in short int long float double \ + float_int double_int long_int short_int two_int ; do eval len=\$ac_cv_sizeof_$type if test -z "$len" ; then - len=0 - # Check for sizes from the CHECK_SIZEOF_DERIVED macro - eval pclen=\$ac_cv_sizeof_$type - if test -n "$pclen" ; then - len=$pclen - else - # check for a non-optional type - if test $type != long_long -a \ - $type != long_double -a \ - $type != long_double_int -a \ - $type != _Bool -a \ - $type != float__Complex -a \ - $type != double__Complex -a \ - $type != long_double__Complex ; then - AC_MSG_ERROR([Configure was unable to determine the size of $type ; if cross compiling, + AC_MSG_ERROR([Configure was unable to determine the size of $type ; if cross compiling, use the environment variables CROSS_SIZEOF_typename, e.g., CROSS_SIZEOF_SHORT, or use the --with-cross=file configure option to specify a file containing Bourne (sh) shell assignments to CROSS_SIZEOF_typename for all datatype types. The program maint/getcross.c can be compiled and run on the target system; this program outputs an appropriate file for the --with-cross option]) - fi - fi - fi - # - # Take len and turn it into two hex digits (there are 8 bits available - # in the built-in datatype handle for the length; see - # src/mpid/common/datatype/mpidu_datatype.h) - if test "$len" -gt 255 ; then - AC_MSG_ERROR([Type sizes greater than 255 bytes are not supported (type $type is $len bytes)]) - fi - tmplen=$len - hexlen="" - while test $tmplen -gt 0 ; do - lowdigit=`expr $tmplen - 16 \* \( $tmplen / 16 \)` - case $lowdigit in - 10) char=a ;; - 11) char=b ;; - 12) char=c ;; - 13) char=d ;; - 14) char=e ;; - 15) char=f ;; - *) char=$lowdigit ;; - esac - hexlen="$char$hexlen" - tmplen=`expr $tmplen / 16` - done - if test $len -lt 16 ; then - hexlen="0$hexlen" - fi - if test $len = 0 ; then - # This sometimes happens for wchar_t - hexlen="00"; - fi - eval len_$type=$hexlen -done -# By definition, sizeof char is 1 -MPI_CHAR="0x4c000101" -MPI_UNSIGNED_CHAR="0x4c000102" -MPI_SHORT="0x4c00${len_short}03" -MPI_UNSIGNED_SHORT="0x4c00${len_short}04" -MPI_INT="0x4c00${len_int}05" -MPI_UNSIGNED_INT="0x4c00${len_int}06" -MPI_LONG="0x4c00${len_long}07" -MPI_UNSIGNED_LONG="0x4c00${len_long}08" -if test "$len_long_long" != 0 -a "$MPID_NO_LONG_LONG" != yes ; then - MPI_LONG_LONG="0x4c00${len_long_long}09" -else - MPI_LONG_LONG=MPI_DATATYPE_NULL; -fi -MPI_FLOAT="0x4c00${len_float}0a" -MPI_DOUBLE="0x4c00${len_double}0b" -if test "$len_long_double" != 0 -a "$MPID_NO_LONG_DOUBLE" != yes ; then - MPI_LONG_DOUBLE="0x4c00${len_long_double}0c" -else - MPI_LONG_DOUBLE=MPI_DATATYPE_NULL -fi -# If you change MPI_BYTE, you must change it in src/binding/fortran/mpif_h/buildiface -MPI_BYTE="0x4c00010d" -MPI_WCHAR="0x4c00${len_wchar_t}0e" -MPI_PACKED="0x4c00010f" -MPI_LB="0x4c000010" -MPI_UB="0x4c000011" -# -# These should define the mixed types *only* for contiguous data. -# For example, MPI_SHORT_INT may have a gap; it will need to be defined -# as a derived type instead. For IA32, this only affects short_int. -MPI_2INT="0x4c00${len_two_int}16" -# -# For now we aren't being too clever about figuring out which of these -# are in fact contiguous, so these are all allocated as "real" types. -# -# These values correspond to direct types 0..5. -# -dnl MPI_FLOAT_INT="0x4c00${len_float_int}12" -dnl MPI_DOUBLE_INT="0x4c00${len_double_int}13" -dnl MPI_LONG_INT="0x4c00${len_long_int}14" -dnl MPI_SHORT_INT="0x4c00${len_short_int}15" -dnl MPI_LONG_DOUBLE_INT="0x4c00${len_long_double_int}17" -MPI_FLOAT_INT="0x8c000000" -MPI_DOUBLE_INT="0x8c000001" -MPI_LONG_INT="0x8c000002" -MPI_SHORT_INT="0x8c000003" -if test "$MPID_NO_LONG_DOUBLE" != yes ; then - MPI_LONG_DOUBLE_INT="0x8c000004" -else - MPI_LONG_DOUBLE_INT=MPI_DATATYPE_NULL -fi - -# 2 additional predefined types named in MPI-2 -MPI_SIGNED_CHAR="0x4c000118" -if test "$len_long_long" != 0 -a "$MPID_NO_LONG_LONG" != yes ; then - MPI_UNSIGNED_LONG_LONG="0x4c00${len_long_long}19" -else - MPI_UNSIGNED_LONG_LONG=MPI_DATATYPE_NULL -fi - -AC_SUBST(MPI_CHAR) -AC_SUBST(MPI_UNSIGNED_CHAR) -AC_SUBST(MPI_SHORT) -AC_SUBST(MPI_UNSIGNED_SHORT) -AC_SUBST(MPI_INT) -AC_SUBST(MPI_UNSIGNED_INT) -AC_SUBST(MPI_LONG) -AC_SUBST(MPI_UNSIGNED_LONG) -AC_SUBST(MPI_LONG_LONG) -AC_SUBST(MPI_FLOAT) -AC_SUBST(MPI_DOUBLE) -AC_SUBST(MPI_LONG_DOUBLE) -AC_SUBST(MPI_BYTE) -AC_SUBST(MPI_WCHAR) -AC_SUBST(MPI_PACKED) -AC_SUBST(MPI_LB) -AC_SUBST(MPI_UB) -AC_SUBST(MPI_FLOAT_INT) -AC_SUBST(MPI_DOUBLE_INT) -AC_SUBST(MPI_LONG_INT) -AC_SUBST(MPI_SHORT_INT) -AC_SUBST(MPI_2INT) -AC_SUBST(MPI_LONG_DOUBLE_INT) -AC_SUBST(MPI_SIGNED_CHAR) -AC_SUBST(MPI_UNSIGNED_LONG_LONG) -# -# FIXME: Leftover from separate fortran system -## Export the basic C types so that the Fortran system can use them -#export MPI_CHAR -#export MPI_SHORT -#export MPI_INT -#export MPI_LONG -#export MPI_LONG_LONG -#export MPI_FLOAT -#export MPI_DOUBLE -#export MPI_LONG_DOUBLE -# -# Size-specific types. Initialize as NULL -MPI_REAL4=MPI_DATATYPE_NULL -MPI_REAL8=MPI_DATATYPE_NULL -MPI_REAL16=MPI_DATATYPE_NULL -MPI_COMPLEX8=MPI_DATATYPE_NULL -MPI_COMPLEX16=MPI_DATATYPE_NULL -MPI_COMPLEX32=MPI_DATATYPE_NULL -MPI_INTEGER1=MPI_DATATYPE_NULL -MPI_INTEGER2=MPI_DATATYPE_NULL -MPI_INTEGER4=MPI_DATATYPE_NULL -MPI_INTEGER8=MPI_DATATYPE_NULL -MPI_INTEGER16=MPI_DATATYPE_NULL -AC_SUBST(MPI_REAL4) -AC_SUBST(MPI_REAL8) -AC_SUBST(MPI_REAL16) -AC_SUBST(MPI_COMPLEX8) -AC_SUBST(MPI_COMPLEX16) -AC_SUBST(MPI_COMPLEX32) -AC_SUBST(MPI_INTEGER1) -AC_SUBST(MPI_INTEGER2) -AC_SUBST(MPI_INTEGER4) -AC_SUBST(MPI_INTEGER8) -AC_SUBST(MPI_INTEGER16) -export MPI_REAL4 -export MPI_REAL8 -export MPI_REAL16 -export MPI_COMPLEX8 -export MPI_COMPLEX16 -export MPI_COMPLEX32 -export MPI_INTEGER1 -export MPI_INTEGER2 -export MPI_INTEGER4 -export MPI_INTEGER8 -export MPI_INTEGER16 -# -# Try to find corresponding types for the size-specific types. -# -# Assume that the float/double/long double are simply spaced -# Datatypes used up through 26 in Fortran -# 27,28,29,2a,2b,2c -if test "$ac_cv_sizeof_float" = "4" ; then - MPI_REAL4="0x4c000427" - MPI_COMPLEX8="0x4c000828" - MPIR_REAL4_CTYPE=float -fi -if test "$ac_cv_sizeof_double" = "8" ; then - MPI_REAL8="0x4c000829" - MPI_COMPLEX16="0x4c00102a" - MPIR_REAL8_CTYPE=double -fi -if test "$ac_cv_sizeof___float128" = "16" ; then - MPI_REAL16="0x4c00102b" - MPI_COMPLEX32="0x4c00202c" - MPIR_REAL16_CTYPE="__float128" -elif test "$ac_cv_sizeof_long_double" = "16" -a "$MPID_NO_LONG_DOUBLE" != yes ; then - MPI_REAL16="0x4c00102b" - MPI_COMPLEX32="0x4c00202c" - MPIR_REAL16_CTYPE="long double" -fi -if test -n "$MPIR_REAL4_CTYPE" ; then - AC_DEFINE_UNQUOTED(MPIR_REAL4_CTYPE,$MPIR_REAL4_CTYPE,[C type to use for MPI_REAL4]) -fi -if test -n "$MPIR_REAL8_CTYPE" ; then - AC_DEFINE_UNQUOTED(MPIR_REAL8_CTYPE,$MPIR_REAL8_CTYPE,[C type to use for MPI_REAL8]) -fi -if test -n "$MPIR_REAL16_CTYPE" ; then - AC_DEFINE_UNQUOTED(MPIR_REAL16_CTYPE,$MPIR_REAL16_CTYPE,[C type to use for MPI_REAL16]) -fi -# For complex 8/16/32, we assume that these are 2 consecutive real4/8/16 -# -# Search for the integer types -for type in char short int long long_long ; do - # ctype is a valid C type which we can use to declare a C version of - # this item - ctype=`echo $type | sed 's/_/ /'` - eval len=\$ac_cv_sizeof_$type - if test -n "$len" ; then - case $len in - 1) if test "$MPI_INTEGER1" = "MPI_DATATYPE_NULL" ; then - MPI_INTEGER1="0x4c00012d" - MPIR_INTEGER1_CTYPE="$ctype" - fi - ;; - 2) if test "$MPI_INTEGER2" = "MPI_DATATYPE_NULL" ; then - MPI_INTEGER2="0x4c00022f" - MPIR_INTEGER2_CTYPE="$ctype" - fi - ;; - 4) if test "$MPI_INTEGER4" = "MPI_DATATYPE_NULL" ; then - MPI_INTEGER4="0x4c000430" - MPIR_INTEGER4_CTYPE="$ctype" - fi - ;; - 8) if test "$MPI_INTEGER8" = "MPI_DATATYPE_NULL" ; then - MPI_INTEGER8="0x4c000831" - MPIR_INTEGER8_CTYPE="$ctype" - fi - ;; - 16) if test "$MPI_INTEGER16" = "MPI_DATATYPE_NULL" ; then - MPI_INTEGER16="0x4c001032" - MPIR_INTEGER16_CTYPE="$ctype" - fi - ;; - *) - ;; - esac fi done -# -# Add the definitions of these types -if test -n "$MPIR_INTEGER1_CTYPE" ; then - AC_DEFINE_UNQUOTED(MPIR_INTEGER1_CTYPE,$MPIR_INTEGER1_CTYPE,[C type to use for MPI_INTEGER1]) -fi -if test -n "$MPIR_INTEGER2_CTYPE" ; then - AC_DEFINE_UNQUOTED(MPIR_INTEGER2_CTYPE,$MPIR_INTEGER2_CTYPE,[C type to use for MPI_INTEGER2]) -fi -if test -n "$MPIR_INTEGER4_CTYPE" ; then - AC_DEFINE_UNQUOTED(MPIR_INTEGER4_CTYPE,$MPIR_INTEGER4_CTYPE,[C type to use for MPI_INTEGER4]) -fi -if test -n "$MPIR_INTEGER8_CTYPE" ; then - AC_DEFINE_UNQUOTED(MPIR_INTEGER8_CTYPE,$MPIR_INTEGER8_CTYPE,[C type to use for MPI_INTEGER8]) -fi -if test -n "$MPIR_INTEGER16_CTYPE" ; then - AC_DEFINE_UNQUOTED(MPIR_INTEGER16_CTYPE,$MPIR_INTEGER16_CTYPE,[C type to use for MPI_INTEGER16]) -fi - -# ---------------------------------------------------------------------------- - -# C99 types -# The predefined types must be distinct types (as opposed to aliases to MPI_INT -# or MPI_WHATEVER) in order to correctly support MPI_Type_{get,set}_name. -# -# FIXME the "basic id" portion should be automatically assigned. It's too easy -# to have a conflict when this is done by hand. -# -# Because we make up a matching type for the fixed-width types if one doesn't -# exist, we don't ever set these to MPI_DATATYPE_NULL. If we come across a -# platform where 64-bit sizes aren't supported just add a test like the other -# types. -MPI_INT8_T=0x4c000137 -MPI_INT16_T=0x4c000238 -MPI_INT32_T=0x4c000439 -MPI_INT64_T=0x4c00083a -MPI_UINT8_T=0x4c00013b -MPI_UINT16_T=0x4c00023c -MPI_UINT32_T=0x4c00043d -MPI_UINT64_T=0x4c00083e - -# The compiler may or may not support these types, depending on its level of C99 -# compliance. We check for each one individually before assigning a handle -# number. -MPI_C_BOOL=MPI_DATATYPE_NULL -MPI_C_FLOAT_COMPLEX=MPI_DATATYPE_NULL -MPI_C_DOUBLE_COMPLEX=MPI_DATATYPE_NULL -MPI_C_LONG_DOUBLE_COMPLEX=MPI_DATATYPE_NULL -MPIX_C_FLOAT16=MPI_DATATYPE_NULL -if test ${len__Bool} != 0 ; then - MPI_C_BOOL=0x4c00${len__Bool}3f -fi -if test ${len_float__Complex} != 0 ; then - MPI_C_FLOAT_COMPLEX=0x4c00${len_float__Complex}40 -fi -if test ${len_double__Complex} != 0 ; then - MPI_C_DOUBLE_COMPLEX=0x4c00${len_double__Complex}41 -fi -if test ${len_long_double__Complex} != 0 ; then - MPI_C_LONG_DOUBLE_COMPLEX=0x4c00${len_long_double__Complex}42 -fi -if test ${len__Float16} != 0 ; then - MPIX_C_FLOAT16=0x4c000246 -fi - -AC_SUBST(MPI_INT8_T) -AC_SUBST(MPI_INT16_T) -AC_SUBST(MPI_INT32_T) -AC_SUBST(MPI_INT64_T) -AC_SUBST(MPI_UINT8_T) -AC_SUBST(MPI_UINT16_T) -AC_SUBST(MPI_UINT32_T) -AC_SUBST(MPI_UINT64_T) -AC_SUBST(MPI_C_BOOL) -AC_SUBST(MPI_C_FLOAT_COMPLEX) -AC_SUBST(MPI_C_DOUBLE_COMPLEX) -AC_SUBST(MPI_C_LONG_DOUBLE_COMPLEX) -AC_SUBST(MPIX_C_FLOAT16) -export MPI_INT8_T -export MPI_INT16_T -export MPI_INT32_T -export MPI_INT64_T -export MPI_UINT8_T -export MPI_UINT16_T -export MPI_UINT32_T -export MPI_UINT64_T -export MPI_C_BOOL -export MPI_C_FLOAT_COMPLEX -export MPI_C_DOUBLE_COMPLEX -export MPI_C_LONG_DOUBLE_COMPLEX -export MPIX_C_FLOAT16 - # ---------------------------------------------------------------------------- # We can now create the Fortran versions of the datatype values, along with @@ -3241,6 +2888,8 @@ export MPIX_C_FLOAT16 # # ---------------------------------------------------------------------------- if test "$enable_f77" = yes ; then + pac_cv_f77_sizeof_character=1 + # Up to size checking code in main configure.ac (where it tries to # find the matching C sizes) as part of defining mpi_integer8 etc. # The results are available in pac_cv_sizeof_f77_ @@ -3294,55 +2943,10 @@ if test "$enable_f77" = yes ; then pac_cv_fort_real16=yes, pac_cv_fort_real16=no)]) - # Create the default datatype names for the standard MPI Fortran types - MPI_CHARACTER=0x4c00011a - AC_SUBST(MPI_CHARACTER) - if test -z "$pac_cv_f77_sizeof_integer" -o \ "X$pac_cv_f77_sizeof_integer" = "X0" ; then AC_MSG_ERROR([Unable to configure with Fortran support because configure could not determine the size of a Fortran INTEGER. Consider setting CROSS_F77_SIZEOF_INTEGER to the length in bytes of a Fortran INTEGER]) fi - len_integer=$pac_cv_f77_sizeof_integer - # Convert to two digit hex - len=$len_integer - # - # Take len and turn it into two hex digits (there are 8 bits available - # in the built-in datatype handle for the length; see - # src/mpid/common/datatype/mpidu_datatype.h). This code is taken - # from the code in mpich/configure.ac - if test "$len" -gt 255 ; then - AC_MSG_ERROR([Type sizes greater than 255 bytes are not supported (type INTEGER is $len bytes)]) - fi - tmplen=$len - hexlen="" - while test $tmplen -gt 0 ; do - lowdigit=`expr $tmplen - 16 \* \( $tmplen / 16 \)` - case $lowdigit in - 10) char=a ;; - 11) char=b ;; - 12) char=c ;; - 13) char=d ;; - 14) char=e ;; - 15) char=f ;; - *) char=$lowdigit ;; - esac - hexlen="$char$hexlen" - tmplen=`expr $tmplen / 16` - done - if test $len -lt 16 ; then - hexlen="0$hexlen" - fi - len_integer=$hexlen - if test "$len_integer" = 0 ; then - # We have a problem - AC_MSG_WARN([Unable to determine size of an INTEGER type; using 4]) - # We make the length 4 - len_integer="04" - fi - MPI_INTEGER=0x4c00${len_integer}1b - MPI_LOGICAL=0x4c00${len_integer}1d - AC_SUBST(MPI_INTEGER) - AC_SUBST(MPI_LOGICAL) len_real=`printf "%02x" $pac_cv_f77_sizeof_real` MPI_REAL=0x4c00${len_real}1c @@ -3351,338 +2955,41 @@ if test "$enable_f77" = yes ; then if test -z "$pac_cv_f77_sizeof_double_precision" ; then AC_MSG_ERROR([Unable to configure with Fortran support because configure could not determine the size of a Fortran DOUBLE PRECISION. Consider setting CROSS_F77_SIZEOF_DOUBLE_PRECISION to the length in bytes of a Fortran DOUBLE PRECISION]) fi - len_double=$pac_cv_f77_sizeof_double_precision - # Convert to two digit hex - len=$len_double - # - # Take len and turn it into two hex digits (there are 8 bits available - # in the built-in datatype handle for the length; see - # src/mpid/common/datatype/mpidu_datatype.h). This code is taken - # from the code in mpich/configure.ac - if test "$len" -gt 255 ; then - AC_MSG_ERROR([Type sizes greater than 255 bytes are not supported (type DOUBLE is $len bytes)]) - fi - tmplen=$len - hexlen="" - while test $tmplen -gt 0 ; do - lowdigit=`expr $tmplen - 16 \* \( $tmplen / 16 \)` - case $lowdigit in - 10) char=a ;; - 11) char=b ;; - 12) char=c ;; - 13) char=d ;; - 14) char=e ;; - 15) char=f ;; - *) char=$lowdigit ;; - esac - hexlen="$char$hexlen" - tmplen=`expr $tmplen / 16` - done - if test $len -lt 16 ; then - hexlen="0$hexlen" - fi - len_double=$hexlen - if test "$len_double" = 0 ; then - # We have a problem - AC_MSG_WARN([Unable to determine size of a DOUBLE PRECISION type; using 8]) - # We make the length 8 - len_double="08" - fi + + # Provide the corresponding C types for MPI_INTEGER + AC_MSG_CHECKING([for C type matching Fortran integer]) + get_c_int_type $pac_cv_f77_sizeof_integer + MPI_FINT=$pac_retval + AC_MSG_RESULT($MPI_FINT) # Provide the corresponding C types for MPI_REAL and MPI_DOUBLE + # These are needed to correctly implement the MPI reduction operations + AC_MSG_CHECKING([for C type matching Fortran real]) - noval=yes - for c_type in float double "long_double" ; do - eval ctypelen=\$"ac_cv_sizeof_$c_type" - if test "$pac_cv_f77_sizeof_real" = "$ctypelen" -a \ - "$ctypelen" -gt 0 ; then - c_type=`echo $c_type | sed -e 's/_/ /g'` - AC_MSG_RESULT($c_type) - MPIR_FC_REAL_CTYPE=$c_type - noval="no" - break - fi - done - if test "$noval" = "yes" ; then - # Set a default - MPIR_FC_REAL_CTYPE="float" - AC_MSG_RESULT([unavailable]) - fi + get_c_float_type $pac_cv_f77_sizeof_real + MPIR_FC_REAL_CTYPE=$pac_retval + AC_MSG_RESULT($MPIR_FC_REAL_CTYPE) + AC_DEFINE_UNQUOTED([MPIR_FC_REAL_CTYPE],[$MPIR_FC_REAL_CTYPE], [The C type for FORTRAN REAL]) - noval=yes AC_MSG_CHECKING([for C type matching Fortran double]) - for c_type in double "long_double" float ; do - eval ctypelen=\$"ac_cv_sizeof_$c_type" - if test "$pac_cv_f77_sizeof_double_precision" = "$ctypelen" -a \ - "$ctypelen" -gt 0 ; then - c_type=`echo $c_type | sed -e 's/_/ /g'` - AC_MSG_RESULT($c_type) - MPIR_FC_DOUBLE_CTYPE=$c_type - noval="no" - break - fi - done - if test "$noval" = "yes" ; then - # Set a default - MPIR_FC_DOUBLE_CTYPE="double" - AC_MSG_RESULT([unavailable]) - fi + get_c_float_type $pac_cv_f77_sizeof_double_precision + MPIR_FC_DOUBLE_CTYPE=$pac_retval + AC_MSG_RESULT($MPIR_FC_DOUBLE_CTYPE) + AC_DEFINE_UNQUOTED([MPIR_FC_DOUBLE_CTYPE],[$MPIR_FC_DOUBLE_CTYPE], [The C type for FORTRAN DOUBLE PRECISION]) - # These are needed to correctly implement the MPI reduction operations - AC_DEFINE_UNQUOTED([MPIR_FC_REAL_CTYPE],[$MPIR_FC_REAL_CTYPE], - [The C type for FORTRAN REAL]) - AC_DEFINE_UNQUOTED([MPIR_FC_DOUBLE_CTYPE],[$MPIR_FC_DOUBLE_CTYPE], - [The C type for FORTRAN DOUBLE PRECISION]) - - # Use the proper length values for these items in case we are building - # with Fortran integers that are not the same size as C ints and - # reals and double precision that are the same size (not valid Fortran, - # but used by some applications) - - len_2integer=`expr 2 \* $pac_cv_f77_sizeof_integer` - len_2real=`expr 2 \* $pac_cv_f77_sizeof_real` - len_doublecplx=`expr $pac_cv_f77_sizeof_double_precision \* 2` - if test "$len_doublecplx" = 0 ; then - # We have a problem - AC_MSG_WARN([Unable to determine size of a DOUBLE PRECISION type; using 8]) - # We make the length 8*2 (in hex) - len_doublecplx="16" - fi + # get C types for Fortran fixed-size REAL and INTEGER. If no equivallent C type, set + # pac_cv_f77_sizeof_real# to 0, so that PAC_SET_MPI_TYPE can skip the type. - for lenname in len_2integer len_2real len_doublecplx ; do - eval len=\$$lenname - if test "$len" -gt 255 ; then - AC_MSG_ERROR([Type sizes greater than 255 bytes are not supported (type $lenname is $len bytes)]) - fi - tmplen=$len - hexlen="" - while test $tmplen -gt 0 ; do - lowdigit=`expr $tmplen - 16 \* \( $tmplen / 16 \)` - case $lowdigit in - 10) char=a ;; - 11) char=b ;; - 12) char=c ;; - 13) char=d ;; - 14) char=e ;; - 15) char=f ;; - *) char=$lowdigit ;; - esac - hexlen="$char$hexlen" - tmplen=`expr $tmplen / 16` - done - if test $len -lt 16 ; then - hexlen="0$hexlen" - fi - eval ${lenname}=$hexlen - if test "$hexlen" = 0 ; then - # We have a problem - AC_MSG_WARN([Unable to determine size of a $lenname type; using 8]) - # We make the length 8 - eval ${lenname}=$hexlen - fi - done - - MPI_DOUBLE_PRECISION=0x4c00${len_double}1f - MPI_2INTEGER=0x4c00${len_2integer}20 - MPI_2REAL=0x4c00${len_2real}21 - MPI_COMPLEX=0x4c00${len_2real}1e - AC_SUBST(MPI_COMPLEX) - AC_SUBST(MPI_DOUBLE_PRECISION) - AC_SUBST(MPI_2INTEGER) - AC_SUBST(MPI_2REAL) - -dnl len=$len_doublecplx -dnl # -dnl # Take len and turn it into two hex digits (there are 8 bits available -dnl # in the built-in datatype handle for the length; see -dnl # src/mpid/common/datatype/mpidu_datatype.h). This code is taken -dnl # from the code in mpich/configure.ac -dnl if test "$len" -gt 255 ; then -dnl AC_MSG_ERROR([Type sizes greater than 255 bytes are not supported (type DOUBLE COMPLEX is $len bytes)]) -dnl fi -dnl tmplen=$len -dnl hexlen="" -dnl while test $tmplen -gt 0 ; do -dnl lowdigit=`expr $tmplen - 16 \* \( $tmplen / 16 \)` -dnl case $lowdigit in -dnl 10) char=a ;; -dnl 11) char=b ;; -dnl 12) char=c ;; -dnl 13) char=d ;; -dnl 14) char=e ;; -dnl 15) char=f ;; -dnl *) char=$lowdigit ;; -dnl esac -dnl hexlen="$char$hexlen" -dnl tmplen=`expr $tmplen / 16` -dnl done -dnl if test $len -lt 16 ; then -dnl hexlen="0$hexlen" -dnl fi -dnl len_doublecplx=$hexlen - - MPI_DOUBLE_COMPLEX=0x4c00${len_doublecplx}22 - MPI_2DOUBLE_PRECISION=0x4c00${len_doublecplx}23 - AC_SUBST(MPI_DOUBLE_COMPLEX) - AC_SUBST(MPI_2DOUBLE_PRECISION) - -dnl Removed MPI_2COMPLEX and MPI_2DOUBLE_COMPLEX, leaving comments to explain the gap in seq id - # MPI_2COMPLEX=0x4c00${len_doublecplx}24 - # MPI_2DOUBLE_COMPLEX=0x4c00${len_2dc}25 - - MPI_F77_PACKED=$MPI_PACKED - MPI_F77_UB=$MPI_UB - MPI_F77_LB=$MPI_LB - MPI_F77_BYTE=$MPI_BYTE - AC_SUBST(MPI_F77_PACKED) - AC_SUBST(MPI_F77_UB) - AC_SUBST(MPI_F77_LB) - AC_SUBST(MPI_F77_BYTE) - # - # We must convert all hex values to decimal (!) - # It would be nice to use expr to extract the next character rather than - # the heavier-weight sed, but expr under Tru64 Unix discards leading zeros, - # even when used only with the match (:) command. Rather than have - # configure figure out if expr works, we just use sed. Sigh. - for var in CHARACTER INTEGER REAL LOGICAL DOUBLE_PRECISION COMPLEX \ - DOUBLE_COMPLEX 2INTEGER 2REAL 2DOUBLE_PRECISION \ - F77_PACKED F77_UB F77_LB F77_BYTE; do - fullvar="MPI_$var" - eval fullvarvalue=\$$fullvar - #echo "$fullvar = $fullvarvalue" - value=0 - fullvarvalue=`echo $fullvarvalue | sed -e 's/..\(.*\)/\1/'` - for pos in 3 4 5 6 7 8 9 10 ; do - # This works, even for Tru64, because only a single character - # is extracted - char=`expr $fullvarvalue : '\(.\)'` - # FIXME: Tru64 Unix eliminates leading zeros (!) - # How do we fix something that broken? - fullvarvalue=`echo $fullvarvalue | sed -e 's/.\(.*\)/\1/'` - case $char in - a) char=10 ;; - b) char=11 ;; - c) char=12 ;; - d) char=13 ;; - e) char=14 ;; - f) char=15 ;; - esac - value=`expr $value \* 16 + $char` - done - #echo "$fullvar = $value" - if test "X$value" = "X"; then - eval origvarvalue=\$$fullvar - AC_MSG_ERROR([Internal Error: Failed to convert $fullvar value to hex! Original value was $origvarvalue]) - fi - eval $fullvar=$value - done - AC_LANG([C]) + PAC_F77_CHECK_FIXED_REAL(4) + PAC_F77_CHECK_FIXED_REAL(8) + PAC_F77_CHECK_FIXED_REAL(16) + + PAC_F77_CHECK_FIXED_INTEGER(1) + PAC_F77_CHECK_FIXED_INTEGER(2) + PAC_F77_CHECK_FIXED_INTEGER(4) + PAC_F77_CHECK_FIXED_INTEGER(8) + PAC_F77_CHECK_FIXED_INTEGER(16) - # Now, handle the sized types - # - # Preload the C mpi types - # THESE MUST MATCH THE DEFINITIONS IN MPI.H and MPIF.H - # We use these to match the optional Fortran types - char_mpi=${MPI_CHAR:-0} - short_mpi=${MPI_SHORT:-0} - int_mpi=${MPI_INT:-0} - long_mpi=${MPI_LONG:-0} - long_long_mpi=${MPI_LONG_LONG:-0} - float_mpi=${MPI_FLOAT:-0} - double_mpi=${MPI_DOUBLE:-0} - long_double_mpi=${MPI_LONG_DOUBLE:-0} - - # Simply determine which types exist. These may have been set by the - # toplevel configure - for var in INTEGER1 INTEGER2 INTEGER4 INTEGER8 INTEGER16 \ - REAL4 REAL8 REAL16 COMPLEX8 COMPLEX16 COMPLEX32 ; do - eval varname=MPI_$var - eval varvalue=\$$varname - #echo "$varname = $varvalue" - if test "$varvalue" = MPI_DATATYPE_NULL ; then - eval F77_$var=0 - else - eval F77_$var=\$$varname - fi - done - - # We must convert all hex values to decimal (!) - for var in INTEGER1 INTEGER2 INTEGER4 INTEGER8 INTEGER16 \ - REAL4 REAL8 REAL16 COMPLEX8 COMPLEX16 COMPLEX32 ; do - fullvar="F77_$var" - eval fullvarvalue=\$$fullvar - if test "$fullvarvalue" = 0 -o -z "$fullvarvalue" ; then - eval $fullvar=MPI_DATATYPE_NULL - continue - fi - #echo "$fullvar = $fullvarvalue" - value=0 - # See the comments above on why expr with : cannot be used here - fullvarvalue=`echo $fullvarvalue | sed -e 's/..\(.*\)/\1/'` - for pos in 3 4 5 6 7 8 9 10 ; do - #char=`expr substr $fullvarvalue $pos 1` - char=`expr $fullvarvalue : '\(.\)'` - # We don't test for success of expr here because some expr's are - # buggy and set the status to one on expressions like - # expr 00ccc : '\(.\)' - # while both - # expr 00ccc : '\(..\)' - # and - # expr 100cc : '\(.\)' - # return a zero status. So the status is set even on success, - # if the result is a single character that is a zero (!) - #rc=$? - #if test "$rc" != 0 ; then - dnl # AC_MSG_WARN([Failure (status $rc) in extracting first char from $fullvarvalue]) - # break - #fi - fullvarvalue=`echo $fullvarvalue | sed -e 's/.\(.*\)/\1/'` - case $char in - a) char=10 ;; - b) char=11 ;; - c) char=12 ;; - d) char=13 ;; - e) char=14 ;; - f) char=15 ;; - esac - value=`expr $value \* 16 + $char` - if test $? != 0 ; then - AC_MSG_WARN([Failure to evaluate $value \* 16 + $char]) - fi - done - #echo "$fullvar = $value" - eval $fullvar=$value - done - AC_SUBST(F77_INTEGER1) - AC_SUBST(F77_INTEGER2) - AC_SUBST(F77_INTEGER4) - AC_SUBST(F77_INTEGER8) - AC_SUBST(F77_INTEGER16) - AC_SUBST(F77_REAL4) - AC_SUBST(F77_REAL8) - AC_SUBST(F77_REAL16) - AC_SUBST(F77_COMPLEX8) - AC_SUBST(F77_COMPLEX16) - AC_SUBST(F77_COMPLEX32) - - noval="yes" - AC_MSG_CHECKING([for C type matching Fortran integer]) - for c_type in char short int long "long_long" ; do - eval ctypelen=\$"ac_cv_sizeof_$c_type" - if test "$pac_cv_f77_sizeof_integer" = "$ctypelen" -a \ - "$ctypelen" -gt 0 ; then - c_type=`echo $c_type | sed -e 's/_/ /g'` - AC_MSG_RESULT($c_type) - MPI_FINT=$c_type - noval="no" - break - fi - done - if test "$noval" = "yes" ; then - # Set a default - MPI_FINT="int" - AC_MSG_RESULT([unavailable]) - fi # We also need to check the size of MPI_Aint vs MPI_Fint, and # define AINT_LARGER_THAN_FINT if aint is larger (this # affects code in MPI_Address) @@ -3696,115 +3003,12 @@ dnl Removed MPI_2COMPLEX and MPI_2DOUBLE_COMPLEX, leaving comments to explain th fi # Include a defined value for Fint is int - if test "$MPI_FINT" = "int" ; then + if test "$SIZEOF_F77_INTEGER" != "$ac_cv_sizeof_int" ; then AC_DEFINE(HAVE_FINT_IS_INT,1,[Define if Fortran integer are the same size as C ints]) - elif test "$SIZEOF_F77_INTEGER" != "$ac_cv_sizeof_int" ; then - # Make this fatal because we do not want to build a broken fortran - # interface (was error) - # Check to see if the f77 binding has enabled the code to support - # the case of int != fint. + else AC_MSG_WARN([Fortran integers and C ints are not the same size. Support for this case is experimental; use at your own risk]) fi - # We must convert all hex values to decimal (!). - # This is for the C types so they are also available in Fortran - for var in CHAR SIGNED_CHAR UNSIGNED_CHAR WCHAR SHORT \ - UNSIGNED_SHORT INT UNSIGNED_INT LONG UNSIGNED_LONG \ - FLOAT DOUBLE LONG_DOUBLE LONG_LONG_INT \ - UNSIGNED_LONG_LONG LONG_LONG FLOAT_INT DOUBLE_INT \ - LONG_INT SHORT_INT "2INT" LONG_DOUBLE_INT \ - INT8_T INT16_T INT32_T INT64_T \ - UINT8_T UINT16_T UINT32_T UINT64_T \ - C_BOOL C_FLOAT_COMPLEX C_DOUBLE_COMPLEX \ - C_LONG_DOUBLE_COMPLEX AINT OFFSET ; do - fullvar="MPI_$var" - fullf77var="MPI_F77_$var" - eval fullvarvalue=\$$fullvar - #echo "$fullvar = $fullvarvalue" - if test "x$fullvarvalue" = "x" -o \ - "x$fullvarvalue" = "xMPI_DATATYPE_NULL" ; then - eval $fullf77var="MPI_DATATYPE_NULL" - continue - fi - value=0 - fullvarvalue=`echo $fullvarvalue | sed -e 's/..\(.*\)/\1/'` - offset=0 - for pos in 3 4 5 6 7 8 9 10 ; do - # This works, even for Tru64, because only a single character - # is extracted - char=`expr $fullvarvalue : '\(.\)'` - # FIXME: Tru64 Unix eliminates leading zeros (!) - # How do we fix something that broken? - fullvarvalue=`echo $fullvarvalue | sed -e 's/.\(.*\)/\1/'` - case $char in - a) char=10 ;; - b) char=11 ;; - c) char=12 ;; - d) char=13 ;; - e) char=14 ;; - f) char=15 ;; - esac - # For Fortran, if the value is too big for an unsigned int, - # we need to make it a signed (negative) int. Currently, the - # types in this class are the minloc/maxloc types. - if test $pos = 3 -a $char -ge 8 ; then - #echo "for $var in position $pos found a value >= 8" - char=`expr $char - 8` - offset=-2147483648 - fi - value=`expr $value \* 16 + $char` - done - if test "$offset" != 0 ; then - #echo "$fullf77var: $value, $offset" - value=`expr $value + $offset` - fi - #echo "$fullf77var = $value" - eval $fullf77var=$value - done - AC_SUBST(MPI_F77_CHAR) - AC_SUBST(MPI_F77_SIGNED_CHAR) - AC_SUBST(MPI_F77_UNSIGNED_CHAR) - AC_SUBST(MPI_F77_WCHAR) - AC_SUBST(MPI_F77_SHORT) - AC_SUBST(MPI_F77_UNSIGNED_SHORT) - MPI_F77_UNSIGNED=$MPI_F77_UNSIGNED_INT - AC_SUBST(MPI_F77_UNSIGNED) - AC_SUBST(MPI_F77_INT) - AC_SUBST(MPI_F77_LONG) - AC_SUBST(MPI_F77_UNSIGNED_LONG) - AC_SUBST(MPI_F77_FLOAT) - AC_SUBST(MPI_F77_DOUBLE) - AC_SUBST(MPI_F77_LONG_DOUBLE) - AC_SUBST(MPI_F77_UNSIGNED_LONG_LONG) - MPI_F77_LONG_LONG_INT=$MPI_F77_LONG_LONG - AC_SUBST(MPI_F77_LONG_LONG_INT) - AC_SUBST(MPI_F77_LONG_LONG) - AC_SUBST(MPI_F77_FLOAT_INT) - AC_SUBST(MPI_F77_DOUBLE_INT) - AC_SUBST(MPI_F77_LONG_INT) - AC_SUBST(MPI_F77_SHORT_INT) - AC_SUBST(MPI_F77_2INT) - AC_SUBST(MPI_F77_LONG_DOUBLE_INT) - AC_SUBST(MPI_F77_INT8_T) - AC_SUBST(MPI_F77_INT16_T) - AC_SUBST(MPI_F77_INT32_T) - AC_SUBST(MPI_F77_INT64_T) - AC_SUBST(MPI_F77_UINT8_T) - AC_SUBST(MPI_F77_UINT16_T) - AC_SUBST(MPI_F77_UINT32_T) - AC_SUBST(MPI_F77_UINT64_T) - AC_SUBST(MPI_F77_C_BOOL) - AC_SUBST(MPI_F77_C_FLOAT_COMPLEX) - # C_COMPLEX is an alias for FLOAT_COMPLEX - MPI_F77_C_COMPLEX=$MPI_F77_C_FLOAT_COMPLEX - AC_SUBST(MPI_F77_C_COMPLEX) - AC_SUBST(MPI_F77_C_DOUBLE_COMPLEX) - AC_SUBST(MPI_F77_C_LONG_DOUBLE_COMPLEX) - # these two are not yet defined, but AC_SUBST only cares about them at - # AC_OUTPUT-time - AC_SUBST(MPI_F77_AINT) - AC_SUBST(MPI_F77_OFFSET) - # Try and compute the values of .true. and .false. in Fortran # This code has been removed because the Fortran binding code does # not yet support it. @@ -3995,51 +3199,36 @@ dnl Removed MPI_2COMPLEX and MPI_2DOUBLE_COMPLEX, leaving comments to explain th # AC_LANG([C]) +else + MPI_FINT=int + + # set following sizes to 0 will disable the corresponding datatype + pac_cv_f77_sizeof_character=0 + pac_cv_f77_sizeof_integer=0 + pac_cv_f77_sizeof_real=0 + pac_cv_f77_sizeof_double_precision=0 + pac_cv_f77_sizeof_integer1=0 + pac_cv_f77_sizeof_integer2=0 + pac_cv_f77_sizeof_integer4=0 + pac_cv_f77_sizeof_integer8=0 + pac_cv_f77_sizeof_integer16=0 + pac_cv_f77_sizeof_real4=0 + pac_cv_f77_sizeof_real8=0 + pac_cv_f77_sizeof_real16=0 + + AC_DEFINE(HAVE_NO_FORTRAN_MPI_TYPES_IN_C,1,[Define if the Fortran types are not available in C]) fi # ---------------------------------------------------------------------------- # C++ types -# default to null types -# Set to "0x0c000000" instead of "MPI_DATATYPE_NULL" because these values -# sometimes are used in preprocessor tests where we cannot compare the -# type-casted values. -MPIR_CXX_BOOL=0x0c000000 -MPIR_CXX_COMPLEX=0x0c000000 -MPIR_CXX_DOUBLE_COMPLEX=0x0c000000 -MPIR_CXX_LONG_DOUBLE_COMPLEX=0x0c000000 -MPI_F77_CXX_BOOL=MPI_DATATYPE_NULL -MPI_F77_CXX_FLOAT_COMPLEX=MPI_DATATYPE_NULL -MPI_F77_CXX_DOUBLE_COMPLEX=MPI_DATATYPE_NULL -MPI_F77_CXX_LONG_DOUBLE_COMPLEX=MPI_DATATYPE_NULL if test "$enable_cxx" = "yes" ; then AC_LANG([C++]) AC_CHECK_SIZEOF(bool) - # Find a C type that matches the size of the C++ boolean type - case "$ac_cv_sizeof_bool" in - $ac_cv_sizeof__Bool) - bool_type=_Bool - ;; - $ac_cv_sizeof_unsigned_char) - bool_type="unsigned char" - ;; - $ac_cv_sizeof_unsigned_short) - bool_type="unsigned short" - ;; - $ac_cv_sizeof_unsigned_int) - bool_type="unsigned int" - ;; - $ac_cv_sizeof_unsigned_long) - bool_type="unsigned long" - ;; - $ac_cv_sizeof_unsigned_long_long) - bool_type="unsigned long long" - ;; - *) - AC_MSG_ERROR([unable to determine matching C type for C++ bool]) - ;; - esac - AC_DEFINE_UNQUOTED([MPIR_CXX_BOOL_CTYPE],[$bool_type], + AC_MSG_CHECKING([for C types matching C++ bool]) + get_c_bool_type $ac_cv_sizeof_bool + AC_MSG_RESULT([$pac_retval]) + AC_DEFINE_UNQUOTED([MPIR_CXX_BOOL_CTYPE],[$pac_retval], [a C type used to compute C++ bool reductions]) AC_CHECK_HEADER(complex) @@ -4070,63 +3259,286 @@ using namespace std; "$ac_cv_sizeof_DoubleComplex" != 0 ; then AC_DEFINE(HAVE_CXX_COMPLEX,1,[Define is C++ supports complex types]) fi - - # Datatypes are given by - # 0x4c00 (1 byte) (1 byte) - # where the unique nums are - # 33,34,35,36 - case "$ac_cv_sizeof_bool" in - 1) MPIR_CXX_BOOL=0x4c000133 ;; - 2) MPIR_CXX_BOOL=0x4c000233 ;; - 4) MPIR_CXX_BOOL=0x4c000433 ;; - 8) MPIR_CXX_BOOL=0x4c000833 ;; - *) ;; - esac - case "$ac_cv_sizeof_Complex" in - 8) MPIR_CXX_COMPLEX=0x4c000834 ;; - 16) MPIR_CXX_COMPLEX=0x4c001034 ;; - *) ;; - esac - case "$ac_cv_sizeof_DoubleComplex" in - 8) MPIR_CXX_DOUBLE_COMPLEX=0x4c000835 ;; - 16) MPIR_CXX_DOUBLE_COMPLEX=0x4c001035 ;; - 32) MPIR_CXX_DOUBLE_COMPLEX=0x4c002035 ;; - *) ;; - esac - # only enable CXX "long double" if we have a C "long double", since we - # currently perform reductions on CXX "long double" types via C. - if test "X$pac_cv_have_long_double" = "Xyes" ; then - case "$ac_cv_sizeof_LongDoubleComplex" in - 8) MPIR_CXX_LONG_DOUBLE_COMPLEX=0x4c000836 ;; - 16) MPIR_CXX_LONG_DOUBLE_COMPLEX=0x4c001036 ;; - 24) MPIR_CXX_LONG_DOUBLE_COMPLEX=0x4c001836 ;; - 32) MPIR_CXX_LONG_DOUBLE_COMPLEX=0x4c002036 ;; - *) ;; - esac + # mark availability of c++ long double complex + if test $ac_cv_sizeof_long_double__Complex != 0 ; then + AC_DEFINE([HAVE_CXX_LONG_DOUBLE_COMPLEX], 1, [Define if C++ supports long double complex]) fi + fi + AC_LANG([C]) +else + # set following sizes to 0 to disable the corresponding datatypes + ac_cv_sizeof_bool=0 + ac_cv_sizeof_Complex=0 + ac_cv_sizeof_DoubleComplex=0 + ac_cv_sizeof_LongDoubleComplex=0 +fi + +# ------------ +# MPI_FINT +# ------------ +# MPI_FINT is already set +AC_SUBST(MPI_FINT) + +# ------------ +# MPI_AINT +# ------------ +# Note that aint_size must be used instead of void_p where the desired check +# is on the size of MPI_Aint +aint_size=$ac_cv_sizeof_void_p +if test "$with_aint_size" -gt 0 ; then + aint_size=$with_aint_size + if test "$aint_size" != "$ac_cv_sizeof_void_p" ; then + AC_MSG_RESULT([Overriding MPI_Aint to be $aint_size bytes]) + fi +fi +if test "$ac_cv_sizeof_void_p" -lt "$aint_size" ; then + AC_DEFINE(USE_AINT_FOR_ATTRVAL,1,[Define if MPI_Aint should be used instead of void * for storing attribute values]) +fi + +get_c_int_type $aint_size +MPI_AINT=$pac_retval +MPI_SIZEOF_AINT=$aint_size +export MPI_SIZEOF_AINT + +case $MPI_AINT in + int) + MPI_AINT_FMT_DEC_SPEC="%d" + MPI_AINT_FMT_HEX_SPEC="%x" + MPIR_AINT_MAX="INT_MAX" + ;; + long) + MPI_AINT_FMT_DEC_SPEC="%ld" + MPI_AINT_FMT_HEX_SPEC="%lx" + MPIR_AINT_MAX="LONG_MAX" + ;; + long_long) + MPI_AINT_FMT_DEC_SPEC="%lld" + MPI_AINT_FMT_HEX_SPEC="%llx" + # tt#1776: if LLONG_MAX is missing, we fix it up in C, b/c it's + # easier there. See mpiiimpl.h. + MPIR_AINT_MAX="LLONG_MAX" + ;; + short) + MPI_AINT_FMT_DEC_SPEC="%hd" + MPI_AINT_FMT_HEX_SPEC="%hx" + MPIR_AINT_MAX="SHRT_MAX" + ;; + *) + AC_MSG_WARN([unable to determine format specifiers for MPI_Aint, defaulting to int]) + MPI_AINT_FMT_DEC_SPEC="%d" + MPI_AINT_FMT_HEX_SPEC="%x" + MPIR_AINT_MAX="INT_MAX" + ;; +esac +export MPI_AINT_FMT_DEC_SPEC MPI_AINT_FMT_HEX_SPEC + +AC_SUBST(MPI_AINT) +AC_SUBST(MPI_AINT_FMT_DEC_SPEC) +AC_SUBST(MPI_AINT_FMT_HEX_SPEC) +AC_DEFINE_UNQUOTED([MPIR_AINT_MAX],[$MPIR_AINT_MAX],[limits.h _MAX constant for MPI_Aint]) + +# ------------ +# MPI_OFFSET +# ------------ +# If ROMIO was successfully configured, then ROMIO will have exported the +# definition of MPI_OFFSET_TYPE through its localdefs file (created by the +# ROMIO configure in src/mpi/romio/localdefs). If MPI_OFFSET_TYPE was not +# defined, this code attempts to find a good choice for MPI_OFFSET_TYPE +# (As the offset type is used for File operations, the specific type +# really doesn't matter if ROMIO doesn't provide it). +if test -n "$MPI_OFFSET_TYPE" ; then + # We got the value from the ROMIO configure + MPI_OFFSET="$MPI_OFFSET_TYPE" + # Get and export the size of this type if possible + if test -z "$MPI_SIZEOF_OFFSET" ; then + # set a default + AC_CACHE_CHECK([the sizeof MPI_Offset],ac_cv_sizeof_MPI_Offset,[ + ac_cv_sizeof_MPI_Offset=unknown + AC_COMPUTE_INT([ac_cv_sizeof_MPI_Offset],[sizeof($MPI_OFFSET)],[],[ + AC_MSG_WARN([Unable to determine the size of MPI_Offset]) + ]) + ]) + if test "$ac_cv_sizeof_MPI_Offset" != "unknown" ; then + MPI_SIZEOF_OFFSET=$ac_cv_sizeof_MPI_Offset + fi + fi + export MPI_SIZEOF_OFFSET +else + # Make a guess at the appropriate definition for offset. Try to + # find a 64bit type. + if test "$ac_cv_sizeof_long" = 8 ; then + MPI_OFFSET="long" + # Make the size of this type available to other configures + MPI_SIZEOF_OFFSET=8 + elif test "$ac_cv_sizeof_long_long" = 8 ; then + MPI_OFFSET="long long" + # Make the size of this type available to other configures + MPI_SIZEOF_OFFSET=8 + else + MPI_OFFSET=long + MPI_SIZEOF_OFFSET=$ac_cv_sizeof_long + fi + export MPI_SIZEOF_OFFSET +fi +AC_SUBST(MPI_OFFSET) + +AS_CASE([$MPI_OFFSET], + [int], [MPIR_OFFSET_MAX="INT_MAX"], + [long], [MPIR_OFFSET_MAX="LONG_MAX"], + ['long long'], [MPIR_OFFSET_MAX="LLONG_MAX"], + [short], [MPIR_OFFSET_MAX="SHRT_MAX"], + [AC_MSG_ERROR([unable to determine MPIR_OFFSET_MAX for MPI_Offset])]) +AC_DEFINE_UNQUOTED([MPIR_OFFSET_MAX],[$MPIR_OFFSET_MAX],[limits.h _MAX constant for MPI_Offset]) + +# FIXME: we need an explanation of why we need both MPI_OFFSET and +# MPI_OFFSET_TYPEDEF. Why is MPI_OFFSET_TYPEDEF necessary? +# This appears to be used by the Windows "winconfigure.wsf" which is used +# to create a multiline definition using an #ifdef check on USE_GCC +# We may wish to use a different approach +MPI_OFFSET_TYPEDEF="typedef $MPI_OFFSET MPI_Offset;" +AC_SUBST(MPI_OFFSET_TYPEDEF) +# +# Fortran type for an Offset type (needed to define MPI_DISPLACEMENT_CURRENT +# The value for this comes from ROMIO, and is needed in mpif.h.in +# First, we check that this works with both Fortran compilers (if +# they are defined) +# +# If there is no FORTRAN_MPI_OFFSET type (because ROMIO is disabled), +# just use INTEGER +if test -z "$FORTRAN_MPI_OFFSET" ; then + FORTRAN_MPI_OFFSET=INTEGER +fi +if test "$enable_f77" = yes -a "$enable_fc" = yes ; then + AC_LANG_PUSH([Fortran 77]) + AC_MSG_CHECKING([whether the Fortran Offset type works with Fortran 77]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([],[ $FORTRAN_MPI_OFFSET i]) + ],[has_f77_offsettype=yes],[has_f77_offsetype=no]) + AC_MSG_RESULT($has_f77_offsettype) + AC_LANG_POP([Fortran 77]) + + AC_LANG_PUSH([Fortran]) + AC_MSG_CHECKING([whether the Fortran Offset type works with Fortran 90]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([],[ $FORTRAN_MPI_OFFSET i]) + ],[has_fc_offsettype=yes],[has_fc_offsetype=no]) + AC_LANG_POP([Fortran]) + AC_MSG_RESULT($has_fc_offsettype) + + if test "$has_f77_offsettype" != yes -o "$has_fc_offsettype" != yes ; then + AC_MSG_WARN([mpif.h is not compatible with both $F77 $FFLAGS and $FC $FCFLAGS. We recommend that you set both F77 and FC to the same compiler and reconfigure.]) + fi +fi +AC_SUBST(FORTRAN_MPI_OFFSET) + +# ------------ +# MPI_COUNT +# ------------ +# quick sanity checking to avoid a bad test immediately below +AS_IF([test -z "$MPI_SIZEOF_AINT"], + [AC_MSG_ERROR([size of MPI_Aint is unknown at this stage])]) +AS_IF([test -z "$MPI_SIZEOF_OFFSET"], + [AC_MSG_ERROR([size of MPI_Offset is unknown at this stage])]) + +AS_IF([test "$MPI_SIZEOF_AINT" -gt "$MPI_SIZEOF_OFFSET"], + [# an unlikely case, but I suppose it's theoretically possible + MPI_COUNT="$MPI_AINT" + COUNT_KIND="$ADDRESS_KIND" + MPIR_COUNT_MAX="$MPIR_AINT_MAX" + MPI_SIZEOF_COUNT="$MPI_SIZEOF_AINT"], + [# don't bother checking whether Aint or Offset are larger than int, they + # surely will be + MPI_COUNT="$MPI_OFFSET" + COUNT_KIND="$OFFSET_KIND" + MPIR_COUNT_MAX="$MPIR_OFFSET_MAX" + MPI_SIZEOF_COUNT="$MPI_SIZEOF_OFFSET"]) +AC_SUBST([MPI_COUNT]) +AC_SUBST([COUNT_KIND]) +AC_DEFINE_UNQUOTED([MPIR_COUNT_MAX],[$MPIR_COUNT_MAX],[limits.h _MAX constant for MPI_Count]) +AC_DEFINE_UNQUOTED(MPIR_Ucount,unsigned $MPI_COUNT,[MPIR_Ucount is an unsigned MPI_Count-sized integer]) - # Make these available to the collective operations and other code - AC_DEFINE_UNQUOTED(MPIR_CXX_BOOL_VALUE,$MPIR_CXX_BOOL,[Define as the MPI Datatype handle for MPI::BOOL]) - AC_DEFINE_UNQUOTED(MPIR_CXX_COMPLEX_VALUE,$MPIR_CXX_COMPLEX,[Define as the MPI Datatype handle for MPI::COMPLEX]) - AC_DEFINE_UNQUOTED(MPIR_CXX_DOUBLE_COMPLEX_VALUE,$MPIR_CXX_DOUBLE_COMPLEX,[Define as the MPI Datatype handle for MPI::DOUBLE_COMPLEX]) - AC_DEFINE_UNQUOTED(MPIR_CXX_LONG_DOUBLE_COMPLEX_VALUE,$MPIR_CXX_LONG_DOUBLE_COMPLEX,[Define as the MPI Datatype handle for MPI::LONG_DOUBLE_COMPLEX]) - - # compute F77 decimal constant values for these types - PAC_CONV_HEX_TO_DEC([$MPIR_CXX_BOOL], [MPI_F77_CXX_BOOL]) - PAC_CONV_HEX_TO_DEC([$MPIR_CXX_COMPLEX], [MPI_F77_CXX_FLOAT_COMPLEX]) - PAC_CONV_HEX_TO_DEC([$MPIR_CXX_DOUBLE_COMPLEX], [MPI_F77_CXX_DOUBLE_COMPLEX]) - PAC_CONV_HEX_TO_DEC([$MPIR_CXX_LONG_DOUBLE_COMPLEX],[MPI_F77_CXX_LONG_DOUBLE_COMPLEX]) -fi -AC_SUBST([MPIR_CXX_BOOL]) -AC_SUBST([MPIR_CXX_COMPLEX]) -AC_SUBST([MPIR_CXX_DOUBLE_COMPLEX]) -AC_SUBST([MPIR_CXX_LONG_DOUBLE_COMPLEX]) -AC_SUBST([MPI_F77_CXX_BOOL]) -AC_SUBST([MPI_F77_CXX_FLOAT_COMPLEX]) -AC_SUBST([MPI_F77_CXX_DOUBLE_COMPLEX]) -AC_SUBST([MPI_F77_CXX_LONG_DOUBLE_COMPLEX]) +#-------------------------------------------------------------------------------- +# Now we collected all the datatype sizes, we can set values for MPI builtin datatypes +AC_MSG_CHECKING([MPI datatypes]) +# PAC_SET_MPI_TYPE(hex_idx, NAME, len) +PAC_SET_MPI_TYPE(01, MPI_CHAR, 1) +PAC_SET_MPI_TYPE(02, MPI_UNSIGNED_CHAR, 1) +PAC_SET_MPI_TYPE(03, MPI_SHORT, $ac_cv_sizeof_short) +PAC_SET_MPI_TYPE(04, MPI_UNSIGNED_SHORT, $ac_cv_sizeof_short) +PAC_SET_MPI_TYPE(05, MPI_INT, $ac_cv_sizeof_int) +PAC_SET_MPI_TYPE(06, MPI_UNSIGNED, $ac_cv_sizeof_int) +PAC_SET_MPI_TYPE(07, MPI_LONG, $ac_cv_sizeof_long) +PAC_SET_MPI_TYPE(08, MPI_UNSIGNED_LONG, $ac_cv_sizeof_long) +PAC_SET_MPI_TYPE(09, MPI_LONG_LONG_INT, $ac_cv_sizeof_long_long) +PAC_SET_MPI_TYPE(0a, MPI_FLOAT, $ac_cv_sizeof_float) +PAC_SET_MPI_TYPE(0b, MPI_DOUBLE, $ac_cv_sizeof_double) +PAC_SET_MPI_TYPE(0c, MPI_LONG_DOUBLE, $ac_cv_sizeof_long_double) +PAC_SET_MPI_TYPE(0d, MPI_BYTE, 1) +PAC_SET_MPI_TYPE(0e, MPI_WCHAR, $ac_cv_sizeof_wchar_t) +PAC_SET_MPI_TYPE(0f, MPI_PACKED, 1) +PAC_SET_MPI_LBUB(10, MPI_LB) +PAC_SET_MPI_LBUB(11, MPI_UB) + +PAC_SET_MPI_PAIRTYPE(00, MPI_FLOAT_INT) +PAC_SET_MPI_PAIRTYPE(01, MPI_DOUBLE_INT) +PAC_SET_MPI_PAIRTYPE(02, MPI_LONG_INT) +PAC_SET_MPI_PAIRTYPE(03, MPI_SHORT_INT) +PAC_SET_MPI_TYPE(16, MPI_2INT, $ac_cv_sizeof_two_int) +PAC_SET_MPI_PAIRTYPE(04, MPI_LONG_DOUBLE_INT) +PAC_SET_MPI_TYPE(18, MPI_SIGNED_CHAR, 1) +PAC_SET_MPI_TYPE(19, MPI_UNSIGNED_LONG_LONG, $ac_cv_sizeof_long_long) +PAC_SET_MPI_TYPE(1a, MPI_CHARACTER, $pac_cv_f77_sizeof_character) +PAC_SET_MPI_TYPE(1b, MPI_INTEGER, $pac_cv_f77_sizeof_integer) +PAC_SET_MPI_TYPE(1c, MPI_REAL, $pac_cv_f77_sizeof_real) +PAC_SET_MPI_TYPE(1d, MPI_LOGICAL, $pac_cv_f77_sizeof_integer) +PAC_SET_MPI_TYPE(1e, MPI_COMPLEX, $pac_cv_f77_sizeof_real, 2) +PAC_SET_MPI_TYPE(1f, MPI_DOUBLE_PRECISION, $pac_cv_f77_sizeof_double_precision) +PAC_SET_MPI_TYPE(20, MPI_2INTEGER, $pac_cv_f77_sizeof_integer, 2) +PAC_SET_MPI_TYPE(21, MPI_2REAL, $pac_cv_f77_sizeof_real, 2) +PAC_SET_MPI_TYPE(22, MPI_DOUBLE_COMPLEX, $pac_cv_f77_sizeof_double_precision, 2) +PAC_SET_MPI_TYPE(23, MPI_2DOUBLE_PRECISION, $pac_cv_f77_sizeof_double_precision, 2) +PAC_SET_MPI_TYPE(24, MPI_2COMPLEX, $pac_cv_f77_sizeof_real, 4) +PAC_SET_MPI_TYPE(25, MPI_2DOUBLE_COMPLEX, $pac_cv_f77_sizeof_double_precision, 4) + +PAC_SET_MPI_TYPE(27, MPI_REAL4, $pac_cv_f77_sizeof_real4) +PAC_SET_MPI_TYPE(28, MPI_COMPLEX8, $pac_cv_f77_sizeof_real4, 2) +PAC_SET_MPI_TYPE(29, MPI_REAL8, $pac_cv_f77_sizeof_real8) +PAC_SET_MPI_TYPE(2a, MPI_COMPLEX16, $pac_cv_f77_sizeof_real8, 2) +PAC_SET_MPI_TYPE(2b, MPI_REAL16, $pac_cv_f77_sizeof_real16) +PAC_SET_MPI_TYPE(2c, MPI_COMPLEX32, $pac_cv_f77_sizeof_real16, 2) +PAC_SET_MPI_TYPE(2d, MPI_INTEGER1, $pac_cv_f77_sizeof_integer1) + +PAC_SET_MPI_TYPE(2f, MPI_INTEGER2, $pac_cv_f77_sizeof_integer2) +PAC_SET_MPI_TYPE(30, MPI_INTEGER4, $pac_cv_f77_sizeof_integer4) +PAC_SET_MPI_TYPE(31, MPI_INTEGER8, $pac_cv_f77_sizeof_integer8) +PAC_SET_MPI_TYPE(32, MPI_INTEGER16, $pac_cv_f77_sizeof_integer16) +PAC_SET_MPI_TYPE(33, MPIR_CXX_BOOL, $ac_cv_sizeof_bool) +PAC_SET_MPI_TYPE(34, MPIR_CXX_FLOAT_COMPLEX, $ac_cv_sizeof_Complex) +PAC_SET_MPI_TYPE(35, MPIR_CXX_DOUBLE_COMPLEX, $ac_cv_sizeof_DoubleComplex) +PAC_SET_MPI_TYPE(36, MPIR_CXX_LONG_DOUBLE_COMPLEX, $ac_cv_sizeof_LongDoubleComplex) +PAC_SET_MPI_TYPE(37, MPI_INT8_T, 1) +PAC_SET_MPI_TYPE(38, MPI_INT16_T, 2) +PAC_SET_MPI_TYPE(39, MPI_INT32_T, 4) +PAC_SET_MPI_TYPE(3a, MPI_INT64_T, 8) +PAC_SET_MPI_TYPE(3b, MPI_UINT8_T, 1) +PAC_SET_MPI_TYPE(3c, MPI_UINT16_T, 2) +PAC_SET_MPI_TYPE(3d, MPI_UINT32_T, 4) +PAC_SET_MPI_TYPE(3e, MPI_UINT64_T, 8) +PAC_SET_MPI_TYPE(3f, MPI_C_BOOL, $ac_cv_sizeof__Bool) +PAC_SET_MPI_TYPE(40, MPI_C_FLOAT_COMPLEX, $ac_cv_sizeof_float__Complex) +PAC_SET_MPI_TYPE(41, MPI_C_DOUBLE_COMPLEX, $ac_cv_sizeof_double__Complex) +PAC_SET_MPI_TYPE(42, MPI_C_LONG_DOUBLE_COMPLEX, $ac_cv_sizeof_long_double__Complex) +PAC_SET_MPI_TYPE(43, MPI_AINT_DATATYPE, $MPI_SIZEOF_AINT) +PAC_SET_MPI_TYPE(44, MPI_OFFSET_DATATYPE, $MPI_SIZEOF_OFFSET) +PAC_SET_MPI_TYPE(45, MPI_COUNT_DATATYPE, $MPI_SIZEOF_COUNT) +PAC_SET_MPI_TYPE(46, MPIX_C_FLOAT16, 2) +AC_MSG_RESULT([done]) + +# aliases +PAC_SET_MPI_DATATYPE_ALIAS(MPI_LONG_LONG, MPI_LONG_LONG_INT) +PAC_SET_MPI_DATATYPE_ALIAS(MPI_C_COMPLEX, MPI_C_FLOAT_COMPLEX) # ------------------------------------------------------------------------ # Test if type_tag_for_datatype is agnostic to modifiers such as const, volatile, and restrict @@ -4326,90 +3738,8 @@ if test "$NEEDSPLIB" = "yes" ; then fi AC_SUBST(LPMPILIBNAME) -# Note that aint_size must be used instead of void_p where the desired check -# is on the size of MPI_Aint -aint_size=$ac_cv_sizeof_void_p -if test "$with_aint_size" -gt 0 ; then - aint_size=$with_aint_size - if test "$aint_size" != "$ac_cv_sizeof_void_p" ; then - AC_MSG_RESULT([Overriding MPI_Aint to be $aint_size bytes]) - fi -fi -MPI_AINT=int -for type in int long long_long short ; do - eval len=\$ac_cv_sizeof_$type - if test "$len" = "$aint_size" ; then - MPI_AINT=`echo $type | sed -e 's/_/ /'` - # Make the sizeof AINT available to other configures - MPI_SIZEOF_AINT=$len - export MPI_SIZEOF_AINT - case $type in - int) - MPI_AINT_FMT_DEC_SPEC="%d" - MPI_AINT_FMT_HEX_SPEC="%x" - MPIR_AINT_MAX="INT_MAX" - ;; - long) - MPI_AINT_FMT_DEC_SPEC="%ld" - MPI_AINT_FMT_HEX_SPEC="%lx" - MPIR_AINT_MAX="LONG_MAX" - ;; - long_long) - MPI_AINT_FMT_DEC_SPEC="%lld" - MPI_AINT_FMT_HEX_SPEC="%llx" - # tt#1776: if LLONG_MAX is missing, we fix it up in C, b/c it's - # easier there. See mpiiimpl.h. - MPIR_AINT_MAX="LLONG_MAX" - ;; - short) - MPI_AINT_FMT_DEC_SPEC="%hd" - MPI_AINT_FMT_HEX_SPEC="%hx" - MPIR_AINT_MAX="SHRT_MAX" - ;; - *) - AC_MSG_WARN([unable to determine format specifiers for MPI_Aint, defaulting to int]) - MPI_AINT_FMT_DEC_SPEC="%d" - MPI_AINT_FMT_HEX_SPEC="%x" - MPIR_AINT_MAX="INT_MAX" - ;; - esac - export MPI_AINT_FMT_DEC_SPEC MPI_AINT_FMT_HEX_SPEC - break - fi -done -AC_SUBST(MPI_AINT) -AC_SUBST(MPI_AINT_FMT_DEC_SPEC) -AC_SUBST(MPI_AINT_FMT_HEX_SPEC) -AC_DEFINE_UNQUOTED([MPIR_AINT_MAX],[$MPIR_AINT_MAX],[limits.h _MAX constant for MPI_Aint]) - -# ---------------------------------------------------------------------------- -# MPI_AINT datatype -# ---------------------------------------------------------------------------- -# Must be done after MPI_Aint type determination but before subconfigures. - -# convert to 2-char hex size -case "$MPI_SIZEOF_AINT" in - 4) len_mpi_aint=04 ;; - 8) len_mpi_aint=08 ;; - 16) len_mpi_aint=10 ;; - *) AC_MSG_ERROR([Unable to convert MPI_SIZEOF_AINT to a hex string. This is either because we are building on a very strange platform or there is a bug somewhere in configure.]) ;; -esac -# MPI_AINT and MPI_OFFSET are already taken, appending a _DATATYPE suffix -MPI_AINT_DATATYPE=0x4c00${len_mpi_aint}43 -AC_SUBST(MPI_AINT_DATATYPE) -export MPI_AINT_DATATYPE - -# 0x4c000043 is 1275068483 in decimal, add ($MPI_SIZEOF_AINT * 256) and you get -# the decimal equivalent of the hex number -MPI_F77_AINT=`expr 1275068483 '+' '(' 256 '*' $MPI_SIZEOF_AINT ')'` -AC_SUBST(MPI_F77_AINT) -export MPI_F77_AINT # ---------------------------------------------------------------------------- -if test "$ac_cv_sizeof_void_p" -lt "$aint_size" ; then - AC_DEFINE(USE_AINT_FOR_ATTRVAL,1,[Define if MPI_Aint should be used instead of void * for storing attribute values]) -fi - # with MPI_AINT defined, now we can # Get the size for the bsendoverhead AC_CHECK_SIZEOF(MPII_Bsend_data_t,0,[ @@ -4555,183 +3885,6 @@ dnl PAC_SUBDIR_CACHE_CLEANUP # FIXME does the makefile actually need this? subsystems="$devsubsystems $subsystems $bindingsubsystems" -if test "$enable_f77" != "yes" ; then - # These are Fortran datatypes ONLY. Set to null if no Fortran compiler. - for name in CHARACTER INTEGER REAL LOGICAL COMPLEX DOUBLE_PRECISION \ - 2INTEGER 2REAL DOUBLE_COMPLEX 2DOUBLE_PRECISION ; do - fullname="MPI_$name" - eval $fullname=MPI_DATATYPE_NULL - done - AC_MSG_WARN([Could not define Fortran MPI datatypes for C]) - AC_DEFINE(HAVE_NO_FORTRAN_MPI_TYPES_IN_C,1,[Define if the Fortran types are not available in C]) - # Temporary values for MPI_Fint (need help from the Fortran subsystem) - MPI_FINT=int -fi -AC_SUBST(MPI_CHARACTER) -AC_SUBST(MPI_INTEGER) -AC_SUBST(MPI_REAL) -AC_SUBST(MPI_LOGICAL) -AC_SUBST(MPI_COMPLEX) -AC_SUBST(MPI_DOUBLE_PRECISION) -AC_SUBST(MPI_2INTEGER) -AC_SUBST(MPI_2REAL) -AC_SUBST(MPI_DOUBLE_COMPLEX) -AC_SUBST(MPI_2DOUBLE_PRECISION) -AC_SUBST(MPI_FINT) - -# If ROMIO was successfully configured, then ROMIO will have exported the -# definition of MPI_OFFSET_TYPE through its localdefs file (created by the -# ROMIO configure in src/mpi/romio/localdefs). If MPI_OFFSET_TYPE was not -# defined, this code attempts to find a good choice for MPI_OFFSET_TYPE -# (As the offset type is used for File operations, the specific type -# really doesn't matter if ROMIO doesn't provide it). -if test -n "$MPI_OFFSET_TYPE" ; then - # We got the value from the ROMIO configure - MPI_OFFSET="$MPI_OFFSET_TYPE" - # Get and export the size of this type if possible - if test -z "$MPI_SIZEOF_OFFSET" ; then - # set a default - AC_CACHE_CHECK([the sizeof MPI_Offset],ac_cv_sizeof_MPI_Offset,[ - ac_cv_sizeof_MPI_Offset=unknown - AC_COMPUTE_INT([ac_cv_sizeof_MPI_Offset],[sizeof($MPI_OFFSET)],[],[ - AC_MSG_WARN([Unable to determine the size of MPI_Offset]) - ]) - ]) - if test "$ac_cv_sizeof_MPI_Offset" != "unknown" ; then - MPI_SIZEOF_OFFSET=$ac_cv_sizeof_MPI_Offset - fi - fi - export MPI_SIZEOF_OFFSET -else - # Make a guess at the appropriate definition for offset. Try to - # find a 64bit type. - if test "$ac_cv_sizeof_long" = 8 ; then - MPI_OFFSET="long" - # Make the size of this type available to other configures - MPI_SIZEOF_OFFSET=8 - elif test "$ac_cv_sizeof_long_long" = 8 ; then - MPI_OFFSET="long long" - # Make the size of this type available to other configures - MPI_SIZEOF_OFFSET=8 - else - MPI_OFFSET=long - MPI_SIZEOF_OFFSET=$ac_cv_sizeof_long - fi - export MPI_SIZEOF_OFFSET -fi -AC_SUBST(MPI_OFFSET) - -AS_CASE([$MPI_OFFSET], - [int], [MPIR_OFFSET_MAX="INT_MAX"], - [long], [MPIR_OFFSET_MAX="LONG_MAX"], - ['long long'], [MPIR_OFFSET_MAX="LLONG_MAX"], - [short], [MPIR_OFFSET_MAX="SHRT_MAX"], - [AC_MSG_ERROR([unable to determine MPIR_OFFSET_MAX for MPI_Offset])]) -AC_DEFINE_UNQUOTED([MPIR_OFFSET_MAX],[$MPIR_OFFSET_MAX],[limits.h _MAX constant for MPI_Offset]) - -# FIXME: we need an explanation of why we need both MPI_OFFSET and -# MPI_OFFSET_TYPEDEF. Why is MPI_OFFSET_TYPEDEF necessary? -# This appears to be used by the Windows "winconfigure.wsf" which is used -# to create a multiline definition using an #ifdef check on USE_GCC -# We may wish to use a different approach -MPI_OFFSET_TYPEDEF="typedef $MPI_OFFSET MPI_Offset;" -AC_SUBST(MPI_OFFSET_TYPEDEF) -# -# Fortran type for an Offset type (needed to define MPI_DISPLACEMENT_CURRENT -# The value for this comes from ROMIO, and is needed in mpif.h.in -# First, we check that this works with both Fortran compilers (if -# they are defined) -# -# If there is no FORTRAN_MPI_OFFSET type (because ROMIO is disabled), -# just use INTEGER -if test -z "$FORTRAN_MPI_OFFSET" ; then - FORTRAN_MPI_OFFSET=INTEGER -fi -if test "$enable_f77" = yes -a "$enable_fc" = yes ; then - AC_LANG_PUSH([Fortran 77]) - AC_MSG_CHECKING([whether the Fortran Offset type works with Fortran 77]) - AC_COMPILE_IFELSE([ - AC_LANG_PROGRAM([],[ $FORTRAN_MPI_OFFSET i]) - ],[has_f77_offsettype=yes],[has_f77_offsetype=no]) - AC_MSG_RESULT($has_f77_offsettype) - AC_LANG_POP([Fortran 77]) - - AC_LANG_PUSH([Fortran]) - AC_MSG_CHECKING([whether the Fortran Offset type works with Fortran 90]) - AC_COMPILE_IFELSE([ - AC_LANG_PROGRAM([],[ $FORTRAN_MPI_OFFSET i]) - ],[has_fc_offsettype=yes],[has_fc_offsetype=no]) - AC_LANG_POP([Fortran]) - AC_MSG_RESULT($has_fc_offsettype) - - if test "$has_f77_offsettype" != yes -o "$has_fc_offsettype" != yes ; then - AC_MSG_WARN([mpif.h is not compatible with both $F77 $FFLAGS and $FC $FCFLAGS. We recommend that you set both F77 and FC to the same compiler and reconfigure.]) - fi -fi -AC_SUBST(FORTRAN_MPI_OFFSET) -# - -# ---------------------------------------------------------------------------- -# MPI_OFFSET datatype -# ---------------------------------------------------------------------------- -# must be done after ROMIO configure step -case "$MPI_SIZEOF_OFFSET" in - 4) len_mpi_offset=04 ;; - 8) len_mpi_offset=08 ;; - 16) len_mpi_offset=10 ;; - *) AC_MSG_ERROR([Unable to convert MPI_SIZEOF_OFFSET to a hex string. This is either because we are building on a very strange platform or there is a bug somewhere in configure.]) ;; -esac -MPI_OFFSET_DATATYPE=0x4c00${len_mpi_offset}44 -AC_SUBST(MPI_OFFSET_DATATYPE) -export MPI_OFFSET_DATATYPE - -# 0x4c000044 is 1275068484 in decimal, add ($MPI_SIZEOF_OFFSET * 256) and you get -# the decimal equivalent of the hex number -MPI_F77_OFFSET=`expr 1275068484 '+' '(' 256 '*' $MPI_SIZEOF_OFFSET ')'` -AC_SUBST(MPI_F77_OFFSET) -export MPI_F77_OFFSET - -# ---------------------------------------------------------------------------- -# MPI_COUNT datatype -# ---------------------------------------------------------------------------- -# quick sanity checking to avoid a bad test immediately below -AS_IF([test -z "$MPI_SIZEOF_AINT"], - [AC_MSG_ERROR([size of MPI_Aint is unknown at this stage])]) -AS_IF([test -z "$MPI_SIZEOF_OFFSET"], - [AC_MSG_ERROR([size of MPI_Offset is unknown at this stage])]) - -AS_IF([test "$MPI_SIZEOF_AINT" -gt "$MPI_SIZEOF_OFFSET"], - [# an unlikely case, but I suppose it's theoretically possible - MPI_COUNT="$MPI_AINT" - COUNT_KIND="$ADDRESS_KIND" - MPIR_COUNT_MAX="$MPIR_AINT_MAX" - MPI_SIZEOF_COUNT="$MPI_SIZEOF_AINT"], - [# don't bother checking whether Aint or Offset are larger than int, they - # surely will be - MPI_COUNT="$MPI_OFFSET" - COUNT_KIND="$OFFSET_KIND" - MPIR_COUNT_MAX="$MPIR_OFFSET_MAX" - MPI_SIZEOF_COUNT="$MPI_SIZEOF_OFFSET"]) -AC_SUBST([MPI_COUNT]) -AC_SUBST([COUNT_KIND]) -AC_DEFINE_UNQUOTED([MPIR_COUNT_MAX],[$MPIR_COUNT_MAX],[limits.h _MAX constant for MPI_Count]) -AC_DEFINE_UNQUOTED(MPIR_Ucount,unsigned $MPI_COUNT,[MPIR_Ucount is an unsigned MPI_Count-sized integer]) - -AS_CASE([$MPI_SIZEOF_COUNT], - [4], [len_mpi_count=04], - [8], [len_mpi_count=08], - [16],[len_mpi_count=10], - [AC_MSG_ERROR([Unable to convert MPI_SIZEOF_COUNT to a hex string!])]) -MPI_COUNT_DATATYPE=0x4c00${len_mpi_count}45 -AC_SUBST([MPI_COUNT_DATATYPE]) - -# 0x4c000045 is 1275068485 in decimal, add ($MPI_SIZEOF_COUNT * 256) and you get -# the decimal equivalent of the hex number -MPI_F77_COUNT=`expr 1275068485 '+' '(' 256 '*' $MPI_SIZEOF_OFFSET ')'` -AC_SUBST([MPI_F77_COUNT]) - -# ---------------------------------------------------------------------------- - # MPI_STATUS_SIZE is hardcoded and need to be synchronized with mpi.h MPI_STATUS_SIZE=5 AC_SUBST([MPI_STATUS_SIZE]) @@ -5002,103 +4155,7 @@ if test "X$enable_shared" = "Xyes" ; then ) fi -# Set F08 versions of datatypes, which have type MPI_Datatype and are not integers anymore. -# If the corresponding F77 datatypes exist, i.e., not MPI_DATATYPE_NULL, we simply use their -# integer value (already converted into decimal) in F08 counterparts. Otherwise, we use -# MPI_VAL value of F08 MPI_DATATYPE_NULL. -# We put the code at the end to ensure all F77 datatypes have been set. - if test "X$f08_works" = "Xyes"; then - for type in INTEGER1 INTEGER2 INTEGER4 INTEGER8 INTEGER16 \ - REAL4 REAL8 REAL16 \ - COMPLEX8 COMPLEX16 COMPLEX32; do - eval f77typename=F77_$type - eval f77typevalue=\$$f77typename - if test "$f77typevalue" = MPI_DATATYPE_NULL ; then - eval F08_$type=MPI_DATATYPE_NULL%MPI_VAL - else - eval F08_$type=$f77typevalue - fi - done - AC_SUBST(F08_INTEGER1) - AC_SUBST(F08_INTEGER2) - AC_SUBST(F08_INTEGER4) - AC_SUBST(F08_INTEGER8) - AC_SUBST(F08_INTEGER16) - AC_SUBST(F08_REAL4) - AC_SUBST(F08_REAL8) - AC_SUBST(F08_REAL16) - AC_SUBST(F08_COMPLEX8) - AC_SUBST(F08_COMPLEX16) - AC_SUBST(F08_COMPLEX32) - - for type in PACKED UB LB BYTE \ - CHAR SIGNED_CHAR UNSIGNED_CHAR WCHAR SHORT \ - UNSIGNED_SHORT UNSIGNED INT LONG UNSIGNED_INT UNSIGNED_LONG \ - FLOAT DOUBLE LONG_DOUBLE LONG_LONG_INT \ - UNSIGNED_LONG_LONG LONG_LONG FLOAT_INT DOUBLE_INT \ - LONG_INT SHORT_INT "2INT" LONG_DOUBLE_INT \ - INT8_T INT16_T INT32_T INT64_T \ - UINT8_T UINT16_T UINT32_T UINT64_T \ - C_BOOL C_FLOAT_COMPLEX C_COMPLEX C_DOUBLE_COMPLEX C_LONG_DOUBLE_COMPLEX \ - AINT OFFSET COUNT \ - CXX_BOOL CXX_FLOAT_COMPLEX CXX_DOUBLE_COMPLEX CXX_LONG_DOUBLE_COMPLEX; do - eval f77typename=MPI_F77_$type - eval f77typevalue=\$$f77typename - if test "$f77typevalue" = MPI_DATATYPE_NULL ; then - eval F08_$type=MPI_DATATYPE_NULL%MPI_VAL - else - eval F08_$type=$f77typevalue - fi - done - AC_SUBST(F08_PACKED) - AC_SUBST(F08_UB) - AC_SUBST(F08_LB) - AC_SUBST(F08_BYTE) - AC_SUBST(F08_CHAR) - AC_SUBST(F08_SIGNED_CHAR) - AC_SUBST(F08_UNSIGNED_CHAR) - AC_SUBST(F08_WCHAR) - AC_SUBST(F08_SHORT) - AC_SUBST(F08_UNSIGNED_SHORT) - AC_SUBST(F08_UNSIGNED) - AC_SUBST(F08_INT) - AC_SUBST(F08_LONG) - AC_SUBST(F08_UNSIGNED_INT) - AC_SUBST(F08_UNSIGNED_LONG) - AC_SUBST(F08_FLOAT) - AC_SUBST(F08_DOUBLE) - AC_SUBST(F08_LONG_DOUBLE) - AC_SUBST(F08_LONG_LONG_INT) - AC_SUBST(F08_UNSIGNED_LONG_LONG) - AC_SUBST(F08_LONG_LONG) - AC_SUBST(F08_FLOAT_INT) - AC_SUBST(F08_DOUBLE_INT) - AC_SUBST(F08_LONG_INT) - AC_SUBST(F08_SHORT_INT) - AC_SUBST(F08_2INT) - AC_SUBST(F08_LONG_DOUBLE_INT) - AC_SUBST(F08_INT8_T) - AC_SUBST(F08_INT16_T) - AC_SUBST(F08_INT32_T) - AC_SUBST(F08_INT64_T) - AC_SUBST(F08_UINT8_T) - AC_SUBST(F08_UINT16_T) - AC_SUBST(F08_UINT32_T) - AC_SUBST(F08_UINT64_T) - AC_SUBST(F08_C_BOOL) - AC_SUBST(F08_C_FLOAT_COMPLEX) - AC_SUBST(F08_C_COMPLEX) - AC_SUBST(F08_C_DOUBLE_COMPLEX) - AC_SUBST(F08_C_LONG_DOUBLE_COMPLEX) - AC_SUBST(F08_AINT) - AC_SUBST(F08_OFFSET) - AC_SUBST(F08_COUNT) - AC_SUBST(F08_CXX_BOOL) - AC_SUBST(F08_CXX_FLOAT_COMPLEX) - AC_SUBST(F08_CXX_DOUBLE_COMPLEX) - AC_SUBST(F08_CXX_LONG_DOUBLE_COMPLEX) - AS_CASE([$MPI_AINT], [short], [F08_C_AINT="c_short"], [int], [F08_C_AINT="c_int"], From 343d95907bf143fd777960031171fc01c988295e Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 20 Oct 2021 22:30:48 -0500 Subject: [PATCH 122/607] misc: fix compatibility issues --- src/binding/cxx/buildiface | 7 +++++-- src/binding/fortran/mpif_h/buildiface | 21 ++++++++++++--------- src/binding/fortran/use_mpi_f08/buildiface | 19 +++++++++++++++---- src/include/mpi.h.in | 6 +++--- src/include/mpir_op_util.h | 10 +++++----- 5 files changed, 40 insertions(+), 23 deletions(-) diff --git a/src/binding/cxx/buildiface b/src/binding/cxx/buildiface index f9e96bc837a..141570e36cc 100755 --- a/src/binding/cxx/buildiface +++ b/src/binding/cxx/buildiface @@ -1861,11 +1861,14 @@ sub PrintConstants { # C counterpart; their MPI Datatype handles are determined by the # configure step and inserted into mpicxx.h as #define's foreach $dtype (@cppdtypes) { + my $use_dtype = $dtype; + if ($dtype eq "COMPLEX") { + $use_dtype = "FLOAT_COMPLEX" + } print $OUTFD "${extern}Datatype $dtype"; - if ($giveValue) { print $OUTFD "(MPIR_CXX_$dtype);\n"; } + if ($giveValue) { print $OUTFD "(MPI_CXX_$use_dtype);\n"; } else { print $OUTFD ";\n"; - print $OUTFD "#define MPIR_CXX_$dtype \@MPIR_CXX_${dtype}\@\n"; } } diff --git a/src/binding/fortran/mpif_h/buildiface b/src/binding/fortran/mpif_h/buildiface index ae957800542..019855a7da7 100755 --- a/src/binding/fortran/mpif_h/buildiface +++ b/src/binding/fortran/mpif_h/buildiface @@ -226,13 +226,13 @@ if ($write_mpif) { # These are determined and set at configure time foreach $key (COMPLEX, DOUBLE_COMPLEX, LOGICAL, REAL, DOUBLE_PRECISION, INTEGER, '2INTEGER', '2DOUBLE_PRECISION', '2REAL', CHARACTER) { print MPIFFD " INTEGER MPI_$key\n"; - print MPIFFD " PARAMETER (MPI_$key=\@MPI_$key\@)\n"; + print MPIFFD " PARAMETER (MPI_$key=\@F77_MPI_$key\@)\n"; } # Value of MPI_BYTE from top level configure! $mpidef{"MPI_BYTE"} = hex "0x4c00010d"; foreach $key (BYTE, UB, LB, PACKED) { print MPIFFD " INTEGER MPI_$key\n"; - print MPIFFD " PARAMETER (MPI_$key=\@MPI_F77_$key\@)\n"; + print MPIFFD " PARAMETER (MPI_$key=\@F77_MPI_$key\@)\n"; } #&print_mpif_int( "MPI_BYTE" ); #&print_mpif_int( "MPI_UB" ); @@ -245,7 +245,7 @@ if ($write_mpif) { foreach $key (INTEGER1, INTEGER2, INTEGER4, INTEGER8, INTEGER16, REAL4, REAL8, REAL16, COMPLEX8, COMPLEX16, COMPLEX32) { print MPIFFD " INTEGER MPI_$key\n"; - print MPIFFD " PARAMETER (MPI_$key=\@F77_$key\@)\n"; + print MPIFFD " PARAMETER (MPI_$key=\@F77_MPI_$key\@)\n"; } # # Fortran 90 types @@ -269,24 +269,27 @@ if ($write_mpif) { UNSIGNED_LONG_LONG, LONG_LONG, FLOAT_INT, DOUBLE_INT, LONG_INT, SHORT_INT, "2INT", LONG_DOUBLE_INT) { print MPIFFD " INTEGER MPI_$key\n"; - print MPIFFD " PARAMETER (MPI_$key=\@MPI_F77_$key\@)\n"; + print MPIFFD " PARAMETER (MPI_$key=\@F77_MPI_$key\@)\n"; } # C types added in MPI 2.2 foreach $key (INT8_T, INT16_T, INT32_T, INT64_T, UINT8_T, UINT16_T, UINT32_T, UINT64_T, C_BOOL, C_FLOAT_COMPLEX, C_COMPLEX, - C_DOUBLE_COMPLEX, C_LONG_DOUBLE_COMPLEX, AINT, OFFSET) { + C_DOUBLE_COMPLEX, C_LONG_DOUBLE_COMPLEX) { print MPIFFD " INTEGER MPI_$key\n"; - print MPIFFD " PARAMETER (MPI_$key=\@MPI_F77_$key\@)\n"; + print MPIFFD " PARAMETER (MPI_$key=\@F77_MPI_$key\@)\n"; + } + foreach $key (qw(AINT OFFSET COUNT)) { + print MPIFFD " INTEGER MPI_$key\n"; + print MPIFFD " PARAMETER (MPI_$key=\@F77_MPI_${key}_DATATYPE\@)\n"; } # C types added in MPI 3.0 - foreach $key (qw(COUNT - CXX_BOOL + foreach $key (qw(CXX_BOOL CXX_FLOAT_COMPLEX CXX_DOUBLE_COMPLEX CXX_LONG_DOUBLE_COMPLEX)) { print MPIFFD " INTEGER MPI_$key\n"; - print MPIFFD " PARAMETER (MPI_$key=\@MPI_F77_$key\@)\n"; + print MPIFFD " PARAMETER (MPI_$key=\@F77_MPIR_$key\@)\n"; } # Datatype combiners foreach $key (NAMED, DUP, CONTIGUOUS, VECTOR, HVECTOR_INTEGER, HVECTOR, diff --git a/src/binding/fortran/use_mpi_f08/buildiface b/src/binding/fortran/use_mpi_f08/buildiface index 4ffc64e2dca..2655e89e73b 100755 --- a/src/binding/fortran/use_mpi_f08/buildiface +++ b/src/binding/fortran/use_mpi_f08/buildiface @@ -427,6 +427,7 @@ print $constants_fh "\n! Datatypes\n"; foreach $key (qw(COMPLEX DOUBLE_COMPLEX LOGICAL REAL DOUBLE_PRECISION INTEGER 2INTEGER 2DOUBLE_PRECISION 2REAL CHARACTER)) { + $mpidef{"MPI_$key"} = "\@F08_MPI_$key\@"; &print_param("MPI_Datatype", "MPI_$key"); } @@ -442,11 +443,21 @@ foreach $key (qw(BYTE UB LB PACKED LONG_INT SHORT_INT 2INT LONG_DOUBLE_INT INT8_T INT16_T INT32_T INT64_T UINT8_T UINT16_T UINT32_T UINT64_T - C_BOOL C_FLOAT_COMPLEX C_COMPLEX C_DOUBLE_COMPLEX C_LONG_DOUBLE_COMPLEX - AINT OFFSET COUNT - CXX_BOOL CXX_FLOAT_COMPLEX CXX_DOUBLE_COMPLEX CXX_LONG_DOUBLE_COMPLEX)) + C_BOOL C_FLOAT_COMPLEX C_COMPLEX C_DOUBLE_COMPLEX C_LONG_DOUBLE_COMPLEX)) { - $mpidef{"MPI_$key"} = "\@F08_$key\@"; + $mpidef{"MPI_$key"} = "\@F08_MPI_$key\@"; + &print_param("MPI_Datatype", "MPI_$key"); +} + +foreach $key (qw(AINT OFFSET COUNT)) +{ + $mpidef{"MPI_$key"} = "\@F08_MPI_${key}_DATATYPE\@"; + &print_param("MPI_Datatype", "MPI_$key"); +} + +foreach $key (qw(CXX_BOOL CXX_FLOAT_COMPLEX CXX_DOUBLE_COMPLEX CXX_LONG_DOUBLE_COMPLEX)) +{ + $mpidef{"MPI_$key"} = "\@F08_MPIR_${key}\@"; &print_param("MPI_Datatype", "MPI_$key"); } diff --git a/src/include/mpi.h.in b/src/include/mpi.h.in index 4eb4c6eba9f..d82c5dd6734 100644 --- a/src/include/mpi.h.in +++ b/src/include/mpi.h.in @@ -110,13 +110,13 @@ typedef int MPI_Datatype; #define MPI_SHORT ((MPI_Datatype)@MPI_SHORT@) #define MPI_UNSIGNED_SHORT ((MPI_Datatype)@MPI_UNSIGNED_SHORT@) #define MPI_INT ((MPI_Datatype)@MPI_INT@) -#define MPI_UNSIGNED ((MPI_Datatype)@MPI_UNSIGNED_INT@) +#define MPI_UNSIGNED ((MPI_Datatype)@MPI_UNSIGNED@) #define MPI_LONG ((MPI_Datatype)@MPI_LONG@) #define MPI_UNSIGNED_LONG ((MPI_Datatype)@MPI_UNSIGNED_LONG@) #define MPI_FLOAT ((MPI_Datatype)@MPI_FLOAT@) #define MPI_DOUBLE ((MPI_Datatype)@MPI_DOUBLE@) #define MPI_LONG_DOUBLE ((MPI_Datatype)@MPI_LONG_DOUBLE@) -#define MPI_LONG_LONG_INT ((MPI_Datatype)@MPI_LONG_LONG@) +#define MPI_LONG_LONG_INT ((MPI_Datatype)@MPI_LONG_LONG_INT@) #define MPI_UNSIGNED_LONG_LONG ((MPI_Datatype)@MPI_UNSIGNED_LONG_LONG@) #define MPI_LONG_LONG MPI_LONG_LONG_INT @@ -265,7 +265,7 @@ static const MPI_Datatype mpich_mpi_c_long_double_complex MPICH_ATTR_TYPE_TAG_C9 /* MPI-3 C++ types */ #define MPI_CXX_BOOL ((MPI_Datatype)@MPIR_CXX_BOOL@) -#define MPI_CXX_FLOAT_COMPLEX ((MPI_Datatype)@MPIR_CXX_COMPLEX@) +#define MPI_CXX_FLOAT_COMPLEX ((MPI_Datatype)@MPIR_CXX_FLOAT_COMPLEX@) #define MPI_CXX_DOUBLE_COMPLEX ((MPI_Datatype)@MPIR_CXX_DOUBLE_COMPLEX@) #define MPI_CXX_LONG_DOUBLE_COMPLEX ((MPI_Datatype)@MPIR_CXX_LONG_DOUBLE_COMPLEX@) diff --git a/src/include/mpir_op_util.h b/src/include/mpir_op_util.h index 5f57101e0e1..0f94dd168bc 100644 --- a/src/include/mpir_op_util.h +++ b/src/include/mpir_op_util.h @@ -155,7 +155,7 @@ MPIR_OP_TYPE_GROUP(C_INTEGER) #define MPIR_OP_TYPE_MACRO_HAVE_CXX_COMPLEX(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_) #endif /* also test against MPI_DATATYPE_NULL for extra safety, 0x0c000000 is the uncasted value. */ -#if defined(HAVE_CXX_COMPLEX) && (MPIR_CXX_LONG_DOUBLE_COMPLEX_VALUE != 0x0c000000) +#if defined(HAVE_CXX_COMPLEX) && defined(HAVE_CXX_LONG_DOUBLE_COMPLEX) #undef MPIR_OP_TYPE_MACRO_HAVE_CXX_LONG_DOUBLE_COMPLEX #define MPIR_OP_TYPE_MACRO_HAVE_CXX_LONG_DOUBLE_COMPLEX(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_) #endif @@ -321,7 +321,7 @@ typedef struct { #define MPIR_OP_TYPE_GROUP_LOGICAL \ MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(MPI_LOGICAL, MPI_Fint, mpir_typename_logical) \ MPIR_OP_TYPE_MACRO_HAVE_C_BOOL(MPI_C_BOOL, _Bool, mpir_typename_c_bool) \ - MPIR_OP_TYPE_MACRO_HAVE_CXX(MPIR_CXX_BOOL_VALUE, MPIR_CXX_BOOL_CTYPE, mpir_typename_cxx_bool_value) + MPIR_OP_TYPE_MACRO_HAVE_CXX(MPI_CXX_BOOL, MPIR_CXX_BOOL_CTYPE, mpir_typename_cxx_bool_value) #define MPIR_OP_TYPE_GROUP_LOGICAL_EXTRA /* empty, provided for consistency */ /* complex group */ @@ -334,9 +334,9 @@ typedef struct { MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(MPI_DOUBLE_COMPLEX, d_fc_complex, mpir_typename_double_complex) \ MPIR_OP_TYPE_MACRO_HAVE_COMPLEX8(MPI_COMPLEX8, s_complex, mpir_typename_complex8) \ MPIR_OP_TYPE_MACRO_HAVE_COMPLEX16(MPI_COMPLEX16, d_complex, mpir_typename_complex16) \ - MPIR_OP_TYPE_MACRO_HAVE_CXX_COMPLEX(MPIR_CXX_COMPLEX_VALUE, s_complex, mpir_typename_cxx_complex_value) \ - MPIR_OP_TYPE_MACRO_HAVE_CXX_COMPLEX(MPIR_CXX_DOUBLE_COMPLEX_VALUE, d_complex, mpir_typename_cxx_double_complex_value) \ - MPIR_OP_TYPE_MACRO_HAVE_CXX_LONG_DOUBLE_COMPLEX(MPIR_CXX_LONG_DOUBLE_COMPLEX_VALUE, ld_complex, mpir_typename_cxx_long_double_complex_value) + MPIR_OP_TYPE_MACRO_HAVE_CXX_COMPLEX(MPI_CXX_FLOAT_COMPLEX, s_complex, mpir_typename_cxx_complex_value) \ + MPIR_OP_TYPE_MACRO_HAVE_CXX_COMPLEX(MPI_CXX_DOUBLE_COMPLEX, d_complex, mpir_typename_cxx_double_complex_value) \ + MPIR_OP_TYPE_MACRO_HAVE_CXX_LONG_DOUBLE_COMPLEX(MPI_CXX_LONG_DOUBLE_COMPLEX, ld_complex, mpir_typename_cxx_long_double_complex_value) /* byte group */ #define MPIR_OP_TYPE_GROUP_BYTE \ From 9c54ee6593d0dc3fa6395237e2bfc9a2159be7fc Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 15 Oct 2021 09:46:28 -0500 Subject: [PATCH 123/607] configure: set default ch4 device to ofi Not having a default device is negatively impacting user experience. Choose ch4:ofi as default and provide prominent summary notes to advise user. --- configure.ac | 21 ++-------- src/mpid/ch4/subconfigure.m4 | 80 ++++++++++++++++++++++++++---------- 2 files changed, 62 insertions(+), 39 deletions(-) diff --git a/configure.ac b/configure.ac index ae60d207f7e..f20a445cf76 100644 --- a/configure.ac +++ b/configure.ac @@ -4246,25 +4246,9 @@ AC_CONFIG_FILES([Makefile \ test/commands/cmdtests]) AC_OUTPUT +echo '*****************************************************' if test ${device_name} = "ch4" ; then - t_netmod=$ch4_netmods - if test "$ch4_netmods" = "ofi" -a "$with_libfabric" = "embedded"; then - t_netmod="ofi (embedded libfabric)" - elif test "$ch4_netmods" = "ucx" -a "$with_ucx" = "embedded"; then - t_netmod="ucx (embedded)" - fi - t_xpmem="" - if test "$pac_have_xpmem" = "yes" ; then - t_xpmem="xpmem" - fi -cat < or --with-ucx= - - to the configuration. - - The previous MPICH default device (ch3) is also available and - supported with option: - - --with-device=ch3 - ]) + pac_ch4_choice="ofi-default" + ch4_netmods=ofi fi], [ dnl non-linux use libfabric + pac_ch4_choice="ofi-default" ch4_netmods=ofi ]) else @@ -454,4 +440,56 @@ AM_CONDITIONAL([BUILD_CH4_COLL_TUNING],[test -e "$srcdir/src/mpid/ch4/src/ch4_co ])dnl end _BODY +dnl Summary notes at the end of configure +AC_DEFUN([PAC_CH4_CONFIG_SUMMARY], [ + t_netmod=$ch4_netmods + if test "$ch4_netmods" = "ofi" -a "$with_libfabric" = "embedded"; then + t_netmod="ofi (embedded libfabric)" + elif test "$ch4_netmods" = "ucx" -a "$with_ucx" = "embedded"; then + t_netmod="ucx (embedded)" + fi + t_xpmem="" + if test "$pac_have_xpmem" = "yes" ; then + t_xpmem="xpmem" + fi + t_gpu="disabled" + if test -n "${GPU_SUPPORT}" ; then + t_gpu="${GPU_SUPPORT}" + fi + cat < Date: Wed, 10 Feb 2021 17:16:20 -0500 Subject: [PATCH 124/607] ROMIO: GPFS: fix for Alltoallv potentially using large disps There was a problem with the Alltoallv in ADIOI_GPFS_Calc_others_req(). It was using sendbuf and sdisps[] to reference the various my_req[x].offsets, but those are all malloced separately and could thus be further apart than the integers in sdisps[] would allow. So this PR either uses MPI_Alltoallv_c if that's available, or it copies all that data into a new send buf before the Alltoallv, then copies it back out of a new recv buf if MPI_Alltoallv_c isn't available. I don't have a testcase that demonstrates the failure, but I did at least run a GPFS test that called MPI_File_write_all() and uses the Alltoallv(). Signed-off-by: Mark Allen --- src/mpi/romio/adio/ad_gpfs/ad_gpfs_aggrs.c | 114 +++++++++++++++++++-- 1 file changed, 106 insertions(+), 8 deletions(-) diff --git a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_aggrs.c b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_aggrs.c index 226e6c71a55..2dbdffd270b 100644 --- a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_aggrs.c +++ b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_aggrs.c @@ -26,6 +26,10 @@ #define TRACE_ERR(format...) #endif +static int +MY_Alltoallv(void *sbuf, int *scounts, MPI_Aint * sdisps, MPI_Datatype stype, + void *rbuf, int *rcounts, MPI_Aint * rdisps, MPI_Datatype rtype, MPI_Comm comm); + /* Comments copied from common: * This file contains four functions: * @@ -595,7 +599,7 @@ void ADIOI_GPFS_Calc_my_req(ADIO_File fd, ADIO_Offset * offset_list, ADIO_Offset (long long) my_req[i].offsets[l], l, (long long) my_req[i].lens[l]); } } - DBG_FPRINTF(stderr, "buf_idx[%d] = 0x%x\n", i, buf_idx[i]); + DBG_FPRINTF(stderr, "buf_idx[%d] = 0x%lx\n", i, buf_idx[i]); } #endif @@ -657,8 +661,13 @@ void ADIOI_GPFS_Calc_others_req(ADIO_File fd, int count_my_req_procs, int i; ADIOI_Access *others_req; +#if MPI_VERSION >= 4 +#define HAS_ALLTOALLV_C 1 +#else +#define HAS_ALLTOALLV_C 0 +#endif /* Parameters for MPI_Alltoallv */ - int *scounts, *sdispls, *rcounts, *rdispls; + MPI_Aint *sdispls, *rdispls; /* Parameters for MPI_Alltoallv. These are the buffers, which * are later computed to be the lowest address of all buffers @@ -692,10 +701,15 @@ void ADIOI_GPFS_Calc_others_req(ADIO_File fd, int count_my_req_procs, ADIOI_Malloc(nprocs * sizeof(ADIOI_Access)); others_req = *others_req_ptr; - scounts = ADIOI_Malloc(nprocs * sizeof(int)); - sdispls = ADIOI_Malloc(nprocs * sizeof(int)); - rcounts = ADIOI_Malloc(nprocs * sizeof(int)); - rdispls = ADIOI_Malloc(nprocs * sizeof(int)); + sdispls = ADIOI_Malloc(nprocs * sizeof(MPI_Aint)); + rdispls = ADIOI_Malloc(nprocs * sizeof(MPI_Aint)); +#if HAS_ALLTOALLV_C + MPI_Count *scounts = ADIOI_Malloc(nprocs * sizeof(MPI_Count)); + MPI_Count *rcounts = ADIOI_Malloc(nprocs * sizeof(MPI_Count)); +#else + int *scounts = ADIOI_Malloc(nprocs * sizeof(int)); + int *rcounts = ADIOI_Malloc(nprocs * sizeof(int)); +#endif /* If process[i] has any requests in my file domain, * initialize an ADIOI_Access structure that will describe each request @@ -769,8 +783,13 @@ void ADIOI_GPFS_Calc_others_req(ADIO_File fd, int count_my_req_procs, } /* Exchange the offsets and lengths */ - MPI_Alltoallv(sendBuf, scounts, sdispls, ADIO_OFFSET, - recvBuf, rcounts, rdispls, ADIO_OFFSET, fd->comm); +#if HAS_ALLTOALLV_C + MPI_Alltoallv_c(sendBuf, scounts, sdispls, ADIO_OFFSET, + recvBuf, rcounts, rdispls, ADIO_OFFSET, fd->comm); +#else + MY_Alltoallv(sendBuf, scounts, sdispls, ADIO_OFFSET, + recvBuf, rcounts, rdispls, ADIO_OFFSET, fd->comm); +#endif /* Clean up */ ADIOI_Free(scounts); @@ -798,3 +817,82 @@ void ADIOI_GPFS_Free_others_req(int nprocs, int *count_others_req_per_proc, ADIOI_Free(others_req); ADIOI_Free(count_others_req_per_proc); } + +/* + * Alltoallv with MPI_Aint for sdisps/rdisps + * + * If the disps are actually small enough to fit in an int, it + * creates int arrays and calls regular MPI_Alltoallv. + * Otherwise it does a bunch of copies to make the data contiguous + * so it can fit in int displacements. + */ +static int +MY_Alltoallv(void *sbuf, int *scounts, MPI_Aint * sdisps, MPI_Datatype stype, + void *rbuf, int *rcounts, MPI_Aint * rdisps, MPI_Datatype rtype, MPI_Comm comm) +{ + int sizeof_stype, sizeof_rtype; + int rv, i; + int nranks; + int disps_are_small_enough; + int *sdisps_int; + int *rdisps_int; + + MPI_Comm_size(comm, &nranks); + MPI_Type_size(stype, &sizeof_stype); + MPI_Type_size(rtype, &sizeof_rtype); + sdisps_int = ADIOI_Malloc(2 * nranks * sizeof(int)); + rdisps_int = &sdisps_int[nranks]; + + disps_are_small_enough = 1; + for (i = 0; i < nranks && disps_are_small_enough; ++i) { + if (sdisps[i] != (int) sdisps[i]) { + disps_are_small_enough = 0; + } + } + for (i = 0; i < nranks && disps_are_small_enough; ++i) { + if (rdisps[i] != (int) sdisps[i]) { + disps_are_small_enough = 0; + } + } + + if (disps_are_small_enough) { + for (i = 0; i < nranks; ++i) { + sdisps_int[i] = sdisps[i]; + } + for (i = 0; i < nranks; ++i) { + rdisps_int[i] = rdisps[i]; + } + rv = MPI_Alltoallv(sbuf, scounts, sdisps_int, stype, + rbuf, rcounts, rdisps_int, rtype, comm); + ADIOI_Free(sdisps_int); + return rv; + } + + void *sbuf_copy; + void *rbuf_copy; + int scount_total = 0; + int rcount_total = 0; + for (i = 0; i < nranks; i++) { + sdisps_int[i] = scount_total; + scount_total += scounts[i]; + rdisps_int[i] = rcount_total; + rcount_total += rcounts[i]; + } + sbuf_copy = (void *) ADIOI_Malloc(scount_total * sizeof_stype); + rbuf_copy = (void *) ADIOI_Malloc(rcount_total * sizeof_rtype); + for (i = 0; i < nranks; i++) { + memcpy((char *) sbuf_copy + sdisps_int[i] * sizeof_stype, + (char *) sbuf + sdisps[i] * sizeof_stype, scounts[i] * sizeof_stype); + } + rv = MPI_Alltoallv(sbuf_copy, scounts, sdisps_int, stype, + rbuf_copy, rcounts, rdisps_int, rtype, comm); + for (i = 0; i < nranks; i++) { + memcpy((char *) rbuf + rdisps[i] * sizeof_rtype, + (char *) rbuf_copy + rdisps_int[i] * sizeof_rtype, rcounts[i] * sizeof_rtype); + } + + ADIOI_Free(sbuf_copy); + ADIOI_Free(rbuf_copy); + ADIOI_Free(sdisps_int); + return rv; +} From 7bb460c55aadde5b65ed6a06baed1d8b4c7487e9 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 2 Nov 2021 15:40:03 -0500 Subject: [PATCH 125/607] test: add barrier in errors/pt2pt/truncmsg1.c In this test the sender sends a huge message while the receiver posts a tiny buffer. The receiver will quickly complete on receiving the first packet, acknowledge and exit, while the send may still be sending the remaining packets. The sender may fail due to disconnection. The behavior is system dependent. On linux, the send is often able to complete before detecting the disconnect. On FreeBSD, this test nearly always fails with I/O error at the libfabric sockets layer. Because the purpose of test is not about disconnection error, and the disconnection error can be legitimate. Therefore, we are adding a barrier to prevent the disconnect error. The test still tests the implementations handling of truncation error. --- test/mpi/errors/pt2pt/truncmsg1.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/mpi/errors/pt2pt/truncmsg1.c b/test/mpi/errors/pt2pt/truncmsg1.c index 2328a27bb83..98fda9832fb 100644 --- a/test/mpi/errors/pt2pt/truncmsg1.c +++ b/test/mpi/errors/pt2pt/truncmsg1.c @@ -93,6 +93,8 @@ int main(int argc, char *argv[]) } } + MPI_Barrier(MPI_COMM_WORLD); + free(buf); MTest_Finalize(errs); From ad06aa0b2f5e5330e993c98d931fbb224030b8aa Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Wed, 3 Nov 2021 10:57:49 -0500 Subject: [PATCH 126/607] coll: Promote count types for large count support Areas of the collective code (csel, tsp, gentran) were still using int for some count values. Replace all these instances with MPI_Aint. --- src/mpi/coll/src/csel.c | 3 ++- src/mpi/coll/transports/gentran/gentran_types.h | 12 ++++++------ src/mpi/coll/transports/gentran/tsp_gentran.c | 12 ++++++------ src/mpi/coll/transports/tsp_impl.h | 12 ++++++------ 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/mpi/coll/src/csel.c b/src/mpi/coll/src/csel.c index 5c650b6da87..f80f20f96d1 100644 --- a/src/mpi/coll/src/csel.c +++ b/src/mpi/coll/src/csel.c @@ -909,7 +909,8 @@ static inline MPI_Aint get_avg_msgsize(MPIR_Csel_coll_sig_s coll_info) static inline int get_count(MPIR_Csel_coll_sig_s coll_info) { - int count = 0, i = 0; + MPI_Aint count = 0; + int i = 0; int comm_size = coll_info.comm_ptr->local_size; switch (coll_info.coll_type) { diff --git a/src/mpi/coll/transports/gentran/gentran_types.h b/src/mpi/coll/transports/gentran/gentran_types.h index 62231b6c1b9..63cb1770711 100644 --- a/src/mpi/coll/transports/gentran/gentran_types.h +++ b/src/mpi/coll/transports/gentran/gentran_types.h @@ -45,7 +45,7 @@ typedef struct MPII_Genutil_vtx_t { union { struct { const void *buf; - int count; + MPI_Aint count; MPI_Datatype dt; int dest; int tag; @@ -54,7 +54,7 @@ typedef struct MPII_Genutil_vtx_t { } isend; struct { void *buf; - int count; + MPI_Aint count; MPI_Datatype dt; int src; int tag; @@ -63,7 +63,7 @@ typedef struct MPII_Genutil_vtx_t { } irecv; struct { void *buf; - int count; + MPI_Aint count; MPI_Datatype dt; int src; int tag; @@ -73,7 +73,7 @@ typedef struct MPII_Genutil_vtx_t { } irecv_status; struct { const void *buf; - int count; + MPI_Aint count; MPI_Datatype dt; UT_array dests; int num_dests; @@ -84,7 +84,7 @@ typedef struct MPII_Genutil_vtx_t { } imcast; struct { const void *buf; - int count; + MPI_Aint count; MPI_Datatype dt; int dest; int tag; @@ -94,7 +94,7 @@ typedef struct MPII_Genutil_vtx_t { struct { const void *inbuf; void *inoutbuf; - int count; + MPI_Aint count; MPI_Datatype datatype; MPI_Op op; } reduce_local; diff --git a/src/mpi/coll/transports/gentran/tsp_gentran.c b/src/mpi/coll/transports/gentran/tsp_gentran.c index 61158712be4..5d0e6f8faca 100644 --- a/src/mpi/coll/transports/gentran/tsp_gentran.c +++ b/src/mpi/coll/transports/gentran/tsp_gentran.c @@ -187,7 +187,7 @@ int MPIR_TSP_sched_generic(int type_id, void *data, } int MPIR_TSP_sched_isend(const void *buf, - int count, + MPI_Aint count, MPI_Datatype dt, int dest, int tag, @@ -224,7 +224,7 @@ int MPIR_TSP_sched_isend(const void *buf, int MPIR_TSP_sched_irecv(void *buf, - int count, + MPI_Aint count, MPI_Datatype dt, int source, int tag, @@ -258,7 +258,7 @@ int MPIR_TSP_sched_irecv(void *buf, } int MPIR_TSP_sched_irecv_status(void *buf, - int count, + MPI_Aint count, MPI_Datatype dt, int source, int tag, @@ -295,7 +295,7 @@ int MPIR_TSP_sched_irecv_status(void *buf, int MPIR_TSP_sched_imcast(const void *buf, - int count, + MPI_Aint count, MPI_Datatype dt, int *dests, int num_dests, @@ -335,7 +335,7 @@ int MPIR_TSP_sched_imcast(const void *buf, } int MPIR_TSP_sched_issend(const void *buf, - int count, + MPI_Aint count, MPI_Datatype dt, int dest, int tag, @@ -367,7 +367,7 @@ int MPIR_TSP_sched_issend(const void *buf, return mpi_errno; } -int MPIR_TSP_sched_reduce_local(const void *inbuf, void *inoutbuf, int count, +int MPIR_TSP_sched_reduce_local(const void *inbuf, void *inoutbuf, MPI_Aint count, MPI_Datatype datatype, MPI_Op op, MPIR_TSP_sched_t s, int n_in_vtcs, int *in_vtcs, int *vtx_id) { diff --git a/src/mpi/coll/transports/tsp_impl.h b/src/mpi/coll/transports/tsp_impl.h index 4ebd85fd3f6..468b8a38754 100644 --- a/src/mpi/coll/transports/tsp_impl.h +++ b/src/mpi/coll/transports/tsp_impl.h @@ -45,7 +45,7 @@ int MPIR_TSP_sched_generic(int type_id, void *data, /* Transport function to schedule an isend vertex */ int MPIR_TSP_sched_isend(const void *buf, - int count, + MPI_Aint count, MPI_Datatype dt, int dest, int tag, @@ -54,7 +54,7 @@ int MPIR_TSP_sched_isend(const void *buf, /* Transport function to schedule a issend vertex */ int MPIR_TSP_sched_issend(const void *buf, - int count, + MPI_Aint count, MPI_Datatype dt, int dest, int tag, @@ -63,7 +63,7 @@ int MPIR_TSP_sched_issend(const void *buf, /* Transport function to schedule an irecv vertex */ int MPIR_TSP_sched_irecv(void *buf, - int count, + MPI_Aint count, MPI_Datatype dt, int source, int tag, @@ -72,7 +72,7 @@ int MPIR_TSP_sched_irecv(void *buf, /* Transport function to schedule a irecv with status vertex */ int MPIR_TSP_sched_irecv_status(void *buf, - int count, + MPI_Aint count, MPI_Datatype dt, int source, int tag, @@ -81,7 +81,7 @@ int MPIR_TSP_sched_irecv_status(void *buf, /* Transport function to schedule an imcast vertex */ int MPIR_TSP_sched_imcast(const void *buf, - int count, + MPI_Aint count, MPI_Datatype dt, int *dests, int num_dests, @@ -91,7 +91,7 @@ int MPIR_TSP_sched_imcast(const void *buf, /* Transport function to schedule a local reduce vertex */ -int MPIR_TSP_sched_reduce_local(const void *inbuf, void *inoutbuf, int count, +int MPIR_TSP_sched_reduce_local(const void *inbuf, void *inoutbuf, MPI_Aint count, MPI_Datatype datatype, MPI_Op op, MPIR_TSP_sched_t sched, int n_in_vtcs, int *in_vtcs, int *vtx_id); From d22805f0c02d3d0de90e248dbd5d7e54be399a90 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 28 Oct 2021 12:40:26 -0500 Subject: [PATCH 127/607] binding/f77: use C signature for mpi_conversion_fn_null MPI_CONVERSION_FN_NULL is not callable and it is just a symbol for Fortran to use. Use the exact C signature to avoid compiler warning. --- maint/local_python/binding_f77.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/maint/local_python/binding_f77.py b/maint/local_python/binding_f77.py index 39757620350..4cd54bdc953 100644 --- a/maint/local_python/binding_f77.py +++ b/maint/local_python/binding_f77.py @@ -527,6 +527,7 @@ def dump_custom_functions(func): err = func['parameters'][-1]['name'] if re.match(r'MPI_CONVERSION_FN_NULL', func['name'], re.IGNORECASE): G.out.append("/* dummy function, not callable */") + G.out.append("return 0;") elif re.match(r'MPI.*_DUP_FN', func['name'], re.IGNORECASE): G.out.append("* (MPI_Aint *) attribute_val_out = * (MPI_Aint *) attribute_val_in;") G.out.append("*flag = MPII_TO_FLOG(1);") @@ -841,7 +842,10 @@ def process_func_parameters(): c_arg_list_A.insert(0, "0, 0") c_arg_list_B.insert(0, "0, 0") - if 'return' not in func: + if re.match(r'MPI_CONVERSION_FN_NULL', func['name'], re.IGNORECASE): + param_str = "void *userbuf, MPI_Datatype datatype, int count, void *filebuf, MPI_Offset position, void *extra_state" + return_type = "int" + elif 'return' not in func: if not need_skip_ierr: if c_param_list: param_str = ', '.join(c_param_list) + ", MPI_Fint *ierr" From b7b0d6e43069f846a94930160884d820624a6217 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 3 Nov 2021 11:01:22 -0500 Subject: [PATCH 128/607] config: remove the extra AC_CHECK_SIZEOF(_BOOL) This resulted in double definition of SIZEOF__BOOL in config tests. Some tests need use -Werror, but the double definition prevented -Werror to be added, resulting in false positives. In particular, this resulted in NO_TAGS_WITH_MODIFIERS not being defined when it should. --- configure.ac | 2 -- 1 file changed, 2 deletions(-) diff --git a/configure.ac b/configure.ac index f20a445cf76..dd4a2118f5a 100644 --- a/configure.ac +++ b/configure.ac @@ -2735,8 +2735,6 @@ AC_CHECK_SIZEOF(wchar_t, 0, [ #endif ]) -AC_CHECK_SIZEOF(_BOOL, 0) - AC_CHECK_SIZEOF(__float128, 0) if test "$ac_cv_sizeof___float128" = "16" ; then AC_DEFINE(HAVE_FLOAT128, 1, [Define if __float128 is supported]) From a4acb83f8386da68f4cb0153e3960d4ef254bfe6 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 3 Nov 2021 12:25:18 -0500 Subject: [PATCH 129/607] config: fix typo in defining MPIR_INTERGERx_CTYPE It was mistyped to MPIR_REALx_CTYPE, resulting double definitions and missing definitions of MPIR_INTERGERx_CTYPE. --- confdb/aclocal_datatype.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/confdb/aclocal_datatype.m4 b/confdb/aclocal_datatype.m4 index 727e57e0aa1..01ad703f959 100644 --- a/confdb/aclocal_datatype.m4 +++ b/confdb/aclocal_datatype.m4 @@ -177,7 +177,7 @@ AC_DEFUN([PAC_F77_CHECK_FIXED_INTEGER], [ eval pac_cv_f77_sizeof_integer$1=0 else eval pac_cv_f77_sizeof_integer$1=$1 - AC_DEFINE_UNQUOTED(MPIR_REAL$1_CTYPE,$pac_retval,[C type to use for MPI_INTEGER$1]) + AC_DEFINE_UNQUOTED(MPIR_INTEGER$1_CTYPE,$pac_retval,[C type to use for MPI_INTEGER$1]) fi ]) From e9274b0d999c3f5716cc2a64eab24c5abb48dfd2 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 3 Nov 2021 15:58:37 -0500 Subject: [PATCH 130/607] python: fix qmpi prototypes The MPICH_ATTR_POINTER_WITH_TYPE_TAG in QMPI need add 2 to account for the two additional parameters. Rewrite the code to use single regex rather than multiple re.sub. It is more readable. --- maint/local_python/binding_c.py | 44 ++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/maint/local_python/binding_c.py b/maint/local_python/binding_c.py index c9b11333b88..4460f88b89a 100644 --- a/maint/local_python/binding_c.py +++ b/maint/local_python/binding_c.py @@ -160,25 +160,35 @@ def dump_mpix_symbols(): print("#endif /* MPIR_IMPL_H_INCLUDED */", file=Out) def get_qmpi_decl_from_func_decl(func_decl): - func_decl = re.sub('\(void\)', '()', func_decl, 1) - func_decl = re.sub(' MPI', ' QMPI', func_decl, 1) - func_decl = re.sub('\(', '(QMPI_Context context, int tool_id, ', func_decl, 1) - func_decl = re.sub(', \)', ')', func_decl, 1) # Remove the extra comma from the previous - # line (if there is one) - return func_decl + if RE.match(r'(.*) (MPIX?_\w+)\((.*?)\)(.*)', func_decl): + T, name, args, tail = RE.m.group(1,2,3,4) + else: + raise Exception("Bad pattern in declaration %s" % func_decl) + + if args == 'void': + t = "%s Q%s(QMPI_Context context, int tool_id)" % (T, name) + else: + t = "%s Q%s(QMPI_Context context, int tool_id, %s)" % (T, name, args) + + while RE.search(r'MPICH_ATTR_POINTER_WITH_TYPE_TAG\((\d+),(\d+)\)(.*)', tail): + i1, i2, tail = RE.m.group(1, 2, 3) + t += " MPICH_ATTR_POINTER_WITH_TYPE_TAG(%d,%d)" % (int(i1) + 2, int(i2) + 2) + + t += " MPICH_API_PUBLIC" + + return t def get_qmpi_typedef_from_func_decl(func_decl): - func_decl = re.sub('\(void\)', '()', func_decl, 1) - func_decl = re.sub(" MPI", " QMPI", func_decl, 1) - func_decl = re.sub("\(", "_t) (QMPI_Context context, int tool_id, ", func_decl, 1) - func_decl = re.sub(', \)', ')', func_decl, 1) # Remove the extra comma from the previous - # line (if there is one) - func_decl = re.sub("QMPI", "(QMPI", func_decl, 1) - func_decl = re.sub("^", "typedef ", func_decl, 1) - func_decl = re.sub("\s*$", ";", func_decl, 1) - func_decl = re.sub(" MPICH_API_PUBLIC", "", func_decl, 1) - func_decl = re.sub(" MPICH_ATTR_POINTER_WITH_TYPE_TAG\(.*,.*\)", "", func_decl, 1) - return func_decl + if RE.match(r'(.*) (MPIX?_\w+)\((.*?)\)', func_decl): + T, name, args = RE.m.group(1,2,3) + else: + raise Exception("Bad pattern in declaration %s" % func_decl) + + if args == 'void': + t = "typedef %s (Q%s_t) (QMPI_Context context, int tool_id);" % (T, name) + else: + t = "typedef %s (Q%s_t) (QMPI_Context context, int tool_id, %s);" % (T, name, args) + return t def need_skip_qmpi(func_name): # If this is a large count function, it needs to have the suffix removed since we add that From 4c605b13538ef7e81202741c5f86b2d32f38f803 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Thu, 27 May 2021 13:53:52 -0500 Subject: [PATCH 131/607] test/mpi: Add communicator refcount test Add a test that receives a synchronous send *after* the user has freed the comm in the application. MPI is required to keep the communicator active because of pending communication. In this case it is needed for the ACK message to the sender. ch4/am code previously did not pass this test. --- test/mpi/.gitignore | 1 + test/mpi/comm/Makefile.am | 1 + test/mpi/comm/cmfree2.c | 49 +++++++++++++++++++++++++++++++++++++++ test/mpi/comm/testlist.in | 1 + 4 files changed, 52 insertions(+) create mode 100644 test/mpi/comm/cmfree2.c diff --git a/test/mpi/.gitignore b/test/mpi/.gitignore index c31b7a725ae..6d53039c23f 100644 --- a/test/mpi/.gitignore +++ b/test/mpi/.gitignore @@ -183,6 +183,7 @@ /coll/uoplong /coll/uoplong_large /comm/cmfree +/comm/cmfree2 /comm/cmsplit /comm/cmsplit2 /comm/cmsplit_type diff --git a/test/mpi/comm/Makefile.am b/test/mpi/comm/Makefile.am index 98f9c259868..c225ecf587d 100644 --- a/test/mpi/comm/Makefile.am +++ b/test/mpi/comm/Makefile.am @@ -25,6 +25,7 @@ noinst_PROGRAMS = \ icsplit \ iccreate \ cmfree \ + cmfree2 \ icm \ cmsplit \ cmsplit2 \ diff --git a/test/mpi/comm/cmfree2.c b/test/mpi/comm/cmfree2.c new file mode 100644 index 00000000000..fc94efb0bd4 --- /dev/null +++ b/test/mpi/comm/cmfree2.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpi.h" +#include +#include "mpitest.h" + +/* +static char MTEST_Descrip[] = "Test that communicators have reference count semantics"; +*/ + +int main(int argc, char *argv[]) +{ + int errs = 0; + int rank, size; + MPI_Comm comm; + + MTest_Init(&argc, &argv); + + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + if (size < 2) { + fprintf(stderr, "This test requires at least two processes."); + MPI_Abort(MPI_COMM_WORLD, 1); + } + + MPI_Comm_dup(MPI_COMM_WORLD, &comm); + + if (rank == 0) { + MPI_Barrier(MPI_COMM_WORLD); + MPI_Ssend(NULL, 0, MPI_INT, 1, 0, comm); + MPI_Comm_free(&comm); + } else if (rank == 1) { + MPI_Request req; + /* recv an ssend after the user frees the comm */ + MPI_Irecv(NULL, 0, MPI_INT, 0, 0, comm, &req); + MPI_Comm_free(&comm); + MPI_Barrier(MPI_COMM_WORLD); + MPI_Wait(&req, MPI_STATUS_IGNORE); + } else { + MPI_Comm_free(&comm); + MPI_Barrier(MPI_COMM_WORLD); + } + + MTest_Finalize(errs); + return MTestReturnValue(errs); +} diff --git a/test/mpi/comm/testlist.in b/test/mpi/comm/testlist.in index ac94c7c42f4..b92f7dd4b3f 100644 --- a/test/mpi/comm/testlist.in +++ b/test/mpi/comm/testlist.in @@ -12,6 +12,7 @@ iccreate 8 ctxalloc 2 timeLimit=300 ctxsplit 4 timeLimit=300 cmfree 4 +cmfree2 2 cmsplit 4 cmsplit2 12 probe_intercomm 2 From 94248aa239a7f9bc3dc3a6ffb81fd4028dfae08d Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Mon, 25 Oct 2021 15:23:31 -0500 Subject: [PATCH 132/607] ch4/am: Use union to differentiate send/recv request fields It is sometimes hard to tell how fields in generic requests are being used, for example in what type of operation. Use a union to add context about the type of operation. In this case, send and recv requests. RMA requests also use these fields based on the type (or stage) of operation. --- src/mpid/ch4/include/mpidpre.h | 32 +++++++++---- src/mpid/ch4/shm/ipc/src/ipc_p2p.h | 16 +++---- src/mpid/ch4/src/mpidig_part.c | 16 ++++--- src/mpid/ch4/src/mpidig_part_callbacks.c | 6 +-- src/mpid/ch4/src/mpidig_part_utils.h | 10 ++-- src/mpid/ch4/src/mpidig_probe.h | 8 ++-- src/mpid/ch4/src/mpidig_pt2pt_callbacks.c | 20 ++++---- src/mpid/ch4/src/mpidig_recv.h | 20 ++++---- src/mpid/ch4/src/mpidig_recv_utils.h | 12 ++--- src/mpid/ch4/src/mpidig_recvq.h | 25 +++++----- src/mpid/ch4/src/mpidig_rma.h | 10 ++-- src/mpid/ch4/src/mpidig_rma_callbacks.c | 56 ++++++++++++----------- src/mpid/ch4/src/mpidig_send.h | 4 +- 13 files changed, 127 insertions(+), 108 deletions(-) diff --git a/src/mpid/ch4/include/mpidpre.h b/src/mpid/ch4/include/mpidpre.h index a25996e4aba..077b3fffd49 100644 --- a/src/mpid/ch4/include/mpidpre.h +++ b/src/mpid/ch4/include/mpidpre.h @@ -209,13 +209,20 @@ typedef struct MPIDIG_req_t { MPIDI_SHM_REQUEST_AM_DECL} shm_am; #endif MPIDIG_req_ext_t *req; - void *buffer; void *rndv_hdr; + void *buffer; MPI_Aint count; - int rank; - int tag; - MPIR_Context_id_t context_id; MPI_Datatype datatype; + union { + struct { + int dest; + } send; + struct { + int source; + MPIR_Context_id_t context_id; + int tag; + } recv; + } u; } MPIDIG_req_t; /* Structure to capture arguments for pt2pt persistent communications */ @@ -251,13 +258,18 @@ typedef struct MPIDI_part_request { /* partitioned attributes */ void *buffer; - MPI_Aint count; /* count per partition */ - int rank; - int tag; - MPIR_Context_id_t context_id; /* temporarily store send context_id in unexp_rreq. - * Valid also in posted_rreq so that single dequeue - * routine can be used. */ + MPI_Aint count; MPI_Datatype datatype; + union { + struct { + int dest; + } send; + struct { + int source; + MPIR_Context_id_t context_id; + int tag; + } recv; + } u; union { MPIDI_NM_PART_DECL} netmod; } MPIDI_part_request_t; diff --git a/src/mpid/ch4/shm/ipc/src/ipc_p2p.h b/src/mpid/ch4/shm/ipc/src/ipc_p2p.h index b8908c27982..56795ac5fee 100644 --- a/src/mpid/ch4/shm/ipc/src/ipc_p2p.h +++ b/src/mpid/ch4/shm/ipc/src/ipc_p2p.h @@ -56,9 +56,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_IPCI_send_lmt(const void *buf, MPI_Aint count MPIR_Comm_add_ref(comm); MPIDIG_REQUEST(sreq, buffer) = (void *) buf; MPIDIG_REQUEST(sreq, datatype) = datatype; - MPIDIG_REQUEST(sreq, rank) = rank; + MPIDIG_REQUEST(sreq, u.send.dest) = rank; MPIDIG_REQUEST(sreq, count) = count; - MPIDIG_REQUEST(sreq, context_id) = comm->context_id + context_offset; am_hdr.ipc_hdr.ipc_type = ipc_attr.ipc_type; am_hdr.ipc_hdr.ipc_handle = ipc_attr.ipc_handle; @@ -132,7 +131,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_IPCI_copy_data(MPIDI_IPC_hdr * ipc_hdr, MPIR_ if (ipc_hdr->is_contig) { MPI_Aint actual_unpack_bytes; mpi_errno = MPIR_Typerep_unpack(src_buf, src_data_sz, - MPIDIG_REQUEST(rreq, buffer), MPIDIG_REQUEST(rreq, count), + MPIDIG_REQUEST(rreq, buffer), MPIDIG_REQUEST(rreq, + count), MPIDIG_REQUEST(rreq, datatype), 0, &actual_unpack_bytes); MPIR_ERR_CHECK(mpi_errno); MPIR_Assert(actual_unpack_bytes == src_data_sz); @@ -176,8 +176,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_IPCI_handle_lmt_recv(MPIDI_IPC_hdr * ipc_hdr, /* Set receive status */ MPIR_STATUS_SET_COUNT(rreq->status, recv_data_sz); - rreq->status.MPI_SOURCE = MPIDIG_REQUEST(rreq, rank); - rreq->status.MPI_TAG = MPIDIG_REQUEST(rreq, tag); + rreq->status.MPI_SOURCE = MPIDIG_REQUEST(rreq, u.recv.source); + rreq->status.MPI_TAG = MPIDIG_REQUEST(rreq, u.recv.tag); /* attach remote buffer */ if (ipc_hdr->ipc_type == MPIDI_IPCI_TYPE__XPMEM) { @@ -211,8 +211,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_IPCI_handle_lmt_recv(MPIDI_IPC_hdr * ipc_hdr, IPC_TRACE("handle_lmt_recv: handle matched rreq %p [source %d, tag %d, " " context_id 0x%x], copy dst %p, bytes %ld\n", rreq, - MPIDIG_REQUEST(rreq, rank), MPIDIG_REQUEST(rreq, tag), - MPIDIG_REQUEST(rreq, context_id), (char *) MPIDIG_REQUEST(rreq, buffer), + MPIDIG_REQUEST(rreq, u.recv.source), MPIDIG_REQUEST(rreq, u.recv.tag), + MPIDIG_REQUEST(rreq, u.recv.context_id), (char *) MPIDIG_REQUEST(rreq, buffer), recv_data_sz); MPIDI_IPC_ack_t am_hdr; @@ -221,7 +221,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_IPCI_handle_lmt_recv(MPIDI_IPC_hdr * ipc_hdr, int local_vci = MPIDIG_REQUEST(rreq, req->local_vci); int remote_vci = MPIDIG_REQUEST(rreq, req->remote_vci); - CH4_CALL(am_send_hdr(MPIDIG_REQUEST(rreq, rank), rreq->comm, MPIDI_IPC_ACK, + CH4_CALL(am_send_hdr(MPIDIG_REQUEST(rreq, u.recv.source), rreq->comm, MPIDI_IPC_ACK, &am_hdr, sizeof(am_hdr), local_vci, remote_vci), 1, mpi_errno); MPIR_ERR_CHECK(mpi_errno); diff --git a/src/mpid/ch4/src/mpidig_part.c b/src/mpid/ch4/src/mpidig_part.c index 04b38e920c9..540c025332c 100644 --- a/src/mpid/ch4/src/mpidig_part.c +++ b/src/mpid/ch4/src/mpidig_part.c @@ -24,13 +24,17 @@ static int part_req_create(void *buf, int partitions, MPI_Aint count, req->comm = comm; MPIR_Datatype_add_ref_if_not_builtin(datatype); - MPIDI_PART_REQUEST(req, datatype) = datatype; - MPIDI_PART_REQUEST(req, rank) = rank; - MPIDI_PART_REQUEST(req, tag) = tag; MPIDI_PART_REQUEST(req, buffer) = buf; MPIDI_PART_REQUEST(req, count) = count; - MPIDI_PART_REQUEST(req, context_id) = comm->context_id; + MPIDI_PART_REQUEST(req, datatype) = datatype; + if (kind == MPIR_REQUEST_KIND__PART_SEND) { + MPIDI_PART_REQUEST(req, u.send.dest) = rank; + } else { + MPIDI_PART_REQUEST(req, u.recv.source) = rank; + MPIDI_PART_REQUEST(req, u.recv.tag) = tag; + MPIDI_PART_REQUEST(req, u.recv.context_id) = comm->context_id; + } req->u.part.partitions = partitions; MPIR_Part_request_inactivate(req); @@ -69,8 +73,8 @@ void MPIDIG_precv_matched(MPIR_Request * part_req) /* Set status for partitioned req */ MPIR_STATUS_SET_COUNT(part_req->status, sdata_size); - part_req->status.MPI_SOURCE = MPIDI_PART_REQUEST(part_req, rank); - part_req->status.MPI_TAG = MPIDI_PART_REQUEST(part_req, tag); + part_req->status.MPI_SOURCE = MPIDI_PART_REQUEST(part_req, u.recv.source); + part_req->status.MPI_TAG = MPIDI_PART_REQUEST(part_req, u.recv.tag); part_req->status.MPI_ERROR = MPI_SUCCESS; /* Additional check for partitioned pt2pt: require identical buffer size */ diff --git a/src/mpid/ch4/src/mpidig_part_callbacks.c b/src/mpid/ch4/src/mpidig_part_callbacks.c index 4aaedaa1637..3f76ce9d0fb 100644 --- a/src/mpid/ch4/src/mpidig_part_callbacks.c +++ b/src/mpid/ch4/src/mpidig_part_callbacks.c @@ -76,9 +76,9 @@ int MPIDIG_part_send_init_target_msg_cb(void *am_hdr, void *data, MPIR_ERR_CHKANDSTMT(unexp_req == NULL, mpi_errno, MPIX_ERR_NOREQ, goto fn_fail, "**nomemreq"); - MPIDI_PART_REQUEST(unexp_req, rank) = msg_hdr->src_rank; - MPIDI_PART_REQUEST(unexp_req, tag) = msg_hdr->tag; - MPIDI_PART_REQUEST(unexp_req, context_id) = msg_hdr->context_id; + MPIDI_PART_REQUEST(unexp_req, u.recv.source) = msg_hdr->src_rank; + MPIDI_PART_REQUEST(unexp_req, u.recv.tag) = msg_hdr->tag; + MPIDI_PART_REQUEST(unexp_req, u.recv.context_id) = msg_hdr->context_id; part_rreq_update_sinfo(unexp_req, msg_hdr); MPIDIG_enqueue_request(unexp_req, &MPIDI_global.part_unexp_list, MPIDIG_PART); diff --git a/src/mpid/ch4/src/mpidig_part_utils.h b/src/mpid/ch4/src/mpidig_part_utils.h index 1c032c5e977..6ef8585978a 100644 --- a/src/mpid/ch4/src/mpidig_part_utils.h +++ b/src/mpid/ch4/src/mpidig_part_utils.h @@ -18,7 +18,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_part_issue_cts(MPIR_Request * rreq_ptr) am_hdr.sreq_ptr = MPIDIG_PART_REQUEST(rreq_ptr, peer_req_ptr); am_hdr.rreq_ptr = rreq_ptr; - int source = MPIDI_PART_REQUEST(rreq_ptr, rank); + int source = MPIDI_PART_REQUEST(rreq_ptr, u.recv.source); CH4_CALL(am_send_hdr_reply(rreq_ptr->comm, source, MPIDIG_PART_CTS, &am_hdr, sizeof(am_hdr), 0, 0), MPIDI_REQUEST(rreq_ptr, is_local), mpi_errno); @@ -60,13 +60,13 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_part_issue_data(MPIR_Request * part_sreq, MPIR_AINT_MAX); if (mode == MPIDIG_PART_REGULAR) { - CH4_CALL(am_isend(MPIDI_PART_REQUEST(part_sreq, rank), part_sreq->comm, + CH4_CALL(am_isend(MPIDI_PART_REQUEST(part_sreq, u.send.dest), part_sreq->comm, MPIDIG_PART_SEND_DATA, - &am_hdr, sizeof(am_hdr), MPIDI_PART_REQUEST(part_sreq, buffer), count, - MPIDI_PART_REQUEST(part_sreq, datatype), 0, 0, sreq), + &am_hdr, sizeof(am_hdr), MPIDI_PART_REQUEST(part_sreq, buffer), + count, MPIDI_PART_REQUEST(part_sreq, datatype), 0, 0, sreq), MPIDI_REQUEST(part_sreq, is_local), mpi_errno); } else { /* MPIDIG_PART_REPLY */ - CH4_CALL(am_isend_reply(part_sreq->comm, MPIDI_PART_REQUEST(part_sreq, rank), + CH4_CALL(am_isend_reply(part_sreq->comm, MPIDI_PART_REQUEST(part_sreq, u.send.dest), MPIDIG_PART_SEND_DATA, &am_hdr, sizeof(am_hdr), MPIDI_PART_REQUEST(part_sreq, buffer), count, diff --git a/src/mpid/ch4/src/mpidig_probe.h b/src/mpid/ch4/src/mpidig_probe.h index 712a41da0d8..7833e2d23fe 100644 --- a/src/mpid/ch4/src/mpidig_probe.h +++ b/src/mpid/ch4/src/mpidig_probe.h @@ -26,8 +26,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_mpi_iprobe(int source, int tag, MPIR_Comm * if (unexp_req) { *flag = 1; unexp_req->status.MPI_ERROR = MPI_SUCCESS; - unexp_req->status.MPI_SOURCE = MPIDIG_REQUEST(unexp_req, rank); - unexp_req->status.MPI_TAG = MPIDIG_REQUEST(unexp_req, tag); + unexp_req->status.MPI_SOURCE = MPIDIG_REQUEST(unexp_req, u.recv.source); + unexp_req->status.MPI_TAG = MPIDIG_REQUEST(unexp_req, u.recv.tag); MPIR_STATUS_SET_COUNT(unexp_req->status, MPIDIG_REQUEST(unexp_req, count)); MPIR_Request_extract_status(unexp_req, status); @@ -65,8 +65,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_mpi_improbe(int source, int tag, MPIR_Comm * MPIR_Comm_add_ref(comm); unexp_req->status.MPI_ERROR = MPI_SUCCESS; - unexp_req->status.MPI_SOURCE = MPIDIG_REQUEST(unexp_req, rank); - unexp_req->status.MPI_TAG = MPIDIG_REQUEST(unexp_req, tag); + unexp_req->status.MPI_SOURCE = MPIDIG_REQUEST(unexp_req, u.recv.source); + unexp_req->status.MPI_TAG = MPIDIG_REQUEST(unexp_req, u.recv.tag); MPIR_STATUS_SET_COUNT(unexp_req->status, MPIDIG_REQUEST(unexp_req, count)); MPIDIG_REQUEST(unexp_req, req->status) |= MPIDIG_REQ_UNEXP_DQUED; diff --git a/src/mpid/ch4/src/mpidig_pt2pt_callbacks.c b/src/mpid/ch4/src/mpidig_pt2pt_callbacks.c index 9f264f27bfd..f731d189112 100644 --- a/src/mpid/ch4/src/mpidig_pt2pt_callbacks.c +++ b/src/mpid/ch4/src/mpidig_pt2pt_callbacks.c @@ -24,7 +24,7 @@ int MPIDIG_do_cts(MPIR_Request * rreq) int local_vci = MPIDIG_REQUEST(rreq, req->local_vci); int remote_vci = MPIDIG_REQUEST(rreq, req->remote_vci); - CH4_CALL(am_send_hdr_reply(rreq->comm, MPIDIG_REQUEST(rreq, rank), MPIDIG_SEND_CTS, + CH4_CALL(am_send_hdr_reply(rreq->comm, MPIDIG_REQUEST(rreq, u.recv.source), MPIDIG_SEND_CTS, &am_hdr, sizeof(am_hdr), local_vci, remote_vci), MPIDI_REQUEST(rreq, is_local), mpi_errno); MPIR_ERR_CHECK(mpi_errno); @@ -120,8 +120,8 @@ static int recv_target_cmpl_cb(MPIR_Request * rreq) goto fn_exit; } - rreq->status.MPI_SOURCE = MPIDIG_REQUEST(rreq, rank); - rreq->status.MPI_TAG = MPIDIG_REQUEST(rreq, tag); + rreq->status.MPI_SOURCE = MPIDIG_REQUEST(rreq, u.recv.source); + rreq->status.MPI_TAG = MPIDIG_REQUEST(rreq, u.recv.tag); if (MPIDIG_REQUEST(rreq, req->status) & MPIDIG_REQ_PEER_SSEND) { mpi_errno = MPIDIG_reply_ssend(rreq); @@ -235,9 +235,9 @@ static int create_unexp_rreq(int rank, int tag, MPIR_Context_id_t context_id, MPIDIG_REQUEST(rreq, datatype) = MPI_BYTE; MPIDIG_REQUEST(rreq, count) = data_sz; MPIDIG_REQUEST(rreq, buffer) = NULL; /* default */ - MPIDIG_REQUEST(rreq, rank) = rank; - MPIDIG_REQUEST(rreq, tag) = tag; - MPIDIG_REQUEST(rreq, context_id) = context_id; + MPIDIG_REQUEST(rreq, u.recv.source) = rank; + MPIDIG_REQUEST(rreq, u.recv.tag) = tag; + MPIDIG_REQUEST(rreq, u.recv.context_id) = context_id; MPIDIG_REQUEST(rreq, req->status) |= MPIDIG_REQ_UNEXPECTED; MPIDIG_REQUEST(rreq, req->rreq.match_req) = NULL; @@ -304,9 +304,9 @@ static void set_matched_rreq_fields(MPIR_Request * rreq, int rank, int tag, MPIR_Context_id_t context_id, int error_bits, int is_local) { MPIR_FUNC_ENTER; - MPIDIG_REQUEST(rreq, rank) = rank; - MPIDIG_REQUEST(rreq, tag) = tag; - MPIDIG_REQUEST(rreq, context_id) = context_id; + MPIDIG_REQUEST(rreq, u.recv.source) = rank; + MPIDIG_REQUEST(rreq, u.recv.tag) = tag; + MPIDIG_REQUEST(rreq, u.recv.context_id) = context_id; #ifndef MPIDI_CH4_DIRECT_NETMOD MPIDI_REQUEST(rreq, is_local) = is_local; #endif @@ -485,7 +485,7 @@ int MPIDIG_send_cts_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, /* Start the main data transfer */ send_hdr.rreq_ptr = msg_hdr->rreq_ptr; CH4_CALL(am_isend_reply(sreq->comm, - MPIDIG_REQUEST(sreq, rank), MPIDIG_SEND_DATA, + MPIDIG_REQUEST(sreq, u.send.dest), MPIDIG_SEND_DATA, &send_hdr, sizeof(send_hdr), MPIDIG_REQUEST(sreq, req->sreq).src_buf, MPIDIG_REQUEST(sreq, req->sreq).count, diff --git a/src/mpid/ch4/src/mpidig_recv.h b/src/mpid/ch4/src/mpidig_recv.h index 787818b6095..54a6789b151 100644 --- a/src/mpid/ch4/src/mpidig_recv.h +++ b/src/mpid/ch4/src/mpidig_recv.h @@ -16,11 +16,11 @@ MPL_STATIC_INLINE_PREFIX void MPIDIG_prepare_recv_req(int rank, int tag, { MPIR_FUNC_ENTER; - MPIDIG_REQUEST(rreq, rank) = rank; - MPIDIG_REQUEST(rreq, tag) = tag; - MPIDIG_REQUEST(rreq, context_id) = context_id; + MPIDIG_REQUEST(rreq, u.recv.source) = rank; + MPIDIG_REQUEST(rreq, u.recv.tag) = tag; + MPIDIG_REQUEST(rreq, u.recv.context_id) = context_id; MPIDIG_REQUEST(rreq, datatype) = datatype; - MPIDIG_REQUEST(rreq, buffer) = (char *) buf; + MPIDIG_REQUEST(rreq, buffer) = buf; MPIDIG_REQUEST(rreq, count) = count; MPIR_FUNC_EXIT; @@ -105,7 +105,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_reply_ssend(MPIR_Request * rreq) int local_vci = MPIDIG_REQUEST(rreq, req->local_vci); int remote_vci = MPIDIG_REQUEST(rreq, req->remote_vci); - CH4_CALL(am_send_hdr_reply(rreq->comm, MPIDIG_REQUEST(rreq, rank), MPIDIG_SSEND_ACK, + CH4_CALL(am_send_hdr_reply(rreq->comm, MPIDIG_REQUEST(rreq, u.recv.source), MPIDIG_SSEND_ACK, &ack_msg, (MPI_Aint) sizeof(ack_msg), local_vci, remote_vci), MPIDI_REQUEST(rreq, is_local), mpi_errno); MPIR_ERR_CHECK(mpi_errno); @@ -127,8 +127,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_handle_unexpected(void *buf, MPI_Aint count, /* if we have an unexp buffer, we just need to copy the data in it to the user buffer */ /* This is the fast path and we can avoid calling the target_cmpl_cb and complete the * request here */ - rreq->status.MPI_SOURCE = MPIDIG_REQUEST(rreq, rank); - rreq->status.MPI_TAG = MPIDIG_REQUEST(rreq, tag); + rreq->status.MPI_SOURCE = MPIDIG_REQUEST(rreq, u.recv.source); + rreq->status.MPI_TAG = MPIDIG_REQUEST(rreq, u.recv.tag); mpi_errno = MPIDIG_copy_from_unexp_req(rreq, buf, datatype, count); MPIR_ERR_CHECK(mpi_errno); @@ -156,7 +156,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_handle_unexpected(void *buf, MPI_Aint count, MPIDIG_REQUEST(rreq, req->status) &= ~MPIDIG_REQ_UNEXPECTED; MPIR_Datatype_add_ref_if_not_builtin(datatype); MPIDIG_REQUEST(rreq, datatype) = datatype; - MPIDIG_REQUEST(rreq, buffer) = (char *) buf; + MPIDIG_REQUEST(rreq, buffer) = buf; MPIDIG_REQUEST(rreq, count) = count; MPIDIG_recv_type_init(unexp_data_sz, rreq); } @@ -214,7 +214,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_irecv(void *buf, MPI_Aint count, MPI_Data /* Matching receive is now posted, tell the netmod/shmmod */ MPIR_Datatype_add_ref_if_not_builtin(datatype); MPIDIG_REQUEST(unexp_req, datatype) = datatype; - MPIDIG_REQUEST(unexp_req, buffer) = (char *) buf; + MPIDIG_REQUEST(unexp_req, buffer) = buf; MPIDIG_REQUEST(unexp_req, count) = count; if (*request == NULL) { /* Regular (non-enqueuing) path: MPIDIG is responsbile for allocating @@ -310,7 +310,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_mpi_imrecv(void *buf, MPI_Aint data_sz = MPIDIG_REQUEST(message, count); /* Matching receive is now posted, tell the netmod */ MPIDIG_REQUEST(message, datatype) = datatype; - MPIDIG_REQUEST(message, buffer) = (char *) buf; + MPIDIG_REQUEST(message, buffer) = buf; MPIDIG_REQUEST(message, count) = count; MPIDIG_REQUEST(message, req->status) &= ~MPIDIG_REQ_UNEXPECTED; MPIDIG_recv_type_init(data_sz, message); diff --git a/src/mpid/ch4/src/mpidig_recv_utils.h b/src/mpid/ch4/src/mpidig_recv_utils.h index 239ec0b525d..52683273758 100644 --- a/src/mpid/ch4/src/mpidig_recv_utils.h +++ b/src/mpid/ch4/src/mpidig_recv_utils.h @@ -148,8 +148,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_get_recv_iov_count(MPIR_Request * rreq) MPIDIG_rreq_async_t *p = &(MPIDIG_REQUEST(rreq, req->recv_async)); if (p->recv_type == MPIDIG_RECV_DATATYPE) { MPI_Aint num_iov; - MPIR_Typerep_iov_len(MPIDIG_REQUEST(rreq, count), MPIDIG_REQUEST(rreq, datatype), - p->in_data_sz, &num_iov); + MPIR_Typerep_iov_len(MPIDIG_REQUEST(rreq, count), + MPIDIG_REQUEST(rreq, datatype), p->in_data_sz, &num_iov); return num_iov; } else if (p->recv_type == MPIDIG_RECV_CONTIG) { return 1; @@ -343,8 +343,8 @@ MPL_STATIC_INLINE_PREFIX void MPIDIG_convert_datatype(MPIR_Request * rreq) MPI_Aint data_sz; MPIR_Datatype *dt_ptr; MPI_Aint dt_true_lb; - MPIDI_Datatype_get_info(MPIDIG_REQUEST(rreq, count), MPIDIG_REQUEST(rreq, datatype), - dt_contig, data_sz, dt_ptr, dt_true_lb); + MPIDI_Datatype_get_info(MPIDIG_REQUEST(rreq, count), + MPIDIG_REQUEST(rreq, datatype), dt_contig, data_sz, dt_ptr, dt_true_lb); MPIDIG_rreq_async_t *p = &(MPIDIG_REQUEST(rreq, req->recv_async)); if (dt_contig) { @@ -354,8 +354,8 @@ MPL_STATIC_INLINE_PREFIX void MPIDIG_convert_datatype(MPIR_Request * rreq) } else { struct iovec *iov; MPI_Aint num_iov; - MPIR_Typerep_iov_len(MPIDIG_REQUEST(rreq, count), MPIDIG_REQUEST(rreq, datatype), - data_sz, &num_iov); + MPIR_Typerep_iov_len(MPIDIG_REQUEST(rreq, count), + MPIDIG_REQUEST(rreq, datatype), data_sz, &num_iov); MPIR_Assert(num_iov > 0); iov = MPL_malloc(num_iov * sizeof(struct iovec), MPL_MEM_OTHER); diff --git a/src/mpid/ch4/src/mpidig_recvq.h b/src/mpid/ch4/src/mpidig_recvq.h index 401e6daabdc..ea0e1cfc302 100644 --- a/src/mpid/ch4/src/mpidig_recvq.h +++ b/src/mpid/ch4/src/mpidig_recvq.h @@ -79,7 +79,7 @@ enum MPIDIG_queue_type { if (qtype_ == MPIDIG_PT2PT_UNEXP) { \ MPIR_T_DO_EVENT(unexp_message_indices[0], \ MPI_T_CB_REQUIRE_MPI_RESTRICTED, \ - &MPIDIG_REQUEST(req, rank)); \ + &MPIDIG_REQUEST(req, u.recv.source)); \ } \ } while (0) @@ -88,7 +88,7 @@ enum MPIDIG_queue_type { if (qtype_ == MPIDIG_PT2PT_UNEXP) { \ MPIR_T_DO_EVENT(unexp_message_indices[1], \ MPI_T_CB_REQUIRE_MPI_RESTRICTED, \ - &MPIDIG_REQUEST(req, rank)); \ + &MPIDIG_REQUEST(req, u.recv.source)); \ } \ } while (0) @@ -98,18 +98,19 @@ MPL_STATIC_INLINE_PREFIX bool MPIDIG_match_request(int rank, int tag, enum MPIDIG_queue_type qtype) { if (qtype == MPIDIG_PT2PT_POSTED) { - return (rank == MPIDIG_REQUEST(req, rank) || MPIDIG_REQUEST(req, rank) == MPI_ANY_SOURCE) && - (tag == MPIR_TAG_MASK_ERROR_BITS(MPIDIG_REQUEST(req, tag)) || - MPIDIG_REQUEST(req, tag) == MPI_ANY_TAG) && - context_id == MPIDIG_REQUEST(req, context_id); + return (rank == MPIDIG_REQUEST(req, u.recv.source) || + MPIDIG_REQUEST(req, u.recv.source) == MPI_ANY_SOURCE) && + (tag == MPIR_TAG_MASK_ERROR_BITS(MPIDIG_REQUEST(req, u.recv.tag)) || + MPIDIG_REQUEST(req, u.recv.tag) == MPI_ANY_TAG) && + context_id == MPIDIG_REQUEST(req, u.recv.context_id); } else if (qtype == MPIDIG_PT2PT_UNEXP) { - return (rank == MPIDIG_REQUEST(req, rank) || rank == MPI_ANY_SOURCE) && - (tag == MPIR_TAG_MASK_ERROR_BITS(MPIDIG_REQUEST(req, tag)) || - tag == MPI_ANY_TAG) && context_id == MPIDIG_REQUEST(req, context_id); + return (rank == MPIDIG_REQUEST(req, u.recv.source) || rank == MPI_ANY_SOURCE) && + (tag == MPIR_TAG_MASK_ERROR_BITS(MPIDIG_REQUEST(req, u.recv.tag)) || + tag == MPI_ANY_TAG) && context_id == MPIDIG_REQUEST(req, u.recv.context_id); } else if (qtype == MPIDIG_PART) { - return rank == MPIDI_PART_REQUEST(req, rank) && - tag == MPIR_TAG_MASK_ERROR_BITS(MPIDI_PART_REQUEST(req, tag)) && - context_id == MPIDI_PART_REQUEST(req, context_id); + return rank == MPIDI_PART_REQUEST(req, u.recv.source) && + tag == MPIR_TAG_MASK_ERROR_BITS(MPIDI_PART_REQUEST(req, u.recv.tag)) && + context_id == MPIDI_PART_REQUEST(req, u.recv.context_id); } else { /* unknown queue type */ MPIR_Assert(0); diff --git a/src/mpid/ch4/src/mpidig_rma.h b/src/mpid/ch4/src/mpidig_rma.h index 4b385e58643..958a977c2de 100644 --- a/src/mpid/ch4/src/mpidig_rma.h +++ b/src/mpid/ch4/src/mpidig_rma.h @@ -71,7 +71,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_put(const void *origin_addr, int origin_c /* Increase local and remote completion counters and set the local completion * counter in request, thus it can be decreased at request completion. */ MPIDIG_win_cmpl_cnts_incr(win, target_rank, &sreq->completion_notification); - MPIDIG_REQUEST(sreq, rank) = target_rank; + MPIDIG_REQUEST(sreq, u.send.dest) = target_rank; int is_contig; MPIR_Datatype_is_contig(target_datatype, &is_contig); @@ -195,7 +195,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_get(void *origin_addr, int origin_count, MPIDIG_REQUEST(sreq, req->greq.count) = origin_count; MPIDIG_REQUEST(sreq, req->greq.datatype) = origin_datatype; MPIDIG_REQUEST(sreq, req->greq.target_datatype) = target_datatype; - MPIDIG_REQUEST(sreq, rank) = target_rank; + MPIDIG_REQUEST(sreq, u.send.dest) = target_rank; MPIR_Datatype_add_ref_if_not_builtin(origin_datatype); MPIR_Datatype_add_ref_if_not_builtin(target_datatype); @@ -321,7 +321,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_accumulate(const void *origin_addr, int o /* Increase remote completion counter for acc. */ MPIDIG_win_remote_acc_cmpl_cnt_incr(win, target_rank); - MPIDIG_REQUEST(sreq, rank) = target_rank; + MPIDIG_REQUEST(sreq, u.send.dest) = target_rank; if (MPIR_DATATYPE_IS_PREDEFINED(target_datatype)) { am_hdr.flattened_sz = 0; MPIR_T_PVAR_TIMER_END(RMA, rma_amhdr_set); @@ -473,7 +473,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_get_accumulate(const void *origin_addr, /* Increase remote completion counter for acc. */ MPIDIG_win_remote_acc_cmpl_cnt_incr(win, target_rank); - MPIDIG_REQUEST(sreq, rank) = target_rank; + MPIDIG_REQUEST(sreq, u.send.dest) = target_rank; if (MPIR_DATATYPE_IS_PREDEFINED(target_datatype)) { am_hdr.flattened_sz = 0; MPIR_T_PVAR_TIMER_END(RMA, rma_amhdr_set); @@ -783,7 +783,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_mpi_compare_and_swap(const void *origin_addr MPIDIG_REQUEST(sreq, req->creq.datatype) = datatype; MPIDIG_REQUEST(sreq, req->creq.result_addr) = result_addr; MPIDIG_REQUEST(sreq, req->creq.data) = p_data; - MPIDIG_REQUEST(sreq, rank) = target_rank; + MPIDIG_REQUEST(sreq, u.send.dest) = target_rank; MPIR_cc_inc(sreq->cc_ptr); MPIR_T_PVAR_TIMER_START(RMA, rma_amhdr_set); diff --git a/src/mpid/ch4/src/mpidig_rma_callbacks.c b/src/mpid/ch4/src/mpidig_rma_callbacks.c index 19a0496af17..f0da5528f70 100644 --- a/src/mpid/ch4/src/mpidig_rma_callbacks.c +++ b/src/mpid/ch4/src/mpidig_rma_callbacks.c @@ -464,7 +464,7 @@ static int ack_put(MPIR_Request * rreq) int local_vci = MPIDIG_REQUEST(rreq, req->local_vci); int remote_vci = MPIDIG_REQUEST(rreq, req->remote_vci); ack_msg.preq_ptr = MPIDIG_REQUEST(rreq, req->preq.preq_ptr); - CH4_CALL(am_send_hdr_reply(rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, rank), + CH4_CALL(am_send_hdr_reply(rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, u.recv.source), MPIDIG_PUT_ACK, &ack_msg, sizeof(ack_msg), local_vci, remote_vci), MPIDI_REQUEST(rreq, is_local), mpi_errno); MPIR_ERR_CHECK(mpi_errno); @@ -492,7 +492,7 @@ static int ack_cswap(MPIR_Request * rreq) int local_vci = MPIDIG_REQUEST(rreq, req->local_vci); int remote_vci = MPIDIG_REQUEST(rreq, req->remote_vci); - CH4_CALL(am_isend_reply(rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, rank), + CH4_CALL(am_isend_reply(rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, u.recv.source), MPIDIG_CSWAP_ACK, &ack_msg, sizeof(ack_msg), result_addr, 1, MPIDIG_REQUEST(rreq, req->creq.datatype), local_vci, remote_vci, rreq), MPIDI_REQUEST(rreq, is_local), mpi_errno); @@ -514,7 +514,7 @@ static int ack_acc(MPIR_Request * rreq) int local_vci = MPIDIG_REQUEST(rreq, req->local_vci); int remote_vci = MPIDIG_REQUEST(rreq, req->remote_vci); ack_msg.req_ptr = MPIDIG_REQUEST(rreq, req->areq.req_ptr); - CH4_CALL(am_send_hdr_reply(rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, rank), + CH4_CALL(am_send_hdr_reply(rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, u.recv.source), MPIDIG_ACC_ACK, &ack_msg, sizeof(ack_msg), local_vci, remote_vci), MPIDI_REQUEST(rreq, is_local), mpi_errno); MPIR_ERR_CHECK(mpi_errno); @@ -537,7 +537,7 @@ static int ack_get_acc(MPIR_Request * rreq) int local_vci = MPIDIG_REQUEST(rreq, req->local_vci); int remote_vci = MPIDIG_REQUEST(rreq, req->remote_vci); - CH4_CALL(am_isend_reply(rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, rank), + CH4_CALL(am_isend_reply(rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, u.recv.source), MPIDIG_GET_ACC_ACK, &ack_msg, sizeof(ack_msg), MPIDIG_REQUEST(rreq, req->areq.data), MPIDIG_REQUEST(rreq, req->areq.result_data_sz), MPI_BYTE, local_vci, @@ -890,7 +890,7 @@ static int get_target_cmpl_cb(MPIR_Request * rreq) if (MPIDIG_REQUEST(rreq, req->greq.flattened_dt) == NULL) { MPIDI_Datatype_check_size(MPIDIG_REQUEST(rreq, req->greq.datatype), MPIDIG_REQUEST(rreq, req->greq.count), get_ack.target_data_sz); - CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(rreq, rank), + CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(rreq, u.recv.source), MPIDIG_GET_ACK, &get_ack, sizeof(get_ack), (void *) MPIDIG_REQUEST(rreq, req->greq.addr), MPIDIG_REQUEST(rreq, req->greq.count), @@ -914,7 +914,7 @@ static int get_target_cmpl_cb(MPIR_Request * rreq) get_ack.target_data_sz = MPIDIG_REQUEST(rreq, req->greq.count); MPIDIG_REQUEST(rreq, req->greq.count) /= dt->size; - CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(rreq, rank), + CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(rreq, u.recv.source), MPIDIG_GET_ACK, &get_ack, sizeof(get_ack), MPIDIG_REQUEST(rreq, req->greq.addr), MPIDIG_REQUEST(rreq, req->greq.count), dt->handle, local_vci, @@ -958,13 +958,13 @@ static int put_dt_target_cmpl_cb(MPIR_Request * rreq) MPIR_FUNC_ENTER; - ack_msg.src_rank = MPIDIG_REQUEST(rreq, rank); + ack_msg.src_rank = MPIDIG_REQUEST(rreq, u.recv.source); ack_msg.origin_preq_ptr = MPIDIG_REQUEST(rreq, req->preq.preq_ptr); ack_msg.target_preq_ptr = rreq; int local_vci = MPIDIG_REQUEST(rreq, req->local_vci); int remote_vci = MPIDIG_REQUEST(rreq, req->remote_vci); - CH4_CALL(am_send_hdr_reply(rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, rank), + CH4_CALL(am_send_hdr_reply(rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, u.recv.source), MPIDIG_PUT_DT_ACK, &ack_msg, sizeof(ack_msg), local_vci, remote_vci), MPIDI_REQUEST(rreq, is_local), mpi_errno); MPIR_ERR_CHECK(mpi_errno); @@ -988,7 +988,7 @@ static int acc_dt_target_cmpl_cb(MPIR_Request * rreq) int local_vci = MPIDIG_REQUEST(rreq, req->local_vci); int remote_vci = MPIDIG_REQUEST(rreq, req->remote_vci); - CH4_CALL(am_send_hdr_reply(rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, rank), + CH4_CALL(am_send_hdr_reply(rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, u.recv.source), MPIDIG_ACC_DT_ACK, &ack_msg, sizeof(ack_msg), local_vci, remote_vci), MPIDI_REQUEST(rreq, is_local), mpi_errno); MPIR_ERR_CHECK(mpi_errno); @@ -1012,7 +1012,7 @@ static int get_acc_dt_target_cmpl_cb(MPIR_Request * rreq) int local_vci = MPIDIG_REQUEST(rreq, req->local_vci); int remote_vci = MPIDIG_REQUEST(rreq, req->remote_vci); - CH4_CALL(am_send_hdr_reply(rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, rank), + CH4_CALL(am_send_hdr_reply(rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, u.recv.source), MPIDIG_GET_ACC_DT_ACK, &ack_msg, sizeof(ack_msg), local_vci, remote_vci), MPIDI_REQUEST(rreq, is_local), mpi_errno); MPIR_ERR_CHECK(mpi_errno); @@ -1128,7 +1128,7 @@ static int get_ack_target_cmpl_cb(MPIR_Request * rreq) MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(rreq, req->greq.target_datatype)); win = rreq->u.rma.win; - MPIDIG_win_remote_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, rank)); + MPIDIG_win_remote_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, u.send.dest)); MPIDIG_recv_finish(rreq); @@ -1149,8 +1149,8 @@ static int get_acc_ack_target_cmpl_cb(MPIR_Request * rreq) MPIDIG_recv_finish(rreq); win = rreq->u.rma.win; - MPIDIG_win_remote_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, rank)); - MPIDIG_win_remote_acc_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, rank)); + MPIDIG_win_remote_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, u.send.dest)); + MPIDIG_win_remote_acc_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, u.send.dest)); MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(rreq, req->areq.result_datatype)); MPID_Request_complete(rreq); @@ -1167,8 +1167,8 @@ static int cswap_ack_target_cmpl_cb(MPIR_Request * rreq) MPIR_FUNC_ENTER; win = rreq->u.rma.win; - MPIDIG_win_remote_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, rank)); - MPIDIG_win_remote_acc_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, rank)); + MPIDIG_win_remote_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, u.send.dest)); + MPIDIG_win_remote_acc_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, u.send.dest)); MPL_free(MPIDIG_REQUEST(rreq, req->creq.data)); MPID_Request_complete(rreq); @@ -1193,7 +1193,7 @@ int MPIDIG_put_ack_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(preq, req->preq.target_datatype)); - MPIDIG_win_remote_cmpl_cnt_decr(win, MPIDIG_REQUEST(preq, rank)); + MPIDIG_win_remote_cmpl_cnt_decr(win, MPIDIG_REQUEST(preq, u.send.dest)); MPID_Request_complete(preq); @@ -1223,8 +1223,8 @@ int MPIDIG_acc_ack_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(rreq, req->areq.target_datatype)); - MPIDIG_win_remote_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, rank)); - MPIDIG_win_remote_acc_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, rank)); + MPIDIG_win_remote_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, u.send.dest)); + MPIDIG_win_remote_acc_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, u.send.dest)); MPID_Request_complete(rreq); @@ -1254,6 +1254,7 @@ int MPIDIG_get_acc_ack_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_ MPIDIG_REQUEST(rreq, req->target_cmpl_cb) = get_acc_ack_target_cmpl_cb; + /* setup recv fields for result data */ MPIDIG_REQUEST(rreq, buffer) = MPIDIG_REQUEST(rreq, req->areq.result_addr); MPIDIG_REQUEST(rreq, count) = MPIDIG_REQUEST(rreq, req->areq.result_count); MPIDIG_REQUEST(rreq, datatype) = MPIDIG_REQUEST(rreq, req->areq.result_datatype); @@ -1445,7 +1446,7 @@ int MPIDIG_put_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, MPIR_ERR_CHKANDSTMT(rreq == NULL, mpi_errno, MPIX_ERR_NOREQ, goto fn_fail, "**nomemreq"); MPIDIG_REQUEST(rreq, req->preq.preq_ptr) = msg_hdr->preq_ptr; - MPIDIG_REQUEST(rreq, rank) = msg_hdr->src_rank; + MPIDIG_REQUEST(rreq, u.recv.source) = msg_hdr->src_rank; win = (MPIR_Win *) MPIDIU_map_lookup(MPIDI_global.win_map, msg_hdr->win_id); MPIR_Assert(win); @@ -1521,7 +1522,7 @@ int MPIDIG_put_dt_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, MPIR_ERR_CHKANDSTMT(rreq == NULL, mpi_errno, MPIX_ERR_NOREQ, goto fn_fail, "**nomemreq"); MPIDIG_REQUEST(rreq, req->preq.preq_ptr) = msg_hdr->preq_ptr; - MPIDIG_REQUEST(rreq, rank) = msg_hdr->src_rank; + MPIDIG_REQUEST(rreq, u.recv.source) = msg_hdr->src_rank; win = (MPIR_Win *) MPIDIU_map_lookup(MPIDI_global.win_map, msg_hdr->win_id); MPIR_Assert(win); @@ -1580,7 +1581,7 @@ int MPIDIG_put_dt_ack_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_s dat_msg.preq_ptr = msg_hdr->target_preq_ptr; win = origin_req->u.rma.win; - CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(origin_req, rank), + CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(origin_req, u.send.dest), MPIDIG_PUT_DAT_REQ, &dat_msg, sizeof(dat_msg), MPIDIG_REQUEST(origin_req, req->preq.origin_addr), MPIDIG_REQUEST(origin_req, req->preq.origin_count), @@ -1624,7 +1625,7 @@ int MPIDIG_acc_dt_ack_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_s dat_msg.preq_ptr = msg_hdr->target_preq_ptr; win = origin_req->u.rma.win; - CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(origin_req, rank), + CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(origin_req, u.send.dest), MPIDIG_ACC_DAT_REQ, &dat_msg, sizeof(dat_msg), MPIDIG_REQUEST(origin_req, req->areq.origin_addr), MPIDIG_REQUEST(origin_req, req->areq.origin_count), @@ -1668,7 +1669,7 @@ int MPIDIG_get_acc_dt_ack_target_msg_cb(void *am_hdr, void *data, dat_msg.preq_ptr = msg_hdr->target_preq_ptr; win = origin_req->u.rma.win; - CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(origin_req, rank), + CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(origin_req, u.send.dest), MPIDIG_GET_ACC_DAT_REQ, &dat_msg, sizeof(dat_msg), MPIDIG_REQUEST(origin_req, req->areq.origin_addr), MPIDIG_REQUEST(origin_req, req->areq.origin_count), @@ -1830,7 +1831,7 @@ int MPIDIG_cswap_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, MPIDIG_REQUEST(rreq, req->creq.creq_ptr) = msg_hdr->req_ptr; MPIDIG_REQUEST(rreq, req->creq.datatype) = msg_hdr->datatype; MPIDIG_REQUEST(rreq, req->creq.addr) = (char *) base + offset; - MPIDIG_REQUEST(rreq, rank) = msg_hdr->src_rank; + MPIDIG_REQUEST(rreq, u.recv.source) = msg_hdr->src_rank; MPIR_Assert(dt_contig == 1); p_data = MPL_malloc(data_sz * 2, MPL_MEM_RMA); @@ -1908,7 +1909,7 @@ int MPIDIG_acc_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, MPIDIG_REQUEST(rreq, req->areq.data) = p_data; MPIDIG_REQUEST(rreq, req->areq.flattened_dt) = NULL; MPIDIG_REQUEST(rreq, req->areq.result_data_sz) = msg_hdr->result_data_sz; - MPIDIG_REQUEST(rreq, rank) = msg_hdr->src_rank; + MPIDIG_REQUEST(rreq, u.recv.source) = msg_hdr->src_rank; if (msg_hdr->flattened_sz) { /* FIXME: MPIR_Typerep_unflatten should allocate the new object */ @@ -2001,7 +2002,7 @@ int MPIDIG_acc_dt_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, MPIDIG_REQUEST(rreq, req->areq.target_addr) = (void *) (offset + base); MPIDIG_REQUEST(rreq, req->areq.op) = msg_hdr->op; MPIDIG_REQUEST(rreq, req->areq.result_data_sz) = msg_hdr->result_data_sz; - MPIDIG_REQUEST(rreq, rank) = msg_hdr->src_rank; + MPIDIG_REQUEST(rreq, u.recv.source) = msg_hdr->src_rank; void *flattened_dt = MPL_malloc(msg_hdr->flattened_sz, MPL_MEM_RMA); MPIR_Assert(flattened_dt); @@ -2093,7 +2094,7 @@ int MPIDIG_get_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, MPIDIG_REQUEST(rreq, req->greq.flattened_dt) = NULL; MPIDIG_REQUEST(rreq, req->greq.dt) = NULL; MPIDIG_REQUEST(rreq, req->greq.greq_ptr) = msg_hdr->greq_ptr; - MPIDIG_REQUEST(rreq, rank) = msg_hdr->src_rank; + MPIDIG_REQUEST(rreq, u.recv.source) = msg_hdr->src_rank; if (msg_hdr->flattened_sz) { void *flattened_dt = MPL_malloc(msg_hdr->flattened_sz, MPL_MEM_BUFFER); @@ -2141,6 +2142,7 @@ int MPIDIG_get_ack_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, MPIDI_REQUEST(rreq, is_local) = (attr & MPIDIG_AM_ATTR__IS_LOCAL) ? 1 : 0; #endif + /* setup recv fields for get data */ MPIDIG_REQUEST(rreq, buffer) = MPIDIG_REQUEST(rreq, req->greq.addr); MPIDIG_REQUEST(rreq, count) = MPIDIG_REQUEST(rreq, req->greq.count); MPIDIG_REQUEST(rreq, datatype) = MPIDIG_REQUEST(rreq, req->greq.datatype); diff --git a/src/mpid/ch4/src/mpidig_send.h b/src/mpid/ch4/src/mpidig_send.h index aad31e5ca12..1bce46b21a3 100644 --- a/src/mpid/ch4/src/mpidig_send.h +++ b/src/mpid/ch4/src/mpidig_send.h @@ -81,7 +81,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_isend_impl(const void *buf, MPI_Aint count, #ifdef HAVE_DEBUGGER_SUPPORT MPIDIG_REQUEST(sreq, datatype) = datatype; - MPIDIG_REQUEST(sreq, buffer) = (char *) buf; + MPIDIG_REQUEST(sreq, buffer) = (void *) buf; MPIDIG_REQUEST(sreq, count) = count; #endif @@ -98,7 +98,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_isend_impl(const void *buf, MPI_Aint count, MPIDIG_REQUEST(sreq, req->sreq).datatype = datatype; MPIDIG_REQUEST(sreq, req->sreq).rank = am_hdr.src_rank; MPIDIG_REQUEST(sreq, req->sreq).context_id = am_hdr.context_id; - MPIDIG_REQUEST(sreq, rank) = rank; + MPIDIG_REQUEST(sreq, u.send.dest) = rank; MPIR_Datatype_add_ref_if_not_builtin(datatype); MPIDIG_AM_SEND_SET_RNDV(am_hdr.flags, MPIDIG_RNDV_GENERIC); From 69644a50a3fe7aaaee4805ebb3a6ec05bbbbcb03 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 2 Nov 2021 11:35:15 -0500 Subject: [PATCH 133/607] ch4/am: Avoid using extended request for send operations The fields in the extended send request are redundant. Use the regular generic request instead. --- src/mpid/ch4/include/mpidpre.h | 10 ---------- src/mpid/ch4/src/mpidig_pt2pt_callbacks.c | 8 ++++---- src/mpid/ch4/src/mpidig_send.h | 8 +++----- 3 files changed, 7 insertions(+), 19 deletions(-) diff --git a/src/mpid/ch4/include/mpidpre.h b/src/mpid/ch4/include/mpidpre.h index 077b3fffd49..2ffea6ecdf8 100644 --- a/src/mpid/ch4/include/mpidpre.h +++ b/src/mpid/ch4/include/mpidpre.h @@ -73,15 +73,6 @@ typedef enum { #define MPIDI_PARENT_PORT_KVSKEY "PARENT_ROOT_PORT_NAME" #define MPIDI_MAX_KVS_VALUE_LEN 4096 -typedef struct MPIDIG_sreq_t { - /* persistent send fields */ - const void *src_buf; - MPI_Aint count; - MPI_Datatype datatype; - int rank; - MPIR_Context_id_t context_id; -} MPIDIG_sreq_t; - typedef struct MPIDIG_rreq_t { /* mrecv fields */ void *mrcv_buffer; @@ -179,7 +170,6 @@ typedef struct MPIDIG_sreq_async { typedef struct MPIDIG_req_ext_t { union { - MPIDIG_sreq_t sreq; MPIDIG_rreq_t rreq; MPIDIG_put_req_t preq; MPIDIG_get_req_t greq; diff --git a/src/mpid/ch4/src/mpidig_pt2pt_callbacks.c b/src/mpid/ch4/src/mpidig_pt2pt_callbacks.c index f731d189112..52a1329a4ad 100644 --- a/src/mpid/ch4/src/mpidig_pt2pt_callbacks.c +++ b/src/mpid/ch4/src/mpidig_pt2pt_callbacks.c @@ -166,7 +166,7 @@ int MPIDIG_send_data_origin_cb(MPIR_Request * sreq) { int mpi_errno = MPI_SUCCESS; MPIR_FUNC_ENTER; - MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(sreq, req->sreq).datatype); + MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(sreq, datatype)); MPID_Request_complete(sreq); MPIR_FUNC_EXIT; return mpi_errno; @@ -487,9 +487,9 @@ int MPIDIG_send_cts_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, CH4_CALL(am_isend_reply(sreq->comm, MPIDIG_REQUEST(sreq, u.send.dest), MPIDIG_SEND_DATA, &send_hdr, sizeof(send_hdr), - MPIDIG_REQUEST(sreq, req->sreq).src_buf, - MPIDIG_REQUEST(sreq, req->sreq).count, - MPIDIG_REQUEST(sreq, req->sreq).datatype, local_vci, remote_vci, sreq), + MPIDIG_REQUEST(sreq, buffer), + MPIDIG_REQUEST(sreq, count), + MPIDIG_REQUEST(sreq, datatype), local_vci, remote_vci, sreq), MPIDI_REQUEST(sreq, is_local), mpi_errno); MPIR_ERR_CHECK(mpi_errno); diff --git a/src/mpid/ch4/src/mpidig_send.h b/src/mpid/ch4/src/mpidig_send.h index 1bce46b21a3..812c455401c 100644 --- a/src/mpid/ch4/src/mpidig_send.h +++ b/src/mpid/ch4/src/mpidig_send.h @@ -93,11 +93,9 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_isend_impl(const void *buf, MPI_Aint count, src_vci, dst_vci, sreq), is_local, mpi_errno); } else { /* RNDV send */ - MPIDIG_REQUEST(sreq, req->sreq).src_buf = buf; - MPIDIG_REQUEST(sreq, req->sreq).count = count; - MPIDIG_REQUEST(sreq, req->sreq).datatype = datatype; - MPIDIG_REQUEST(sreq, req->sreq).rank = am_hdr.src_rank; - MPIDIG_REQUEST(sreq, req->sreq).context_id = am_hdr.context_id; + MPIDIG_REQUEST(sreq, buffer) = (void *) buf; + MPIDIG_REQUEST(sreq, count) = count; + MPIDIG_REQUEST(sreq, datatype) = datatype; MPIDIG_REQUEST(sreq, u.send.dest) = rank; MPIR_Datatype_add_ref_if_not_builtin(datatype); MPIDIG_AM_SEND_SET_RNDV(am_hdr.flags, MPIDIG_RNDV_GENERIC); From 3e715a5a4d5e47da7b4ea458be4b5dac1105777c Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Thu, 28 Oct 2021 16:15:51 -0500 Subject: [PATCH 134/607] ch4/am: Only reference RMA target datatypes when necessary In generic RMA, origin processes were adding/releasing references to target datatypes unconditionally. Since the target datatype is immediately flattened and sent to the target, the only instance where a reference is needed is when the flattened type is large enough that we do not copy it into the message header. In that case, the flattened buffer lives in the MPIR_Datatype struct, so a reference must be added to keep it from being freed if the user frees the datatype. The reference can then be released when the flattened send is locally complete. --- src/mpid/ch4/src/mpidig_rma.h | 16 ++++++++++------ src/mpid/ch4/src/mpidig_rma_callbacks.c | 9 +++------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/mpid/ch4/src/mpidig_rma.h b/src/mpid/ch4/src/mpidig_rma.h index 958a977c2de..e975c291fbe 100644 --- a/src/mpid/ch4/src/mpidig_rma.h +++ b/src/mpid/ch4/src/mpidig_rma.h @@ -57,8 +57,6 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_put(const void *origin_addr, int origin_c sreq = MPIDIG_request_create(MPIR_REQUEST_KIND__RMA, 2, vci, vci); MPIR_ERR_CHKANDSTMT(sreq == NULL, mpi_errno, MPIX_ERR_NOREQ, goto fn_fail, "**nomemreq"); sreq->u.rma.win = win; - MPIDIG_REQUEST(sreq, req->preq.target_datatype) = target_datatype; - MPIR_Datatype_add_ref_if_not_builtin(target_datatype); MPIR_cc_inc(sreq->cc_ptr); MPIR_T_PVAR_TIMER_START(RMA, rma_amhdr_set); @@ -130,6 +128,9 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_put(const void *origin_addr, int origin_c MPIDIG_REQUEST(sreq, req->preq.origin_count) = origin_count; MPIDIG_REQUEST(sreq, req->preq.origin_datatype) = origin_datatype; MPIR_Datatype_add_ref_if_not_builtin(origin_datatype); + /* add reference to ensure the flattened_dt buffer does not get freed */ + MPIDIG_REQUEST(sreq, req->preq.target_datatype) = target_datatype; + MPIR_Datatype_add_ref_if_not_builtin(target_datatype); CH4_CALL(am_isend(target_rank, win->comm_ptr, MPIDIG_PUT_DT_REQ, &am_hdr, sizeof(am_hdr), flattened_dt, flattened_sz, MPI_BYTE, vci, vci, sreq), is_local, @@ -291,8 +292,6 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_accumulate(const void *origin_addr, int o sreq = MPIDIG_request_create(MPIR_REQUEST_KIND__RMA, 2, vci, vci); MPIR_ERR_CHKANDSTMT(sreq == NULL, mpi_errno, MPIX_ERR_NOREQ, goto fn_fail, "**nomemreq"); sreq->u.rma.win = win; - MPIDIG_REQUEST(sreq, req->areq.target_datatype) = target_datatype; - MPIR_Datatype_add_ref_if_not_builtin(target_datatype); MPIR_cc_inc(sreq->cc_ptr); @@ -364,6 +363,9 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_accumulate(const void *origin_addr, int o MPIDIG_REQUEST(sreq, req->areq.origin_count) = origin_count; MPIDIG_REQUEST(sreq, req->areq.origin_datatype) = origin_datatype; MPIR_Datatype_add_ref_if_not_builtin(origin_datatype); + /* add reference to ensure the flattened_dt buffer does not get freed */ + MPIDIG_REQUEST(sreq, req->areq.target_datatype) = target_datatype; + MPIR_Datatype_add_ref_if_not_builtin(target_datatype); CH4_CALL(am_isend(target_rank, win->comm_ptr, MPIDIG_ACC_DT_REQ, &am_hdr, sizeof(am_hdr), flattened_dt, flattened_sz, MPI_BYTE, vci, vci, sreq), is_local, @@ -441,8 +443,6 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_get_accumulate(const void *origin_addr, MPIDIG_REQUEST(sreq, req->areq.result_count) = result_count; MPIDIG_REQUEST(sreq, req->areq.result_datatype) = result_datatype; MPIR_Datatype_add_ref_if_not_builtin(result_datatype); - MPIDIG_REQUEST(sreq, req->areq.target_datatype) = target_datatype; - MPIR_Datatype_add_ref_if_not_builtin(target_datatype); MPIR_cc_inc(sreq->cc_ptr); /* TODO: have common routine for accumulate/get_accumulate */ @@ -516,6 +516,10 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_get_accumulate(const void *origin_addr, MPIDIG_REQUEST(sreq, req->areq.origin_count) = origin_count; MPIDIG_REQUEST(sreq, req->areq.origin_datatype) = origin_datatype; MPIR_Datatype_add_ref_if_not_builtin(origin_datatype); + /* add reference to ensure the flattened_dt buffer does not get freed */ + MPIDIG_REQUEST(sreq, req->areq.target_datatype) = target_datatype; + MPIR_Datatype_add_ref_if_not_builtin(target_datatype); + CH4_CALL(am_isend(target_rank, win->comm_ptr, MPIDIG_GET_ACC_DT_REQ, &am_hdr, sizeof(am_hdr), flattened_dt, flattened_sz, MPI_BYTE, vci, vci, sreq), is_local, mpi_errno); diff --git a/src/mpid/ch4/src/mpidig_rma_callbacks.c b/src/mpid/ch4/src/mpidig_rma_callbacks.c index f0da5528f70..aaf7eaa8a53 100644 --- a/src/mpid/ch4/src/mpidig_rma_callbacks.c +++ b/src/mpid/ch4/src/mpidig_rma_callbacks.c @@ -208,6 +208,7 @@ int MPIDIG_put_dt_origin_cb(MPIR_Request * sreq) { int mpi_errno = MPI_SUCCESS; MPIR_FUNC_ENTER; + MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(sreq, req->preq.target_datatype)); MPID_Request_complete(sreq); MPIR_FUNC_EXIT; return mpi_errno; @@ -217,6 +218,7 @@ int MPIDIG_acc_dt_origin_cb(MPIR_Request * sreq) { int mpi_errno = MPI_SUCCESS; MPIR_FUNC_ENTER; + MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(sreq, req->areq.target_datatype)); MPID_Request_complete(sreq); MPIR_FUNC_EXIT; return mpi_errno; @@ -226,6 +228,7 @@ int MPIDIG_get_acc_dt_origin_cb(MPIR_Request * sreq) { int mpi_errno = MPI_SUCCESS; MPIR_FUNC_ENTER; + MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(sreq, req->areq.target_datatype)); MPID_Request_complete(sreq); MPIR_FUNC_EXIT; return mpi_errno; @@ -1191,8 +1194,6 @@ int MPIDIG_put_ack_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, preq = (MPIR_Request *) msg_hdr->preq_ptr; win = preq->u.rma.win; - MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(preq, req->preq.target_datatype)); - MPIDIG_win_remote_cmpl_cnt_decr(win, MPIDIG_REQUEST(preq, u.send.dest)); MPID_Request_complete(preq); @@ -1221,8 +1222,6 @@ int MPIDIG_acc_ack_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, rreq = (MPIR_Request *) msg_hdr->req_ptr; win = rreq->u.rma.win; - MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(rreq, req->areq.target_datatype)); - MPIDIG_win_remote_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, u.send.dest)); MPIDIG_win_remote_acc_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, u.send.dest)); @@ -1250,8 +1249,6 @@ int MPIDIG_get_acc_ack_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_ rreq = (MPIR_Request *) msg_hdr->req_ptr; - MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(rreq, req->areq.target_datatype)); - MPIDIG_REQUEST(rreq, req->target_cmpl_cb) = get_acc_ack_target_cmpl_cb; /* setup recv fields for result data */ From 883e0ea7b4c32798f2242163e9f95094919b8d2c Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 2 Nov 2021 12:15:57 -0500 Subject: [PATCH 135/607] ch4/am: Avoid using extended request for PUT|ACC origin Origin-side put and accumulate requests can use the generic request fields for buffer, datatype, and count. --- src/mpid/ch4/include/mpidpre.h | 4 ---- src/mpid/ch4/src/mpidig_rma.h | 12 ++++++------ src/mpid/ch4/src/mpidig_rma_callbacks.c | 16 ++++++++-------- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/mpid/ch4/include/mpidpre.h b/src/mpid/ch4/include/mpidpre.h index 2ffea6ecdf8..b007802e851 100644 --- a/src/mpid/ch4/include/mpidpre.h +++ b/src/mpid/ch4/include/mpidpre.h @@ -91,10 +91,6 @@ typedef struct MPIDIG_put_req_t { MPIR_Request *preq_ptr; void *flattened_dt; MPIR_Datatype *dt; - void *origin_addr; - int origin_count; - MPI_Datatype origin_datatype; - void *target_addr; MPI_Datatype target_datatype; MPI_Aint origin_data_sz; } MPIDIG_put_req_t; diff --git a/src/mpid/ch4/src/mpidig_rma.h b/src/mpid/ch4/src/mpidig_rma.h index e975c291fbe..5a0b037e6cb 100644 --- a/src/mpid/ch4/src/mpidig_rma.h +++ b/src/mpid/ch4/src/mpidig_rma.h @@ -124,9 +124,9 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_put(const void *origin_addr, int origin_c is_local, mpi_errno); MPL_free(header); } else { - MPIDIG_REQUEST(sreq, req->preq.origin_addr) = (void *) origin_addr; - MPIDIG_REQUEST(sreq, req->preq.origin_count) = origin_count; - MPIDIG_REQUEST(sreq, req->preq.origin_datatype) = origin_datatype; + MPIDIG_REQUEST(sreq, buffer) = (void *) origin_addr; + MPIDIG_REQUEST(sreq, count) = origin_count; + MPIDIG_REQUEST(sreq, datatype) = origin_datatype; MPIR_Datatype_add_ref_if_not_builtin(origin_datatype); /* add reference to ensure the flattened_dt buffer does not get freed */ MPIDIG_REQUEST(sreq, req->preq.target_datatype) = target_datatype; @@ -359,9 +359,9 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_accumulate(const void *origin_addr, int o vci, vci, sreq), is_local, mpi_errno); MPL_free(header); } else { - MPIDIG_REQUEST(sreq, req->areq.origin_addr) = (void *) origin_addr; - MPIDIG_REQUEST(sreq, req->areq.origin_count) = origin_count; - MPIDIG_REQUEST(sreq, req->areq.origin_datatype) = origin_datatype; + MPIDIG_REQUEST(sreq, buffer) = (void *) origin_addr; + MPIDIG_REQUEST(sreq, count) = origin_count; + MPIDIG_REQUEST(sreq, datatype) = origin_datatype; MPIR_Datatype_add_ref_if_not_builtin(origin_datatype); /* add reference to ensure the flattened_dt buffer does not get freed */ MPIDIG_REQUEST(sreq, req->areq.target_datatype) = target_datatype; diff --git a/src/mpid/ch4/src/mpidig_rma_callbacks.c b/src/mpid/ch4/src/mpidig_rma_callbacks.c index aaf7eaa8a53..5361f1fcc9a 100644 --- a/src/mpid/ch4/src/mpidig_rma_callbacks.c +++ b/src/mpid/ch4/src/mpidig_rma_callbacks.c @@ -1580,13 +1580,13 @@ int MPIDIG_put_dt_ack_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_s CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(origin_req, u.send.dest), MPIDIG_PUT_DAT_REQ, &dat_msg, sizeof(dat_msg), - MPIDIG_REQUEST(origin_req, req->preq.origin_addr), - MPIDIG_REQUEST(origin_req, req->preq.origin_count), - MPIDIG_REQUEST(origin_req, req->preq.origin_datatype), + MPIDIG_REQUEST(origin_req, buffer), + MPIDIG_REQUEST(origin_req, count), + MPIDIG_REQUEST(origin_req, datatype), local_vci, remote_vci, rreq), (attr & MPIDIG_AM_ATTR__IS_LOCAL), mpi_errno); MPIR_ERR_CHECK(mpi_errno); - MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(origin_req, req->preq.origin_datatype)); + MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(origin_req, datatype)); if (attr & MPIDIG_AM_ATTR__IS_ASYNC) { *req = NULL; @@ -1624,13 +1624,13 @@ int MPIDIG_acc_dt_ack_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_s CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(origin_req, u.send.dest), MPIDIG_ACC_DAT_REQ, &dat_msg, sizeof(dat_msg), - MPIDIG_REQUEST(origin_req, req->areq.origin_addr), - MPIDIG_REQUEST(origin_req, req->areq.origin_count), - MPIDIG_REQUEST(origin_req, req->areq.origin_datatype), + MPIDIG_REQUEST(origin_req, buffer), + MPIDIG_REQUEST(origin_req, count), + MPIDIG_REQUEST(origin_req, datatype), local_vci, remote_vci, rreq), (attr & MPIDIG_AM_ATTR__IS_LOCAL), mpi_errno); MPIR_ERR_CHECK(mpi_errno); - MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(origin_req, req->areq.origin_datatype)); + MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(origin_req, datatype)); if (attr & MPIDIG_AM_ATTR__IS_ASYNC) { *req = NULL; From 409114083b33047b5e75dc2d3aae59020ebf0a6f Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 2 Nov 2021 14:47:58 -0500 Subject: [PATCH 136/607] ch4/am: Release origin datatype after am_isend completion The datatype might still be in use before the origin callback has executed. --- src/mpid/ch4/src/mpidig_rma_callbacks.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/mpid/ch4/src/mpidig_rma_callbacks.c b/src/mpid/ch4/src/mpidig_rma_callbacks.c index 5361f1fcc9a..c47dc9cebc3 100644 --- a/src/mpid/ch4/src/mpidig_rma_callbacks.c +++ b/src/mpid/ch4/src/mpidig_rma_callbacks.c @@ -181,6 +181,7 @@ int MPIDIG_put_data_origin_cb(MPIR_Request * sreq) { int mpi_errno = MPI_SUCCESS; MPIR_FUNC_ENTER; + MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(sreq, datatype)); MPID_Request_complete(sreq); MPIR_FUNC_EXIT; return mpi_errno; @@ -190,6 +191,7 @@ int MPIDIG_acc_data_origin_cb(MPIR_Request * sreq) { int mpi_errno = MPI_SUCCESS; MPIR_FUNC_ENTER; + MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(sreq, datatype)); MPID_Request_complete(sreq); MPIR_FUNC_EXIT; return mpi_errno; @@ -199,6 +201,7 @@ int MPIDIG_get_acc_data_origin_cb(MPIR_Request * sreq) { int mpi_errno = MPI_SUCCESS; MPIR_FUNC_ENTER; + MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(sreq, datatype)); MPID_Request_complete(sreq); MPIR_FUNC_EXIT; return mpi_errno; @@ -1577,6 +1580,8 @@ int MPIDIG_put_dt_ack_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_s origin_req = (MPIR_Request *) msg_hdr->origin_preq_ptr; dat_msg.preq_ptr = msg_hdr->target_preq_ptr; win = origin_req->u.rma.win; + /* origin datatype to be released in MPIDIG_put_data_origin_cb */ + MPIDIG_REQUEST(rreq, datatype) = MPIDIG_REQUEST(origin_req, datatype); CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(origin_req, u.send.dest), MPIDIG_PUT_DAT_REQ, &dat_msg, sizeof(dat_msg), @@ -1586,7 +1591,6 @@ int MPIDIG_put_dt_ack_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_s local_vci, remote_vci, rreq), (attr & MPIDIG_AM_ATTR__IS_LOCAL), mpi_errno); MPIR_ERR_CHECK(mpi_errno); - MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(origin_req, datatype)); if (attr & MPIDIG_AM_ATTR__IS_ASYNC) { *req = NULL; @@ -1621,6 +1625,8 @@ int MPIDIG_acc_dt_ack_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_s origin_req = (MPIR_Request *) msg_hdr->origin_preq_ptr; dat_msg.preq_ptr = msg_hdr->target_preq_ptr; win = origin_req->u.rma.win; + /* origin datatype to be released in MPIDIG_acc_data_origin_cb */ + MPIDIG_REQUEST(rreq, datatype) = MPIDIG_REQUEST(origin_req, datatype); CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(origin_req, u.send.dest), MPIDIG_ACC_DAT_REQ, &dat_msg, sizeof(dat_msg), @@ -1630,7 +1636,6 @@ int MPIDIG_acc_dt_ack_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_s local_vci, remote_vci, rreq), (attr & MPIDIG_AM_ATTR__IS_LOCAL), mpi_errno); MPIR_ERR_CHECK(mpi_errno); - MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(origin_req, datatype)); if (attr & MPIDIG_AM_ATTR__IS_ASYNC) { *req = NULL; @@ -1665,6 +1670,8 @@ int MPIDIG_get_acc_dt_ack_target_msg_cb(void *am_hdr, void *data, origin_req = (MPIR_Request *) msg_hdr->origin_preq_ptr; dat_msg.preq_ptr = msg_hdr->target_preq_ptr; win = origin_req->u.rma.win; + /* origin datatype to be released in MPIDIG_get_acc_data_origin_cb */ + MPIDIG_REQUEST(rreq, datatype) = MPIDIG_REQUEST(origin_req, req->areq.origin_datatype); CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(origin_req, u.send.dest), MPIDIG_GET_ACC_DAT_REQ, &dat_msg, sizeof(dat_msg), @@ -1673,7 +1680,6 @@ int MPIDIG_get_acc_dt_ack_target_msg_cb(void *am_hdr, void *data, MPIDIG_REQUEST(origin_req, req->areq.origin_datatype), local_vci, remote_vci, rreq), (attr & MPIDIG_AM_ATTR__IS_LOCAL), mpi_errno); MPIR_ERR_CHECK(mpi_errno); - MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(origin_req, req->areq.origin_datatype)); if (attr & MPIDIG_AM_ATTR__IS_ASYNC) { *req = NULL; From dd476695d7cbaaf781bfeef4338573f1688ec944 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 2 Nov 2021 13:04:29 -0500 Subject: [PATCH 137/607] ch4/am: Avoid using extended request for GET When dealing with buffers for GET operations, we can use the generic request fields for buffer, datatype, and count. --- src/mpid/ch4/include/mpidpre.h | 3 --- src/mpid/ch4/src/mpidig_rma.h | 6 ++--- src/mpid/ch4/src/mpidig_rma_callbacks.c | 33 +++++++++++-------------- 3 files changed, 17 insertions(+), 25 deletions(-) diff --git a/src/mpid/ch4/include/mpidpre.h b/src/mpid/ch4/include/mpidpre.h index b007802e851..f81898335d5 100644 --- a/src/mpid/ch4/include/mpidpre.h +++ b/src/mpid/ch4/include/mpidpre.h @@ -97,9 +97,6 @@ typedef struct MPIDIG_put_req_t { typedef struct MPIDIG_get_req_t { MPIR_Request *greq_ptr; - void *addr; - MPI_Datatype datatype; - int count; void *flattened_dt; MPIR_Datatype *dt; MPI_Datatype target_datatype; diff --git a/src/mpid/ch4/src/mpidig_rma.h b/src/mpid/ch4/src/mpidig_rma.h index 5a0b037e6cb..8b110f60b93 100644 --- a/src/mpid/ch4/src/mpidig_rma.h +++ b/src/mpid/ch4/src/mpidig_rma.h @@ -192,9 +192,9 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_get(void *origin_addr, int origin_count, MPIR_ERR_CHKANDSTMT(sreq == NULL, mpi_errno, MPIX_ERR_NOREQ, goto fn_fail, "**nomemreq"); sreq->u.rma.win = win; - MPIDIG_REQUEST(sreq, req->greq.addr) = origin_addr; - MPIDIG_REQUEST(sreq, req->greq.count) = origin_count; - MPIDIG_REQUEST(sreq, req->greq.datatype) = origin_datatype; + MPIDIG_REQUEST(sreq, buffer) = origin_addr; + MPIDIG_REQUEST(sreq, count) = origin_count; + MPIDIG_REQUEST(sreq, datatype) = origin_datatype; MPIDIG_REQUEST(sreq, req->greq.target_datatype) = target_datatype; MPIDIG_REQUEST(sreq, u.send.dest) = target_rank; MPIR_Datatype_add_ref_if_not_builtin(origin_datatype); diff --git a/src/mpid/ch4/src/mpidig_rma_callbacks.c b/src/mpid/ch4/src/mpidig_rma_callbacks.c index c47dc9cebc3..7e517e06eab 100644 --- a/src/mpid/ch4/src/mpidig_rma_callbacks.c +++ b/src/mpid/ch4/src/mpidig_rma_callbacks.c @@ -894,13 +894,13 @@ static int get_target_cmpl_cb(MPIR_Request * rreq) int local_vci = MPIDIG_REQUEST(rreq, req->local_vci); int remote_vci = MPIDIG_REQUEST(rreq, req->remote_vci); if (MPIDIG_REQUEST(rreq, req->greq.flattened_dt) == NULL) { - MPIDI_Datatype_check_size(MPIDIG_REQUEST(rreq, req->greq.datatype), - MPIDIG_REQUEST(rreq, req->greq.count), get_ack.target_data_sz); + MPIDI_Datatype_check_size(MPIDIG_REQUEST(rreq, datatype), + MPIDIG_REQUEST(rreq, count), get_ack.target_data_sz); CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(rreq, u.recv.source), MPIDIG_GET_ACK, &get_ack, sizeof(get_ack), - (void *) MPIDIG_REQUEST(rreq, req->greq.addr), - MPIDIG_REQUEST(rreq, req->greq.count), - MPIDIG_REQUEST(rreq, req->greq.datatype), local_vci, remote_vci, + MPIDIG_REQUEST(rreq, buffer), + MPIDIG_REQUEST(rreq, count), + MPIDIG_REQUEST(rreq, datatype), local_vci, remote_vci, rreq), MPIDI_REQUEST(rreq, is_local), mpi_errno); MPID_Request_complete(rreq); MPIR_ERR_CHECK(mpi_errno); @@ -917,13 +917,13 @@ static int get_target_cmpl_cb(MPIR_Request * rreq) MPIR_Typerep_unflatten(dt, MPIDIG_REQUEST(rreq, req->greq.flattened_dt)); MPIDIG_REQUEST(rreq, req->greq.dt) = dt; /* count is still target_data_sz now, use it for reply */ - get_ack.target_data_sz = MPIDIG_REQUEST(rreq, req->greq.count); - MPIDIG_REQUEST(rreq, req->greq.count) /= dt->size; + get_ack.target_data_sz = MPIDIG_REQUEST(rreq, count); + MPIDIG_REQUEST(rreq, count) /= dt->size; CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(rreq, u.recv.source), MPIDIG_GET_ACK, &get_ack, sizeof(get_ack), - MPIDIG_REQUEST(rreq, req->greq.addr), - MPIDIG_REQUEST(rreq, req->greq.count), dt->handle, local_vci, + MPIDIG_REQUEST(rreq, buffer), + MPIDIG_REQUEST(rreq, count), dt->handle, local_vci, remote_vci, rreq), MPIDI_REQUEST(rreq, is_local), mpi_errno); MPID_Request_complete(rreq); MPIR_ERR_CHECK(mpi_errno); @@ -1138,7 +1138,7 @@ static int get_ack_target_cmpl_cb(MPIR_Request * rreq) MPIDIG_recv_finish(rreq); - MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(rreq, req->greq.datatype)); + MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(rreq, datatype)); MPID_Request_complete(rreq); MPIR_FUNC_EXIT; return mpi_errno; @@ -2092,8 +2092,8 @@ int MPIDIG_get_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, size_t offset = win->disp_unit * msg_hdr->target_disp; rreq->u.rma.win = win; - MPIDIG_REQUEST(rreq, req->greq.count) = msg_hdr->target_count; - MPIDIG_REQUEST(rreq, req->greq.datatype) = msg_hdr->target_datatype; + MPIDIG_REQUEST(rreq, count) = msg_hdr->target_count; + MPIDIG_REQUEST(rreq, datatype) = msg_hdr->target_datatype; MPIDIG_REQUEST(rreq, req->greq.flattened_dt) = NULL; MPIDIG_REQUEST(rreq, req->greq.dt) = NULL; MPIDIG_REQUEST(rreq, req->greq.greq_ptr) = msg_hdr->greq_ptr; @@ -2103,12 +2103,11 @@ int MPIDIG_get_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, void *flattened_dt = MPL_malloc(msg_hdr->flattened_sz, MPL_MEM_BUFFER); MPIDIG_recv_init(1, msg_hdr->flattened_sz, flattened_dt, msg_hdr->flattened_sz, rreq); MPIDIG_REQUEST(rreq, req->greq.flattened_dt) = flattened_dt; - MPIDIG_REQUEST(rreq, req->greq.addr) = (char *) base + offset; + MPIDIG_REQUEST(rreq, buffer) = (char *) base + offset; } else { MPIR_Assert(!in_data_sz || in_data_sz == 0); MPIDIG_recv_init(1, 0, NULL, 0, rreq); - MPIDIG_REQUEST(rreq, req->greq.addr) = - MPIR_get_contig_ptr(base, offset + msg_hdr->target_true_lb); + MPIDIG_REQUEST(rreq, buffer) = MPIR_get_contig_ptr(base, offset + msg_hdr->target_true_lb); } if (attr & MPIDIG_AM_ATTR__IS_ASYNC) { @@ -2145,10 +2144,6 @@ int MPIDIG_get_ack_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, MPIDI_REQUEST(rreq, is_local) = (attr & MPIDIG_AM_ATTR__IS_LOCAL) ? 1 : 0; #endif - /* setup recv fields for get data */ - MPIDIG_REQUEST(rreq, buffer) = MPIDIG_REQUEST(rreq, req->greq.addr); - MPIDIG_REQUEST(rreq, count) = MPIDIG_REQUEST(rreq, req->greq.count); - MPIDIG_REQUEST(rreq, datatype) = MPIDIG_REQUEST(rreq, req->greq.datatype); MPIDIG_recv_type_init(msg_hdr->target_data_sz, rreq); if (attr & MPIDIG_AM_ATTR__IS_ASYNC) { From d61afa3004504f4433ac2aac401fe1d00322d80b Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 2 Nov 2021 13:13:32 -0500 Subject: [PATCH 138/607] ch4/am: Remove datatype pointer from extended PUT|GET request It is sufficient to use the handle from the unflattened datatype for all future use. --- src/mpid/ch4/include/mpidpre.h | 2 -- src/mpid/ch4/src/mpidig_rma_callbacks.c | 12 +++--------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/mpid/ch4/include/mpidpre.h b/src/mpid/ch4/include/mpidpre.h index f81898335d5..4befac7815f 100644 --- a/src/mpid/ch4/include/mpidpre.h +++ b/src/mpid/ch4/include/mpidpre.h @@ -90,7 +90,6 @@ typedef struct MPIDIG_part_am_req_t { typedef struct MPIDIG_put_req_t { MPIR_Request *preq_ptr; void *flattened_dt; - MPIR_Datatype *dt; MPI_Datatype target_datatype; MPI_Aint origin_data_sz; } MPIDIG_put_req_t; @@ -98,7 +97,6 @@ typedef struct MPIDIG_put_req_t { typedef struct MPIDIG_get_req_t { MPIR_Request *greq_ptr; void *flattened_dt; - MPIR_Datatype *dt; MPI_Datatype target_datatype; } MPIDIG_get_req_t; diff --git a/src/mpid/ch4/src/mpidig_rma_callbacks.c b/src/mpid/ch4/src/mpidig_rma_callbacks.c index 7e517e06eab..a0c093f10f8 100644 --- a/src/mpid/ch4/src/mpidig_rma_callbacks.c +++ b/src/mpid/ch4/src/mpidig_rma_callbacks.c @@ -133,8 +133,7 @@ int MPIDIG_get_ack_origin_cb(MPIR_Request * req) MPIR_FUNC_ENTER; MPL_free(MPIDIG_REQUEST(req, req->greq.flattened_dt)); - if (MPIDIG_REQUEST(req, req->greq.dt)) - MPIR_Datatype_ptr_release(MPIDIG_REQUEST(req, req->greq.dt)); + MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(req, datatype)); MPID_Request_complete(req); MPIR_FUNC_EXIT; @@ -915,7 +914,7 @@ static int get_target_cmpl_cb(MPIR_Request * rreq) } MPIR_Object_set_ref(dt, 1); MPIR_Typerep_unflatten(dt, MPIDIG_REQUEST(rreq, req->greq.flattened_dt)); - MPIDIG_REQUEST(rreq, req->greq.dt) = dt; + MPIDIG_REQUEST(rreq, datatype) = dt->handle; /* count is still target_data_sz now, use it for reply */ get_ack.target_data_sz = MPIDIG_REQUEST(rreq, count); MPIDIG_REQUEST(rreq, count) /= dt->size; @@ -943,8 +942,7 @@ static int put_target_cmpl_cb(MPIR_Request * rreq) MPIDIG_recv_finish(rreq); MPL_free(MPIDIG_REQUEST(rreq, req->preq.flattened_dt)); - if (MPIDIG_REQUEST(rreq, req->preq.dt)) - MPIR_Datatype_ptr_release(MPIDIG_REQUEST(rreq, req->preq.dt)); + MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(rreq, datatype)); mpi_errno = ack_put(rreq); MPIR_ERR_CHECK(mpi_errno); @@ -1471,7 +1469,6 @@ int MPIDIG_put_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, MPIR_Object_set_ref(dt, 1); MPIR_Typerep_unflatten(dt, (char *) am_hdr + sizeof(*msg_hdr)); MPIDIG_REQUEST(rreq, req->preq.flattened_dt) = NULL; - MPIDIG_REQUEST(rreq, req->preq.dt) = dt; MPIDIG_REQUEST(rreq, buffer) = (void *) (base + offset); MPIDIG_REQUEST(rreq, datatype) = dt->handle; @@ -1479,7 +1476,6 @@ int MPIDIG_put_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, MPIDIG_recv_type_init(msg_hdr->origin_data_sz, rreq); } else { MPIDIG_REQUEST(rreq, req->preq.flattened_dt) = NULL; - MPIDIG_REQUEST(rreq, req->preq.dt) = NULL; MPIDIG_REQUEST(rreq, buffer) = MPIR_get_contig_ptr(base, offset + msg_hdr->target_true_lb); MPIDIG_REQUEST(rreq, count) = msg_hdr->target_count; @@ -1716,7 +1712,6 @@ int MPIDIG_put_data_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, /* Note: handle is filled in by MPIR_Handle_obj_alloc() */ MPIR_Object_set_ref(dt, 1); MPIR_Typerep_unflatten(dt, MPIDIG_REQUEST(rreq, req->preq.flattened_dt)); - MPIDIG_REQUEST(rreq, req->preq.dt) = dt; MPIDIG_REQUEST(rreq, datatype) = dt->handle; MPIDIG_REQUEST(rreq, req->target_cmpl_cb) = put_target_cmpl_cb; @@ -2095,7 +2090,6 @@ int MPIDIG_get_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, MPIDIG_REQUEST(rreq, count) = msg_hdr->target_count; MPIDIG_REQUEST(rreq, datatype) = msg_hdr->target_datatype; MPIDIG_REQUEST(rreq, req->greq.flattened_dt) = NULL; - MPIDIG_REQUEST(rreq, req->greq.dt) = NULL; MPIDIG_REQUEST(rreq, req->greq.greq_ptr) = msg_hdr->greq_ptr; MPIDIG_REQUEST(rreq, u.recv.source) = msg_hdr->src_rank; From a4813378d8fdf85292bfdbb82ae2a81da004a8c5 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 2 Nov 2021 13:39:00 -0500 Subject: [PATCH 139/607] ch4/am: Avoid using extended request for CSWAP When dealing with buffers for compare and swap operations, we can use the generic request fields for buffer, datatype, and count. --- src/mpid/ch4/include/mpidpre.h | 3 --- src/mpid/ch4/src/mpidig_rma.h | 5 ++--- src/mpid/ch4/src/mpidig_rma_callbacks.c | 24 ++++++++++++------------ 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/mpid/ch4/include/mpidpre.h b/src/mpid/ch4/include/mpidpre.h index 4befac7815f..5cc4dc3f081 100644 --- a/src/mpid/ch4/include/mpidpre.h +++ b/src/mpid/ch4/include/mpidpre.h @@ -102,10 +102,7 @@ typedef struct MPIDIG_get_req_t { typedef struct MPIDIG_cswap_req_t { MPIR_Request *creq_ptr; - void *addr; - MPI_Datatype datatype; void *data; - void *result_addr; } MPIDIG_cswap_req_t; typedef struct MPIDIG_acc_req_t { diff --git a/src/mpid/ch4/src/mpidig_rma.h b/src/mpid/ch4/src/mpidig_rma.h index 8b110f60b93..c7fcb3fe3e4 100644 --- a/src/mpid/ch4/src/mpidig_rma.h +++ b/src/mpid/ch4/src/mpidig_rma.h @@ -783,9 +783,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_mpi_compare_and_swap(const void *origin_addr MPIR_ERR_CHKANDSTMT(sreq == NULL, mpi_errno, MPIX_ERR_NOREQ, goto fn_fail, "**nomemreq"); sreq->u.rma.win = win; - MPIDIG_REQUEST(sreq, req->creq.addr) = result_addr; - MPIDIG_REQUEST(sreq, req->creq.datatype) = datatype; - MPIDIG_REQUEST(sreq, req->creq.result_addr) = result_addr; + MPIDIG_REQUEST(sreq, buffer) = result_addr; + MPIDIG_REQUEST(sreq, datatype) = datatype; MPIDIG_REQUEST(sreq, req->creq.data) = p_data; MPIDIG_REQUEST(sreq, u.send.dest) = target_rank; MPIR_cc_inc(sreq->cc_ptr); diff --git a/src/mpid/ch4/src/mpidig_rma_callbacks.c b/src/mpid/ch4/src/mpidig_rma_callbacks.c index a0c093f10f8..1466874ac5d 100644 --- a/src/mpid/ch4/src/mpidig_rma_callbacks.c +++ b/src/mpid/ch4/src/mpidig_rma_callbacks.c @@ -489,7 +489,7 @@ static int ack_cswap(MPIR_Request * rreq) MPIR_FUNC_ENTER; - MPIDI_Datatype_check_size(MPIDIG_REQUEST(rreq, req->creq.datatype), 1, data_sz); + MPIDI_Datatype_check_size(MPIDIG_REQUEST(rreq, datatype), 1, data_sz); result_addr = ((char *) MPIDIG_REQUEST(rreq, req->creq.data)) + data_sz; MPIR_cc_inc(rreq->cc_ptr); @@ -499,7 +499,7 @@ static int ack_cswap(MPIR_Request * rreq) int remote_vci = MPIDIG_REQUEST(rreq, req->remote_vci); CH4_CALL(am_isend_reply(rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, u.recv.source), MPIDIG_CSWAP_ACK, &ack_msg, sizeof(ack_msg), result_addr, 1, - MPIDIG_REQUEST(rreq, req->creq.datatype), local_vci, remote_vci, rreq), + MPIDIG_REQUEST(rreq, datatype), local_vci, remote_vci, rreq), MPIDI_REQUEST(rreq, is_local), mpi_errno); MPIR_ERR_CHECK(mpi_errno); fn_exit: @@ -1042,7 +1042,7 @@ static int cswap_target_cmpl_cb(MPIR_Request * rreq) if (!MPIDIG_check_cmpl_order(rreq, vci)) return mpi_errno; - MPIDI_Datatype_check_size(MPIDIG_REQUEST(rreq, req->creq.datatype), 1, data_sz); + MPIDI_Datatype_check_size(MPIDIG_REQUEST(rreq, datatype), 1, data_sz); origin_addr = MPIDIG_REQUEST(rreq, req->creq.data); compare_addr = ((char *) MPIDIG_REQUEST(rreq, req->creq.data)) + data_sz; @@ -1054,12 +1054,12 @@ static int cswap_target_cmpl_cb(MPIR_Request * rreq) } #endif - if (MPIR_Compare_equal((void *) MPIDIG_REQUEST(rreq, req->creq.addr), compare_addr, - MPIDIG_REQUEST(rreq, req->creq.datatype))) { - MPIR_Typerep_copy(compare_addr, (void *) MPIDIG_REQUEST(rreq, req->creq.addr), data_sz); - MPIR_Typerep_copy((void *) MPIDIG_REQUEST(rreq, req->creq.addr), origin_addr, data_sz); + if (MPIR_Compare_equal((void *) MPIDIG_REQUEST(rreq, buffer), compare_addr, + MPIDIG_REQUEST(rreq, datatype))) { + MPIR_Typerep_copy(compare_addr, (void *) MPIDIG_REQUEST(rreq, buffer), data_sz); + MPIR_Typerep_copy((void *) MPIDIG_REQUEST(rreq, buffer), origin_addr, data_sz); } else { - MPIR_Typerep_copy(compare_addr, (void *) MPIDIG_REQUEST(rreq, req->creq.addr), data_sz); + MPIR_Typerep_copy(compare_addr, (void *) MPIDIG_REQUEST(rreq, buffer), data_sz); } #ifndef MPIDI_CH4_DIRECT_NETMOD @@ -1286,8 +1286,8 @@ int MPIDIG_cswap_ack_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz MPIR_T_PVAR_TIMER_START(RMA, rma_targetcb_cas_ack); rreq = (MPIR_Request *) msg_hdr->req_ptr; - MPIDI_Datatype_check_size(MPIDIG_REQUEST(rreq, req->creq.datatype), 1, data_sz); - void *result_addr = MPIDIG_REQUEST(rreq, req->creq.result_addr); + MPIDI_Datatype_check_size(MPIDIG_REQUEST(rreq, datatype), 1, data_sz); + void *result_addr = MPIDIG_REQUEST(rreq, buffer); MPIDIG_recv_init(1, data_sz, result_addr, data_sz, rreq); @@ -1827,8 +1827,8 @@ int MPIDIG_cswap_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, rreq->u.rma.win = win; MPIDIG_REQUEST(rreq, req->creq.creq_ptr) = msg_hdr->req_ptr; - MPIDIG_REQUEST(rreq, req->creq.datatype) = msg_hdr->datatype; - MPIDIG_REQUEST(rreq, req->creq.addr) = (char *) base + offset; + MPIDIG_REQUEST(rreq, datatype) = msg_hdr->datatype; + MPIDIG_REQUEST(rreq, buffer) = (char *) base + offset; MPIDIG_REQUEST(rreq, u.recv.source) = msg_hdr->src_rank; MPIR_Assert(dt_contig == 1); From 63fabebf23481c5daf139d019d49de0c23e1dfd0 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Wed, 3 Nov 2021 10:31:19 -0500 Subject: [PATCH 140/607] ch4/am: Add origin and target structs to generic union Rather than RMA requests using send and recv structs to store operation information, add origin and target specific fields to give better context for the reader. --- src/mpid/ch4/include/mpidpre.h | 6 ++ src/mpid/ch4/src/mpidig_rma.h | 10 ++-- src/mpid/ch4/src/mpidig_rma_callbacks.c | 75 +++++++++++++------------ 3 files changed, 51 insertions(+), 40 deletions(-) diff --git a/src/mpid/ch4/include/mpidpre.h b/src/mpid/ch4/include/mpidpre.h index 5cc4dc3f081..f20aeba011b 100644 --- a/src/mpid/ch4/include/mpidpre.h +++ b/src/mpid/ch4/include/mpidpre.h @@ -200,6 +200,12 @@ typedef struct MPIDIG_req_t { MPIR_Context_id_t context_id; int tag; } recv; + struct { + int target_rank; + } origin; + struct { + int origin_rank; + } target; } u; } MPIDIG_req_t; diff --git a/src/mpid/ch4/src/mpidig_rma.h b/src/mpid/ch4/src/mpidig_rma.h index c7fcb3fe3e4..5f7afd5ad6e 100644 --- a/src/mpid/ch4/src/mpidig_rma.h +++ b/src/mpid/ch4/src/mpidig_rma.h @@ -69,7 +69,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_put(const void *origin_addr, int origin_c /* Increase local and remote completion counters and set the local completion * counter in request, thus it can be decreased at request completion. */ MPIDIG_win_cmpl_cnts_incr(win, target_rank, &sreq->completion_notification); - MPIDIG_REQUEST(sreq, u.send.dest) = target_rank; + MPIDIG_REQUEST(sreq, u.origin.target_rank) = target_rank; int is_contig; MPIR_Datatype_is_contig(target_datatype, &is_contig); @@ -196,7 +196,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_get(void *origin_addr, int origin_count, MPIDIG_REQUEST(sreq, count) = origin_count; MPIDIG_REQUEST(sreq, datatype) = origin_datatype; MPIDIG_REQUEST(sreq, req->greq.target_datatype) = target_datatype; - MPIDIG_REQUEST(sreq, u.send.dest) = target_rank; + MPIDIG_REQUEST(sreq, u.origin.target_rank) = target_rank; MPIR_Datatype_add_ref_if_not_builtin(origin_datatype); MPIR_Datatype_add_ref_if_not_builtin(target_datatype); @@ -320,7 +320,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_accumulate(const void *origin_addr, int o /* Increase remote completion counter for acc. */ MPIDIG_win_remote_acc_cmpl_cnt_incr(win, target_rank); - MPIDIG_REQUEST(sreq, u.send.dest) = target_rank; + MPIDIG_REQUEST(sreq, u.origin.target_rank) = target_rank; if (MPIR_DATATYPE_IS_PREDEFINED(target_datatype)) { am_hdr.flattened_sz = 0; MPIR_T_PVAR_TIMER_END(RMA, rma_amhdr_set); @@ -473,7 +473,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_get_accumulate(const void *origin_addr, /* Increase remote completion counter for acc. */ MPIDIG_win_remote_acc_cmpl_cnt_incr(win, target_rank); - MPIDIG_REQUEST(sreq, u.send.dest) = target_rank; + MPIDIG_REQUEST(sreq, u.origin.target_rank) = target_rank; if (MPIR_DATATYPE_IS_PREDEFINED(target_datatype)) { am_hdr.flattened_sz = 0; MPIR_T_PVAR_TIMER_END(RMA, rma_amhdr_set); @@ -786,7 +786,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_mpi_compare_and_swap(const void *origin_addr MPIDIG_REQUEST(sreq, buffer) = result_addr; MPIDIG_REQUEST(sreq, datatype) = datatype; MPIDIG_REQUEST(sreq, req->creq.data) = p_data; - MPIDIG_REQUEST(sreq, u.send.dest) = target_rank; + MPIDIG_REQUEST(sreq, u.origin.target_rank) = target_rank; MPIR_cc_inc(sreq->cc_ptr); MPIR_T_PVAR_TIMER_START(RMA, rma_amhdr_set); diff --git a/src/mpid/ch4/src/mpidig_rma_callbacks.c b/src/mpid/ch4/src/mpidig_rma_callbacks.c index 1466874ac5d..f8dd29d0238 100644 --- a/src/mpid/ch4/src/mpidig_rma_callbacks.c +++ b/src/mpid/ch4/src/mpidig_rma_callbacks.c @@ -469,9 +469,10 @@ static int ack_put(MPIR_Request * rreq) int local_vci = MPIDIG_REQUEST(rreq, req->local_vci); int remote_vci = MPIDIG_REQUEST(rreq, req->remote_vci); ack_msg.preq_ptr = MPIDIG_REQUEST(rreq, req->preq.preq_ptr); - CH4_CALL(am_send_hdr_reply(rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, u.recv.source), - MPIDIG_PUT_ACK, &ack_msg, sizeof(ack_msg), local_vci, remote_vci), - MPIDI_REQUEST(rreq, is_local), mpi_errno); + CH4_CALL(am_send_hdr_reply + (rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, u.target.origin_rank), MPIDIG_PUT_ACK, + &ack_msg, sizeof(ack_msg), local_vci, remote_vci), MPIDI_REQUEST(rreq, is_local), + mpi_errno); MPIR_ERR_CHECK(mpi_errno); fn_exit: MPIR_FUNC_EXIT; @@ -497,7 +498,7 @@ static int ack_cswap(MPIR_Request * rreq) int local_vci = MPIDIG_REQUEST(rreq, req->local_vci); int remote_vci = MPIDIG_REQUEST(rreq, req->remote_vci); - CH4_CALL(am_isend_reply(rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, u.recv.source), + CH4_CALL(am_isend_reply(rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, u.target.origin_rank), MPIDIG_CSWAP_ACK, &ack_msg, sizeof(ack_msg), result_addr, 1, MPIDIG_REQUEST(rreq, datatype), local_vci, remote_vci, rreq), MPIDI_REQUEST(rreq, is_local), mpi_errno); @@ -519,9 +520,10 @@ static int ack_acc(MPIR_Request * rreq) int local_vci = MPIDIG_REQUEST(rreq, req->local_vci); int remote_vci = MPIDIG_REQUEST(rreq, req->remote_vci); ack_msg.req_ptr = MPIDIG_REQUEST(rreq, req->areq.req_ptr); - CH4_CALL(am_send_hdr_reply(rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, u.recv.source), - MPIDIG_ACC_ACK, &ack_msg, sizeof(ack_msg), local_vci, remote_vci), - MPIDI_REQUEST(rreq, is_local), mpi_errno); + CH4_CALL(am_send_hdr_reply + (rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, u.target.origin_rank), MPIDIG_ACC_ACK, + &ack_msg, sizeof(ack_msg), local_vci, remote_vci), MPIDI_REQUEST(rreq, is_local), + mpi_errno); MPIR_ERR_CHECK(mpi_errno); fn_exit: MPIR_FUNC_EXIT; @@ -542,7 +544,7 @@ static int ack_get_acc(MPIR_Request * rreq) int local_vci = MPIDIG_REQUEST(rreq, req->local_vci); int remote_vci = MPIDIG_REQUEST(rreq, req->remote_vci); - CH4_CALL(am_isend_reply(rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, u.recv.source), + CH4_CALL(am_isend_reply(rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, u.target.origin_rank), MPIDIG_GET_ACC_ACK, &ack_msg, sizeof(ack_msg), MPIDIG_REQUEST(rreq, req->areq.data), MPIDIG_REQUEST(rreq, req->areq.result_data_sz), MPI_BYTE, local_vci, @@ -895,7 +897,7 @@ static int get_target_cmpl_cb(MPIR_Request * rreq) if (MPIDIG_REQUEST(rreq, req->greq.flattened_dt) == NULL) { MPIDI_Datatype_check_size(MPIDIG_REQUEST(rreq, datatype), MPIDIG_REQUEST(rreq, count), get_ack.target_data_sz); - CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(rreq, u.recv.source), + CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(rreq, u.target.origin_rank), MPIDIG_GET_ACK, &get_ack, sizeof(get_ack), MPIDIG_REQUEST(rreq, buffer), MPIDIG_REQUEST(rreq, count), @@ -919,7 +921,7 @@ static int get_target_cmpl_cb(MPIR_Request * rreq) get_ack.target_data_sz = MPIDIG_REQUEST(rreq, count); MPIDIG_REQUEST(rreq, count) /= dt->size; - CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(rreq, u.recv.source), + CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(rreq, u.target.origin_rank), MPIDIG_GET_ACK, &get_ack, sizeof(get_ack), MPIDIG_REQUEST(rreq, buffer), MPIDIG_REQUEST(rreq, count), dt->handle, local_vci, @@ -962,14 +964,15 @@ static int put_dt_target_cmpl_cb(MPIR_Request * rreq) MPIR_FUNC_ENTER; - ack_msg.src_rank = MPIDIG_REQUEST(rreq, u.recv.source); + ack_msg.src_rank = MPIDIG_REQUEST(rreq, u.target.origin_rank); ack_msg.origin_preq_ptr = MPIDIG_REQUEST(rreq, req->preq.preq_ptr); ack_msg.target_preq_ptr = rreq; int local_vci = MPIDIG_REQUEST(rreq, req->local_vci); int remote_vci = MPIDIG_REQUEST(rreq, req->remote_vci); - CH4_CALL(am_send_hdr_reply(rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, u.recv.source), - MPIDIG_PUT_DT_ACK, &ack_msg, sizeof(ack_msg), local_vci, remote_vci), + CH4_CALL(am_send_hdr_reply + (rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, u.target.origin_rank), + MPIDIG_PUT_DT_ACK, &ack_msg, sizeof(ack_msg), local_vci, remote_vci), MPIDI_REQUEST(rreq, is_local), mpi_errno); MPIR_ERR_CHECK(mpi_errno); @@ -992,8 +995,9 @@ static int acc_dt_target_cmpl_cb(MPIR_Request * rreq) int local_vci = MPIDIG_REQUEST(rreq, req->local_vci); int remote_vci = MPIDIG_REQUEST(rreq, req->remote_vci); - CH4_CALL(am_send_hdr_reply(rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, u.recv.source), - MPIDIG_ACC_DT_ACK, &ack_msg, sizeof(ack_msg), local_vci, remote_vci), + CH4_CALL(am_send_hdr_reply + (rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, u.target.origin_rank), + MPIDIG_ACC_DT_ACK, &ack_msg, sizeof(ack_msg), local_vci, remote_vci), MPIDI_REQUEST(rreq, is_local), mpi_errno); MPIR_ERR_CHECK(mpi_errno); @@ -1016,9 +1020,10 @@ static int get_acc_dt_target_cmpl_cb(MPIR_Request * rreq) int local_vci = MPIDIG_REQUEST(rreq, req->local_vci); int remote_vci = MPIDIG_REQUEST(rreq, req->remote_vci); - CH4_CALL(am_send_hdr_reply(rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, u.recv.source), - MPIDIG_GET_ACC_DT_ACK, &ack_msg, sizeof(ack_msg), local_vci, - remote_vci), MPIDI_REQUEST(rreq, is_local), mpi_errno); + CH4_CALL(am_send_hdr_reply + (rreq->u.rma.win->comm_ptr, MPIDIG_REQUEST(rreq, u.target.origin_rank), + MPIDIG_GET_ACC_DT_ACK, &ack_msg, sizeof(ack_msg), local_vci, remote_vci), + MPIDI_REQUEST(rreq, is_local), mpi_errno); MPIR_ERR_CHECK(mpi_errno); fn_exit: @@ -1132,7 +1137,7 @@ static int get_ack_target_cmpl_cb(MPIR_Request * rreq) MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(rreq, req->greq.target_datatype)); win = rreq->u.rma.win; - MPIDIG_win_remote_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, u.send.dest)); + MPIDIG_win_remote_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, u.origin.target_rank)); MPIDIG_recv_finish(rreq); @@ -1153,8 +1158,8 @@ static int get_acc_ack_target_cmpl_cb(MPIR_Request * rreq) MPIDIG_recv_finish(rreq); win = rreq->u.rma.win; - MPIDIG_win_remote_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, u.send.dest)); - MPIDIG_win_remote_acc_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, u.send.dest)); + MPIDIG_win_remote_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, u.origin.target_rank)); + MPIDIG_win_remote_acc_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, u.origin.target_rank)); MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(rreq, req->areq.result_datatype)); MPID_Request_complete(rreq); @@ -1171,8 +1176,8 @@ static int cswap_ack_target_cmpl_cb(MPIR_Request * rreq) MPIR_FUNC_ENTER; win = rreq->u.rma.win; - MPIDIG_win_remote_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, u.send.dest)); - MPIDIG_win_remote_acc_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, u.send.dest)); + MPIDIG_win_remote_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, u.origin.target_rank)); + MPIDIG_win_remote_acc_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, u.origin.target_rank)); MPL_free(MPIDIG_REQUEST(rreq, req->creq.data)); MPID_Request_complete(rreq); @@ -1195,7 +1200,7 @@ int MPIDIG_put_ack_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, preq = (MPIR_Request *) msg_hdr->preq_ptr; win = preq->u.rma.win; - MPIDIG_win_remote_cmpl_cnt_decr(win, MPIDIG_REQUEST(preq, u.send.dest)); + MPIDIG_win_remote_cmpl_cnt_decr(win, MPIDIG_REQUEST(preq, u.origin.target_rank)); MPID_Request_complete(preq); @@ -1223,8 +1228,8 @@ int MPIDIG_acc_ack_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, rreq = (MPIR_Request *) msg_hdr->req_ptr; win = rreq->u.rma.win; - MPIDIG_win_remote_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, u.send.dest)); - MPIDIG_win_remote_acc_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, u.send.dest)); + MPIDIG_win_remote_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, u.origin.target_rank)); + MPIDIG_win_remote_acc_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, u.origin.target_rank)); MPID_Request_complete(rreq); @@ -1444,7 +1449,7 @@ int MPIDIG_put_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, MPIR_ERR_CHKANDSTMT(rreq == NULL, mpi_errno, MPIX_ERR_NOREQ, goto fn_fail, "**nomemreq"); MPIDIG_REQUEST(rreq, req->preq.preq_ptr) = msg_hdr->preq_ptr; - MPIDIG_REQUEST(rreq, u.recv.source) = msg_hdr->src_rank; + MPIDIG_REQUEST(rreq, u.target.origin_rank) = msg_hdr->src_rank; win = (MPIR_Win *) MPIDIU_map_lookup(MPIDI_global.win_map, msg_hdr->win_id); MPIR_Assert(win); @@ -1518,7 +1523,7 @@ int MPIDIG_put_dt_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, MPIR_ERR_CHKANDSTMT(rreq == NULL, mpi_errno, MPIX_ERR_NOREQ, goto fn_fail, "**nomemreq"); MPIDIG_REQUEST(rreq, req->preq.preq_ptr) = msg_hdr->preq_ptr; - MPIDIG_REQUEST(rreq, u.recv.source) = msg_hdr->src_rank; + MPIDIG_REQUEST(rreq, u.target.origin_rank) = msg_hdr->src_rank; win = (MPIR_Win *) MPIDIU_map_lookup(MPIDI_global.win_map, msg_hdr->win_id); MPIR_Assert(win); @@ -1579,7 +1584,7 @@ int MPIDIG_put_dt_ack_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_s /* origin datatype to be released in MPIDIG_put_data_origin_cb */ MPIDIG_REQUEST(rreq, datatype) = MPIDIG_REQUEST(origin_req, datatype); - CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(origin_req, u.send.dest), + CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(origin_req, u.origin.target_rank), MPIDIG_PUT_DAT_REQ, &dat_msg, sizeof(dat_msg), MPIDIG_REQUEST(origin_req, buffer), MPIDIG_REQUEST(origin_req, count), @@ -1624,7 +1629,7 @@ int MPIDIG_acc_dt_ack_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_s /* origin datatype to be released in MPIDIG_acc_data_origin_cb */ MPIDIG_REQUEST(rreq, datatype) = MPIDIG_REQUEST(origin_req, datatype); - CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(origin_req, u.send.dest), + CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(origin_req, u.origin.target_rank), MPIDIG_ACC_DAT_REQ, &dat_msg, sizeof(dat_msg), MPIDIG_REQUEST(origin_req, buffer), MPIDIG_REQUEST(origin_req, count), @@ -1669,7 +1674,7 @@ int MPIDIG_get_acc_dt_ack_target_msg_cb(void *am_hdr, void *data, /* origin datatype to be released in MPIDIG_get_acc_data_origin_cb */ MPIDIG_REQUEST(rreq, datatype) = MPIDIG_REQUEST(origin_req, req->areq.origin_datatype); - CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(origin_req, u.send.dest), + CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(origin_req, u.origin.target_rank), MPIDIG_GET_ACC_DAT_REQ, &dat_msg, sizeof(dat_msg), MPIDIG_REQUEST(origin_req, req->areq.origin_addr), MPIDIG_REQUEST(origin_req, req->areq.origin_count), @@ -1829,7 +1834,7 @@ int MPIDIG_cswap_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, MPIDIG_REQUEST(rreq, req->creq.creq_ptr) = msg_hdr->req_ptr; MPIDIG_REQUEST(rreq, datatype) = msg_hdr->datatype; MPIDIG_REQUEST(rreq, buffer) = (char *) base + offset; - MPIDIG_REQUEST(rreq, u.recv.source) = msg_hdr->src_rank; + MPIDIG_REQUEST(rreq, u.target.origin_rank) = msg_hdr->src_rank; MPIR_Assert(dt_contig == 1); p_data = MPL_malloc(data_sz * 2, MPL_MEM_RMA); @@ -1907,7 +1912,7 @@ int MPIDIG_acc_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, MPIDIG_REQUEST(rreq, req->areq.data) = p_data; MPIDIG_REQUEST(rreq, req->areq.flattened_dt) = NULL; MPIDIG_REQUEST(rreq, req->areq.result_data_sz) = msg_hdr->result_data_sz; - MPIDIG_REQUEST(rreq, u.recv.source) = msg_hdr->src_rank; + MPIDIG_REQUEST(rreq, u.target.origin_rank) = msg_hdr->src_rank; if (msg_hdr->flattened_sz) { /* FIXME: MPIR_Typerep_unflatten should allocate the new object */ @@ -2000,7 +2005,7 @@ int MPIDIG_acc_dt_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, MPIDIG_REQUEST(rreq, req->areq.target_addr) = (void *) (offset + base); MPIDIG_REQUEST(rreq, req->areq.op) = msg_hdr->op; MPIDIG_REQUEST(rreq, req->areq.result_data_sz) = msg_hdr->result_data_sz; - MPIDIG_REQUEST(rreq, u.recv.source) = msg_hdr->src_rank; + MPIDIG_REQUEST(rreq, u.target.origin_rank) = msg_hdr->src_rank; void *flattened_dt = MPL_malloc(msg_hdr->flattened_sz, MPL_MEM_RMA); MPIR_Assert(flattened_dt); @@ -2091,7 +2096,7 @@ int MPIDIG_get_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, MPIDIG_REQUEST(rreq, datatype) = msg_hdr->target_datatype; MPIDIG_REQUEST(rreq, req->greq.flattened_dt) = NULL; MPIDIG_REQUEST(rreq, req->greq.greq_ptr) = msg_hdr->greq_ptr; - MPIDIG_REQUEST(rreq, u.recv.source) = msg_hdr->src_rank; + MPIDIG_REQUEST(rreq, u.target.origin_rank) = msg_hdr->src_rank; if (msg_hdr->flattened_sz) { void *flattened_dt = MPL_malloc(msg_hdr->flattened_sz, MPL_MEM_BUFFER); From 54275a6aa62b64c06518f73fd34bfb468843b5fe Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Wed, 3 Nov 2021 11:51:31 -0500 Subject: [PATCH 141/607] ch4/am: Avoid using extended request for GACC When dealing with origin buffers for get_accumulate operations, we can use the generic request fields for buffer, datatype, and count. --- src/mpid/ch4/src/mpidig_rma.h | 6 +++--- src/mpid/ch4/src/mpidig_rma_callbacks.c | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/mpid/ch4/src/mpidig_rma.h b/src/mpid/ch4/src/mpidig_rma.h index 5f7afd5ad6e..95b5daf67e4 100644 --- a/src/mpid/ch4/src/mpidig_rma.h +++ b/src/mpid/ch4/src/mpidig_rma.h @@ -512,9 +512,9 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_get_accumulate(const void *origin_addr, vci, vci, sreq), is_local, mpi_errno); MPL_free(header); } else { - MPIDIG_REQUEST(sreq, req->areq.origin_addr) = (void *) origin_addr; - MPIDIG_REQUEST(sreq, req->areq.origin_count) = origin_count; - MPIDIG_REQUEST(sreq, req->areq.origin_datatype) = origin_datatype; + MPIDIG_REQUEST(sreq, buffer) = (void *) origin_addr; + MPIDIG_REQUEST(sreq, count) = origin_count; + MPIDIG_REQUEST(sreq, datatype) = origin_datatype; MPIR_Datatype_add_ref_if_not_builtin(origin_datatype); /* add reference to ensure the flattened_dt buffer does not get freed */ MPIDIG_REQUEST(sreq, req->areq.target_datatype) = target_datatype; diff --git a/src/mpid/ch4/src/mpidig_rma_callbacks.c b/src/mpid/ch4/src/mpidig_rma_callbacks.c index f8dd29d0238..fd492f6a8c7 100644 --- a/src/mpid/ch4/src/mpidig_rma_callbacks.c +++ b/src/mpid/ch4/src/mpidig_rma_callbacks.c @@ -1672,13 +1672,13 @@ int MPIDIG_get_acc_dt_ack_target_msg_cb(void *am_hdr, void *data, dat_msg.preq_ptr = msg_hdr->target_preq_ptr; win = origin_req->u.rma.win; /* origin datatype to be released in MPIDIG_get_acc_data_origin_cb */ - MPIDIG_REQUEST(rreq, datatype) = MPIDIG_REQUEST(origin_req, req->areq.origin_datatype); + MPIDIG_REQUEST(rreq, datatype) = MPIDIG_REQUEST(origin_req, datatype); CH4_CALL(am_isend_reply(win->comm_ptr, MPIDIG_REQUEST(origin_req, u.origin.target_rank), MPIDIG_GET_ACC_DAT_REQ, &dat_msg, sizeof(dat_msg), - MPIDIG_REQUEST(origin_req, req->areq.origin_addr), - MPIDIG_REQUEST(origin_req, req->areq.origin_count), - MPIDIG_REQUEST(origin_req, req->areq.origin_datatype), local_vci, + MPIDIG_REQUEST(origin_req, buffer), + MPIDIG_REQUEST(origin_req, count), + MPIDIG_REQUEST(origin_req, datatype), local_vci, remote_vci, rreq), (attr & MPIDIG_AM_ATTR__IS_LOCAL), mpi_errno); MPIR_ERR_CHECK(mpi_errno); From 837c7077c57e6e4d383d3a70acf2c2d632dcc85c Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Wed, 3 Nov 2021 11:57:35 -0500 Subject: [PATCH 142/607] ch4/am: Store target datatype in origin struct Origin-side operations which need to keep a reference to a target datatype can do so in the man generic request struct. For some common RMA operations on the origin side, this eliminates any accesses to the extended request structure. --- src/mpid/ch4/include/mpidpre.h | 3 +-- src/mpid/ch4/src/mpidig_rma.h | 8 ++++---- src/mpid/ch4/src/mpidig_rma_callbacks.c | 8 ++++---- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/mpid/ch4/include/mpidpre.h b/src/mpid/ch4/include/mpidpre.h index f20aeba011b..4be45d88c80 100644 --- a/src/mpid/ch4/include/mpidpre.h +++ b/src/mpid/ch4/include/mpidpre.h @@ -90,14 +90,12 @@ typedef struct MPIDIG_part_am_req_t { typedef struct MPIDIG_put_req_t { MPIR_Request *preq_ptr; void *flattened_dt; - MPI_Datatype target_datatype; MPI_Aint origin_data_sz; } MPIDIG_put_req_t; typedef struct MPIDIG_get_req_t { MPIR_Request *greq_ptr; void *flattened_dt; - MPI_Datatype target_datatype; } MPIDIG_get_req_t; typedef struct MPIDIG_cswap_req_t { @@ -202,6 +200,7 @@ typedef struct MPIDIG_req_t { } recv; struct { int target_rank; + MPI_Datatype target_datatype; } origin; struct { int origin_rank; diff --git a/src/mpid/ch4/src/mpidig_rma.h b/src/mpid/ch4/src/mpidig_rma.h index 95b5daf67e4..cad2aca7108 100644 --- a/src/mpid/ch4/src/mpidig_rma.h +++ b/src/mpid/ch4/src/mpidig_rma.h @@ -129,7 +129,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_put(const void *origin_addr, int origin_c MPIDIG_REQUEST(sreq, datatype) = origin_datatype; MPIR_Datatype_add_ref_if_not_builtin(origin_datatype); /* add reference to ensure the flattened_dt buffer does not get freed */ - MPIDIG_REQUEST(sreq, req->preq.target_datatype) = target_datatype; + MPIDIG_REQUEST(sreq, u.origin.target_datatype) = target_datatype; MPIR_Datatype_add_ref_if_not_builtin(target_datatype); CH4_CALL(am_isend(target_rank, win->comm_ptr, MPIDIG_PUT_DT_REQ, &am_hdr, sizeof(am_hdr), @@ -195,7 +195,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_get(void *origin_addr, int origin_count, MPIDIG_REQUEST(sreq, buffer) = origin_addr; MPIDIG_REQUEST(sreq, count) = origin_count; MPIDIG_REQUEST(sreq, datatype) = origin_datatype; - MPIDIG_REQUEST(sreq, req->greq.target_datatype) = target_datatype; + MPIDIG_REQUEST(sreq, u.origin.target_datatype) = target_datatype; MPIDIG_REQUEST(sreq, u.origin.target_rank) = target_rank; MPIR_Datatype_add_ref_if_not_builtin(origin_datatype); MPIR_Datatype_add_ref_if_not_builtin(target_datatype); @@ -364,7 +364,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_accumulate(const void *origin_addr, int o MPIDIG_REQUEST(sreq, datatype) = origin_datatype; MPIR_Datatype_add_ref_if_not_builtin(origin_datatype); /* add reference to ensure the flattened_dt buffer does not get freed */ - MPIDIG_REQUEST(sreq, req->areq.target_datatype) = target_datatype; + MPIDIG_REQUEST(sreq, u.origin.target_datatype) = target_datatype; MPIR_Datatype_add_ref_if_not_builtin(target_datatype); CH4_CALL(am_isend(target_rank, win->comm_ptr, MPIDIG_ACC_DT_REQ, &am_hdr, sizeof(am_hdr), @@ -517,7 +517,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_get_accumulate(const void *origin_addr, MPIDIG_REQUEST(sreq, datatype) = origin_datatype; MPIR_Datatype_add_ref_if_not_builtin(origin_datatype); /* add reference to ensure the flattened_dt buffer does not get freed */ - MPIDIG_REQUEST(sreq, req->areq.target_datatype) = target_datatype; + MPIDIG_REQUEST(sreq, u.origin.target_datatype) = target_datatype; MPIR_Datatype_add_ref_if_not_builtin(target_datatype); CH4_CALL(am_isend(target_rank, win->comm_ptr, MPIDIG_GET_ACC_DT_REQ, diff --git a/src/mpid/ch4/src/mpidig_rma_callbacks.c b/src/mpid/ch4/src/mpidig_rma_callbacks.c index fd492f6a8c7..2d6efaddf9b 100644 --- a/src/mpid/ch4/src/mpidig_rma_callbacks.c +++ b/src/mpid/ch4/src/mpidig_rma_callbacks.c @@ -210,7 +210,7 @@ int MPIDIG_put_dt_origin_cb(MPIR_Request * sreq) { int mpi_errno = MPI_SUCCESS; MPIR_FUNC_ENTER; - MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(sreq, req->preq.target_datatype)); + MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(sreq, u.origin.target_datatype)); MPID_Request_complete(sreq); MPIR_FUNC_EXIT; return mpi_errno; @@ -220,7 +220,7 @@ int MPIDIG_acc_dt_origin_cb(MPIR_Request * sreq) { int mpi_errno = MPI_SUCCESS; MPIR_FUNC_ENTER; - MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(sreq, req->areq.target_datatype)); + MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(sreq, u.origin.target_datatype)); MPID_Request_complete(sreq); MPIR_FUNC_EXIT; return mpi_errno; @@ -230,7 +230,7 @@ int MPIDIG_get_acc_dt_origin_cb(MPIR_Request * sreq) { int mpi_errno = MPI_SUCCESS; MPIR_FUNC_ENTER; - MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(sreq, req->areq.target_datatype)); + MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(sreq, u.origin.target_datatype)); MPID_Request_complete(sreq); MPIR_FUNC_EXIT; return mpi_errno; @@ -1134,7 +1134,7 @@ static int get_ack_target_cmpl_cb(MPIR_Request * rreq) MPIR_FUNC_ENTER; - MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(rreq, req->greq.target_datatype)); + MPIR_Datatype_release_if_not_builtin(MPIDIG_REQUEST(rreq, u.origin.target_datatype)); win = rreq->u.rma.win; MPIDIG_win_remote_cmpl_cnt_decr(win, MPIDIG_REQUEST(rreq, u.origin.target_rank)); From 4508cbc334ece270bc43daf43741712f2cbf1021 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Wed, 3 Nov 2021 16:17:18 -0500 Subject: [PATCH 143/607] debugger: Update ch4 generic request support Fields used by receive queue debugging have relocated in the ch4 request structure. --- src/mpi/debugger/dbgstub.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mpi/debugger/dbgstub.c b/src/mpi/debugger/dbgstub.c index bdc9cf039ea..66efc9da868 100644 --- a/src/mpi/debugger/dbgstub.c +++ b/src/mpi/debugger/dbgstub.c @@ -199,11 +199,11 @@ int dbgrI_field_offset(mqs_type * type, char *name) } else if (strcmp(name, "count") == 0) { off = ((char *) &c.count - (char *) &c); } else if (strcmp(name, "rank") == 0) { - off = ((char *) &c.rank - (char *) &c); + off = ((char *) &c.u.recv.source - (char *) &c); } else if (strcmp(name, "tag") == 0) { - off = ((char *) &c.tag - (char *) &c); + off = ((char *) &c.u.recv.tag - (char *) &c); } else if (strcmp(name, "context_id") == 0) { - off = ((char *) &c.context_id - (char *) &c); + off = ((char *) &c.u.recv.context_id - (char *) &c); } else if (strcmp(name, "datatype") == 0) { off = ((char *) &c.datatype - (char *) &c); } else { From 0eecf27ba057078d343caa97e50d4651e804eb19 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Thu, 29 Jul 2021 14:18:39 -0500 Subject: [PATCH 144/607] test/mpi: Add test for unstarted partitioned request Add a test to ensure MPI behaves correctly if a partitioned requests is initialized and then freed without ever being started. In MPICH, this means a reference must be held until the setup handshake completes to avoid trying to write to an unallocated request. --- test/mpi/.gitignore | 1 + test/mpi/part/Makefile.am | 3 ++- test/mpi/part/no_start.c | 43 +++++++++++++++++++++++++++++++++++++++ test/mpi/part/testlist | 2 +- 4 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 test/mpi/part/no_start.c diff --git a/test/mpi/.gitignore b/test/mpi/.gitignore index 6d53039c23f..0cbca5d09ee 100644 --- a/test/mpi/.gitignore +++ b/test/mpi/.gitignore @@ -1231,6 +1231,7 @@ /mpi_t/mpit_vars /mpi_t/qmpi_test /part/multipart +/part/no_start /part/nonblocking_pready /part/parrived /part/parrived_pready_out_of_order diff --git a/test/mpi/part/Makefile.am b/test/mpi/part/Makefile.am index 003083800ca..d1b6dc8a038 100644 --- a/test/mpi/part/Makefile.am +++ b/test/mpi/part/Makefile.am @@ -21,7 +21,8 @@ noinst_PROGRAMS = \ parrived_pready_out_of_order \ pingping \ multipart \ - nonblocking_pready + nonblocking_pready \ + no_start start_pready_wait_CPPFLAGS = -DTEST_WAIT $(AM_CPPFLAGS) diff --git a/test/mpi/part/no_start.c b/test/mpi/part/no_start.c new file mode 100644 index 00000000000..46fdfc8308a --- /dev/null +++ b/test/mpi/part/no_start.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpi.h" +#include +#include "mpitest.h" + +/* +static char MTEST_Descrip[] = "Test for a partitioned request that is never started"; +*/ + +int main(int argc, char *argv[]) +{ + int errs = 0; + MTest_Init(&argc, &argv); + + int size; + int rank; + MPI_Comm_size(MPI_COMM_WORLD, &size); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + if (size < 2) { + fprintf(stderr, "This test requires at least two processes\n"); + MPI_Abort(MPI_COMM_WORLD, 1); + } + + int a; + MPI_Request request; + if (rank == 0) { + MPI_Psend_init(&a, 1, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, MPI_INFO_NULL, &request); + } else if (rank == 1) { + MPI_Precv_init(&a, 1, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_INFO_NULL, &request); + } + + if (rank < 2) { + MPI_Request_free(&request); + } + MPI_Barrier(MPI_COMM_WORLD); + MTest_Finalize(errs); + return MTestReturnValue(errs); +} diff --git a/test/mpi/part/testlist b/test/mpi/part/testlist index 85eac703112..23d01b78dc1 100644 --- a/test/mpi/part/testlist +++ b/test/mpi/part/testlist @@ -40,4 +40,4 @@ parrived_pready_out_of_order 2 arg=-spart=16 arg=-rpart=32 arg=-tot_count=512 ar multipart 2 nonblocking_pready 2 - +no_start 2 From ec5793669569ec35691a941c636a84dbda35e3c6 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Fri, 30 Jul 2021 09:31:50 -0500 Subject: [PATCH 145/607] ch4/part: Add reference for generic init handshake Hold a reference to a partitioned request for the initialization handshake. This ensures it will not be prematurely freed before the handshake completes. --- src/mpid/ch4/src/mpidig_part.c | 3 +++ src/mpid/ch4/src/mpidig_part_callbacks.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/mpid/ch4/src/mpidig_part.c b/src/mpid/ch4/src/mpidig_part.c index 540c025332c..4b22cd33641 100644 --- a/src/mpid/ch4/src/mpidig_part.c +++ b/src/mpid/ch4/src/mpidig_part.c @@ -162,6 +162,9 @@ int MPIDIG_mpi_precv_init(void *buf, int partitions, int count, MPIDIG_precv_matched(*request); } else { + /* add a reference for handshake */ + MPIR_Request_add_ref(*request); + MPIDIG_enqueue_request(*request, &MPIDI_global.part_posted_list, MPIDIG_PART); } diff --git a/src/mpid/ch4/src/mpidig_part_callbacks.c b/src/mpid/ch4/src/mpidig_part_callbacks.c index 3f76ce9d0fb..fa7c072edcc 100644 --- a/src/mpid/ch4/src/mpidig_part_callbacks.c +++ b/src/mpid/ch4/src/mpidig_part_callbacks.c @@ -68,6 +68,9 @@ int MPIDIG_part_send_init_target_msg_cb(void *am_hdr, void *data, if (MPIR_Part_request_is_active(posted_req)) { mpi_errno = MPIDIG_part_issue_cts(posted_req); } + + /* release handshake reference */ + MPIR_Request_free_unsafe(posted_req); } else { MPIR_Request *unexp_req = NULL; From 7ac6581f568d61e7bcef1c93c107ae5753749298 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 5 Nov 2021 10:14:36 -0500 Subject: [PATCH 146/607] f08: avoid using MPL memory functions in f08 When compiled with debug options, MPL_malloc refers to MPL_trmalloc, which now is hidden inside libmpi.so and cannot be accessed from libmpifort.so. --- .../use_mpi_f08/wrappers_c/comm_spawn_c.c | 2 +- .../wrappers_c/comm_spawn_multiple_c.c | 20 +++++++++---------- .../fortran/use_mpi_f08/wrappers_c/utils.c | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_c.c b/src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_c.c index 9e4a5b4eddb..d77ff7754de 100644 --- a/src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_c.c +++ b/src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_c.c @@ -26,7 +26,7 @@ int MPIR_Comm_spawn_c(const char *command, char *argv_f, int maxprocs, MPI_Info PMPI_Comm_spawn(command, argv_c, maxprocs, info, root, comm, intercomm, array_of_errcodes); if (argv_c != MPI_ARGV_NULL) { - MPL_free(argv_c); + free(argv_c); } fn_exit: diff --git a/src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_multiple_c.c b/src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_multiple_c.c index ce9802d0965..e7923500b4f 100644 --- a/src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_multiple_c.c +++ b/src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_multiple_c.c @@ -52,13 +52,13 @@ int MPIR_Comm_spawn_multiple_c(int count, char *array_of_commands_f, if ((char ***) array_of_argv_f == MPI_ARGVS_NULL) { array_of_argv_c = MPI_ARGVS_NULL; } else { - array_of_argv_c = (char ***) MPL_malloc(sizeof(char **) * count, MPL_MEM_BUFFER); + array_of_argv_c = (char ***) malloc(sizeof(char **) * count); if (!array_of_argv_c) MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nomem"); /* Allocate a temp buf to put args of a command */ len = 256; /* length of buf. Initialized with an arbitrary value */ - buf = (char *) MPL_malloc(sizeof(char) * len, MPL_MEM_BUFFER); + buf = (char *) malloc(sizeof(char) * len); if (!buf) MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nomem"); @@ -70,9 +70,9 @@ int MPIR_Comm_spawn_multiple_c(int count, char *array_of_commands_f, do { if (offset + argv_elem_len > len) { /* Make sure buf is big enough */ len = offset + argv_elem_len; - newbuf = (char *) MPL_realloc(buf, len, MPL_MEM_BUFFER); + newbuf = (char *) realloc(buf, len); if (!newbuf) { - MPL_free(buf); + free(buf); MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nomem"); } buf = newbuf; @@ -96,25 +96,25 @@ int MPIR_Comm_spawn_multiple_c(int count, char *array_of_commands_f, MPIR_Fortran_array_of_string_f2c(buf, &(array_of_argv_c[i]), argv_elem_len, 0, 0); if (mpi_errno != MPI_SUCCESS) { for (j = i - 1; j >= 0; j--) - MPL_free(array_of_argv_c[j]); - MPL_free(buf); + free(array_of_argv_c[j]); + free(buf); goto fn_fail; } } - MPL_free(buf); + free(buf); } mpi_errno = PMPI_Comm_spawn_multiple(count, array_of_commands_c, array_of_argv_c, array_of_maxprocs, array_of_info, root, comm, intercomm, array_of_errcodes); - MPL_free(array_of_commands_c); + free(array_of_commands_c); if (array_of_argv_c != MPI_ARGVS_NULL) { for (i = 0; i < count; i++) - MPL_free(array_of_argv_c[i]); - MPL_free(array_of_argv_c); + free(array_of_argv_c[i]); + free(array_of_argv_c); } fn_exit: diff --git a/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c b/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c index 265d34df97c..f393046e8bf 100644 --- a/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c +++ b/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c @@ -54,7 +54,7 @@ extern int MPIR_Fortran_array_of_string_f2c(const char *strs_f, char ***strs_c, } /* Allocate memory for pointers to strings and the strings themself */ - buf = (char *) MPL_malloc(sizeof(char *) * num_strs + sizeof(char) * (num_chars + num_strs), MPL_MEM_STRINGS); /* Add \0 for each string */ + buf = (char *) malloc(sizeof(char *) * num_strs + sizeof(char) * (num_chars + num_strs)); /* Add \0 for each string */ if (buf == NULL) { MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nomem"); } From b1509310746076ccc7c79a217dfe977563d908db Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 5 Nov 2021 10:27:42 -0500 Subject: [PATCH 147/607] f08: remove inclusion of mpiimpl.h from wrappers_c The internal functions in mpiimpl.h is inaccessible from fortran bindings. --- src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_c.c | 1 - .../fortran/use_mpi_f08/wrappers_c/comm_spawn_multiple_c.c | 1 - src/binding/fortran/use_mpi_f08/wrappers_c/utils.c | 1 - 3 files changed, 3 deletions(-) diff --git a/src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_c.c b/src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_c.c index d77ff7754de..e9cb9e9138a 100644 --- a/src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_c.c +++ b/src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_c.c @@ -3,7 +3,6 @@ * See COPYRIGHT in top-level directory */ -#include "mpiimpl.h" #include "cdesc.h" int MPIR_Comm_spawn_c(const char *command, char *argv_f, int maxprocs, MPI_Info info, int root, diff --git a/src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_multiple_c.c b/src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_multiple_c.c index e7923500b4f..33c43454c61 100644 --- a/src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_multiple_c.c +++ b/src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_multiple_c.c @@ -3,7 +3,6 @@ * See COPYRIGHT in top-level directory */ -#include "mpiimpl.h" #include "cdesc.h" int MPIR_Comm_spawn_multiple_c(int count, char *array_of_commands_f, diff --git a/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c b/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c index f393046e8bf..47b995874cc 100644 --- a/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c +++ b/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c @@ -3,7 +3,6 @@ * See COPYRIGHT in top-level directory */ -#include "mpiimpl.h" #include "cdesc.h" /* From ae563330e7bb8a21b41431eb86e4bb273139ae71 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 5 Nov 2021 12:03:39 -0500 Subject: [PATCH 148/607] f08: avoid MPIR_ERR_SETANDJUMP We can't use internal utilities in fortran bindings. --- .../wrappers_c/comm_spawn_multiple_c.c | 15 ++++++++++----- .../fortran/use_mpi_f08/wrappers_c/utils.c | 3 ++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_multiple_c.c b/src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_multiple_c.c index 33c43454c61..0dc49c23fb5 100644 --- a/src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_multiple_c.c +++ b/src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_multiple_c.c @@ -52,14 +52,18 @@ int MPIR_Comm_spawn_multiple_c(int count, char *array_of_commands_f, array_of_argv_c = MPI_ARGVS_NULL; } else { array_of_argv_c = (char ***) malloc(sizeof(char **) * count); - if (!array_of_argv_c) - MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nomem"); + if (!array_of_argv_c) { + mpi_errno = MPI_ERR_OTHER; + goto fn_fail; + } /* Allocate a temp buf to put args of a command */ len = 256; /* length of buf. Initialized with an arbitrary value */ buf = (char *) malloc(sizeof(char) * len); - if (!buf) - MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nomem"); + if (!buf) { + mpi_errno = MPI_ERR_OTHER; + goto fn_fail; + } for (i = 0; i < count; i++) { /* Extract args of command i, and put them in buf */ @@ -72,7 +76,8 @@ int MPIR_Comm_spawn_multiple_c(int count, char *array_of_commands_f, newbuf = (char *) realloc(buf, len); if (!newbuf) { free(buf); - MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nomem"); + mpi_errno = MPI_ERR_OTHER; + goto fn_fail; } buf = newbuf; } diff --git a/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c b/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c index 47b995874cc..5913a634089 100644 --- a/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c +++ b/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c @@ -55,7 +55,8 @@ extern int MPIR_Fortran_array_of_string_f2c(const char *strs_f, char ***strs_c, /* Allocate memory for pointers to strings and the strings themself */ buf = (char *) malloc(sizeof(char *) * num_strs + sizeof(char) * (num_chars + num_strs)); /* Add \0 for each string */ if (buf == NULL) { - MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nomem"); + mpi_errno = MPI_ERR_OTHER; + goto fn_fail; } *strs_c = (char **) buf; From 9de2048bc7c73d59631639a92e78b6f2f0679a1e Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 5 Nov 2021 14:22:37 -0500 Subject: [PATCH 149/607] configure: fix typo in defining HAVE_FINT_IS_INT The typo defined the opposite. When FINT actually is INT, it still worked. But it breaks when we configure FINT to be different than INT. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index dd4a2118f5a..f1ab2ef609d 100644 --- a/configure.ac +++ b/configure.ac @@ -3001,7 +3001,7 @@ if test "$enable_f77" = yes ; then fi # Include a defined value for Fint is int - if test "$SIZEOF_F77_INTEGER" != "$ac_cv_sizeof_int" ; then + if test "$SIZEOF_F77_INTEGER" == "$ac_cv_sizeof_int" ; then AC_DEFINE(HAVE_FINT_IS_INT,1,[Define if Fortran integer are the same size as C ints]) else AC_MSG_WARN([Fortran integers and C ints are not the same size. Support for this case is experimental; use at your own risk]) From 9fa538a2d5ca1dddd91a4874942330cc80dd464b Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 5 Nov 2021 15:59:57 -0500 Subject: [PATCH 150/607] ch4/ofi: protect mr_key_allocator in per-vci thread-cs We need protect the global mr_key_allocator. This issue manifests in when we --disable-ofi-domain, i.e. using SEP context for vci since collided keys are being used in the single fi domain. However, even with using fi domain for vci, we are still corrupting the global data, which need to be fixed. This is in the sending huge path when we using local provider key. The performance impact of the lock should be small. --- src/mpid/ch4/netmod/ofi/util.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/util.c b/src/mpid/ch4/netmod/ofi/util.c index c35f3de4caa..cc0e34ea0fd 100644 --- a/src/mpid/ch4/netmod/ofi/util.c +++ b/src/mpid/ch4/netmod/ofi/util.c @@ -25,11 +25,16 @@ typedef struct MPIDI_OFI_mr_key_allocator_t { } MPIDI_OFI_mr_key_allocator_t; static MPIDI_OFI_mr_key_allocator_t mr_key_allocator; +static MPID_Thread_mutex_t mr_key_allocator_lock; int MPIDI_OFI_mr_key_allocator_init(void) { int mpi_errno = MPI_SUCCESS; + int err; + MPID_Thread_mutex_create(&mr_key_allocator_lock, &err); + MPIR_Assert(err == 0); + mr_key_allocator.chunk_size = 128; mr_key_allocator.num_ints = mr_key_allocator.chunk_size; mr_key_allocator.last_free_mr_key = 0; @@ -66,8 +71,8 @@ uint64_t MPIDI_OFI_mr_key_alloc(int key_type, uint64_t requested_key) switch (key_type) { case MPIDI_OFI_LOCAL_MR_KEY: { - uint64_t i; - for (i = mr_key_allocator.last_free_mr_key; i < mr_key_allocator.num_ints; i++) { + MPID_THREAD_CS_ENTER(VCI, mr_key_allocator_lock); + for (int i = mr_key_allocator.last_free_mr_key; i < mr_key_allocator.num_ints; i++) { if (mr_key_allocator.bitmask[i]) { register uint64_t val, nval; val = mr_key_allocator.bitmask[i]; @@ -96,6 +101,7 @@ uint64_t MPIDI_OFI_mr_key_alloc(int key_type, uint64_t requested_key) sizeof(uint64_t) * mr_key_allocator.chunk_size); } } + MPID_THREAD_CS_EXIT(VCI, mr_key_allocator_lock); break; } @@ -123,12 +129,14 @@ void MPIDI_OFI_mr_key_free(int key_type, uint64_t alloc_key) { uint64_t int_index, bitpos, numbits; + MPID_THREAD_CS_ENTER(VCI, mr_key_allocator_lock); numbits = sizeof(uint64_t) * 8; int_index = alloc_key / numbits; bitpos = alloc_key % numbits; mr_key_allocator.last_free_mr_key = MPL_MIN(int_index, mr_key_allocator.last_free_mr_key); mr_key_allocator.bitmask[int_index] |= (0x1ULL << bitpos); + MPID_THREAD_CS_EXIT(VCI, mr_key_allocator_lock); break; } @@ -147,7 +155,9 @@ void MPIDI_OFI_mr_key_free(int key_type, uint64_t alloc_key) void MPIDI_OFI_mr_key_allocator_destroy(void) { + MPID_THREAD_CS_ENTER(VCI, mr_key_allocator_lock); MPL_free(mr_key_allocator.bitmask); + MPID_THREAD_CS_EXIT(VCI, mr_key_allocator_lock); } int MPIDI_OFI_control_handler(void *am_hdr, void *data, MPI_Aint data_sz, From 188865158d3fa808bf92d15a6953b442cf41573e Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 2 Nov 2021 11:21:16 -0500 Subject: [PATCH 151/607] ch4/ofi: suppress warning of discarding volatile qualifier Somehow this warning shows up in regular build but not in strict build. --- src/mpid/ch4/netmod/ofi/ofi_huge.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_huge.c b/src/mpid/ch4/netmod/ofi/ofi_huge.c index 8f70eb176e9..39f8c383bfb 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_huge.c +++ b/src/mpid/ch4/netmod/ofi/ofi_huge.c @@ -384,7 +384,8 @@ int MPIDI_OFI_huge_chunk_done_event(int vni, struct fi_cq_tagged_entry *wc, void MPIR_cc_decr(chunk_req->chunks_outstanding, &c); if (c == 0) { - MPL_free(chunk_req->chunks_outstanding); + /* cast to suppress warning -- discard volatile qualifier */ + MPL_free((void *) chunk_req->chunks_outstanding); mpi_errno = get_huge_complete(chunk_req->localreq); MPIR_ERR_CHECK(mpi_errno); } From 96e022ebfa2e91ee6631edadee64b24deed6674d Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Fri, 5 Nov 2021 16:19:26 -0500 Subject: [PATCH 152/607] ch4/ucx: Configure embedded UCX optimizations with --enable-fast Add optimization flags to UCX embedded configure if the user supplies --enable-fast. Flags are copied from contrib/configure-opt in the UCX source. Note that this enables non-portable CPU optimizations. --- src/mpid/ch4/netmod/ucx/subconfigure.m4 | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/mpid/ch4/netmod/ucx/subconfigure.m4 b/src/mpid/ch4/netmod/ucx/subconfigure.m4 index 4e6bf7161f5..c8659879827 100644 --- a/src/mpid/ch4/netmod/ucx/subconfigure.m4 +++ b/src/mpid/ch4/netmod/ucx/subconfigure.m4 @@ -41,7 +41,13 @@ AM_COND_IF([BUILD_CH4_NETMOD_UCX],[ if test "$with_ucx" = "embedded" ; then PAC_PUSH_ALL_FLAGS() PAC_RESET_ALL_FLAGS() - PAC_CONFIG_SUBDIR_ARGS([modules/ucx],[--disable-static --enable-embedded --with-java=no],[],[AC_MSG_ERROR(ucx configure failed)]) + if test "$enable_fast" = "yes" -o "$enable_fast" = "all" ; then + # add flags from contrib/configure-release and contrib/configure-opt scripts in the ucx source + ucx_opt_flags="--disable-logging --disable-debug --disable-assertions --disable-params-check --enable-optimizations" + else + ucx_opt_flags="" + fi + PAC_CONFIG_SUBDIR_ARGS([modules/ucx],[--disable-static --enable-embedded --with-java=no $ucx_opt_flags],[],[AC_MSG_ERROR(ucx configure failed)]) PAC_POP_ALL_FLAGS() PAC_APPEND_FLAG([-I${main_top_builddir}/modules/ucx/src], [CPPFLAGS]) PAC_APPEND_FLAG([-I${use_top_srcdir}/modules/ucx/src], [CPPFLAGS]) From 3be884799cf10cdd284718b2a9545ff08ea47ceb Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 6 Nov 2021 08:36:05 -0500 Subject: [PATCH 153/607] f08: add missing string.h Need include string.h for strncpy. --- .../fortran/use_mpi_f08/wrappers_c/comm_spawn_multiple_c.c | 1 + src/binding/fortran/use_mpi_f08/wrappers_c/utils.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_multiple_c.c b/src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_multiple_c.c index 0dc49c23fb5..1860d82af63 100644 --- a/src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_multiple_c.c +++ b/src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_multiple_c.c @@ -4,6 +4,7 @@ */ #include "cdesc.h" +#include int MPIR_Comm_spawn_multiple_c(int count, char *array_of_commands_f, char *array_of_argv_f, const int *array_of_maxprocs, diff --git a/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c b/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c index 5913a634089..241c7455334 100644 --- a/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c +++ b/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c @@ -4,6 +4,7 @@ */ #include "cdesc.h" +#include /* Convert an array of strings in Fortran Format to an array of strings in C format (i.e., char* a[]). From 5653ca6a94ee88658ea8d25e547b7f69d0e0a257 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 8 Nov 2021 14:57:45 -0600 Subject: [PATCH 154/607] ch4/ofi: fix warning - unused label --- src/mpid/ch4/netmod/ofi/util.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mpid/ch4/netmod/ofi/util.c b/src/mpid/ch4/netmod/ofi/util.c index cc0e34ea0fd..8636f2dd8c9 100644 --- a/src/mpid/ch4/netmod/ofi/util.c +++ b/src/mpid/ch4/netmod/ofi/util.c @@ -192,7 +192,6 @@ int MPIDI_OFI_control_handler(void *am_hdr, void *data, MPI_Aint data_sz, MPIR_Assert(0); } - fn_exit: return mpi_errno; } From 3b37839b5a33416f1de07c3b72e7d922f5c614a5 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 8 Nov 2021 15:39:41 -0600 Subject: [PATCH 155/607] hydra: fix slurm nodelist parsing Fix for simple patterns e.g. c[1-2]. --- src/pm/hydra/maint/slurm_nodelist_parse.c | 2 +- src/pm/hydra/tools/bootstrap/external/slurm_query_node_list.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pm/hydra/maint/slurm_nodelist_parse.c b/src/pm/hydra/maint/slurm_nodelist_parse.c index b5db37d7ac0..58054df892c 100644 --- a/src/pm/hydra/maint/slurm_nodelist_parse.c +++ b/src/pm/hydra/maint/slurm_nodelist_parse.c @@ -89,7 +89,7 @@ void list_to_nodes(char *str, struct list **node_list) regcomp(&ematch_old, "([a-z]+[0-9]+)", REG_EXTENDED | REG_ICASE); /* compile group-0 regex for new format: "h00-[00-12,14] | h00[00-12,14] | h00-14 | h0014" */ - regcomp(&gmatch_new[0], "(,|^)([a-z0-9][\\.a-z0-9-]+)(\\[[-,0-9]+\\])?(,|$)", + regcomp(&gmatch_new[0], "(,|^)([a-z0-9][\\.a-z0-9-]*)(\\[[-,0-9]+\\])?(,|$)", REG_EXTENDED | REG_ICASE); /* compile group-1 regex for new format: "00-12 | 14" */ diff --git a/src/pm/hydra/tools/bootstrap/external/slurm_query_node_list.c b/src/pm/hydra/tools/bootstrap/external/slurm_query_node_list.c index f941346100e..869d38b7add 100644 --- a/src/pm/hydra/tools/bootstrap/external/slurm_query_node_list.c +++ b/src/pm/hydra/tools/bootstrap/external/slurm_query_node_list.c @@ -108,7 +108,7 @@ static HYD_status list_to_nodes(char *str) regcomp(&ematch_old, "([a-z]+[0-9]+)", REG_EXTENDED | REG_ICASE); /* compile group-0 regex for new format: "h00-[00-12,14] | h00[00-12,14] | h00-14 | h0014" */ - regcomp(&gmatch_new[0], "(,|^)([a-z0-9][\\.a-z0-9-]+)(\\[[-,0-9]+\\])?(,|$)", + regcomp(&gmatch_new[0], "(,|^)([a-z0-9][\\.a-z0-9-]*)(\\[[-,0-9]+\\])?(,|$)", REG_EXTENDED | REG_ICASE); /* compile group-1 regex for new format: "00-12 | 14" */ From 8d857e6d1a48a8f12ac12de9cfc9df3b24ac242c Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 9 Nov 2021 10:01:43 -0600 Subject: [PATCH 156/607] misc: update CHANGES --- CHANGES | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 5eb55c8f196..5cda522eccd 100644 --- a/CHANGES +++ b/CHANGES @@ -18,7 +18,9 @@ # Generate C API interface functions including man page notes and error checking using Python scripts. -# Generate Fortran mpi_f08 binding using Python scripts. +# Generate Fortran bindings using Python scripts. + +# Generate collective entrance functions and generate per-algorithm tests. # Support explicit --without-cuda configure option. @@ -28,9 +30,22 @@ # Multi-NIC support in ch4:ofi. - A full list of changes is available at the following link: +# Default to ch4:ofi when configure doesn't have a clear choice. Add message + block at the end of configure to advise user. + +# Multiple VCI is fully implemented including the active message fallback paths. + +# Extend IPC to support non-contig datatypes. + +# Add AMD GPU support using HIP. + +# Add generic RNDV callback mechanism with active messages. + +# Refactor ch4 dynamic process functions. + +# Avoid building MPL and hwloc multiple times. - http://www.mpich.org/static/downloads/4.0a2/shortlog +# Many bug fixes and code clean-ups. =============================================================================== Changes in 3.4 From e4855c865ba3f340a34285e562b504e6e122589b Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 9 Nov 2021 10:28:32 -0600 Subject: [PATCH 157/607] maint: remove autotools version check in release.pl It is not clear that autotools version change will always result in ABI breakage. It is likely some autotool bugs in older versions. Remove the check and add a note to advise to check ABI compatibility instead. --- maint/release.pl | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/maint/release.pl b/maint/release.pl index 6291736ed56..477ba9e5635 100755 --- a/maint/release.pl +++ b/maint/release.pl @@ -151,13 +151,9 @@ sub run_cmd check_package("automake"); print("\n"); -## IMPORTANT: Changing the autotools versions can result in ABI -## breakage. So make sure the ABI string in the release tarball is -## updated when you do that. -check_autotools_version("autoconf", "2.69"); -check_autotools_version("automake", "1.15"); -check_autotools_version("libtool", "2.4.6"); -print("\n"); +## NOTE: Different autotools versions may result in accidental ABI chanages. +## For flexibility, we no longer enforce the check for specific versions. +## Always double check using the ABI compatibility tool before the final release. my $tdir = tempdir(CLEANUP => 1); From 0d4512636a20bd11c682f4048c271001ba51693f Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 6 Nov 2021 20:11:13 -0500 Subject: [PATCH 158/607] datatype: fix dataloop MPIR_Typerep_pack When it is a contig datatype and offset is nonzero, it was copying the entire data_sz rather than what is left. This triggers the assertion error in src/mpid/ch4/src/mpidig_send_utils.h due to packing more bytes than data_sz_left. --- .../typerep/src/typerep_dataloop_pack.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/mpi/datatype/typerep/src/typerep_dataloop_pack.c b/src/mpi/datatype/typerep/src/typerep_dataloop_pack.c index 81d29002dfd..415186af71b 100644 --- a/src/mpi/datatype/typerep/src/typerep_dataloop_pack.c +++ b/src/mpi/datatype/typerep/src/typerep_dataloop_pack.c @@ -51,16 +51,17 @@ int MPIR_Typerep_ipack(const void *inbuf, MPI_Aint incount, MPI_Datatype datatyp data_sz = incount * dt_ptr->size; } - /* make sure we don't pack more than the max bytes */ - /* FIXME: we need to make sure to pack each basic datatype - * atomically, even if the max_pack_bytes allows us to split it */ - if (data_sz > max_pack_bytes) - data_sz = max_pack_bytes; - /* Handle contig case quickly */ if (contig) { - MPIR_Memcpy(outbuf, MPIR_get_contig_ptr(inbuf, dt_true_lb + inoffset), data_sz); - *actual_pack_bytes = data_sz; + MPI_Aint pack_size = data_sz - inoffset; + + /* make sure we don't pack more than the max bytes */ + /* FIXME: we need to make sure to pack each basic datatype + * atomically, even if the max_pack_bytes allows us to split it */ + pack_size = MPL_MIN(pack_size, max_pack_bytes); + + MPIR_Memcpy(outbuf, MPIR_get_contig_ptr(inbuf, dt_true_lb + inoffset), pack_size); + *actual_pack_bytes = pack_size; } else { segp = MPIR_Segment_alloc(inbuf, incount, datatype); MPIR_ERR_CHKANDJUMP1(segp == NULL, mpi_errno, MPI_ERR_OTHER, "**nomem", "**nomem %s", From f2e58c3fc29e2e7566cf9a4bbbba2a8c4b82aeb7 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 6 Nov 2021 20:15:11 -0500 Subject: [PATCH 159/607] ch4/posix: minor clean up Fixing a type in a comment. Consolidate setting bytes_sent in MPIDI_POSIX_eager_send. Avoid duplicate calling MPIDIG_am_send_async_get_data_sz_left. --- .../ch4/shm/posix/eager/iqueue/iqueue_send.h | 7 ++----- src/mpid/ch4/shm/posix/posix_am.h | 20 +++++++++---------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/mpid/ch4/shm/posix/eager/iqueue/iqueue_send.h b/src/mpid/ch4/shm/posix/eager/iqueue/iqueue_send.h index 9ea0c450afb..4cefbba501e 100644 --- a/src/mpid/ch4/shm/posix/eager/iqueue/iqueue_send.h +++ b/src/mpid/ch4/shm/posix/eager/iqueue/iqueue_send.h @@ -93,7 +93,7 @@ MPIDI_POSIX_eager_send(int grank, MPIDI_POSIX_am_header_t * msg_hdr, const void cell->type = MPIDI_POSIX_EAGER_IQUEUE_CELL_TYPE_DATA; } - /* We want to skip packing of send buffer is there is no data to be sent . buf == NULL is + /* We want to skip packing of send buffer if there is no data to be sent . buf == NULL is * not a correct check here because derived datatype can use absolute address for displacement * which requires buffer address passed as MPI_BOTTOM which is usually NULL. count == 0 is also * not reliable because the derived datatype could have zero block size which contains no @@ -101,14 +101,11 @@ MPIDI_POSIX_eager_send(int grank, MPIDI_POSIX_am_header_t * msg_hdr, const void if (bytes_sent) { MPIR_Typerep_pack(buf, count, datatype, offset, payload, available, &packed_size); cell->payload_size += packed_size; + *bytes_sent = packed_size; } MPIDU_genq_shmem_queue_enqueue(transport->cell_pool, terminal, (void *) cell); - if (bytes_sent) { - *bytes_sent = packed_size; - } - fn_exit: MPIR_FUNC_EXIT; return ret; diff --git a/src/mpid/ch4/shm/posix/posix_am.h b/src/mpid/ch4/shm/posix/posix_am.h index 4688be25d3d..4cb591c30ef 100644 --- a/src/mpid/ch4/shm/posix/posix_am.h +++ b/src/mpid/ch4/shm/posix/posix_am.h @@ -272,9 +272,6 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_do_am_isend(int grank, bool issue_deferred, int src_vsi, int dst_vsi) { int mpi_errno = MPI_SUCCESS; - int rc = 0; - MPI_Aint data_sz, send_size, offset = 0; - MPIDI_POSIX_am_header_t *msg_hdr_p; MPIR_FUNC_ENTER; @@ -282,9 +279,11 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_do_am_isend(int grank, * we need to skip some code path in the scenario. Also am_hdr, am_hdr_sz and data_sz are * ignored when issue_deferred is set to true. They should have been saved in the request. */ + MPIDI_POSIX_am_header_t *msg_hdr_p; if (!issue_deferred) { - MPIDI_POSIX_AMREQUEST(sreq, req_hdr) = NULL; + MPI_Aint data_sz; + MPIDI_POSIX_AMREQUEST(sreq, req_hdr) = NULL; MPIDI_Datatype_check_size(datatype, count, data_sz); msg_hdr_p = msg_hdr; @@ -304,15 +303,16 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_do_am_isend(int grank, goto fn_deferred; } - send_size = MPIDIG_am_send_async_get_data_sz_left(sreq); + MPI_Aint offset, sent_size; offset = MPIDIG_am_send_async_get_offset(sreq); - MPI_Aint *bytes_sent_out = MPIDIG_am_send_async_get_data_sz_left(sreq) ? &send_size : NULL; + + int rc; if (offset) { rc = MPIDI_POSIX_eager_send(grank, NULL, NULL, 0, data, count, datatype, offset, - src_vsi, dst_vsi, bytes_sent_out); + src_vsi, dst_vsi, &sent_size); } else { rc = MPIDI_POSIX_eager_send(grank, msg_hdr, am_hdr, am_hdr_sz, data, count, datatype, - offset, src_vsi, dst_vsi, bytes_sent_out); + offset, src_vsi, dst_vsi, &sent_size); } if (rc == MPIDI_POSIX_NOK) { @@ -325,8 +325,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_do_am_isend(int grank, MPL_DBG_MSG_FMT(MPIDI_CH4_DBG_GENERAL, VERBOSE, (MPL_DBG_FDEST, - "issue seg for req handle=0x%x send_size %ld", sreq->handle, send_size)); - MPIDIG_am_send_async_issue_seg(sreq, send_size); + "issue seg for req handle=0x%x sent_size %ld", sreq->handle, sent_size)); + MPIDIG_am_send_async_issue_seg(sreq, sent_size); MPIDIG_am_send_async_finish_seg(sreq); /* if there IS MORE DATA to be sent and we ARE NOT called for issue deferred op, enqueue. From 4a4dfb4e51206d7f538271381e13471fabacb580 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 7 Nov 2021 08:22:40 -0600 Subject: [PATCH 160/607] datatype: move reduce related dataloop functions These functions, MPIR_Typerep_reduce_is_supported, MPIR_Typerep_op, and MPIR_Typerep_reduce, are moved into typerep_dataloop_pack.c, symmetric to typerep_yaksa_pack.c. --- src/mpi/datatype/typerep/dataloop/dataloop.c | 27 ------------------- .../typerep/src/typerep_dataloop_pack.c | 27 +++++++++++++++++++ 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/mpi/datatype/typerep/dataloop/dataloop.c b/src/mpi/datatype/typerep/dataloop/dataloop.c index f1f4d9d6693..9ef5cc74633 100644 --- a/src/mpi/datatype/typerep/dataloop/dataloop.c +++ b/src/mpi/datatype/typerep/dataloop/dataloop.c @@ -184,33 +184,6 @@ static void dloop_copy(void *dest, void *src, MPI_Aint size) return; } -int MPIR_Typerep_reduce_is_supported(MPI_Op op, MPI_Datatype datatype) -{ - /* This function is supposed to return 1 only for yaksa */ - return 0; -} - -int MPIR_Typerep_op(void *source_buf, MPI_Aint source_count, MPI_Datatype source_dtp, - void *target_buf, MPI_Aint target_count, MPI_Datatype target_dtp, MPI_Op op, - bool source_is_packed, int mapped_device) -{ - int mpi_errno = MPI_SUCCESS; - - MPIR_Assert(0); - - return mpi_errno; -} - -int MPIR_Typerep_reduce(const void *in_buf, void *out_buf, MPI_Aint count, MPI_Datatype datatype, - MPI_Op op) -{ - int mpi_errno = MPI_SUCCESS; - - MPIR_Assert(0); - - return mpi_errno; -} - /*@ MPII_Dataloop_update - update pointers after a copy operation diff --git a/src/mpi/datatype/typerep/src/typerep_dataloop_pack.c b/src/mpi/datatype/typerep/src/typerep_dataloop_pack.c index 415186af71b..95fca685875 100644 --- a/src/mpi/datatype/typerep/src/typerep_dataloop_pack.c +++ b/src/mpi/datatype/typerep/src/typerep_dataloop_pack.c @@ -160,3 +160,30 @@ int MPIR_Typerep_wait(MPIR_Typerep_req typereq_req) /* All nonblocking operations are actually blocking. Thus, do nothing in wait. */ return MPI_SUCCESS; } + +int MPIR_Typerep_reduce_is_supported(MPI_Op op, MPI_Datatype datatype) +{ + /* This function is supposed to return 1 only for yaksa */ + return 0; +} + +int MPIR_Typerep_op(void *source_buf, MPI_Aint source_count, MPI_Datatype source_dtp, + void *target_buf, MPI_Aint target_count, MPI_Datatype target_dtp, MPI_Op op, + bool source_is_packed, int mapped_device) +{ + int mpi_errno = MPI_SUCCESS; + + MPIR_Assert(0); + + return mpi_errno; +} + +int MPIR_Typerep_reduce(const void *in_buf, void *out_buf, MPI_Aint count, MPI_Datatype datatype, + MPI_Op op) +{ + int mpi_errno = MPI_SUCCESS; + + MPIR_Assert(0); + + return mpi_errno; +} From 4b2b8aabb6d27864043ff336c7363b149ead8841 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 7 Nov 2021 00:23:49 -0500 Subject: [PATCH 161/607] datatype: implement MPIR_Typerep_op with dataloop The fallback should work for dataloop engine. --- src/mpi/datatype/typerep/src/Makefile.mk | 3 +- .../typerep/src/typerep_dataloop_pack.c | 20 ++- .../datatype/typerep/src/typerep_internal.h | 4 + src/mpi/datatype/typerep/src/typerep_op.c | 160 ++++++++++++++++++ .../datatype/typerep/src/typerep_yaksa_pack.c | 135 +-------------- 5 files changed, 188 insertions(+), 134 deletions(-) create mode 100644 src/mpi/datatype/typerep/src/typerep_op.c diff --git a/src/mpi/datatype/typerep/src/Makefile.mk b/src/mpi/datatype/typerep/src/Makefile.mk index 43dd9f960e6..02709f2a49c 100644 --- a/src/mpi/datatype/typerep/src/Makefile.mk +++ b/src/mpi/datatype/typerep/src/Makefile.mk @@ -5,7 +5,8 @@ mpi_core_sources += \ src/mpi/datatype/typerep/src/typerep_ext32.c \ - src/mpi/datatype/typerep/src/typerep_flatten.c + src/mpi/datatype/typerep/src/typerep_flatten.c \ + src/mpi/datatype/typerep/src/typerep_op.c if BUILD_YAKSA_ENGINE mpi_core_sources += \ diff --git a/src/mpi/datatype/typerep/src/typerep_dataloop_pack.c b/src/mpi/datatype/typerep/src/typerep_dataloop_pack.c index 95fca685875..920b5a839b5 100644 --- a/src/mpi/datatype/typerep/src/typerep_dataloop_pack.c +++ b/src/mpi/datatype/typerep/src/typerep_dataloop_pack.c @@ -6,6 +6,7 @@ #include "mpiimpl.h" #include #include "typerep_pre.h" +#include "typerep_internal.h" int MPIR_Typerep_icopy(void *outbuf, const void *inbuf, MPI_Aint num_bytes, MPIR_Typerep_req * typereq_req) @@ -172,10 +173,27 @@ int MPIR_Typerep_op(void *source_buf, MPI_Aint source_count, MPI_Datatype source bool source_is_packed, int mapped_device) { int mpi_errno = MPI_SUCCESS; + MPIR_FUNC_ENTER; - MPIR_Assert(0); + /* trivial cases */ + if (op == MPI_NO_OP) { + goto fn_exit; + } + + /* error checking */ + MPIR_Assert(HANDLE_IS_BUILTIN(op)); + MPIR_Assert(MPIR_DATATYPE_IS_PREDEFINED(source_dtp)); + mpi_errno = MPII_Typerep_op_fallback(source_buf, source_count, source_dtp, + target_buf, target_count, target_dtp, + op, source_is_packed); + MPIR_ERR_CHECK(mpi_errno); + + fn_exit: + MPIR_FUNC_EXIT; return mpi_errno; + fn_fail: + goto fn_exit; } int MPIR_Typerep_reduce(const void *in_buf, void *out_buf, MPI_Aint count, MPI_Datatype datatype, diff --git a/src/mpi/datatype/typerep/src/typerep_internal.h b/src/mpi/datatype/typerep/src/typerep_internal.h index 0e4ba813722..00dc6c82b27 100644 --- a/src/mpi/datatype/typerep/src/typerep_internal.h +++ b/src/mpi/datatype/typerep/src/typerep_internal.h @@ -9,6 +9,10 @@ #include "mpiimpl.h" #include "typerep_pre.h" +int MPII_Typerep_op_fallback(void *source_buf, MPI_Aint source_count, MPI_Datatype source_dtp, + void *target_buf, MPI_Aint target_count, MPI_Datatype target_dtp, + MPI_Op op, bool source_is_packed); + #if (MPICH_DATATYPE_ENGINE == MPICH_DATATYPE_ENGINE_YAKSA) #include "yaksa.h" diff --git a/src/mpi/datatype/typerep/src/typerep_op.c b/src/mpi/datatype/typerep/src/typerep_op.c new file mode 100644 index 00000000000..5545a8bfcf1 --- /dev/null +++ b/src/mpi/datatype/typerep/src/typerep_op.c @@ -0,0 +1,160 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpiimpl.h" +#include "typerep_internal.h" + +/* MPII_Typerep_op_fallback - accumulate source_buf onto target_buf with op. + * Assume (we may relax and extend in the future) + * - source datatype is predefined (basic or pairtype) + * - target datatype may be derived with the same basic type as source + * - op is builtin op + */ +static int typerep_op_fallback(void *source_buf, MPI_Aint source_count, MPI_Datatype source_dtp, + void *target_buf, MPI_Aint target_count, MPI_Datatype target_dtp, + MPI_Op op); + +int MPII_Typerep_op_fallback(void *source_buf, MPI_Aint source_count, MPI_Datatype source_dtp, + void *target_buf, MPI_Aint target_count, MPI_Datatype target_dtp, + MPI_Op op, bool source_is_packed) +{ + int mpi_errno = MPI_SUCCESS; + + mpi_errno = (*MPIR_OP_HDL_TO_DTYPE_FN(op)) (source_dtp); + MPIR_ERR_CHECK(mpi_errno); + + /* unpack source buffer if necessary */ + bool source_unpacked = false; + if (source_is_packed) { + MPI_Aint source_dtp_size, source_dtp_extent; + MPIR_Datatype_get_size_macro(source_dtp, source_dtp_size); + MPIR_Datatype_get_extent_macro(source_dtp, source_dtp_extent); + if (source_dtp_size != source_dtp_extent) { + /* assume source_dtp is a pairtype */ + MPIR_Assert(MPIR_DATATYPE_IS_PREDEFINED(source_dtp)); + void *src_ptr = MPL_malloc(source_dtp_extent * source_count, MPL_MEM_OTHER); + MPI_Aint unpack_size; + MPIR_Typerep_unpack(source_buf, source_dtp_size * source_count, src_ptr, + source_count, source_dtp, 0, &unpack_size); + source_buf = src_ptr; + source_unpacked = true; + } + } + /* swap host buffers if necessary */ + void *save_targetbuf = NULL; + void *host = MPIR_gpu_host_swap(target_buf, target_count, target_dtp); + if (host) { + save_targetbuf = target_buf; + target_buf = host; + } + + mpi_errno = typerep_op_fallback(source_buf, source_count, source_dtp, + target_buf, target_count, target_dtp, op); + + if (save_targetbuf) { + MPIR_gpu_swap_back(target_buf, save_targetbuf, target_count, target_dtp); + target_buf = save_targetbuf; + } + if (source_unpacked) { + MPL_free(source_buf); + } + MPIR_ERR_CHECK(mpi_errno); + + fn_exit: + return mpi_errno; + fn_fail: + goto fn_exit; +} + +static int typerep_op_fallback(void *source_buf, MPI_Aint source_count, MPI_Datatype source_dtp, + void *target_buf, MPI_Aint target_count, MPI_Datatype target_dtp, + MPI_Op op) +{ + int mpi_errno = MPI_SUCCESS; + + MPIR_op_function *uop; + uop = MPIR_OP_HDL_TO_FN(op); + + if (HANDLE_IS_BUILTIN(target_dtp)) { + MPIR_Assert(source_dtp == target_dtp); + MPIR_Assert(source_count == target_count); + + (*uop) (source_buf, target_buf, &target_count, &target_dtp); + } else { + /* check source type */ + MPI_Aint source_dtp_size, source_dtp_extent; + MPIR_Datatype_get_size_macro(source_dtp, source_dtp_size); + MPIR_Datatype_get_extent_macro(source_dtp, source_dtp_extent); + bool is_pairtype = (source_dtp_size < source_dtp_extent); + + /* get target iov */ + MPI_Aint vec_len; + struct iovec *typerep_vec = NULL; + { + MPIR_Datatype *dtp ATTRIBUTE((unused)); + MPIR_Datatype_get_ptr(target_dtp, dtp); + MPIR_Assert(dtp != NULL); + MPIR_Assert(dtp->basic_type == source_dtp); + MPIR_Assert(dtp->basic_type != MPI_DATATYPE_NULL); + + mpi_errno = MPIR_Typerep_iov_len(target_count, target_dtp, + source_dtp_size * source_count, &vec_len); + MPIR_ERR_CHECK(mpi_errno); + typerep_vec = (struct iovec *) + MPL_malloc(vec_len * sizeof(struct iovec), MPL_MEM_OTHER); + MPIR_ERR_CHKANDJUMP(!typerep_vec, mpi_errno, MPI_ERR_OTHER, "**nomem"); + + MPI_Aint actual_iov_len, actual_iov_bytes; + MPIR_Typerep_to_iov(NULL, target_count, target_dtp, 0, typerep_vec, vec_len, + source_count * source_dtp_size, &actual_iov_len, &actual_iov_bytes); + vec_len = actual_iov_len; + MPIR_Assert(vec_len <= INT_MAX); + } + + /* iterate iov */ + void *source_ptr = source_buf; + void *target_ptr = NULL; + MPI_Aint curr_len = 0; /* current target buffer space discounting gaps */ + for (int i = 0; i < vec_len; i++) { + if (is_pairtype) { + if (curr_len == 0) { + target_ptr = (char *) target_buf + MPIR_Ptr_to_aint(typerep_vec[i].iov_base); + } + curr_len += typerep_vec[i].iov_len; + if (curr_len < source_dtp_size) { + continue; + } + } else { + target_ptr = (char *) target_buf + MPIR_Ptr_to_aint(typerep_vec[i].iov_base); + curr_len = typerep_vec[i].iov_len; + } + + MPI_Aint count = curr_len / source_dtp_size; + MPI_Aint data_sz = count * source_dtp_size; + MPI_Aint stride = count * source_dtp_extent; + + (*uop) (source_ptr, target_ptr, &count, &source_dtp); + + source_ptr = (char *) source_ptr + stride; + if (is_pairtype) { + curr_len -= data_sz; + if (curr_len > 0) { + target_ptr = + (char *) target_buf + MPIR_Ptr_to_aint(typerep_vec[i].iov_base) + + (typerep_vec[i].iov_len - curr_len); + } + } else { + MPIR_Assert(curr_len == data_sz); + } + } + + MPL_free(typerep_vec); + } + + fn_exit: + return mpi_errno; + fn_fail: + goto fn_exit; +} diff --git a/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c b/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c index 23748b14c5e..1ce51988ede 100644 --- a/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c +++ b/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c @@ -411,9 +411,6 @@ int MPIR_Typerep_wait(MPIR_Typerep_req typerep_req) * - target datatype may be derived with the same basic type as source * - op is builtin op */ -static int typerep_op_fallback(void *source_buf, MPI_Aint source_count, MPI_Datatype source_dtp, - void *target_buf, MPI_Aint target_count, MPI_Datatype target_dtp, - MPI_Op op); static int typerep_op_unpack(void *source_buf, void *target_buf, MPI_Aint count, MPI_Datatype datatype, MPI_Op op, int mapped_device); static int typerep_op_pack(void *source_buf, void *target_buf, MPI_Aint count, @@ -488,44 +485,9 @@ int MPIR_Typerep_op(void *source_buf, MPI_Aint source_count, MPI_Datatype source MPL_free(src_ptr); } } else { - mpi_errno = (*MPIR_OP_HDL_TO_DTYPE_FN(op)) (source_dtp); - MPIR_ERR_CHECK(mpi_errno); - - /* unpack source buffer if necessary */ - bool source_unpacked = false; - if (source_is_packed) { - MPI_Aint source_dtp_size, source_dtp_extent; - MPIR_Datatype_get_size_macro(source_dtp, source_dtp_size); - MPIR_Datatype_get_extent_macro(source_dtp, source_dtp_extent); - if (source_dtp_size != source_dtp_extent) { - /* assume source_dtp is a pairtype */ - MPIR_Assert(MPIR_DATATYPE_IS_PREDEFINED(source_dtp)); - void *src_ptr = MPL_malloc(source_dtp_extent * source_count, MPL_MEM_OTHER); - MPI_Aint unpack_size; - MPIR_Typerep_unpack(source_buf, source_dtp_size * source_count, src_ptr, - source_count, source_dtp, 0, &unpack_size); - source_buf = src_ptr; - source_unpacked = true; - } - } - /* swap host buffers if necessary */ - void *save_targetbuf = NULL; - void *host = MPIR_gpu_host_swap(target_buf, target_count, target_dtp); - if (host) { - save_targetbuf = target_buf; - target_buf = host; - } - - mpi_errno = typerep_op_fallback(source_buf, source_count, source_dtp, - target_buf, target_count, target_dtp, op); - - if (save_targetbuf) { - MPIR_gpu_swap_back(target_buf, save_targetbuf, target_count, target_dtp); - target_buf = save_targetbuf; - } - if (source_unpacked) { - MPL_free(source_buf); - } + mpi_errno = MPII_Typerep_op_fallback(source_buf, source_count, source_dtp, + target_buf, target_count, target_dtp, + op, source_is_packed); } MPIR_ERR_CHECK(mpi_errno); @@ -603,94 +565,3 @@ static int typerep_op_pack(void *source_buf, void *target_buf, MPI_Aint count, fn_fail: goto fn_exit; } - -static int typerep_op_fallback(void *source_buf, MPI_Aint source_count, MPI_Datatype source_dtp, - void *target_buf, MPI_Aint target_count, MPI_Datatype target_dtp, - MPI_Op op) -{ - int mpi_errno = MPI_SUCCESS; - - MPIR_op_function *uop; - uop = MPIR_OP_HDL_TO_FN(op); - - if (HANDLE_IS_BUILTIN(target_dtp)) { - MPIR_Assert(source_dtp == target_dtp); - MPIR_Assert(source_count == target_count); - - (*uop) (source_buf, target_buf, &target_count, &target_dtp); - } else { - /* check source type */ - MPI_Aint source_dtp_size, source_dtp_extent; - MPIR_Datatype_get_size_macro(source_dtp, source_dtp_size); - MPIR_Datatype_get_extent_macro(source_dtp, source_dtp_extent); - bool is_pairtype = (source_dtp_size < source_dtp_extent); - - /* get target iov */ - MPI_Aint vec_len; - struct iovec *typerep_vec = NULL; - { - MPIR_Datatype *dtp ATTRIBUTE((unused)); - MPIR_Datatype_get_ptr(target_dtp, dtp); - MPIR_Assert(dtp != NULL); - MPIR_Assert(dtp->basic_type == source_dtp); - MPIR_Assert(dtp->basic_type != MPI_DATATYPE_NULL); - - mpi_errno = MPIR_Typerep_iov_len(target_count, target_dtp, - source_dtp_size * source_count, &vec_len); - MPIR_ERR_CHECK(mpi_errno); - typerep_vec = (struct iovec *) - MPL_malloc(vec_len * sizeof(struct iovec), MPL_MEM_OTHER); - MPIR_ERR_CHKANDJUMP(!typerep_vec, mpi_errno, MPI_ERR_OTHER, "**nomem"); - - MPI_Aint actual_iov_len, actual_iov_bytes; - MPIR_Typerep_to_iov(NULL, target_count, target_dtp, 0, typerep_vec, vec_len, - source_count * source_dtp_size, &actual_iov_len, &actual_iov_bytes); - vec_len = actual_iov_len; - MPIR_Assert(vec_len <= INT_MAX); - } - - /* iterate iov */ - void *source_ptr = source_buf; - void *target_ptr = NULL; - MPI_Aint curr_len = 0; /* current target buffer space discounting gaps */ - for (int i = 0; i < vec_len; i++) { - if (is_pairtype) { - if (curr_len == 0) { - target_ptr = (char *) target_buf + MPIR_Ptr_to_aint(typerep_vec[i].iov_base); - } - curr_len += typerep_vec[i].iov_len; - if (curr_len < source_dtp_size) { - continue; - } - } else { - target_ptr = (char *) target_buf + MPIR_Ptr_to_aint(typerep_vec[i].iov_base); - curr_len = typerep_vec[i].iov_len; - } - - MPI_Aint count = curr_len / source_dtp_size; - MPI_Aint data_sz = count * source_dtp_size; - MPI_Aint stride = count * source_dtp_extent; - - (*uop) (source_ptr, target_ptr, &count, &source_dtp); - - source_ptr = (char *) source_ptr + stride; - if (is_pairtype) { - curr_len -= data_sz; - if (curr_len > 0) { - target_ptr = - (char *) target_buf + MPIR_Ptr_to_aint(typerep_vec[i].iov_base) + - (typerep_vec[i].iov_len - curr_len); - } - } else { - MPIR_Assert(curr_len == data_sz); - } - } - - MPL_free(typerep_vec); - } - - fn_exit: - return mpi_errno; - fn_fail: - goto fn_exit; -} From b9419137b45086b25835a51b09a8a79a4b1126de Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 7 Nov 2021 09:11:08 -0600 Subject: [PATCH 162/607] datatype: allow MPIR_Typerep_to_iov of 0 bytes Check the trivial case of zero data to prevent assertion error later. For example: Assertion failed in file src/mpi/datatype/typerep/dataloop/looputil.c at line 815: *lengthp > 0 --- .../typerep/src/typerep_dataloop_iov.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/mpi/datatype/typerep/src/typerep_dataloop_iov.c b/src/mpi/datatype/typerep/src/typerep_dataloop_iov.c index 17047b4031f..a2c9353da37 100644 --- a/src/mpi/datatype/typerep/src/typerep_dataloop_iov.c +++ b/src/mpi/datatype/typerep/src/typerep_dataloop_iov.c @@ -12,17 +12,22 @@ int MPIR_Typerep_to_iov(const void *buf, MPI_Aint count, MPI_Datatype type, MPI_ struct iovec *iov, MPI_Aint max_iov_len, MPI_Aint max_iov_bytes, MPI_Aint * actual_iov_len, MPI_Aint * actual_iov_bytes) { - MPIR_Segment *seg; int mpi_errno = MPI_SUCCESS; - seg = MPIR_Segment_alloc(buf, count, type); + if (max_iov_len == 0 || max_iov_bytes == 0) { + *actual_iov_len = 0; + *actual_iov_bytes = 0; + } else { + MPIR_Segment *seg; + seg = MPIR_Segment_alloc(buf, count, type); - MPI_Aint last = byte_offset + max_iov_bytes; - *actual_iov_len = max_iov_len; - MPIR_Segment_to_iov(seg, byte_offset, &last, iov, (int *) actual_iov_len); - *actual_iov_bytes = last - byte_offset; + MPI_Aint last = byte_offset + max_iov_bytes; + *actual_iov_len = max_iov_len; + MPIR_Segment_to_iov(seg, byte_offset, &last, iov, (int *) actual_iov_len); + *actual_iov_bytes = last - byte_offset; - MPIR_Segment_free(seg); + MPIR_Segment_free(seg); + } return mpi_errno; } From 69a29a025d9bac96b307fc7c8728f40cb5145a16 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 8 Nov 2021 12:39:47 -0600 Subject: [PATCH 163/607] ch4/ofi: fix MAX_HDR_SIZE in am_recv_event The maximum header size need account for MPIDI_OFI_am_header_t (16 bytes). This fixes the error building ch4 with dataloop, when certain rma header with flattened type in header makes the header size falls within the margin. --- src/mpid/ch4/netmod/ofi/ofi_events.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_events.c b/src/mpid/ch4/netmod/ofi/ofi_events.c index bef72a690db..9df23a18aca 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_events.c +++ b/src/mpid/ch4/netmod/ofi/ofi_events.c @@ -279,7 +279,9 @@ static int am_recv_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * #ifdef NEEDS_STRICT_ALIGNMENT /* FI_MULTI_RECV may pack the message at lesser alignment, copy the header * when that's the case */ -#define MAX_HDR_SIZE 256 /* need accommodate MPIDI_AMTYPE_RDMA_READ */ +#define MAX_HDR_SIZE 280 /* MPIDI_OFI_AM_MSG_HEADER_SIZE + MPIDI_OFI_MAX_AM_HDR_SIZE */ + MPL_COMPILE_TIME_ASSERT(MAX_HDR_SIZE >= + MPIDI_OFI_AM_MSG_HEADER_SIZE + MPIDI_OFI_MAX_AM_HDR_SIZE); /* if has_alignment_copy is 0 and the message contains extended header, the * header needs to be copied out for alignment to access */ int has_alignment_copy = 0; @@ -291,7 +293,7 @@ static int am_recv_event(int vni, struct fi_cq_tagged_entry *wc, MPIR_Request * } memcpy(temp, orig_buf, temp_size); am_hdr = (void *) temp; - /* confirm it (in case MPL_ATTR_ALIGNED didn't work) */ + /* confirm alignment (in case MPL_ATTR_ALIGNED didn't work) */ MPIR_Assert(((intptr_t) am_hdr & (MAX_ALIGNMENT - 1)) == 0); } #endif From 9a2c682daa6e8b8bd906ca4d1aaf430fe396e449 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 10 Nov 2021 09:05:34 -0600 Subject: [PATCH 164/607] binding/c: check userbuffer with displacement We need consider the case when displacement is set to the address and the buffer is MPI_BOTTOM. --- maint/local_python/binding_c.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/maint/local_python/binding_c.py b/maint/local_python/binding_c.py index 4460f88b89a..43a0e28725c 100644 --- a/maint/local_python/binding_c.py +++ b/maint/local_python/binding_c.py @@ -2034,7 +2034,9 @@ def dump_validate_userbuffer_neighbor_vw(func, kind, buf, ct, dt, disp): dt += '[i]' dump_validate_datatype(func, dt) G.out.append("MPIR_ERRTEST_COUNT(%s, mpi_errno);" % ct) - G.out.append("MPIR_ERRTEST_USERBUFFER(%s, %s, %s, mpi_errno);" % (buf, ct, dt)) + G.out.append("if (%s[i] == 0) {" % disp) + G.out.append(" MPIR_ERRTEST_USERBUFFER(%s, %s, %s, mpi_errno);" % (buf, ct, dt)) + G.out.append("}") dump_for_close() def dump_validate_userbuffer_reduce(func, sbuf, rbuf, ct, dt, op): @@ -2164,7 +2166,11 @@ def dump_validate_userbuffer_coll(func, kind, buf, ct, dt, disp): # -- check count && buffer G.out.append("MPIR_ERRTEST_COUNT(%s, mpi_errno);" % ct) + if disp: + dump_if_open("%s[i] == 0" % disp) G.out.append("MPIR_ERRTEST_USERBUFFER(%s, %s, %s, mpi_errno);" % (buf, ct, dt)) + if disp: + dump_if_close() if with_vw: dump_for_close() # i = 0:comm_size From dc0d0a9ae0f995933f32f59d368b083db601d252 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Wed, 10 Nov 2021 11:09:45 -0600 Subject: [PATCH 165/607] coll: Add count == 0 to MPI_(I)BCAST trivial cases MPI_(I)BCAST with 0 count is a no-op. Add an early return check to catch it before calling down into algorithm selection. --- src/binding/c/coll_api.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/binding/c/coll_api.txt b/src/binding/c/coll_api.txt index 842a36e1799..55be70d093e 100644 --- a/src/binding/c/coll_api.txt +++ b/src/binding/c/coll_api.txt @@ -125,7 +125,7 @@ MPI_Barrier_init: MPI_Bcast: .desc: Broadcasts a message from the process with rank "root" to all other processes of the communicator { -- early_return -- - if (comm_ptr->comm_kind == MPIR_COMM_KIND__INTRACOMM && MPIR_Comm_size(comm_ptr) == 1) { + if (count == 0 || (comm_ptr->comm_kind == MPIR_COMM_KIND__INTRACOMM && MPIR_Comm_size(comm_ptr) == 1)) { goto fn_exit; } } @@ -249,7 +249,7 @@ MPI_Ibarrier: MPI_Ibcast: .desc: Broadcasts a message from the process with rank "root" to all other processes of the communicator in a nonblocking way { -- early_return -- - if (comm_ptr->comm_kind == MPIR_COMM_KIND__INTRACOMM && MPIR_Comm_size(comm_ptr) == 1) { + if (count == 0 || (comm_ptr->comm_kind == MPIR_COMM_KIND__INTRACOMM && MPIR_Comm_size(comm_ptr) == 1)) { MPIR_Request *request_ptr = MPIR_Request_create_complete(MPIR_REQUEST_KIND__COLL); *request = request_ptr->handle; goto fn_exit; From 9138152973e3d3b1b025f8d3ab5d078c5f922b4d Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 10 Nov 2021 10:36:06 -0600 Subject: [PATCH 166/607] config: remove -Wno-unused-label Since intel compiler (and some other) doesn't support this option and we need clean for intel compiler anyway, we should clean this warning rather than exempt from it. --- confdb/aclocal_cc.m4 | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/confdb/aclocal_cc.m4 b/confdb/aclocal_cc.m4 index 77a473a4b9c..d30e809fe20 100644 --- a/confdb/aclocal_cc.m4 +++ b/confdb/aclocal_cc.m4 @@ -565,21 +565,6 @@ if test "$enable_strict_done" != "yes" ; then -fno-var-tracking " - case "$pac_cv_cc_vendor" in - gnu) - pac_common_strict_flags="${pac_common_strict_flags} - -Wno-unused-label - " - ;; - icx) - pac_common_strict_flags="${pac_common_strict_flags} - -Wno-unused-label - " - ;; - *) - ;; - esac - if test -z "$1"; then flags=no else From 96b652f207e2bee48b70ad6ab92aa1af97e7439c Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 10 Nov 2021 11:09:47 -0600 Subject: [PATCH 167/607] mpi: use _impl functions in binding layer Many simple functions are directly coded in the binding config files. Instead, always use an impl function that returns mpi_errno. This brings more consistency. It avoids the warning of unused fn_fail label, since mpi_errno is always checked. --- maint/local_python/__init__.py | 2 +- maint/local_python/binding_c.py | 2 +- src/binding/c/attr_api.txt | 12 ------ src/binding/c/comm_api.txt | 19 --------- src/binding/c/datatype_api.txt | 62 ++++++++--------------------- src/binding/c/errhan_api.txt | 9 ----- src/binding/c/group_api.txt | 6 --- src/binding/c/init_api.txt | 23 ----------- src/binding/c/misc_api.txt | 25 ------------ src/binding/c/mpit_api.txt | 3 ++ src/binding/c/request_api.txt | 6 --- src/binding/c/rma_api.txt | 7 ---- src/binding/c/spawn_api.txt | 4 -- src/include/mpir_datatype.h | 5 --- src/mpi/attr/attr_impl.c | 19 ++++++++- src/mpi/comm/comm_impl.c | 34 ++++++++++++++++ src/mpi/datatype/datatype_impl.c | 63 ++++++++++++++++++++++------- src/mpi/errhan/errhan_impl.c | 17 ++++++++ src/mpi/group/group_impl.c | 12 ++++++ src/mpi/init/init_impl.c | 68 ++++++++++++++++++++++++++++++++ src/mpi/request/request_impl.c | 14 +++++++ src/mpi/rma/Makefile.mk | 1 + src/mpi/rma/rma_impl.c | 21 ++++++++++ src/mpi/spawn/spawn_impl.c | 8 ++++ 24 files changed, 264 insertions(+), 178 deletions(-) create mode 100644 src/mpi/rma/rma_impl.c diff --git a/maint/local_python/__init__.py b/maint/local_python/__init__.py index 9c18cccf0e7..a8ee2a98c1e 100644 --- a/maint/local_python/__init__.py +++ b/maint/local_python/__init__.py @@ -109,7 +109,7 @@ def check_write_path(path): 'OPERATION': "MPI_OP_NULL", 'INFO': "MPI_INFO_NULL", 'WINDOW': "MPI_WIN_NULL", - # 'KEYVAL': "", + 'KEYVAL': "MPI_KEYVAL_INVALID", 'REQUEST': "MPI_REQUEST_NULL", 'MESSAGE': "MPI_MESSAGE_NULL", 'SESSION': "MPI_SESSION_NULL", diff --git a/maint/local_python/binding_c.py b/maint/local_python/binding_c.py index 43a0e28725c..41769c78bbb 100644 --- a/maint/local_python/binding_c.py +++ b/maint/local_python/binding_c.py @@ -506,7 +506,7 @@ def process_func_parameters(func): validation_list.append({'kind': "ARGNULL-length", 'name': name, 'length': p['length']}) else: validation_list.append({'kind': "ARGNULL", 'name': name}) - if RE.search(r'get_errhandler$', func_name): + if RE.search(r'(get_errhandler|mpi_comm_get_parent)$', func_name, re.IGNORECASE): # we may get the built-in handler, which doesn't have pointer pass elif kind == "GREQUEST_CLASS" or kind == "DATATYPE": diff --git a/src/binding/c/attr_api.txt b/src/binding/c/attr_api.txt index 7e5c7312f3e..ce37804cb26 100644 --- a/src/binding/c/attr_api.txt +++ b/src/binding/c/attr_api.txt @@ -52,10 +52,6 @@ MPI_Comm_delete_attr: MPI_Comm_free_keyval: .desc: Frees an attribute key for communicators -{ - MPIR_free_keyval(comm_keyval_ptr); - *comm_keyval = MPI_KEYVAL_INVALID; -} MPI_Comm_get_attr: .desc: Retrieves attribute value by key @@ -123,10 +119,6 @@ MPI_Type_delete_attr: MPI_Type_free_keyval: .desc: Frees an attribute key for datatypes -{ - MPIR_free_keyval(type_keyval_ptr); - *type_keyval = MPI_KEYVAL_INVALID; -} MPI_Type_get_attr: .desc: Retrieves attribute value by key @@ -187,10 +179,6 @@ MPI_Win_delete_attr: MPI_Win_free_keyval: .desc: Frees an attribute key for MPI RMA windows -{ - MPIR_free_keyval(win_keyval_ptr); - *win_keyval = MPI_KEYVAL_INVALID; -} MPI_Win_get_attr: .desc: Get attribute cached on an MPI window object diff --git a/src/binding/c/comm_api.txt b/src/binding/c/comm_api.txt index ecab58fd9e9..d84c4ef9cde 100644 --- a/src/binding/c/comm_api.txt +++ b/src/binding/c/comm_api.txt @@ -114,9 +114,6 @@ MPI_Comm_rank: .desc: Determines the rank of the calling process in the communicator .skip: global_cs .extra: ignore_revoked_comm -{ - *rank = MPIR_Comm_rank(comm_ptr); -} MPI_Comm_remote_group: .desc: Accesses the remote group associated with @@ -131,9 +128,6 @@ MPI_Comm_remote_size: .desc: Determines the size of the remote group .skip: global_cs .extra: ignore_revoked_comm -{ - *size = comm_ptr->remote_size; -} MPI_Comm_set_info: .desc: Set new values for the hints of the communicator associated with comm @@ -147,22 +141,12 @@ MPI_Comm_set_info: MPI_Comm_set_name: .desc: Sets the print name for a communicator -{ - MPID_THREAD_CS_ENTER(POBJ, comm_ptr->mutex); - MPID_THREAD_CS_ENTER(VCI, comm_ptr->mutex); - MPL_strncpy(comm_ptr->name, comm_name, MPI_MAX_OBJECT_NAME); - MPID_THREAD_CS_EXIT(POBJ, comm_ptr->mutex); - MPID_THREAD_CS_EXIT(VCI, comm_ptr->mutex); -} MPI_Comm_size: .desc: Determines the size of the group associated with a communicator .skip: global_cs .docnotes: NULL .extra: ignore_revoked_comm -{ - *size = MPIR_Comm_size(comm_ptr); -} MPI_Comm_split: .desc: Creates new communicators based on colors and keys @@ -198,9 +182,6 @@ MPI_Comm_split_type: MPI_Comm_test_inter: .desc: Tests to see if a comm is an inter-communicator .skip: global_cs -{ - *flag = (comm_ptr->comm_kind == MPIR_COMM_KIND__INTERCOMM); -} MPI_Intercomm_create_from_groups: .desc: Create an intercommuncator from local and remote groups diff --git a/src/binding/c/datatype_api.txt b/src/binding/c/datatype_api.txt index 3331730df0b..ee0750d2150 100644 --- a/src/binding/c/datatype_api.txt +++ b/src/binding/c/datatype_api.txt @@ -35,26 +35,6 @@ MPI_Get_address: { -- error_check -- location /* location can be NULL (MPI_BOTTOM) */ } -{ - /* SX_4 needs to set CHAR_PTR_IS_ADDRESS - * The reason is that it computes the different in two pointers in - * an "int", and addresses typically have the high (bit 31) bit set; - * thus the difference, when cast as MPI_Aint (long), is sign-extended, - * making the absolute address negative. Without a copy of the C - * standard, I can't tell if this is a compiler bug or a language bug. - */ -#ifdef CHAR_PTR_IS_ADDRESS - *address = (MPI_Aint) location; -#else - /* Note that this is the "portable" way to generate an address. - * The difference of two pointers is the number of elements - * between them, so this gives the number of chars between location - * and ptr. As long as sizeof(char) represents one byte, - * of bytes from 0 to location */ - *address = (MPI_Aint) ((char *) location - (char *) MPI_BOTTOM); -#endif - /* The same code is used in MPI_Address */ -} MPI_Get_count: .desc: Gets the number of "top level" elements @@ -217,9 +197,6 @@ MPI_Type_free: goto fn_fail; } } -{ - MPIR_Type_free_impl(datatype); -} MPI_Type_extent: datatype: DATATYPE, [datatype to get information on] @@ -228,7 +205,11 @@ MPI_Type_extent: .skip: global_cs .replace: removed with MPI_Type_get_extent { - MPIR_Datatype_get_extent_macro(datatype, *extent); + MPI_Aint lb; + mpi_errno = MPIR_Type_get_extent_impl(datatype, &lb, extent); + if (mpi_errno) { + goto fn_fail; + } } MPI_Type_lb: @@ -236,9 +217,13 @@ MPI_Type_lb: displacement: DISPLACEMENT_AINT_COUNT_SMALL, direction=out, [displacement of lower bound from origin, in bytes] .desc: Returns the lower-bound of a datatype .skip: global_cs - .replace: removed with MPI_Type_Get_extent + .replace: removed with MPI_Type_get_extent { - MPIR_Type_lb_impl(datatype, displacement); + MPI_Aint extent; + mpi_errno = MPIR_Type_get_extent_impl(datatype, displacement, &extent); + if (mpi_errno) { + goto fn_fail; + } } MPI_Type_ub: @@ -248,10 +233,12 @@ MPI_Type_ub: .skip: global_cs .replace: removed with MPI_Type_get_extent { - if (HANDLE_IS_BUILTIN(datatype)) - *displacement = MPIR_Datatype_get_basic_size(datatype); - else - *displacement = datatype_ptr->ub; + MPI_Aint lb, extent; + mpi_errno = MPIR_Type_get_extent_impl(datatype, &lb, &extent); + if (mpi_errno) { + goto fn_fail; + } + *displacement = lb + extent; } MPI_Type_get_contents: @@ -276,9 +263,6 @@ MPI_Type_get_extent: MPI_Type_get_extent_x: .desc: Get the lower bound and extent as MPI_Count values for a datatype .skip: initcheck -{ - MPIR_Type_get_extent_x_impl(datatype, lb, extent); -} MPI_Type_get_true_extent: .desc: Get the true lower bound and extent for a datatype @@ -288,9 +272,6 @@ MPI_Type_get_true_extent: MPI_Type_get_true_extent_x: .desc: Get the true lower bound and extent as MPI_Count values for a datatype .skip: initcheck -{ - MPIR_Type_get_true_extent_x_impl(datatype, true_lb, true_extent); -} MPI_Type_size: .desc: Return the number of bytes occupied by entries in the datatype @@ -304,19 +285,10 @@ MPI_Type_size_x: MPI_Type_set_name: .desc: set datatype name .skip: ThreadSafe -{ - /* Include the null in MPI_MAX_OBJECT_NAME */ - MPL_strncpy(datatype_ptr->name, type_name, MPI_MAX_OBJECT_NAME); -} MPI_Type_get_name: .desc: Get the print name for a datatype .docnotes: ThreadSafeNoUpdate, NULL -{ - /* Include the null in MPI_MAX_OBJECT_NAME */ - MPL_strncpy(type_name, datatype_ptr->name, MPI_MAX_OBJECT_NAME); - *resultlen = (int) strlen(type_name); -} MPI_Type_contiguous: .desc: Creates a contiguous datatype diff --git a/src/binding/c/errhan_api.txt b/src/binding/c/errhan_api.txt index 0aba9faca06..eade227be0d 100644 --- a/src/binding/c/errhan_api.txt +++ b/src/binding/c/errhan_api.txt @@ -48,11 +48,6 @@ MPI_Delete_error_string: MPI_Error_class: .desc: Converts an error code into an error class .skip: initcheck, global_cs -{ - /* We include the dynamic bit because this is needed to fully - * describe the dynamic error classes */ - *errorclass = errorcode & (ERROR_CLASS_MASK | ERROR_DYN_MASK); -} MPI_Error_string: .desc: Return a string for a given error code @@ -63,10 +58,6 @@ MPI_Error_string: 'ierr' argument (in Fortran). These can be converted into error classes with the routine 'MPI_Error_class'. */ -{ - MPIR_Err_get_string(errorcode, string, MPI_MAX_ERROR_STRING, NULL); - *resultlen = (int) strlen(string); -} MPI_Errhandler_create: comm_errhandler_fn: FUNCTION_SMALL, func_type=MPI_Comm_errhandler_function, [user defined error handling procedure] diff --git a/src/binding/c/group_api.txt b/src/binding/c/group_api.txt index fa3b2adecd3..dd2074024d0 100644 --- a/src/binding/c/group_api.txt +++ b/src/binding/c/group_api.txt @@ -106,16 +106,10 @@ MPI_Group_range_incl: MPI_Group_rank: .desc: Returns the rank of this process in the given group .skip: global_cs -{ - *rank = group_ptr->rank; -} MPI_Group_size: .desc: Returns the size of a group .skip: global_cs -{ - *size = group_ptr->size; -} MPI_Group_translate_ranks: .desc: Translates the ranks of processes in one group to those in another group diff --git a/src/binding/c/init_api.txt b/src/binding/c/init_api.txt index 1f0bc1c2e43..a139bcc024f 100644 --- a/src/binding/c/init_api.txt +++ b/src/binding/c/init_api.txt @@ -34,9 +34,6 @@ MPI_Finalized: .desc: Indicates whether 'MPI_Finalize' has been called. .skip: initcheck .include: mpi_init.h -{ - *flag = MPII_world_is_finalized(); -} MPI_Init: .desc: Initialize the MPI execution environment @@ -74,9 +71,6 @@ MPI_Initialized: .desc: Indicates whether 'MPI_Init' has been called. .skip: initcheck .include: mpi_init.h -{ - *flag = MPII_world_is_initialized(); -} MPI_Init_thread: .desc: Initialize the MPI execution environment @@ -112,20 +106,6 @@ MPI_Init_thread: MPI_Is_thread_main: .desc: Returns a flag indicating whether this thread called 'MPI_Init' or 'MPI_Init_thread' .skip: global_cs -{ -#if MPICH_THREAD_LEVEL <= MPI_THREAD_FUNNELED || ! defined(MPICH_IS_THREADED) - { - *flag = TRUE; - } -#else - { - MPID_Thread_id_t my_thread_id; - - MPID_Thread_self(&my_thread_id); - MPID_Thread_same(&MPIR_ThreadInfo.main_thread, &my_thread_id, flag); - } -#endif -} MPI_Query_thread: .desc: Return the level of thread support provided by the MPI library @@ -148,9 +128,6 @@ MPI_Query_thread: routines that discover that MPI has already been initialized and wish to determine what level of thread support is available. */ -{ - *provided = MPIR_ThreadInfo.thread_provided; -} MPI_Session_init: .desc: Initialize an MPI session diff --git a/src/binding/c/misc_api.txt b/src/binding/c/misc_api.txt index 76e67e1ce3e..6c308b8771d 100644 --- a/src/binding/c/misc_api.txt +++ b/src/binding/c/misc_api.txt @@ -92,27 +92,6 @@ MPI_Get_processor_name: MPI_Get_library_version: .desc: Return the version number of MPI library .skip: initcheck -{ - int printed_len; - printed_len = MPL_snprintf(version, MPI_MAX_LIBRARY_VERSION_STRING, - "MPICH Version:\t%s\n" - "MPICH Release date:\t%s\n" - "MPICH ABI:\t%s\n" - "MPICH Device:\t%s\n" - "MPICH configure:\t%s\n" - "MPICH CC:\t%s\n" - "MPICH CXX:\t%s\n" - "MPICH F77:\t%s\n" - "MPICH FC:\t%s\n", - MPII_Version_string, MPII_Version_date, MPII_Version_ABI, - MPII_Version_device, MPII_Version_configure, MPII_Version_CC, - MPII_Version_CXX, MPII_Version_F77, MPII_Version_FC); - if (strlen(MPII_Version_custom) > 0) - MPL_snprintf(version + printed_len, MPI_MAX_LIBRARY_VERSION_STRING - printed_len, - "MPICH Custom Information:\t%s\n", MPII_Version_custom); - - *resultlen = (int) strlen(version); -} MPI_Pcontrol: .desc: Controls profiling @@ -154,10 +133,6 @@ MPI_Pcontrol: MPI_Get_version: .desc: Return the version number of MPI .skip: initcheck -{ - *version = MPI_VERSION; - *subversion = MPI_SUBVERSION; -} MPIX_GPU_query_support: gpu_type: GPU_TYPE, [MPIX_GPU_SUPPORT_CUDA or MPIX_GPU_SUPPORT_ZE] diff --git a/src/binding/c/mpit_api.txt b/src/binding/c/mpit_api.txt index a3a80e8f8b6..7e0096ef106 100644 --- a/src/binding/c/mpit_api.txt +++ b/src/binding/c/mpit_api.txt @@ -266,6 +266,9 @@ MPI_T_init_thread: if (MPIR_T_init_balance == 1) { MPIR_T_THREAD_CS_INIT(); mpi_errno = MPIR_T_env_init(); + if (mpi_errno) { + goto fn_fail; + } } } diff --git a/src/binding/c/request_api.txt b/src/binding/c/request_api.txt index 90f0b16b730..311bde37462 100644 --- a/src/binding/c/request_api.txt +++ b/src/binding/c/request_api.txt @@ -127,16 +127,10 @@ MPI_Startall: MPI_Status_set_cancelled: .desc: Sets the cancelled state associated with a request -{ - MPIR_STATUS_SET_CANCEL_BIT(*status, flag ? TRUE : FALSE); -} MPI_Test_cancelled: .desc: Tests to see if a request was cancelled .skip: global_cs -{ - *flag = MPIR_STATUS_GET_CANCEL_BIT(*status); -} MPI_Test: .desc: Test for the completion of a request diff --git a/src/binding/c/rma_api.txt b/src/binding/c/rma_api.txt index 3958b2f5934..baeff78fe7f 100644 --- a/src/binding/c/rma_api.txt +++ b/src/binding/c/rma_api.txt @@ -419,10 +419,6 @@ MPI_Win_get_info: MPI_Win_get_name: .desc: Get the print name associated with the MPI RMA window -{ - MPL_strncpy(win_name, win_ptr->name, MPI_MAX_OBJECT_NAME); - *resultlen = (int) strlen(win_name); -} MPI_Win_lock: .desc: Begin an RMA access epoch at the target process @@ -526,9 +522,6 @@ MPI_Win_set_info: MPI_Win_set_name: .desc: Set the print name for an MPI RMA window -{ - MPL_strncpy(win_ptr->name, win_name, MPI_MAX_OBJECT_NAME); -} MPI_Win_shared_query: .desc: Query the size and base pointer for a patch of a shared memory window diff --git a/src/binding/c/spawn_api.txt b/src/binding/c/spawn_api.txt index fb275da28ad..96c4ec198ff 100644 --- a/src/binding/c/spawn_api.txt +++ b/src/binding/c/spawn_api.txt @@ -17,10 +17,6 @@ MPI_Comm_get_parent: After the parent communicator is freed or disconnected, 'MPI_Comm_get_parent' returns 'MPI_COMM_NULL'. */ -{ - *parent = (MPIR_Process.comm_parent == NULL) ? MPI_COMM_NULL : - (MPIR_Process.comm_parent)->handle; -} MPI_Comm_join: .desc: Create a communicator by joining two processes connected by a socket diff --git a/src/include/mpir_datatype.h b/src/include/mpir_datatype.h index 90b38483374..3622472fba1 100644 --- a/src/include/mpir_datatype.h +++ b/src/include/mpir_datatype.h @@ -572,13 +572,8 @@ void MPII_Datatype_attr_finalize(void); int MPII_Type_zerolen(MPI_Datatype * newtype); int MPIR_Get_elements_x_impl(MPI_Count * bytes, MPI_Datatype datatype, MPI_Count * elements); -void MPIR_Type_get_extent_x_impl(MPI_Datatype datatype, MPI_Count * lb, MPI_Count * extent); -void MPIR_Type_get_true_extent_x_impl(MPI_Datatype datatype, MPI_Count * true_lb, - MPI_Count * true_extent); int MPIR_Type_contiguous_x_impl(MPI_Count count, MPI_Datatype old_type, MPI_Datatype * new_type_p); -void MPIR_Type_free_impl(MPI_Datatype * datatype); void MPIR_Pack_size(MPI_Aint incount, MPI_Datatype datatype, MPI_Aint * size); -void MPIR_Type_lb_impl(MPI_Datatype datatype, MPI_Aint * displacement); /* Datatype functions */ int MPII_Type_zerolen(MPI_Datatype * newtype); diff --git a/src/mpi/attr/attr_impl.c b/src/mpi/attr/attr_impl.c index 3891e4fa4db..dfbc2539ea8 100644 --- a/src/mpi/attr/attr_impl.c +++ b/src/mpi/attr/attr_impl.c @@ -18,7 +18,24 @@ void MPIR_free_keyval(MPII_Keyval * keyval_ptr) MPIR_Handle_obj_free(&MPII_Keyval_mem, keyval_ptr); } } - return; +} + +int MPIR_Comm_free_keyval_impl(MPII_Keyval * keyval_ptr) +{ + MPIR_free_keyval(keyval_ptr); + return MPI_SUCCESS; +} + +int MPIR_Type_free_keyval_impl(MPII_Keyval * keyval_ptr) +{ + MPIR_free_keyval(keyval_ptr); + return MPI_SUCCESS; +} + +int MPIR_Win_free_keyval_impl(MPII_Keyval * keyval_ptr) +{ + MPIR_free_keyval(keyval_ptr); + return MPI_SUCCESS; } int MPIR_Comm_create_keyval_impl(MPI_Comm_copy_attr_function * comm_copy_attr_fn, diff --git a/src/mpi/comm/comm_impl.c b/src/mpi/comm/comm_impl.c index ab7d854fc00..c30dc893968 100644 --- a/src/mpi/comm/comm_impl.c +++ b/src/mpi/comm/comm_impl.c @@ -26,6 +26,40 @@ === END_MPI_T_CVAR_INFO_BLOCK === */ +int MPIR_Comm_rank_impl(MPIR_Comm * comm_ptr, int *rank) +{ + *rank = MPIR_Comm_rank(comm_ptr); + return MPI_SUCCESS; +} + +int MPIR_Comm_size_impl(MPIR_Comm * comm_ptr, int *size) +{ + *size = MPIR_Comm_size(comm_ptr); + return MPI_SUCCESS; +} + +int MPIR_Comm_remote_size_impl(MPIR_Comm * comm_ptr, int *size) +{ + *size = comm_ptr->remote_size; + return MPI_SUCCESS; +} + +int MPIR_Comm_set_name_impl(MPIR_Comm * comm_ptr, const char *comm_name) +{ + MPID_THREAD_CS_ENTER(POBJ, comm_ptr->mutex); + MPID_THREAD_CS_ENTER(VCI, comm_ptr->mutex); + MPL_strncpy(comm_ptr->name, comm_name, MPI_MAX_OBJECT_NAME); + MPID_THREAD_CS_EXIT(POBJ, comm_ptr->mutex); + MPID_THREAD_CS_EXIT(VCI, comm_ptr->mutex); + return MPI_SUCCESS; +} + +int MPIR_Comm_test_inter_impl(MPIR_Comm * comm_ptr, int *flag) +{ + *flag = (comm_ptr->comm_kind == MPIR_COMM_KIND__INTERCOMM); + return MPI_SUCCESS; +} + /* used in MPIR_Comm_group_impl and MPIR_Comm_create_group_impl */ static int comm_create_local_group(MPIR_Comm * comm_ptr) { diff --git a/src/mpi/datatype/datatype_impl.c b/src/mpi/datatype/datatype_impl.c index e870460cdc4..c0603da7674 100644 --- a/src/mpi/datatype/datatype_impl.c +++ b/src/mpi/datatype/datatype_impl.c @@ -6,6 +6,29 @@ #include "mpiimpl.h" #include "datatype.h" +int MPIR_Get_address_impl(const void *location, MPI_Aint * address) +{ + /* SX_4 needs to set CHAR_PTR_IS_ADDRESS + * The reason is that it computes the different in two pointers in + * an "int", and addresses typically have the high (bit 31) bit set; + * thus the difference, when cast as MPI_Aint (long), is sign-extended, + * making the absolute address negative. Without a copy of the C + * standard, I can't tell if this is a compiler bug or a language bug. + */ +#ifdef CHAR_PTR_IS_ADDRESS + *address = (MPI_Aint) location; +#else + /* Note that this is the "portable" way to generate an address. + * The difference of two pointers is the number of elements + * between them, so this gives the number of chars between location + * and ptr. As long as sizeof(char) represents one byte, + * of bytes from 0 to location */ + *address = (MPI_Aint) ((char *) location - (char *) MPI_BOTTOM); +#endif + /* The same code is used in MPI_Address */ + return MPI_SUCCESS; +} + int MPIR_Get_count_impl(const MPI_Status * status, MPI_Datatype datatype, MPI_Aint * count) { MPI_Aint size; @@ -168,7 +191,7 @@ int MPIR_Type_commit_impl(MPI_Datatype * datatype_p) return mpi_errno; } -void MPIR_Type_free_impl(MPI_Datatype * datatype) +int MPIR_Type_free_impl(MPI_Datatype * datatype) { MPIR_Datatype *datatype_ptr = NULL; @@ -176,6 +199,8 @@ void MPIR_Type_free_impl(MPI_Datatype * datatype) MPIR_Assert(datatype_ptr); MPIR_Datatype_ptr_release(datatype_ptr); *datatype = MPI_DATATYPE_NULL; + + return MPI_SUCCESS; } int MPIR_Type_get_extent_impl(MPI_Datatype datatype, MPI_Aint * lb, MPI_Aint * extent) @@ -188,7 +213,7 @@ int MPIR_Type_get_extent_impl(MPI_Datatype datatype, MPI_Aint * lb, MPI_Aint * e return MPI_SUCCESS; } -void MPIR_Type_get_extent_x_impl(MPI_Datatype datatype, MPI_Count * lb, MPI_Count * extent) +int MPIR_Type_get_extent_x_impl(MPI_Datatype datatype, MPI_Count * lb, MPI_Count * extent) { MPIR_Datatype *datatype_ptr = NULL; @@ -201,6 +226,7 @@ void MPIR_Type_get_extent_x_impl(MPI_Datatype datatype, MPI_Count * lb, MPI_Coun *lb = datatype_ptr->lb; *extent = datatype_ptr->extent; /* derived, should be same as ub - lb */ } + return MPI_SUCCESS; } int MPIR_Type_get_true_extent_impl(MPI_Datatype datatype, MPI_Aint * true_lb, @@ -211,13 +237,14 @@ int MPIR_Type_get_true_extent_impl(MPI_Datatype datatype, MPI_Aint * true_lb, MPIR_Type_get_true_extent_x_impl(datatype, &true_lb_x, &true_extent_x); *true_lb = (true_lb_x > MPIR_AINT_MAX) ? MPI_UNDEFINED : (MPI_Aint) true_lb_x; *true_extent = (true_extent_x > MPIR_AINT_MAX) ? MPI_UNDEFINED : (MPI_Aint) true_extent_x; + return MPI_SUCCESS; } /* any non-MPI functions go here, especially non-static ones */ -void MPIR_Type_get_true_extent_x_impl(MPI_Datatype datatype, MPI_Count * true_lb, - MPI_Count * true_extent) +int MPIR_Type_get_true_extent_x_impl(MPI_Datatype datatype, MPI_Count * true_lb, + MPI_Count * true_extent) { MPIR_Datatype *datatype_ptr = NULL; @@ -230,17 +257,8 @@ void MPIR_Type_get_true_extent_x_impl(MPI_Datatype datatype, MPI_Count * true_lb *true_lb = datatype_ptr->true_lb; *true_extent = datatype_ptr->true_ub - datatype_ptr->true_lb; } -} -void MPIR_Type_lb_impl(MPI_Datatype datatype, MPI_Aint * displacement) -{ - if (HANDLE_IS_BUILTIN(datatype)) { - *displacement = 0; - } else { - MPIR_Datatype *datatype_ptr = NULL; - MPIR_Datatype_get_ptr(datatype, datatype_ptr); - *displacement = datatype_ptr->lb; - } + return MPI_SUCCESS; } int MPIR_Type_size_impl(MPI_Datatype datatype, MPI_Aint * size) @@ -379,3 +397,20 @@ int MPIR_Type_match_size_impl(int typeclass, int size, MPI_Datatype * datatype) fn_fail: goto fn_exit; } + +int MPIR_Type_get_name_impl(MPIR_Datatype * datatype_ptr, char *type_name, int *resultlen) +{ + /* Include the null in MPI_MAX_OBJECT_NAME */ + MPL_strncpy(type_name, datatype_ptr->name, MPI_MAX_OBJECT_NAME); + *resultlen = (int) strlen(type_name); + + return MPI_SUCCESS; +} + +int MPIR_Type_set_name_impl(MPIR_Datatype * datatype_ptr, const char *type_name) +{ + /* Include the null in MPI_MAX_OBJECT_NAME */ + MPL_strncpy(datatype_ptr->name, type_name, MPI_MAX_OBJECT_NAME); + + return MPI_SUCCESS; +} diff --git a/src/mpi/errhan/errhan_impl.c b/src/mpi/errhan/errhan_impl.c index 4d44e8e8075..91664d27112 100644 --- a/src/mpi/errhan/errhan_impl.c +++ b/src/mpi/errhan/errhan_impl.c @@ -507,3 +507,20 @@ int MPIR_Errhandler_free_impl(MPIR_Errhandler * errhan_ptr) } return MPI_SUCCESS; } + +int MPIR_Error_class_impl(int errorcode, int *errorclass) +{ + /* We include the dynamic bit because this is needed to fully + * describe the dynamic error classes */ + *errorclass = errorcode & (ERROR_CLASS_MASK | ERROR_DYN_MASK); + + return MPI_SUCCESS; +} + +int MPIR_Error_string_impl(int errorcode, char *string, int *resultlen) +{ + MPIR_Err_get_string(errorcode, string, MPI_MAX_ERROR_STRING, NULL); + *resultlen = (int) strlen(string); + + return MPI_SUCCESS; +} diff --git a/src/mpi/group/group_impl.c b/src/mpi/group/group_impl.c index 789b6a2f94c..3c3d0c2f53f 100644 --- a/src/mpi/group/group_impl.c +++ b/src/mpi/group/group_impl.c @@ -6,6 +6,18 @@ #include "mpiimpl.h" #include "group.h" +int MPIR_Group_rank_impl(MPIR_Group * group_ptr, int *rank) +{ + *rank = group_ptr->rank; + return MPI_SUCCESS; +} + +int MPIR_Group_size_impl(MPIR_Group * group_ptr, int *size) +{ + *size = group_ptr->size; + return MPI_SUCCESS; +} + int MPIR_Group_compare_impl(MPIR_Group * group_ptr1, MPIR_Group * group_ptr2, int *result) { int mpi_errno = MPI_SUCCESS; diff --git a/src/mpi/init/init_impl.c b/src/mpi/init/init_impl.c index 4e51da29d2c..db2071f52b0 100644 --- a/src/mpi/init/init_impl.c +++ b/src/mpi/init/init_impl.c @@ -31,6 +31,74 @@ === END_MPI_T_CVAR_INFO_BLOCK === */ +int MPIR_Initialized_impl(int *flag) +{ + *flag = MPII_world_is_initialized(); + return MPI_SUCCESS; +} + +int MPIR_Finalized_impl(int *flag) +{ + *flag = MPII_world_is_finalized(); + return MPI_SUCCESS; +} + +int MPIR_Query_thread_impl(int *provided) +{ + *provided = MPIR_ThreadInfo.thread_provided; + return MPI_SUCCESS; +} + +int MPIR_Is_thread_main_impl(int *flag) +{ +#if MPICH_THREAD_LEVEL <= MPI_THREAD_FUNNELED || ! defined(MPICH_IS_THREADED) + { + *flag = TRUE; + } +#else + { + MPID_Thread_id_t my_thread_id; + + MPID_Thread_self(&my_thread_id); + MPID_Thread_same(&MPIR_ThreadInfo.main_thread, &my_thread_id, flag); + } +#endif + return MPI_SUCCESS; +} + +int MPIR_Get_version_impl(int *version, int *subversion) +{ + *version = MPI_VERSION; + *subversion = MPI_SUBVERSION; + + return MPI_SUCCESS; +} + +int MPIR_Get_library_version_impl(char *version, int *resultlen) +{ + int printed_len; + printed_len = MPL_snprintf(version, MPI_MAX_LIBRARY_VERSION_STRING, + "MPICH Version:\t%s\n" + "MPICH Release date:\t%s\n" + "MPICH ABI:\t%s\n" + "MPICH Device:\t%s\n" + "MPICH configure:\t%s\n" + "MPICH CC:\t%s\n" + "MPICH CXX:\t%s\n" + "MPICH F77:\t%s\n" + "MPICH FC:\t%s\n", + MPII_Version_string, MPII_Version_date, MPII_Version_ABI, + MPII_Version_device, MPII_Version_configure, MPII_Version_CC, + MPII_Version_CXX, MPII_Version_F77, MPII_Version_FC); + if (strlen(MPII_Version_custom) > 0) + MPL_snprintf(version + printed_len, MPI_MAX_LIBRARY_VERSION_STRING - printed_len, + "MPICH Custom Information:\t%s\n", MPII_Version_custom); + + *resultlen = (int) strlen(version); + + return MPI_SUCCESS; +} + /* temporary declarations until they are autogenerated */ int MPIR_Session_finalize_impl(MPIR_Session * session_ptr); int MPIR_Session_get_info_impl(MPIR_Session * session_ptr, MPIR_Info ** info_used_ptr); diff --git a/src/mpi/request/request_impl.c b/src/mpi/request/request_impl.c index 28cbe39624f..e432a1e5741 100644 --- a/src/mpi/request/request_impl.c +++ b/src/mpi/request/request_impl.c @@ -5,6 +5,20 @@ #include "mpiimpl.h" +int MPIR_Status_set_cancelled_impl(MPI_Status * status, int flag) +{ + MPIR_STATUS_SET_CANCEL_BIT(*status, flag ? TRUE : FALSE); + + return MPI_SUCCESS; +} + +int MPIR_Test_cancelled_impl(const MPI_Status * status, int *flag) +{ + *flag = MPIR_STATUS_GET_CANCEL_BIT(*status); + + return MPI_SUCCESS; +} + int MPIR_Cancel_impl(MPIR_Request * request_ptr) { int mpi_errno = MPI_SUCCESS; diff --git a/src/mpi/rma/Makefile.mk b/src/mpi/rma/Makefile.mk index 0742a85242b..5b8b40c196c 100644 --- a/src/mpi/rma/Makefile.mk +++ b/src/mpi/rma/Makefile.mk @@ -4,5 +4,6 @@ ## mpi_core_sources += \ + src/mpi/rma/rma_impl.c \ src/mpi/rma/winutil.c \ src/mpi/rma/rmatypeutil.c diff --git a/src/mpi/rma/rma_impl.c b/src/mpi/rma/rma_impl.c new file mode 100644 index 00000000000..401b18bc575 --- /dev/null +++ b/src/mpi/rma/rma_impl.c @@ -0,0 +1,21 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpiimpl.h" + +int MPIR_Win_get_name_impl(MPIR_Win * win_ptr, char *win_name, int *resultlen) +{ + MPL_strncpy(win_name, win_ptr->name, MPI_MAX_OBJECT_NAME); + *resultlen = (int) strlen(win_name); + + return MPI_SUCCESS; +} + +int MPIR_Win_set_name_impl(MPIR_Win * win_ptr, const char *win_name) +{ + MPL_strncpy(win_ptr->name, win_name, MPI_MAX_OBJECT_NAME); + + return MPI_SUCCESS; +} diff --git a/src/mpi/spawn/spawn_impl.c b/src/mpi/spawn/spawn_impl.c index b212be7f5c0..a03e99ddec4 100644 --- a/src/mpi/spawn/spawn_impl.c +++ b/src/mpi/spawn/spawn_impl.c @@ -20,6 +20,14 @@ #define SOCKET_EINTR EINTR #endif +int MPIR_Comm_get_parent_impl(MPI_Comm * parent) +{ + *parent = (MPIR_Process.comm_parent == NULL) ? MPI_COMM_NULL : + (MPIR_Process.comm_parent)->handle; + + return MPI_SUCCESS; +} + static int MPIR_fd_send(int fd, void *buffer, int length) { int mpi_errno = MPI_SUCCESS; From 7ce5d3e031ce0b1bcd8fbe70901be2727efcc27d Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 9 Nov 2021 11:14:05 -0600 Subject: [PATCH 168/607] romio: use constant tag in collective write The code was using `myrank + i + 100 * iter` for tag. With large data or large number of processes, this tag may exceed the tag limit. We find this complex tag is unnecessary. Because the message is send and received using explicit source and destination, we don't need the rank info in the tag. Because MPI message matching is guaranteed to be in order, we don't need iteration number in the tag either. Thus, simply using a constant tag is suffice for the correctness. --- src/mpi/romio/adio/ad_gpfs/ad_gpfs_rdcoll.c | 8 ++++---- src/mpi/romio/adio/ad_gpfs/ad_gpfs_wrcoll.c | 13 +++++++------ src/mpi/romio/adio/ad_lustre/ad_lustre_wrcoll.c | 12 ++++++------ src/mpi/romio/adio/common/ad_iread_coll.c | 8 ++++---- src/mpi/romio/adio/common/ad_iwrite_coll.c | 6 +++--- src/mpi/romio/adio/common/ad_read_coll.c | 8 ++++---- src/mpi/romio/adio/common/ad_write_coll.c | 16 +++++++++------- src/mpi/romio/adio/include/adio.h | 10 ++++++++++ 8 files changed, 47 insertions(+), 34 deletions(-) diff --git a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_rdcoll.c b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_rdcoll.c index 19a1d157129..cbd96645d87 100644 --- a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_rdcoll.c +++ b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_rdcoll.c @@ -829,7 +829,7 @@ static void ADIOI_R_Exchange_data(ADIO_File fd, void *buf, ADIOI_Flatlist_node for (i = 0; i < nprocs; i++) if (recv_size[i]) { MPI_Irecv(((char *) buf) + buf_idx[i], recv_size[i], - MPI_BYTE, i, myrank + i + 100 * iter, fd->comm, requests + j); + MPI_BYTE, i, ADIOI_COLL_TAG(i, iter), fd->comm, requests + j); j++; buf_idx[i] += recv_size[i]; } @@ -845,11 +845,11 @@ static void ADIOI_R_Exchange_data(ADIO_File fd, void *buf, ADIOI_Flatlist_node for (i = 0; i < nprocs; i++) { if (recv_size[i]) { MPI_Irecv(recv_buf[i], recv_size[i], MPI_BYTE, i, - myrank + i + 100 * iter, fd->comm, requests + j); + ADIOI_COLL_TAG(i, iter), fd->comm, requests + j); j++; #ifdef RDCOLL_DEBUG DBG_FPRINTF(stderr, "node %d, recv_size %d, tag %d \n", - myrank, recv_size[i], myrank + i + 100 * iter); + myrank, recv_size[i], ADIOI_COLL_TAG(i, iter)); #endif } } @@ -872,7 +872,7 @@ static void ADIOI_R_Exchange_data(ADIO_File fd, void *buf, ADIOI_Flatlist_node MPI_BYTE, &send_type); /* absolute displacement; use MPI_BOTTOM in send */ MPI_Type_commit(&send_type); - MPI_Isend(MPI_BOTTOM, 1, send_type, i, myrank + i + 100 * iter, + MPI_Isend(MPI_BOTTOM, 1, send_type, i, ADIOI_COLL_TAG(i, iter), fd->comm, requests + nprocs_recv + j); MPI_Type_free(&send_type); if (partial_send[i]) diff --git a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_wrcoll.c b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_wrcoll.c index d7edc14901a..bd17c8a4439 100644 --- a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_wrcoll.c +++ b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_wrcoll.c @@ -34,6 +34,7 @@ #endif #include + /* prototypes of functions used for collective writes only. */ static void ADIOI_Exch_and_write(ADIO_File fd, const void *buf, MPI_Datatype datatype, int nprocs, int myrank, ADIOI_Access @@ -1108,7 +1109,7 @@ static void ADIOI_W_Exchange_data(ADIO_File fd, const void *buf, char *write_buf j = 0; for (i = 0; i < nprocs; i++) { if (recv_size[i]) { - MPI_Irecv(MPI_BOTTOM, 1, recv_types[j], i, myrank + i + 100 * iter, + MPI_Irecv(MPI_BOTTOM, 1, recv_types[j], i, ADIOI_COLL_TAG(i, iter), fd->comm, requests + j); j++; } @@ -1127,7 +1128,7 @@ static void ADIOI_W_Exchange_data(ADIO_File fd, const void *buf, char *write_buf for (i = 0; i < nprocs; i++) if (send_size[i]) { MPI_Isend(((char *) buf) + buf_idx[i], send_size[i], - MPI_BYTE, i, myrank + i + 100 * iter, fd->comm, send_req + j); + MPI_BYTE, i, ADIOI_COLL_TAG(i, iter), fd->comm, send_req + j); j++; buf_idx[i] += send_size[i]; } @@ -1157,8 +1158,8 @@ static void ADIOI_W_Exchange_data(ADIO_File fd, const void *buf, char *write_buf for (i = 0; i < nprocs; i++) { MPI_Status wkl_status; if (recv_size[i]) { - MPI_Recv(MPI_BOTTOM, 1, recv_types[j], i, myrank + i + 100 * iter, - fd->comm, &wkl_status); + MPI_Recv(MPI_BOTTOM, 1, recv_types[j], i, ADIOI_COLL_TAG(i, iter), fd->comm, + &wkl_status); j++; } } @@ -1337,7 +1338,7 @@ static void ADIOI_Fill_send_buffer(ADIO_File fd, const void *buf, ADIOI_Flatlist ADIOI_BUF_COPY} if (send_buf_idx[p] == send_size[p]) { MPI_Isend(send_buf[p], send_size[p], MPI_BYTE, p, - myrank + p + 100 * iter, fd->comm, requests + jj); + ADIOI_COLL_TAG(p, iter), fd->comm, requests + jj); jj++; } } else { @@ -1731,7 +1732,7 @@ static void ADIOI_Fill_send_buffer_nosend(ADIO_File fd, const void *buf, ADIOI_F /* * if (send_buf_idx[p] == send_size[p]) { * MPI_Isend(send_buf[p], send_size[p], MPI_BYTE, p, - * myrank+p+100*iter, fd->comm, requests+jj); + * ADIOI_COLL_TAG(p, iter), fd->comm, requests+jj); * jj++; * } */ diff --git a/src/mpi/romio/adio/ad_lustre/ad_lustre_wrcoll.c b/src/mpi/romio/adio/ad_lustre/ad_lustre_wrcoll.c index ebc0a82343f..2893732f841 100644 --- a/src/mpi/romio/adio/ad_lustre/ad_lustre_wrcoll.c +++ b/src/mpi/romio/adio/ad_lustre/ad_lustre_wrcoll.c @@ -806,8 +806,8 @@ static void ADIOI_LUSTRE_W_Exchange_data(ADIO_File fd, const void *buf, j = 0; for (i = 0; i < nprocs; i++) { if (recv_size[i]) { - MPI_Irecv(MPI_BOTTOM, 1, recv_types[j], i, - myrank + i + 100 * iter, fd->comm, requests + j); + MPI_Irecv(MPI_BOTTOM, 1, recv_types[j], i, ADIOI_COLL_TAG(i, iter), fd->comm, + requests + j); j++; } } @@ -824,7 +824,7 @@ static void ADIOI_LUSTRE_W_Exchange_data(ADIO_File fd, const void *buf, if (send_size[i]) { ADIOI_Assert(buf_idx[i] != -1); MPI_Issend(((char *) buf) + buf_idx[i], send_size[i], - MPI_BYTE, i, myrank + i + 100 * iter, fd->comm, send_req + j); + MPI_BYTE, i, ADIOI_COLL_TAG(i, iter), fd->comm, send_req + j); j++; } } else if (nprocs_send) { @@ -849,8 +849,8 @@ static void ADIOI_LUSTRE_W_Exchange_data(ADIO_File fd, const void *buf, for (i = 0; i < nprocs; i++) { MPI_Status wkl_status; if (recv_size[i]) { - MPI_Recv(MPI_BOTTOM, 1, recv_types[j], i, - myrank + i + 100 * iter, fd->comm, &wkl_status); + MPI_Recv(MPI_BOTTOM, 1, recv_types[j], i, ADIOI_COLL_TAG(i, iter), fd->comm, + &wkl_status); j++; } } @@ -1025,7 +1025,7 @@ static void ADIOI_LUSTRE_Fill_send_buffer(ADIO_File fd, const void *buf, ADIOI_BUF_COPY} if (send_buf_idx[p] == send_size[p]) { MPI_Issend(send_buf[p], send_size[p], MPI_BYTE, p, - myrank + p + 100 * iter, fd->comm, requests + jj); + ADIOI_COLL_TAG(p, iter), fd->comm, requests + jj); jj++; } } else { diff --git a/src/mpi/romio/adio/common/ad_iread_coll.c b/src/mpi/romio/adio/common/ad_iread_coll.c index 28f1afe6718..927ae347a7b 100644 --- a/src/mpi/romio/adio/common/ad_iread_coll.c +++ b/src/mpi/romio/adio/common/ad_iread_coll.c @@ -1005,7 +1005,7 @@ static void ADIOI_R_Iexchange_data_recv(ADIOI_NBC_Request * nbc_req, int *error_ for (i = 0; i < nprocs; i++) if (recv_size[i]) { MPI_Irecv(((char *) vars->buf) + buf_idx[i], recv_size[i], - MPI_BYTE, i, myrank + i + 100 * iter, fd->comm, vars->req2 + j); + MPI_BYTE, i, ADIOI_COLL_TAG(i, iter), fd->comm, vars->req2 + j); j++; buf_idx[i] += recv_size[i]; } @@ -1021,11 +1021,11 @@ static void ADIOI_R_Iexchange_data_recv(ADIOI_NBC_Request * nbc_req, int *error_ for (i = 0; i < nprocs; i++) if (recv_size[i]) { MPI_Irecv(recv_buf[i], recv_size[i], MPI_BYTE, i, - myrank + i + 100 * iter, fd->comm, vars->req2 + j); + ADIOI_COLL_TAG(i, iter), fd->comm, vars->req2 + j); j++; #ifdef RDCOLL_DEBUG DBG_FPRINTF(stderr, "node %d, recv_size %d, tag %d \n", - myrank, recv_size[i], myrank + i + 100 * iter); + myrank, recv_size[i], ADIOI_COLL_TAG(i, iter)); #endif } } @@ -1047,7 +1047,7 @@ static void ADIOI_R_Iexchange_data_recv(ADIOI_NBC_Request * nbc_req, int *error_ MPI_BYTE, &send_type); /* absolute displacement; use MPI_BOTTOM in send */ MPI_Type_commit(&send_type); - MPI_Isend(MPI_BOTTOM, 1, send_type, i, myrank + i + 100 * iter, + MPI_Isend(MPI_BOTTOM, 1, send_type, i, ADIOI_COLL_TAG(i, iter), fd->comm, vars->req2 + nprocs_recv + j); MPI_Type_free(&send_type); if (partial_send[i]) diff --git a/src/mpi/romio/adio/common/ad_iwrite_coll.c b/src/mpi/romio/adio/common/ad_iwrite_coll.c index 894be818b46..9de8447e449 100644 --- a/src/mpi/romio/adio/common/ad_iwrite_coll.c +++ b/src/mpi/romio/adio/common/ad_iwrite_coll.c @@ -1156,7 +1156,7 @@ static void ADIOI_W_Iexchange_data_send(ADIOI_NBC_Request * nbc_req, int *error_ j = 0; for (i = 0; i < nprocs; i++) { if (recv_size[i]) { - MPI_Irecv(MPI_BOTTOM, 1, recv_types[j], i, myrank + i + 100 * iter, + MPI_Irecv(MPI_BOTTOM, 1, recv_types[j], i, ADIOI_COLL_TAG(i, iter), fd->comm, vars->requests + j); j++; } @@ -1175,7 +1175,7 @@ static void ADIOI_W_Iexchange_data_send(ADIOI_NBC_Request * nbc_req, int *error_ for (i = 0; i < nprocs; i++) if (send_size[i]) { MPI_Isend(((char *) buf) + buf_idx[i], send_size[i], - MPI_BYTE, i, myrank + i + 100 * iter, fd->comm, vars->send_req + j); + MPI_BYTE, i, ADIOI_COLL_TAG(i, iter), fd->comm, vars->send_req + j); j++; buf_idx[i] += send_size[i]; } @@ -1211,7 +1211,7 @@ static void ADIOI_W_Iexchange_data_send(ADIOI_NBC_Request * nbc_req, int *error_ j = 0; for (i = 0; i < nprocs; i++) { if (recv_size[i]) { - MPI_Irecv(MPI_BOTTOM, 1, recv_types[j], i, myrank + i + 100 * iter, + MPI_Irecv(MPI_BOTTOM, 1, recv_types[j], i, ADIOI_COLL_TAG(i, iter), fd->comm, vars->req3 + j); j++; } diff --git a/src/mpi/romio/adio/common/ad_read_coll.c b/src/mpi/romio/adio/common/ad_read_coll.c index a72e5723e82..dea0668fab4 100644 --- a/src/mpi/romio/adio/common/ad_read_coll.c +++ b/src/mpi/romio/adio/common/ad_read_coll.c @@ -796,7 +796,7 @@ static void ADIOI_R_Exchange_data(ADIO_File fd, void *buf, ADIOI_Flatlist_node for (i = 0; i < nprocs; i++) { if (recv_size[i]) { MPI_Irecv(((char *) buf) + buf_idx[i], recv_size[i], - MPI_BYTE, i, myrank + i + 100 * iter, fd->comm, requests + j); + MPI_BYTE, i, ADIOI_COLL_TAG(i, iter), fd->comm, requests + j); j++; buf_idx[i] += recv_size[i]; } @@ -812,11 +812,11 @@ static void ADIOI_R_Exchange_data(ADIO_File fd, void *buf, ADIOI_Flatlist_node for (i = 0; i < nprocs; i++) { if (recv_size[i]) { MPI_Irecv(recv_buf[i], recv_size[i], MPI_BYTE, i, - myrank + i + 100 * iter, fd->comm, requests + j); + ADIOI_COLL_TAG(i, iter), fd->comm, requests + j); j++; #ifdef RDCOLL_DEBUG DBG_FPRINTF(stderr, "node %d, recv_size %d, tag %d \n", - myrank, recv_size[i], myrank + i + 100 * iter); + myrank, recv_size[i], ADIOI_COLL_TAG(i, iter)); #endif } } @@ -839,7 +839,7 @@ static void ADIOI_R_Exchange_data(ADIO_File fd, void *buf, ADIOI_Flatlist_node MPI_BYTE, &send_type); /* absolute displacement; use MPI_BOTTOM in send */ MPI_Type_commit(&send_type); - MPI_Isend(MPI_BOTTOM, 1, send_type, i, myrank + i + 100 * iter, + MPI_Isend(MPI_BOTTOM, 1, send_type, i, ADIOI_COLL_TAG(i, iter), fd->comm, requests + nprocs_recv + j); MPI_Type_free(&send_type); if (partial_send[i]) diff --git a/src/mpi/romio/adio/common/ad_write_coll.c b/src/mpi/romio/adio/common/ad_write_coll.c index d2742b12f5a..7acf06e189e 100644 --- a/src/mpi/romio/adio/common/ad_write_coll.c +++ b/src/mpi/romio/adio/common/ad_write_coll.c @@ -656,7 +656,7 @@ static void ADIOI_W_Exchange_data(ADIO_File fd, void *buf, char *write_buf, j = 0; for (i = 0; i < nprocs; i++) { if (recv_size[i]) { - MPI_Irecv(MPI_BOTTOM, 1, recv_types[j], i, myrank + i + 100 * iter, + MPI_Irecv(MPI_BOTTOM, 1, recv_types[j], i, ADIOI_COLL_TAG(i, iter), fd->comm, requests + j); j++; } @@ -675,7 +675,7 @@ static void ADIOI_W_Exchange_data(ADIO_File fd, void *buf, char *write_buf, for (i = 0; i < nprocs; i++) if (send_size[i]) { MPI_Isend(((char *) buf) + buf_idx[i], send_size[i], - MPI_BYTE, i, myrank + i + 100 * iter, fd->comm, send_req + j); + MPI_BYTE, i, ADIOI_COLL_TAG(i, iter), fd->comm, send_req + j); j++; buf_idx[i] += send_size[i]; } @@ -705,8 +705,8 @@ static void ADIOI_W_Exchange_data(ADIO_File fd, void *buf, char *write_buf, for (i = 0; i < nprocs; i++) { MPI_Status wkl_status; if (recv_size[i]) { - MPI_Recv(MPI_BOTTOM, 1, recv_types[j], i, myrank + i + 100 * iter, - fd->comm, &wkl_status); + MPI_Recv(MPI_BOTTOM, 1, recv_types[j], i, ADIOI_COLL_TAG(i, iter), fd->comm, + &wkl_status); j++; } } @@ -889,7 +889,7 @@ void ADIOI_Fill_send_buffer(ADIO_File fd, void *buf, ADIOI_Flatlist_node ADIOI_BUF_COPY} if (send_buf_idx[p] == send_size[p]) { MPI_Isend(send_buf[p], send_size[p], MPI_BYTE, p, - myrank + p + 100 * iter, fd->comm, requests + jj); + ADIOI_COLL_TAG(p, iter), fd->comm, requests + jj); jj++; } } else { @@ -905,9 +905,11 @@ void ADIOI_Fill_send_buffer(ADIO_File fd, void *buf, ADIOI_Flatlist_node rem_len -= len; } } - for (i = 0; i < nprocs; i++) - if (send_size[i]) + for (i = 0; i < nprocs; i++) { + if (send_size[i]) { sent_to_proc[i] = curr_to_proc[i]; + } + } } diff --git a/src/mpi/romio/adio/include/adio.h b/src/mpi/romio/adio/include/adio.h index 17a609443f0..4b82c793314 100644 --- a/src/mpi/romio/adio/include/adio.h +++ b/src/mpi/romio/adio/include/adio.h @@ -328,6 +328,16 @@ typedef struct { #define ADIOI_FILE_COOKIE 2487376 #define ADIOI_REQ_COOKIE 3493740 +/* In collective read/write using send/recv for data exchange in multiple iterations, + * use following tag for consistency. + */ +/* Note: originally we used the formula - myrank + rank + 100 * iter. This is not + * safe since iter can be very large for huge messages and potentially exceed tag + * limit. Since we don't really need source/dest in the tag, and the message matching + * order is guaranteed, a constant tag will do. + */ +#define ADIOI_COLL_TAG(rank,iter) 0 + /* ADIO function prototypes */ /* all these may not be necessary, as many of them are macro replaced to function pointers that point to the appropriate functions for each From 1424222e499b49146d49d7ffe2131162ac7de7ae Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 15 Nov 2021 21:58:36 -0600 Subject: [PATCH 169/607] binding/c: fix missing check in MPI_Type_create_struct We should not allow MPI_DATATYPE_NULL in MPI_Type_create_struct. --- maint/local_python/binding_c.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/maint/local_python/binding_c.py b/maint/local_python/binding_c.py index 41769c78bbb..21f27105686 100644 --- a/maint/local_python/binding_c.py +++ b/maint/local_python/binding_c.py @@ -1983,7 +1983,12 @@ def dump_validation(func, t): dump_if_open("%s > 0" % t['length']) G.out.append("MPIR_ERRTEST_ARGNULL(%s, \"%s\", mpi_errno);" % (name, name)) dump_for_open('i', t['length']) - dump_if_open("%s[i] != MPI_DATATYPE_NULL && !HANDLE_IS_BUILTIN(%s[i])" % (name, name)) + if re.match(r'mpi_type_create_struct', func_name, re.IGNORECASE): + # MPI_DATATYPE_NULL not allowed + cond = "!HANDLE_IS_BUILTIN(%s[i])" % name + else: + cond = "%s[i] != MPI_DATATYPE_NULL && !HANDLE_IS_BUILTIN(%s[i])" % (name, name) + dump_if_open(cond) G.out.append("MPIR_Datatype *datatype_ptr;") G.out.append("MPIR_Datatype_get_ptr(%s[i], datatype_ptr);" % name) G.out.append("MPIR_Datatype_valid_ptr(datatype_ptr, mpi_errno);") From 8c273451df33b5f33bd20bc2aa1e79aa497e100d Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 14 Nov 2021 22:29:09 -0600 Subject: [PATCH 170/607] romio: silence warnings in debug prints When long is the same size as long long, it is tricky to set MPI_Offset to long or long long, and the printf fmt have to adapt to avoid warnings. Add a cast to silence them. --- src/mpi/romio/adio/common/ad_read_coll.c | 6 ++--- src/mpi/romio/adio/common/flatten.c | 34 +++++++++++++++--------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/mpi/romio/adio/common/ad_read_coll.c b/src/mpi/romio/adio/common/ad_read_coll.c index dea0668fab4..495b5743240 100644 --- a/src/mpi/romio/adio/common/ad_read_coll.c +++ b/src/mpi/romio/adio/common/ad_read_coll.c @@ -339,10 +339,10 @@ void ADIOI_Calc_my_off_len(ADIO_File fd, int bufcount, MPI_Datatype #ifdef RDCOLL_DEBUG { int ii; - DBG_FPRINTF(stderr, "flattened %3lld : ", flat_file->count); + DBG_FPRINTF(stderr, "flattened %3lld : ", (long long) flat_file->count); for (ii = 0; ii < flat_file->count; ii++) { - DBG_FPRINTF(stderr, "%16lld:%-16lld", flat_file->indices[ii], - flat_file->blocklens[ii]); + DBG_FPRINTF(stderr, "%16lld:%-16lld", (long long) flat_file->indices[ii], + (long long) flat_file->blocklens[ii]); } DBG_FPRINTF(stderr, "\n"); } diff --git a/src/mpi/romio/adio/common/flatten.c b/src/mpi/romio/adio/common/flatten.c index a2b48e79764..57c3411cb34 100644 --- a/src/mpi/romio/adio/common/flatten.c +++ b/src/mpi/romio/adio/common/flatten.c @@ -128,7 +128,7 @@ ADIOI_Flatlist_node *ADIOI_Flatten_datatype(MPI_Datatype datatype) for (i = 0; i < flat->count; i++) { DBG_FPRINTF(stderr, "ADIOI_Flatten_datatype:: i %#X, blocklens %#llX, indices %#llX\n", i, - flat->blocklens[i], flat->indices[i]); + (long long) flat->blocklens[i], (long long) flat->indices[i]); } } #endif @@ -164,8 +164,8 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat, MPI_Type_get_contents(datatype, nints, nadds, ntypes, ints, adds, types); #ifdef FLATTEN_DEBUG - DBG_FPRINTF(stderr, "ADIOI_Flatten:: st_offset %#llX, curr_index %#llX\n", st_offset, - *curr_index); + DBG_FPRINTF(stderr, "ADIOI_Flatten:: st_offset %#llX, curr_index %#llX\n", + (long long) st_offset, (long long) *curr_index); DBG_FPRINTF(stderr, "ADIOI_Flatten:: nints %#X, nadds %#X, ntypes %#X\n", nints, nadds, ntypes); for (i = 0; i < nints; ++i) { DBG_FPRINTF(stderr, "ADIOI_Flatten:: ints[%lld]=%#X\n", (long long) i, ints[i]); @@ -238,13 +238,15 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat, #ifdef FLATTEN_DEBUG DBG_FPRINTF(stderr, "ADIOI_Flatten:: MPI_COMBINER_DARRAY indices[%#X] %#llX, flat->blocklens[%#X] %#llX, st_offset %#llX, curr_index %#llX);\n", - 0, flat->indices[0], 0, flat->blocklens[0], st_offset, *curr_index); + 0, (long long) flat->indices[0], 0, (long long) flat->blocklens[0], + (long long) st_offset, (long long) *curr_index); #endif ADIOI_Flatten(dtype, flat, st_offset, curr_index); #ifdef FLATTEN_DEBUG DBG_FPRINTF(stderr, "ADIOI_Flatten:: MPI_COMBINER_DARRAY >ADIOI_Flatten(dtype, flat->indices[%#X] %#llX, flat->blocklens[%#X] %#llX, st_offset %#llX, curr_index %#llX);\n", - 0, flat->indices[0], 0, flat->blocklens[0], st_offset, *curr_index); + 0, (long long) flat->indices[0], 0, (long long) flat->blocklens[0], + (long long) st_offset, (long long) *curr_index); #endif MPI_Type_free(&dtype); } @@ -272,7 +274,8 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat, #ifdef FLATTEN_DEBUG DBG_FPRINTF(stderr, "ADIOI_Flatten:: simple flat->indices[%#llX] %#llX, flat->blocklens[%#llX] %#llX\n", - j, flat->indices[j], j, flat->blocklens[j]); + (long long) j, (long long) flat->indices[j], + (long long) j, (long long) flat->blocklens[j]); #endif (*curr_index)++; } else { @@ -291,7 +294,8 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat, #ifdef FLATTEN_DEBUG DBG_FPRINTF(stderr, "ADIOI_Flatten:: derived flat->indices[%#llX] %#llX, flat->blocklens[%#llX] %#llX\n", - j, flat->indices[j], j, flat->blocklens[j]); + (long long) j, (long long) flat->indices[j], + (long long) j, (long long) flat->blocklens[j]); #endif j++; } @@ -765,7 +769,8 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat, DBG_FPRINTF(stderr, "ADIOI_Flatten:: simple old_extent " MPI_AINT_FMT_HEX_SPEC ", flat->indices[%#llX] %#llX, flat->blocklens[%#llX] %#llX\n", - old_extent, j, flat->indices[j], j, flat->blocklens[j]); + old_extent, (long long) j, (long long) flat->indices[j], + (long long) j, (long long) flat->blocklens[j]); #endif j++; } @@ -803,7 +808,8 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat, DBG_FPRINTF(stderr, "ADIOI_Flatten:: simple adds[%#X] " MPI_AINT_FMT_HEX_SPEC ", flat->indices[%#llX] %#llX, flat->blocklens[%#llX] %#llX\n", 0, - adds[0], j, flat->indices[j], j, flat->blocklens[j]); + adds[0], (long long) j, (long long) flat->indices[j], + (long long) j, (long long) flat->blocklens[j]); #endif (*curr_index)++; @@ -832,7 +838,8 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat, DBG_FPRINTF(stderr, "ADIOI_Flatten:: simple adds[%#X] " MPI_AINT_FMT_HEX_SPEC ", flat->indices[%#llX] %#llX, flat->blocklens[%#llX] %#llX\n", 0, - adds[0], j, flat->indices[j], j, flat->blocklens[j]); + adds[0], (long long) j, (long long) flat->indices[j], + (long long) j, (long long) flat->blocklens[j]); #endif (*curr_index)++; @@ -858,7 +865,8 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat, DBG_FPRINTF(stderr, "ADIOI_Flatten:: simple adds[%#X] " MPI_AINT_FMT_HEX_SPEC ", flat->indices[%#llX] %#llX, flat->blocklens[%#llX] %#llX\n", 1, adds[1], - j, flat->indices[j], j, flat->blocklens[j]); + (long long) j, (long long) flat->indices[j], + (long long) j, (long long) flat->blocklens[j]); #endif (*curr_index)++; @@ -882,8 +890,8 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat, ADIOI_Free(types); #ifdef FLATTEN_DEBUG - DBG_FPRINTF(stderr, "ADIOI_Flatten:: return st_offset %#llX, curr_index %#llX\n", st_offset, - *curr_index); + DBG_FPRINTF(stderr, "ADIOI_Flatten:: return st_offset %#llX, curr_index %#llX\n", + (long long) st_offset, (long long) *curr_index); #endif } From 9cc63dd460e0703cd3d5ae293178a3030fd88ac8 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 15 Nov 2021 20:28:52 -0600 Subject: [PATCH 171/607] romio: warning fix of unused variable This is a left over fix from PR #5660 --- src/mpi/romio/adio/common/ad_iread_coll.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/mpi/romio/adio/common/ad_iread_coll.c b/src/mpi/romio/adio/common/ad_iread_coll.c index 927ae347a7b..bacf1ad2b9b 100644 --- a/src/mpi/romio/adio/common/ad_iread_coll.c +++ b/src/mpi/romio/adio/common/ad_iread_coll.c @@ -968,9 +968,7 @@ static void ADIOI_R_Iexchange_data_recv(ADIOI_NBC_Request * nbc_req, int *error_ int *start_pos = vars->start_pos; int *partial_send = vars->partial_send; int nprocs = vars->nprocs; - int myrank = vars->myrank; ADIOI_Access *others_req = vars->others_req; - int iter = vars->iter; MPI_Aint *buf_idx = vars->buf_idx; int i, j, k = 0, tmp = 0, nprocs_recv, nprocs_send; @@ -1005,7 +1003,7 @@ static void ADIOI_R_Iexchange_data_recv(ADIOI_NBC_Request * nbc_req, int *error_ for (i = 0; i < nprocs; i++) if (recv_size[i]) { MPI_Irecv(((char *) vars->buf) + buf_idx[i], recv_size[i], - MPI_BYTE, i, ADIOI_COLL_TAG(i, iter), fd->comm, vars->req2 + j); + MPI_BYTE, i, ADIOI_COLL_TAG(i, vars->iter), fd->comm, vars->req2 + j); j++; buf_idx[i] += recv_size[i]; } @@ -1021,11 +1019,11 @@ static void ADIOI_R_Iexchange_data_recv(ADIOI_NBC_Request * nbc_req, int *error_ for (i = 0; i < nprocs; i++) if (recv_size[i]) { MPI_Irecv(recv_buf[i], recv_size[i], MPI_BYTE, i, - ADIOI_COLL_TAG(i, iter), fd->comm, vars->req2 + j); + ADIOI_COLL_TAG(i, vars->iter), fd->comm, vars->req2 + j); j++; #ifdef RDCOLL_DEBUG DBG_FPRINTF(stderr, "node %d, recv_size %d, tag %d \n", - myrank, recv_size[i], ADIOI_COLL_TAG(i, iter)); + vars->myrank, recv_size[i], ADIOI_COLL_TAG(i, vars->iter)); #endif } } @@ -1047,7 +1045,7 @@ static void ADIOI_R_Iexchange_data_recv(ADIOI_NBC_Request * nbc_req, int *error_ MPI_BYTE, &send_type); /* absolute displacement; use MPI_BOTTOM in send */ MPI_Type_commit(&send_type); - MPI_Isend(MPI_BOTTOM, 1, send_type, i, ADIOI_COLL_TAG(i, iter), + MPI_Isend(MPI_BOTTOM, 1, send_type, i, ADIOI_COLL_TAG(i, vars->iter), fd->comm, vars->req2 + nprocs_recv + j); MPI_Type_free(&send_type); if (partial_send[i]) From fa5e63b988977c415d06725af14cddacc3f2db93 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 18 Nov 2021 10:59:58 -0600 Subject: [PATCH 172/607] datatype/yaksa: fix MPI_COMPLEX8 and MPI_COMPLEX16 It was matching the wrong floating point size. --- src/mpi/datatype/typerep/src/typerep_yaksa_init.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mpi/datatype/typerep/src/typerep_yaksa_init.c b/src/mpi/datatype/typerep/src/typerep_yaksa_init.c index 56b9a89dedd..2c0813fae6b 100644 --- a/src/mpi/datatype/typerep/src/typerep_yaksa_init.c +++ b/src/mpi/datatype/typerep/src/typerep_yaksa_init.c @@ -278,22 +278,22 @@ yaksa_type_t MPII_Typerep_get_yaksa_type(MPI_Datatype type) break; case MPI_COMPLEX8: - if (sizeof(float) == 8) + if (sizeof(float) == 4) yaksa_type = YAKSA_TYPE__C_COMPLEX; - else if (sizeof(double) == 8) + else if (sizeof(double) == 4) yaksa_type = YAKSA_TYPE__C_DOUBLE_COMPLEX; - else if (sizeof(long double) == 8) + else if (sizeof(long double) == 4) yaksa_type = YAKSA_TYPE__C_LONG_DOUBLE_COMPLEX; else assert(0); break; case MPI_COMPLEX16: - if (sizeof(float) == 16) + if (sizeof(float) == 8) yaksa_type = YAKSA_TYPE__C_COMPLEX; - else if (sizeof(double) == 16) + else if (sizeof(double) == 8) yaksa_type = YAKSA_TYPE__C_DOUBLE_COMPLEX; - else if (sizeof(long double) == 16) + else if (sizeof(long double) == 8) yaksa_type = YAKSA_TYPE__C_LONG_DOUBLE_COMPLEX; else assert(0); From d11488ad388ceacaa9b068490d374c8adee00223 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 12 Nov 2021 22:05:45 -0600 Subject: [PATCH 173/607] xfail: fix typos The .* was accidentally omitted during previous commit 01dc636df7b378132125141f7f6ad4208323e2a5. --- test/mpi/maint/jenkins/xfail.conf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/mpi/maint/jenkins/xfail.conf b/test/mpi/maint/jenkins/xfail.conf index b7dbac1fe40..6a37f715b00 100644 --- a/test/mpi/maint/jenkins/xfail.conf +++ b/test/mpi/maint/jenkins/xfail.conf @@ -94,11 +94,11 @@ * * * ch3:tcp * /^mt_iprobe_isendrecv/ xfail=issue4258 test/mpi/threads/pt2pt/testlist * * * ch3:tcp * /^mt_improbe_isendrecv/ xfail=issue4258 test/mpi/threads/pt2pt/testlist # pingping tests with large testsize currently fails async tests due to netmod handling of large message queue -* * async * * /^pingpingtestsize=32.*/ xfail=issue4474 test/mpi/pt2pt/testlist.dtp +* * async * * /^pingping .*testsize=32/ xfail=issue4474 test/mpi/pt2pt/testlist.dtp # dup_leak_test suffers from mutex unfairness issue under load for ch4:ofi -* * * ch4:ofi * /^dup_leak_testiter=12345.*/ xfail=issue4595 test/mpi/threads/comm/testlist +* * * ch4:ofi * /^dup_leak_test .*iter=12345.*/ xfail=issue4595 test/mpi/threads/comm/testlist # more mutex unfairness on freebsd64. note: check these after upgrading freebsd64 hardware -* * * ch4:ofi freebsd64 /^dup_leak_testiter=1234.*/ xfail=issue4595 test/mpi/threads/comm/testlist +* * * ch4:ofi freebsd64 /^dup_leak_test .*iter=1234.*/ xfail=issue4595 test/mpi/threads/comm/testlist * * * ch4:ofi freebsd64 /^alltoall/ xfail=issue4595 test/mpi/threads/pt2pt/testlist # release-gather algorithm won't work with multithread * * async * * /^.*_ALGORITHM=release_gather.*/ xfail=ticket0 test/mpi/coll/testlist.cvar From a2d7634b5ed8014ac4f8bba4469d05a7b386dc6c Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 13 Nov 2021 11:36:37 -0600 Subject: [PATCH 174/607] test: make xfail script work from test/mpi Currently we autoconf test/mpi from mpich top directory. Make the xfail scripts also work inside test/mpi/ so that we can autoconf and apply xfail from test/mpi as well. --- test/mpi/maint/jenkins/set_xfail.py | 3 + test/mpi/maint/jenkins/xfail.conf | 118 ++++++++++++++-------------- 2 files changed, 62 insertions(+), 59 deletions(-) diff --git a/test/mpi/maint/jenkins/set_xfail.py b/test/mpi/maint/jenkins/set_xfail.py index 93d38c01419..13ce6bb44cd 100644 --- a/test/mpi/maint/jenkins/set_xfail.py +++ b/test/mpi/maint/jenkins/set_xfail.py @@ -19,6 +19,8 @@ def search(pat, str, flags=0): def main(): parse_args() load_xfail_conf() + if os.path.exists('test/mpi'): + os.chdir('test/mpi') apply_xfails() # ---- subroutines -------------------------------------------- @@ -76,6 +78,7 @@ def load_xfail_conf(): elif RE.match(r'\s*(.*?)\s*\/(.*)\/\s*xfail=(\w*)\s*(\S+)\s*$', line): # -- new direct pattern cond, pat, reason, testlist = RE.m.group(1, 2, 3, 4) + testlist = re.sub(r'^test\/mpi\/', '', testlist) if match_states(cond, G.states): cond = re.sub(r'\s\s+', ' ', cond) if testlist not in G.xfails: diff --git a/test/mpi/maint/jenkins/xfail.conf b/test/mpi/maint/jenkins/xfail.conf index 6a37f715b00..a5060ba6f02 100644 --- a/test/mpi/maint/jenkins/xfail.conf +++ b/test/mpi/maint/jenkins/xfail.conf @@ -31,85 +31,85 @@ ################################################################################ # xfail ch4 bugs -* * * ch4:ofi * /^idup_comm_gen/ xfail=ticket3794 test/mpi/threads/comm/testlist -* * * ch4:ofi * /^idup_nb/ xfail=ticket3794 test/mpi/threads/comm/testlist -* * * ch4:ucx * /^idup_comm_gen/ xfail=ticket3794 test/mpi/threads/comm/testlist -* * * ch4:ucx * /^idup_nb/ xfail=ticket3794 test/mpi/threads/comm/testlist +* * * ch4:ofi * /^idup_comm_gen/ xfail=ticket3794 threads/comm/testlist +* * * ch4:ofi * /^idup_nb/ xfail=ticket3794 threads/comm/testlist +* * * ch4:ucx * /^idup_comm_gen/ xfail=ticket3794 threads/comm/testlist +* * * ch4:ucx * /^idup_nb/ xfail=ticket3794 threads/comm/testlist ################################################################################ # misc special build -* * nofast * * /^large_acc_flush_local/ xfail=issue4663 test/mpi/rma/testlist +* * nofast * * /^large_acc_flush_local/ xfail=issue4663 rma/testlist #ch3:ofi -* * * ch3:ofi * /^manyget/ xfail=ticket0 test/mpi/rma/testlist -* * * ch3:ofi * /^manyrma2/ xfail=ticket0 test/mpi/rma/testlist -* * * ch3:ofi * /^manyrma2_shm/ xfail=ticket0 test/mpi/rma/testlist +* * * ch3:ofi * /^manyget/ xfail=ticket0 rma/testlist +* * * ch3:ofi * /^manyrma2/ xfail=ticket0 rma/testlist +* * * ch3:ofi * /^manyrma2_shm/ xfail=ticket0 rma/testlist ################################################################################ -* * * * osx /^throwtest/ xfail=ticket0 test/mpi/errors/cxx/errhan/testlist -* * * * osx /^commerrx/ xfail=ticket0 test/mpi/errors/cxx/errhan/testlist -* * * * osx /^fileerrretx/ xfail=ticket0 test/mpi/errors/cxx/io/testlist -* * * * osx /^throwtestfilex/ xfail=ticket0 test/mpi/errors/cxx/io/testlist -* gnu debug ch3:tcp osx /^namepubx/ xfail=issue3506 test/mpi/cxx/spawn/testlist -* intel * * osx /^statusesf08/ xfail=issue4374 test/mpi/f08/pt2pt/testlist -* intel * * osx /^vw_inplacef08/ xfail=issue4374 test/mpi/f08/coll/testlist -* intel * * osx /^red_scat_blockf08/ xfail=issue4374 test/mpi/f08/coll/testlist -* intel * * osx /^nonblocking_inpf08/ xfail=issue4374 test/mpi/f08/coll/testlist -* intel * * osx /^structf/ xfail=issue4374 test/mpi/f08/datatype/testlist -* intel * * osx /^aintf08/ xfail=issue4374 test/mpi/f08/rma/testlist -* intel * * osx /^dgraph_unwgtf90/ xfail=issue4374 test/mpi/f08/topo/testlist +* * * * osx /^throwtest/ xfail=ticket0 errors/cxx/errhan/testlist +* * * * osx /^commerrx/ xfail=ticket0 errors/cxx/errhan/testlist +* * * * osx /^fileerrretx/ xfail=ticket0 errors/cxx/io/testlist +* * * * osx /^throwtestfilex/ xfail=ticket0 errors/cxx/io/testlist +* gnu debug ch3:tcp osx /^namepubx/ xfail=issue3506 cxx/spawn/testlist +* intel * * osx /^statusesf08/ xfail=issue4374 f08/pt2pt/testlist +* intel * * osx /^vw_inplacef08/ xfail=issue4374 f08/coll/testlist +* intel * * osx /^red_scat_blockf08/ xfail=issue4374 f08/coll/testlist +* intel * * osx /^nonblocking_inpf08/ xfail=issue4374 f08/coll/testlist +* intel * * osx /^structf/ xfail=issue4374 f08/datatype/testlist +* intel * * osx /^aintf08/ xfail=issue4374 f08/rma/testlist +* intel * * osx /^dgraph_unwgtf90/ xfail=issue4374 f08/topo/testlist ################################################################################ # xfail large count tests on 32 bit architectures (cannot allocate such large memory) -* * * * freebsd32 /^getfence1 [0-9]* arg=-type=.* arg=-count=16000000/ xfail=ticket0 test/mpi/rma/testlist.dtp -* * * * freebsd32 /^putfence1 [0-9]* arg=-type=.* arg=-count=16000000/ xfail=ticket0 test/mpi/rma/testlist.dtp -* * * * ubuntu32 /^getfence1 [0-9]* arg=-type=.* arg=-count=16000000/ xfail=ticket0 test/mpi/rma/testlist.dtp -* * * * ubuntu32 /^putfence1 [0-9]* arg=-type=.* arg=-count=16000000/ xfail=ticket0 test/mpi/rma/testlist.dtp +* * * * freebsd32 /^getfence1 [0-9]* arg=-type=.* arg=-count=16000000/ xfail=ticket0 rma/testlist.dtp +* * * * freebsd32 /^putfence1 [0-9]* arg=-type=.* arg=-count=16000000/ xfail=ticket0 rma/testlist.dtp +* * * * ubuntu32 /^getfence1 [0-9]* arg=-type=.* arg=-count=16000000/ xfail=ticket0 rma/testlist.dtp +* * * * ubuntu32 /^putfence1 [0-9]* arg=-type=.* arg=-count=16000000/ xfail=ticket0 rma/testlist.dtp # intercomm abort test are expected to fail since MPI_Finalize will try to perform Allreduce on all process (includeing the aborted ones) -* * * * * /^intercomm_abort/ xfail=ticket0 test/mpi/errors/comm/testlist +* * * * * /^intercomm_abort/ xfail=ticket0 errors/comm/testlist # asan glitches with ucx for large buffer (when greater than ~1GB) -* * asan ch4:ucx * /^.*262144\|65530\|16000000.*/ xfail=ticket0 test/mpi/coll/testlist.dtp -* * asan ch4:ucx * /^.*262144\|65530\|16000000.*/ xfail=ticket0 test/mpi/pt2pt/testlist.dtp -* * asan ch4:ucx * /^.*262144\|65530\|16000000.*/ xfail=ticket0 test/mpi/rma/testlist.dtp +* * asan ch4:ucx * /^.*262144\|65530\|16000000.*/ xfail=ticket0 coll/testlist.dtp +* * asan ch4:ucx * /^.*262144\|65530\|16000000.*/ xfail=ticket0 pt2pt/testlist.dtp +* * asan ch4:ucx * /^.*262144\|65530\|16000000.*/ xfail=ticket0 rma/testlist.dtp # Bug - Github Issue https://github.com/pmodels/mpich/issues/3618 -* * * ch4:ucx * /^darray_pack/ xfail=ticket0 test/mpi/datatype/testlist +* * * ch4:ucx * /^darray_pack/ xfail=ticket0 datatype/testlist # Collectivess other than bcast don't currently detect mismatched datatype lengths -* * * * * /^reducelength/ xfail=ticket3655 test/mpi/errors/coll/testlist -* * * * * /^ireducelength/ xfail=ticket3655 test/mpi/errors/coll/testlist -* * * * * /^allreducelength/ xfail=ticket3655 test/mpi/errors/coll/testlist -* * * * * /^iallreducelength/ xfail=ticket3655 test/mpi/errors/coll/testlist -* * * * * /^reduceop/ xfail=ticket3655 test/mpi/errors/coll/testlist -* * * * * /^ireduceop/ xfail=ticket3655 test/mpi/errors/coll/testlist -* * * * * /^gatherlength/ xfail=ticket3655 test/mpi/errors/coll/testlist -* * * * * /^igatherlength/ xfail=ticket3655 test/mpi/errors/coll/testlist -* * * * * /^allgatherlength/ xfail=ticket3655 test/mpi/errors/coll/testlist -* * * * * /^iallgatherlength/ xfail=ticket3655 test/mpi/errors/coll/testlist -* * * * * /^alltoalllength/ xfail=ticket3655 test/mpi/errors/coll/testlist -* * * * * /^ialltoalllength/ xfail=ticket3655 test/mpi/errors/coll/testlist -* * * * * /^scatterlength/ xfail=ticket3655 test/mpi/errors/coll/testlist -* * * * * /^iscatterlength/ xfail=ticket3655 test/mpi/errors/coll/testlist +* * * * * /^reducelength/ xfail=ticket3655 errors/coll/testlist +* * * * * /^ireducelength/ xfail=ticket3655 errors/coll/testlist +* * * * * /^allreducelength/ xfail=ticket3655 errors/coll/testlist +* * * * * /^iallreducelength/ xfail=ticket3655 errors/coll/testlist +* * * * * /^reduceop/ xfail=ticket3655 errors/coll/testlist +* * * * * /^ireduceop/ xfail=ticket3655 errors/coll/testlist +* * * * * /^gatherlength/ xfail=ticket3655 errors/coll/testlist +* * * * * /^igatherlength/ xfail=ticket3655 errors/coll/testlist +* * * * * /^allgatherlength/ xfail=ticket3655 errors/coll/testlist +* * * * * /^iallgatherlength/ xfail=ticket3655 errors/coll/testlist +* * * * * /^alltoalllength/ xfail=ticket3655 errors/coll/testlist +* * * * * /^ialltoalllength/ xfail=ticket3655 errors/coll/testlist +* * * * * /^scatterlength/ xfail=ticket3655 errors/coll/testlist +* * * * * /^iscatterlength/ xfail=ticket3655 errors/coll/testlist # some of the bcastlength test that is still failing -* * * ch3:ofi * /^ibcastlength/ xfail=issue3775 test/mpi/errors/coll/testlist -* * * ch3:ofi * /^bcastlength/ xfail=issue4373 test/mpi/errors/coll/testlist +* * * ch3:ofi * /^ibcastlength/ xfail=issue3775 errors/coll/testlist +* * * ch3:ofi * /^bcastlength/ xfail=issue4373 errors/coll/testlist # hwloc is unable to detect topology info on FreeBSD in strict mode with GCC -* gnu strict * freebsd64 /^cmsplit_type/ xfail=ticket3972 test/mpi/comm/testlist -* gnu strict * freebsd32 /^cmsplit_type/ xfail=ticket3972 test/mpi/comm/testlist +* gnu strict * freebsd64 /^cmsplit_type/ xfail=ticket3972 comm/testlist +* gnu strict * freebsd32 /^cmsplit_type/ xfail=ticket3972 comm/testlist # multi-threading tests failing for ch3 freebsd64 -* * * ch3:tcp * /^mt_iprobe_isendrecv/ xfail=issue4258 test/mpi/threads/pt2pt/testlist -* * * ch3:tcp * /^mt_improbe_isendrecv/ xfail=issue4258 test/mpi/threads/pt2pt/testlist +* * * ch3:tcp * /^mt_iprobe_isendrecv/ xfail=issue4258 threads/pt2pt/testlist +* * * ch3:tcp * /^mt_improbe_isendrecv/ xfail=issue4258 threads/pt2pt/testlist # pingping tests with large testsize currently fails async tests due to netmod handling of large message queue -* * async * * /^pingping .*testsize=32/ xfail=issue4474 test/mpi/pt2pt/testlist.dtp +* * async * * /^pingping .*testsize=32/ xfail=issue4474 pt2pt/testlist.dtp # dup_leak_test suffers from mutex unfairness issue under load for ch4:ofi -* * * ch4:ofi * /^dup_leak_test .*iter=12345.*/ xfail=issue4595 test/mpi/threads/comm/testlist +* * * ch4:ofi * /^dup_leak_test .*iter=12345.*/ xfail=issue4595 threads/comm/testlist # more mutex unfairness on freebsd64. note: check these after upgrading freebsd64 hardware -* * * ch4:ofi freebsd64 /^dup_leak_test .*iter=1234.*/ xfail=issue4595 test/mpi/threads/comm/testlist -* * * ch4:ofi freebsd64 /^alltoall/ xfail=issue4595 test/mpi/threads/pt2pt/testlist +* * * ch4:ofi freebsd64 /^dup_leak_test .*iter=1234.*/ xfail=issue4595 threads/comm/testlist +* * * ch4:ofi freebsd64 /^alltoall/ xfail=issue4595 threads/pt2pt/testlist # release-gather algorithm won't work with multithread -* * async * * /^.*_ALGORITHM=release_gather.*/ xfail=ticket0 test/mpi/coll/testlist.cvar +* * async * * /^.*_ALGORITHM=release_gather.*/ xfail=ticket0 coll/testlist.cvar # freebsd failures -* * debug ch3:tcp freebsd64 /^comm_create_group_threads/ xfail=issue4372 test/mpi/threads/comm/testlist +* * debug ch3:tcp freebsd64 /^comm_create_group_threads/ xfail=issue4372 threads/comm/testlist # timeout due to lack of passive progress -* * vci ch4:ofi * /^rma_contig.*iter=10000/ xfail=issue5565 test/mpi/rma/testlist +* * vci ch4:ofi * /^rma_contig.*iter=10000/ xfail=issue5565 rma/testlist # Job-sepecific xfails # Our Arm servers are too slow for some tests -mpich-main-arm.* * * * * /^sendflood / xfail=ticket0 test/mpi/pt2pt/testlist -mpich-main-arm.* * * * * /^nonblocking3 / xfail=ticket0 test/mpi/coll/testlist -mpich-main-arm.* * * * * /^alltoall / xfail=ticket0 test/mpi/threads/pt2pt/testlist +mpich-main-arm.* * * * * /^sendflood / xfail=ticket0 pt2pt/testlist +mpich-main-arm.* * * * * /^nonblocking3 / xfail=ticket0 coll/testlist +mpich-main-arm.* * * * * /^alltoall / xfail=ticket0 threads/pt2pt/testlist From a0b70933acfcb5d12e92a9567df54d6bcc6e5390 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 14 Nov 2021 16:35:55 -0600 Subject: [PATCH 175/607] config: do not probe fortran compiler if --disable-fortran Some build system, e.g. spack, uses fake fortran compiler and even probing it with AC_PROG_FC may end up turning off the shared library option from libtool. Both spack and libtool can do something to fix this behavior, but let's see if we can simply clean it here. --- configure.ac | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/configure.ac b/configure.ac index f1ab2ef609d..e99a4cde275 100644 --- a/configure.ac +++ b/configure.ac @@ -697,10 +697,6 @@ AS_IF([test "x$enable_fc" = "xno"],[FC=no]) : ${CXXFLAGS=""} AC_PROG_CXX -# suppress default "-g -O2" from AC_PROG_FC -: ${FCFLAGS=""} -AC_PROG_FC - enable_f77=no enable_fc=no case "$enable_fortran" in @@ -715,22 +711,29 @@ case "$enable_fortran" in ;; esac -# HACK, use $FC as F77. We should remove all the F77 usages. -if test "$enable_fc" = "yes" ; then - F77=$FC - if test ! -z "$FCFLAGS" ; then - FFLAGS=$FCFLAGS - fi -fi +if test "$enable_fortran" != "no" ; then + # suppress default "-g -O2" from AC_PROG_FC + : ${FCFLAGS=""} + AC_PROG_FC + + # HACK, use $FC as F77. We should remove all the F77 usages. + if test "$enable_fc" = "yes" ; then + F77=$FC + if test ! -z "$FCFLAGS" ; then + FFLAGS=$FCFLAGS + fi + fi -AM_CONDITIONAL([INSTALL_MPIF77],[test "$F77" != "$FC" -a "$FFLAGS" != "$FCFLAGS"]) + # This needs to come after we've potentially set F77=$FC. Otherwise, we could + # override the user's Fortran compiler selection when only specifying FC at configure + # time, as is allowed. + # suppress default "-g -O2" from AC_PROG_F77 + : ${FFLAGS=""} + AC_PROG_F77 + +fi -# This needs to come after we've potentially set F77=$FC. Otherwise, we could -# override the user's Fortran compiler selection when only specifying FC at configure -# time, as is allowed. -# suppress default "-g -O2" from AC_PROG_F77 -: ${FFLAGS=""} -AC_PROG_F77 +AM_CONDITIONAL([INSTALL_MPIF77],[test "$enable_fc" = "yes" -a "$F77" != "$FC" -a "$FFLAGS" != "$FCFLAGS"]) # compute canonical system types AC_CANONICAL_BUILD From 68e04a340967c5c43f45597f21c739bc140c085a Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 17 Nov 2021 08:07:20 -0600 Subject: [PATCH 176/607] test/config: remove enable-fortran sub options We only accept --enable-fortran/--disable-fortran now. --- test/mpi/configure.ac | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index c43ae862877..597bb092952 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -99,11 +99,8 @@ AC_ARG_ENABLE(echo, AC_ARG_ENABLE(fortran, [ --enable-fortran=option - Control the level of Fortran support in the MPICH implementation. yes|all - Enable all available Fortran implementations (F77, F90, F08) - f77 - Enable Fortran 77 support - f90 - Enable Fortran 90 support - f08 - Enable Fortran 2008 support no|none - No Fortran support -],,[enable_fortran=f77,f90]) +],,[enable_fortran=all]) save_IFS="$IFS" IFS="," @@ -122,15 +119,6 @@ for option in $enable_fortran ; do enable_fc=no enable_f08=no ;; - f77) - enable_f77=yes - ;; - f90) - enable_fc=yes - ;; - f08) - enable_f08=yes - ;; *) IFS="$save_IFS" AC_MSG_WARN([Unknown value $option for --enable-fortran]) From 1e0bae70d857dd767613c7139965fc5b029c8366 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 14 Nov 2021 21:32:02 -0600 Subject: [PATCH 177/607] test: f08/init/baseenvf90 to account for MPI version 4 --- test/mpi/f08/init/baseenvf90.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/mpi/f08/init/baseenvf90.f90 b/test/mpi/f08/init/baseenvf90.f90 index a78d7e19c1f..c7cfeeb1a6f 100644 --- a/test/mpi/f08/init/baseenvf90.f90 +++ b/test/mpi/f08/init/baseenvf90.f90 @@ -44,7 +44,7 @@ program main & MPI_SUBVERSION print *, 'Version in get_version is ', iv, '.', isubv endif - if (iv .lt. 1 .or. iv .gt. 3) then + if (iv .lt. 1 .or. iv .gt. 4) then errs = errs + 1 print *, 'Version of MPI is invalid (=', iv, ')' endif From 6fc06471cd870a74b0b293f2fc53bf50ec408bb1 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 14 Nov 2021 22:00:13 -0600 Subject: [PATCH 178/607] configure: fix use of SIZEOF_F77_INTEGER SIZEOF_F77_INTEGER is no longer set. Use pac_cv_f77_sizeof_integer instead. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index e99a4cde275..4bf6edab20c 100644 --- a/configure.ac +++ b/configure.ac @@ -3004,7 +3004,7 @@ if test "$enable_f77" = yes ; then fi # Include a defined value for Fint is int - if test "$SIZEOF_F77_INTEGER" == "$ac_cv_sizeof_int" ; then + if test "$pac_cv_f77_sizeof_integer" == "$ac_cv_sizeof_int" ; then AC_DEFINE(HAVE_FINT_IS_INT,1,[Define if Fortran integer are the same size as C ints]) else AC_MSG_WARN([Fortran integers and C ints are not the same size. Support for this case is experimental; use at your own risk]) @@ -4207,7 +4207,7 @@ if test "$f08_works" = "yes" ; then if test "$enable_romio" = "no" ; then cmd="$cmd -no-mpiio" fi - cmd="$cmd -fint-size=$SIZEOF_F77_INTEGER -aint-size=$MPI_SIZEOF_AINT -count-size=$MPI_SIZEOF_COUNT -cint-size=$ac_cv_sizeof_int" + cmd="$cmd -fint-size=$pac_cv_f77_sizeof_integer -aint-size=$MPI_SIZEOF_AINT -count-size=$MPI_SIZEOF_COUNT -cint-size=$ac_cv_sizeof_int" AC_CONFIG_COMMANDS([gen_binding_f08], [$cmd_gen_binding_f08], [cmd_gen_binding_f08="$cmd"]) fi From 4b902113c231d96dfc3235b8898224d75b88f804 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 14 Nov 2021 22:09:54 -0600 Subject: [PATCH 179/607] binding/f08: fix alltoallv with MPI_IN_PLACE The same hack for fixing alltoallw will also apply to alltoallv when MPI_Fint and C int is not the same size. --- maint/local_python/binding_f08.py | 35 ++++++++++++++++++------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/maint/local_python/binding_f08.py b/maint/local_python/binding_f08.py index a1ea86bf79e..d7905277da4 100644 --- a/maint/local_python/binding_f08.py +++ b/maint/local_python/binding_f08.py @@ -173,7 +173,7 @@ def dump_f08_wrappers_f(func, is_large): has_comm_size = False # arrays of length = comm_size status_var = "" status_count = "" - is_alltoallw = False + is_alltoallvw = False if need_cdesc(func): f08ts_name = get_f08ts_name(func, is_large) @@ -189,28 +189,33 @@ def dump_f08_wrappers_f(func, is_large): arg_list_2.append("c_null_ptr") arg_list_2.append("c_null_ptr") uses['c_null_ptr'] = 1 - elif RE.match(r'mpi_i?alltoallw', func['name'], re.IGNORECASE): - # Need check MPI_IN_PLACE in order to skip sendtypes array - is_alltoallw = True + elif RE.match(r'mpi_i?alltoall[vw]', func['name'], re.IGNORECASE): + # Need check MPI_IN_PLACE in order to skip accessing sender arrays + is_alltoallvw = True uses['c_loc'] = 1 uses['c_associated'] = 1 uses['MPI_IN_PLACE'] = 1 # alltoallw inplace hack (since it is a corner case) - def dump_alltoallw_inplace(arg_list_1, arg_list_2, convert_list_2): + def dump_alltoallvw_inplace(arg_list_1, arg_list_2, convert_list_2): # cannot use like sendcounts(1:length) if G.opts['fint-size'] == G.opts['cint-size']: - send_args = "sendbuf, sendcounts, sdispls, sendtypes(1:1)%MPI_VAL" - args1 = send_args + ", " + ', '.join(arg_list_1[4:]) + if re.match(r'mpi_i?alltoallw', func['name'], re.IGNORECASE): + send_args = "sendbuf, sendcounts, sdispls, sendtypes(1:1)%MPI_VAL" + args1 = send_args + ", " + ', '.join(arg_list_1[4:]) + else: + # alltoallv is fine + args1 = ', '.join(arg_list_1) dump_fortran_line("ierror_c = %s(%s)" % (c_func_name, args1)) else: args2 = ', '.join(arg_list_2) G.out.append("sendcounts_c = sendcounts(1:1)") - G.out.append("sdispls_c = sdispls_c(1:1)") - G.out.append("sendtypes_c = sendtypes(1:1)%MPI_VAL") + G.out.append("sdispls_c = sdispls(1:1)") G.out.append("recvcounts_c = recvcounts(1:length)") - G.out.append("rdispls_c = rdispls_c(1:length)") - G.out.append("recvtypes_c = recvtypes(1:length)%MPI_VAL") + G.out.append("rdispls_c = rdispls(1:length)") + if re.match(r'mpi_i?alltoallw', func['name'], re.IGNORECASE): + G.out.append("sendtypes_c = sendtypes(1:1)%MPI_VAL") + G.out.append("recvtypes_c = recvtypes(1:length)%MPI_VAL") dump_fortran_line("ierror_c = %s(%s)" % (c_func_name, args2)) G.out.extend(convert_list_2) @@ -590,7 +595,7 @@ def post_string_len(v): has_attribute_val = True f_param_list.append(p['name']) f_decl = get_F_decl(p, f08_mapping) - if is_alltoallw and p['name'] == 'sendbuf': + if is_alltoallvw and p['name'] == 'sendbuf': f_decl = re.sub(r' ::', ', TARGET ::', f_decl) f_decl_list.append(f_decl) check_decl_uses(f_decl, uses) @@ -703,9 +708,9 @@ def dump_call(s, check_int_kind): else: ret = 'res' - if is_alltoallw: + if is_alltoallvw: dump_F_if_open("c_associated(c_loc(sendbuf), c_loc(MPI_IN_PLACE))") - dump_alltoallw_inplace(arg_list_1, arg_list_2, convert_list_2) + dump_alltoallvw_inplace(arg_list_1, arg_list_2, convert_list_2) dump_F_else() if need_check_int_kind and G.opts['fint-size'] == G.opts['cint-size']: dump_call("%s = %s(%s)" % (ret, c_func_name, ', '.join(arg_list_1)), False) @@ -714,7 +719,7 @@ def dump_call(s, check_int_kind): dump_call("%s = %s(%s)" % (ret, c_func_name, ', '.join(arg_list_2)), True) G.out.extend(convert_list_2) - if is_alltoallw: + if is_alltoallvw: dump_F_if_close() G.out.append("") From 8bda3e650b11ab55fc2bf413536f48188b3c7432 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 15 Nov 2021 08:35:10 -0600 Subject: [PATCH 180/607] binding/f08: fix checking POLY interface The previous patch to detect real poly kinds was bugged. Apparently the f08 interface was not tested in regular CI tests. --- maint/local_python/binding_f08.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/maint/local_python/binding_f08.py b/maint/local_python/binding_f08.py index d7905277da4..34b79508def 100644 --- a/maint/local_python/binding_f08.py +++ b/maint/local_python/binding_f08.py @@ -1575,16 +1575,19 @@ def get_int_type(fortran_type): elif "MPI_COUNT_KIND" in fortran_type: return "count" else: - raise Exception("Unrecognized POLY type") + raise Exception("Unrecognized POLY int type: %s" % fortran_type) small_map = G.MAPS['SMALL_F08_KIND_MAP'] large_map = G.MAPS['BIG_F08_KIND_MAP'] for kind in small_map: - if small_map[kind].startswith('POLY'): + if kind == 'POLYFUNCTION': + # TODO: potentially tricky. Might be easier to treat individual function case by case. + G.real_poly_kinds[kind] = 1 + elif kind.startswith('POLY'): a = get_int_type(small_map[kind]) + "-size" b = get_int_type(large_map[kind]) + "-size" if G.opts[a] != G.opts[b]: - G.real_poly_kinds['kind'] = 1 + G.real_poly_kinds[kind] = 1 def function_has_real_POLY_parameters(func): for p in func['parameters']: From 76957ff9408fc6a50cac7bd730bab409a6938db4 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Fri, 19 Nov 2021 14:59:54 -0600 Subject: [PATCH 181/607] xfail: Update xfail.conf comment This file is now processed by a new script, and the format has been changed and extended over time. Update the comment to reflect those changes. --- test/mpi/maint/jenkins/xfail.conf | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/test/mpi/maint/jenkins/xfail.conf b/test/mpi/maint/jenkins/xfail.conf index a5060ba6f02..08d67cfe83f 100644 --- a/test/mpi/maint/jenkins/xfail.conf +++ b/test/mpi/maint/jenkins/xfail.conf @@ -1,31 +1,27 @@ # Contitional XFAIL settings # # Syntax (similar to a cron file): -# [jobname] [compiler] [jenkins_configure] [netmod] [queue] [sed of XFAIL] +# [jobname] [compiler] [jenkins_configure] [netmod] [queue] [regex] [ticket reference] [testlist] # Note that the [jobname] allows partial matches (see examples). Other -# conditions only allows exact matches. +# conditions only allow exact matches. # The actual allowed combinations are depending on the Jenkins job. For # example, -# ofi * * tcp * sed -i "..." +# ofi * * tcp * /.../ # will have no effect since none of the ofi jobs has tcp netmod in the # configuration. # # Examples: -# tcp gnu debug * * sed -i "..." -# This will apply the set the XFAIL when the job is "mpich-main-tcp" or +# tcp gnu debug * * /.../ +# This will apply the XFAIL when the job is "mpich-main-tcp" or # "mpich-review-tcp", the compiler is "gnu", and the jenkins_configure is # "debug". # -# main-ubuntu * * * ubuntu32 sed -i "..." +# main-ubuntu * * * ubuntu32 /.../ # This will apply the set the XFAIL when the job is "mpich-main-ubuntu" and # the running queue is "ubuntu32". # -# Important note: -# Always use `sed` in this configuration. The `set-xfail.zsh` script will -# replace `sed` with `gsed`. -# -# For each build, all applied XFAILS will be summaried in -# ${SOURCE}/apply-xfail.sh +# For each build, set_xfail.py will summarize all applied XFAILS in the +# console log. # ################################################################################ From ce07bf5be6e0344c538fab022942a0fc45040634 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 23 Nov 2021 13:41:47 -0600 Subject: [PATCH 182/607] github: Add CODEOWNERS file Add initial CODEOWNERS file that sets @pmodels/mpich-intel as owner for collective frameworks initially contributed by the Intel team. Pull requests to this code, or any code with an owner specified, will automatically request a review from said owner(s). The overall intention is for code owners to have the authority to accept or reject code changes based on whatever criteria they prefer, with some exceptions. For example, security or licensing issues may result in changes to the code by the core MPICH team without involvement of the code owner. --- .github/CODEOWNERS | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000000..561b0795260 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,4 @@ +# The Intel MPICH team is primarily responsible for the collective TSP +# and algorithm frameworks. +/src/mpi/coll/algorithms/ @pmodels/mpich-intel +/src/mpi/coll/transports/ @pmodels/mpich-intel From 2cd3a6713e804f6d4a5e1ba1caf2a9ce9090eafc Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Wed, 24 Nov 2021 09:35:02 -0600 Subject: [PATCH 183/607] ch4: Only unmap memory allocated with mmap In the allocation path, we may use either MPL_mmap or MPL_malloc, but the free path always used MPL_munmap. Add a similar branch in the free logic to call MPL_free when appropriate. --- src/mpid/ch4/src/ch4_init.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mpid/ch4/src/ch4_init.c b/src/mpid/ch4/src/ch4_init.c index ed5965fe3df..cd7d45a70ad 100644 --- a/src/mpid/ch4/src/ch4_init.c +++ b/src/mpid/ch4/src/ch4_init.c @@ -726,7 +726,11 @@ int MPID_Free_mem(void *user_buf) switch (container->buf_type) { case ALLOC_MEM_BUF_TYPE__HBM: case ALLOC_MEM_BUF_TYPE__DDR: +#ifdef MAP_ANON MPL_munmap(container->real_buf, container->size, MPL_MEM_USER); +#else + MPL_free(container->real_buf, MPL_MEM_USER); +#endif break; case ALLOC_MEM_BUF_TYPE__NETMOD: From db0abb8732beef54f2d5735b129f8faa7ab8a195 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Mon, 29 Nov 2021 10:44:02 -0600 Subject: [PATCH 184/607] github: Use intel-reviewers team instead of mpich-intel It seems CODEOWNERS need write permissions in order to function correctly. We have created a sub team of the mpich-intel team specifically for use in CODEOWNERS. --- .github/CODEOWNERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 561b0795260..03450f1dc86 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,4 +1,4 @@ # The Intel MPICH team is primarily responsible for the collective TSP # and algorithm frameworks. -/src/mpi/coll/algorithms/ @pmodels/mpich-intel -/src/mpi/coll/transports/ @pmodels/mpich-intel +/src/mpi/coll/algorithms/ @pmodels/intel-reviewers +/src/mpi/coll/transports/ @pmodels/intel-reviewers From aea70bdabb413e7c6d7e295933061510e29b62d1 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 25 Nov 2021 16:41:02 -0600 Subject: [PATCH 185/607] f08: disable generic interface for POLYFUNCTION Fortran is not able to differentiate generic interfaces based on different function callback signatures. Disable for now. --- maint/local_python/binding_f08.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/maint/local_python/binding_f08.py b/maint/local_python/binding_f08.py index 34b79508def..ee4fa7fab9b 100644 --- a/maint/local_python/binding_f08.py +++ b/maint/local_python/binding_f08.py @@ -1581,8 +1581,11 @@ def get_int_type(fortran_type): large_map = G.MAPS['BIG_F08_KIND_MAP'] for kind in small_map: if kind == 'POLYFUNCTION': - # TODO: potentially tricky. Might be easier to treat individual function case by case. - G.real_poly_kinds[kind] = 1 + # Currently there are only two: MPI_User_function, MPI_Datarep_conversion_function, + # both contains parameter POLYXFER_NUM_ELEM. However, Fortran is not able to + # differentiate generic interface based on different function signature. Disable + # for now. + pass elif kind.startswith('POLY'): a = get_int_type(small_map[kind]) + "-size" b = get_int_type(large_map[kind]) + "-size" From 0d06757f39c9866cbfd1de3abf73f4a9d7829c90 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 25 Nov 2021 16:42:44 -0600 Subject: [PATCH 186/607] f08: remove old hack for skip_large_list Now we test actual parameter variations, we no longer need this hack, which is incomplete anyway. --- maint/gen_binding_f08.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/maint/gen_binding_f08.py b/maint/gen_binding_f08.py index 66adf370740..4543aa6ea90 100644 --- a/maint/gen_binding_f08.py +++ b/maint/gen_binding_f08.py @@ -28,9 +28,6 @@ def main(): func_list.extend(get_type_create_f90_func_list()) skip_large_list = [] - # skip large variations because MPI_ADDRESS_KIND == MPI_COUNT_KIND - if G.opts['aint-size'] == G.opts['count-size']: - skip_large_list.extend(["MPI_Op_create", "MPI_Register_datarep", "MPI_Type_create_resized", "MPI_Type_get_extent", "MPI_Type_get_true_extent", "MPI_File_get_type_extent", "MPI_Win_allocate", "MPI_Win_allocate_shared", "MPI_Win_create", "MPI_Win_shared_query"]) # skip File large count functions because it is not implemented yet for func in func_list: if func['name'].startswith('MPI_File_') or func['name'] == 'MPI_Register_datarep': From a4141b49d31f73c27b0c808a8fd5895c28762e02 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 26 Nov 2021 08:55:11 -0600 Subject: [PATCH 187/607] xfail: osx f08/topo/dgraph_unwgtf90 This test is fixed with pmodels/mpich#5682. Xfail for now. --- test/mpi/maint/jenkins/xfail.conf | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/test/mpi/maint/jenkins/xfail.conf b/test/mpi/maint/jenkins/xfail.conf index 08d67cfe83f..08c28caa164 100644 --- a/test/mpi/maint/jenkins/xfail.conf +++ b/test/mpi/maint/jenkins/xfail.conf @@ -44,13 +44,7 @@ * * * * osx /^fileerrretx/ xfail=ticket0 errors/cxx/io/testlist * * * * osx /^throwtestfilex/ xfail=ticket0 errors/cxx/io/testlist * gnu debug ch3:tcp osx /^namepubx/ xfail=issue3506 cxx/spawn/testlist -* intel * * osx /^statusesf08/ xfail=issue4374 f08/pt2pt/testlist -* intel * * osx /^vw_inplacef08/ xfail=issue4374 f08/coll/testlist -* intel * * osx /^red_scat_blockf08/ xfail=issue4374 f08/coll/testlist -* intel * * osx /^nonblocking_inpf08/ xfail=issue4374 f08/coll/testlist -* intel * * osx /^structf/ xfail=issue4374 f08/datatype/testlist -* intel * * osx /^aintf08/ xfail=issue4374 f08/rma/testlist -* intel * * osx /^dgraph_unwgtf90/ xfail=issue4374 f08/topo/testlist +* * * * osx /^dgraph_unwgtf90/ xfail=issue4374 f08/topo/testlist ################################################################################ # xfail large count tests on 32 bit architectures (cannot allocate such large memory) * * * * freebsd32 /^getfence1 [0-9]* arg=-type=.* arg=-count=16000000/ xfail=ticket0 rma/testlist.dtp From 53a9355ea533d3b2ccccf5424736f4b7582c8727 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 29 Nov 2021 09:01:57 -0600 Subject: [PATCH 188/607] mpl: remove AI_V4MAPPED from sockaddr The purpose of AI_V4MAPPED flag is to be able to use IPv6 when hosts are only configured with IPv4 addresses. Unfortunately, AI_V4MAPPED is not widely supported, e.g. on OpenBSD. And since the use scenario is not common -- currently we default to IPv4 -- it is safe to remove this hint. --- src/mpl/src/sock/mpl_sockaddr.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mpl/src/sock/mpl_sockaddr.c b/src/mpl/src/sock/mpl_sockaddr.c index 0adda43abe9..cb04792773d 100644 --- a/src/mpl/src/sock/mpl_sockaddr.c +++ b/src/mpl/src/sock/mpl_sockaddr.c @@ -98,7 +98,6 @@ int MPL_get_sockaddr(const char *s_hostname, MPL_sockaddr_t * p_addr) ai_hint.ai_family = af_type; ai_hint.ai_socktype = SOCK_STREAM; ai_hint.ai_protocol = IPPROTO_TCP; - ai_hint.ai_flags = AI_V4MAPPED; ret = getaddrinfo(s_hostname, NULL, &ai_hint, &ai_list); if (ret) { return ret; From 7fbeec233f996e2a1bcb43f138e013cad52c49a7 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 29 Nov 2021 10:03:11 -0600 Subject: [PATCH 189/607] ch3: use MPL_proc_mutex abstraction We have abstracted the process shared mutex creation utilities into MPL but failed to convert some of the usages in ch3. The MPL abstraction takes care of the case when shared mutex isn't available or even when the pthread API isn't available. --- .../channels/nemesis/include/mpidi_ch3_impl.h | 16 ++-------------- src/mpid/ch3/channels/nemesis/src/ch3_init.c | 12 +----------- 2 files changed, 3 insertions(+), 25 deletions(-) diff --git a/src/mpid/ch3/channels/nemesis/include/mpidi_ch3_impl.h b/src/mpid/ch3/channels/nemesis/include/mpidi_ch3_impl.h index e23cebff6ae..c7e9be58870 100644 --- a/src/mpid/ch3/channels/nemesis/include/mpidi_ch3_impl.h +++ b/src/mpid/ch3/channels/nemesis/include/mpidi_ch3_impl.h @@ -104,20 +104,8 @@ int MPIDI_CH3_SHM_Win_free(MPIR_Win **win_ptr); #define MPIDI_CH3I_SHM_MUTEX_INIT(win_ptr) \ do { \ int pt_err; \ - pthread_mutexattr_t attr; \ - \ - pt_err = pthread_mutexattr_init(&attr); \ - MPIR_ERR_CHKANDJUMP1(pt_err, mpi_errno, MPI_ERR_OTHER, "**pthread_mutex", \ - "**pthread_mutex %s", strerror(pt_err)); \ - pt_err = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); \ - MPIR_ERR_CHKANDJUMP1(pt_err, mpi_errno, MPI_ERR_OTHER, "**pthread_mutex", \ - "**pthread_mutex %s", strerror(pt_err)); \ - pt_err = pthread_mutex_init((win_ptr)->shm_mutex, &attr); \ - MPIR_ERR_CHKANDJUMP1(pt_err, mpi_errno, MPI_ERR_OTHER, "**pthread_mutex", \ - "**pthread_mutex %s", strerror(pt_err)); \ - pt_err = pthread_mutexattr_destroy(&attr); \ - MPIR_ERR_CHKANDJUMP1(pt_err, mpi_errno, MPI_ERR_OTHER, "**pthread_mutex", \ - "**pthread_mutex %s", strerror(pt_err)); \ + MPL_proc_mutex_create((win_ptr)->shm_mutex, &pt_err); \ + MPIR_ERR_CHECK(pt_err); \ } while (0); #define MPIDI_CH3I_SHM_MUTEX_DESTROY(win_ptr) \ diff --git a/src/mpid/ch3/channels/nemesis/src/ch3_init.c b/src/mpid/ch3/channels/nemesis/src/ch3_init.c index 30797865169..561ae2db578 100644 --- a/src/mpid/ch3/channels/nemesis/src/ch3_init.c +++ b/src/mpid/ch3/channels/nemesis/src/ch3_init.c @@ -62,17 +62,7 @@ static int split_type(MPIR_Comm * user_comm_ptr, int stype, int key, int MPIDI_CH3I_Shm_supported(void) { - int mutex_err; - pthread_mutexattr_t attr; - - /* Test for PTHREAD_PROCESS_SHARED support. Some platforms do not support - * this capability even though it is a part of the pthreads core API (e.g., - * FreeBSD does not support this as of version 9.1) */ - pthread_mutexattr_init(&attr); - mutex_err = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); - pthread_mutexattr_destroy(&attr); - - return !mutex_err; + return MPL_proc_mutex_enabled(); } static MPIR_Commops comm_fns = { From 9fe7c6acaad6c2da5f1d5a09a345a2a1e92fa825 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 28 Nov 2021 23:47:33 -0600 Subject: [PATCH 190/607] configure: pass USER_CFLAGS to hwloc When we reset flags, we need make sure to pass along user flags. --- confdb/aclocal_modules.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/confdb/aclocal_modules.m4 b/confdb/aclocal_modules.m4 index 4c92ca02266..bb2eca940de 100644 --- a/confdb/aclocal_modules.m4 +++ b/confdb/aclocal_modules.m4 @@ -41,7 +41,7 @@ dnl internal routine, $1 is the extra cflags, hwloc_embedded_dir is m4 macro dnl defined to be the path to embedded hwloc. AC_DEFUN([PAC_CONFIG_HWLOC_EMBEDDED],[ PAC_PUSH_FLAG([CFLAGS]) - CFLAGS="$1" + CFLAGS="$USER_CFLAGS $1" hwloc_config_args="--enable-embedded-mode --disable-visibility" hwloc_config_args="$hwloc_config_args --disable-libxml2" hwloc_config_args="$hwloc_config_args --disable-nvml" From 7215c919effd78e166fa868aa25a46258ce5a1a1 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 29 Nov 2021 22:48:12 -0600 Subject: [PATCH 191/607] hydra: save USER flags when being built standalone The user flags are saved from MPICH configure when it is built with mpich, but we need save them if hydra is being built alone. This is needed for resetting CFLAGS when subconfiguring submodules, e.g. hwloc. --- src/pm/hydra/configure.ac | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pm/hydra/configure.ac b/src/pm/hydra/configure.ac index 30c4b457ec3..3370eb1d28e 100644 --- a/src/pm/hydra/configure.ac +++ b/src/pm/hydra/configure.ac @@ -11,6 +11,10 @@ AC_INIT([Hydra], MPICH_VERSION_m4) AC_CONFIG_AUX_DIR(confdb) AC_CONFIG_MACRO_DIR(confdb) +if test "$FROM_MPICH" != "yes" ; then + PAC_PREFIX_ALL_FLAGS(USER) +fi + AC_ARG_PROGRAM dnl must come before LT_INIT, which AC_REQUIREs AC_PROG_CC From 42038c1d4d902fa5eb6f181adadffb37a5801aa0 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 29 Nov 2021 22:51:01 -0600 Subject: [PATCH 192/607] confdb: move PAC_RESET_ALL_FLAGS etc into aclocal_util.m4 Move the macros that manipulate build flags together since they need be consistent. --- confdb/aclocal_subcfg.m4 | 21 --------------------- confdb/aclocal_util.m4 | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/confdb/aclocal_subcfg.m4 b/confdb/aclocal_subcfg.m4 index fbd1899f4dd..f865a8d0819 100644 --- a/confdb/aclocal_subcfg.m4 +++ b/confdb/aclocal_subcfg.m4 @@ -1,24 +1,3 @@ -dnl PAC_RESET_ALL_FLAGS - Reset precious flags to those set by the user -AC_DEFUN([PAC_RESET_ALL_FLAGS],[ - if test "$FROM_MPICH" = "yes" ; then - CFLAGS="$USER_CFLAGS" - CPPFLAGS="$USER_CPPFLAGS" - CXXFLAGS="$USER_CXXFLAGS" - FFLAGS="$USER_FFLAGS" - FCFLAGS="$USER_FCFLAGS" - LDFLAGS="$USER_LDFLAGS" - LIBS="$USER_LIBS" - fi -]) - -dnl PAC_RESET_LINK_FLAGS - Reset precious link flags to those set by the user -AC_DEFUN([PAC_RESET_LINK_FLAGS],[ - if test "$FROM_MPICH" = "yes" ; then - LDFLAGS="$USER_LDFLAGS" - LIBS="$USER_LIBS" - fi -]) - dnl Sandbox configure with additional arguments dnl Usage: PAC_CONFIG_SUBDIR_ARGS(subdir,configure-args,action-if-success,action-if-failure) dnl diff --git a/confdb/aclocal_util.m4 b/confdb/aclocal_util.m4 index 91e4823a05a..88b99928625 100644 --- a/confdb/aclocal_util.m4 +++ b/confdb/aclocal_util.m4 @@ -58,6 +58,27 @@ AC_DEFUN([PAC_PREFIX_ALL_FLAGS],[ PAC_PREFIX_FLAG($1, EXTRA_LIBS) ]) +dnl PAC_RESET_ALL_FLAGS - Reset precious flags to those set by the user +AC_DEFUN([PAC_RESET_ALL_FLAGS],[ + if test "$FROM_MPICH" = "yes" ; then + CFLAGS="$USER_CFLAGS" + CPPFLAGS="$USER_CPPFLAGS" + CXXFLAGS="$USER_CXXFLAGS" + FFLAGS="$USER_FFLAGS" + FCFLAGS="$USER_FCFLAGS" + LDFLAGS="$USER_LDFLAGS" + LIBS="$USER_LIBS" + fi +]) + +dnl PAC_RESET_LINK_FLAGS - Reset precious link flags to those set by the user +AC_DEFUN([PAC_RESET_LINK_FLAGS],[ + if test "$FROM_MPICH" = "yes" ; then + LDFLAGS="$USER_LDFLAGS" + LIBS="$USER_LIBS" + fi +]) + AC_DEFUN([PAC_CHECK_FGREP_WORD],[ AC_PROG_FGREP AC_MSG_CHECKING([if fgrep support -w option]) From 300b306a7f582d07f21de1b71081e51537b586e3 Mon Sep 17 00:00:00 2001 From: "Islam, Nusrat" Date: Thu, 22 Jul 2021 11:50:56 -0500 Subject: [PATCH 193/607] coll: Add CVARs for blocking Bcast algorithm selection The kary and knomial tree based blocking Bcast algorithms perform better than the binomial tree based algorithm for small messages because of being able to send to K (branching factor) children at each level of the tree. On the other hand, for large messages, the pipelined tree based algorithm performs well because it divides the message into multiple smaller chunks. For all these algorithms, non-blocking send-recv APIs have been used to get better overlapping. --- src/mpi/coll/coll_algorithms.txt | 6 +++ src/mpi/coll/cvars.txt | 55 +++++++++++++++++++++++++++ src/mpi/coll/include/coll_impl.h | 1 + src/mpi/coll/include/csel_container.h | 16 ++++++++ src/mpi/coll/src/coll_impl.c | 11 ++++++ src/mpi/coll/src/csel_container.c | 41 ++++++++++++++++++++ 6 files changed, 130 insertions(+) diff --git a/src/mpi/coll/coll_algorithms.txt b/src/mpi/coll/coll_algorithms.txt index 8ea0f802a12..b02054f21d0 100644 --- a/src/mpi/coll/coll_algorithms.txt +++ b/src/mpi/coll/coll_algorithms.txt @@ -55,6 +55,12 @@ bcast-intra: scatter_ring_allgather smp restrictions: parent-comm + tree + extra_params: tree_type, k, is_non_blocking + cvar_params: TREE_TYPE, TREE_KVAL, IS_NON_BLOCKING + pipelined_tree + extra_params: tree_type, k, is_non_blocking, chunk_size, recv_pre_posted + cvar_params: TREE_TYPE, TREE_KVAL, IS_NON_BLOCKING, TREE_PIPELINE_CHUNK_SIZE, RECV_PRE_POST ibcast-intra: sched_binomial sched_smp diff --git a/src/mpi/coll/cvars.txt b/src/mpi/coll/cvars.txt index f1b924b2ee0..5fdf5d7716d 100644 --- a/src/mpi/coll/cvars.txt +++ b/src/mpi/coll/cvars.txt @@ -156,6 +156,61 @@ cvars: smp - Force smp algorithm scatter_recursive_doubling_allgather - Force Scatter Recursive-Doubling Allgather scatter_ring_allgather - Force Scatter Ring + pipelined_tree - Force tree-based pipelined algorithm + tree - Force tree-based algorithm + + - name : MPIR_CVAR_BCAST_TREE_KVAL + category : COLLECTIVE + type : int + default : 2 + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + k value for tree (kary, knomial, etc.) based bcast + + - name : MPIR_CVAR_BCAST_TREE_TYPE + category : COLLECTIVE + type : string + default : kary + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + Tree type for tree based ibcast + kary - kary tree type + knomial_1 - knomial_1 tree type + knomial_2 - knomial_2 tree type + + - name : MPIR_CVAR_BCAST_IS_NON_BLOCKING + category : COLLECTIVE + type : boolean + default : true + class : device + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + If set to true, MPI_Bcast will use non-blocking send. + + - name : MPIR_CVAR_BCAST_TREE_PIPELINE_CHUNK_SIZE + category : COLLECTIVE + type : int + default : 8192 + class : device + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + Indicates the chunk size for pipelined bcast. + + - name : MPIR_CVAR_BCAST_RECV_PRE_POST + category : COLLECTIVE + type : boolean + default : false + class : device + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + If set to true, MPI_Bcast will pre-post all the receives. - name : MPIR_CVAR_BCAST_INTER_ALGORITHM category : COLLECTIVE diff --git a/src/mpi/coll/include/coll_impl.h b/src/mpi/coll/include/coll_impl.h index 1b7c25c4c51..84390c45ca6 100644 --- a/src/mpi/coll/include/coll_impl.h +++ b/src/mpi/coll/include/coll_impl.h @@ -39,6 +39,7 @@ extern int MPIR_Nbc_progress_hook_id; extern MPIR_Tree_type_t MPIR_Iallreduce_tree_type; extern MPIR_Tree_type_t MPIR_Ireduce_tree_type; extern MPIR_Tree_type_t MPIR_Ibcast_tree_type; +extern MPIR_Tree_type_t MPIR_Bcast_tree_type; extern void *MPIR_Csel_root; extern char MPII_coll_generic_json[]; diff --git a/src/mpi/coll/include/csel_container.h b/src/mpi/coll/include/csel_container.h index e810df9323b..8cc31580302 100644 --- a/src/mpi/coll/include/csel_container.h +++ b/src/mpi/coll/include/csel_container.h @@ -48,6 +48,8 @@ typedef enum { MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Bcast_intra_scatter_recursive_doubling_allgather, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Bcast_intra_scatter_ring_allgather, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Bcast_intra_smp, + MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Bcast_intra_tree, + MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Bcast_intra_pipelined_tree, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Bcast_inter_remote_send_local_bcast, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Bcast_allcomm_nb, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Exscan_intra_recursive_doubling, @@ -278,6 +280,20 @@ typedef struct { int allgatherv_k; } intra_tsp_scatterv_recexch_allgatherv; } ibcast; + struct { + struct { + int tree_type; + int k; + int is_non_blocking; + } intra_tree; + struct { + int tree_type; + int k; + int is_non_blocking; + int chunk_size; + int recv_pre_posted; + } intra_pipelined_tree; + } bcast; struct { struct { int k; diff --git a/src/mpi/coll/src/coll_impl.c b/src/mpi/coll/src/coll_impl.c index 3593d90b35d..f250ea2b2f9 100644 --- a/src/mpi/coll/src/coll_impl.c +++ b/src/mpi/coll/src/coll_impl.c @@ -60,6 +60,7 @@ int MPIR_Nbc_progress_hook_id = 0; MPIR_Tree_type_t MPIR_Iallreduce_tree_type = MPIR_TREE_TYPE_KARY; MPIR_Tree_type_t MPIR_Ibcast_tree_type = MPIR_TREE_TYPE_KARY; +MPIR_Tree_type_t MPIR_Bcast_tree_type = MPIR_TREE_TYPE_KARY; MPIR_Tree_type_t MPIR_Ireduce_tree_type = MPIR_TREE_TYPE_KARY; void *MPIR_Csel_root = NULL; @@ -86,6 +87,16 @@ int MPII_Coll_init(void) else MPIR_Ibcast_tree_type = MPIR_TREE_TYPE_KARY; + /* Bcast */ + if (0 == strcmp(MPIR_CVAR_BCAST_TREE_TYPE, "kary")) + MPIR_Bcast_tree_type = MPIR_TREE_TYPE_KARY; + else if (0 == strcmp(MPIR_CVAR_BCAST_TREE_TYPE, "knomial_1")) + MPIR_Bcast_tree_type = MPIR_TREE_TYPE_KNOMIAL_1; + else if (0 == strcmp(MPIR_CVAR_BCAST_TREE_TYPE, "knomial_2")) + MPIR_Bcast_tree_type = MPIR_TREE_TYPE_KNOMIAL_2; + else + MPIR_Bcast_tree_type = MPIR_TREE_TYPE_KARY; + /* Ireduce */ if (0 == strcmp(MPIR_CVAR_IREDUCE_TREE_TYPE, "kary")) MPIR_Ireduce_tree_type = MPIR_TREE_TYPE_KARY; diff --git a/src/mpi/coll/src/csel_container.c b/src/mpi/coll/src/csel_container.c index ecc26ba2893..e3064e8a415 100644 --- a/src/mpi/coll/src/csel_container.c +++ b/src/mpi/coll/src/csel_container.c @@ -42,6 +42,43 @@ static void parse_container_params(struct json_object *obj, MPII_Csel_container_ } break; + case MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Bcast_intra_tree: + { + json_object_object_foreach(obj, key, val) { + ckey = MPL_strdup_no_spaces(key); + if (!strncmp(ckey, "tree_type=", strlen("tree_type="))) + cnt->u.bcast.intra_tree.tree_type = atoi(ckey + strlen("tree_type=")); + else if (!strncmp(ckey, "k=", strlen("k="))) + cnt->u.bcast.intra_tree.k = atoi(ckey + strlen("k=")); + else if (!strncmp(ckey, "is_non_blocking=", strlen("is_non_blocking="))) + cnt->u.bcast.intra_tree.k = atoi(ckey + strlen("k=")); + MPL_free(ckey); + } + } + break; + + case MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Bcast_intra_pipelined_tree: + { + json_object_object_foreach(obj, key, val) { + ckey = MPL_strdup_no_spaces(key); + if (!strncmp(ckey, "tree_type=", strlen("tree_type="))) + cnt->u.bcast.intra_pipelined_tree.tree_type = + atoi(ckey + strlen("tree_type=")); + else if (!strncmp(ckey, "k=", strlen("k="))) + cnt->u.bcast.intra_pipelined_tree.k = atoi(ckey + strlen("k=")); + else if (!strncmp(ckey, "is_non_blocking=", strlen("is_non_blocking="))) + cnt->u.bcast.intra_pipelined_tree.k = atoi(ckey + strlen("k=")); + else if (!strncmp(ckey, "chunk_size=", strlen("chunk_size="))) + cnt->u.bcast.intra_pipelined_tree.chunk_size = + atoi(ckey + strlen("chunk_size=")); + else if (!strncmp(ckey, "recv_pre_posted=", strlen("recv_pre_posted="))) + cnt->u.bcast.intra_pipelined_tree.recv_pre_posted = + atoi(ckey + strlen("recv_pre_posted=")); + MPL_free(ckey); + } + } + break; + case MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ireduce_intra_tsp_tree: { json_object_object_foreach(obj, key, val) { @@ -242,6 +279,10 @@ void *MPII_Create_container(struct json_object *obj) cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Bcast_intra_scatter_ring_allgather; else if (!strcmp(ckey, "algorithm=MPIR_Bcast_intra_smp")) cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Bcast_intra_smp; + else if (!strcmp(ckey, "algorithm=MPIR_Bcast_intra_tree")) + cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Bcast_intra_tree; + else if (!strcmp(ckey, "algorithm=MPIR_Bcast_intra_pipelined_tree")) + cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Bcast_intra_pipelined_tree; else if (!strcmp(ckey, "algorithm=MPIR_Bcast_inter_remote_send_local_bcast")) cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Bcast_inter_remote_send_local_bcast; else if (!strcmp(ckey, "algorithm=MPIR_Bcast_allcomm_nb")) From a00485d5497637b1fd6ce2aec6f40ff2f631aa50 Mon Sep 17 00:00:00 2001 From: "Islam, Nusrat" Date: Fri, 23 Jul 2021 10:38:54 -0500 Subject: [PATCH 194/607] coll: Add tree-based blocking Bcast algorithms --- src/mpi/coll/bcast/Makefile.mk | 2 + .../coll/bcast/bcast_intra_pipelined_tree.c | 246 ++++++++++++++++++ src/mpi/coll/bcast/bcast_intra_tree.c | 167 ++++++++++++ 3 files changed, 415 insertions(+) create mode 100644 src/mpi/coll/bcast/bcast_intra_pipelined_tree.c create mode 100644 src/mpi/coll/bcast/bcast_intra_tree.c diff --git a/src/mpi/coll/bcast/Makefile.mk b/src/mpi/coll/bcast/Makefile.mk index aa4fe4456b6..32fb8bbe2be 100644 --- a/src/mpi/coll/bcast/Makefile.mk +++ b/src/mpi/coll/bcast/Makefile.mk @@ -14,6 +14,8 @@ mpi_core_sources += \ src/mpi/coll/bcast/bcast_intra_scatter_recursive_doubling_allgather.c \ src/mpi/coll/bcast/bcast_intra_scatter_ring_allgather.c \ src/mpi/coll/bcast/bcast_intra_smp.c \ + src/mpi/coll/bcast/bcast_intra_tree.c \ + src/mpi/coll/bcast/bcast_intra_pipelined_tree.c \ src/mpi/coll/bcast/bcast_inter_remote_send_local_bcast.c noinst_HEADERS += \ diff --git a/src/mpi/coll/bcast/bcast_intra_pipelined_tree.c b/src/mpi/coll/bcast/bcast_intra_pipelined_tree.c new file mode 100644 index 00000000000..0b3f11ecc6f --- /dev/null +++ b/src/mpi/coll/bcast/bcast_intra_pipelined_tree.c @@ -0,0 +1,246 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpiimpl.h" +#include "algo_common.h" +#include "treealgo.h" + +/* Algorithm: Pipelined bcast + * For large messages, we use the tree-based pipelined algorithm. + * Time = Time to send the first chunk to the rightmost child + (num_chunks - 1) * software overhead to inject a chunk + */ +int MPIR_Bcast_intra_pipelined_tree(void *buffer, + MPI_Aint count, + MPI_Datatype datatype, + int root, MPIR_Comm * comm_ptr, int tree_type, + int branching_factor, int is_nb, int chunk_size, + int recv_pre_posted, MPIR_Errflag_t * errflag) +{ + int rank, comm_size, i, j, k, *p, src = -1, dst, offset = 0; + int msgsize, is_contig; + int mpi_errno = MPI_SUCCESS; + int mpi_errno_ret = MPI_SUCCESS; + MPI_Status status; + MPI_Aint type_size, num_chunks, chunk_size_floor, chunk_size_ceil; + MPI_Aint true_lb, true_extent, recvd_size, actual_packed_unpacked_bytes, nbytes = 0; + void *sendbuf = NULL; + int parent = -1, num_children = 0, lrank = 0, num_req = 0; + MPIR_Request **reqs = NULL; + MPI_Status *statuses = NULL; + MPIR_Treealgo_tree_t my_tree; + MPIR_CHKLMEM_DECL(3); + + comm_size = comm_ptr->local_size; + rank = comm_ptr->rank; + + /* If there is only one process, return */ + if (comm_size == 1) + goto fn_exit; + + MPIR_Datatype_is_contig(datatype, &is_contig); + + if (is_contig) { + MPIR_Datatype_get_size_macro(datatype, type_size); + } else { + MPIR_Pack_size(1, datatype, &type_size); + } + + nbytes = type_size * count; + + if (nbytes == 0) + goto fn_exit; + + if (is_contig) { /* no need to pack */ + MPIR_Type_get_true_extent_impl(datatype, &true_lb, &true_extent); + sendbuf = (char *) buffer + true_lb; + } else { + MPIR_CHKLMEM_MALLOC(sendbuf, void *, nbytes, mpi_errno, "sendbuf", MPL_MEM_BUFFER); + if (rank == root) { + mpi_errno = MPIR_Typerep_pack(buffer, count, datatype, 0, sendbuf, nbytes, + &actual_packed_unpacked_bytes); + MPIR_ERR_CHECK(mpi_errno); + } + } + + /* treat all cases as MPI_BYTE */ + MPIR_Algo_calculate_pipeline_chunk_info(chunk_size, 1, nbytes, &num_chunks, + &chunk_size_floor, &chunk_size_ceil); + + if (tree_type == MPIR_TREE_TYPE_KARY) { + lrank = (rank + (comm_size - root)) % comm_size; + parent = (lrank == 0) ? -1 : (((lrank - 1) / branching_factor) + root) % comm_size; + num_children = branching_factor; + } else { + mpi_errno = + MPIR_Treealgo_tree_create(rank, comm_size, tree_type, branching_factor, root, &my_tree); + MPIR_ERR_CHECK(mpi_errno); + num_children = my_tree.num_children; + } + + if (is_nb) { + MPIR_CHKLMEM_MALLOC(reqs, MPIR_Request **, + sizeof(MPIR_Request *) * (num_children * num_chunks + num_chunks), + mpi_errno, "request array", MPL_MEM_COLL); + MPIR_CHKLMEM_MALLOC(statuses, MPI_Status *, + sizeof(MPI_Status) * (num_children * num_chunks + num_chunks), + mpi_errno, "status array", MPL_MEM_COLL); + } + + if (tree_type != MPIR_TREE_TYPE_KARY && my_tree.parent != -1) + src = my_tree.parent; + else if (tree_type == MPIR_TREE_TYPE_KARY && parent != -1) + src = parent; + + if (is_nb) { + if (num_chunks > 3 && !recv_pre_posted) { + /* For large number of chunks, pre-posting all the receives can add overhead + * so posting three IRecvs to keep the pipeline going*/ + for (i = 0; i < 3; i++) { + msgsize = (i == 0) ? chunk_size_floor : chunk_size_ceil; + + if (src != -1) { /* post receive from parent */ + mpi_errno = + MPIC_Irecv((char *) sendbuf + offset, msgsize, MPI_BYTE, + src, MPIR_BCAST_TAG, comm_ptr, &reqs[num_req++]); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); + } + offset += msgsize; + } + + } else { + /* For small number of chunks, all the receives can be pre-posted */ + for (i = 0; i < num_chunks; i++) { + msgsize = (i == 0) ? chunk_size_floor : chunk_size_ceil; + if (src != -1) { + mpi_errno = + MPIC_Irecv((char *) sendbuf + offset, msgsize, MPI_BYTE, + src, MPIR_BCAST_TAG, comm_ptr, &reqs[num_req++]); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); + } + offset += msgsize; + } + } + } + offset = 0; + + for (i = 0; i < num_chunks; i++) { + msgsize = (i == 0) ? chunk_size_floor : chunk_size_ceil; + + if ((num_chunks <= 3 && is_nb) || (recv_pre_posted && is_nb)) { + /* Wait to receive the chunk before it can be sent to the children */ + if (src != -1) { + mpi_errno = MPIC_Wait(reqs[i], errflag); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); + MPIR_Get_count_impl(&reqs[i]->status, MPI_BYTE, &recvd_size); + if (recvd_size != msgsize) { + if (*errflag == MPIR_ERR_NONE) + *errflag = MPIR_ERR_OTHER; + MPIR_ERR_SET2(mpi_errno, MPI_ERR_OTHER, + "**collective_size_mismatch", + "**collective_size_mismatch %d %d", recvd_size, msgsize); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + } + } else if (num_chunks > 3 && is_nb && i < 3 && !recv_pre_posted) { + /* Wait to receive the chunk before it can be sent to the children */ + if (src != -1) { + mpi_errno = MPIC_Wait(reqs[i], errflag); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); + MPIR_Get_count_impl(&reqs[i]->status, MPI_BYTE, &recvd_size); + if (recvd_size != msgsize) { + if (*errflag == MPIR_ERR_NONE) + *errflag = MPIR_ERR_OTHER; + MPIR_ERR_SET2(mpi_errno, MPI_ERR_OTHER, + "**collective_size_mismatch", + "**collective_size_mismatch %d %d", recvd_size, msgsize); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + } + } else { + /* Receive message from parent */ + if (src != -1) { + mpi_errno = + MPIC_Recv((char *) sendbuf + offset, msgsize, MPI_BYTE, + src, MPIR_BCAST_TAG, comm_ptr, &status, errflag); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); + MPIR_Get_count_impl(&status, MPI_BYTE, &recvd_size); + if (recvd_size != msgsize) { + if (*errflag == MPIR_ERR_NONE) + *errflag = MPIR_ERR_OTHER; + MPIR_ERR_SET2(mpi_errno, MPI_ERR_OTHER, + "**collective_size_mismatch", + "**collective_size_mismatch %d %d", recvd_size, msgsize); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + + } + } + if (tree_type == MPIR_TREE_TYPE_KARY) { + /* Send data to the children */ + for (k = 1; k <= branching_factor; k++) { + dst = lrank * branching_factor + k; + if (dst >= comm_size) + break; + + dst = (dst + root) % comm_size; + + if (!is_nb) { + mpi_errno = + MPIC_Send((char *) sendbuf + offset, msgsize, MPI_BYTE, dst, + MPIR_BCAST_TAG, comm_ptr, errflag); + } else { + mpi_errno = + MPIC_Isend((char *) sendbuf + offset, msgsize, MPI_BYTE, dst, + MPIR_BCAST_TAG, comm_ptr, &reqs[num_req++], errflag); + } + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); + + } + } else if (num_children) { + /* Send data to the children */ + for (j = 0; j < num_children; j++) { + p = (int *) utarray_eltptr(my_tree.children, j); + dst = *p; + if (!is_nb) { + mpi_errno = MPIC_Send((char *) sendbuf + offset, msgsize, MPI_BYTE, dst, + MPIR_BCAST_TAG, comm_ptr, errflag); + } else { + mpi_errno = + MPIC_Isend((char *) sendbuf + offset, msgsize, MPI_BYTE, dst, + MPIR_BCAST_TAG, comm_ptr, &reqs[num_req++], errflag); + } + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); + } + } + offset += msgsize; + } + + if (is_nb) { + mpi_errno = MPIC_Waitall(num_req, reqs, statuses, errflag); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); + } + + if (!is_contig) { + if (rank != root) { + mpi_errno = MPIR_Typerep_unpack(sendbuf, nbytes, buffer, count, datatype, 0, + &actual_packed_unpacked_bytes); + MPIR_ERR_CHECK(mpi_errno); + } + } + + if (tree_type != MPIR_TREE_TYPE_KARY) + MPIR_Treealgo_tree_free(&my_tree); + fn_exit: + MPIR_CHKLMEM_FREEALL(); + /* --BEGIN ERROR HANDLING-- */ + if (mpi_errno_ret) + mpi_errno = mpi_errno_ret; + else if (*errflag != MPIR_ERR_NONE) + MPIR_ERR_SET(mpi_errno, *errflag, "**coll_fail"); + /* --END ERROR HANDLING-- */ + return mpi_errno; + fn_fail: + goto fn_exit; +} diff --git a/src/mpi/coll/bcast/bcast_intra_tree.c b/src/mpi/coll/bcast/bcast_intra_tree.c new file mode 100644 index 00000000000..f944ab45d5e --- /dev/null +++ b/src/mpi/coll/bcast/bcast_intra_tree.c @@ -0,0 +1,167 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpiimpl.h" +/* Algorithm: Tree-based bcast + * For short messages, we use a kary/knomial tree-based algorithm. + * Cost = lgp.alpha + n.lgp.beta + */ + +int MPIR_Bcast_intra_tree(void *buffer, + MPI_Aint count, + MPI_Datatype datatype, + int root, MPIR_Comm * comm_ptr, int tree_type, + int branching_factor, int is_nb, MPIR_Errflag_t * errflag) +{ + int rank, comm_size, src, dst, *p, j, k, lrank, is_contig; + int parent = -1, num_children = 0, num_req = 0, saved_count = count, is_root = 0; + int mpi_errno = MPI_SUCCESS; + int mpi_errno_ret = MPI_SUCCESS; + MPI_Aint nbytes = 0, type_size, actual_packed_unpacked_bytes, recvd_size; + MPI_Status status; + void *send_buf = NULL; + MPIR_Request **reqs = NULL; + MPI_Status *statuses = NULL; + MPI_Datatype dtype; + + MPIR_Treealgo_tree_t my_tree; + MPIR_CHKLMEM_DECL(3); + + comm_size = comm_ptr->local_size; + rank = comm_ptr->rank; + + /* If there is only one process, return */ + if (comm_size == 1) + goto fn_exit; + + if (HANDLE_GET_KIND(datatype) == HANDLE_KIND_BUILTIN) + is_contig = 1; + else { + MPIR_Datatype_is_contig(datatype, &is_contig); + } + + MPIR_Datatype_get_size_macro(datatype, type_size); + + nbytes = type_size * count; + if (nbytes == 0) + goto fn_exit; /* nothing to do */ + + send_buf = buffer; + dtype = datatype; + + if (!is_contig) { + MPIR_CHKLMEM_MALLOC(send_buf, void *, nbytes, mpi_errno, "send_buf", MPL_MEM_BUFFER); + + /* TODO: Pipeline the packing and communication */ + if (rank == root) { + mpi_errno = MPIR_Typerep_pack(buffer, count, datatype, 0, send_buf, nbytes, + &actual_packed_unpacked_bytes); + MPIR_ERR_CHECK(mpi_errno); + } + count = count * type_size; + dtype = MPI_BYTE; + } + + if (tree_type == MPIR_TREE_TYPE_KARY) { + if (rank == root) + is_root = 1; + lrank = (rank + (comm_size - root)) % comm_size; + parent = (lrank == 0) ? -1 : (((lrank - 1) / branching_factor) + root) % comm_size; + num_children = branching_factor; + } else { + /*construct the knomial tree */ + my_tree.children = NULL; + mpi_errno = + MPIR_Treealgo_tree_create(rank, comm_size, tree_type, branching_factor, root, &my_tree); + MPIR_ERR_CHECK(mpi_errno); + num_children = my_tree.num_children; + parent = my_tree.parent; + } + + if (is_nb) { + MPIR_CHKLMEM_MALLOC(reqs, MPIR_Request **, sizeof(MPIR_Request *) * num_children, + mpi_errno, "request array", MPL_MEM_COLL); + MPIR_CHKLMEM_MALLOC(statuses, MPI_Status *, sizeof(MPI_Status) * num_children, + mpi_errno, "status array", MPL_MEM_COLL); + } + + if ((parent != -1 && tree_type != MPIR_TREE_TYPE_KARY) + || (!is_root && tree_type == MPIR_TREE_TYPE_KARY)) { + src = parent; + mpi_errno = MPIC_Recv(send_buf, count, dtype, src, + MPIR_BCAST_TAG, comm_ptr, &status, errflag); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); + /* check that we received as much as we expected */ + MPIR_Get_count_impl(&status, MPI_BYTE, &recvd_size); + if (recvd_size != nbytes) { + if (*errflag == MPIR_ERR_NONE) + *errflag = MPIR_ERR_OTHER; + MPIR_ERR_SET2(mpi_errno, MPI_ERR_OTHER, + "**collective_size_mismatch", + "**collective_size_mismatch %d %d", recvd_size, nbytes); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + + } + if (tree_type == MPIR_TREE_TYPE_KARY) { + for (k = 1; k <= branching_factor; k++) { /* Send to children */ + dst = lrank * branching_factor + k; + if (dst >= comm_size) + break; + + dst = (dst + root) % comm_size; + + if (!is_nb) { + mpi_errno = + MPIC_Send(send_buf, count, dtype, dst, MPIR_BCAST_TAG, comm_ptr, errflag); + } else { + mpi_errno = MPIC_Isend(send_buf, count, dtype, dst, + MPIR_BCAST_TAG, comm_ptr, &reqs[num_req++], errflag); + } + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); + } + } else { + for (j = 0; j < num_children; j++) { + p = (int *) utarray_eltptr(my_tree.children, j); + dst = *p; + + if (!is_nb) { + mpi_errno = + MPIC_Send(send_buf, count, dtype, dst, MPIR_BCAST_TAG, comm_ptr, errflag); + } else { + mpi_errno = MPIC_Isend(send_buf, count, dtype, dst, + MPIR_BCAST_TAG, comm_ptr, &reqs[num_req++], errflag); + } + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); + } + } + if (is_nb) { + mpi_errno = MPIC_Waitall(num_req, reqs, statuses, errflag); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); + } + + if (tree_type != MPIR_TREE_TYPE_KARY) + MPIR_Treealgo_tree_free(&my_tree); + + if (!is_contig) { + if (rank != root) { + mpi_errno = MPIR_Typerep_unpack(send_buf, nbytes, buffer, saved_count, datatype, 0, + &actual_packed_unpacked_bytes); + MPIR_ERR_CHECK(mpi_errno); + } + } + + fn_exit: + MPIR_CHKLMEM_FREEALL(); + /* --BEGIN ERROR HANDLING-- */ + if (mpi_errno_ret) + mpi_errno = mpi_errno_ret; + else if (*errflag != MPIR_ERR_NONE) + MPIR_ERR_SET(mpi_errno, *errflag, "**coll_fail"); + /* --END ERROR HANDLING-- */ + return mpi_errno; + fn_fail: + goto fn_exit; +} From a25592d1ec3761deaa148142f5be99bd0537a43c Mon Sep 17 00:00:00 2001 From: "Islam, Nusrat" Date: Fri, 23 Jul 2021 11:06:21 -0500 Subject: [PATCH 195/607] test: Add tests for tree-based blocking bcast --- test/mpi/maint/coll_cvars.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/mpi/maint/coll_cvars.txt b/test/mpi/maint/coll_cvars.txt index 5bf8a378117..02da800ee38 100644 --- a/test/mpi/maint/coll_cvars.txt +++ b/test/mpi/maint/coll_cvars.txt @@ -311,6 +311,13 @@ algorithms: smp scatter_recursive_doubling_allgather scatter_ring_allgather + tree + .MPIR_CVAR_BCAST_TREE_TYPE=kary,knomial_1,knomial_2 + .MPIR_CVAR_BCAST_IS_NON_BLOCKING=1 + pipelined_tree + .MPIR_CVAR_BCAST_TREE_TYPE=kary,knomial_1,knomial_2 + .MPIR_CVAR_BCAST_IS_NON_BLOCKING=1 + .MPIR_CVAR_BCAST_TREE_PIPELINE_CHUNK_SIZE=4096,8192 posix:release_gather .MPIR_CVAR_COLL_SHM_LIMIT_PER_NODE=131072 .MPIR_CVAR_BCAST_INTRANODE_BUFFER_TOTAL_SIZE=16384,32768 From f39d3f7e0030913cf9a693167ea46d0646790fe7 Mon Sep 17 00:00:00 2001 From: Erik Schnetter Date: Fri, 26 Nov 2021 16:05:44 -0500 Subject: [PATCH 196/607] Correct spelling --- src/mpi/coll/ireduce/ireduce_intra_sched_binomial.c | 4 ++-- src/mpi/coll/reduce/reduce_intra_binomial.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mpi/coll/ireduce/ireduce_intra_sched_binomial.c b/src/mpi/coll/ireduce/ireduce_intra_sched_binomial.c index c31142fc131..5ed414d2c09 100644 --- a/src/mpi/coll/ireduce/ireduce_intra_sched_binomial.c +++ b/src/mpi/coll/ireduce/ireduce_intra_sched_binomial.c @@ -63,8 +63,8 @@ int MPIR_Ireduce_intra_sched_binomial(const void *sendbuf, void *recvbuf, MPI_Ai * results (roundoff error, over/underflows in some cases, etc). * * Because of the way these are ordered, if root is 0, then this is correct - * for both commutative and non-commutitive operations. If root is not - * 0, then for non-commutitive, we use a root of zero and then send + * for both commutative and non-commutative operations. If root is not + * 0, then for non-commutative, we use a root of zero and then send * the result to the root. To see this, note that the ordering is * mask = 1: (ab)(cd)(ef)(gh) (odds send to evens) * mask = 2: ((ab)(cd))((ef)(gh)) (3,6 send to 0,4) diff --git a/src/mpi/coll/reduce/reduce_intra_binomial.c b/src/mpi/coll/reduce/reduce_intra_binomial.c index 6fc71f31c9a..59cc656da2a 100644 --- a/src/mpi/coll/reduce/reduce_intra_binomial.c +++ b/src/mpi/coll/reduce/reduce_intra_binomial.c @@ -69,8 +69,8 @@ int MPIR_Reduce_intra_binomial(const void *sendbuf, * results (roundoff error, over/underflows in some cases, etc). * * Because of the way these are ordered, if root is 0, then this is correct - * for both commutative and non-commutitive operations. If root is not - * 0, then for non-commutitive, we use a root of zero and then send + * for both commutative and non-commutative operations. If root is not + * 0, then for non-commutative, we use a root of zero and then send * the result to the root. To see this, note that the ordering is * mask = 1: (ab)(cd)(ef)(gh) (odds send to evens) * mask = 2: ((ab)(cd))((ef)(gh)) (3,6 send to 0,4) From edd4710d8486d914e7f9393b7e998c5045035654 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 14 Feb 2021 15:46:09 -0600 Subject: [PATCH 197/607] build: configure test/mpi independently We used to configure test/mpi as a sub-configure of mpich. For one, this wastes build (configure) time when user has no intention to run the full testsuite. For two, this complicates the build script since test/mpi/configure.ac need deal with two very difference situation -- configured standalone or configured from mpich. Since we'll need installing the mpich before running the test suite anyway, it makes little sense to configure test suite during the build of mpich. While we may need add additional feature tests to detect enable/disabled mpich features, it is necessary to fully support independent MPI testing anyway. --- configure.ac | 1 - test/mpi/autogen.sh | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 4bf6edab20c..779a1a218eb 100644 --- a/configure.ac +++ b/configure.ac @@ -3992,7 +3992,6 @@ PAC_GET_EXENAME("mpifort", MPIFORT_NAME) PAC_GET_EXENAME("mpif90", MPIF90_NAME) PAC_GET_EXENAME("mpif77", MPIF77_NAME) -AC_CONFIG_SUBDIRS([test/mpi]) dnl dnl Generate the Makefiles from Makefile.in dnl Also generate mpi.h from mpi.h.in so that we can eliminate all ifdefs diff --git a/test/mpi/autogen.sh b/test/mpi/autogen.sh index 3d1d0eb6d02..1f3307ae07f 100755 --- a/test/mpi/autogen.sh +++ b/test/mpi/autogen.sh @@ -35,3 +35,5 @@ for dir in errors/f77/* ; do fi done echo "done" + +autoreconf -ivf From ebe83e3012cb9569932612e98f49ab2b3b6b7e7f Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 15 Feb 2021 14:43:29 -0600 Subject: [PATCH 198/607] test/config: whitespace clean Replace tab with spaces. Remove trailing spaces. --- test/mpi/configure.ac | 362 +++++++++++++++++++++--------------------- 1 file changed, 181 insertions(+), 181 deletions(-) diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index 597bb092952..585a33fc44d 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -6,12 +6,12 @@ dnl Process this file with autoconf to produce a configure script. AC_PREREQ(2.67) dnl -dnl aclocal_cache.m4, included by sowing/confdb/aclocal.m4, fixes +dnl aclocal_cache.m4, included by sowing/confdb/aclocal.m4, fixes dnl bugs in autoconf caching. dnl dnl dnl Environment variables that affect behavior of the test configure -dnl MPICH_FAST +dnl MPICH_FAST dnl dnl The file name here refers to a file in the source being configured dnl FIXME this is the old style, needs updating to new style @@ -46,9 +46,9 @@ AM_MAINTAINER_MODE([enable]) # Non-verbose make by default m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) -if test -z "$mpich_top_srcdir" ; then +if test -z "$mpich_top_srcdir" ; then if test -z "$top_srcdir" ; then - use_top_srcdir=$srcdir + use_top_srcdir=$srcdir else use_top_srcdir=$top_srcdir fi @@ -56,9 +56,9 @@ if test -z "$mpich_top_srcdir" ; then /*) ;; *) use_top_srcdir=`(cd $use_top_srcdir && pwd)` - ;; + ;; esac - if test -f $use_top_srcdir/../../maint/version.m4 ; then + if test -f $use_top_srcdir/../../maint/version.m4 ; then mpich_top_srcdir=`cd $use_top_srcdir && cd ../.. && pwd` fi fi @@ -73,7 +73,7 @@ AC_ARG_VAR([main_top_srcdir],[path to the MPICH top-level source directory (if p # since some of the Makefile targets require it. if test "X$main_top_srcdir" = "X" -a "$USE_MAINTAINER_MODE" = "yes" ; then if test -z "$top_srcdir" ; then - use_top_srcdir=$srcdir + use_top_srcdir=$srcdir else use_top_srcdir=$top_srcdir fi @@ -82,19 +82,19 @@ if test "X$main_top_srcdir" = "X" -a "$USE_MAINTAINER_MODE" = "yes" ; then /*) ;; *) use_top_srcdir=`(cd $use_top_srcdir && pwd)` - ;; + ;; esac # Now, see if we can find the f77tof90 routine if test -x $use_top_srcdir/maint/f77tof90 ; then main_top_srcdir=$use_top_srcdir - else + else AC_MSG_ERROR([Unable to find main source file - reconfigure using --disable-maintainer_mode]) fi fi AC_ARG_ENABLE(echo, - [AS_HELP_STRING([--enable-echo],[Turn on strong echoing. The default is enable=no.])], - [set -x]) + [AC_HELP_STRING([--enable-echo],[Turn on strong echoing. The default is enable=no.])], + [set -x]) AC_ARG_ENABLE(fortran, [ --enable-fortran=option - Control the level of Fortran support in the MPICH implementation. @@ -142,105 +142,105 @@ fi AC_SUBST(DTP_SWITCH) AC_ARG_ENABLE(cxx, - [AS_HELP_STRING([--enable-cxx],[Turn on C++ tests (default)])],,[enable_cxx=yes]) + [AC_HELP_STRING([--enable-cxx],[Turn on C++ tests (default)])],,[enable_cxx=yes]) AC_ARG_ENABLE(romio, - [AS_HELP_STRING([--enable-romio],[Enable ROMIO MPI I/O implementation])],, - [enable_romio=yes]) + [AC_HELP_STRING([--enable-romio],[Enable ROMIO MPI I/O implementation])],, + [enable_romio=yes]) AC_ARG_ENABLE(spawn, - [AS_HELP_STRING([--enable-spawn], - [Enable tests of the dynamic process parts of MPI-2 (default)])],, - [enable_spawn=yes]) + [AC_HELP_STRING([--enable-spawn], + [Enable tests of the dynamic process parts of MPI-2 (default)])],, + [enable_spawn=yes]) AC_ARG_ENABLE(rma, - [AS_HELP_STRING([--enable-rma],[Enable tests of the one sided parts of MPI-2 (default)])],, - [enable_rma=yes]) + [AC_HELP_STRING([--enable-rma],[Enable tests of the one sided parts of MPI-2 (default)])],, + [enable_rma=yes]) AC_ARG_ENABLE(part, - [AS_HELP_STRING([--enable-part],[Enable tests of partitioned communication of MPI-4 (default)])],, - [enable_part=yes]) + [AS_HELP_STRING([--enable-part],[Enable tests of partitioned communication of MPI-4 (default)])],, + [enable_part=yes]) AC_ARG_ENABLE(long-double-complex, - [AS_HELP_STRING([--enable-long-double-complex], - [Enable tests involving MPI_LONG_DOUBLE_COMPLEX (default)])],, - [enable_long_double_complex=yes]) + [AS_HELP_STRING([--enable-long-double-complex], + [Enable tests involving MPI_LONG_DOUBLE_COMPLEX (default)])],, + [enable_long_double_complex=yes]) AC_ARG_ENABLE(long-double, - [AS_HELP_STRING([--enable-long-double-complex], - [Enable tests involving MPI_LONG_DOUBLE and related types (default)])],, - [enable_long_double=yes]) + [AS_HELP_STRING([--enable-long-double-complex], + [Enable tests involving MPI_LONG_DOUBLE and related types (default)])],, + [enable_long_double=yes]) AC_ARG_ENABLE(checkerrors, - [AS_HELP_STRING([--enable-checkerrors], - [Add some tests for checking for errors in user programs])],, - [enable_checkerrors=yes]) + [AS_HELP_STRING([--enable-checkerrors], + [Add some tests for checking for errors in user programs])],, + [enable_checkerrors=yes]) AC_ARG_ENABLE(perftest, - [AS_HELP_STRING([--enable-perftest], - [Include tests for basic performance consistency (default)])],, - [enable_perftest=yes]) + [AS_HELP_STRING([--enable-perftest], + [Include tests for basic performance consistency (default)])],, + [enable_perftest=yes]) AC_ARG_ENABLE(large-tests, - [AS_HELP_STRING([--enable-large-tests], - [Enable tests which require large (>2GB per proc) amount of memory])],, - [enable_large_tests=no]) + [AS_HELP_STRING([--enable-large-tests], + [Enable tests which require large (>2GB per proc) amount of memory])],, + [enable_large_tests=no]) AC_ARG_ENABLE(ft-tests, - [AS_HELP_STRING([--enable-ft-tests], - [Include tests for fault tolerance (default no)])],, - [enable_ft_tests=no]) + [AS_HELP_STRING([--enable-ft-tests], + [Include tests for fault tolerance (default no)])],, + [enable_ft_tests=no]) AC_ARG_ENABLE(comm-overlap-tests, - [AS_HELP_STRING([--enable-comm-overlap-tests], - [Include tests for communicator overlap (default)])],, - [enable_comm_overlap_tests=yes]) + [AS_HELP_STRING([--enable-comm-overlap-tests], + [Include tests for communicator overlap (default)])],, + [enable_comm_overlap_tests=yes]) AC_ARG_ENABLE(checkfaults, - [AS_HELP_STRING([--enable-checkfaults], - [Add some tests for checking on handling of faults in user programs])],, - [enable_checkfaults=no]) + [AS_HELP_STRING([--enable-checkfaults], + [Add some tests for checking on handling of faults in user programs])],, + [enable_checkfaults=no]) AC_ARG_ENABLE(checkpointing, - [AS_HELP_STRING([--enable-checkpointing], - [Add some tests for checkpointing])],, - [enable_checkpointing=no]) + [AS_HELP_STRING([--enable-checkpointing], + [Add some tests for checkpointing])],, + [enable_checkpointing=no]) AC_ARG_ENABLE(fast, - [AS_HELP_STRING([--enable-fast], - [Indicates that the MPI implementation may have been - built for fastest operation, such as building without - error checking. Has the effect of - --enable-checkerrors=no])],,) + [AS_HELP_STRING([--enable-fast], + [Indicates that the MPI implementation may have been + built for fastest operation, such as building without + error checking. Has the effect of + --enable-checkerrors=no])],,) AC_ARG_ENABLE(strictmpi, - [AS_HELP_STRING([--enable-strictmpi], - [Only test for operations specifically defined by the - MPI standard. This turns off tests for some common - extensions, including for combinations of predefined - datatypes and predefined MPI_Op s.])],, - [enable_strictmpi=no]) + [AS_HELP_STRING([--enable-strictmpi], + [Only test for operations specifically defined by the + MPI standard. This turns off tests for some common + extensions, including for combinations of predefined + datatypes and predefined MPI_Op s.])],, + [enable_strictmpi=no]) AC_ARG_ENABLE(threads, - [--enable-threads=level - Specify the level of thread support expected from the - MPI implementation. The following levels are supported. - - single - No threads (MPI_THREAD_SINGLE) - funneled - Only the main thread calls MPI (MPI_THREAD_FUNNELED) - serialized - User serializes calls to MPI (MPI_THREAD_SERIALIZED) - multiple - Fully multi-threaded (MPI_THREAD_MULTIPLE) - - The default is funneled. If enabled and no level is - specified, the level is set to multiple. If disabled, the - level is set to single. If the environment variable - MPICH_THREAD_LEVEL is set, that thread level is used (this is - to let MPICH build for the correct thread support without - requiring a specific --enable-threads argument.],, - [enable_threads=default]) + [--enable-threads=level - Specify the level of thread support expected from the + MPI implementation. The following levels are supported. + + single - No threads (MPI_THREAD_SINGLE) + funneled - Only the main thread calls MPI (MPI_THREAD_FUNNELED) + serialized - User serializes calls to MPI (MPI_THREAD_SERIALIZED) + multiple - Fully multi-threaded (MPI_THREAD_MULTIPLE) + + The default is funneled. If enabled and no level is + specified, the level is set to multiple. If disabled, the + level is set to single. If the environment variable + MPICH_THREAD_LEVEL is set, that thread level is used (this is + to let MPICH build for the correct thread support without + requiring a specific --enable-threads argument.],, + [enable_threads=default]) AC_ARG_ENABLE(xfail, - [AS_HELP_STRING([--enable-xfail], - [Run tests marked for expected failure])],, - [enable_xfail=no]) + [AC_HELP_STRING([--enable-xfail], + [Run tests marked for expected failure])],, + [enable_xfail=no]) AC_ARG_ENABLE(gpu-tests-only, [AS_HELP_STRING([--enable-gpu-tests-only], @@ -265,13 +265,13 @@ cmd="$PYTHON $srcdir/maint/gen_coll_cvar.py" AC_CONFIG_COMMANDS([collcvartests],[$cmd_gen_coll],[cmd_gen_coll="$cmd"]) AC_ARG_WITH(mpi, - [AS_HELP_STRING([--with-mpi=dir], - [Use the selected MPI; compilation scripts for mpicc, - mpifort and mpicxx should be in dir/bin])],,) + [AC_HELP_STRING([--with-mpi=dir], + [Use the selected MPI; compilation scripts for mpicc, + mpifort and mpicxx should be in dir/bin])],,) AC_ARG_WITH(pm, - AS_HELP_STRING([--with-pm=name], - [Specify the process manager for MPICH. "no" or "none" are + AC_HELP_STRING([--with-pm=name], + [Specify the process manager for MPICH. "no" or "none" are valid values. Multiple process managers may be specified as long as they all use the same pmi interface by separating them with colons. The mpiexec for the first named process manager @@ -314,17 +314,17 @@ else fi AC_ARG_WITH(config-args, - [AS_HELP_STRING([--with-config-args=filename], - [Specify configure argument file that contains the - values of variables that configure reads, - e.g. CC,CFLAGS,F77,FFLAGS,FC,FCFLAGS.... If the - filename does not begin with / (absolute path), . or - .. (relative path), the filename will be assumed to be - $top_srcdir/configargs/.cfg.])],, - [with_config_args=no]) + [AC_HELP_STRING([--with-config-args=filename], + [Specify configure argument file that contains the + values of variables that configure reads, + e.g. CC,CFLAGS,F77,FFLAGS,FC,FCFLAGS.... If the + filename does not begin with / (absolute path), . or + .. (relative path), the filename will be assumed to be + $top_srcdir/configargs/.cfg.])],, + [with_config_args=no]) if test "$with_config_args" != "no" ; then - case "$with_config_args" in + case "$with_config_args" in /*|../*|./*) config_args_file="$with_config_args" ;; @@ -366,13 +366,13 @@ AC_ARG_VAR([MPICH_THREAD_LEVEL], [the MPI thread level supported by the enclosing MPICH build (when built within MPICH)]) # ------------------------------------------------------------------------ -if test "$enable_threads" = "yes" ; then +if test "$enable_threads" = "yes" ; then enable_threads=multiple elif test "$enable_threads" = "no" ; then enable_threads=single elif test "$enable_threads" = default ; then if test -n "$MPICH_THREAD_LEVEL" ; then - case $MPICH_THREAD_LEVEL in + case $MPICH_THREAD_LEVEL in MPI_THREAD_MULTIPLE) enable_threads=multiple ;; @@ -422,12 +422,12 @@ else fi AC_SUBST(comm_overlap) -# +# # Only run the threads tests if multiple is specified if test "$enable_threads" = "multiple" -o "$enable_threads" = "runtime" ; then threadsdir="threads" fi -# +# # Only run the checkpointing tests if enabled ckpointdir="#ckpoint" if test "$enable_checkpointing" = "yes" ; then @@ -473,7 +473,7 @@ fi # Some MPI-2 implementations (including some of the MPICH shared-memory # channels and BG/L) leave out the dynamic process routines. This -# allows tests to avoid reporting failure for these routines. +# allows tests to avoid reporting failure for these routines. # This can be controlled by either a --disable-spawn argument or by # setting the environment variable MPI_NO_SPAWN to yes. AC_ARG_VAR([MPI_NO_SPAWN],[set to "yes" to disable dynamic process tests]) @@ -604,11 +604,11 @@ else fi if test "x$MPICC" != "x" ; then CC=$MPICC - fi + fi if test -z "$MPIF77" ; then AC_PATH_PROG(MPIF77,$MPIF77_NAME mpf77) fi - if test "x$MPIF77" != "x" ; then + if test "x$MPIF77" != "x" ; then F77=$MPIF77 fi if test -z "$MPIFC" ; then @@ -618,13 +618,13 @@ else FC=$MPIFC fi if test -z "$MPICXX" ; then - # We left mpiCC off of this list because mpicc and mpiCC are the + # We left mpiCC off of this list because mpicc and mpiCC are the # same on Mac OSX systems. AC_PATH_PROG(MPICXX,$MPICXX_NAME mpCC) fi if test "x$MPICXX" != "x" ; then CXX=$MPICXX - fi + fi if test -z "$MPIEXEC" ; then AC_PATH_PROG(MPIEXEC,$MPIEXEC_NAME) fi @@ -645,8 +645,8 @@ AM_PROG_CC_C_O # Ensure that we can compile an MPI program before we go any further # We don't use a cached value here because this is a sanity check -# The exception is if we are executing this configure from within the -# MPICH configure - in that case, the +# The exception is if we are executing this configure from within the +# MPICH configure - in that case, the if test "$FROM_MPICH" != "yes" ; then AC_MSG_CHECKING([whether we can compile and link MPI programs in C]) AC_LINK_IFELSE([ @@ -664,7 +664,7 @@ dnl same test in the MPICH configure. # Check on support for long double and long long types. Do this before the # structure alignment test because it will test for including those # types as well -# +# # If --disable-long-double is selected, then bypass this test. # Some MPI implementations may choose to not support long double because # their C compilers are inconsistent on the length of long double (this @@ -685,7 +685,7 @@ AC_CACHE_CHECK([whether long long is supported],pac_cv_have_long_long,[ AC_LANG_PROGRAM([],[long long a;]) ],[pac_cv_have_long_long=yes],[pac_cv_have_long_long=no]) ]) -if test "$pac_cv_have_long_long" = yes ; then +if test "$pac_cv_have_long_long" = yes ; then AC_DEFINE(HAVE_LONG_LONG,1,[Define if compiler supports long long]) fi # @@ -903,7 +903,7 @@ case $with_thread_package in THREAD_PACKAGE_NAME=THREAD_PACKAGE_NONE ;; *) - AC_MSG_ERROR([The specified thread package, $with_thread_package, is not supported.]) + AC_MSG_ERROR([The specified thread package, $with_thread_package, is not supported.]) ;; esac @@ -943,7 +943,7 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include "mpi.h"],[MPI_Init(0,0);MPI_Finaliz AC_CACHE_CHECK([for major version of MPI],pac_cv_mpi_major_version,[ for pac_cv_mpi_major_version in 3 2 1 unknown ; do AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include "mpi.h"],[ -#if MPI_VERSION == $pac_cv_mpi_major_version +#if MPI_VERSION == $pac_cv_mpi_major_version ''' force failure ''' #endif])],,break) done @@ -952,7 +952,7 @@ done AC_CACHE_CHECK([for minor version of MPI],pac_cv_mpi_minor_version,[ for pac_cv_mpi_minor_version in 4 3 2 1 0 unknown ; do AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include "mpi.h"],[ -#if MPI_SUBVERSION == $pac_cv_mpi_minor_version +#if MPI_SUBVERSION == $pac_cv_mpi_minor_version ''' force failure ''' #endif])],,break) done @@ -960,15 +960,15 @@ done MPI_VERSION=$pac_cv_mpi_major_version MPI_SUBVERSION=$pac_cv_mpi_minor_version else - # We are within the MPICH build. Extract the MPI versions from - # mpi.h.in + # We are within the MPICH build. Extract the MPI versions from + # mpi.h.in if test ! -f $mpich_top_srcdir/src/include/mpi.h.in ; then AC_MSG_ERROR([Could not find the required mpi.h.in file!]) fi MPI_VERSION=`grep MPI_VERSION $mpich_top_srcdir/src/include/mpi.h.in | \ - sed -e 's/#define *MPI_VERSION *\([0-4]\).*/\1/g'` + sed -e 's/#define *MPI_VERSION *\([0-4]\).*/\1/g'` MPI_SUBVERSION=`grep MPI_SUBVERSION $mpich_top_srcdir/src/include/mpi.h.in | \ - sed -e 's/#define *MPI_SUBVERSION *\([0-9]\).*/\1/g'` + sed -e 's/#define *MPI_SUBVERSION *\([0-9]\).*/\1/g'` fi AC_SUBST(MPI_VERSION) @@ -980,9 +980,9 @@ if test "$enable_f77" = yes ; then # If there is no working F77, then set enable_f77 to no if test -z "$F77" ; then enable_f77=no - fi + fi fi -# Simple tests for which other languages we can handle. +# Simple tests for which other languages we can handle. # Use these only when configuring separate from an MPICH build f77dir="#" AC_SUBST(f77dir) @@ -1017,7 +1017,7 @@ elif test "$enable_f77" = yes ; then AC_LANG_POP([Fortran 77]) fi # -# At least one test (C++ test of C and Fortran datatypes) needs to +# At least one test (C++ test of C and Fortran datatypes) needs to # know if Fortran is supported if test "$f77dir" = "f77" ; then AC_DEFINE(HAVE_FORTRAN_BINDING,1,[Define if Fortran is supported]) @@ -1040,17 +1040,17 @@ if test "$buildingF77" = "yes" ; then # Aint should be an address-sized integer, the same as void* # We use a test on the size of void * to avoid any complications # in dealing with running programs containing MPI headers (e.g., - # the IBM MPI changes the main entry point so that MPI + # the IBM MPI changes the main entry point so that MPI # programs cannot be run on the host node) AC_CHECK_SIZEOF(void *) MPI_SIZEOF_AINT=$ac_cv_sizeof_void_p fi if test -z "$MPI_SIZEOF_OFFSET" ; then - # We have to try and get the size of offset anyway, since + # We have to try and get the size of offset anyway, since # it is not the same as void * (it depends on the available # file systems). Since we want to avoid using the MPI linker, # we could do the following: - # Use the mpi compiler to compile the file, using the mpi + # Use the mpi compiler to compile the file, using the mpi # header but no MPI calls # Use the regular C linker to link the program # However, we do this only if the environment variable BASECC @@ -1077,7 +1077,7 @@ dnl } dnl EOF dnl # FIXME. Check for BASECC dnl # Note: This assumes that CC has been set to the C compiler for -dnl # MPI Programs, and that either any necessary include paths are +dnl # MPI Programs, and that either any necessary include paths are dnl # already set or they are in CPPFLAGS (preferred) or CFLAGS. dnl if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext ; then dnl if ./conftest$ac_exeext ; then @@ -1106,7 +1106,7 @@ dnl ]) MPI_SIZEOF_OFFSET=$ac_cv_sizeof_MPI_Offset fi fi - + AC_LANG_PUSH([Fortran 77]) AC_CACHE_CHECK([whether integer*4 is supported],pac_cv_fort_integer4,[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[ integer*4 i])], @@ -1148,20 +1148,20 @@ dnl ]) cat > f77/init/checksizes.c < -int main( int argc, char **argv ) +int main( int argc, char **argv ) { int fsizeof_aint = $MPI_SIZEOF_AINT; int fsizeof_offset = $MPI_SIZEOF_OFFSET; int err = 0, rc = 0; - + MPI_Init( &argc, &argv ); if (sizeof(MPI_Aint) != fsizeof_aint) { - printf( "Sizeof MPI_Aint is %d but Fortran thinks it is %d\n", + printf( "Sizeof MPI_Aint is %d but Fortran thinks it is %d\n", (int)sizeof(MPI_Aint), fsizeof_aint ); err++; } if (sizeof(MPI_Offset) != fsizeof_offset) { - printf( "Sizeof MPI_Offset is %d but Fortran thinks it is %d\n", + printf( "Sizeof MPI_Offset is %d but Fortran thinks it is %d\n", (int)sizeof(MPI_Offset), fsizeof_offset ); err++; } @@ -1178,7 +1178,7 @@ EOF # Check that the Fortran compiler will allow us to pass arguments # of different types (e.g., for MPI_Send) - # Any strict Fortran compiler will require that the arguments be + # Any strict Fortran compiler will require that the arguments be # the same type - currently, the NAG Fortran compiler (nagfor) is known # to enforce this. # We could set the FFLAGS/FCFLAGS values with the option that disables @@ -1186,22 +1186,22 @@ EOF # instead we tell the user and exit. PAC_PROG_F77_MISMATCHED_ARGS(addarg,yes) if test "X$addarg" != "X" ; then - # We could add the names of all of the MPI routines that - # accept different types. Instead, we fail cleanly. - # Some Fortran compilers allow you to turn off checking for + # We could add the names of all of the MPI routines that + # accept different types. Instead, we fail cleanly. + # Some Fortran compilers allow you to turn off checking for # mismatched arguments for *all* routines. Adding an argument - # that turns off checking for *everything* is not something that - # configure should do - if the user wants this, they can follow - # the instructions in the following error message. - AC_MSG_ERROR([The Fortran compiler $F77 does not accept programs that call the same routine with arguments of different types without the option $addarg. Rerun configure with FFLAGS=$addarg]) + # that turns off checking for *everything* is not something that + # configure should do - if the user wants this, they can follow + # the instructions in the following error message. + AC_MSG_ERROR([The Fortran compiler $F77 does not accept programs that call the same routine with arguments of different types without the option $addarg. Rerun configure with FFLAGS=$addarg]) fi - # Check whether we need -lU77 to get iargc and getarg, which + # Check whether we need -lU77 to get iargc and getarg, which # are used for a few of the tests in spawn (U77 was needed with - # the native compilers on HPUX. See the aclocal_f77(old).m4 file, + # the native compilers on HPUX. See the aclocal_f77(old).m4 file, # which has a much more complete set of tests. # - # FIXME: if we can't figure out how to get iargc/getarg, then + # FIXME: if we can't figure out how to get iargc/getarg, then # we should really turn off those spawn tests # Even better is to limit this to the F200x version, where there is # an interface to the command line. @@ -1238,10 +1238,10 @@ EOF if test -n "$F77_GETARG_LIBS" ; then AC_MSG_RESULT($F77_GETARG_LIBS) else - if test "$pac_cv_getarg_needs_u77" = "unavailable" ; then + if test "$pac_cv_getarg_needs_u77" = "unavailable" ; then AC_MSG_RESULT([getarg and/or iargc are not available. Some spawn tests will fail to link]) - F77SPAWNARGTEST="#" - else + F77SPAWNARGTEST="#" + else AC_MSG_RESULT([none needed]) fi fi @@ -1249,8 +1249,8 @@ EOF # FIXME: Currently, we hope that FC accepts the same library FC_GETARG_LIBS="$F77_GETARG_LIBS" AC_SUBST(FC_GETARG_LIBS) - # F77SPAWNARGTEST is set to "#" to comment out tests in - # f77/spawn/testlist.in that require non-standard extensions to + # F77SPAWNARGTEST is set to "#" to comment out tests in + # f77/spawn/testlist.in that require non-standard extensions to # access the commandline AC_SUBST(F77SPAWNARGTEST) @@ -1304,12 +1304,12 @@ fi dnl If enable_fc=yes up to this point then enable_f77=yes also dnl PAC_PROG_FC and PAC_PROG_FC_WORKS return OK if test "$enable_fc" = yes ; then - # Make sure that the compilers are compatible. This + # Make sure that the compilers are compatible. This # will also make sure that the program named in FC is # a working Fortran 90 compiler - # Only check if we're *not* building within MPICH + # Only check if we're *not* building within MPICH # (MPICH will have made the test) - # FIXME: Do we want to check only simple routine names + # FIXME: Do we want to check only simple routine names # (those without an underscore?) if test "$FROM_MPICH" != yes ; then PAC_FC_AND_F77_COMPATIBLE(enable_fc=yes,enable_fc=no) @@ -1332,7 +1332,7 @@ if test "$enable_fc" = yes ; then # The Fortran90 tests rely on free-form input which needs to be tested # before any test that may modify FCFLAGS, e.g. the cray-pointer test. # The order of the tests is important in compiler like g95. - # Recent experience showed that the IBM xlf compiler, at least on + # Recent experience showed that the IBM xlf compiler, at least on # some systems, requires -qfree=f90 instead of -qfree . At this # writing (11/27/12), this Autoconf macro still uses -qfree and has # no mechanism for extension. This test may fail in that case; if @@ -1361,9 +1361,9 @@ if test "$enable_fc" = yes ; then AC_MSG_RESULT($pac_cv_fc_has_args) if test "$pac_cv_fc_has_args" != "yes" ; then F03SPAWNARGTEST="#" - fi - # F03SPAWNARGTEST is set to "#" to comment out tests in - # f90/spawn/testlist.in that require Fortran 2003 features to + fi + # F03SPAWNARGTEST is set to "#" to comment out tests in + # f90/spawn/testlist.in that require Fortran 2003 features to # access the commandline AC_SUBST(F03SPAWNARGTEST) AC_LANG_POP([Fortran]) @@ -1438,8 +1438,8 @@ if test "$FROM_MPICH" = yes ; then otherlangs="$otherlangs cxx" cxxdir=cxx # MPICH ABI removed support for MPI::Distgraphcomm, so - # nocxxdistgraph is left as #, which comments out the test - # in cxx/topol/testlist.in + # nocxxdistgraph is left as #, which comments out the test + # in cxx/topol/testlist.in fi elif test "$enable_cxx" = yes ; then AC_MSG_CHECKING([that we can build MPI programs with C++]) @@ -1499,7 +1499,7 @@ if test "$enable_cxx" = yes ; then fi # Warning: the autoconf macros will fall back onto /lib/cpp for # C and C++ preprocessing *without* checking that /lib/cpp even - # exists. + # exists. if test "$CXXCPP" = "/lib/cpp" ; then if test ! -x "/lib/cpp" ; then AC_MSG_WARN([Warning: Autoconf error, could not find a C++ Preprocessor. Using false for the preprocessor so that tests will continue.]) @@ -1509,8 +1509,8 @@ if test "$enable_cxx" = yes ; then fi AX_CXX_NAMESPACE_STD - - if test "$ac_cv_cxx_namespaces" != yes ; then + + if test "$ac_cv_cxx_namespaces" != yes ; then AC_MSG_WARN([The compiler $CXX does not support C++ namespaces. This may cause problems for the tests]) fi AC_LANG_POP([C++]) @@ -1528,7 +1528,7 @@ if test "$enable_romio" != no ; then if test "$FROM_MPICH" = yes ; then # MPICH no longer uses and MPIO_Request pac_cv_have_mpio_request=no - else + else AC_CACHE_CHECK([whether MPIO_Request is defined for MPI IO], pac_cv_have_mpio_request,[ AC_COMPILE_IFELSE([ @@ -1564,7 +1564,7 @@ fi AC_SUBST(impldir) # # MPI_INTEGER16 is mentioned in only one place in MPI 2.1, and some -# implementations may have missed it. Check to see if it is available in +# implementations may have missed it. Check to see if it is available in # C. if test "$FROM_MPICH" = yes ; then # MPICH correctly includes this type. @@ -1579,11 +1579,11 @@ else ],[pac_cv_have_mpi_integer16=yes],[pac_cv_have_mpi_integer16=no]) ]) fi -if test "$pac_cv_have_mpi_integer16" = yes ; then +if test "$pac_cv_have_mpi_integer16" = yes ; then AC_DEFINE(HAVE_MPI_INTEGER16,1,[Define if MPI_INTEGER16 is available]) fi -# MPI_Aint was intended as an address-sized int. However, MPI didn't +# MPI_Aint was intended as an address-sized int. However, MPI didn't # specify this - MPI_Aint must be large enough to hold an address-sized # integer, but it can be larger. To get clean compilation in some places, # we need a pointer-sized integer. The following code looks for one. @@ -1608,7 +1608,7 @@ done AC_MSG_RESULT($POINTERINT) AC_DEFINE_UNQUOTED(POINTERINT_t,$POINTERINT,[POINTERINT_t is a pointer-sized integer]) -# Find perl; used to create some of the tests from template and +# Find perl; used to create some of the tests from template and # definition files AC_PATH_PROG(PERL,perl) AC_SUBST(PERL) @@ -1627,10 +1627,10 @@ AC_SUBST(MPI_SOURCE) if test "$FROM_MPICH" = yes ; then # Set compilers/flags to be substituted in output files, e.g. Makefiles. LDFLAGS="$saveLDFLAGS" - # note that the default definition of bindir is + # note that the default definition of bindir is # '${exec_prefix}/bin' # so even if prefix is set, exec prefix is not until - # the very last moment (i.e., not here). + # the very last moment (i.e., not here). if test "X$exec_prefix" = "XNONE" ; then saveExec_prefix=$exec_prefix if test "X$prefix" = "XNONE" ; then @@ -1702,7 +1702,7 @@ AC_OUTPUT(maint/testmerge \ attr/testlist \ util/Makefile \ coll/Makefile \ - coll/testlist \ + coll/testlist \ comm/Makefile \ comm/testlist \ datatype/Makefile \ @@ -1737,7 +1737,7 @@ AC_OUTPUT(maint/testmerge \ f77/pt2pt/Makefile \ f77/info/Makefile \ f77/spawn/Makefile \ - f77/spawn/testlist \ + f77/spawn/testlist \ f77/spawn/type1aint.h \ f77/rma/Makefile \ f77/ext/Makefile \ @@ -1747,7 +1747,7 @@ AC_OUTPUT(maint/testmerge \ f77/io/iodisp.h \ f77/io/ioaint.h \ f77/io/testlist \ - f77/profile/Makefile \ + f77/profile/Makefile \ f90/Makefile \ f90/attr/Makefile \ f90/datatype/Makefile \ @@ -1760,25 +1760,25 @@ AC_OUTPUT(maint/testmerge \ f90/rma/Makefile \ f90/info/Makefile \ f90/spawn/Makefile \ - f90/spawn/testlist \ + f90/spawn/testlist \ f90/timer/Makefile \ f90/ext/Makefile \ f90/ext/testlist \ f90/io/Makefile \ f90/io/testlist \ f90/misc/Makefile \ - f90/profile/Makefile \ - f08/Makefile \ - f08/attr/Makefile \ - f08/datatype/Makefile \ - f08/coll/Makefile \ - f08/comm/Makefile \ - f08/pt2pt/Makefile \ - f08/rma/Makefile \ - f08/subarray/Makefile \ - f08/topo/Makefile \ - f08/io/Makefile \ - f08/io/testlist \ + f90/profile/Makefile \ + f08/Makefile \ + f08/attr/Makefile \ + f08/datatype/Makefile \ + f08/coll/Makefile \ + f08/comm/Makefile \ + f08/pt2pt/Makefile \ + f08/rma/Makefile \ + f08/subarray/Makefile \ + f08/topo/Makefile \ + f08/io/Makefile \ + f08/io/testlist \ f08/init/Makefile \ f08/info/Makefile \ f08/spawn/Makefile \ @@ -1793,7 +1793,7 @@ AC_OUTPUT(maint/testmerge \ cxx/pt2pt/Makefile \ cxx/comm/Makefile \ cxx/coll/Makefile \ - cxx/errhan/Makefile \ + cxx/errhan/Makefile \ cxx/info/Makefile \ cxx/datatype/Makefile \ cxx/datatype/testlist \ @@ -1802,7 +1802,7 @@ AC_OUTPUT(maint/testmerge \ cxx/rma/Makefile \ cxx/spawn/Makefile \ cxx/spawn/testlist \ - cxx/topo/Makefile \ + cxx/topo/Makefile \ threads/Makefile \ threads/pt2pt/Makefile \ threads/comm/Makefile \ @@ -1837,18 +1837,18 @@ AC_OUTPUT(maint/testmerge \ errors/f77/io/addsize.h \ errors/f77/io/iooffset.h \ errors/f90/Makefile \ - errors/f90/io/Makefile \ + errors/f90/io/Makefile \ errors/f08/Makefile \ - errors/f08/io/Makefile \ - ckpoint/Makefile \ - ft/Makefile \ + errors/f08/io/Makefile \ + ckpoint/Makefile \ + ft/Makefile \ manual/Makefile \ manual/manyconnect \ manual/mpi_t/Makefile \ perf/Makefile \ testlist \ cxx/testlist \ - cxx/topo/testlist \ + cxx/topo/testlist \ f77/testlist \ f90/testlist \ f08/testlist \ From 59749b6b7840beea1339eaf2e0655cc6498f7b69 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 15 Feb 2021 14:37:55 -0600 Subject: [PATCH 199/607] test/config: remove FROM_MPICH Now we always configure test/mpi separately from MPICH -- in fact, always configure test/mpi after mpich is installed -- we can consolidate the configure to directly test features based on the installed mpi. --- test/mpi/configure.ac | 315 +++++++++++------------------------------- 1 file changed, 80 insertions(+), 235 deletions(-) diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index 585a33fc44d..557299d9fad 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -229,12 +229,9 @@ AC_ARG_ENABLE(threads, serialized - User serializes calls to MPI (MPI_THREAD_SERIALIZED) multiple - Fully multi-threaded (MPI_THREAD_MULTIPLE) - The default is funneled. If enabled and no level is + The default is to run check. If enabled and no level is specified, the level is set to multiple. If disabled, the - level is set to single. If the environment variable - MPICH_THREAD_LEVEL is set, that thread level is used (this is - to let MPICH build for the correct thread support without - requiring a specific --enable-threads argument.],, + level is set to single.],, [enable_threads=default]) AC_ARG_ENABLE(xfail, @@ -358,37 +355,23 @@ if test -n "$F90" -o -n "$F90FLAGS" ; then AC_MSG_ERROR([F90 and F90FLAGS are replaced by FC and FCFLAGS respectively in this configure, please unset F90/F90FLAGS and set FC/FCFLAGS instead and rerun configure again.]) fi -# ------------------------------------------------------------------------ -dnl use AC_ARG_VAR to mark FROM_MPICH as "precious" to autoconf so that -dnl automatic re-runs of config.status preserve its value correctly -AC_ARG_VAR([FROM_MPICH],[should be set to "yes" if this configure script is being invoked by the main MPICH configure]) -AC_ARG_VAR([MPICH_THREAD_LEVEL], - [the MPI thread level supported by the enclosing MPICH build (when built within MPICH)]) -# ------------------------------------------------------------------------ - +# check whether to enable thread tests +# if test "$enable_threads" = "yes" ; then enable_threads=multiple elif test "$enable_threads" = "no" ; then enable_threads=single elif test "$enable_threads" = default ; then - if test -n "$MPICH_THREAD_LEVEL" ; then - case $MPICH_THREAD_LEVEL in - MPI_THREAD_MULTIPLE) - enable_threads=multiple - ;; - MPI_THREAD_SERIALIZED) - enable_threads=serialized - ;; - MPI_THREAD_FUNNELED) - enable_threads=funneled - ;; - MPI_THREAD_SINGLE) - enable_threads=single - ;; - esac - else - enable_threads=funneled - fi + # I believe AC_TRY_RUN here is OK. The worst case (for cross compile) will result in + # multi-thread tests disabled. By pass by explicitly configure with --enable-threads=xxx + AC_TRY_RUN(AC_LANG_PROGRAM([#include "mpi.h"],[ + int provided = MPI_THREAD_SINGLE; + MPI_Init_thread(0,0,MPI_THREAD_MULTIPLE,&provided); + MPI_Finalize(); + if (provided != MPI_THREAD_MULTIPLE) exit(1); + ]), + [enable_threads=multiple], [enable_threads=single], [enable_threads=single] + ) fi # errordir is substituted into the testlist file as errors when the @@ -454,23 +437,6 @@ AC_SUBST(MPILIBLOC) AC_ARG_VAR([MPICH_ENABLE_FC],["yes" if the enclosing MPICH build supports modern Fortran]) AC_ARG_VAR([MPICH_ENABLE_CXX],["yes" if the enclosing MPICH build supports C++]) -# If we're building from MPICH, check the MPICH_ENABLE_xxx environment -# variables for enable defaults -if test "$FROM_MPICH" = yes ; then - if test -n "$MPICH_ENABLE_FC" ; then - enable_f77=$MPICH_ENABLE_FC - enable_fc=$MPICH_ENABLE_FC - fi - if test -n "$MPICH_ENABLE_CXX" ; then - enable_cxx=$MPICH_ENABLE_CXX - fi - namepub_tests="#" - if test -n "$nameserv_name" ; then - namepub_tests="" - fi - AC_SUBST(namepub_tests) -fi - # Some MPI-2 implementations (including some of the MPICH shared-memory # channels and BG/L) leave out the dynamic process routines. This # allows tests to avoid reporting failure for these routines. @@ -522,8 +488,8 @@ fi # based on earlier versions of MPICH. MPI_HAS_MPIX=no # -# Hack to detect build from within MPICH. Ensure strictmpi not selected. -if test "$FROM_MPICH" = "yes" -a "$enable_strictmpi" = "no" ; then +# If MPI is derived from MPICH and strictmpi not selected, let's test mpix extensions. +if test "$MPI_IS_MPICH" = "yes" -a "$enable_strictmpi" = "no" ; then MPI_HAS_MPIX=yes fi AC_SUBST(MPI_HAS_MPIX) @@ -556,24 +522,7 @@ PAC_GET_EXENAME("mpifort", MPIFORT_NAME) PAC_GET_EXENAME("mpicxx", MPICXX_NAME) PAC_GET_EXENAME("mpiexec", MPIEXEC_NAME) -if test "$FROM_MPICH" = "yes" ; then - # perform configure tests with the normal compilers ($CC/$F77/etc), but use - # the WRAPPER_xFLAGS computed by MPICH as our flags instead. Then at the - # end of configure we will empty out these flags and set our compilers to - # the installed compiler wrappers - CFLAGS="$WRAPPER_CFLAGS" - CPPFLAGS="$WRAPPER_CPPFLAGS" - LDFLAGS="$WRAPPER_LDFLAGS" - FFLAGS="$WRAPPER_FFLAGS" - FCFLAGS="$WRAPPER_FCFLAGS" - CXXFLAGS="$WRAPPER_CXXFLAGS" - - # WRAPPER_LIBS contains currently non-existent libs like "-lopa" and "-lmpl" - # right now, so set LIBS to the user-specified libs for now. - # FIXME Does this need to be an AC_ARG_VAR? - LIBS="$MPICH_LIBS" - -elif test -n "$with_mpi" ; then +if test -n "$with_mpi" ; then if test -z "$MPICC" ; then CC=$with_mpi/bin/$MPICC_NAME else @@ -639,25 +588,24 @@ AC_PROG_CC AC_PROG_CC_C99 AM_PROG_CC_C_O -# Note that some versions of autoconf will insist that the compiler -# produce executables at this point, which is why we must do something -# special for building within MPICH - # Ensure that we can compile an MPI program before we go any further # We don't use a cached value here because this is a sanity check -# The exception is if we are executing this configure from within the -# MPICH configure - in that case, the -if test "$FROM_MPICH" != "yes" ; then - AC_MSG_CHECKING([whether we can compile and link MPI programs in C]) - AC_LINK_IFELSE([ -AC_LANG_PROGRAM([#include "mpi.h"],[MPI_Init(0,0);MPI_Finalize();]) +AC_MSG_CHECKING([whether we can compile and link MPI programs in C]) +AC_LINK_IFELSE([ + AC_LANG_PROGRAM([#include "mpi.h"],[MPI_Init(0,0);MPI_Finalize();]) ],[mpi_compile_works=yes],[mpi_compile_works=no]) AC_MSG_RESULT($mpi_compile_works) - if test "$mpi_compile_works" != "yes" ; then - AC_MSG_ERROR([Unable to compile and/or link an MPI program! Check config.log]) - fi +if test "$mpi_compile_works" != "yes" ; then + AC_MSG_ERROR([Unable to compile and/or link an MPI program! Check config.log]) fi + +# Check whether we are testing MPI derived from MPICH +MPI_IS_MPICH=no +AC_MSG_CHECKING([Is the MPI derived from MPICH]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include "mpi.h"],[return 1 + MPICH;])], + [MPI_IS_MPICH=yes],[MPI_IS_MPICH=no]) + dnl We cannot use AC_C_LONG_DOUBLE dnl because it does not support cross-compilation. Instead, we use the dnl same test in the MPICH configure. @@ -934,42 +882,25 @@ AC_CHECK_FUNCS(getrusage) # Check for the MPI Version. This test assumes at least MPI 2.0. For # some tests, we need to know if we are MPI 2.1 or MPI 2.2, # particularly for new routines in Fortran -if test "$FROM_MPICH" != "yes" ; then - AC_CACHE_CHECK([that MPI program can be compiled],pac_cv_mpi_compile_ok,[ -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include "mpi.h"],[MPI_Init(0,0);MPI_Finalize();])],pac_cv_mpi_compile_ok=yes,pac_cv_mpi_compile_ok=no)]) - if test "$pac_cv_mpi_compile_ok" != yes ; then - AC_MSG_ERROR([Unable to compile an MPI program containing mpi.h!]) - fi - AC_CACHE_CHECK([for major version of MPI],pac_cv_mpi_major_version,[ -for pac_cv_mpi_major_version in 3 2 1 unknown ; do - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include "mpi.h"],[ +AC_CACHE_CHECK([for major version of MPI],pac_cv_mpi_major_version,[ + for pac_cv_mpi_major_version in 3 2 1 unknown ; do + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include "mpi.h"],[ #if MPI_VERSION == $pac_cv_mpi_major_version ''' force failure ''' #endif])],,break) -done + done ]) - AC_CACHE_CHECK([for minor version of MPI],pac_cv_mpi_minor_version,[ -for pac_cv_mpi_minor_version in 4 3 2 1 0 unknown ; do - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include "mpi.h"],[ +AC_CACHE_CHECK([for minor version of MPI],pac_cv_mpi_minor_version,[ + for pac_cv_mpi_minor_version in 4 3 2 1 0 unknown ; do + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include "mpi.h"],[ #if MPI_SUBVERSION == $pac_cv_mpi_minor_version ''' force failure ''' #endif])],,break) -done + done ]) MPI_VERSION=$pac_cv_mpi_major_version MPI_SUBVERSION=$pac_cv_mpi_minor_version -else - # We are within the MPICH build. Extract the MPI versions from - # mpi.h.in - if test ! -f $mpich_top_srcdir/src/include/mpi.h.in ; then - AC_MSG_ERROR([Could not find the required mpi.h.in file!]) - fi - MPI_VERSION=`grep MPI_VERSION $mpich_top_srcdir/src/include/mpi.h.in | \ - sed -e 's/#define *MPI_VERSION *\([0-4]\).*/\1/g'` - MPI_SUBVERSION=`grep MPI_SUBVERSION $mpich_top_srcdir/src/include/mpi.h.in | \ - sed -e 's/#define *MPI_SUBVERSION *\([0-9]\).*/\1/g'` -fi AC_SUBST(MPI_VERSION) AC_SUBST(MPI_SUBVERSION) @@ -987,14 +918,7 @@ fi f77dir="#" AC_SUBST(f77dir) buildingF77=no -if test "$FROM_MPICH" = yes ; then - if test "$enable_f77" = yes ; then - # Assume success - otherlangs="$otherlangs f77" - f77dir=f77 - buildingF77=yes - fi -elif test "$enable_f77" = yes ; then +if test "$enable_f77" = yes ; then AC_MSG_CHECKING([that we can build MPI programs with Fortran 77]) AC_LANG_PUSH([Fortran 77]) AC_LINK_IFELSE([ @@ -1307,13 +1231,7 @@ if test "$enable_fc" = yes ; then # Make sure that the compilers are compatible. This # will also make sure that the program named in FC is # a working Fortran 90 compiler - # Only check if we're *not* building within MPICH - # (MPICH will have made the test) - # FIXME: Do we want to check only simple routine names - # (those without an underscore?) - if test "$FROM_MPICH" != yes ; then - PAC_FC_AND_F77_COMPATIBLE(enable_fc=yes,enable_fc=no) - fi + PAC_FC_AND_F77_COMPATIBLE(enable_fc=yes,enable_fc=no) fi if test "$enable_fc" = yes ; then @@ -1381,12 +1299,7 @@ if test "$enable_fc" = yes ; then PAC_FC_MODULE fi # -if test "$FROM_MPICH" = yes ; then - if test "$enable_fc" = yes ; then - otherlangs="$otherlangs f90" - f90dir=f90 - fi -elif test "$enable_fc" = yes ; then +if test "$enable_fc" = yes ; then AC_MSG_CHECKING([that we can build MPI programs with Fortran 90]) AC_LANG_PUSH([Fortran]) AC_LINK_IFELSE([ @@ -1408,15 +1321,27 @@ elif test "$enable_fc" = yes ; then AC_LANG_POP([Fortran]) fi -if test "$enable_f08" = "yes" ; then - PAC_FC_2008_SUPPORT([enable_f08=yes],[enable_f08=no]) -fi - f08dir="#" AC_SUBST(f08dir) -# FIXME if $FROM_MPICH is no, we should test build an MPI F08 program -if test "$enable_f08" = "yes" -a "$FROM_MPICH" = "yes" ; then - f08dir=f08 +if test "$enable_f08" = "yes" ; then + AC_MSG_CHECKING([that we can build MPI programs with use mpi_f08]) + AC_LANG_PUSH([Fortran]) + AC_LINK_IFELSE([ + AC_LANG_SOURCE([ + program main + use mpi_f08 + integer ierr + call mpi_init(ierr) + call mpi_finalize(ierr) + end + ]) + ],[ + AC_MSG_RESULT(yes) + f08dir=f08 + ],[ + AC_MSG_RESULT(no) + ]) + AC_LANG_POP([Fortran]) fi # Running C++ compiler tests @@ -1433,15 +1358,7 @@ cxxdir="#" # us to detect that and to skip the test when it is not supported. nocxxdistgraph="#" AC_SUBST(cxxdir) -if test "$FROM_MPICH" = yes ; then - if test "$enable_cxx" = yes ; then - otherlangs="$otherlangs cxx" - cxxdir=cxx - # MPICH ABI removed support for MPI::Distgraphcomm, so - # nocxxdistgraph is left as #, which comments out the test - # in cxx/topol/testlist.in - fi -elif test "$enable_cxx" = yes ; then +if test "$enable_cxx" = yes ; then AC_MSG_CHECKING([that we can build MPI programs with C++]) AC_LANG_PUSH([C++]) AC_LINK_IFELSE([ @@ -1525,17 +1442,12 @@ iodir="#" if test "$enable_romio" != no ; then iodir=io AC_DEFINE(HAVE_MPI_IO,1,[Define if MPI-IO (really ROMIO) is included]) - if test "$FROM_MPICH" = yes ; then - # MPICH no longer uses and MPIO_Request - pac_cv_have_mpio_request=no - else - AC_CACHE_CHECK([whether MPIO_Request is defined for MPI IO], - pac_cv_have_mpio_request,[ - AC_COMPILE_IFELSE([ - AC_LANG_PROGRAM([#include "mpi.h"],[MPIO_Request r;]) - ],[pac_cv_have_mpio_request=yes],[pac_cv_have_mpio_request=no]) - ]) - fi + AC_CACHE_CHECK([whether MPIO_Request is defined for MPI IO], + pac_cv_have_mpio_request,[ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([#include "mpi.h"],[MPIO_Request r;]) + ],[pac_cv_have_mpio_request=yes],[pac_cv_have_mpio_request=no]) + ]) if test "$pac_cv_have_mpio_request" = no ; then AC_DEFINE(MPIO_USES_MPI_REQUEST,,[Define if MPI IO uses MPI_Request]) fi @@ -1546,39 +1458,23 @@ impldir="#" # # Check for implementation to enable implementation-specific options if test $enable_strictmpi != "yes" ; then - # Is this MPICH? - if test "$FROM_MPICH" = yes ; then - impldir="mpich" - else - AC_CACHE_CHECK([Is the MPI derived from MPICH], - pac_cv_ismpich,[ - AC_COMPILE_IFELSE([ - AC_LANG_PROGRAM([#include "mpi.h"],[return 1 + MPICH;]) - ],[pac_cv_ismpich=yes],[pac_cv_ismpich=no]) - ]) - if test "$pac_cv_ismpich" = "yes" ; then - impldir="mpich" - fi - fi + if test "$MPI_IS_MPICH" = "yes" ; then + impldir="mpich" + fi fi AC_SUBST(impldir) # # MPI_INTEGER16 is mentioned in only one place in MPI 2.1, and some # implementations may have missed it. Check to see if it is available in # C. -if test "$FROM_MPICH" = yes ; then - # MPICH correctly includes this type. - pac_cv_have_mpi_integer16=yes -else - AC_CACHE_CHECK([whether MPI_INTEGER16 is available], - pac_cv_have_mpi_integer16,[ - AC_COMPILE_IFELSE([ - AC_LANG_PROGRAM([#include "mpi.h"],[ - MPI_Datatype t = MPI_INTEGER16; - ]) - ],[pac_cv_have_mpi_integer16=yes],[pac_cv_have_mpi_integer16=no]) - ]) -fi +AC_CACHE_CHECK([whether MPI_INTEGER16 is available], +pac_cv_have_mpi_integer16,[ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([#include "mpi.h"],[ + MPI_Datatype t = MPI_INTEGER16; + ]) + ],[pac_cv_have_mpi_integer16=yes],[pac_cv_have_mpi_integer16=no]) +]) if test "$pac_cv_have_mpi_integer16" = yes ; then AC_DEFINE(HAVE_MPI_INTEGER16,1,[Define if MPI_INTEGER16 is available]) fi @@ -1624,60 +1520,9 @@ dnl the location of the source of the MPI implementation into the XML dnl summary file AC_SUBST(MPI_SOURCE) -if test "$FROM_MPICH" = yes ; then - # Set compilers/flags to be substituted in output files, e.g. Makefiles. - LDFLAGS="$saveLDFLAGS" - # note that the default definition of bindir is - # '${exec_prefix}/bin' - # so even if prefix is set, exec prefix is not until - # the very last moment (i.e., not here). - if test "X$exec_prefix" = "XNONE" ; then - saveExec_prefix=$exec_prefix - if test "X$prefix" = "XNONE" ; then - # Use the default - exec_prefix=$ac_default_prefix - else - exec_prefix=$prefix - fi - # Evaluate with the current setting of exec_prefix - eval mpibindir=${bindir} - exec_prefix=$saveExec_prefix - else - eval mpibindir=${bindir} - fi - - # we did our tests with the base compilers, now point the make system at the - # installed compiler wrappers for actually building the tests - CC=$mpibindir/$MPICC_NAME - F77=$mpibindir/$MPIF77_NAME - FC=$mpibindir/$MPIFORT_NAME - CXX=$mpibindir/$MPICXX_NAME - if test -z "$MPIEXEC" ; then - MPIEXEC=$mpibindir/$MPIEXEC_NAME - fi - - # Zero out the flags, since they are already contained in the compiler - # wrapper scripts. Note that this will kill any flags that have been added - # to the xFLAGS only in this script. - # - # The only real flags we seem to add in this script relate to cray - # pointer support in Fortran, so we include that var here where - # appropriate. - # - # The other case are the performance tests - for datatype performance, - # compiling with optimization is important. - CFLAGS="" - CPPFLAGS="" - LDFLAGS="" - LIBS="" - FFLAGS="$CRAYPTR_FFLAGS" - FCFLAGS="$CRAYPTR_FCFLAGS" - CXXFLAGS="" -else - # We need either mpiexec or mpirun. If we don't find them, - # the user will need to determine how to run a program - AC_PATH_PROG(MPIEXEC,$MPIEXEC_NAME) -fi +# We need either mpiexec or mpirun. If we don't find them, +# the user will need to determine how to run a program +AC_PATH_PROG(MPIEXEC,$MPIEXEC_NAME) # TODO: use variables such as has_f77 etc. instead of double use $f77dir etc. AM_CONDITIONAL([HAS_F77], [test $f77dir = f77]) From d99eb147ea494319c46b9765b782c43b1f18c1af Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 15 Feb 2021 18:28:10 -0600 Subject: [PATCH 200/607] test/config: add --enable-namepub option We used to get whether to test namepub tests by checking $nameserv_name from the mpich configure. Now that we configure separately, we need explicit option for this. --- test/mpi/configure.ac | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index 557299d9fad..56c41e1ebfb 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -148,6 +148,11 @@ AC_ARG_ENABLE(romio, [AC_HELP_STRING([--enable-romio],[Enable ROMIO MPI I/O implementation])],, [enable_romio=yes]) +AC_ARG_ENABLE(namepub, + [AC_HELP_STRING([--enable-namepub], + [Enable tests of the dynamic process parts of MPI-2 (default)])],, + [enable_namepub=yes]) + AC_ARG_ENABLE(spawn, [AC_HELP_STRING([--enable-spawn], [Enable tests of the dynamic process parts of MPI-2 (default)])],, @@ -437,6 +442,12 @@ AC_SUBST(MPILIBLOC) AC_ARG_VAR([MPICH_ENABLE_FC],["yes" if the enclosing MPICH build supports modern Fortran]) AC_ARG_VAR([MPICH_ENABLE_CXX],["yes" if the enclosing MPICH build supports C++]) +namepub_tests="#" +if test "$enable_namepub" = "yes" ; then + namepub_tests="" +fi +AC_SUBST(namepub_tests) + # Some MPI-2 implementations (including some of the MPICH shared-memory # channels and BG/L) leave out the dynamic process routines. This # allows tests to avoid reporting failure for these routines. From cf8c1bf1422783920de87c1ab7059bba0b9b5439 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 15 Feb 2021 14:54:20 -0600 Subject: [PATCH 201/607] test/config: move AC_PROG_CC earlier So we can do feature test with it. --- test/mpi/configure.ac | 182 +++++++++++++++++++++--------------------- 1 file changed, 91 insertions(+), 91 deletions(-) diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index 56c41e1ebfb..44e648b6e61 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -350,6 +350,97 @@ if test "$with_config_args" != "no" ; then fi fi +# Attach program prefix and suffix to executable names +PAC_GET_EXENAME("mpicc", MPICC_NAME) +PAC_GET_EXENAME("mpif77", MPIF77_NAME) +PAC_GET_EXENAME("mpifort", MPIFORT_NAME) +PAC_GET_EXENAME("mpicxx", MPICXX_NAME) +PAC_GET_EXENAME("mpiexec", MPIEXEC_NAME) + +if test -n "$with_mpi" ; then + if test -z "$MPICC" ; then + CC=$with_mpi/bin/$MPICC_NAME + else + CC=$MPICC + fi + if test -z "$MPIF77" ; then + F77=$with_mpi/bin/$MPIF77_NAME + else + F77=$MPIF77 + fi + if test -z "$MPIFC" ; then + FC=$with_mpi/bin/$MPIFORT_NAME + else + FC=$MPIFC + fi + if test -z "$MPICXX" ; then + CXX=$with_mpi/bin/$MPICXX_NAME + else + CXX=$MPICXX + fi + if test -z "$MPIEXEC" ; then + MPIEXEC=$with_mpi/bin/$MPIEXEC_NAME + fi +else + # Try to use mpicc etc names + if test -z "$MPICC" ; then + AC_PATH_PROG(MPICC,$MPICC_NAME mpcc) + fi + if test "x$MPICC" != "x" ; then + CC=$MPICC + fi + if test -z "$MPIF77" ; then + AC_PATH_PROG(MPIF77,$MPIF77_NAME mpf77) + fi + if test "x$MPIF77" != "x" ; then + F77=$MPIF77 + fi + if test -z "$MPIFC" ; then + AC_PATH_PROG(MPIFC,$MPIFORT_NAME mpftn) + fi + if test "x$MPIFC" != "x" ; then + FC=$MPIFC + fi + if test -z "$MPICXX" ; then + # We left mpiCC off of this list because mpicc and mpiCC are the + # same on Mac OSX systems. + AC_PATH_PROG(MPICXX,$MPICXX_NAME mpCC) + fi + if test "x$MPICXX" != "x" ; then + CXX=$MPICXX + fi + if test -z "$MPIEXEC" ; then + AC_PATH_PROG(MPIEXEC,$MPIEXEC_NAME) + fi +fi +# Make sure we export CC before configuring DTPools, since MPI is +# needed to build the library. +export CC +AC_CONFIG_SUBDIRS([dtpools]) + +# Running C compiler tests +AC_PROG_CC +AC_PROG_CC_C99 +AM_PROG_CC_C_O + +# Ensure that we can compile an MPI program before we go any further +# We don't use a cached value here because this is a sanity check +AC_MSG_CHECKING([whether we can compile and link MPI programs in C]) +AC_LINK_IFELSE([ + AC_LANG_PROGRAM([#include "mpi.h"],[MPI_Init(0,0);MPI_Finalize();]) + ],[mpi_compile_works=yes],[mpi_compile_works=no]) +AC_MSG_RESULT($mpi_compile_works) + +if test "$mpi_compile_works" != "yes" ; then + AC_MSG_ERROR([Unable to compile and/or link an MPI program! Check config.log]) +fi + +# Check whether we are testing MPI derived from MPICH +MPI_IS_MPICH=no +AC_MSG_CHECKING([Is the MPI derived from MPICH]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include "mpi.h"],[return 1 + MPICH;])], + [MPI_IS_MPICH=yes],[MPI_IS_MPICH=no]) + # First, determine whether we are/can support the language bindings # # Since F90/F90FLAGS are replaced by FC/FCFLAGS, rather than silently @@ -526,97 +617,6 @@ AC_ARG_VAR([WRAPPER_FFLAGS],[]) AC_ARG_VAR([WRAPPER_FCFLAGS],[]) AC_ARG_VAR([WRAPPER_CXXFLAGS],[]) -# Attach program prefix and suffix to executable names -PAC_GET_EXENAME("mpicc", MPICC_NAME) -PAC_GET_EXENAME("mpif77", MPIF77_NAME) -PAC_GET_EXENAME("mpifort", MPIFORT_NAME) -PAC_GET_EXENAME("mpicxx", MPICXX_NAME) -PAC_GET_EXENAME("mpiexec", MPIEXEC_NAME) - -if test -n "$with_mpi" ; then - if test -z "$MPICC" ; then - CC=$with_mpi/bin/$MPICC_NAME - else - CC=$MPICC - fi - if test -z "$MPIF77" ; then - F77=$with_mpi/bin/$MPIF77_NAME - else - F77=$MPIF77 - fi - if test -z "$MPIFC" ; then - FC=$with_mpi/bin/$MPIFORT_NAME - else - FC=$MPIFC - fi - if test -z "$MPICXX" ; then - CXX=$with_mpi/bin/$MPICXX_NAME - else - CXX=$MPICXX - fi - if test -z "$MPIEXEC" ; then - MPIEXEC=$with_mpi/bin/$MPIEXEC_NAME - fi -else - # Try to use mpicc etc names - if test -z "$MPICC" ; then - AC_PATH_PROG(MPICC,$MPICC_NAME mpcc) - fi - if test "x$MPICC" != "x" ; then - CC=$MPICC - fi - if test -z "$MPIF77" ; then - AC_PATH_PROG(MPIF77,$MPIF77_NAME mpf77) - fi - if test "x$MPIF77" != "x" ; then - F77=$MPIF77 - fi - if test -z "$MPIFC" ; then - AC_PATH_PROG(MPIFC,$MPIFORT_NAME mpftn) - fi - if test "x$MPIFC" != "x" ; then - FC=$MPIFC - fi - if test -z "$MPICXX" ; then - # We left mpiCC off of this list because mpicc and mpiCC are the - # same on Mac OSX systems. - AC_PATH_PROG(MPICXX,$MPICXX_NAME mpCC) - fi - if test "x$MPICXX" != "x" ; then - CXX=$MPICXX - fi - if test -z "$MPIEXEC" ; then - AC_PATH_PROG(MPIEXEC,$MPIEXEC_NAME) - fi -fi -# Make sure we export CC before configuring DTPools, since MPI is -# needed to build the library. -export CC -AC_CONFIG_SUBDIRS([dtpools]) - -# Running C compiler tests -AC_PROG_CC -AC_PROG_CC_C99 -AM_PROG_CC_C_O - -# Ensure that we can compile an MPI program before we go any further -# We don't use a cached value here because this is a sanity check -AC_MSG_CHECKING([whether we can compile and link MPI programs in C]) -AC_LINK_IFELSE([ - AC_LANG_PROGRAM([#include "mpi.h"],[MPI_Init(0,0);MPI_Finalize();]) - ],[mpi_compile_works=yes],[mpi_compile_works=no]) -AC_MSG_RESULT($mpi_compile_works) - -if test "$mpi_compile_works" != "yes" ; then - AC_MSG_ERROR([Unable to compile and/or link an MPI program! Check config.log]) -fi - -# Check whether we are testing MPI derived from MPICH -MPI_IS_MPICH=no -AC_MSG_CHECKING([Is the MPI derived from MPICH]) -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include "mpi.h"],[return 1 + MPICH;])], - [MPI_IS_MPICH=yes],[MPI_IS_MPICH=no]) - dnl We cannot use AC_C_LONG_DOUBLE dnl because it does not support cross-compilation. Instead, we use the dnl same test in the MPICH configure. From 2f12b59af4462dc1f1dfcdd13bf62c59e1147260 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 15 Feb 2021 17:00:44 -0600 Subject: [PATCH 202/607] test/config: remove unused WARPPER flags --- test/mpi/configure.ac | 9 --------- 1 file changed, 9 deletions(-) diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index 44e648b6e61..2444d15fbe6 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -608,15 +608,6 @@ AC_SUBST(mpix) # to noninst_PROGRAMS to skip building the tests when we do strict MPI test AM_CONDITIONAL([BUILD_MPIX_TESTS], [test "$enable_strictmpi" = "no"]) -# preserve these values across a reconfigure -AC_ARG_VAR([WRAPPER_CFLAGS],[]) -AC_ARG_VAR([WRAPPER_CPPFLAGS],[]) -AC_ARG_VAR([WRAPPER_LDFLAGS],[]) -AC_ARG_VAR([WRAPPER_LIBS],[]) -AC_ARG_VAR([WRAPPER_FFLAGS],[]) -AC_ARG_VAR([WRAPPER_FCFLAGS],[]) -AC_ARG_VAR([WRAPPER_CXXFLAGS],[]) - dnl We cannot use AC_C_LONG_DOUBLE dnl because it does not support cross-compilation. Instead, we use the dnl same test in the MPICH configure. From 652c520ad0a83b14dfbc701e972aad25eddccc4b Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 15 Feb 2021 17:01:55 -0600 Subject: [PATCH 203/607] test/config: remove non-applicable comments The comments on getting sizeof MPI_Offset without actually using MPI_Offset is no longer applicable now that we always to test configure after installing MPI. --- test/mpi/configure.ac | 51 ------------------------------------------- 1 file changed, 51 deletions(-) diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index 2444d15fbe6..77122cf5e1c 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -972,57 +972,6 @@ if test "$buildingF77" = "yes" ; then MPI_SIZEOF_AINT=$ac_cv_sizeof_void_p fi if test -z "$MPI_SIZEOF_OFFSET" ; then - # We have to try and get the size of offset anyway, since - # it is not the same as void * (it depends on the available - # file systems). Since we want to avoid using the MPI linker, - # we could do the following: - # Use the mpi compiler to compile the file, using the mpi - # header but no MPI calls - # Use the regular C linker to link the program - # However, we do this only if the environment variable BASECC - # has been provided. Else we can try the following: - # use - # sed -n 's/typedef \(.*\) MPI_Offset *;/\1/p' mpi.h - # to extract the type corresponding to MPI_Offset and then - # just use that. -dnl AC_CACHE_CHECK([the sizeof MPI_Offset],ac_cv_sizeof_MPI_Offset,[ -dnl ac_cv_sizeof_MPI_Offset=unknown -dnl rm -f conftest* -dnl cat >>conftest.c < -dnl int main( int argc, char **argv ) -dnl { -dnl MPI_Offset a; -dnl FILE *f = fopen("conftestval", "w" ); -dnl if (! f) exit(1); -dnl fprintf( f, "%ld\n", (long)sizeof(MPI_Offset) ); -dnl fclose(f); -dnl return 0; -dnl } -dnl EOF -dnl # FIXME. Check for BASECC -dnl # Note: This assumes that CC has been set to the C compiler for -dnl # MPI Programs, and that either any necessary include paths are -dnl # already set or they are in CPPFLAGS (preferred) or CFLAGS. -dnl if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext ; then -dnl if ./conftest$ac_exeext ; then -dnl #success -dnl ac_cv_sizeof_MPI_Offset=`cat conftestval` -dnl else -dnl # failure -dnl AC_MSG_WARN([Unable to run the program to determine the size of MPI_Offset]) -dnl echo "configure: failed program was:" >&AS_MESSAGE_LOG_FD -dnl cat conftest.c >&AS_MESSAGE_LOG_FD -dnl fi -dnl else -dnl # failure -dnl AC_MSG_WARN([Unable to build the program to determine the size of MPI_Offset]) -dnl echo "configure: failed program was:" >&AS_MESSAGE_LOG_FD -dnl cat conftest.c >&AS_MESSAGE_LOG_FD -dnl fi -dnl rm -f conftest* -dnl ]) AC_CHECK_SIZEOF([MPI_Offset],[],[#include "mpi.h"]) if test "$ac_cv_sizeof_MPI_Offset" = "unknown" \ -o "$ac_cv_sizeof_MPI_Offset" -eq 0 ; then From 6d9226bf14167664019bd5520cf0197ba2710c27 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 3 Apr 2021 10:08:59 -0500 Subject: [PATCH 204/607] test/config: add AC_USE_SYSTEM_EXTENSIONS Mainly we use strdup a lot and it requires _POSIX_C_SOURCE. Rather than adding tons of configure complexities, AC_USE_SYSTEM_EXTENSIONS should work for most platforms. --- test/mpi/configure.ac | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index 77122cf5e1c..69623e6f190 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -423,6 +423,8 @@ AC_PROG_CC AC_PROG_CC_C99 AM_PROG_CC_C_O +AC_USE_SYSTEM_EXTENSIONS + # Ensure that we can compile an MPI program before we go any further # We don't use a cached value here because this is a sanity check AC_MSG_CHECKING([whether we can compile and link MPI programs in C]) From 80007f1310547d3dbaeb0c9a7dc34ba6fffe85d8 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 1 Dec 2021 14:21:02 -0600 Subject: [PATCH 205/607] test/config: simplify option for multi-thread tests Default to enable, explicitly disable with --disable-threads. --- test/mpi/configure.ac | 42 +++++++----------------------------------- 1 file changed, 7 insertions(+), 35 deletions(-) diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index 69623e6f190..84d96a4a624 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -226,18 +226,9 @@ AC_ARG_ENABLE(strictmpi, [enable_strictmpi=no]) AC_ARG_ENABLE(threads, - [--enable-threads=level - Specify the level of thread support expected from the - MPI implementation. The following levels are supported. - - single - No threads (MPI_THREAD_SINGLE) - funneled - Only the main thread calls MPI (MPI_THREAD_FUNNELED) - serialized - User serializes calls to MPI (MPI_THREAD_SERIALIZED) - multiple - Fully multi-threaded (MPI_THREAD_MULTIPLE) - - The default is to run check. If enabled and no level is - specified, the level is set to multiple. If disabled, the - level is set to single.],, - [enable_threads=default]) + [AS_HELP_STRING([--enable-threads], + [Whether to enable multi-thread tests])],, + [enable_threads=yes]) AC_ARG_ENABLE(xfail, [AC_HELP_STRING([--enable-xfail], @@ -453,25 +444,6 @@ if test -n "$F90" -o -n "$F90FLAGS" ; then AC_MSG_ERROR([F90 and F90FLAGS are replaced by FC and FCFLAGS respectively in this configure, please unset F90/F90FLAGS and set FC/FCFLAGS instead and rerun configure again.]) fi -# check whether to enable thread tests -# -if test "$enable_threads" = "yes" ; then - enable_threads=multiple -elif test "$enable_threads" = "no" ; then - enable_threads=single -elif test "$enable_threads" = default ; then - # I believe AC_TRY_RUN here is OK. The worst case (for cross compile) will result in - # multi-thread tests disabled. By pass by explicitly configure with --enable-threads=xxx - AC_TRY_RUN(AC_LANG_PROGRAM([#include "mpi.h"],[ - int provided = MPI_THREAD_SINGLE; - MPI_Init_thread(0,0,MPI_THREAD_MULTIPLE,&provided); - MPI_Finalize(); - if (provided != MPI_THREAD_MULTIPLE) exit(1); - ]), - [enable_threads=multiple], [enable_threads=single], [enable_threads=single] - ) -fi - # errordir is substituted into the testlist file as errors when the # tests should check error handling and as a comment (#) otherwise. errordir="#" @@ -503,10 +475,10 @@ else fi AC_SUBST(comm_overlap) -# -# Only run the threads tests if multiple is specified -if test "$enable_threads" = "multiple" -o "$enable_threads" = "runtime" ; then - threadsdir="threads" +# The multi-thread tests can be disabled by --disable-threads +threadsdir="threads" +if test "$enable_threads" = "no"; then + threadsdir="#threads" fi # # Only run the checkpointing tests if enabled From 2e9857c7adb4cfe00b7a2b0c1330231349de849f Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 2 Apr 2021 18:51:27 -0500 Subject: [PATCH 206/607] test: fix strict warnings --- test/mpi/basic/adapt.c | 2 +- test/mpi/basic/netmpi.c | 4 +- test/mpi/coll/nonblocking2.c | 1 - test/mpi/coll/p_alltoall.c | 1 - test/mpi/coll/p_barrier.c | 2 +- test/mpi/datatype/hvecblklen.c | 2 +- test/mpi/datatype/pack_external.c | 10 ++--- test/mpi/datatype/vecblklen.c | 2 +- .../mpich/threads/pt2pt/sendrecv_vci_hint.c | 6 +-- test/mpi/init/session_psets.c | 1 + test/mpi/io/zero_count.c | 2 +- .../mpi_t/nem_fbox_fallback_to_queue_count.c | 4 +- .../mpi_t/unexpected_recvq_buffer_size.c | 4 +- test/mpi/manual/singjoin.c | 3 +- test/mpi/manual/tchandlers.c | 2 +- test/mpi/manual/tcutil.c | 2 +- test/mpi/mpi_t/mpit_isendirecv.c | 44 ++++++++++--------- test/mpi/mpi_t/qmpi_test.c | 2 +- test/mpi/part/pingping.c | 3 -- test/mpi/pt2pt/inactivereq.c | 2 +- test/mpi/rma/overlap_wins_rma.c | 2 +- test/mpi/rma/win_shared_rma_flush_load.c | 2 +- test/mpi/rma/wrma_flush_get.c | 2 +- test/mpi/threads/perf/mt_rma_msgrate.c | 1 - .../mpi/threads/pt2pt/mt_pers_sendrecv_impl.c | 1 - test/mpi/threads/pt2pt/mt_probe_impl.c | 1 - test/mpi/threads/spawn/th_taskmanager.c | 1 - test/mpi/util/mtest_common.c | 6 ++- 28 files changed, 56 insertions(+), 59 deletions(-) diff --git a/test/mpi/basic/adapt.c b/test/mpi/basic/adapt.c index b0f0ae1a8db..6db0404b575 100644 --- a/test/mpi/basic/adapt.c +++ b/test/mpi/basic/adapt.c @@ -90,7 +90,7 @@ void PrintOptions(void); int DetermineLatencyReps(ArgStruct * p); int DetermineLatencyReps012(ArgStruct * p); -void PrintOptions() +void PrintOptions(void) { printf("\n"); printf("Usage: adapt flags\n"); diff --git a/test/mpi/basic/netmpi.c b/test/mpi/basic/netmpi.c index 4b69da32503..7d0b34697e9 100644 --- a/test/mpi/basic/netmpi.c +++ b/test/mpi/basic/netmpi.c @@ -85,7 +85,7 @@ double TestSyncTime(ArgStruct * p); void PrintOptions(void); int DetermineLatencyReps(ArgStruct * p); -void PrintOptions() +void PrintOptions(void) { printf("\n"); printf("Usage: netpipe flags\n"); @@ -464,7 +464,7 @@ int main(int argc, char *argv[]) /* Return the current time in seconds, using a double precision number. */ -double When() +double When(void) { return MPI_Wtime(); } diff --git a/test/mpi/coll/nonblocking2.c b/test/mpi/coll/nonblocking2.c index 32926ca3c30..615d3082efc 100644 --- a/test/mpi/coll/nonblocking2.c +++ b/test/mpi/coll/nonblocking2.c @@ -34,7 +34,6 @@ static void sum_fn(void *invec, void *inoutvec, int *len, MPI_Datatype * datatyp int i; int *in = invec; int *inout = inoutvec; - int stride; if (*datatype == MPI_INT) { for (i = 0; i < *len; ++i) { diff --git a/test/mpi/coll/p_alltoall.c b/test/mpi/coll/p_alltoall.c index eb77554ca38..8bc486d07ff 100644 --- a/test/mpi/coll/p_alltoall.c +++ b/test/mpi/coll/p_alltoall.c @@ -36,7 +36,6 @@ int main(int argc, char **argv) MPI_Comm comm; int iters = 10; int j = 0; - int root = 1; int count = 1; /* sendcount and recvcount. */ MTest_Init(&argc, &argv); diff --git a/test/mpi/coll/p_barrier.c b/test/mpi/coll/p_barrier.c index 78fb96fde99..0c1a49ae83b 100644 --- a/test/mpi/coll/p_barrier.c +++ b/test/mpi/coll/p_barrier.c @@ -12,7 +12,7 @@ int main(int argc, char *argv[]) { MPI_Request req; MPI_Info info; - int rank, i, done; + int rank, i; MTest_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); diff --git a/test/mpi/datatype/hvecblklen.c b/test/mpi/datatype/hvecblklen.c index 03f9e264b30..1cba8ca320c 100644 --- a/test/mpi/datatype/hvecblklen.c +++ b/test/mpi/datatype/hvecblklen.c @@ -16,7 +16,7 @@ int main(int argc, char *argv[]) { MPI_Datatype dt, dt2, newtype; int position, psize, insize, outsize; - signed char *inbuf = 0, *outbuf = 0, *pbuf = 0, *p; + char *inbuf = 0, *outbuf = 0, *pbuf = 0, *p; int i, j, k; int errs = 0; int veccount = 16, stride = 16; diff --git a/test/mpi/datatype/pack_external.c b/test/mpi/datatype/pack_external.c index abaf5a4568b..5912fbfd5e2 100644 --- a/test/mpi/datatype/pack_external.c +++ b/test/mpi/datatype/pack_external.c @@ -234,7 +234,7 @@ int main(int argc, char **argv) const char *ref = get_pack_buffer(dt_list[i]); if (mpi_type_is_bool(dt_list[i].mpi_type)) { - /* Many C compilers will covert boolean values on assignment, e.g. 2->1, + /* Many C compilers will convert boolean values on assignment, e.g. 2->1, * but some compilers does not, e.g. Solaris suncc. * Current MPICH relies on compiler conversion. For other compilers, it is * probably not critical as long as the rount trip check (below) passes. @@ -244,10 +244,10 @@ int main(int argc, char **argv) get_mpi_type_name(dt_list[i].mpi_type)); errs++; const char *p = pack_buf + OFFSET; - for (int i = 0; i < size; i++) { - if (ref[i] != p[i]) { - printf(" pack_buf[%d] is 0x%02x, expect 0x%02x\n", i, p[i] & 0xff, - ref[i] & 0xff); + for (int j = 0; j < size; j++) { + if (ref[j] != p[j]) { + printf(" pack_buf[%d] is 0x%02x, expect 0x%02x\n", j, p[j] & 0xff, + ref[j] & 0xff); } } } diff --git a/test/mpi/datatype/vecblklen.c b/test/mpi/datatype/vecblklen.c index 03a0a3ef12b..e3c43f1d545 100644 --- a/test/mpi/datatype/vecblklen.c +++ b/test/mpi/datatype/vecblklen.c @@ -16,7 +16,7 @@ int main(int argc, char *argv[]) { MPI_Datatype dt, dt2, newtype; int position, psize, insize, outsize; - signed char *inbuf = 0, *outbuf = 0, *pbuf = 0, *p; + char *inbuf = 0, *outbuf = 0, *pbuf = 0, *p; int i, j, k; int errs = 0; int veccount = 16, stride = 16; diff --git a/test/mpi/impls/mpich/threads/pt2pt/sendrecv_vci_hint.c b/test/mpi/impls/mpich/threads/pt2pt/sendrecv_vci_hint.c index 95c4a8f7496..bbf93bde65e 100644 --- a/test/mpi/impls/mpich/threads/pt2pt/sendrecv_vci_hint.c +++ b/test/mpi/impls/mpich/threads/pt2pt/sendrecv_vci_hint.c @@ -69,8 +69,8 @@ MTEST_THREAD_RETURN_TYPE run_send_recv_test(void *arg) } /* Launch multiple threads, apply provided comm hints, run send/recv */ -int comm_hint_test(const char **comm_hints, const char **comm_hints_vals, int n_hints, - bool test_set_value, bool maintain_msg_order) +static int comm_hint_test(const char **comm_hints, const char **comm_hints_vals, int n_hints, + bool test_set_value, bool maintain_msg_order) { int i, j, errs = 0, nprocs, rank, flag; struct thread_param params[NTHREADS]; @@ -142,7 +142,7 @@ int comm_hint_test(const char **comm_hints, const char **comm_hints_vals, int n_ int main(int argc, char **argv) { - int i, pmode, nprocs, errs = 0, err, count = 0, iter = 0; + int pmode, nprocs, errs = 0, err; const char *hints_1[2]; const char *hints_1_vals[2]; diff --git a/test/mpi/init/session_psets.c b/test/mpi/init/session_psets.c index 162dde7c133..1422aae96e7 100644 --- a/test/mpi/init/session_psets.c +++ b/test/mpi/init/session_psets.c @@ -7,6 +7,7 @@ #include "mpi.h" #include #include +#include /* This is adapted example 10.9 from MPI Standard 4.0 * This example illustrates the use of Process Set query functions to select a diff --git a/test/mpi/io/zero_count.c b/test/mpi/io/zero_count.c index a305b76821a..ff1a3d5dd0b 100644 --- a/test/mpi/io/zero_count.c +++ b/test/mpi/io/zero_count.c @@ -18,7 +18,7 @@ int main(int argc, char **argv) int errs = 0; int len, rank, get_size; char buf[10]; - const char *filename = argv[0]; + const char *filename = __FILE__; MPI_File fh; MPI_Status status; diff --git a/test/mpi/manual/mpi_t/nem_fbox_fallback_to_queue_count.c b/test/mpi/manual/mpi_t/nem_fbox_fallback_to_queue_count.c index 3a74b5f8195..d755a1f2968 100644 --- a/test/mpi/manual/mpi_t/nem_fbox_fallback_to_queue_count.c +++ b/test/mpi/manual/mpi_t/nem_fbox_fallback_to_queue_count.c @@ -37,7 +37,7 @@ MPI_T_pvar_handle fbox_handle; * Question: Do we really want to write pvars other than reset? */ void blank_test(void); -void blank_test() +void blank_test(void) { uint64_t temp[2] = { -1 }; @@ -118,7 +118,7 @@ static void send_first_test(void) * workaround. */ void recv_first_test(void); -void recv_first_test() +void recv_first_test(void) { uint64_t nem_fbox_fall_back_to_queue_count[2] = { -1 }; diff --git a/test/mpi/manual/mpi_t/unexpected_recvq_buffer_size.c b/test/mpi/manual/mpi_t/unexpected_recvq_buffer_size.c index 1b39dcd9688..b6d09aca741 100644 --- a/test/mpi/manual/mpi_t/unexpected_recvq_buffer_size.c +++ b/test/mpi/manual/mpi_t/unexpected_recvq_buffer_size.c @@ -31,7 +31,7 @@ MPI_T_pvar_handle uqsize_handle; /* The first receive will block waiting for the last send, since messages from * a given rank are received in order. */ -static void reversed_tags_test() +static void reversed_tags_test(void) { size_t unexpected_recvq_buffer_size; @@ -69,7 +69,7 @@ static void reversed_tags_test() /* Rendezvous-based messages will never be unexpected (except for the initial RTS, * which has an empty buffer anyhow). */ -static void rndv_test() +static void rndv_test(void) { size_t unexpected_recvq_buffer_size; diff --git a/test/mpi/manual/singjoin.c b/test/mpi/manual/singjoin.c index b5d3ce8848f..ad945387a08 100644 --- a/test/mpi/manual/singjoin.c +++ b/test/mpi/manual/singjoin.c @@ -60,7 +60,8 @@ int opt_port = 0; SOCKET_FD_TYPE server_routine(int portnum) { SOCKET_FD_TYPE listenfd, peer_fd; - int ret, peer_addr_size; + int ret; + socklen_t peer_addr_size; struct sockaddr_in server_addr, peer_addr; listenfd = socket(AF_INET, SOCK_STREAM, 0); diff --git a/test/mpi/manual/tchandlers.c b/test/mpi/manual/tchandlers.c index cb79d21e898..86cc5e66488 100644 --- a/test/mpi/manual/tchandlers.c +++ b/test/mpi/manual/tchandlers.c @@ -78,7 +78,7 @@ void startWatchdog(int seconds) pthread_create(&theThread, NULL, threadLooper, NULL); } -void strokeWatchdog() +void strokeWatchdog(void) { sWatchdogStrokeCount++; } diff --git a/test/mpi/manual/tcutil.c b/test/mpi/manual/tcutil.c index 165d9e7f3f1..964ffa90687 100644 --- a/test/mpi/manual/tcutil.c +++ b/test/mpi/manual/tcutil.c @@ -50,7 +50,7 @@ void safeSleep(double seconds) } } -void printStackTrace() +void printStackTrace(void) { static char cmd[512]; snprintf(cmd, 512, "/bin/sh -c \"/home/eellis/bin/pstack1 %d\"", getpid()); diff --git a/test/mpi/mpi_t/mpit_isendirecv.c b/test/mpi/mpi_t/mpit_isendirecv.c index e4fadcd8c6e..908d3ae0755 100644 --- a/test/mpi/mpi_t/mpit_isendirecv.c +++ b/test/mpi/mpi_t/mpit_isendirecv.c @@ -20,7 +20,6 @@ static MPI_T_pvar_handle nsc_handle, nrc_handle, snsc_handle, snrc_handle; static MPI_T_pvar_session session; static int elems = 1000000; static MPI_Request *reqs; -static int num_nics = 1; static int enable_striping = 1; static int enable_hashing = 0; static int num_nodes = 0; @@ -118,23 +117,24 @@ static int compare_vars(int rank, int target, int num_nics) if (rank < num_pairs) { if (expected_mapping[0].nic_sent_bytes_count[idx] != nic_sent_bytes_count[idx]) { printf - ("rank=%d --> target=%d: Actual sent byte count=%ld through NIC %d does not match with the " - "expected sent byte count=%ld\n", rank, target, nic_sent_bytes_count[idx], idx, - expected_mapping[0].nic_sent_bytes_count[idx]); + ("rank=%d --> target=%d: Actual sent byte count=%llu through NIC %d does not match with the " + "expected sent byte count=%llu\n", rank, target, nic_sent_bytes_count[idx], + idx, expected_mapping[0].nic_sent_bytes_count[idx]); errs++; } if (expected_mapping[0].nic_recvd_bytes_count[idx] != nic_recvd_bytes_count[idx]) { printf - ("rank=%d --> target=%d: Actual received byte count=%ld through NIC %d does not match with the " - "expected received byte count=%ld\n", rank, target, nic_recvd_bytes_count[idx], - idx, expected_mapping[0].nic_recvd_bytes_count[idx]); + ("rank=%d --> target=%d: Actual received byte count=%llu through NIC %d does not match with the " + "expected received byte count=%llu\n", rank, target, + nic_recvd_bytes_count[idx], idx, + expected_mapping[0].nic_recvd_bytes_count[idx]); errs++; } if (expected_mapping[0].striped_nic_sent_bytes_count[idx] != striped_nic_sent_bytes_count[idx]) { printf - ("rank=%d --> target=%d: Actual striped sent byte count=%ld through NIC %d does not match with the " - "expected striped sent byte count=%ld\n", rank, target, + ("rank=%d --> target=%d: Actual striped sent byte count=%llu through NIC %d does not match with the " + "expected striped sent byte count=%llu\n", rank, target, striped_nic_sent_bytes_count[idx], idx, expected_mapping[0].striped_nic_sent_bytes_count[idx]); return -1; @@ -142,8 +142,8 @@ static int compare_vars(int rank, int target, int num_nics) if (expected_mapping[0].striped_nic_recvd_bytes_count[idx] != striped_nic_recvd_bytes_count[idx]) { printf - ("rank=%d --> target=%d: Actual striped received byte count=%ld through NIC %d does not match with the " - "expected striped received byte count=%ld\n", rank, target, + ("rank=%d --> target=%d: Actual striped received byte count=%llu through NIC %d does not match with the " + "expected striped received byte count=%llu\n", rank, target, striped_nic_recvd_bytes_count[idx], idx, expected_mapping[0].striped_nic_recvd_bytes_count[idx]); return -1; @@ -151,23 +151,24 @@ static int compare_vars(int rank, int target, int num_nics) } else if (rank < num_pairs * 2) { if (expected_mapping[1].nic_sent_bytes_count[idx] != nic_sent_bytes_count[idx]) { printf - ("rank=%d --> target=%d: Actual sent byte count=%ld through NIC %d does not match with the " - "expected sent byte count=%ld\n", rank, target, nic_sent_bytes_count[idx], idx, - expected_mapping[1].nic_sent_bytes_count[idx]); + ("rank=%d --> target=%d: Actual sent byte count=%llu through NIC %d does not match with the " + "expected sent byte count=%llu\n", rank, target, nic_sent_bytes_count[idx], + idx, expected_mapping[1].nic_sent_bytes_count[idx]); errs++; } if (expected_mapping[1].nic_recvd_bytes_count[idx] != nic_recvd_bytes_count[idx]) { printf - ("rank=%d --> target=%d: Actual received byte count=%ld through NIC %d does not match with the " - "expected received byte count=%ld\n", rank, target, nic_recvd_bytes_count[idx], - idx, expected_mapping[1].nic_recvd_bytes_count[idx]); + ("rank=%d --> target=%d: Actual received byte count=%llu through NIC %d does not match with the " + "expected received byte count=%llu\n", rank, target, + nic_recvd_bytes_count[idx], idx, + expected_mapping[1].nic_recvd_bytes_count[idx]); errs++; } if (expected_mapping[1].striped_nic_sent_bytes_count[idx] != striped_nic_sent_bytes_count[idx]) { printf - ("rank=%d --> target=%d: Actual striped sent byte count=%ld through NIC %d does not match with the " - "expected striped sent byte count=%ld\n", rank, target, + ("rank=%d --> target=%d: Actual striped sent byte count=%llu through NIC %d does not match with the " + "expected striped sent byte count=%llu\n", rank, target, striped_nic_sent_bytes_count[idx], idx, expected_mapping[1].striped_nic_sent_bytes_count[idx]); return -1; @@ -175,8 +176,8 @@ static int compare_vars(int rank, int target, int num_nics) if (expected_mapping[1].striped_nic_recvd_bytes_count[idx] != striped_nic_recvd_bytes_count[idx]) { printf - ("rank=%d --> target=%d: Actual striped received byte count=%ld through NIC %d does not match with the " - "expected striped received byte count=%ld\n", rank, target, + ("rank=%d --> target=%d: Actual striped received byte count=%llu through NIC %d does not match with the " + "expected striped received byte count=%llu\n", rank, target, striped_nic_recvd_bytes_count[idx], idx, expected_mapping[1].striped_nic_recvd_bytes_count[idx]); return -1; @@ -202,6 +203,7 @@ int main(int argc, char *argv[]) int readonly, continuous, atomic; MPI_T_enum enumtype; int nsc_idx = -1, nrc_idx = -1, snsc_idx = -1, snrc_idx = -1; + int num_nics = 1; int required, provided; int errs = 0; diff --git a/test/mpi/mpi_t/qmpi_test.c b/test/mpi/mpi_t/qmpi_test.c index 9bc81116007..f1de2110b29 100644 --- a/test/mpi/mpi_t/qmpi_test.c +++ b/test/mpi/mpi_t/qmpi_test.c @@ -40,7 +40,7 @@ QMPI_Finalize_t *next_finalize_fn[2]; int next_finalize_id[2]; __attribute__ ((constructor)) -void static_register_my_tool() +void static_register_my_tool(void) { if (MPI_SUCCESS == QMPI_Register_tool_name("test_tool", &test_init_function_pointer)) { qmpi_on = 1; diff --git a/test/mpi/part/pingping.c b/test/mpi/part/pingping.c index a366035d23a..800a972df52 100644 --- a/test/mpi/part/pingping.c +++ b/test/mpi/part/pingping.c @@ -72,7 +72,6 @@ int main(int argc, char *argv[]) int minsize = 2, nmsg, maxmsg; int seed, testsize; MPI_Aint sendcnt, recvcnt; - MPI_Aint maxbufsize; MPI_Comm comm; DTP_pool_s dtp; struct mtest_obj send, recv; @@ -90,8 +89,6 @@ int main(int argc, char *argv[]) sendmem = MTestArgListGetMemType(head, "sendmem"); recvmem = MTestArgListGetMemType(head, "recvmem"); - maxbufsize = MTestDefaultMaxBufferSize(); - err = DTP_pool_create(basic_type, sendcnt, seed, &dtp); if (err != DTP_SUCCESS) { fprintf(stderr, "Error while creating send pool (%s,%ld)\n", basic_type, sendcnt); diff --git a/test/mpi/pt2pt/inactivereq.c b/test/mpi/pt2pt/inactivereq.c index c72988ea285..8164d32da39 100644 --- a/test/mpi/pt2pt/inactivereq.c +++ b/test/mpi/pt2pt/inactivereq.c @@ -78,7 +78,7 @@ static int test_recv_init(int src_rank, const char *test_name) return errs; } -static void test_proc_null() +static void test_proc_null(void) { MPI_Request r; MPI_Status s; diff --git a/test/mpi/rma/overlap_wins_rma.c b/test/mpi/rma/overlap_wins_rma.c index 4b4e9a7be68..602983fbb26 100644 --- a/test/mpi/rma/overlap_wins_rma.c +++ b/test/mpi/rma/overlap_wins_rma.c @@ -158,7 +158,7 @@ static void print_target_data(void) fflush(stdout); } -static int run_test() +static int run_test(void) { int errors = 0; int i, x; diff --git a/test/mpi/rma/win_shared_rma_flush_load.c b/test/mpi/rma/win_shared_rma_flush_load.c index 1390789271b..913759f49c7 100644 --- a/test/mpi/rma/win_shared_rma_flush_load.c +++ b/test/mpi/rma/win_shared_rma_flush_load.c @@ -99,7 +99,7 @@ static int check_local_result(int iter) #define check_local_result(iter) (0) #endif -static int run_test() +static int run_test(void) { int i = 0, x = 0; int errors = 0; diff --git a/test/mpi/rma/wrma_flush_get.c b/test/mpi/rma/wrma_flush_get.c index 3f7ac7a2271..2d89c6f616c 100644 --- a/test/mpi/rma/wrma_flush_get.c +++ b/test/mpi/rma/wrma_flush_get.c @@ -100,7 +100,7 @@ static int check_local_result(int iter) #define check_local_result(iter) (0) #endif -static int run_test() +static int run_test(void) { int i = 0, x = 0; int errors = 0; diff --git a/test/mpi/threads/perf/mt_rma_msgrate.c b/test/mpi/threads/perf/mt_rma_msgrate.c index 80ef5d51a99..b24b00e4d6b 100644 --- a/test/mpi/threads/perf/mt_rma_msgrate.c +++ b/test/mpi/threads/perf/mt_rma_msgrate.c @@ -49,7 +49,6 @@ MTEST_THREAD_RETURN_TYPE thread_fn(void *arg) int win_i, win_post_i, win_posts; void *buf, *result_buf; MPI_Request requests[WINDOW_SIZE]; - MPI_Status statuses[WINDOW_SIZE]; double t_start, t_end; tid = (int) (long) arg; diff --git a/test/mpi/threads/pt2pt/mt_pers_sendrecv_impl.c b/test/mpi/threads/pt2pt/mt_pers_sendrecv_impl.c index a8e57f0013e..892f4a4c408 100644 --- a/test/mpi/threads/pt2pt/mt_pers_sendrecv_impl.c +++ b/test/mpi/threads/pt2pt/mt_pers_sendrecv_impl.c @@ -69,7 +69,6 @@ int test_pers_sendrecv(int id, int iter, int count, int *buff, MPI_Comm comm, in if (errs > 0) fprintf(stderr, "thread %d: %d errors found in received data\n", id, errs); - fn_exit: return errs; } diff --git a/test/mpi/threads/pt2pt/mt_probe_impl.c b/test/mpi/threads/pt2pt/mt_probe_impl.c index a85bf0bb3e3..f165b4bb0c7 100644 --- a/test/mpi/threads/pt2pt/mt_probe_impl.c +++ b/test/mpi/threads/pt2pt/mt_probe_impl.c @@ -224,7 +224,6 @@ int test_probe_normal(int id, int iter, int count, int *buff, MPI_Comm comm, int } - fn_exit: return errs; } diff --git a/test/mpi/threads/spawn/th_taskmanager.c b/test/mpi/threads/spawn/th_taskmanager.c index 3adf21146a6..fb21a17893d 100644 --- a/test/mpi/threads/spawn/th_taskmanager.c +++ b/test/mpi/threads/spawn/th_taskmanager.c @@ -147,7 +147,6 @@ int main(int argc, char *argv[]) CHECK_SUCCESS(MPI_Comm_disconnect(&parent)); } - fn_exit: /* Do not call MTest_Finalize (and thus MTest_Init) to avoid printing extra * "No Errors" as many as spawned MPI processes. */ MPI_Finalize(); diff --git a/test/mpi/util/mtest_common.c b/test/mpi/util/mtest_common.c index e649cfe6de7..83cee5813ce 100644 --- a/test/mpi/util/mtest_common.c +++ b/test/mpi/util/mtest_common.c @@ -4,7 +4,9 @@ */ #include "mpitest.h" +#include "mtest_common.h" #include +#include /* ------------------------------------------------------------------------ */ /* Utilities related to test environment */ @@ -15,7 +17,7 @@ It is taking the simplest solution here: default to 2GB, unless user set via environment variable -- MPITEST_MAXBUFFER */ -MPI_Aint MTestDefaultMaxBufferSize() +MPI_Aint MTestDefaultMaxBufferSize(void) { MPI_Aint max_size = 1073741824; if (sizeof(void *) == 4) { @@ -697,7 +699,7 @@ void MTestCopyContent(const void *sbuf, void *dbuf, size_t size, mtest_mem_type_ } } -void MTest_finalize_gpu() +void MTest_finalize_gpu(void) { #ifdef HAVE_ZE if (ndevices != -1) { From 98bf9b006244cbb61abd3684c76369e4ca6f103d Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 15 Nov 2021 08:02:52 -0600 Subject: [PATCH 207/607] test: include mpitest.h before standard headers This fixes the missing strdup declaration when mpich is built with strict flags. --- test/mpi/coll/allred.c | 2 +- test/mpi/coll/allred2.c | 2 +- test/mpi/coll/bcast.c | 2 +- test/mpi/coll/op_coll.c | 2 +- test/mpi/coll/reduce.c | 2 +- test/mpi/include/mtest_dtp.h | 2 ++ test/mpi/part/pingping.c | 2 +- test/mpi/pt2pt/pingping.c | 2 +- test/mpi/pt2pt/sendrecv1.c | 2 +- test/mpi/pt2pt/sendself.c | 2 +- test/mpi/rma/accfence1.c | 2 +- test/mpi/rma/accpscw1.c | 2 +- test/mpi/rma/epochtest.c | 2 +- test/mpi/rma/fence.c | 2 +- test/mpi/rma/lock_x_dt.c | 2 +- test/mpi/rma/putpscw1.c | 2 +- 16 files changed, 17 insertions(+), 15 deletions(-) diff --git a/test/mpi/coll/allred.c b/test/mpi/coll/allred.c index 94b4eef5de0..298364b0a2b 100644 --- a/test/mpi/coll/allred.c +++ b/test/mpi/coll/allred.c @@ -8,8 +8,8 @@ * will occur as the number of processors is increased. */ -#include "mpi.h" #include "mpitest.h" +#include "mpi.h" #include #include #include diff --git a/test/mpi/coll/allred2.c b/test/mpi/coll/allred2.c index 5c94927d44b..71270dcbd81 100644 --- a/test/mpi/coll/allred2.c +++ b/test/mpi/coll/allred2.c @@ -3,10 +3,10 @@ * See COPYRIGHT in top-level directory */ +#include "mpitest.h" #include "mpi.h" #include #include -#include "mpitest.h" #include "mtest_dtp.h" /* diff --git a/test/mpi/coll/bcast.c b/test/mpi/coll/bcast.c index 90f4d4c50fe..3c21c1ec8c7 100644 --- a/test/mpi/coll/bcast.c +++ b/test/mpi/coll/bcast.c @@ -3,10 +3,10 @@ * See COPYRIGHT in top-level directory */ +#include "mpitest.h" #include "mpi.h" #include #include -#include "mpitest.h" #include "dtpools.h" #include "mtest_dtp.h" #include diff --git a/test/mpi/coll/op_coll.c b/test/mpi/coll/op_coll.c index 017568dd508..7ba33dc9ad5 100644 --- a/test/mpi/coll/op_coll.c +++ b/test/mpi/coll/op_coll.c @@ -5,10 +5,10 @@ /* A test of all op-based collectives with support for GPU buffers */ +#include "mpitest.h" #include "mpi.h" #include #include -#include "mpitest.h" #include "mtest_dtp.h" #define COUNT (10) diff --git a/test/mpi/coll/reduce.c b/test/mpi/coll/reduce.c index e20ad344d66..5c61a851508 100644 --- a/test/mpi/coll/reduce.c +++ b/test/mpi/coll/reduce.c @@ -3,10 +3,10 @@ * See COPYRIGHT in top-level directory */ +#include "mpitest.h" #include "mpi.h" #include #include -#include "mpitest.h" #include "mtest_dtp.h" /* diff --git a/test/mpi/include/mtest_dtp.h b/test/mpi/include/mtest_dtp.h index c2a181e3c64..0ca7405508f 100644 --- a/test/mpi/include/mtest_dtp.h +++ b/test/mpi/include/mtest_dtp.h @@ -8,6 +8,8 @@ #include "dtpools.h" #include "mtest_common.h" +#include +#include #include typedef enum { diff --git a/test/mpi/part/pingping.c b/test/mpi/part/pingping.c index 800a972df52..0d51841241e 100644 --- a/test/mpi/part/pingping.c +++ b/test/mpi/part/pingping.c @@ -3,10 +3,10 @@ * See COPYRIGHT in top-level directory */ +#include "mpitest.h" #include "mpi.h" #include #include -#include "mpitest.h" #include "mtest_dtp.h" #include "dtpools.h" #include diff --git a/test/mpi/pt2pt/pingping.c b/test/mpi/pt2pt/pingping.c index d9be79cf007..01282ec87d9 100644 --- a/test/mpi/pt2pt/pingping.c +++ b/test/mpi/pt2pt/pingping.c @@ -3,10 +3,10 @@ * See COPYRIGHT in top-level directory */ +#include "mpitest.h" #include "mpi.h" #include #include -#include "mpitest.h" #include "dtpools.h" #include "mtest_dtp.h" #include diff --git a/test/mpi/pt2pt/sendrecv1.c b/test/mpi/pt2pt/sendrecv1.c index fd133ae201d..2b49e3dbc7e 100644 --- a/test/mpi/pt2pt/sendrecv1.c +++ b/test/mpi/pt2pt/sendrecv1.c @@ -3,10 +3,10 @@ * See COPYRIGHT in top-level directory */ +#include "mpitest.h" #include "mpi.h" #include #include -#include "mpitest.h" #include "dtpools.h" #include "mtest_dtp.h" #include diff --git a/test/mpi/pt2pt/sendself.c b/test/mpi/pt2pt/sendself.c index 92da212c903..9ab17bb6b4c 100644 --- a/test/mpi/pt2pt/sendself.c +++ b/test/mpi/pt2pt/sendself.c @@ -3,10 +3,10 @@ * See COPYRIGHT in top-level directory */ +#include "mpitest.h" #include "mpi.h" #include #include -#include "mpitest.h" #include "dtpools.h" #include "mtest_dtp.h" #include diff --git a/test/mpi/rma/accfence1.c b/test/mpi/rma/accfence1.c index 3c43cd21f9f..2f3c68511c9 100644 --- a/test/mpi/rma/accfence1.c +++ b/test/mpi/rma/accfence1.c @@ -3,11 +3,11 @@ * See COPYRIGHT in top-level directory */ +#include "mpitest.h" #include "mpi.h" #include #include #include -#include "mpitest.h" #include "dtpools.h" #include "mtest_dtp.h" #include diff --git a/test/mpi/rma/accpscw1.c b/test/mpi/rma/accpscw1.c index cd56bd75f14..0b29fc7a021 100644 --- a/test/mpi/rma/accpscw1.c +++ b/test/mpi/rma/accpscw1.c @@ -3,10 +3,10 @@ * See COPYRIGHT in top-level directory */ +#include "mpitest.h" #include "mpi.h" #include #include -#include "mpitest.h" #include "dtpools.h" #include "mtest_dtp.h" #include diff --git a/test/mpi/rma/epochtest.c b/test/mpi/rma/epochtest.c index a7d3142866b..7917b0242a2 100644 --- a/test/mpi/rma/epochtest.c +++ b/test/mpi/rma/epochtest.c @@ -19,10 +19,10 @@ * fence fence */ +#include "mpitest.h" #include "mpi.h" #include #include -#include "mpitest.h" #include "dtpools.h" #include "mtest_dtp.h" #include diff --git a/test/mpi/rma/fence.c b/test/mpi/rma/fence.c index 8e4c514ede4..cf0b1d219ee 100644 --- a/test/mpi/rma/fence.c +++ b/test/mpi/rma/fence.c @@ -3,12 +3,12 @@ * See COPYRIGHT in top-level directory */ +#include "mpitest.h" #include "mpi.h" #include #include #include #include -#include "mpitest.h" #include "dtpools.h" #include "mtest_dtp.h" #include diff --git a/test/mpi/rma/lock_x_dt.c b/test/mpi/rma/lock_x_dt.c index 5addbd4d175..8dcb53689df 100644 --- a/test/mpi/rma/lock_x_dt.c +++ b/test/mpi/rma/lock_x_dt.c @@ -3,11 +3,11 @@ * See COPYRIGHT in top-level directory */ +#include "mpitest.h" #include "mpi.h" #include #include #include -#include "mpitest.h" #include "dtpools.h" #include "mtest_dtp.h" diff --git a/test/mpi/rma/putpscw1.c b/test/mpi/rma/putpscw1.c index f69f96883ad..dd193799bbc 100644 --- a/test/mpi/rma/putpscw1.c +++ b/test/mpi/rma/putpscw1.c @@ -3,10 +3,10 @@ * See COPYRIGHT in top-level directory */ +#include "mpitest.h" #include "mpi.h" #include #include -#include "mpitest.h" #include "dtpools.h" #include "mtest_dtp.h" #include From 3354a6967092cbf5541a25e504e621dda7d62ef2 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 13 Nov 2021 16:32:12 -0600 Subject: [PATCH 208/607] test: allow independent autogen from test/mpi This patch allows using test suite independently, e.g. git clone the repository, go to test/mpi, and autogen from there assuming there is an valid mpi instanallation already. --- test/mpi/autogen.sh | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/mpi/autogen.sh b/test/mpi/autogen.sh index 1f3307ae07f..51bf8dd8c26 100755 --- a/test/mpi/autogen.sh +++ b/test/mpi/autogen.sh @@ -4,6 +4,27 @@ ## See COPYRIGHT in top-level directory ## +check_copy() { + name=$1 + orig=$2 + printf "Checking $name... " + if test ! -e $name ; then + if test -e $orig; then + cp -a $orig $name + echo "copy from $orig" + else + echo "missing" + exit 1 + fi + else + echo "found" + fi +} + +check_copy version.m4 ../../maint/version.m4 +check_copy confdb ../../confdb +check_copy dtpools/confdb ../../confdb + # Create and/or update the f90 tests printf "Create or update the Fortran 90 tests derived from the Fortran 77 tests... " for dir in f77/* ; do From 74cd41b047db7c96e1928f257f5849f128cbf5a2 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 13 Nov 2021 20:40:05 -0600 Subject: [PATCH 209/607] test/config: check for major version 4 --- test/mpi/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index 84d96a4a624..17677e685bf 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -859,7 +859,7 @@ AC_CHECK_FUNCS(getrusage) # some tests, we need to know if we are MPI 2.1 or MPI 2.2, # particularly for new routines in Fortran AC_CACHE_CHECK([for major version of MPI],pac_cv_mpi_major_version,[ - for pac_cv_mpi_major_version in 3 2 1 unknown ; do + for pac_cv_mpi_major_version in 4 3 2 1 unknown ; do AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include "mpi.h"],[ #if MPI_VERSION == $pac_cv_mpi_major_version ''' force failure ''' From e8fa5315e1dac126ad3e66c9d82876f3b56c81e0 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 13 Nov 2021 21:08:20 -0600 Subject: [PATCH 210/607] test/config: detect mpi-io availability Do no rely on option but detect mpi-io availability. --- test/mpi/configure.ac | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index 17677e685bf..34425574f85 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -145,8 +145,7 @@ AC_ARG_ENABLE(cxx, [AC_HELP_STRING([--enable-cxx],[Turn on C++ tests (default)])],,[enable_cxx=yes]) AC_ARG_ENABLE(romio, - [AC_HELP_STRING([--enable-romio],[Enable ROMIO MPI I/O implementation])],, - [enable_romio=yes]) + [AC_HELP_STRING([--enable-romio],[Enable MPI I/O tests])]) AC_ARG_ENABLE(namepub, [AC_HELP_STRING([--enable-namepub], @@ -881,6 +880,17 @@ MPI_SUBVERSION=$pac_cv_mpi_minor_version AC_SUBST(MPI_VERSION) AC_SUBST(MPI_SUBVERSION) +AC_MSG_CHECKING([whether MPI-IO is available]) +AC_LINK_IFELSE([ + AC_LANG_PROGRAM([#include "mpi.h"],[ + MPI_File fh; + MPI_Init(0,0); + MPI_File_open(MPI_COMM_WORLD,"/dev/null",MPI_MODE_WRONLY,MPI_INFO_NULL,&fh); + MPI_File_close(&fh); + MPI_Finalize();]) + ],[mpi_io_works=yes],[mpi_io_works=no]) +AC_MSG_RESULT($mpi_io_works) + # Running Fortran 77 compiler tests AC_PROG_F77 if test "$enable_f77" = yes ; then @@ -1356,6 +1366,11 @@ if test "$enable_cxx" = yes ; then AC_MSG_WARN([The compiler $CXX does not support C++ namespaces. This may cause problems for the tests]) fi AC_LANG_POP([C++]) + + dnl for util/mtest_cxx.cxx + if test "$mpi_io_works" = "yes" ; then + AC_DEFINE(HAVE_MPI_IO,1,[Define if MPI-IO (really ROMIO) is included]) + fi fi AC_LANG_C @@ -1364,9 +1379,10 @@ LT_INIT() # IO iodir="#" -if test "$enable_romio" != no ; then +if test "$enable_romio" != no -a "$mpi_io_works" = yes ; then iodir=io - AC_DEFINE(HAVE_MPI_IO,1,[Define if MPI-IO (really ROMIO) is included]) + + dnl for io/async.c AC_CACHE_CHECK([whether MPIO_Request is defined for MPI IO], pac_cv_have_mpio_request,[ AC_COMPILE_IFELSE([ From 166c8b90d891b0bb3a0b453703739d0ff91d72ca Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 13 Nov 2021 21:53:08 -0600 Subject: [PATCH 211/607] test/Makefile.am: add dependency so make testing works Running make testing from MPICH top dir will call make testing in test. Add minimum rules to bootstrap test/mpi so it still works. --- test/Makefile.am | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/Makefile.am b/test/Makefile.am index a2e0ad706f0..e2a799cd18e 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -9,9 +9,11 @@ SUBDIRS = mpi commands . # Test both the MPI routines and the MPICH command scripts -testing: +testing: mpi/Makefile (NOXMLCLOSE=YES && export NOXMLCLOSE && cd mpi && $(MAKE) testing) (XMLFILE=../mpi/summary.xml && XMLCONTINUE=YES && \ export XMLFILE && export XMLCONTINUE && \ cd commands && $(MAKE) testing) +mpi/Makefile: + cd mpi && ./autogen.sh && ./configure --with-mpi=${prefix} From e32f430197f853356c5c5afa6e74c294e2bcaa94 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 1 Dec 2021 17:27:05 -0600 Subject: [PATCH 212/607] test/config: use PAC_CONFIG_SUBDIR_ARGS for dtpools We need pass CC=mpicc to dtpools' configure or it won't work unless mpi paths are set. AC_CONFIG_SUBDIRS will use cached CC thus won't be overwritable. We don't need export CC explicitly since it is already exported due to its precious status. --- test/mpi/autogen.sh | 4 ++++ test/mpi/configure.ac | 6 ++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/test/mpi/autogen.sh b/test/mpi/autogen.sh index 51bf8dd8c26..106c2a5dafd 100755 --- a/test/mpi/autogen.sh +++ b/test/mpi/autogen.sh @@ -25,6 +25,9 @@ check_copy version.m4 ../../maint/version.m4 check_copy confdb ../../confdb check_copy dtpools/confdb ../../confdb +echo "Running autoreconf in dtpools" +(cd dtpools && autoreconf -ivf) + # Create and/or update the f90 tests printf "Create or update the Fortran 90 tests derived from the Fortran 77 tests... " for dir in f77/* ; do @@ -57,4 +60,5 @@ for dir in errors/f77/* ; do done echo "done" +echo "Running autoreconf in ." autoreconf -ivf diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index 34425574f85..51a3b245c06 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -403,10 +403,8 @@ else AC_PATH_PROG(MPIEXEC,$MPIEXEC_NAME) fi fi -# Make sure we export CC before configuring DTPools, since MPI is -# needed to build the library. -export CC -AC_CONFIG_SUBDIRS([dtpools]) + +PAC_CONFIG_SUBDIR_ARGS([dtpools]) # Running C compiler tests AC_PROG_CC From 7ea9751230bb75783790c6cc93b5e9c4c435efc8 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 1 Dec 2021 17:30:14 -0600 Subject: [PATCH 213/607] test/config: check whether CXX is supported my mpicxx Directly probe rather than relying on --enable/disable-cxx. --disable-cxx will always work to disable the cxx tests. --- test/mpi/configure.ac | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index 51a3b245c06..87bb9281bab 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -1280,9 +1280,20 @@ fi # Running C++ compiler tests AC_PROG_CXX if test "$enable_cxx" = yes ; then - if test -z "$CXX" ; then + AC_MSG_CHECKING([that we can build MPI programs with CXX binding]) + AC_LANG_PUSH([C++]) + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([#include "mpi.h"], [ + MPI::Init(NULL, NULL); + MPI::Finalize(); + ]) + ],[ + AC_MSG_RESULT(yes) + ],[ enable_cxx=no - fi + AC_MSG_RESULT(no) + ]) + AC_LANG_POP([C++]) fi # Simple tests for which other languages we can handle cxxdir="#" From b4c060bb420fa5a3f4c4c0ef603e06f54ef6b1f1 Mon Sep 17 00:00:00 2001 From: Wesley Bland Date: Tue, 30 Nov 2021 10:48:15 -0800 Subject: [PATCH 214/607] ch4/ofi: Create capability for counter wait objects The CXI provider does not currently support counter wait objects so we need a capability set to easily turn that off when it can't be used. Unfortunately, there is no way to programmatically discover what support is present so this will have to be hand-coded. --- src/mpid/ch4/netmod/ofi/globals.c | 8 ++++++++ src/mpid/ch4/netmod/ofi/ofi_capability_sets.h | 16 ++++++++++++++++ src/mpid/ch4/netmod/ofi/ofi_init.c | 6 +++++- src/mpid/ch4/netmod/ofi/ofi_types.h | 1 + src/mpid/ch4/netmod/ofi/ofi_win.h | 2 +- 5 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/globals.c b/src/mpid/ch4/netmod/ofi/globals.c index 874d157a288..f7733df055b 100644 --- a/src/mpid/ch4/netmod/ofi/globals.c +++ b/src/mpid/ch4/netmod/ofi/globals.c @@ -44,6 +44,7 @@ MPIDI_OFI_capabilities_t MPIDI_OFI_caps_list[MPIDI_OFI_NUM_SETS] = .context_bits = MPIDI_OFI_CONTEXT_BITS_DEFAULT, .source_bits = MPIDI_OFI_SOURCE_BITS_DEFAULT, .tag_bits = MPIDI_OFI_TAG_BITS_DEFAULT, + .counter_wait_objects = MPIDI_OFI_COUNTER_WAIT_OBJECTS_DEFAULT, .major_version = MPIDI_OFI_MAJOR_VERSION_DEFAULT, .minor_version = MPIDI_OFI_MINOR_VERSION_DEFAULT} , @@ -68,6 +69,7 @@ MPIDI_OFI_capabilities_t MPIDI_OFI_caps_list[MPIDI_OFI_NUM_SETS] = .context_bits = MPIDI_OFI_CONTEXT_BITS_MINIMAL, .source_bits = MPIDI_OFI_SOURCE_BITS_MINIMAL, .tag_bits = MPIDI_OFI_TAG_BITS_MINIMAL, + .counter_wait_objects = MPIDI_OFI_COUNTER_WAIT_OBJECTS_MINIMAL, .major_version = MPIDI_OFI_MAJOR_VERSION_MINIMAL, .minor_version = MPIDI_OFI_MINOR_VERSION_MINIMAL} , @@ -92,6 +94,7 @@ MPIDI_OFI_capabilities_t MPIDI_OFI_caps_list[MPIDI_OFI_NUM_SETS] = .context_bits = MPIDI_OFI_CONTEXT_BITS_PSM2, .source_bits = MPIDI_OFI_SOURCE_BITS_PSM2, .tag_bits = MPIDI_OFI_TAG_BITS_PSM2, + .counter_wait_objects = MPIDI_OFI_COUNTER_WAIT_OBJECTS_PSM2, .major_version = MPIDI_OFI_MAJOR_VERSION_PSM2, .minor_version = MPIDI_OFI_MINOR_VERSION_PSM2} , @@ -116,6 +119,7 @@ MPIDI_OFI_capabilities_t MPIDI_OFI_caps_list[MPIDI_OFI_NUM_SETS] = .context_bits = MPIDI_OFI_CONTEXT_BITS_SOCKETS, .source_bits = MPIDI_OFI_SOURCE_BITS_SOCKETS, .tag_bits = MPIDI_OFI_TAG_BITS_SOCKETS, + .counter_wait_objects = MPIDI_OFI_COUNTER_WAIT_OBJECTS_SOCKETS, .major_version = MPIDI_OFI_MAJOR_VERSION_SOCKETS, .minor_version = MPIDI_OFI_MINOR_VERSION_SOCKETS} , @@ -140,6 +144,7 @@ MPIDI_OFI_capabilities_t MPIDI_OFI_caps_list[MPIDI_OFI_NUM_SETS] = .context_bits = MPIDI_OFI_CONTEXT_BITS_BGQ, .source_bits = MPIDI_OFI_SOURCE_BITS_BGQ, .tag_bits = MPIDI_OFI_TAG_BITS_BGQ, + .counter_wait_objects = MPIDI_OFI_COUNTER_WAIT_OBJECTS_BGQ, .major_version = MPIDI_OFI_MAJOR_VERSION_BGQ, .minor_version = MPIDI_OFI_MINOR_VERSION_BGQ} , @@ -164,6 +169,7 @@ MPIDI_OFI_capabilities_t MPIDI_OFI_caps_list[MPIDI_OFI_NUM_SETS] = .context_bits = MPIDI_OFI_CONTEXT_BITS_VERBS_RXM, .source_bits = MPIDI_OFI_SOURCE_BITS_VERBS_RXM, .tag_bits = MPIDI_OFI_TAG_BITS_VERBS_RXM, + .counter_wait_objects = MPIDI_OFI_COUNTER_WAIT_OBJECTS_VERBS_RXM, .major_version = MPIDI_OFI_MAJOR_VERSION_RXM, .minor_version = MPIDI_OFI_MINOR_VERSION_RXM} , @@ -188,6 +194,7 @@ MPIDI_OFI_capabilities_t MPIDI_OFI_caps_list[MPIDI_OFI_NUM_SETS] = .context_bits = MPIDI_OFI_CONTEXT_BITS_RXM, .source_bits = MPIDI_OFI_SOURCE_BITS_RXM, .tag_bits = MPIDI_OFI_TAG_BITS_RXM, + .counter_wait_objects = MPIDI_OFI_COUNTER_WAIT_OBJECTS_RXM, .major_version = MPIDI_OFI_MAJOR_VERSION_RXM, .minor_version = MPIDI_OFI_MINOR_VERSION_RXM} , @@ -212,6 +219,7 @@ MPIDI_OFI_capabilities_t MPIDI_OFI_caps_list[MPIDI_OFI_NUM_SETS] = .context_bits = MPIDI_OFI_CONTEXT_BITS_GNI, .source_bits = MPIDI_OFI_SOURCE_BITS_GNI, .tag_bits = MPIDI_OFI_TAG_BITS_GNI, + .counter_wait_objects = MPIDI_OFI_COUNTER_WAIT_OBJECTS_GNI, .major_version = MPIDI_OFI_MAJOR_VERSION_GNI, .minor_version = MPIDI_OFI_MINOR_VERSION_GNI} }; diff --git a/src/mpid/ch4/netmod/ofi/ofi_capability_sets.h b/src/mpid/ch4/netmod/ofi/ofi_capability_sets.h index 669b124e480..fed37b2c368 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_capability_sets.h +++ b/src/mpid/ch4/netmod/ofi/ofi_capability_sets.h @@ -89,6 +89,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) * MPIDI_OFI_CONTEXT_BITS The number of bits used for the context ID in an OFI message * MPIDI_OFI_SOURCE_BITS The number of bits used for the source rank in an OFI message * MPIDI_OFI_TAG_BITS The number of bits used for the tag in an OFI message + * MPIDI_OFI_COUNTER_WAIT_OBJECTS The provider supports the use of count wait objects * MPIDI_OFI_MAJOR_VERSION The major API version of libfabric required * MPIDI_OFI_MINOR_VERSION The minor API version of libfabric required * @@ -128,6 +129,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_CONTEXT_BITS_PSM2 (20) #define MPIDI_OFI_SOURCE_BITS_PSM2 (0) #define MPIDI_OFI_TAG_BITS_PSM2 (31) +#define MPIDI_OFI_COUNTER_WAIT_OBJECTS_PSM2 MPIDI_OFI_ON #define MPIDI_OFI_MAJOR_VERSION_PSM2 1 #define MPIDI_OFI_MINOR_VERSION_PSM2 6 @@ -159,6 +161,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_CONTEXT_BITS MPIDI_OFI_CONTEXT_BITS_PSM2 #define MPIDI_OFI_SOURCE_BITS MPIDI_OFI_SOURCE_BITS_PSM2 #define MPIDI_OFI_TAG_BITS MPIDI_OFI_TAG_BITS_PSM2 +#define MPIDI_OFI_COUNTER_WAIT_OBJECTS MPIDI_OFI_COUNTER_WAIT_OBJECTS_PSM2 #define MPIDI_OFI_SYNC_SEND_ACK (0x0010000000000000ULL) #define MPIDI_OFI_SYNC_SEND (0x0020000000000000ULL) #define MPIDI_OFI_DYNPROC_SEND (0x0040000000000000ULL) @@ -189,6 +192,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_CONTEXT_BITS_SOCKETS (20) #define MPIDI_OFI_SOURCE_BITS_SOCKETS (0) #define MPIDI_OFI_TAG_BITS_SOCKETS (31) +#define MPIDI_OFI_COUNTER_WAIT_OBJECTS_SOCKETS MPIDI_OFI_ON #define MPIDI_OFI_MAJOR_VERSION_SOCKETS 1 #define MPIDI_OFI_MINOR_VERSION_SOCKETS 5 @@ -220,6 +224,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_CONTEXT_BITS MPIDI_OFI_CONTEXT_BITS_SOCKETS #define MPIDI_OFI_SOURCE_BITS MPIDI_OFI_SOURCE_BITS_SOCKETS #define MPIDI_OFI_TAG_BITS MPIDI_OFI_TAG_BITS_SOCKETS +#define MPIDI_OFI_COUNTER_WAIT_OBJECTS MPIDI_OFI_COUNTER_WAIT_OBJECTS_SOCKETS #define MPIDI_OFI_SYNC_SEND_ACK (0x0010000000000000ULL) #define MPIDI_OFI_SYNC_SEND (0x0020000000000000ULL) #define MPIDI_OFI_DYNPROC_SEND (0x0040000000000000ULL) @@ -250,6 +255,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_CONTEXT_BITS_BGQ (20) #define MPIDI_OFI_SOURCE_BITS_BGQ (0) #define MPIDI_OFI_TAG_BITS_BGQ (31) +#define MPIDI_OFI_COUNTER_WAIT_OBJECTS_BGQ MPIDI_OFI_ON #define MPIDI_OFI_MAJOR_VERSION_BGQ 1 #define MPIDI_OFI_MINOR_VERSION_BGQ 5 @@ -281,6 +287,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_CONTEXT_BITS MPIDI_OFI_CONTEXT_BITS_BGQ #define MPIDI_OFI_SOURCE_BITS MPIDI_OFI_SOURCE_BITS_BGQ #define MPIDI_OFI_TAG_BITS MPIDI_OFI_TAG_BITS_BGQ +#define MPIDI_OFI_COUNTER_WAIT_OBJECTS MPIDI_OFI_COUNTER_WAIT_OBJECTS_BGQ #define MPIDI_OFI_SYNC_SEND_ACK (0x0010000000000000ULL) #define MPIDI_OFI_SYNC_SEND (0x0020000000000000ULL) #define MPIDI_OFI_DYNPROC_SEND (0x0040000000000000ULL) @@ -311,6 +318,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_CONTEXT_BITS_RXM (20) #define MPIDI_OFI_SOURCE_BITS_RXM (0) #define MPIDI_OFI_TAG_BITS_RXM (31) +#define MPIDI_OFI_COUNTER_WAIT_OBJECTS_RXM MPIDI_OFI_ON #define MPIDI_OFI_MAJOR_VERSION_RXM 1 #define MPIDI_OFI_MINOR_VERSION_RXM 6 @@ -341,6 +349,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_CONTEXT_BITS MPIDI_OFI_CONTEXT_BITS_RXM #define MPIDI_OFI_SOURCE_BITS MPIDI_OFI_SOURCE_BITS_RXM #define MPIDI_OFI_TAG_BITS MPIDI_OFI_TAG_BITS_RXM +#define MPIDI_OFI_COUNTER_WAIT_OBJECTS MPIDI_OFI_COUNTER_WAIT_OBJECTS_RXM #define MPIDI_OFI_SYNC_SEND_ACK (0x0010000000000000ULL) #define MPIDI_OFI_SYNC_SEND (0x0020000000000000ULL) #define MPIDI_OFI_DYNPROC_SEND (0x0040000000000000ULL) @@ -371,6 +380,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_CONTEXT_BITS_VERBS_RXM (20) #define MPIDI_OFI_SOURCE_BITS_VERBS_RXM (0) #define MPIDI_OFI_TAG_BITS_VERBS_RXM (31) +#define MPIDI_OFI_COUNTER_WAIT_OBJECTS_VERBS_RXM MPIDI_OFI_ON #define MPIDI_OFI_MAJOR_VERSION_VERBS_RXM 1 #define MPIDI_OFI_MINOR_VERSION_VERBS_RXM 5 @@ -403,6 +413,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_CONTEXT_BITS MPIDI_OFI_CONTEXT_BITS_VERBS_RXM #define MPIDI_OFI_SOURCE_BITS MPIDI_OFI_SOURCE_BITS_VERBS_RXM #define MPIDI_OFI_TAG_BITS MPIDI_OFI_TAG_BITS_VERBS_RXM +#define MPIDI_OFI_COUNTER_WAIT_OBJECTS MPIDI_OFI_COUNTER_WAIT_OBJECTS_VERBS_RXM #define MPIDI_OFI_SYNC_SEND_ACK (0x0010000000000000ULL) #define MPIDI_OFI_SYNC_SEND (0x0020000000000000ULL) #define MPIDI_OFI_DYNPROC_SEND (0x0040000000000000ULL) @@ -433,6 +444,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_CONTEXT_BITS_GNI (16) #define MPIDI_OFI_SOURCE_BITS_GNI (24) #define MPIDI_OFI_TAG_BITS_GNI (20) +#define MPIDI_OFI_COUNTER_WAIT_OBJECTS_GNI MPIDI_OFI_ON #define MPIDI_OFI_MAJOR_VERSION_GNI 1 #define MPIDI_OFI_MINOR_VERSION_GNI 5 @@ -465,6 +477,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_CONTEXT_BITS MPIDI_OFI_CONTEXT_BITS_GNI #define MPIDI_OFI_SOURCE_BITS MPIDI_OFI_SOURCE_BITS_GNI #define MPIDI_OFI_TAG_BITS MPIDI_OFI_TAG_BITS_GNI +#define MPIDI_OFI_COUNTER_WAIT_OBJECTS MPIDI_OFI_COUNTER_WAIT_OBJECTS_GNI #define MPIDI_OFI_SYNC_SEND_ACK (0x1000000000000000ULL) #define MPIDI_OFI_SYNC_SEND (0x2000000000000000ULL) #define MPIDI_OFI_DYNPROC_SEND (0x4000000000000000ULL) @@ -502,6 +515,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_CONTEXT_BITS_DEFAULT (20) #define MPIDI_OFI_SOURCE_BITS_DEFAULT (0) #define MPIDI_OFI_TAG_BITS_DEFAULT (31) +#define MPIDI_OFI_COUNTER_WAIT_OBJECTS_DEFAULT MPIDI_OFI_ON #define MPIDI_OFI_SYNC_SEND_ACK_DEFAULT (0x0010000000000000ULL) #define MPIDI_OFI_SYNC_SEND_DEFAULT (0x0020000000000000ULL) #define MPIDI_OFI_DYNPROC_SEND_DEFAULT (0x0040000000000000ULL) @@ -536,6 +550,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_CONTEXT_BITS_MINIMAL (16) #define MPIDI_OFI_SOURCE_BITS_MINIMAL (24) #define MPIDI_OFI_TAG_BITS_MINIMAL (20) +#define MPIDI_OFI_COUNTER_WAIT_OBJECTS_MINIMAL MPIDI_OFI_ON #define MPIDI_OFI_SYNC_SEND_MINIMAL (0x1000000000000000ULL) #define MPIDI_OFI_SYNC_SEND_ACK_MINIMAL (0x2000000000000000ULL) #define MPIDI_OFI_DYNPROC_SEND_MINIMAL (0x4000000000000000ULL) @@ -568,6 +583,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_CONTEXT_BITS MPIDI_OFI_global.settings.context_bits #define MPIDI_OFI_SOURCE_BITS MPIDI_OFI_global.settings.source_bits #define MPIDI_OFI_TAG_BITS MPIDI_OFI_global.settings.tag_bits +#define MPIDI_OFI_COUNTER_WAIT_OBJECTS MPIDI_OFI_global.settings.counter_wait_objects #define MPIDI_OFI_MAJOR_VERSION MPIDI_OFI_global.settings.major_version #define MPIDI_OFI_MINOR_VERSION MPIDI_OFI_global.settings.minor_version #define MPIDI_OFI_CONTEXT_STRUCTS 2 /* Compile time configurable only */ diff --git a/src/mpid/ch4/netmod/ofi/ofi_init.c b/src/mpid/ch4/netmod/ofi/ofi_init.c index 2c575b726c3..9612dcc4e1c 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_init.c +++ b/src/mpid/ch4/netmod/ofi/ofi_init.c @@ -1213,7 +1213,11 @@ static int create_vni_domain(struct fid_domain **p_domain, struct fid_av **p_av, struct fi_cntr_attr cntr_attr; memset(&cntr_attr, 0, sizeof(cntr_attr)); cntr_attr.events = FI_CNTR_EVENTS_COMP; - cntr_attr.wait_obj = FI_WAIT_UNSPEC; + if (MPIDI_OFI_COUNTER_WAIT_OBJECTS) { + cntr_attr.wait_obj = FI_WAIT_UNSPEC; + } else { + cntr_attr.wait_obj = FI_WAIT_NONE; + } MPIDI_OFI_CALL(fi_cntr_open(domain, &cntr_attr, p_cntr, NULL), openct); fn_exit: diff --git a/src/mpid/ch4/netmod/ofi/ofi_types.h b/src/mpid/ch4/netmod/ofi/ofi_types.h index 09ff0a7ba0a..a871ac441f0 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_types.h +++ b/src/mpid/ch4/netmod/ofi/ofi_types.h @@ -308,6 +308,7 @@ typedef struct { int context_bits; int source_bits; int tag_bits; + int counter_wait_objects; int major_version; int minor_version; int num_am_buffers; diff --git a/src/mpid/ch4/netmod/ofi/ofi_win.h b/src/mpid/ch4/netmod/ofi/ofi_win.h index 37346b07cb6..0ebd83b6f36 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_win.h +++ b/src/mpid/ch4/netmod/ofi/ofi_win.h @@ -48,7 +48,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_win_do_progress(MPIR_Win * win, int vni) donecount = fi_cntr_read(MPIDI_OFI_WIN(win).cmpl_cntr); itercount++; - if (itercount == 1000) { + if (itercount == 1000 && MPIDI_OFI_COUNTER_WAIT_OBJECTS) { ret = fi_cntr_wait(MPIDI_OFI_WIN(win).cmpl_cntr, tcount, 0); MPIDI_OFI_ERR(ret < 0 && ret != -FI_ETIMEDOUT, mpi_errno, From 47f4a1315e7fa01aba89dd06f2736216e3445772 Mon Sep 17 00:00:00 2001 From: Wesley Bland Date: Wed, 29 Sep 2021 15:35:43 -0500 Subject: [PATCH 215/607] ch4/ofi: Add support for FI_MR_ENDPOINT FI_MR_ENDPOINT requires that memory regions be bound to an endpoint before they can be used. This is in addition to any other bindings that may need to happen. The MR also needs to be enabled after all of the bindings are done. --- src/mpid/ch4/netmod/ofi/init_settings.c | 4 ++++ src/mpid/ch4/netmod/ofi/ofi_am_impl.h | 4 ++++ src/mpid/ch4/netmod/ofi/ofi_impl.h | 21 +++++++++++++++++++++ src/mpid/ch4/netmod/ofi/ofi_send.h | 4 ++++ src/mpid/ch4/netmod/ofi/ofi_win.c | 12 ++++++++++-- 5 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/init_settings.c b/src/mpid/ch4/netmod/ofi/init_settings.c index 5a0492fc979..0b25dacf00c 100644 --- a/src/mpid/ch4/netmod/ofi/init_settings.c +++ b/src/mpid/ch4/netmod/ofi/init_settings.c @@ -159,6 +159,10 @@ void MPIDI_OFI_init_hints(struct fi_info *hints) hints->domain_attr->mr_mode |= FI_MR_PROV_KEY; } #endif + +#ifdef FI_MR_ENDPOINT + hints->domain_attr->mr_mode |= FI_MR_ENDPOINT; +#endif } else { /* In old versions FI_MR_BASIC is equivallent to set * FI_MR_VIRT_ADDR, FI_MR_PROV_KEY, and FI_MR_ALLOCATED on. diff --git a/src/mpid/ch4/netmod/ofi/ofi_am_impl.h b/src/mpid/ch4/netmod/ofi/ofi_am_impl.h index d3e821e4ef4..25c35b63e7e 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_am_impl.h +++ b/src/mpid/ch4/netmod/ofi/ofi_am_impl.h @@ -281,6 +281,10 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_am_isend_long(int rank, MPIR_Comm * comm, 0ULL, lmt_info->rma_key, 0ULL, &MPIDI_OFI_AM_SREQ_HDR(sreq, lmt_mr), NULL), mr_reg); + mpi_errno = MPIDI_OFI_mr_bind(MPIDI_OFI_global.prov_use[0], MPIDI_OFI_AM_SREQ_HDR(sreq, lmt_mr), + MPIDI_OFI_global.ctx[ctx_idx].ep, NULL); + MPIR_ERR_CHECK(mpi_errno); + MPIDI_OFI_global.per_vni[vni_src].am_inflight_rma_send_mrs += 1; if (MPIDI_OFI_ENABLE_MR_PROV_KEY) { diff --git a/src/mpid/ch4/netmod/ofi/ofi_impl.h b/src/mpid/ch4/netmod/ofi/ofi_impl.h index 397aade7adf..f2bd05dfb06 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_impl.h +++ b/src/mpid/ch4/netmod/ofi/ofi_impl.h @@ -302,6 +302,27 @@ MPL_STATIC_INLINE_PREFIX void MPIDI_OFI_cntr_set(int ctx_idx, int val) #endif } +MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_mr_bind(struct fi_info *prov, struct fid_mr *mr, + struct fid_ep *ep, struct fid_cntr *cntr) +{ + int mpi_errno = MPI_SUCCESS; + + if (prov->domain_attr->mr_mode == FI_MR_ENDPOINT) { + /* Bind the memory region to the endpoint */ + MPIDI_OFI_CALL(fi_mr_bind(mr, &ep->fid, 0ULL), mr_bind); + /* Bind the memory region to the counter */ + if (cntr != NULL) { + MPIDI_OFI_CALL(fi_mr_bind(mr, &cntr->fid, 0ULL), mr_bind); + } + MPIDI_OFI_CALL(fi_mr_enable(mr), mr_enable); + } + + fn_exit: + return mpi_errno; + fn_fail: + goto fn_exit; +} + /* Externs: see util.c for definition */ #define MPIDI_OFI_LOCAL_MR_KEY 0 #define MPIDI_OFI_COLL_MR_KEY 1 diff --git a/src/mpid/ch4/netmod/ofi/ofi_send.h b/src/mpid/ch4/netmod/ofi/ofi_send.h index d0d95962005..0a0f6e269c4 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_send.h +++ b/src/mpid/ch4/netmod/ofi/ofi_send.h @@ -323,6 +323,10 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_send_normal(const void *buf, MPI_Aint cou 0ULL, /* In: flags */ &huge_send_mrs[i], /* Out: memregion object */ NULL), mr_reg); /* In: context */ + mpi_errno = MPIDI_OFI_mr_bind(MPIDI_OFI_global.prov_use[0], huge_send_mrs[i], + MPIDI_OFI_global.ctx[MPIDI_OFI_get_ctx_index + (comm, vni_local, i)].ep, NULL); + MPIR_ERR_CHECK(mpi_errno); } MPIDI_OFI_REQUEST(sreq, huge.send_mrs) = huge_send_mrs; if (MPIDI_OFI_ENABLE_MR_PROV_KEY) { diff --git a/src/mpid/ch4/netmod/ofi/ofi_win.c b/src/mpid/ch4/netmod/ofi/ofi_win.c index fa4d7f8326a..b831017188d 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_win.c +++ b/src/mpid/ch4/netmod/ofi/ofi_win.c @@ -158,7 +158,7 @@ static int win_allgather(MPIR_Win * win, void *base, int disp_unit) /* device buffers are not currently supported */ if (MPIR_GPU_query_pointer_is_dev(base)) rc = -1; - else + else { MPIDI_OFI_CALL_RETURN(fi_mr_reg(MPIDI_OFI_global.ctx[ctx_idx].domain, /* In: Domain Object */ base, /* In: Lower memory address */ len, /* In: Length */ @@ -168,6 +168,10 @@ static int win_allgather(MPIR_Win * win, void *base, int disp_unit) 0ULL, /* In: flags */ &MPIDI_OFI_WIN(win).mr, /* Out: memregion object */ NULL), rc); /* In: context */ + mpi_errno = MPIDI_OFI_mr_bind(MPIDI_OFI_global.prov_use[0], MPIDI_OFI_WIN(win).mr, + MPIDI_OFI_WIN(win).ep, MPIDI_OFI_WIN(win).cmpl_cntr); + MPIR_ERR_CHECK(mpi_errno); + } } else if (win->create_flavor == MPI_WIN_FLAVOR_DYNAMIC) { /* We may still do native atomics with collective attach, let's load acc_hint */ load_acc_hint(win); @@ -907,7 +911,7 @@ int MPIDI_OFI_mpi_win_attach_hook(MPIR_Win * win, void *base, MPI_Aint size) /* device buffers are not currently supported */ if (MPIR_GPU_query_pointer_is_dev(base)) rc = -1; - else + else { MPIDI_OFI_CALL_RETURN(fi_mr_reg(MPIDI_OFI_global.ctx[ctx_idx].domain, /* In: Domain Object */ base, /* In: Lower memory address */ size, /* In: Length */ @@ -917,6 +921,10 @@ int MPIDI_OFI_mpi_win_attach_hook(MPIR_Win * win, void *base, MPI_Aint size) 0ULL, /* In: flags */ &mr, /* Out: memregion object */ NULL), rc); /* In: context */ + mpi_errno = MPIDI_OFI_mr_bind(MPIDI_OFI_global.prov_use[0], MPIDI_OFI_WIN(win).mr, + MPIDI_OFI_WIN(win).ep, MPIDI_OFI_WIN(win).cmpl_cntr); + MPIR_ERR_CHECK(mpi_errno); + } /* Check if any process fails to register. If so, release local MR and force AM path. */ MPIR_Allreduce(&rc, &allrc, 1, MPI_INT, MPI_MIN, comm_ptr, &errflag); From b9b4a1d0fa144e889c06773d7edc3b366cca20cd Mon Sep 17 00:00:00 2001 From: Wesley Bland Date: Mon, 1 Jun 2020 17:08:30 -0500 Subject: [PATCH 216/607] ch4/ofi: Create CXI Capability Set Co-authored-by: Atul Kulkarni --- src/mpid/ch4/netmod/ofi/globals.c | 25 ++++++ src/mpid/ch4/netmod/ofi/ofi_capability_sets.h | 78 +++++++++++++++++++ src/mpid/ch4/netmod/ofi/subconfigure.m4 | 10 +++ 3 files changed, 113 insertions(+) diff --git a/src/mpid/ch4/netmod/ofi/globals.c b/src/mpid/ch4/netmod/ofi/globals.c index f7733df055b..d40ab2d52a9 100644 --- a/src/mpid/ch4/netmod/ofi/globals.c +++ b/src/mpid/ch4/netmod/ofi/globals.c @@ -148,6 +148,31 @@ MPIDI_OFI_capabilities_t MPIDI_OFI_caps_list[MPIDI_OFI_NUM_SETS] = .major_version = MPIDI_OFI_MAJOR_VERSION_BGQ, .minor_version = MPIDI_OFI_MINOR_VERSION_BGQ} , + { /* cxi */ + .enable_av_table = MPIDI_OFI_ENABLE_AV_TABLE_CXI, + .enable_scalable_endpoints = MPIDI_OFI_ENABLE_SCALABLE_ENDPOINTS_CXI, + .enable_shared_contexts = MPIDI_OFI_ENABLE_SHARED_CONTEXTS_CXI, + .enable_mr_virt_address = MPIDI_OFI_ENABLE_MR_VIRT_ADDRESS_CXI, + .enable_mr_allocated = MPIDI_OFI_ENABLE_MR_ALLOCATED_CXI, + .enable_mr_prov_key = MPIDI_OFI_ENABLE_MR_PROV_KEY_CXI, + .enable_tagged = MPIDI_OFI_ENABLE_TAGGED_CXI, + .enable_am = MPIDI_OFI_ENABLE_AM_CXI, + .enable_rma = MPIDI_OFI_ENABLE_RMA_CXI, + .enable_atomics = MPIDI_OFI_ENABLE_ATOMICS_CXI, + .enable_data_auto_progress = MPIDI_OFI_ENABLE_DATA_AUTO_PROGRESS_CXI, + .enable_control_auto_progress = MPIDI_OFI_ENABLE_CONTROL_AUTO_PROGRESS_CXI, + .enable_pt2pt_nopack = MPIDI_OFI_ENABLE_PT2PT_NOPACK_CXI, + .num_am_buffers = MPIDI_OFI_NUM_AM_BUFFERS_CXI, + .max_endpoints = MPIDI_OFI_MAX_ENDPOINTS_CXI, + .max_endpoints_bits = MPIDI_OFI_MAX_ENDPOINTS_BITS_CXI, + .fetch_atomic_iovecs = MPIDI_OFI_FETCH_ATOMIC_IOVECS_CXI, + .context_bits = MPIDI_OFI_CONTEXT_BITS_CXI, + .source_bits = MPIDI_OFI_SOURCE_BITS_CXI, + .tag_bits = MPIDI_OFI_TAG_BITS_CXI, + .counter_wait_objects = MPIDI_OFI_COUNTER_WAIT_OBJECTS_CXI, + .major_version = MPIDI_OFI_MAJOR_VERSION_CXI, + .minor_version = MPIDI_OFI_MINOR_VERSION_CXI} + , { /* VERBS_RXM */ .enable_av_table = MPIDI_OFI_ENABLE_AV_TABLE_VERBS_RXM, .enable_scalable_endpoints = MPIDI_OFI_ENABLE_SCALABLE_ENDPOINTS_VERBS_RXM, diff --git a/src/mpid/ch4/netmod/ofi/ofi_capability_sets.h b/src/mpid/ch4/netmod/ofi/ofi_capability_sets.h index fed37b2c368..9e623a64ad8 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_capability_sets.h +++ b/src/mpid/ch4/netmod/ofi/ofi_capability_sets.h @@ -24,6 +24,7 @@ enum { MPIDI_OFI_SET_NUMBER_PSM2, MPIDI_OFI_SET_NUMBER_SOCKETS, MPIDI_OFI_SET_NUMBER_BGQ, + MPIDI_OFI_SET_NUMBER_CXI, MPIDI_OFI_SET_NUMBER_VERBS_RXM, MPIDI_OFI_SET_NUMBER_RXM, MPIDI_OFI_SET_NUMBER_GNI, @@ -49,6 +50,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) return MPIDI_OFI_SET_NUMBER_SOCKETS; } else if (!strcmp("bgq", set_name)) { return MPIDI_OFI_SET_NUMBER_BGQ; + } else if (!strcmp("cxi", set_name)) { + return MPIDI_OFI_SET_NUMBER_CXI; } else if (!strcmp("verbs;ofi_rxm", set_name)) { return MPIDI_OFI_SET_NUMBER_VERBS_RXM; } else if (strstr(set_name, "ofi_rxm")) { @@ -297,6 +300,81 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_CONTEXT_STRUCTS 2 #endif +#define MPIDI_OFI_ENABLE_AV_TABLE_CXI MPIDI_OFI_ON +#define MPIDI_OFI_ENABLE_SCALABLE_ENDPOINTS_CXI MPIDI_OFI_OFF /* This is expected to change in + * the future. */ +#define MPIDI_OFI_MAX_ENDPOINTS_CXI MPIDI_OFI_MAX_ENDPOINTS_REGULAR +#define MPIDI_OFI_MAX_ENDPOINTS_BITS_CXI MPIDI_OFI_MAX_ENDPOINTS_BITS_REGULAR +#define MPIDI_OFI_ENABLE_SHARED_CONTEXTS_CXI MPIDI_OFI_OFF +#define MPIDI_OFI_ENABLE_MR_VIRT_ADDRESS_CXI MPIDI_OFI_OFF +#define MPIDI_OFI_ENABLE_MR_ALLOCATED_CXI MPIDI_OFI_OFF +#define MPIDI_OFI_ENABLE_MR_PROV_KEY_CXI MPIDI_OFI_OFF +#define MPIDI_OFI_ENABLE_TAGGED_CXI MPIDI_OFI_ON +#define MPIDI_OFI_ENABLE_RMA_CXI MPIDI_OFI_ON +#define MPIDI_OFI_ENABLE_AM_CXI MPIDI_OFI_ON +#define MPIDI_OFI_ENABLE_ATOMICS_CXI MPIDI_OFI_ENABLE_RMA_CXI +#define MPIDI_OFI_FETCH_ATOMIC_IOVECS_CXI 1 +#define MPIDI_OFI_ENABLE_DATA_AUTO_PROGRESS_CXI MPIDI_OFI_OFF +#define MPIDI_OFI_ENABLE_CONTROL_AUTO_PROGRESS_CXI MPIDI_OFI_OFF +#define MPIDI_OFI_ENABLE_PT2PT_NOPACK_CXI MPIDI_OFI_ON +#define MPIDI_OFI_ENABLE_HMEM_CXI MPIDI_OFI_OFF +#define MPIDI_OFI_NUM_AM_BUFFERS_CXI MPIDI_OFI_MAX_NUM_AM_BUFFERS +#define MPIDI_OFI_CONTEXT_BITS_CXI (20) +#define MPIDI_OFI_SOURCE_BITS_CXI (0) +#define MPIDI_OFI_TAG_BITS_CXI (20) /* The CXI provider has a smaller tag space + * than other providers so the number of + * tag bits exposed to the user is + * restricted. This might be expanded + * slightly at some point, but it will + * probably never be the same as some of + * the other providers. */ +#define MPIDI_OFI_COUNTER_WAIT_OBJECTS_CXI MPIDI_OFI_OFF +#define MPIDI_OFI_MAJOR_VERSION_CXI 1 +#define MPIDI_OFI_MINOR_VERSION_CXI 5 + +#ifdef MPIDI_CH4_OFI_USE_SET_CXI +#define MPIDI_OFI_SET_NUMBER MPIDI_OFI_SET_NUMBER_CXI +#define MPIDI_OFI_ENABLE_AV_TABLE MPIDI_OFI_ENABLE_AV_TABLE_CXI +#define MPIDI_OFI_ENABLE_SCALABLE_ENDPOINTS MPIDI_OFI_ENABLE_SCALABLE_ENDPOINTS_CXI +#define MPIDI_OFI_MAX_ENDPOINTS MPIDI_OFI_MAX_ENDPOINTS_CXI +#define MPIDI_OFI_MAX_ENDPOINTS_BITS MPIDI_OFI_MAX_ENDPOINTS_BITS_CXI +#define MPIDI_OFI_ENABLE_SHARED_CONTEXTS MPIDI_OFI_global.settings.enable_shared_contexts /* Always controlled by CVAR */ +#define MPIDI_OFI_ENABLE_MR_VIRT_ADDRESS MPIDI_OFI_ENABLE_MR_VIRT_ADDRESS_CXI +#define MPIDI_OFI_ENABLE_MR_ALLOCATED MPIDI_OFI_ENABLE_MR_ALLOCATED_CXI +#define MPIDI_OFI_ENABLE_MR_PROV_KEY MPIDI_OFI_ENABLE_MR_PROV_KEY_CXI +#define MPIDI_OFI_ENABLE_TAGGED MPIDI_OFI_ENABLE_TAGGED_CXI +#define MPIDI_OFI_ENABLE_AM MPIDI_OFI_ENABLE_AM_CXI +#define MPIDI_OFI_ENABLE_RMA MPIDI_OFI_ENABLE_RMA_CXI +#define MPIDI_OFI_ENABLE_ATOMICS MPIDI_OFI_ENABLE_ATOMICS_CXI +#define MPIDI_OFI_FETCH_ATOMIC_IOVECS MPIDI_OFI_FETCH_ATOMIC_IOVECS_CXI +#define MPIDI_OFI_IOVEC_ALIGN (1) +#define MPIDI_OFI_ENABLE_DATA_AUTO_PROGRESS MPIDI_OFI_ENABLE_DATA_AUTO_PROGRESS_CXI +#define MPIDI_OFI_ENABLE_CONTROL_AUTO_PROGRESS MPIDI_OFI_ENABLE_CONTROL_AUTO_PROGRESS_CXI +#define MPIDI_OFI_ENABLE_PT2PT_NOPACK MPIDI_OFI_ENABLE_PT2PT_NOPACK_CXI +#define MPIDI_OFI_ENABLE_HMEM MPIDI_OFI_ENABLE_HMEM_CXI +#define MPIDI_OFI_NUM_AM_BUFFERS MPIDI_OFI_NUM_AM_BUFFERS_CXI +#define MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS_CXI +#define MPIDI_OFI_PROTOCOL_MASK (0x00000E0000000000ULL) /* This is set to 3 (E) even though we actually use 4 (F). The + * ssend ack bit needs to live outside the protocol bit space + * to avoid accidentally matching unintended messages. Because + * of this, we shift the PROTOCOL_MASK one extra bit to the + * left to take the place of the empty SSEND_ACK bit. */ +#define MPIDI_OFI_CONTEXT_MASK (0x000000FFFFF00000ULL) +#define MPIDI_OFI_SOURCE_MASK (0x0000000000000000ULL) /* CXI does support immediate data so this field is zeroed */ +#define MPIDI_OFI_TAG_MASK (0x00000000000FFFFFULL) +#define MPIDI_OFI_CONTEXT_BITS MPIDI_OFI_CONTEXT_BITS_CXI +#define MPIDI_OFI_SOURCE_BITS MPIDI_OFI_SOURCE_BITS_CXI +#define MPIDI_OFI_TAG_BITS MPIDI_OFI_TAG_BITS_CXI +#define MPIDI_OFI_COUNTER_WAIT_OBJECTS MPIDI_OFI_COUNTER_WAIT_OBJECTS_CXI +#define MPIDI_OFI_SYNC_SEND_ACK (0x0000010000000000ULL) +#define MPIDI_OFI_SYNC_SEND (0x0000020000000000ULL) +#define MPIDI_OFI_DYNPROC_SEND (0x0000040000000000ULL) +#define MPIDI_OFI_HUGE_SEND (0x0000080000000000ULL) +#define MPIDI_OFI_MAJOR_VERSION MPIDI_OFI_MAJOR_VERSION_CXI +#define MPIDI_OFI_MINOR_VERSION MPIDI_OFI_MINOR_VERSION_CXI +#define MPIDI_OFI_CONTEXT_STRUCTS 2 +#endif + #define MPIDI_OFI_ENABLE_AV_TABLE_RXM MPIDI_OFI_OFF #define MPIDI_OFI_ENABLE_SCALABLE_ENDPOINTS_RXM MPIDI_OFI_OFF #define MPIDI_OFI_ENABLE_SHARED_CONTEXTS_RXM MPIDI_OFI_OFF diff --git a/src/mpid/ch4/netmod/ofi/subconfigure.m4 b/src/mpid/ch4/netmod/ofi/subconfigure.m4 index 71533eb2327..83891a0ab18 100644 --- a/src/mpid/ch4/netmod/ofi/subconfigure.m4 +++ b/src/mpid/ch4/netmod/ofi/subconfigure.m4 @@ -67,6 +67,7 @@ AM_COND_IF([BUILD_CH4_NETMOD_OFI],[ enable_mrail="no" enable_efa="no" enable_netdir="no" + enable_cxi="no" else enable_psm="yes" enable_psm2="yes" @@ -86,6 +87,7 @@ AM_COND_IF([BUILD_CH4_NETMOD_OFI],[ enable_mrail="yes" enable_efa="yes" enable_netdir="yes" + enable_cxi="yes" fi for provider in $netmod_args ; do @@ -111,6 +113,9 @@ AM_COND_IF([BUILD_CH4_NETMOD_OFI],[ enable_verbs="yes" enable_rxm="yes" ;; + "cxi") + enable_cxi="yes" + ;; dnl For these providers, we don't know exactly which capabilities we dnl want to select by default so we turn on runtime checks. At some point @@ -253,6 +258,10 @@ AM_COND_IF([BUILD_CH4_NETMOD_OFI],[ enable_verbs="yes" enable_rxm="yes" ;; + "cxi") + AC_DEFINE([MPIDI_CH4_OFI_USE_SET_CXI], [1], [Define to use cxi capability set]) + enable_cxi="yes" + ;; *) AC_MSG_WARN("Invalid provider $netmod_args") esac @@ -286,6 +295,7 @@ AM_COND_IF([BUILD_CH4_NETMOD_OFI],[ prov_config="$prov_config --enable-mrail=${enable_mrail}" prov_config="$prov_config --enable-efa=${enable_efa}" prov_config="$prov_config --enable-netdir=${enable_netdir}" + prov_config="$prov_config --enable-cxi=${enable_cxi}" fi if test "x${ofi_direct_provider}" != "x" ; then From cc2a0a587bc90df9c4ff20cf86c6f91335d4edf6 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 2 Dec 2021 08:52:57 -0600 Subject: [PATCH 217/607] maint: mark main branch as version 4.1a1 --- maint/version.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maint/version.m4 b/maint/version.m4 index f72d55c7b4d..f4981e9880e 100644 --- a/maint/version.m4 +++ b/maint/version.m4 @@ -14,7 +14,7 @@ # changing this by playing with diversions, but then we would probably be # playing with autotools-fire. -m4_define([MPICH_VERSION_m4],[4.0a2])dnl +m4_define([MPICH_VERSION_m4],[4.1a1])dnl m4_define([MPICH_RELEASE_DATE_m4],[unreleased development copy])dnl # For libtool ABI versioning rules see: From 843084d3dcd6cb2c4eceb5da8e789b641178ba51 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 2 Dec 2021 17:14:54 -0600 Subject: [PATCH 218/607] xfail: part/pingping The corresponding test in pt2pt is already xfailed. --- test/mpi/maint/jenkins/xfail.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/test/mpi/maint/jenkins/xfail.conf b/test/mpi/maint/jenkins/xfail.conf index 08c28caa164..356f7b95af0 100644 --- a/test/mpi/maint/jenkins/xfail.conf +++ b/test/mpi/maint/jenkins/xfail.conf @@ -85,6 +85,7 @@ * * * ch3:tcp * /^mt_improbe_isendrecv/ xfail=issue4258 threads/pt2pt/testlist # pingping tests with large testsize currently fails async tests due to netmod handling of large message queue * * async * * /^pingping .*testsize=32/ xfail=issue4474 pt2pt/testlist.dtp +* * async * * /^pingping .*testsize=32/ xfail=issue4474 part/testlist.dtp # dup_leak_test suffers from mutex unfairness issue under load for ch4:ofi * * * ch4:ofi * /^dup_leak_test .*iter=12345.*/ xfail=issue4595 threads/comm/testlist # more mutex unfairness on freebsd64. note: check these after upgrading freebsd64 hardware From 1141aa6d0502f06aa043c908df51274139231136 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 6 Dec 2021 14:02:44 -0600 Subject: [PATCH 219/607] modules: use --disable-gl to configure embedded hwloc The extra grphic layer dependency is undesirable. --- confdb/aclocal_modules.m4 | 1 + 1 file changed, 1 insertion(+) diff --git a/confdb/aclocal_modules.m4 b/confdb/aclocal_modules.m4 index bb2eca940de..51a92106721 100644 --- a/confdb/aclocal_modules.m4 +++ b/confdb/aclocal_modules.m4 @@ -43,6 +43,7 @@ AC_DEFUN([PAC_CONFIG_HWLOC_EMBEDDED],[ PAC_PUSH_FLAG([CFLAGS]) CFLAGS="$USER_CFLAGS $1" hwloc_config_args="--enable-embedded-mode --disable-visibility" + hwloc_config_args="$hwloc_config_args --disable-gl" hwloc_config_args="$hwloc_config_args --disable-libxml2" hwloc_config_args="$hwloc_config_args --disable-nvml" hwloc_config_args="$hwloc_config_args --disable-cuda" From 80f193864a2bf4a124961669bfd844f8a558b116 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 6 Dec 2021 14:09:11 -0600 Subject: [PATCH 220/607] ch4: allow --with-ch4-vci-method=tag We should assume the user know what they are doing if they explicitly configure with the option. --- src/mpid/ch4/src/ch4_vci.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mpid/ch4/src/ch4_vci.h b/src/mpid/ch4/src/ch4_vci.h index e985af1ce73..0d8a4258b50 100644 --- a/src/mpid/ch4/src/ch4_vci.h +++ b/src/mpid/ch4/src/ch4_vci.h @@ -51,7 +51,6 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_get_vci(int flag, MPIR_Comm * comm_ptr, } #elif MPIDI_CH4_VCI_METHOD == MPICH_VCI__TAG -#error "MPICH_VCI__TAG not implemented." /* A way to allow explicit vci by user, based on (undocumented) convention. Embed src_vci and dst_vci inside tag, 5 bits each NOTE: this serve as temporary replacement for explicit scheme (until mpi-layer api adds support). From 4f9f8514df80edb1e6b25415d12dbd07c3ac179d Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 3 Jun 2021 22:26:22 -0500 Subject: [PATCH 221/607] request: add MPIR_CVAR_REQUEST_ERR_FATAL When set, let MPIR_Waitall, MPIR_Testall, MPIR_Waitsome, and MPIR_Testsome return error code so the default error handler will dump error stack on abort. --- src/mpi/request/request_impl.c | 76 ++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 12 deletions(-) diff --git a/src/mpi/request/request_impl.c b/src/mpi/request/request_impl.c index e432a1e5741..b2b52c02ac6 100644 --- a/src/mpi/request/request_impl.c +++ b/src/mpi/request/request_impl.c @@ -5,6 +5,28 @@ #include "mpiimpl.h" +/* +=== BEGIN_MPI_T_CVAR_INFO_BLOCK === + +cvars: + - name : MPIR_CVAR_REQUEST_ERR_FATAL + category : REQUEST + type : boolean + default : false + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_LOCAL + description : >- + By default, MPI_Waitall, MPI_Testall, MPI_Waitsome, and MPI_Testsome + return MPI_ERR_IN_STATUS when one of the request fails. If + MPIR_CVAR_REQUEST_ERR_FATAL is set to true, these routines will + return the error code of the request immediately. The default + MPI_ERRS_ARE_FATAL error handler will dump a error stack in this + case, which maybe more convenient for debugging. + +=== END_MPI_T_CVAR_INFO_BLOCK === +*/ + int MPIR_Status_set_cancelled_impl(MPI_Status * status, int flag) { MPIR_STATUS_SET_CANCEL_BIT(*status, flag ? TRUE : FALSE); @@ -492,7 +514,12 @@ int MPIR_Testall(int count, MPI_Request array_of_requests[], int *flag, if (MPIX_ERR_PROC_FAILED == MPIR_ERR_GET_CLASS(rc) || MPIX_ERR_PROC_FAILED_PENDING == MPIR_ERR_GET_CLASS(rc)) proc_failure = TRUE; - mpi_errno = MPI_ERR_IN_STATUS; + if (MPIR_CVAR_REQUEST_ERR_FATAL) { + mpi_errno = request_ptrs[i]->status.MPI_ERROR; + MPIR_ERR_CHECK(mpi_errno); + } else { + mpi_errno = MPI_ERR_IN_STATUS; + } } } else if (unlikely(MPIR_Request_is_anysrc_mismatched(request_ptrs[i]))) { mpi_errno = MPI_ERR_IN_STATUS; @@ -820,9 +847,14 @@ int MPIR_Testsome(int incount, MPI_Request array_of_requests[], MPIR_Request * r if (rc == MPI_SUCCESS) { request_ptrs[idx] = NULL; } else { - mpi_errno = MPI_ERR_IN_STATUS; - if (status_ptr != MPI_STATUS_IGNORE) { - status_ptr->MPI_ERROR = rc; + if (MPIR_CVAR_REQUEST_ERR_FATAL) { + mpi_errno = request_ptrs[idx]->status.MPI_ERROR; + MPIR_ERR_CHECK(mpi_errno); + } else { + mpi_errno = MPI_ERR_IN_STATUS; + if (status_ptr != MPI_STATUS_IGNORE) { + status_ptr->MPI_ERROR = rc; + } } } } @@ -1077,8 +1109,13 @@ int MPIR_Waitall(int count, MPI_Request array_of_requests[], MPI_Status array_of rc = MPIR_Request_completion_processing_fastpath(&array_of_requests[i], request_ptrs[i]); if (rc != MPI_SUCCESS) { - MPIR_ERR_SET(mpi_errno, MPI_ERR_IN_STATUS, "**instatus"); - goto fn_exit; + if (MPIR_CVAR_REQUEST_ERR_FATAL) { + mpi_errno = request_ptrs[i]->status.MPI_ERROR; + MPIR_ERR_CHECK(mpi_errno); + } else { + MPIR_ERR_SET(mpi_errno, MPI_ERR_IN_STATUS, "**instatus"); + goto fn_exit; + } } } continue; @@ -1095,8 +1132,13 @@ int MPIR_Waitall(int count, MPI_Request array_of_requests[], MPI_Status array_of array_of_requests[i] = MPI_REQUEST_NULL; } if (rc != MPI_SUCCESS) { - MPIR_ERR_SET(mpi_errno, MPI_ERR_IN_STATUS, "**instatus"); - goto fn_exit; + if (MPIR_CVAR_REQUEST_ERR_FATAL) { + mpi_errno = request_ptrs[i]->status.MPI_ERROR; + MPIR_ERR_CHECK(mpi_errno); + } else { + MPIR_ERR_SET(mpi_errno, MPI_ERR_IN_STATUS, "**instatus"); + goto fn_exit; + } } } continue; @@ -1115,7 +1157,12 @@ int MPIR_Waitall(int count, MPI_Request array_of_requests[], MPI_Status array_of if (rc == MPI_SUCCESS) { array_of_statuses[i].MPI_ERROR = MPI_SUCCESS; } else { - /* req completed with an error */ + if (MPIR_CVAR_REQUEST_ERR_FATAL) { + mpi_errno = request_ptrs[i]->status.MPI_ERROR; + MPIR_ERR_CHECK(mpi_errno); + } + + /* default error processing */ MPIR_ERR_SET(mpi_errno, MPI_ERR_IN_STATUS, "**instatus"); /* set the error code for this request */ @@ -1433,9 +1480,14 @@ int MPIR_Waitsome(int incount, MPI_Request array_of_requests[], MPIR_Request * r if (rc == MPI_SUCCESS) { request_ptrs[idx] = NULL; } else { - mpi_errno = MPI_ERR_IN_STATUS; - if (status_ptr != MPI_STATUS_IGNORE) { - status_ptr->MPI_ERROR = rc; + if (MPIR_CVAR_REQUEST_ERR_FATAL) { + mpi_errno = request_ptrs[idx]->status.MPI_ERROR; + MPIR_ERR_CHECK(mpi_errno); + } else { + mpi_errno = MPI_ERR_IN_STATUS; + if (status_ptr != MPI_STATUS_IGNORE) { + status_ptr->MPI_ERROR = rc; + } } } } From cf646ed155a1bb4457d821cc41ce060389ede931 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 6 Dec 2021 16:19:29 -0600 Subject: [PATCH 222/607] test: move gpu_query from manual to impls/mpich The manual tests are not regularly tested. Modify the gpu_query to be able to run by default and move into impls/mpich so it can be tested regularly. --- test/mpi/.gitignore | 2 +- test/mpi/configure.ac | 1 + test/mpi/impls/mpich/Makefile.am | 2 +- test/mpi/impls/mpich/misc/Makefile.am | 14 +++++++++ test/mpi/impls/mpich/misc/gpu_query.c | 43 +++++++++++++++++++++++++++ test/mpi/impls/mpich/misc/testlist | 1 + test/mpi/impls/mpich/testlist.in | 1 + test/mpi/manual/Makefile.am | 2 +- test/mpi/manual/gpu_query.c | 39 ------------------------ 9 files changed, 63 insertions(+), 42 deletions(-) create mode 100644 test/mpi/impls/mpich/misc/Makefile.am create mode 100644 test/mpi/impls/mpich/misc/gpu_query.c create mode 100644 test/mpi/impls/mpich/misc/testlist delete mode 100644 test/mpi/manual/gpu_query.c diff --git a/test/mpi/.gitignore b/test/mpi/.gitignore index 0cbca5d09ee..acc0e16f0a1 100644 --- a/test/mpi/.gitignore +++ b/test/mpi/.gitignore @@ -1146,6 +1146,7 @@ /impls/mpich/comm/testlist /impls/mpich/mpi_t/collparmt /impls/mpich/mpi_t/recvq_events +/impls/mpich/misc/gpu_query /impls/mpich/testlist /impls/testlist /include/mtest_mpix.h @@ -1211,7 +1212,6 @@ /maint/testmerge /maint/updatefiles /manual/dimsbalanced -/manual/gpu_query /manual/manyconnect /manual/mpi_t/mpit_test /manual/mpi_t/mpit_test2 diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index 87bb9281bab..31ddc7a88ef 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -1666,5 +1666,6 @@ AC_OUTPUT(maint/testmerge \ impls/mpich/comm/testlist \ impls/mpich/threads/Makefile \ impls/mpich/threads/pt2pt/Makefile \ + impls/mpich/misc/Makefile \ ) diff --git a/test/mpi/impls/mpich/Makefile.am b/test/mpi/impls/mpich/Makefile.am index 6fa7621aa66..8d393a364fd 100644 --- a/test/mpi/impls/mpich/Makefile.am +++ b/test/mpi/impls/mpich/Makefile.am @@ -7,7 +7,7 @@ include $(top_srcdir)/Makefile_single.mtest EXTRA_DIST = testlist.in -static_subdirs = mpi_t comm +static_subdirs = mpi_t comm misc # For future tests - note that the IO and RMA directories are optional, # and need to be handled as shown in this comment #SUBDIRS = $(static_subdirs) $(iodir) $(rmadir) diff --git a/test/mpi/impls/mpich/misc/Makefile.am b/test/mpi/impls/mpich/misc/Makefile.am new file mode 100644 index 00000000000..b6c4e8f32a1 --- /dev/null +++ b/test/mpi/impls/mpich/misc/Makefile.am @@ -0,0 +1,14 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +include $(top_srcdir)/Makefile_single.mtest + +EXTRA_DIST = testlist + +## for all programs that are just built from the single corresponding source +## file, we don't need per-target _SOURCES rules, automake will infer them +## correctly +noinst_PROGRAMS = \ + gpu_query diff --git a/test/mpi/impls/mpich/misc/gpu_query.c b/test/mpi/impls/mpich/misc/gpu_query.c new file mode 100644 index 00000000000..b6afb79cf20 --- /dev/null +++ b/test/mpi/impls/mpich/misc/gpu_query.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpi.h" +#include + +int main(int argc, char **argv) +{ + int errors = 0; + int cuda_support, ze_support, hip_support; + MPI_Init(NULL, NULL); + + MPIX_GPU_query_support(MPIX_GPU_SUPPORT_CUDA, &cuda_support); + MPIX_GPU_query_support(MPIX_GPU_SUPPORT_ZE, &ze_support); + MPIX_GPU_query_support(MPIX_GPU_SUPPORT_HIP, &hip_support); + +#if defined(HAVE_CUDA) + if (!cuda_support) { + printf("Expect cuda support but not found!\n"); + errors++; + } +#elif defined(HAVE_ZE) + if (!ze_support) { + printf("Expect ZE support but not found!\n"); + errors++; + } +#elif defined(HAVE_HIP) + if (!hip_support) { + printf("Expect HIP support but not found!\n"); + errors++; + } +#endif + + if (errors == 0) { + printf("No Errors\n"); + } + + MPI_Finalize(); + + return 0; +} diff --git a/test/mpi/impls/mpich/misc/testlist b/test/mpi/impls/mpich/misc/testlist new file mode 100644 index 00000000000..6bf2bfaa991 --- /dev/null +++ b/test/mpi/impls/mpich/misc/testlist @@ -0,0 +1 @@ +gpu_query 1 diff --git a/test/mpi/impls/mpich/testlist.in b/test/mpi/impls/mpich/testlist.in index da18b95df12..62a569ca772 100644 --- a/test/mpi/impls/mpich/testlist.in +++ b/test/mpi/impls/mpich/testlist.in @@ -1,5 +1,6 @@ mpi_t comm +misc @threadsdir@ # The IO and RMA directories are optional and need to be handled in # a special way. Uncomment these as appropriate when a test is added. diff --git a/test/mpi/manual/Makefile.am b/test/mpi/manual/Makefile.am index cf57ac0bf94..20fc1f2bdf1 100644 --- a/test/mpi/manual/Makefile.am +++ b/test/mpi/manual/Makefile.am @@ -8,7 +8,7 @@ include $(top_srcdir)/Makefile_single.mtest SUBDIRS = mpi_t noinst_PROGRAMS = singjoin testconnect testconnectserial dimsbalanced \ - spawntest_parent spawntest_child segfault gpu_query + spawntest_parent spawntest_child segfault # testconnectserial would like MPICHLIBSTR to be defined as the installation # directory of the MPI library. This definition is not required. diff --git a/test/mpi/manual/gpu_query.c b/test/mpi/manual/gpu_query.c deleted file mode 100644 index 1706ef814d1..00000000000 --- a/test/mpi/manual/gpu_query.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) by Argonne National Laboratory - * See COPYRIGHT in top-level directory - */ - -#include "mpi.h" -#include - -int main(int argc, char **argv) -{ - int cuda_support, ze_support, hip_support; - MPI_Init(NULL, NULL); - - MPIX_GPU_query_support(MPIX_GPU_SUPPORT_CUDA, &cuda_support); - MPIX_GPU_query_support(MPIX_GPU_SUPPORT_ZE, &ze_support); - MPIX_GPU_query_support(MPIX_GPU_SUPPORT_HIP, &hip_support); - - if (cuda_support && ze_support && hip_support) { - printf("CUDA and ZE and HIP are supported\n"); - } else if (cuda_support && ze_support) { - printf("CUDA and ZE are supported\n"); - } else if (cuda_support && hip_support) { - printf("CUDA and HIP are supported\n"); - } else if (ze_support && hip_support) { - printf("ZE and HIP are supported\n"); - } else if (cuda_support) { - printf("CUDA is supported\n"); - } else if (ze_support) { - printf("ZE is supported\n"); - } else if (hip_support) { - printf("HIP is supported\n"); - } else { - printf("No GPUs are supported\n"); - } - - MPI_Finalize(); - - return 0; -} From 7471f2e208be3adb694f26ac44a4c6743a6a6872 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 6 Dec 2021 21:02:22 -0600 Subject: [PATCH 223/607] misc: fix MPIX_Query_cuda_support etc For both MPIX_Query_cuda_support and MPIX_Query_ze_support, "Assert(mpi_errno)" should be "Assert(mpi_errno != MPI_SUCCESS)". --- src/binding/c/misc_api.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/binding/c/misc_api.txt b/src/binding/c/misc_api.txt index 6c308b8771d..d06a2ddbbe2 100644 --- a/src/binding/c/misc_api.txt +++ b/src/binding/c/misc_api.txt @@ -171,7 +171,7 @@ MPIX_Query_cuda_support: int mpi_errno ATTRIBUTE((unused)); mpi_errno = PMPIX_GPU_query_support(MPIX_GPU_SUPPORT_CUDA, &is_supported); - assert(mpi_errno); + assert(mpi_errno == MPI_SUCCESS); return is_supported; } @@ -185,7 +185,7 @@ MPIX_Query_ze_support: int mpi_errno ATTRIBUTE((unused)); mpi_errno = PMPIX_GPU_query_support(MPIX_GPU_SUPPORT_ZE, &is_supported); - assert(mpi_errno); + assert(mpi_errno == MPI_SUCCESS); return is_supported; } From c0595c8300308cd7f71ee194a2d2738df9302349 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 6 Dec 2021 20:54:23 -0600 Subject: [PATCH 224/607] misc: add missing HIP case in MPIX_GPU_query_support --- src/binding/c/misc_api.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/binding/c/misc_api.txt b/src/binding/c/misc_api.txt index d06a2ddbbe2..45c46b092d7 100644 --- a/src/binding/c/misc_api.txt +++ b/src/binding/c/misc_api.txt @@ -156,6 +156,11 @@ MPIX_GPU_query_support: *is_supported = 1; break; + case MPIX_GPU_SUPPORT_HIP: + if (type == MPL_GPU_TYPE_HIP) + *is_supported = 1; + break; + default: MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_ARG, "**badgputype"); } From d505dd78459c4100ef79ac352df764cf15c783c0 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 6 Dec 2021 21:05:11 -0600 Subject: [PATCH 225/607] misc: add MPIX_Query_hip_support Add MPIX_Query_hip_support() for completeness. --- src/binding/c/misc_api.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/binding/c/misc_api.txt b/src/binding/c/misc_api.txt index 45c46b092d7..7834541b27a 100644 --- a/src/binding/c/misc_api.txt +++ b/src/binding/c/misc_api.txt @@ -194,3 +194,17 @@ MPIX_Query_ze_support: return is_supported; } + +MPIX_Query_hip_support: + .desc: Returns whether HIP (AMD GPU) is supported + .impl: direct + .skip: global_cs, Errors +{ + int is_supported = 0; + int mpi_errno ATTRIBUTE((unused)); + + mpi_errno = PMPIX_GPU_query_support(MPIX_GPU_SUPPORT_HIP, &is_supported); + assert(mpi_errno == MPI_SUCCESS); + + return is_supported; +} From 93fd1b45efd0af3a25ce094ae828f5bb322d6da5 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 6 Dec 2021 21:11:04 -0600 Subject: [PATCH 226/607] test: enhance gpu_query test to cover MPIX_Query_cuda_support Enhance the test to cover MPIX_Query_cuda_support, MPIX_Query_ze_support, and MPIX_Query_hip_support. --- test/mpi/impls/mpich/misc/gpu_query.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/mpi/impls/mpich/misc/gpu_query.c b/test/mpi/impls/mpich/misc/gpu_query.c index b6afb79cf20..821266f1554 100644 --- a/test/mpi/impls/mpich/misc/gpu_query.c +++ b/test/mpi/impls/mpich/misc/gpu_query.c @@ -16,6 +16,20 @@ int main(int argc, char **argv) MPIX_GPU_query_support(MPIX_GPU_SUPPORT_ZE, &ze_support); MPIX_GPU_query_support(MPIX_GPU_SUPPORT_HIP, &hip_support); + if (cuda_support != MPIX_Query_cuda_support()) { + printf("MPIX_Query_cuda_support() return disagree with MPIX_GPU_query_support\n"); + errors++; + } + + if (ze_support != MPIX_Query_ze_support()) { + printf("MPIX_Query_ze_support() return disagree with MPIX_GPU_query_support\n"); + errors++; + } + + if (hip_support != MPIX_Query_hip_support()) { + printf("MPIX_Query_hip_support() return disagree with MPIX_GPU_query_support\n"); + errors++; + } #if defined(HAVE_CUDA) if (!cuda_support) { printf("Expect cuda support but not found!\n"); From bb688ad0303ba46504d9765834be6781fb018460 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 3 Dec 2021 14:47:44 -0600 Subject: [PATCH 227/607] datatype/typerep: use macro in checking buffer attr Use a macro to make the condition of cpu-only more concise and readable. --- .../datatype/typerep/src/typerep_yaksa_pack.c | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c b/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c index 1ce51988ede..f9f65977803 100644 --- a/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c +++ b/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c @@ -53,6 +53,10 @@ === END_MPI_T_CVAR_INFO_BLOCK === */ +#define IS_HOST(attr) \ + ((attr).type == MPL_GPU_POINTER_UNREGISTERED_HOST || \ + (attr).type == MPL_GPU_POINTER_REGISTERED_HOST) + /* When a returned typerep_req is expected, using the nonblocking yaksa routine and * return the request; otherwise use the blocking yaksa routine. */ static int typerep_do_copy(void *outbuf, const void *inbuf, MPI_Aint num_bytes, @@ -75,10 +79,7 @@ static int typerep_do_copy(void *outbuf, const void *inbuf, MPI_Aint num_bytes, MPIR_GPU_query_pointer_attr(inbuf, &inattr); MPIR_GPU_query_pointer_attr(outbuf, &outattr); - if ((inattr.type == MPL_GPU_POINTER_UNREGISTERED_HOST || - inattr.type == MPL_GPU_POINTER_REGISTERED_HOST) && - (outattr.type == MPL_GPU_POINTER_UNREGISTERED_HOST || - outattr.type == MPL_GPU_POINTER_REGISTERED_HOST)) { + if (IS_HOST(inattr) && IS_HOST(outattr)) { MPIR_Memcpy(outbuf, inbuf, num_bytes); } else { uintptr_t actual_pack_bytes; @@ -147,11 +148,7 @@ static int typerep_do_pack(const void *inbuf, MPI_Aint incount, MPI_Datatype dat MPIR_GPU_query_pointer_attr(inbuf_ptr, &inattr); MPIR_GPU_query_pointer_attr(outbuf, &outattr); - if (is_contig && - (inattr.type == MPL_GPU_POINTER_UNREGISTERED_HOST || - inattr.type == MPL_GPU_POINTER_REGISTERED_HOST) && - (outattr.type == MPL_GPU_POINTER_UNREGISTERED_HOST || - outattr.type == MPL_GPU_POINTER_REGISTERED_HOST)) { + if (is_contig && IS_HOST(inattr) && IS_HOST(outattr)) { *actual_pack_bytes = MPL_MIN(total_size - inoffset, max_pack_bytes); MPIR_Memcpy(outbuf, MPIR_get_contig_ptr(inbuf_ptr, inoffset), *actual_pack_bytes); goto fn_exit; @@ -270,11 +267,7 @@ static int typerep_do_unpack(const void *inbuf, MPI_Aint insize, void *outbuf, M MPIR_GPU_query_pointer_attr(inbuf, &inattr); MPIR_GPU_query_pointer_attr(outbuf_ptr, &outattr); - if (is_contig && - (inattr.type == MPL_GPU_POINTER_UNREGISTERED_HOST || - inattr.type == MPL_GPU_POINTER_REGISTERED_HOST) && - (outattr.type == MPL_GPU_POINTER_UNREGISTERED_HOST || - outattr.type == MPL_GPU_POINTER_REGISTERED_HOST)) { + if (is_contig && IS_HOST(inattr) && IS_HOST(outattr)) { *actual_unpack_bytes = MPL_MIN(total_size - outoffset, insize); MPIR_Memcpy(MPIR_get_contig_ptr(outbuf_ptr, outoffset), inbuf, *actual_unpack_bytes); goto fn_exit; From 2df7fde33796d8b09443e82f07f9b485aee775c7 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 3 Dec 2021 15:04:44 -0600 Subject: [PATCH 228/607] datatype/yaksa: ensure we never pack partial elements We need check element size and make sure we never pack partial elements in the memcpy fast path. This fixes bugs on 32-bit when packing doubles and the alignment is 4. --- .../datatype/typerep/src/typerep_yaksa_pack.c | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c b/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c index f9f65977803..cc47b1affbb 100644 --- a/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c +++ b/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c @@ -130,16 +130,19 @@ static int typerep_do_pack(const void *inbuf, MPI_Aint incount, MPI_Datatype dat MPIR_Assert(datatype != MPI_DATATYPE_NULL); int is_contig = 0; + int element_size = -1; const void *inbuf_ptr; /* adjusted by true_lb */ MPI_Aint total_size = 0; if (HANDLE_IS_BUILTIN(datatype)) { is_contig = 1; + element_size = MPIR_Datatype_get_basic_size(datatype); inbuf_ptr = inbuf; - total_size = incount * MPIR_Datatype_get_basic_size(datatype); + total_size = incount * element_size; } else { MPIR_Datatype *dtp; MPIR_Datatype_get_ptr(datatype, dtp); is_contig = dtp->is_contig; + element_size = dtp->builtin_element_size; inbuf_ptr = MPIR_get_contig_ptr(inbuf, dtp->true_lb); total_size = incount * dtp->size; } @@ -148,9 +151,12 @@ static int typerep_do_pack(const void *inbuf, MPI_Aint incount, MPI_Datatype dat MPIR_GPU_query_pointer_attr(inbuf_ptr, &inattr); MPIR_GPU_query_pointer_attr(outbuf, &outattr); - if (is_contig && IS_HOST(inattr) && IS_HOST(outattr)) { - *actual_pack_bytes = MPL_MIN(total_size - inoffset, max_pack_bytes); - MPIR_Memcpy(outbuf, MPIR_get_contig_ptr(inbuf_ptr, inoffset), *actual_pack_bytes); + if (is_contig && element_size > 0 && IS_HOST(inattr) && IS_HOST(outattr)) { + MPI_Aint real_bytes = MPL_MIN(total_size - inoffset, max_pack_bytes); + /* Make sure we never pack partial element */ + real_bytes -= real_bytes % element_size; + MPIR_Memcpy(outbuf, MPIR_get_contig_ptr(inbuf_ptr, inoffset), real_bytes); + *actual_pack_bytes = real_bytes; goto fn_exit; } @@ -249,16 +255,19 @@ static int typerep_do_unpack(const void *inbuf, MPI_Aint insize, void *outbuf, M MPIR_Assert(datatype != MPI_DATATYPE_NULL); int is_contig = 0; + int element_size = -1; const void *outbuf_ptr; /* adjusted by true_lb */ MPI_Aint total_size = 0; if (HANDLE_IS_BUILTIN(datatype)) { is_contig = 1; + element_size = MPIR_Datatype_get_basic_size(datatype); outbuf_ptr = outbuf; - total_size = outcount * MPIR_Datatype_get_basic_size(datatype); + total_size = outcount * element_size; } else { MPIR_Datatype *dtp; MPIR_Datatype_get_ptr(datatype, dtp); is_contig = dtp->is_contig; + element_size = dtp->builtin_element_size; outbuf_ptr = MPIR_get_contig_ptr(outbuf, dtp->true_lb); total_size = outcount * dtp->size; } @@ -269,6 +278,8 @@ static int typerep_do_unpack(const void *inbuf, MPI_Aint insize, void *outbuf, M if (is_contig && IS_HOST(inattr) && IS_HOST(outattr)) { *actual_unpack_bytes = MPL_MIN(total_size - outoffset, insize); + /* We assume the amount we unpack is multiple of element_size */ + MPIR_Assert(element_size < 0 || *actual_unpack_bytes % element_size == 0); MPIR_Memcpy(MPIR_get_contig_ptr(outbuf_ptr, outoffset), inbuf, *actual_unpack_bytes); goto fn_exit; } From 3cbc32e9ba285c29d2063ff8b65778597d14b1ee Mon Sep 17 00:00:00 2001 From: Atul Kulkarni Date: Mon, 17 Aug 2020 13:42:27 -0500 Subject: [PATCH 229/607] ch4/ofi: Added support to assign optimized memory regions to RMA window The optimized memory region is a region that will be used for lower overhead, unordered RMA operations. It will use the low-overhead RX path. Additionally, low-overhead packet formats may be used to target an optimized MR. In order to create an optimized memory region, MR with key values in the special range, tentatively 0-200 will be used. Optimized MRs will not support FI_MR_RMA_EVENT. The cxi libfabric provider will support at least 1500 optimized MRs per device. In order to enable these memory regions, the application will need to set the accumulate ordering to 0 as it supports unordered RMA operations. This changeset will enable the capability to assign optimized memory regions to RMA window operations if requested by the application. For all the other libfabric providers, the number of optimized memory regions is set to zero in the capability set since they do not support it. --- src/mpid/ch4/include/mpidpre.h | 1 + src/mpid/ch4/netmod/ofi/globals.c | 8 ++++++ src/mpid/ch4/netmod/ofi/init_settings.c | 2 ++ src/mpid/ch4/netmod/ofi/ofi_capability_sets.h | 15 +++++++++++ src/mpid/ch4/netmod/ofi/ofi_init.c | 15 +++++++++++ src/mpid/ch4/netmod/ofi/ofi_types.h | 6 +++++ src/mpid/ch4/netmod/ofi/ofi_win.c | 27 ++++++++++++++++++- src/mpid/ch4/src/mpidig_win.c | 13 +++++++++ 8 files changed, 86 insertions(+), 1 deletion(-) diff --git a/src/mpid/ch4/include/mpidpre.h b/src/mpid/ch4/include/mpidpre.h index 4be45d88c80..b1008be4aa7 100644 --- a/src/mpid/ch4/include/mpidpre.h +++ b/src/mpid/ch4/include/mpidpre.h @@ -388,6 +388,7 @@ typedef struct MPIDIG_win_info_args_t { * and it means the user window buffer is allocated over shared memory, * thus RMA operation can use shm routines. */ int alloc_shm; + bool optimized_mr; /* false by default. */ } MPIDIG_win_info_args_t; struct MPIDIG_win_lock { diff --git a/src/mpid/ch4/netmod/ofi/globals.c b/src/mpid/ch4/netmod/ofi/globals.c index d40ab2d52a9..5e9ff636024 100644 --- a/src/mpid/ch4/netmod/ofi/globals.c +++ b/src/mpid/ch4/netmod/ofi/globals.c @@ -38,6 +38,7 @@ MPIDI_OFI_capabilities_t MPIDI_OFI_caps_list[MPIDI_OFI_NUM_SETS] = .enable_control_auto_progress = MPIDI_OFI_ENABLE_CONTROL_AUTO_PROGRESS_DEFAULT, .enable_pt2pt_nopack = MPIDI_OFI_ENABLE_PT2PT_NOPACK_DEFAULT, .num_am_buffers = MPIDI_OFI_NUM_AM_BUFFERS_DEFAULT, + .num_optimized_memory_regions = MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS_DEFAULT, .max_endpoints = MPIDI_OFI_MAX_ENDPOINTS_DEFAULT, .max_endpoints_bits = MPIDI_OFI_MAX_ENDPOINTS_BITS_DEFAULT, .fetch_atomic_iovecs = MPIDI_OFI_FETCH_ATOMIC_IOVECS_DEFAULT, @@ -63,6 +64,7 @@ MPIDI_OFI_capabilities_t MPIDI_OFI_caps_list[MPIDI_OFI_NUM_SETS] = .enable_control_auto_progress = MPIDI_OFI_ENABLE_CONTROL_AUTO_PROGRESS_MINIMAL, .enable_pt2pt_nopack = MPIDI_OFI_ENABLE_PT2PT_NOPACK_MINIMAL, .num_am_buffers = MPIDI_OFI_NUM_AM_BUFFERS_MINIMAL, + .num_optimized_memory_regions = MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS_MINIMAL, .max_endpoints = MPIDI_OFI_MAX_ENDPOINTS_MINIMAL, .max_endpoints_bits = MPIDI_OFI_MAX_ENDPOINTS_BITS_MINIMAL, .fetch_atomic_iovecs = MPIDI_OFI_FETCH_ATOMIC_IOVECS_MINIMAL, @@ -88,6 +90,7 @@ MPIDI_OFI_capabilities_t MPIDI_OFI_caps_list[MPIDI_OFI_NUM_SETS] = .enable_control_auto_progress = MPIDI_OFI_ENABLE_CONTROL_AUTO_PROGRESS_PSM2, .enable_pt2pt_nopack = MPIDI_OFI_ENABLE_PT2PT_NOPACK_PSM2, .num_am_buffers = MPIDI_OFI_NUM_AM_BUFFERS_PSM2, + .num_optimized_memory_regions = MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS_PSM2, .max_endpoints = MPIDI_OFI_MAX_ENDPOINTS_PSM2, .max_endpoints_bits = MPIDI_OFI_MAX_ENDPOINTS_BITS_PSM2, .fetch_atomic_iovecs = MPIDI_OFI_FETCH_ATOMIC_IOVECS_PSM2, @@ -113,6 +116,7 @@ MPIDI_OFI_capabilities_t MPIDI_OFI_caps_list[MPIDI_OFI_NUM_SETS] = .enable_control_auto_progress = MPIDI_OFI_ENABLE_CONTROL_AUTO_PROGRESS_SOCKETS, .enable_pt2pt_nopack = MPIDI_OFI_ENABLE_PT2PT_NOPACK_SOCKETS, .num_am_buffers = MPIDI_OFI_NUM_AM_BUFFERS_SOCKETS, + .num_optimized_memory_regions = MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS_SOCKETS, .max_endpoints = MPIDI_OFI_MAX_ENDPOINTS_SOCKETS, .max_endpoints_bits = MPIDI_OFI_MAX_ENDPOINTS_BITS_SOCKETS, .fetch_atomic_iovecs = MPIDI_OFI_FETCH_ATOMIC_IOVECS_SOCKETS, @@ -138,6 +142,7 @@ MPIDI_OFI_capabilities_t MPIDI_OFI_caps_list[MPIDI_OFI_NUM_SETS] = .enable_control_auto_progress = MPIDI_OFI_ENABLE_CONTROL_AUTO_PROGRESS_BGQ, .enable_pt2pt_nopack = MPIDI_OFI_ENABLE_PT2PT_NOPACK_BGQ, .num_am_buffers = MPIDI_OFI_NUM_AM_BUFFERS_BGQ, + .num_optimized_memory_regions = MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS_BGQ, .max_endpoints = MPIDI_OFI_MAX_ENDPOINTS_BGQ, .max_endpoints_bits = MPIDI_OFI_MAX_ENDPOINTS_BITS_BGQ, .fetch_atomic_iovecs = MPIDI_OFI_FETCH_ATOMIC_IOVECS_BGQ, @@ -163,6 +168,7 @@ MPIDI_OFI_capabilities_t MPIDI_OFI_caps_list[MPIDI_OFI_NUM_SETS] = .enable_control_auto_progress = MPIDI_OFI_ENABLE_CONTROL_AUTO_PROGRESS_CXI, .enable_pt2pt_nopack = MPIDI_OFI_ENABLE_PT2PT_NOPACK_CXI, .num_am_buffers = MPIDI_OFI_NUM_AM_BUFFERS_CXI, + .num_optimized_memory_regions = MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS_CXI, .max_endpoints = MPIDI_OFI_MAX_ENDPOINTS_CXI, .max_endpoints_bits = MPIDI_OFI_MAX_ENDPOINTS_BITS_CXI, .fetch_atomic_iovecs = MPIDI_OFI_FETCH_ATOMIC_IOVECS_CXI, @@ -188,6 +194,7 @@ MPIDI_OFI_capabilities_t MPIDI_OFI_caps_list[MPIDI_OFI_NUM_SETS] = .enable_control_auto_progress = MPIDI_OFI_ENABLE_CONTROL_AUTO_PROGRESS_VERBS_RXM, .enable_pt2pt_nopack = MPIDI_OFI_ENABLE_PT2PT_NOPACK_VERBS_RXM, .num_am_buffers = MPIDI_OFI_NUM_AM_BUFFERS_VERBS_RXM, + .num_optimized_memory_regions = MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS_VERBS_RXM, .max_endpoints = MPIDI_OFI_MAX_ENDPOINTS_VERBS_RXM, .max_endpoints_bits = MPIDI_OFI_MAX_ENDPOINTS_BITS_VERBS_RXM, .fetch_atomic_iovecs = MPIDI_OFI_FETCH_ATOMIC_IOVECS_VERBS_RXM, @@ -213,6 +220,7 @@ MPIDI_OFI_capabilities_t MPIDI_OFI_caps_list[MPIDI_OFI_NUM_SETS] = .enable_control_auto_progress = MPIDI_OFI_ENABLE_CONTROL_AUTO_PROGRESS_RXM, .enable_pt2pt_nopack = MPIDI_OFI_ENABLE_PT2PT_NOPACK_RXM, .num_am_buffers = MPIDI_OFI_NUM_AM_BUFFERS_RXM, + .num_optimized_memory_regions = MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS_RXM, .max_endpoints = MPIDI_OFI_MAX_ENDPOINTS_RXM, .max_endpoints_bits = MPIDI_OFI_MAX_ENDPOINTS_BITS_RXM, .fetch_atomic_iovecs = MPIDI_OFI_FETCH_ATOMIC_IOVECS_RXM, diff --git a/src/mpid/ch4/netmod/ofi/init_settings.c b/src/mpid/ch4/netmod/ofi/init_settings.c index 0b25dacf00c..a9899d26754 100644 --- a/src/mpid/ch4/netmod/ofi/init_settings.c +++ b/src/mpid/ch4/netmod/ofi/init_settings.c @@ -260,6 +260,8 @@ void MPIDI_OFI_init_settings(MPIDI_OFI_capabilities_t * p_settings, const char * /* Always required settings */ MPIDI_OFI_global.settings.require_rdm = 1; + UPDATE_SETTING_BY_CAP(num_optimized_memory_regions, + MPIR_CVAR_CH4_OFI_NUM_OPTIMIZED_MEMORY_REGIONS); } #define CHECK_CAP(setting, cond_bad) \ diff --git a/src/mpid/ch4/netmod/ofi/ofi_capability_sets.h b/src/mpid/ch4/netmod/ofi/ofi_capability_sets.h index 9e623a64ad8..f1b41bd9f01 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_capability_sets.h +++ b/src/mpid/ch4/netmod/ofi/ofi_capability_sets.h @@ -129,6 +129,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_ENABLE_PT2PT_NOPACK_PSM2 MPIDI_OFI_ON #define MPIDI_OFI_ENABLE_HMEM_PSM2 MPIDI_OFI_OFF #define MPIDI_OFI_NUM_AM_BUFFERS_PSM2 MPIDI_OFI_MAX_NUM_AM_BUFFERS +#define MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS_PSM2 (0) #define MPIDI_OFI_CONTEXT_BITS_PSM2 (20) #define MPIDI_OFI_SOURCE_BITS_PSM2 (0) #define MPIDI_OFI_TAG_BITS_PSM2 (31) @@ -156,6 +157,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_ENABLE_PT2PT_NOPACK MPIDI_OFI_ENABLE_PT2PT_NOPACK_PSM2 #define MPIDI_OFI_ENABLE_HMEM MPIDI_OFI_ENABLE_HMEM_PSM2 #define MPIDI_OFI_NUM_AM_BUFFERS MPIDI_OFI_NUM_AM_BUFFERS_PSM2 +#define MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS_PSM2 #define MPIDI_OFI_PROTOCOL_MASK (0x00E0000000000000ULL) #define MPIDI_OFI_CONTEXT_MASK (0x000FFFFF00000000ULL) #define MPIDI_OFI_SOURCE_MASK (0x0000000000000000ULL) /* PSM2 does support immediate data @@ -192,6 +194,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_ENABLE_PT2PT_NOPACK_SOCKETS MPIDI_OFI_ON #define MPIDI_OFI_ENABLE_HMEM_SOCKETS MPIDI_OFI_OFF #define MPIDI_OFI_NUM_AM_BUFFERS_SOCKETS MPIDI_OFI_MAX_NUM_AM_BUFFERS +#define MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS_SOCKETS (0) #define MPIDI_OFI_CONTEXT_BITS_SOCKETS (20) #define MPIDI_OFI_SOURCE_BITS_SOCKETS (0) #define MPIDI_OFI_TAG_BITS_SOCKETS (31) @@ -219,6 +222,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_ENABLE_PT2PT_NOPACK MPIDI_OFI_ENABLE_PT2PT_NOPACK_SOCKETS #define MPIDI_OFI_ENABLE_HMEM MPIDI_OFI_ENABLE_HMEM_SOCKETS #define MPIDI_OFI_NUM_AM_BUFFERS MPIDI_OFI_NUM_AM_BUFFERS_SOCKETS +#define MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS_SOCKETS #define MPIDI_OFI_PROTOCOL_MASK (0x00E0000000000000ULL) #define MPIDI_OFI_CONTEXT_MASK (0x000FFFFF00000000ULL) #define MPIDI_OFI_SOURCE_MASK (0x0000000000000000ULL) /* Sockets does support immediate data @@ -255,6 +259,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_ENABLE_PT2PT_NOPACK_BGQ MPIDI_OFI_OFF #define MPIDI_OFI_ENABLE_HMEM_BGQ MPIDI_OFI_OFF #define MPIDI_OFI_NUM_AM_BUFFERS_BGQ MPIDI_OFI_MAX_NUM_AM_BUFFERS +#define MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS_BGQ (0) #define MPIDI_OFI_CONTEXT_BITS_BGQ (20) #define MPIDI_OFI_SOURCE_BITS_BGQ (0) #define MPIDI_OFI_TAG_BITS_BGQ (31) @@ -282,6 +287,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_ENABLE_PT2PT_NOPACK MPIDI_OFI_ENABLE_PT2PT_NOPACK_BGQ #define MPIDI_OFI_ENABLE_HMEM MPIDI_OFI_ENABLE_HMEM_BGQ #define MPIDI_OFI_NUM_AM_BUFFERS MPIDI_OFI_NUM_AM_BUFFERS_BGQ +#define MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS_BGQ #define MPIDI_OFI_PROTOCOL_MASK (0x00E0000000000000ULL) #define MPIDI_OFI_CONTEXT_MASK (0x000FFFFF00000000ULL) #define MPIDI_OFI_SOURCE_MASK (0x0000000000000000ULL) /* BGQ does support immediate data @@ -319,6 +325,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_ENABLE_PT2PT_NOPACK_CXI MPIDI_OFI_ON #define MPIDI_OFI_ENABLE_HMEM_CXI MPIDI_OFI_OFF #define MPIDI_OFI_NUM_AM_BUFFERS_CXI MPIDI_OFI_MAX_NUM_AM_BUFFERS +#define MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS_CXI (0) /* This will be added to the CXI provider as + * RMA support is fixed. */ #define MPIDI_OFI_CONTEXT_BITS_CXI (20) #define MPIDI_OFI_SOURCE_BITS_CXI (0) #define MPIDI_OFI_TAG_BITS_CXI (20) /* The CXI provider has a smaller tag space @@ -393,6 +401,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_ENABLE_PT2PT_NOPACK_RXM MPIDI_OFI_ON #define MPIDI_OFI_ENABLE_HMEM_RXM MPIDI_OFI_OFF #define MPIDI_OFI_NUM_AM_BUFFERS_RXM MPIDI_OFI_MAX_NUM_AM_BUFFERS +#define MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS_RXM (0) #define MPIDI_OFI_CONTEXT_BITS_RXM (20) #define MPIDI_OFI_SOURCE_BITS_RXM (0) #define MPIDI_OFI_TAG_BITS_RXM (31) @@ -419,6 +428,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_ENABLE_PT2PT_NOPACK MPIDI_OFI_ENABLE_PT2PT_NOPACK_RXM #define MPIDI_OFI_ENABLE_HMEM MPIDI_OFI_ENABLE_HMEM_RXM #define MPIDI_OFI_NUM_AM_BUFFERS MPIDI_OFI_NUM_AM_BUFFERS_RXM +#define MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS_RXM #define MPIDI_OFI_PROTOCOL_MASK (0x00E0000000000000ULL) #define MPIDI_OFI_CONTEXT_MASK (0x000FFFFF00000000ULL) #define MPIDI_OFI_SOURCE_MASK (0x0000000000000000ULL) /* RxM does support immediate data @@ -455,6 +465,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_ENABLE_PT2PT_NOPACK_VERBS_RXM MPIDI_OFI_ON #define MPIDI_OFI_ENABLE_HMEM_VERBS_RXM MPIDI_OFI_OFF #define MPIDI_OFI_NUM_AM_BUFFERS_VERBS_RXM MPIDI_OFI_MAX_NUM_AM_BUFFERS +#define MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS_VERBS_RXM (0) #define MPIDI_OFI_CONTEXT_BITS_VERBS_RXM (20) #define MPIDI_OFI_SOURCE_BITS_VERBS_RXM (0) #define MPIDI_OFI_TAG_BITS_VERBS_RXM (31) @@ -483,6 +494,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_ENABLE_PT2PT_NOPACK MPIDI_OFI_ENABLE_PT2PT_NOPACK_VERBS_RXM #define MPIDI_OFI_ENABLE_HMEM MPIDI_OFI_ENABLE_HMEM_VERBS_RXM #define MPIDI_OFI_NUM_AM_BUFFERS MPIDI_OFI_NUM_AM_BUFFERS_VERBS_RXM +#define MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS_VERBS_RXM #define MPIDI_OFI_PROTOCOL_MASK (0x00E0000000000000ULL) #define MPIDI_OFI_CONTEXT_MASK (0x000FFFF000000000ULL) #define MPIDI_OFI_SOURCE_MASK (0x0000000000000000ULL) /* verbs;ofi_rxm does support immediate data @@ -585,6 +597,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_ENABLE_PT2PT_NOPACK_DEFAULT MPIDI_OFI_ON #define MPIDI_OFI_ENABLE_HMEM_DEFAULT MPIDI_OFI_OFF #define MPIDI_OFI_NUM_AM_BUFFERS_DEFAULT MPIDI_OFI_MAX_NUM_AM_BUFFERS +#define MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS_DEFAULT 0 #define MPIDI_OFI_PROTOCOL_MASK_DEFAULT (0x00E0000000000000ULL) #define MPIDI_OFI_CONTEXT_MASK_DEFAULT (0x000FFFFF00000000ULL) #define MPIDI_OFI_SOURCE_MASK_DEFAULT (0x0000000000000000ULL) /* We require support for immediate data @@ -620,6 +633,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_ENABLE_PT2PT_NOPACK_MINIMAL MPIDI_OFI_ON #define MPIDI_OFI_ENABLE_HMEM_MINIMAL MPIDI_OFI_OFF #define MPIDI_OFI_NUM_AM_BUFFERS_MINIMAL MPIDI_OFI_MAX_NUM_AM_BUFFERS +#define MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS_MINIMAL 0 #define MPIDI_OFI_PROTOCOL_MASK_MINIMAL (0xE000000000000000ULL) /* This will be a problem for providers that require all 64 match bits. */ #define MPIDI_OFI_CONTEXT_MASK_MINIMAL (0x0FFFF00000000000ULL) #define MPIDI_OFI_SOURCE_MASK_MINIMAL (0x00000FFFFFF00000ULL) /* assume that provider does not support immediate data @@ -658,6 +672,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_ENABLE_PT2PT_NOPACK MPIDI_OFI_global.settings.enable_pt2pt_nopack #define MPIDI_OFI_ENABLE_HMEM MPIDI_OFI_global.settings.enable_hmem #define MPIDI_OFI_NUM_AM_BUFFERS MPIDI_OFI_global.settings.num_am_buffers +#define MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS MPIDI_OFI_global.settings.num_optimized_memory_regions #define MPIDI_OFI_CONTEXT_BITS MPIDI_OFI_global.settings.context_bits #define MPIDI_OFI_SOURCE_BITS MPIDI_OFI_global.settings.source_bits #define MPIDI_OFI_TAG_BITS MPIDI_OFI_global.settings.tag_bits diff --git a/src/mpid/ch4/netmod/ofi/ofi_init.c b/src/mpid/ch4/netmod/ofi/ofi_init.c index 9612dcc4e1c..3c4e235502d 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_init.c +++ b/src/mpid/ch4/netmod/ofi/ofi_init.c @@ -290,6 +290,19 @@ categories : description : >- Specifies the number of buffers for receiving active messages. + - name : MPIR_CVAR_CH4_OFI_NUM_OPTIMIZED_MEMORY_REGIONS + category : CH4_OFI + type : int + default : 0 + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_LOCAL + description : >- + Specifies the number of optimized memory regions supported by the provider. An optimized + memory region is used for lower-overhead, unordered RMA operations. It uses a low-overhead + RX path and additionally, a low-overhead packet format may be used to target an optimized + memory region. + - name : MPIR_CVAR_CH4_OFI_RMA_PROGRESS_INTERVAL category : CH4_OFI type : int @@ -1448,6 +1461,8 @@ static void dump_global_settings(void) fprintf(stdout, "MPIDI_OFI_ENABLE_PT2PT_NOPACK: %d\n", MPIDI_OFI_ENABLE_PT2PT_NOPACK); fprintf(stdout, "MPIDI_OFI_ENABLE_HMEM: %d\n", MPIDI_OFI_ENABLE_HMEM); fprintf(stdout, "MPIDI_OFI_NUM_AM_BUFFERS: %d\n", MPIDI_OFI_NUM_AM_BUFFERS); + fprintf(stdout, "MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS: %d\n", + MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS); fprintf(stdout, "MPIDI_OFI_CONTEXT_BITS: %d\n", MPIDI_OFI_CONTEXT_BITS); fprintf(stdout, "MPIDI_OFI_SOURCE_BITS: %d\n", MPIDI_OFI_SOURCE_BITS); fprintf(stdout, "MPIDI_OFI_TAG_BITS: %d\n", MPIDI_OFI_TAG_BITS); diff --git a/src/mpid/ch4/netmod/ofi/ofi_types.h b/src/mpid/ch4/netmod/ofi/ofi_types.h index a871ac441f0..4c06274cdf7 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_types.h +++ b/src/mpid/ch4/netmod/ofi/ofi_types.h @@ -312,6 +312,7 @@ typedef struct { int major_version; int minor_version; int num_am_buffers; + int num_optimized_memory_regions; } MPIDI_OFI_capabilities_t; typedef struct { @@ -371,6 +372,11 @@ typedef struct { * OFI provider at MPI initialization.*/ MPIDI_OFI_atomic_valid_t win_op_table[MPIR_DATATYPE_N_PREDEFINED][MPIDIG_ACCU_NUM_OP]; + /* stores the maximum of last recently used optimized memory region key */ + uint64_t global_max_optimized_mr_key; + /* stores the maximum of last recently used regular memory region key */ + uint64_t global_max_regular_mr_key; + /* Process management and PMI globals */ int pname_set; int pname_len; diff --git a/src/mpid/ch4/netmod/ofi/ofi_win.c b/src/mpid/ch4/netmod/ofi/ofi_win.c index b831017188d..61b1b3afad1 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_win.c +++ b/src/mpid/ch4/netmod/ofi/ofi_win.c @@ -121,6 +121,7 @@ static int win_allgather(MPIR_Win * win, void *base, int disp_unit) { int i, same_disp, mpi_errno = MPI_SUCCESS; uint32_t first; + uint64_t local_key = 0; MPIR_Errflag_t errflag = MPIR_ERR_NONE; MPIR_Comm *comm_ptr = win->comm_ptr; MPIDI_OFI_win_targetinfo_t *winfo; @@ -129,8 +130,32 @@ static int win_allgather(MPIR_Win * win, void *base, int disp_unit) MPIR_FUNC_ENTER; if (!MPIDI_OFI_ENABLE_MR_PROV_KEY) { - MPIDI_OFI_WIN(win).mr_key = MPIDI_OFI_WIN(win).win_id; + if (MPIDIG_WIN(win, info_args).optimized_mr && + MPIDIG_WIN(win, info_args).accumulate_ordering == 0) { + /* accumulate_ordering must be set to zero to support creation of optimized + * memory region for use with lower-overhead, unordered RMA operations. + * Attempting to create an optimized memory region key. Gets the next MR key that's + * available to the processes involved in the RMA window. Use the current maximum + 1 + * to ensure that the key is available for all processes. */ + mpi_errno = MPIR_Allreduce(&MPIDI_OFI_global.global_max_optimized_mr_key, &local_key, 1, + MPI_UNSIGNED, MPI_MAX, comm_ptr, &errflag); + MPIR_ERR_CHECK(mpi_errno); + + if (local_key + 1 < MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS) { + MPIDI_OFI_global.global_max_optimized_mr_key = local_key + 1; + MPIDI_OFI_WIN(win).mr_key = local_key; + } + } + /* Assign regular memory registration key if the optimized one is + * not requested or exhausted */ + if (local_key + 1 >= MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS || + !MPIDIG_WIN(win, info_args).optimized_mr) { + /* Makes sure that regular mr key does not fall within optimized mr key range */ + MPIDI_OFI_WIN(win).mr_key = + MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS + MPIDI_OFI_WIN(win).win_id; + } } else { + /* Expect provider to assign the key */ MPIDI_OFI_WIN(win).mr_key = 0; } diff --git a/src/mpid/ch4/src/mpidig_win.c b/src/mpid/ch4/src/mpidig_win.c index cb21c1e1d09..71be6925307 100644 --- a/src/mpid/ch4/src/mpidig_win.c +++ b/src/mpid/ch4/src/mpidig_win.c @@ -217,6 +217,11 @@ static int win_set_info(MPIR_Win * win, MPIR_Info * info, bool is_init) MPIDIG_WIN(win, info_args).alloc_shm = 1; else if (!strcmp(curr_ptr->value, "false")) MPIDIG_WIN(win, info_args).alloc_shm = 0; + } else if (!strcmp(curr_ptr->key, "optimized_mr")) { + if (!strcmp(curr_ptr->value, "true")) + MPIDIG_WIN(win, info_args).optimized_mr = true; + else + MPIDIG_WIN(win, info_args).optimized_mr = false; } /* We allow the user to set the following atomics hint only at window init time, * all future updates by win_set_info are ignored. This is because we do not @@ -332,6 +337,7 @@ static int win_init(MPI_Aint length, int disp_unit, MPIR_Win ** win_ptr, MPIR_In MPIDIG_WIN(win, info_args).accumulate_max_bytes = -1; MPIDIG_WIN(win, info_args).disable_shm_accumulate = false; MPIDIG_WIN(win, info_args).coll_attach = false; + MPIDIG_WIN(win, info_args).optimized_mr = false; if ((info != NULL) && ((int *) info != (int *) MPI_INFO_NULL)) { mpi_errno = win_set_info(win, info, TRUE /* is_init */); @@ -817,6 +823,13 @@ int MPIDIG_mpi_win_get_info(MPIR_Win * win, MPIR_Info ** info_p_p) MPIR_ERR_CHECK(mpi_errno); } + if (MPIDIG_WIN(win, info_args).optimized_mr) { + mpi_errno = MPIR_Info_set_impl(*info_p_p, "optimized_mr", "true"); + } else { + mpi_errno = MPIR_Info_set_impl(*info_p_p, "optimized_mr", "false"); + } + MPIR_ERR_CHECK(mpi_errno); + fn_exit: MPIR_FUNC_EXIT; return mpi_errno; From 6f25672cfd3f34945848493bf0a4274abe2e1588 Mon Sep 17 00:00:00 2001 From: Atul Kulkarni Date: Fri, 25 Sep 2020 13:05:40 -0500 Subject: [PATCH 230/607] test: Modified test to cover newly added optimized_mr info hint --- test/mpi/rma/win_info.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/test/mpi/rma/win_info.c b/test/mpi/rma/win_info.c index b4cf3df1ab0..10c52ea391b 100644 --- a/test/mpi/rma/win_info.c +++ b/test/mpi/rma/win_info.c @@ -141,12 +141,19 @@ int main(int argc, char **argv) win_info_set(win, "same_disp_unit", "true"); errors += check_win_info_get(win, "same_disp_unit", "true"); + /* Test#8: setting "optimized_mr" (no default value) */ + win_info_set(win, "optimized_mr", "false"); + errors += check_win_info_get(win, "optimized_mr", "false"); + + win_info_set(win, "optimized_mr", "true"); + errors += check_win_info_get(win, "optimized_mr", "true"); + /* TODO: check alloc_shm as implementation-specific test */ - /* Test#8: setting "alloc_shared_noncontig" (no default value) in shared window. */ + /* Test#9: setting "alloc_shared_noncontig" (no default value) in shared window. */ MPI_Win_free(&win); - /* #8.1: setting at window allocation */ + /* #9.1: setting at window allocation */ MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, rank, MPI_INFO_NULL, &shm_comm); MPI_Info_create(&info_in); @@ -155,7 +162,7 @@ int main(int argc, char **argv) errors += check_win_info_get(win, "alloc_shared_noncontig", "true"); MPI_Info_free(&info_in); - /* #8.2: setting info */ + /* #9.2: setting info */ win_info_set(win, "alloc_shared_noncontig", "false"); errors += check_win_info_get(win, "alloc_shared_noncontig", "false"); MPI_Comm_free(&shm_comm); From aeb05f70f99ec3405543f14fc43cf8ace1c8da87 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 7 Dec 2021 12:28:48 -0600 Subject: [PATCH 231/607] test/config: Output result after checking for MPICH derivatives --- test/mpi/configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index 31ddc7a88ef..f8b5d61c5ba 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -430,6 +430,7 @@ MPI_IS_MPICH=no AC_MSG_CHECKING([Is the MPI derived from MPICH]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include "mpi.h"],[return 1 + MPICH;])], [MPI_IS_MPICH=yes],[MPI_IS_MPICH=no]) +AC_MSG_RESULT($MPI_IS_MPICH) # First, determine whether we are/can support the language bindings # From 2e00ddd9ae938d931898ed4f5c2598eb238ce908 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 7 Dec 2021 12:37:27 -0600 Subject: [PATCH 232/607] test/config: Export CC before configuring dtpools This export was wrongly removed in [e32f4301]. It is still needed to build dtpools correctly. --- test/mpi/configure.ac | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index f8b5d61c5ba..7c9df2b0052 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -404,6 +404,9 @@ else fi fi +# Make sure we export CC before configuring DTPools, since MPI is +# needed to build the library. +export CC PAC_CONFIG_SUBDIR_ARGS([dtpools]) # Running C compiler tests From 2196fde4af10f29ec11331ce44325528a529124b Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 15 Dec 2021 12:32:19 -0600 Subject: [PATCH 233/607] Revert "test: Modified test to cover newly added optimized_mr info hint" This reverts commit 6f25672cfd3f34945848493bf0a4274abe2e1588. The test does not account that only specific provider support optimized_mr info hint. For the minimum, we need separate specific info hint into separate tests so that we can individually xfail them. --- test/mpi/rma/win_info.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/test/mpi/rma/win_info.c b/test/mpi/rma/win_info.c index 10c52ea391b..b4cf3df1ab0 100644 --- a/test/mpi/rma/win_info.c +++ b/test/mpi/rma/win_info.c @@ -141,19 +141,12 @@ int main(int argc, char **argv) win_info_set(win, "same_disp_unit", "true"); errors += check_win_info_get(win, "same_disp_unit", "true"); - /* Test#8: setting "optimized_mr" (no default value) */ - win_info_set(win, "optimized_mr", "false"); - errors += check_win_info_get(win, "optimized_mr", "false"); - - win_info_set(win, "optimized_mr", "true"); - errors += check_win_info_get(win, "optimized_mr", "true"); - /* TODO: check alloc_shm as implementation-specific test */ - /* Test#9: setting "alloc_shared_noncontig" (no default value) in shared window. */ + /* Test#8: setting "alloc_shared_noncontig" (no default value) in shared window. */ MPI_Win_free(&win); - /* #9.1: setting at window allocation */ + /* #8.1: setting at window allocation */ MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, rank, MPI_INFO_NULL, &shm_comm); MPI_Info_create(&info_in); @@ -162,7 +155,7 @@ int main(int argc, char **argv) errors += check_win_info_get(win, "alloc_shared_noncontig", "true"); MPI_Info_free(&info_in); - /* #9.2: setting info */ + /* #8.2: setting info */ win_info_set(win, "alloc_shared_noncontig", "false"); errors += check_win_info_get(win, "alloc_shared_noncontig", "false"); MPI_Comm_free(&shm_comm); From 96ee73a8fcd505bbe11dcf347669bc7266f16a96 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 15 Dec 2021 12:42:30 -0600 Subject: [PATCH 234/607] test: move rma/win_info to impls/mpich/rma The test on info hints are implementation dependent since the standard does not require all implementations to support any particular hint. --- test/mpi/impls/mpich/rma/Makefile.am | 19 +++++++++++++++++++ test/mpi/impls/mpich/rma/testlist | 1 + test/mpi/{ => impls/mpich}/rma/win_info.c | 0 test/mpi/rma/Makefile.am | 1 - test/mpi/rma/testlist.in | 1 - 5 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 test/mpi/impls/mpich/rma/Makefile.am create mode 100644 test/mpi/impls/mpich/rma/testlist rename test/mpi/{ => impls/mpich}/rma/win_info.c (100%) diff --git a/test/mpi/impls/mpich/rma/Makefile.am b/test/mpi/impls/mpich/rma/Makefile.am new file mode 100644 index 00000000000..aa8709620cd --- /dev/null +++ b/test/mpi/impls/mpich/rma/Makefile.am @@ -0,0 +1,19 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +include $(top_srcdir)/Makefile_single.mtest + +EXTRA_DIST = testlist.in + +AM_DEFAULT_SOURCE_EXT = .c + +## for all programs that are just built from the single corresponding source +## file, we don't need per-target _SOURCES rules, automake will infer them +## correctly +noinst_PROGRAMS = \ + win_info + +# Copied from cxx/rma/Makefile.am +#BINDIR=${bindir} diff --git a/test/mpi/impls/mpich/rma/testlist b/test/mpi/impls/mpich/rma/testlist new file mode 100644 index 00000000000..36e5c3e9880 --- /dev/null +++ b/test/mpi/impls/mpich/rma/testlist @@ -0,0 +1 @@ +win_info 4 diff --git a/test/mpi/rma/win_info.c b/test/mpi/impls/mpich/rma/win_info.c similarity index 100% rename from test/mpi/rma/win_info.c rename to test/mpi/impls/mpich/rma/win_info.c diff --git a/test/mpi/rma/Makefile.am b/test/mpi/rma/Makefile.am index 6b5813f135f..4482c8f4ee9 100644 --- a/test/mpi/rma/Makefile.am +++ b/test/mpi/rma/Makefile.am @@ -136,7 +136,6 @@ noinst_PROGRAMS = \ reqops \ req_example \ req_example_shm \ - win_info \ pscw_ordering \ pscw_ordering_shm \ mutex_bench \ diff --git a/test/mpi/rma/testlist.in b/test/mpi/rma/testlist.in index f87da3b6ac5..6498369a094 100644 --- a/test/mpi/rma/testlist.in +++ b/test/mpi/rma/testlist.in @@ -119,7 +119,6 @@ req_example 4 req_example_shm 4 rput_local_comp 2 racc_local_comp 2 -win_info 4 linked_list_lockall 4 pscw_ordering 4 pscw_ordering_shm 4 From e31a4c3c0ec7827ff7ffafb53a9980ea8cb60865 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Mon, 20 Dec 2021 15:01:52 -0600 Subject: [PATCH 235/607] mtest: Remove extra lock/unlock in thread barrier Unlocking and relocking here makes no sense. Just hold the lock until all work is done. --- test/mpi/util/mtest_thread.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/test/mpi/util/mtest_thread.c b/test/mpi/util/mtest_thread.c index 6b11bd25fdf..dc1f3e1b5b7 100644 --- a/test/mpi/util/mtest_thread.c +++ b/test/mpi/util/mtest_thread.c @@ -99,18 +99,9 @@ int MTest_thread_barrier(int nt) return err; } cntP = &c[phase]; - err = MTest_thread_unlock(&barrierLock); - if (err) { - fprintf(stderr, "Unlock failed in barrier!\n"); - return err; - } /* printf("[%d] cnt = %d, phase = %d\n", pthread_self(), *cntP, phase); */ - err = MTest_thread_lock(&barrierLock); - if (err) { - fprintf(stderr, "Lock failed in barrier!\n"); - return err; - } + /* The first thread to enter will reset the counter */ if (*cntP < 0) *cntP = nt; From 0b01babfee86c522953af3f7a8fb57c0eaf78523 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Mon, 20 Dec 2021 15:03:42 -0600 Subject: [PATCH 236/607] mtest: Add lock error check macro --- test/mpi/util/mtest_thread.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/mpi/util/mtest_thread.c b/test/mpi/util/mtest_thread.c index dc1f3e1b5b7..08e561c15b6 100644 --- a/test/mpi/util/mtest_thread.c +++ b/test/mpi/util/mtest_thread.c @@ -82,6 +82,12 @@ int MTest_thread_barrier_free(void) return MTest_thread_lock_free(&barrierLock); } +#define LOCK_ERR_CHECK(err_) \ + if (err_) { \ + fprintf(stderr, "Lock failed in barrier!\n"); \ + return err_; \ + } + /* This is a generic barrier implementation. To ensure that tests don't silently fail, this both prints an error message and returns an error result on any failure. */ @@ -94,10 +100,7 @@ int MTest_thread_barrier(int nt) nt = nthreads; /* Force a write barrier by using lock/unlock */ err = MTest_thread_lock(&barrierLock); - if (err) { - fprintf(stderr, "Lock failed in barrier!\n"); - return err; - } + LOCK_ERR_CHECK(err); cntP = &c[phase]; /* printf("[%d] cnt = %d, phase = %d\n", pthread_self(), *cntP, phase); */ @@ -116,10 +119,7 @@ int MTest_thread_barrier(int nt) /* Really need a write barrier here */ *cntP = *cntP - 1; err = MTest_thread_unlock(&barrierLock); - if (err) { - fprintf(stderr, "Unlock failed in barrier!\n"); - return err; - } + LOCK_ERR_CHECK(err); while (*cntP > 0); return err; From d9d3f94fdc8ab8df49d179f27ed74591896ac84d Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Mon, 20 Dec 2021 15:05:18 -0600 Subject: [PATCH 237/607] mtest: Fix data race in thread barrier Read the global barrier counter under lock, otherwise we might get a corrupt value. --- test/mpi/util/mtest_thread.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/test/mpi/util/mtest_thread.c b/test/mpi/util/mtest_thread.c index 08e561c15b6..6e1c21b5204 100644 --- a/test/mpi/util/mtest_thread.c +++ b/test/mpi/util/mtest_thread.c @@ -95,6 +95,7 @@ int MTest_thread_barrier(int nt) { volatile int *cntP; int err = 0; + int num_left; if (nt < 0) nt = nthreads; @@ -118,9 +119,23 @@ int MTest_thread_barrier(int nt) } /* Really need a write barrier here */ *cntP = *cntP - 1; + num_left = *cntP; err = MTest_thread_unlock(&barrierLock); LOCK_ERR_CHECK(err); - while (*cntP > 0); + + /* wait for other threads */ + while (num_left > 0) { + err = MTest_thread_lock(&barrierLock); + LOCK_ERR_CHECK(err); + + /* TODO: This would be improved with atomic ops instead of using + * a mutex. Integrating MPL for portable atomics would be an + * improvement. */ + num_left = *cntP; + + err = MTest_thread_unlock(&barrierLock); + LOCK_ERR_CHECK(err); + } return err; } From 6cff62e0ab3bcc8eca8432c0c78c098accd83ba9 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 19 Dec 2021 23:13:09 -0600 Subject: [PATCH 238/607] configure: reset flags before configure hydra etc This avoids pass CPPFLAGS with embedded hwloc path to hydra. Otherwise, on systems with outdated external hwloc, it may result in hydra to be build with embedded headers but linked to external hwloc. --- configure.ac | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configure.ac b/configure.ac index 779a1a218eb..ba432427b9d 100644 --- a/configure.ac +++ b/configure.ac @@ -3874,9 +3874,12 @@ m4_map([PAC_SUBCFG_CONFIGURE_SUBSYS], [PAC_SUBCFG_MODULE_LIST]) # now configure any actual recursively configures subsystems, such as ROMIO and # hydra, or older components that haven't been updated to a subconfigure.m4 yet +PAC_PUSH_ALL_FLAGS() +PAC_RESET_ALL_FLAGS() for subsys in $devsubsystems $subsystems ; do PAC_CONFIG_SUBDIR([$subsys],[],[AC_MSG_ERROR([$subsys configure failed])]) done +PAC_POP_ALL_FLAGS() if test "$DEBUG_SUBDIR_CACHE" = yes -a "$enable_echo" != yes ; then set +x fi From acb15e55098f2c7baaf2955eb00fb205af6d482e Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 20 Dec 2021 08:16:05 -0600 Subject: [PATCH 239/607] romio: config mpl when FROM_MPICH is yes It was skipped and relying on MPICH pass down the CPPFLAGS. Now that we sanitize all flags, we need set the mpl include path again for romio. --- src/mpi/romio/configure.ac | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mpi/romio/configure.ac b/src/mpi/romio/configure.ac index 0ada7a86441..2e81f43387f 100644 --- a/src/mpi/romio/configure.ac +++ b/src/mpi/romio/configure.ac @@ -147,6 +147,9 @@ else mpl_libdir="-L${with_mpl_prefix}/lib" mpl_lib="-l${MPLLIBNAME}" fi +else + # we are configuring romio inside mpich, just set mpl_includedir + mpl_includedir="-I$main_top_builddir/src/mpl/include -I$main_top_srcdir/src/mpl/include" fi CFLAGS=${CFLAGS:-""} From bc5d9fc88b9204945ec0d3ce1c731fe0ea59ffef Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 20 Dec 2021 08:42:26 -0600 Subject: [PATCH 240/607] confdb: fix mpl_includedir We need use double quotes because `main_top_builddir` is not a autoconf variable. --- confdb/aclocal_modules.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/confdb/aclocal_modules.m4 b/confdb/aclocal_modules.m4 index 51a92106721..acae7a09453 100644 --- a/confdb/aclocal_modules.m4 +++ b/confdb/aclocal_modules.m4 @@ -24,7 +24,7 @@ AC_DEFUN([PAC_CONFIG_MPL],[ dnl ---- sub-configure (e.g. hydra, romio) ---- if test "$FROM_MPICH" = "yes"; then mpl_lib="$main_top_builddir/src/mpl/libmpl.la" - mpl_includedir='-I$(main_top_builddir)/src/mpl/include -I$(main_top_srcdir)/src/mpl/include' + mpl_includedir="-I$main_top_builddir/src/mpl/include -I$main_top_srcdir/src/mpl/include" else PAC_CONFIG_MPL_EMBEDDED mpl_srcdir="mpl_embedded_dir" From 72cb7552a79be62fef961fbb131294c62539dfb0 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 26 May 2021 19:53:34 -0500 Subject: [PATCH 241/607] test: make coll/allred.c compile faster This PR rewrites the macros in coll/allred.c into functions, thus significantly shortens the compile time -- from 28 sec down to much less than 1 sec on local machine. --- test/mpi/coll/allred.c | 939 ++++++++++++++++++++++++++--------------- 1 file changed, 589 insertions(+), 350 deletions(-) diff --git a/test/mpi/coll/allred.c b/test/mpi/coll/allred.c index 298364b0a2b..aa933cc487b 100644 --- a/test/mpi/coll/allred.c +++ b/test/mpi/coll/allred.c @@ -18,6 +18,12 @@ #endif #include "mtest_dtp.h" +/* For simplicity, we precalculate solutions in integers. Use "long" type + * to prevent intermediate overflows, especially during get_pow(). On the + * other hand, the truncations during assignment and during allreduce + * operation are usually consistent. + */ +#define LONG long long struct int_test { int a; @@ -40,367 +46,560 @@ struct double_test { int b; }; -#define mpi_op2str(op) \ - ((op == MPI_SUM) ? "MPI_SUM" : \ - (op == MPI_PROD) ? "MPI_PROD" : \ - (op == MPI_MAX) ? "MPI_MAX" : \ - (op == MPI_MIN) ? "MPI_MIN" : \ - (op == MPI_LOR) ? "MPI_LOR" : \ - (op == MPI_LXOR) ? "MPI_LXOR" : \ - (op == MPI_LAND) ? "MPI_LAND" : \ - (op == MPI_BOR) ? "MPI_BOR" : \ - (op == MPI_BAND) ? "MPI_BAND" : \ - (op == MPI_BXOR) ? "MPI_BXOR" : \ - (op == MPI_MAXLOC) ? "MPI_MAXLOC" : \ - (op == MPI_MINLOC) ? "MPI_MINLOC" : \ - "MPI_NO_OP") +enum type_category { + CATEGORY_INT, + CATEGORY_FLOAT, + CATEGORY_COMPLEX, + CATEGORY_PAIR, +}; + +/* global variables */ + +static int rank, size; +static mtest_mem_type_e memtype; +static int count; + +static MPI_Datatype int_types[] = { + MPI_INT, + MPI_LONG, + MPI_SHORT, + MPI_UNSIGNED_SHORT, + MPI_UNSIGNED, + MPI_UNSIGNED_LONG, + MPI_UNSIGNED_CHAR, +#if MTEST_HAVE_MIN_MPI_VERSION(2,2) + MPI_INT8_T, + MPI_INT16_T, + MPI_INT32_T, + MPI_INT64_T, + MPI_UINT8_T, + MPI_UINT16_T, + MPI_UINT32_T, + MPI_UINT64_T, + MPI_AINT, + MPI_OFFSET, +#endif +#if MTEST_HAVE_MIN_MPI_VERSION(3,0) + MPI_COUNT, +#endif +}; + +static MPI_Datatype float_types[] = { + MPI_FLOAT, + MPI_DOUBLE, +}; + +static MPI_Datatype byte_types[] = { + MPI_BYTE, +}; + +#if MTEST_HAVE_MIN_MPI_VERSION(2,2) +static MPI_Datatype complex_types[] = { + MPI_C_FLOAT_COMPLEX, + MPI_C_DOUBLE_COMPLEX, +#ifdef HAVE_LONG_DOUBLE__COMPLEX + MPI_C_LONG_DOUBLE_COMPLEX, +#endif +}; +#endif + +#if MTEST_HAVE_MIN_MPI_VERSION(2,2) && defined(HAVE__BOOL) +static MPI_Datatype logical_types[] = { + MPI_C_BOOL, +}; +#endif + +static MPI_Datatype pair_types[] = { + MPI_2INT, + MPI_LONG_INT, + MPI_SHORT_INT, + MPI_FLOAT_INT, + MPI_DOUBLE_INT +}; + +#define MAX_TYPE_SIZE 16 +static void *in, *out, *sol; +static void *in_d, *out_d; + +/* internal routines */ +static const char *mpi_op2str(MPI_Op op) +{ + return ((op == MPI_SUM) ? "MPI_SUM" : + (op == MPI_PROD) ? "MPI_PROD" : + (op == MPI_MAX) ? "MPI_MAX" : + (op == MPI_MIN) ? "MPI_MIN" : + (op == MPI_LOR) ? "MPI_LOR" : + (op == MPI_LXOR) ? "MPI_LXOR" : + (op == MPI_LAND) ? "MPI_LAND" : + (op == MPI_BOR) ? "MPI_BOR" : + (op == MPI_BAND) ? "MPI_BAND" : + (op == MPI_BXOR) ? "MPI_BXOR" : + (op == MPI_MAXLOC) ? "MPI_MAXLOC" : (op == MPI_MINLOC) ? "MPI_MINLOC" : "MPI_NO_OP"); +} /* calloc to avoid spurious valgrind warnings when "type" has padding bytes */ -#define DECL_MALLOC_IN_OUT_SOL(type) \ - type *in, *out, *sol; /*allocated on host*/ \ - void *in_d, *out_d; /*allocated on device*/ \ - MTestCalloc(count * sizeof(type), memtype, ((void **)&in), &in_d, rank); \ - MTestCalloc(count * sizeof(type), memtype, ((void **)&out), &out_d, rank);\ - sol = (type *) calloc(count, sizeof(type)); - -#define SET_INDEX_CONST(arr, val) \ - { \ - int i; \ - for (i = 0; i < count; i++) \ - arr[i] = val; \ - } +static void malloc_in_out_sol(int memtype, int rank) +{ + MTestCalloc(count * MAX_TYPE_SIZE, memtype, &in, &in_d, rank); + MTestCalloc(count * MAX_TYPE_SIZE, memtype, &out, &out_d, rank); + sol = calloc(count, MAX_TYPE_SIZE); +} + +static void free_in_out_sol(int memtype) +{ + MTestFree(memtype, in, in_d); + MTestFree(memtype, out, out_d); + free(sol); +} + +static int get_mpi_type_size(MPI_Datatype mpi_type) +{ + MPI_Aint lb, extent; + MPI_Type_get_extent(mpi_type, &lb, &extent); + return extent; +} -#define SET_INDEX_SUM(arr, val) \ - { \ - int i; \ - for (i = 0; i < count; i++) \ - arr[i] = i + val; \ +static void set_int_value(void *p, int type_size, LONG val) +{ + switch (type_size) { + case 1: + *(int8_t *) p = (int8_t) val; + break; + case 2: + *(int16_t *) p = (int16_t) val; + break; + case 4: + *(int32_t *) p = (int32_t) val; + break; + case 8: + *(int64_t *) p = (int64_t) val; + break; + default: + assert(0); } +} -#define SET_INDEX_FACTOR(arr, val) \ - { \ - int i; \ - for (i = 0; i < count; i++) \ - arr[i] = i * (val); \ +static void set_float_value(void *p, int type_size, LONG val) +{ + if (type_size == 4) { + *(float *) p = (float) val; + } else if (type_size == 8) { + *(double *) p = (double) val; + } else { + assert(0); } +} -#define SET_INDEX_POWER(arr, val) \ - { \ - int i, j; \ - for (i = 0; i < count; i++) { \ - (arr)[i] = 1; \ - for (j = 0; j < (val); j++) \ - arr[i] *= i; \ - } \ +static void set_complex_value(void *p, int type_size, LONG val) +{ + if (type_size == 8) { + *(float _Complex *) p = (float _Complex) val; + } else if (type_size == 16) { + *(double _Complex *) p = (double _Complex) val; +#ifdef HAVE_LONG_DOUBLE__COMPLEX + } else if (type_size == 32) { + *(long double _Complex *) p = (long double _Complex) val; +#endif + } else { + assert(0); } +} -#define ERROR_CHECK_AND_FREE(lerrcnt, mpi_type, mpi_op) \ - do { \ - char name[MPI_MAX_OBJECT_NAME] = {0}; \ - int len = 0; \ - if (lerrcnt) { \ - MPI_Type_get_name(mpi_type, name, &len); \ - fprintf(stderr, "(%d) Error for type %s and op %s\n", \ - rank, name, mpi_op2str(mpi_op)); \ - } \ - MTestFree(memtype, in, in_d); \ - MTestFree(memtype, out, out_d); \ - free(sol); \ - } while (0) +static void set_category_value(int category, void *p, int type_size, LONG val) +{ + if (category == CATEGORY_INT) { + set_int_value(p, type_size, val); + } else if (category == CATEGORY_FLOAT) { + set_float_value(p, type_size, val); + } else if (category == CATEGORY_COMPLEX) { + set_complex_value(p, type_size, val); + } else { + assert(0); + } +} -/* The logic on the error check on MPI_Allreduce assumes that all - MPI_Allreduce routines return a failure if any do - this is sufficient - for MPI implementations that reject some of the valid op/datatype pairs - (and motivated this addition, as some versions of the IBM MPI - failed in just this way). -*/ -#define ALLREDUCE_AND_FREE(type, mpi_type, mpi_op, in, out, sol) \ - { \ - int i, rc, lerrcnt = 0; \ - MTestCopyContent(in, in_d, count * sizeof(type), memtype); \ - rc = MPI_Allreduce(in_d, out_d, count, mpi_type, mpi_op, MPI_COMM_WORLD); \ - MTestCopyContent(out_d, out, count * sizeof(type), memtype); \ - if (rc) { lerrcnt++; errs++; MTestPrintError(rc); } \ - else { \ - for (i = 0; i < count; i++) { \ - if (out[i] != sol[i]) { \ - errs++; \ - lerrcnt++; \ - } \ - } \ - } \ - ERROR_CHECK_AND_FREE(lerrcnt, mpi_type, mpi_op); \ +static void set_index_const(MPI_Datatype mpi_type, int category, void *arr, int val, int count) +{ + int type_size = get_mpi_type_size(mpi_type); + char *p = arr; + for (int i = 0; i < count; i++) { + set_category_value(category, p, type_size, val); + p += type_size; } +} -#define STRUCT_ALLREDUCE_AND_FREE(type, mpi_type, mpi_op, in, out, sol) \ - { \ - int i, rc, lerrcnt = 0; \ - MTestCopyContent(in, in_d, count * sizeof(type), memtype); \ - rc = MPI_Allreduce(in_d, out_d, count, mpi_type, mpi_op, MPI_COMM_WORLD); \ - MTestCopyContent(out_d, out, count * sizeof(type), memtype); \ - if (rc) { lerrcnt++; errs++; MTestPrintError(rc); } \ - else { \ - for (i = 0; i < count; i++) { \ - if ((out[i].a != sol[i].a) || (out[i].b != sol[i].b)) { \ - errs++; \ - lerrcnt++; \ - } \ - } \ - } \ - ERROR_CHECK_AND_FREE(lerrcnt, mpi_type, mpi_op); \ +static void set_index_sum(MPI_Datatype mpi_type, int category, void *arr, int val, int count) +{ + int type_size = get_mpi_type_size(mpi_type); + char *p = arr; + for (int i = 0; i < count; i++) { + set_category_value(category, p, type_size, i + val); + p += type_size; } +} -#define SET_INDEX_STRUCT_CONST(arr, val, el) \ - { \ - int i; \ - for (i = 0; i < count; i++) \ - arr[i].el = val; \ +static void set_index_factor(MPI_Datatype mpi_type, int category, void *arr, int val, int count) +{ + int type_size = get_mpi_type_size(mpi_type); + char *p = arr; + for (int i = 0; i < count; i++) { + set_category_value(category, p, type_size, i * val); + p += type_size; } +} -#define SET_INDEX_STRUCT_SUM(arr, val, el) \ - { \ - int i; \ - for (i = 0; i < count; i++) \ - arr[i].el = i + (val); \ +static LONG get_pow(int base, int n) +{ + LONG ans = 1; + for (int i = 0; i < n; i++) { + ans *= base; } + return ans; +} -#define sum_test1(type, mpi_type) \ - { \ - DECL_MALLOC_IN_OUT_SOL(type); \ - SET_INDEX_SUM(in, 0); \ - SET_INDEX_FACTOR(sol, size); \ - SET_INDEX_CONST(out, 0); \ - ALLREDUCE_AND_FREE(type, mpi_type, MPI_SUM, in, out, sol); \ +static void set_index_power(MPI_Datatype mpi_type, int category, void *arr, int val, int count) +{ + int type_size = get_mpi_type_size(mpi_type); + char *p = arr; + for (int i = 0; i < count; i++) { + set_category_value(category, p, type_size, get_pow(i, val)); + p += type_size; } +} + +#define SET_PAIR_CASE(type, mpi_type) \ + case mpi_type: \ + { \ + struct type ## _test *pp = p; \ + pp->a = val_a; \ + pp->b = val_b; \ + }; \ + break -#define prod_test1(type, mpi_type) \ - { \ - DECL_MALLOC_IN_OUT_SOL(type); \ - SET_INDEX_SUM(in, 0); \ - SET_INDEX_POWER(sol, size); \ - SET_INDEX_CONST(out, 0); \ - ALLREDUCE_AND_FREE(type, mpi_type, MPI_PROD, in, out, sol); \ +static void set_pair_val(MPI_Datatype mpi_type, void *p, int val_a, int val_b) +{ + switch (mpi_type) { + SET_PAIR_CASE(int, MPI_2INT); + SET_PAIR_CASE(long, MPI_LONG_INT); + SET_PAIR_CASE(short, MPI_SHORT_INT); + SET_PAIR_CASE(float, MPI_FLOAT_INT); + SET_PAIR_CASE(double, MPI_DOUBLE_INT); + default: + assert(0); } +} -#define max_test1(type, mpi_type) \ - { \ - DECL_MALLOC_IN_OUT_SOL(type); \ - SET_INDEX_SUM(in, rank); \ - SET_INDEX_SUM(sol, size - 1); \ - SET_INDEX_CONST(out, 0); \ - ALLREDUCE_AND_FREE(type, mpi_type, MPI_MAX, in, out, sol); \ +static void set_index_pair_const(MPI_Datatype mpi_type, void *arr, int val_a, int val_b, int count) +{ + int type_size = get_mpi_type_size(mpi_type); + char *p = arr; + for (int i = 0; i < count; i++) { + set_pair_val(mpi_type, p, val_a, val_b); + p += type_size; } +} -#define min_test1(type, mpi_type) \ - { \ - DECL_MALLOC_IN_OUT_SOL(type); \ - SET_INDEX_SUM(in, rank); \ - SET_INDEX_SUM(sol, 0); \ - SET_INDEX_CONST(out, 0); \ - ALLREDUCE_AND_FREE(type, mpi_type, MPI_MIN, in, out, sol); \ +static void set_index_pair_sum(MPI_Datatype mpi_type, void *arr, int val_a, int val_b, int count) +{ + int type_size = get_mpi_type_size(mpi_type); + char *p = arr; + for (int i = 0; i < count; i++) { + set_pair_val(mpi_type, p, i + val_a, val_b); + p += type_size; } +} -#define const_test(type, mpi_type, mpi_op, val1, val2, val3) \ - { \ - DECL_MALLOC_IN_OUT_SOL(type); \ - SET_INDEX_CONST(in, (val1)); \ - SET_INDEX_CONST(sol, (val2)); \ - SET_INDEX_CONST(out, (val3)); \ - ALLREDUCE_AND_FREE(type, mpi_type, mpi_op, in, out, sol); \ +static int cmp_float(void *p, void *q, int type_size) +{ + if (type_size == 4) { + if (*(float *) p != *(float *) q) { + return 1; + } + } else if (type_size == 8) { + if (*(double *) p != *(double *) q) { + return 1; + } + } else { + assert(0); } + return 0; +} -#define lor_test1(type, mpi_type) \ - const_test(type, mpi_type, MPI_LOR, (rank & 0x1), (size > 1), 0) -#define lor_test2(type, mpi_type) \ - const_test(type, mpi_type, MPI_LOR, 0, 0, 0) -#define lxor_test1(type, mpi_type) \ - const_test(type, mpi_type, MPI_LXOR, (rank == 1), (size > 1), 0) -#define lxor_test2(type, mpi_type) \ - const_test(type, mpi_type, MPI_LXOR, 0, 0, 0) -#define lxor_test3(type, mpi_type) \ - const_test(type, mpi_type, MPI_LXOR, 1, (size & 0x1), 0) -#define land_test1(type, mpi_type) \ - const_test(type, mpi_type, MPI_LAND, (rank & 0x1), 0, 0) -#define land_test2(type, mpi_type) \ - const_test(type, mpi_type, MPI_LAND, 1, 1, 0) -#define bor_test1(type, mpi_type) \ - const_test(type, mpi_type, MPI_BOR, (rank & 0x3), ((size < 3) ? size - 1 : 0x3), 0) -#define bxor_test1(type, mpi_type) \ - const_test(type, mpi_type, MPI_BXOR, (rank == 1) * 0xf0, (size > 1) * 0xf0, 0) -#define bxor_test2(type, mpi_type) \ - const_test(type, mpi_type, MPI_BXOR, 0, 0, 0) -#define bxor_test3(type, mpi_type) \ - const_test(type, mpi_type, MPI_BXOR, ~0, (size &0x1) ? ~0 : 0, 0) - -#define band_test1(type, mpi_type) \ - { \ - DECL_MALLOC_IN_OUT_SOL(type); \ - if (rank == size-1) { \ - SET_INDEX_SUM(in, 0); \ - } \ - else { \ - SET_INDEX_CONST(in, ~0); \ - } \ - SET_INDEX_SUM(sol, 0); \ - SET_INDEX_CONST(out, 0); \ - ALLREDUCE_AND_FREE(type, mpi_type, MPI_BAND, in, out, sol); \ +static int cmp_complex(void *p, void *q, int type_size) +{ + if (type_size == 8) { + if (*(float _Complex *) p != *(float _Complex *) q) { + return 1; + } + } else if (type_size == 16) { + if (*(double _Complex *) p != *(double _Complex *) q) { + return 1; + } +#ifdef HAVE_LONG_DOUBLE__COMPLEX + } else if (type_size == 32) { + if (*(long double _Complex *) p != *(long double _Complex *) q) { + return 1; + } +#endif + } else { + assert(0); } + return 0; +} -#define band_test2(type, mpi_type) \ - { \ - DECL_MALLOC_IN_OUT_SOL(type); \ - if (rank == size-1) { \ - SET_INDEX_SUM(in, 0); \ - } \ - else { \ - SET_INDEX_CONST(in, 0); \ - } \ - SET_INDEX_CONST(sol, 0); \ - SET_INDEX_CONST(out, 0); \ - ALLREDUCE_AND_FREE(type, mpi_type, MPI_BAND, in, out, sol); \ +static int cmp_int(void *p, void *q, int type_size) +{ + if (memcmp(p, q, type_size) == 0) { + return 0; + } else { + return 1; } +} -#define maxloc_test(type, mpi_type) \ - { \ - DECL_MALLOC_IN_OUT_SOL(type); \ - SET_INDEX_STRUCT_SUM(in, rank, a); \ - SET_INDEX_STRUCT_CONST(in, rank, b); \ - SET_INDEX_STRUCT_SUM(sol, size - 1, a); \ - SET_INDEX_STRUCT_CONST(sol, size - 1, b); \ - SET_INDEX_STRUCT_CONST(out, 0, a); \ - SET_INDEX_STRUCT_CONST(out, -1, b); \ - STRUCT_ALLREDUCE_AND_FREE(type, mpi_type, MPI_MAXLOC, in, out, sol); \ +#define CMP_PAIR_CASE(type, mpi_type) \ + case mpi_type: \ + do { \ + struct type ## _test *pp, *qq; \ + pp = p; \ + qq = q; \ + if (pp->a == qq->a && pp->b == qq->b) { \ + return 0; \ + } else { \ + return 1; \ + } \ + } while (0) + +static int cmp_pair(void *p, void *q, MPI_Datatype mpi_type) +{ + switch (mpi_type) { + CMP_PAIR_CASE(int, MPI_2INT); + CMP_PAIR_CASE(long, MPI_LONG_INT); + CMP_PAIR_CASE(short, MPI_SHORT_INT); + CMP_PAIR_CASE(float, MPI_FLOAT_INT); + CMP_PAIR_CASE(double, MPI_DOUBLE_INT); + default: + assert(0); } + return 1; +} -#define minloc_test(type, mpi_type) \ - { \ - DECL_MALLOC_IN_OUT_SOL(type); \ - SET_INDEX_STRUCT_SUM(in, rank, a); \ - SET_INDEX_STRUCT_CONST(in, rank, b); \ - SET_INDEX_STRUCT_SUM(sol, 0, a); \ - SET_INDEX_STRUCT_CONST(sol, 0, b); \ - SET_INDEX_STRUCT_CONST(out, 0, a); \ - SET_INDEX_STRUCT_CONST(out, -1, b); \ - STRUCT_ALLREDUCE_AND_FREE(type, mpi_type, MPI_MINLOC, in, out, sol); \ +static int cmp_arr_value(MPI_Datatype mpi_type, int category, void *arr1, void *arr2, int count) +{ + int err = 0; + + int type_size = get_mpi_type_size(mpi_type); + char *p = arr1; + char *q = arr2; + for (int i = 0; i < count; i++) { + if (category == CATEGORY_INT) { + err += cmp_int(p, q, type_size); + } else if (category == CATEGORY_FLOAT) { + err += cmp_float(p, q, type_size); + } else if (category == CATEGORY_COMPLEX) { + err += cmp_complex(p, q, type_size); + } else if (category == CATEGORY_PAIR) { + err += cmp_pair(p, q, mpi_type); + } else { + assert(0); + } + p += type_size; + q += type_size; } + return err; +} -#if MTEST_HAVE_MIN_MPI_VERSION(2,2) -#define test_types_set_mpi_2_2_integer(op,post) do { \ - op##_test##post(int8_t, MPI_INT8_T); \ - op##_test##post(int16_t, MPI_INT16_T); \ - op##_test##post(int32_t, MPI_INT32_T); \ - op##_test##post(int64_t, MPI_INT64_T); \ - op##_test##post(uint8_t, MPI_UINT8_T); \ - op##_test##post(uint16_t, MPI_UINT16_T); \ - op##_test##post(uint32_t, MPI_UINT32_T); \ - op##_test##post(uint64_t, MPI_UINT64_T); \ - op##_test##post(MPI_Aint, MPI_AINT); \ - op##_test##post(MPI_Offset, MPI_OFFSET); \ - } while (0) -#else -#define test_types_set_mpi_2_2_integer(op,post) do { } while (0) -#endif +static void report_error(int rank, MPI_Datatype mpi_type, MPI_Op op) +{ + char name[MPI_MAX_OBJECT_NAME] = { 0 }; + int len = 0; -#if MTEST_HAVE_MIN_MPI_VERSION(3,0) -#define test_types_set_mpi_3_0_integer(op,post) do { \ - op##_test##post(MPI_Count, MPI_COUNT); \ - } while (0) -#else -#define test_types_set_mpi_3_0_integer(op,post) do { } while (0) -#endif + MPI_Type_get_name(mpi_type, name, &len); + printf("(%d) Error for type %s and op %s\n", rank, name, mpi_op2str(op)); +} -#define test_types_set1(op, post) \ - { \ - op##_test##post(int, MPI_INT); \ - op##_test##post(long, MPI_LONG); \ - op##_test##post(short, MPI_SHORT); \ - op##_test##post(unsigned short, MPI_UNSIGNED_SHORT); \ - op##_test##post(unsigned, MPI_UNSIGNED); \ - op##_test##post(unsigned long, MPI_UNSIGNED_LONG); \ - op##_test##post(unsigned char, MPI_UNSIGNED_CHAR); \ - test_types_set_mpi_2_2_integer(op,post); \ - test_types_set_mpi_3_0_integer(op,post); \ - } +/* The logic on the error check on MPI_Allreduce assumes that all + MPI_Allreduce routines return a failure if any do - this is sufficient + for MPI implementations that reject some of the valid op/datatype pairs + (and motivated this addition, as some versions of the IBM MPI + failed in just this way). +*/ -#define test_types_set2(op, post) \ - { \ - test_types_set1(op, post); \ - op##_test##post(float, MPI_FLOAT); \ - op##_test##post(double, MPI_DOUBLE); \ +static int allreduce_and_check(MPI_Datatype mpi_type, int category, MPI_Op op, int memtype) +{ + int lerrcnt = 0; + + int type_size = get_mpi_type_size(mpi_type); + MTestCopyContent(in, in_d, count * type_size, memtype); + int rc = MPI_Allreduce(in_d, out_d, count, mpi_type, op, MPI_COMM_WORLD); + MTestCopyContent(out_d, out, count * type_size, memtype); + + if (rc) { + lerrcnt++; + MTestPrintError(rc); + } else { + lerrcnt += cmp_arr_value(mpi_type, category, out, sol, count); } -#define test_types_set3(op, post) \ - { \ - op##_test##post(unsigned char, MPI_BYTE); \ + if (lerrcnt > 0) { + report_error(rank, mpi_type, op); } + return lerrcnt; +} -/* Make sure that we test complex and double complex, even if long - double complex is not available */ -#if defined(USE_LONG_DOUBLE_COMPLEX) - -#if MTEST_HAVE_MIN_MPI_VERSION(2,2) && defined(HAVE_FLOAT__COMPLEX) \ - && defined(HAVE_DOUBLE__COMPLEX) \ - && defined(HAVE_LONG_DOUBLE__COMPLEX) -#define test_types_set4(op, post) \ - do { \ - op##_test##post(float _Complex, MPI_C_FLOAT_COMPLEX); \ - op##_test##post(double _Complex, MPI_C_DOUBLE_COMPLEX); \ - if (MPI_C_LONG_DOUBLE_COMPLEX != MPI_DATATYPE_NULL) { \ - op##_test##post(long double _Complex, MPI_C_LONG_DOUBLE_COMPLEX); \ - } \ - } while (0) +static int sum_test_1(MPI_Datatype mpi_type, int category, int memtype) +{ + set_index_sum(mpi_type, category, in, 0, count); + set_index_factor(mpi_type, category, sol, size, count); + set_index_const(mpi_type, category, out, 0, count); + return allreduce_and_check(mpi_type, category, MPI_SUM, memtype); +} -#else -#define test_types_set4(op, post) do { } while (0) -#endif -#else - -#if MTEST_HAVE_MIN_MPI_VERSION(2,2) && defined(HAVE_FLOAT__COMPLEX) \ - && defined(HAVE_DOUBLE__COMPLEX) -#define test_types_set4(op, post) \ - do { \ - op##_test##post(float _Complex, MPI_C_FLOAT_COMPLEX); \ - op##_test##post(double _Complex, MPI_C_DOUBLE_COMPLEX); \ - } while (0) +static int prod_test_1(MPI_Datatype mpi_type, int category, int memtype) +{ + set_index_sum(mpi_type, category, in, 0, count); + set_index_power(mpi_type, category, sol, size, count); + set_index_const(mpi_type, category, out, 0, count); + return allreduce_and_check(mpi_type, category, MPI_PROD, memtype); +} -#else -#define test_types_set4(op, post) do { } while (0) -#endif +static int max_test_1(MPI_Datatype mpi_type, int category, int memtype) +{ + set_index_sum(mpi_type, category, in, rank, count); + set_index_sum(mpi_type, category, sol, size - 1, count); + set_index_const(mpi_type, category, out, 0, count); + return allreduce_and_check(mpi_type, category, MPI_MAX, memtype); +} -#endif /* defined(USE_LONG_DOUBLE_COMPLEX) */ +static int min_test_1(MPI_Datatype mpi_type, int category, int memtype) +{ + set_index_sum(mpi_type, category, in, rank, count); + set_index_sum(mpi_type, category, sol, 0, count); + set_index_const(mpi_type, category, out, 0, count); + return allreduce_and_check(mpi_type, category, MPI_MIN, memtype); +} -#if MTEST_HAVE_MIN_MPI_VERSION(2,2) && defined(HAVE__BOOL) -#define test_types_set5(op, post) \ - do { \ - op##_test##post(_Bool, MPI_C_BOOL); \ +#define set_const_test(val1, val2, val3) \ + do { \ + set_index_const(mpi_type, category, in, val1, count); \ + set_index_const(mpi_type, category, sol, val2, count); \ + set_index_const(mpi_type, category, out, val3, count); \ } while (0) -#else -#define test_types_set5(op, post) do { } while (0) -#endif +static int lor_test_1(MPI_Datatype mpi_type, int category, int memtype) +{ + set_const_test((rank & 0x1), (size > 1), 0); + return allreduce_and_check(mpi_type, category, MPI_LOR, memtype); +} -static int test_allred(int count, mtest_mem_type_e evenmem, mtest_mem_type_e oddmem) +static int lor_test_2(MPI_Datatype mpi_type, int category, int memtype) { - int errs = 0; - int size, rank; - mtest_mem_type_e memtype; + set_const_test(0, 0, 0); + return allreduce_and_check(mpi_type, category, MPI_LOR, memtype); +} - MPI_Comm_size(MPI_COMM_WORLD, &size); - MPI_Comm_rank(MPI_COMM_WORLD, &rank); +static int lxor_test_1(MPI_Datatype mpi_type, int category, int memtype) +{ + set_const_test((rank == 1), (size > 1), 0); + return allreduce_and_check(mpi_type, category, MPI_LXOR, memtype); +} - if (size < 2) { - fprintf(stderr, "At least 2 processes required\n"); - MPI_Abort(MPI_COMM_WORLD, 1); +static int lxor_test_2(MPI_Datatype mpi_type, int category, int memtype) +{ + set_const_test(0, 0, 0); + return allreduce_and_check(mpi_type, category, MPI_LXOR, memtype); +} + +static int lxor_test_3(MPI_Datatype mpi_type, int category, int memtype) +{ + set_const_test(1, (size & 0x1), 0); + return allreduce_and_check(mpi_type, category, MPI_LXOR, memtype); +} + +static int land_test_1(MPI_Datatype mpi_type, int category, int memtype) +{ + set_const_test((rank & 0x1), 0, 0); + return allreduce_and_check(mpi_type, category, MPI_LAND, memtype); +} + +static int land_test_2(MPI_Datatype mpi_type, int category, int memtype) +{ + set_const_test(1, 1, 0); + return allreduce_and_check(mpi_type, category, MPI_LAND, memtype); +} + +static int bor_test_1(MPI_Datatype mpi_type, int category, int memtype) +{ + set_const_test((rank & 0x3), ((size < 3) ? size - 1 : 0x3), 0); + return allreduce_and_check(mpi_type, category, MPI_BOR, memtype); +} + +static int bxor_test_1(MPI_Datatype mpi_type, int category, int memtype) +{ + set_const_test((rank == 1) * 0xf0, (size > 1) * 0xf0, 0); + return allreduce_and_check(mpi_type, category, MPI_BXOR, memtype); +} + +static int bxor_test_2(MPI_Datatype mpi_type, int category, int memtype) +{ + set_const_test(0, 0, 0); + return allreduce_and_check(mpi_type, category, MPI_BXOR, memtype); +} + +static int bxor_test_3(MPI_Datatype mpi_type, int category, int memtype) +{ + set_const_test(~0, (size & 0x1) ? ~0 : 0, 0); + return allreduce_and_check(mpi_type, category, MPI_BXOR, memtype); +} + +static int band_test_1(MPI_Datatype mpi_type, int category, int memtype) +{ + if (rank == size - 1) { + set_index_sum(mpi_type, category, in, 0, count); + } else { + set_index_const(mpi_type, category, in, ~0, count); + } + set_index_sum(mpi_type, category, sol, 0, count); + set_index_const(mpi_type, category, out, 0, count); + return allreduce_and_check(mpi_type, category, MPI_BAND, memtype); +} + +static int band_test_2(MPI_Datatype mpi_type, int category, int memtype) +{ + if (rank == size - 1) { + set_index_sum(mpi_type, category, in, 0, count); + } else { + set_index_const(mpi_type, category, in, 0, count); } + set_index_const(mpi_type, category, sol, 0, count); + set_index_const(mpi_type, category, out, 0, count); + return allreduce_and_check(mpi_type, category, MPI_BAND, memtype); +} + +static int maxloc_test(MPI_Datatype mpi_type, int memtype) +{ + set_index_pair_sum(mpi_type, in, rank, rank, count); + set_index_pair_sum(mpi_type, sol, size - 1, size - 1, count); + set_index_pair_const(mpi_type, out, 0, -1, count); + return allreduce_and_check(mpi_type, CATEGORY_PAIR, MPI_MAXLOC, memtype); +} + +static int minloc_test(MPI_Datatype mpi_type, int memtype) +{ + set_index_pair_sum(mpi_type, in, rank, rank, count); + set_index_pair_sum(mpi_type, sol, 0, 0, count); + set_index_pair_const(mpi_type, out, 0, 0, count); + return allreduce_and_check(mpi_type, CATEGORY_PAIR, MPI_MINLOC, memtype); +} + +static int test_allred(mtest_mem_type_e evenmem, mtest_mem_type_e oddmem) +{ + int errs = 0; /* Set errors return so that we can provide better information * should a routine reject one of the operand/datatype pairs */ MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN); - if (count <= 0) { - fprintf(stderr, "Invalid count argument %d\n", count); - MPI_Abort(MPI_COMM_WORLD, 1); - } + assert(count > 0); if (rank == 0) { MTestPrintfMsg(1, "./allred -evenmemtype=%s -oddmemtype=%s\n", @@ -412,61 +611,92 @@ static int test_allred(int count, mtest_mem_type_e evenmem, mtest_mem_type_e odd else memtype = oddmem; - test_types_set2(sum, 1); - test_types_set2(prod, 1); - test_types_set2(max, 1); - test_types_set2(min, 1); - - test_types_set1(lor, 1); - test_types_set1(lor, 2); - - test_types_set1(lxor, 1); - test_types_set1(lxor, 2); - test_types_set1(lxor, 3); - - test_types_set1(land, 1); - test_types_set1(land, 2); - - test_types_set1(bor, 1); - test_types_set1(band, 1); - test_types_set1(band, 2); - - test_types_set1(bxor, 1); - test_types_set1(bxor, 2); - test_types_set1(bxor, 3); + malloc_in_out_sol(memtype, rank); + + int num_int_types = sizeof(int_types) / sizeof(MPI_Datatype); + for (int i = 0; i < num_int_types; i++) { + MPI_Datatype mpi_type = int_types[i]; + int category = CATEGORY_INT; + errs += sum_test_1(mpi_type, category, memtype); + errs += prod_test_1(mpi_type, category, memtype); + errs += max_test_1(mpi_type, category, memtype); + errs += min_test_1(mpi_type, category, memtype); + errs += lor_test_1(mpi_type, category, memtype); + errs += lor_test_2(mpi_type, category, memtype); + errs += lxor_test_1(mpi_type, category, memtype); + errs += lxor_test_2(mpi_type, category, memtype); + errs += lxor_test_3(mpi_type, category, memtype); + errs += land_test_1(mpi_type, category, memtype); + errs += land_test_2(mpi_type, category, memtype); + errs += bor_test_1(mpi_type, category, memtype); + errs += band_test_1(mpi_type, category, memtype); + errs += band_test_2(mpi_type, category, memtype); + errs += bxor_test_1(mpi_type, category, memtype); + errs += bxor_test_2(mpi_type, category, memtype); + errs += bxor_test_3(mpi_type, category, memtype); + } - test_types_set3(bor, 1); - test_types_set3(band, 1); - test_types_set3(band, 2); + int num_float_types = sizeof(float_types) / sizeof(MPI_Datatype); + for (int i = 0; i < num_float_types; i++) { + MPI_Datatype mpi_type = float_types[i]; + int category = CATEGORY_FLOAT; + errs += sum_test_1(mpi_type, category, memtype); + errs += prod_test_1(mpi_type, category, memtype); + errs += max_test_1(mpi_type, category, memtype); + errs += min_test_1(mpi_type, category, memtype); + } - test_types_set3(bxor, 1); - test_types_set3(bxor, 2); - test_types_set3(bxor, 3); + int num_byte_types = sizeof(byte_types) / sizeof(MPI_Datatype); + for (int i = 0; i < num_byte_types; i++) { + MPI_Datatype mpi_type = byte_types[i]; + int category = CATEGORY_INT; + errs += bor_test_1(mpi_type, category, memtype); + errs += band_test_1(mpi_type, category, memtype); + errs += band_test_2(mpi_type, category, memtype); + errs += bxor_test_1(mpi_type, category, memtype); + errs += bxor_test_2(mpi_type, category, memtype); + errs += bxor_test_3(mpi_type, category, memtype); + } - test_types_set4(sum, 1); - test_types_set4(prod, 1); +#if MTEST_HAVE_MIN_MPI_VERSION(2,2) + int num_complex_types = sizeof(complex_types) / sizeof(MPI_Datatype); + for (int i = 0; i < num_byte_types; i++) { + MPI_Datatype mpi_type = complex_types[i]; + int category = CATEGORY_COMPLEX; + if (mpi_type != MPI_DATATYPE_NULL) { + errs += sum_test_1(mpi_type, category, memtype); + errs += prod_test_1(mpi_type, category, memtype); + } + } +#endif - test_types_set5(lor, 1); - test_types_set5(lor, 2); - test_types_set5(lxor, 1); - test_types_set5(lxor, 2); - test_types_set5(lxor, 3); - test_types_set5(land, 1); - test_types_set5(land, 2); +#if MTEST_HAVE_MIN_MPI_VERSION(2,2) && defined(HAVE__BOOL) + int num_logical_types = sizeof(logical_types) / sizeof(MPI_Datatype); + for (int i = 0; i < num_byte_types; i++) { + MPI_Datatype mpi_type = logical_types[i]; + int category = CATEGORY_INT; + if (mpi_type != MPI_DATATYPE_NULL) { + errs += lor_test_1(mpi_type, category, memtype); + errs += lor_test_2(mpi_type, category, memtype); + errs += lxor_test_1(mpi_type, category, memtype); + errs += lxor_test_2(mpi_type, category, memtype); + errs += lxor_test_3(mpi_type, category, memtype); + errs += land_test_1(mpi_type, category, memtype); + errs += land_test_2(mpi_type, category, memtype); + } + } +#endif - maxloc_test(struct int_test, MPI_2INT); - maxloc_test(struct long_test, MPI_LONG_INT); - maxloc_test(struct short_test, MPI_SHORT_INT); - maxloc_test(struct float_test, MPI_FLOAT_INT); - maxloc_test(struct double_test, MPI_DOUBLE_INT); + int num_pair_types = sizeof(pair_types) / sizeof(MPI_Datatype); + for (int i = 0; i < num_pair_types; i++) { + errs += maxloc_test(pair_types[i], memtype); + errs += minloc_test(pair_types[i], memtype); + } - minloc_test(struct int_test, MPI_2INT); - minloc_test(struct long_test, MPI_LONG_INT); - minloc_test(struct short_test, MPI_SHORT_INT); - minloc_test(struct float_test, MPI_FLOAT_INT); - minloc_test(struct double_test, MPI_DOUBLE_INT); + free_in_out_sol(memtype); MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_ARE_FATAL); + return errs; } @@ -476,10 +706,19 @@ int main(int argc, char **argv) MTest_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + if (size < 2) { + fprintf(stderr, "At least 2 processes required\n"); + MPI_Abort(MPI_COMM_WORLD, 1); + } + struct dtp_args dtp_args; dtp_args_init(&dtp_args, MTEST_COLL_COUNT, argc, argv); while (dtp_args_get_next(&dtp_args)) { - errs += test_allred(dtp_args.count, dtp_args.u.coll.evenmem, dtp_args.u.coll.oddmem); + count = dtp_args.count; + errs += test_allred(dtp_args.u.coll.evenmem, dtp_args.u.coll.oddmem); } dtp_args_finalize(&dtp_args); From 8c65c2fb77525cc93efcb2383413e704b50ad2da Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 2 Dec 2021 16:55:00 -0600 Subject: [PATCH 242/607] doc: update documents to reflect changes in test/mpi The test suite can be configured and run independently. --- CHANGES | 6 ++++++ README.vin | 11 +++++++++-- doc/installguide/install.tex.vin | 9 +++++++++ doc/userguide/user.tex.vin | 12 ++++++++++-- maint/release.pl | 11 +++++++++++ 5 files changed, 45 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 5cda522eccd..9a8a8b98fca 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +=============================================================================== + Changes in 4.1 +=============================================================================== + +# Testsuite (test/mpi) is configured separately from mpich configure. + =============================================================================== Changes in 4.0 =============================================================================== diff --git a/README.vin b/README.vin index 284bf89cac7..32460a1c950 100644 --- a/README.vin +++ b/README.vin @@ -596,11 +596,18 @@ configuration options can be found using: ================================== To test MPICH, we package the MPICH test suite in the MPICH -distribution. You can run the test suite using: +distribution. You can run the test suite after "make install" using: make testing -The results summary will be placed in test/summary.xml +The results summary will be placed in test/summary.xml. + +The test suite can be used independently to test any installed MPI +implementations: + + cd test/mpi + ./configure --with-mpi=/path/to/mpi + make testing ------------------------------------------------------------------------- diff --git a/doc/installguide/install.tex.vin b/doc/installguide/install.tex.vin index 3bb6faafd29..7c7de184544 100644 --- a/doc/installguide/install.tex.vin +++ b/doc/installguide/install.tex.vin @@ -668,6 +668,15 @@ standard output, along with an XML version of the test results in top-level (\texttt{mpich}) directory will run tests of the commands, such as \texttt{mpicc} and \texttt{mpiexec}, that are included with MPICH. +The MPICH test suite can be used to test any MPI implementations, not just MPICH. +To test a pre-installed MPI implementation, there is no need to configure and +build MPICH. Go to \texttt{test/mpi}` directory and + +\begin{verbatim} + ./configure --with-mpi=/path/to/mpi + make testing +\end{verbatim} + Other MPI test suites are available from \url{http://www.mcs.anl.gov/mpi/mpi-test/tsuite.html}. As part of the MPICH development, we run the MPICH1, MPICH, C++, and Intel test suites every night diff --git a/doc/userguide/user.tex.vin b/doc/userguide/user.tex.vin index 6247aab6d39..73fdba4cb98 100644 --- a/doc/userguide/user.tex.vin +++ b/doc/userguide/user.tex.vin @@ -583,8 +583,16 @@ specified. \label{sec:other-tools} MPICH also includes a test suite for MPI functionality; this suite may be found in the \texttt{mpich/test/mpi} source directory and can be -run with the command \texttt{make testing}. This test suite should -work with any MPI implementation, not just MPICH. +run with the command \texttt{make testing} after \texttt{make install}. +This test suite should work with any MPI implementation, not just MPICH. +To test a pre-installed MPI implementation: +\begin{small} +\begin{verbatim} + shell$ cd mpich/test/mpi + shell$ ./configure --with-mpi=/path/to/mpi + shell$ make testing +\end{verbatim} +\end{small} \clearpage \appendix diff --git a/maint/release.pl b/maint/release.pl index 477ba9e5635..3918e0390e2 100755 --- a/maint/release.pl +++ b/maint/release.pl @@ -225,6 +225,17 @@ sub run_cmd } print("done\n"); +# Create test/mpi/configure +print("===> Creating configure in the test/mpi... "); +chdir("$expdir/test/mpi"); +{ + my $cmd = "./autogen.sh"; + $cmd .= " --with-autoconf=$with_autoconf" if $with_autoconf; + $cmd .= " --with-automake=$with_automake" if $with_automake; + run_cmd($cmd); +} +print("done\n"); + # Disable unnecessary tests in the release tarball print("===> Disabling unnecessary tests in the main codebase... "); chdir($expdir); From 6d0eec54b67f51f9a8603357a45ed71cbdfadbeb Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 22 Nov 2021 23:59:07 -0600 Subject: [PATCH 243/607] autogen: refactor fn_set_autotools --- autogen.sh | 102 +++++++++++++++++++++++++++++------------------------ 1 file changed, 56 insertions(+), 46 deletions(-) diff --git a/autogen.sh b/autogen.sh index 6dc28cf3913..f75620ed405 100755 --- a/autogen.sh +++ b/autogen.sh @@ -68,6 +68,61 @@ sync_external () { } ######################################################################## +## Step functions +######################################################################## + +fn_set_autotools() { + if [ -n "$autotoolsdir" ] ; then + if [ -x $autotoolsdir/autoconf -a -x $autotoolsdir/autoheader ] ; then + autoconf=$autotoolsdir/autoconf + autoheader=$autotoolsdir/autoheader + autoreconf=$autotoolsdir/autoreconf + automake=$autotoolsdir/automake + autom4te=$autotoolsdir/autom4te + aclocal=$autotoolsdir/aclocal + if [ -x "$autotoolsdir/glibtoolize" ] ; then + libtoolize=$autotoolsdir/glibtoolize + else + libtoolize=$autotoolsdir/libtoolize + fi + + AUTOCONF=$autoconf + AUTOHEADER=$autoheader + AUTORECONF=$autoreconf + AUTOMAKE=$automake + AUTOM4TE=$autom4te + ACLOCAL=$aclocal + LIBTOOLIZE=$libtoolize + + export AUTOCONF + export AUTOHEADER + export AUTORECONF + export AUTOM4TE + export AUTOMAKE + export ACLOCAL + export LIBTOOLIZE + else + echo "could not find executable autoconf and autoheader in $autotoolsdir" + exit 1 + fi + else + autoconf=${AUTOCONF:-autoconf} + autoheader=${AUTOHEADER:-autoheader} + autoreconf=${AUTORECONF:-autoreconf} + autom4te=${AUTOM4TE:-autom4te} + automake=${AUTOMAKE:-automake} + aclocal=${ACLOCAL:-aclocal} + if test -z "${LIBTOOLIZE+set}" && ( glibtoolize --version ) >/dev/null 2>&1 ; then + libtoolize=glibtoolize + else + libtoolize=${LIBTOOLIZE:-libtoolize} + fi + fi +} + +# end of utility functions +#----------------------------------------------------------------------- + echo echo "####################################" echo "## Checking user environment" @@ -290,52 +345,7 @@ done ## Check for the location of autotools ######################################################################## -if [ -n "$autotoolsdir" ] ; then - if [ -x $autotoolsdir/autoconf -a -x $autotoolsdir/autoheader ] ; then - autoconf=$autotoolsdir/autoconf - autoheader=$autotoolsdir/autoheader - autoreconf=$autotoolsdir/autoreconf - automake=$autotoolsdir/automake - autom4te=$autotoolsdir/autom4te - aclocal=$autotoolsdir/aclocal - if [ -x "$autotoolsdir/glibtoolize" ] ; then - libtoolize=$autotoolsdir/glibtoolize - else - libtoolize=$autotoolsdir/libtoolize - fi - - AUTOCONF=$autoconf - AUTOHEADER=$autoheader - AUTORECONF=$autoreconf - AUTOMAKE=$automake - AUTOM4TE=$autom4te - ACLOCAL=$aclocal - LIBTOOLIZE=$libtoolize - - export AUTOCONF - export AUTOHEADER - export AUTORECONF - export AUTOM4TE - export AUTOMAKE - export ACLOCAL - export LIBTOOLIZE - else - echo "could not find executable autoconf and autoheader in $autotoolsdir" - exit 1 - fi -else - autoconf=${AUTOCONF:-autoconf} - autoheader=${AUTOHEADER:-autoheader} - autoreconf=${AUTORECONF:-autoreconf} - autom4te=${AUTOM4TE:-autom4te} - automake=${AUTOMAKE:-automake} - aclocal=${ACLOCAL:-aclocal} - if test -z "${LIBTOOLIZE+set}" && ( glibtoolize --version ) >/dev/null 2>&1 ; then - libtoolize=glibtoolize - else - libtoolize=${LIBTOOLIZE:-libtoolize} - fi -fi +fn_set_autotools ProgHomeDir $autoconf autoconfdir ProgHomeDir $automake automakedir From 73ea21cb223c07ff19591ecce9f4aec1dcba3e99 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 22 Nov 2021 23:37:40 -0600 Subject: [PATCH 244/607] autogen: refactor fn_maint_configure Note we will set $autotools if necessary, thus allowing `autogen.sh -do=maint_configure` to run the single step if necessary. --- autogen.sh | 75 +++++++++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/autogen.sh b/autogen.sh index f75620ed405..23cf4bb4faf 100755 --- a/autogen.sh +++ b/autogen.sh @@ -120,6 +120,46 @@ fn_set_autotools() { fi } +fn_maint_configure() { + if test -z "$autoconf" ; then + fn_set_autotools + fi + echo + echo "------------------------------------" + echo "Initiating building required scripts" + # Build scripts such as checkbuilds if necessary + ran_maint_configure=no + run_configure=no + # The information that autoconf uses is saved in the autom4te*.cache + # file; since this cache is not accurate, we delete it. + if [ ! -x maint/configure ] ; then + (cd maint && $autoconf && rm -rf autom4te*.cache ) + elif find maint -name 'configure.ac' -newer 'maint/configure' >/dev/null 2>&1 ; then + # The above relies on the Unix find command + (cd maint && $autoconf && rm -rf autom4te*.cache) + fi + if [ ! -x maint/checkbuilds ] ; then + run_configure=yes + fi + + # The following relies on the Unix find command + if [ -s maint/checkbuilds ] ; then + if find maint -name 'checkbuilds.in' -newer 'maint/checkbuilds' >/dev/null 2>&1 ; then + run_configure=yes + fi + else + run_configure=yes + fi + + if [ "$run_configure" = "yes" ] ; then + (cd maint && ./configure) + ran_maint_configure=yes + fi + echo "Done building required scripts" + echo "------------------------------------" + echo +} + # end of utility functions #----------------------------------------------------------------------- @@ -951,40 +991,7 @@ fi # do_geterrmsgs ## Build required scripts ######################################################################## -echo -echo "------------------------------------" -echo "Initiating building required scripts" -# Build scripts such as checkbuilds if necessary -ran_maint_configure=no -run_configure=no -# The information that autoconf uses is saved in the autom4te*.cache -# file; since this cache is not accurate, we delete it. -if [ ! -x maint/configure ] ; then - (cd maint && $autoconf && rm -rf autom4te*.cache ) -elif find maint -name 'configure.ac' -newer 'maint/configure' >/dev/null 2>&1 ; then - # The above relies on the Unix find command - (cd maint && $autoconf && rm -rf autom4te*.cache) -fi -if [ ! -x maint/checkbuilds ] ; then - run_configure=yes -fi - -# The following relies on the Unix find command -if [ -s maint/checkbuilds ] ; then - if find maint -name 'checkbuilds.in' -newer 'maint/checkbuilds' >/dev/null 2>&1 ; then - run_configure=yes - fi -else - run_configure=yes -fi - -if [ "$run_configure" = "yes" ] ; then - (cd maint && ./configure) - ran_maint_configure=yes -fi -echo "Done building required scripts" -echo "------------------------------------" -echo +fn_maint_configure # new parameter code echo_n "Extracting control variables (cvar) ... " From 9f34b06a861c1c9bc21461ffa9588e09cccbe221 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 22 Nov 2021 23:40:15 -0600 Subject: [PATCH 245/607] autogen: simplify fn_maint_configure The step of configuring in maint folder isn't expensive compared to the rest of the autoconf and configure. Just run autoconf and configure. It isn't worth the complexity to check whether we can skip the step. --- autogen.sh | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/autogen.sh b/autogen.sh index 23cf4bb4faf..ac23479fcc5 100755 --- a/autogen.sh +++ b/autogen.sh @@ -127,34 +127,7 @@ fn_maint_configure() { echo echo "------------------------------------" echo "Initiating building required scripts" - # Build scripts such as checkbuilds if necessary - ran_maint_configure=no - run_configure=no - # The information that autoconf uses is saved in the autom4te*.cache - # file; since this cache is not accurate, we delete it. - if [ ! -x maint/configure ] ; then - (cd maint && $autoconf && rm -rf autom4te*.cache ) - elif find maint -name 'configure.ac' -newer 'maint/configure' >/dev/null 2>&1 ; then - # The above relies on the Unix find command - (cd maint && $autoconf && rm -rf autom4te*.cache) - fi - if [ ! -x maint/checkbuilds ] ; then - run_configure=yes - fi - - # The following relies on the Unix find command - if [ -s maint/checkbuilds ] ; then - if find maint -name 'checkbuilds.in' -newer 'maint/checkbuilds' >/dev/null 2>&1 ; then - run_configure=yes - fi - else - run_configure=yes - fi - - if [ "$run_configure" = "yes" ] ; then - (cd maint && ./configure) - ran_maint_configure=yes - fi + (cd maint && $autoconf && rm -rf autom4te*.cache && ./configure) echo "Done building required scripts" echo "------------------------------------" echo From d78187c6f76a6c1b0d2ce955476aa32501fbab14 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 22 Nov 2021 23:04:18 -0600 Subject: [PATCH 246/607] autogen: refactor fn_geterrmsgs Note that we will run fn_maint_configure if necessary. --- autogen.sh | 122 ++++++++++++++++++++++++++++------------------------- 1 file changed, 64 insertions(+), 58 deletions(-) diff --git a/autogen.sh b/autogen.sh index ac23479fcc5..398b457b49c 100755 --- a/autogen.sh +++ b/autogen.sh @@ -133,6 +133,68 @@ fn_maint_configure() { echo } +fn_geterrmsgs() { + if test ! -x maint/extracterrmsgs ; then + fn_maint_configure + fi + + echo_n "Extracting error messages... " + rm -rf .tmp + rm -f .err + rm -f unusederr.txt + maint/extracterrmsgs -careful=unusederr.txt \ + -skip=src/util/multichannel/mpi.c `cat maint/errmsgdirs` > \ + .tmp 2>.err + # (error here is ok) + echo "done" + + update_errdefs=yes + if [ -s .err ] ; then + cat .err + rm -f .err2 + grep -v "Warning:" .err > .err2 + if [ -s .err2 ] ; then + warn "Because of errors in extracting error messages, the file" + warn "src/mpi/errhan/defmsg.h was not updated." + error "Error message files in src/mpi/errhan were not updated." + rm -f .tmp .err .err2 + exit 1 + fi + rm -f .err .err2 + else + # In case it exists but has zero size + rm -f .err + fi + if [ -s unusederr.txt ] ; then + warn "There are unused error message texts in src/mpi/errhan/errnames.txt" + warn "See the file unusederr.txt for the complete list" + fi + if [ -s .tmp -a "$update_errdefs" = "yes" ] ; then + mv .tmp src/mpi/errhan/defmsg.h + fi + if [ ! -s src/mpi/errhan/defmsg.h ] ; then + echo_n "Creating a dummy defmsg.h file... " + cat > src/mpi/errhan/defmsg.h < MPICH_ERROR_MSG__NONE +#define MPIR_MAX_ERROR_CLASS_INDEX 54 +static int class_to_index[] = { +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0 }; +#endif +EOF + echo "done" + fi +} + # end of utility functions #----------------------------------------------------------------------- @@ -900,64 +962,8 @@ fi # Capture the error messages if [ $do_geterrmsgs = "yes" ] ; then - if [ -x maint/extracterrmsgs ] ; then - echo_n "Extracting error messages... " - rm -rf .tmp - rm -f .err - rm -f unusederr.txt - maint/extracterrmsgs -careful=unusederr.txt \ - -skip=src/util/multichannel/mpi.c `cat maint/errmsgdirs` > \ - .tmp 2>.err - # (error here is ok) - echo "done" - - update_errdefs=yes - if [ -s .err ] ; then - cat .err - rm -f .err2 - grep -v "Warning:" .err > .err2 - if [ -s .err2 ] ; then - warn "Because of errors in extracting error messages, the file" - warn "src/mpi/errhan/defmsg.h was not updated." - error "Error message files in src/mpi/errhan were not updated." - rm -f .tmp .err .err2 - exit 1 - fi - rm -f .err .err2 - else - # In case it exists but has zero size - rm -f .err - fi - if [ -s unusederr.txt ] ; then - warn "There are unused error message texts in src/mpi/errhan/errnames.txt" - warn "See the file unusederr.txt for the complete list" - fi - if [ -s .tmp -a "$update_errdefs" = "yes" ] ; then - mv .tmp src/mpi/errhan/defmsg.h - fi - if [ ! -s src/mpi/errhan/defmsg.h ] ; then - echo_n "Creating a dummy defmsg.h file... " - cat > src/mpi/errhan/defmsg.h < MPICH_ERROR_MSG__NONE -#define MPIR_MAX_ERROR_CLASS_INDEX 54 -static int class_to_index[] = { -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0 }; -#endif -EOF - echo "done" - fi - fi -fi # do_geterrmsgs + fn_geterrmsgs +fi ######################################################################## From 701e3417bc72a97de42f635d80b8692b8d1b7680 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 22 Nov 2021 23:20:57 -0600 Subject: [PATCH 247/607] autogen: refactor fn_getcvars We'll run configure in maint if it isn't run already. --- autogen.sh | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/autogen.sh b/autogen.sh index 398b457b49c..cc243690030 100755 --- a/autogen.sh +++ b/autogen.sh @@ -195,6 +195,21 @@ EOF fi } +fn_getcvars() { + echo_n "Extracting control variables (cvar) ... " + if test ! -x maint/extractcvars ; then + fn_maint_configure + fi + + if ./maint/extractcvars --dirs="`cat maint/cvardirs`"; then + echo "done" + else + echo "failed" + error "unable to extract control variables" + exit 1 + fi +} + # end of utility functions #----------------------------------------------------------------------- @@ -973,17 +988,8 @@ fi fn_maint_configure # new parameter code -echo_n "Extracting control variables (cvar) ... " -if test -x maint/extractcvars -a "$do_getcvars" = "yes" ; then - if ./maint/extractcvars --dirs="`cat maint/cvardirs`"; then - echo "done" - else - echo "failed" - error "unable to extract control variables" - exit 1 - fi -else - echo "skipped" +if test "$do_getcvars" = "yes" ; then + fn_getcvars fi echo From 04eaa356c59207abdf94e0f7667a411f765b088f Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 22 Nov 2021 23:08:08 -0600 Subject: [PATCH 248/607] autogen: refactor fn_autoreconf_amdir --- autogen.sh | 168 ++++++++++++++++------------------------------------- 1 file changed, 51 insertions(+), 117 deletions(-) diff --git a/autogen.sh b/autogen.sh index cc243690030..03b9be2a936 100755 --- a/autogen.sh +++ b/autogen.sh @@ -207,6 +207,56 @@ fn_getcvars() { echo "failed" error "unable to extract control variables" exit 1 + +# internal +_patch_libtool() { + _file=$1 + _patch=$2 + if test -f "$_file" ; then + echo_n "Patching $_file with $_patch..." + patch -N -s -l $_file maint/patches/optional/confdb/$_patch && : + if [ $? -eq 0 ] ; then + # Remove possible leftovers, which don't imply a failure + rm -f $_file.orig + # updates _patch_successful for return + _patch_successful=yes + echo "done" + else + echo "failed" + fi + fi +} + +fn_autoreconf_amdir() { + _dir=$1 + if [ -d "$_dir" -o -L "$_dir" ] ; then + echo "------------------------------------------------------------------------" + echo "running $autoreconf in $_dir" + (cd $_dir && $autoreconf $autoreconf_args) || exit 1 + + # Patching ltmain.sh and libtool.m4 + # This works with libtool versions 2.4 - 2.4.2. + # Older versions are not supported to build mpich. + # Newer versions should have this patch already included. + + _patch_successful=no + + _patch_libtool $_dir/confdb/ltmain.sh intel-compiler.patch + _patch_libtool $_dir/confdb/libtool.m4 sys_lib_dlsearch_path_spec.patch + _patch_libtool $_dir/confdb/libtool.m4 big-sur.patch + if test "$do_bindings" = "yes" ; then + _patch_libtool $_dir/confdb/libtool.m4 darwin-ifort.patch + _patch_libtool $_dir/confdb/libtool.m4 oracle-fort.patch + _patch_libtool $_dir/confdb/libtool.m4 flang.patch + _patch_libtool $_dir/confdb/libtool.m4 arm-compiler.patch + _patch_libtool $_dir/confdb/libtool.m4 ibm-xlf.patch + fi + + if test "$_patch_successful" = "yes" ; then + (cd $_dir && $autoconf -f) || exit 1 + # Reset timestamps to avoid confusing make + touch -r $_dir/confdb/ltversion.m4 $_dir/confdb/ltmain.sh $_dir/confdb/libtool.m4 + fi fi } @@ -1016,123 +1066,7 @@ if [ "$do_build_configure" = "yes" ] ; then done for amdir in $amdirs ; do - if [ -d "$amdir" -o -L "$amdir" ] ; then - echo "------------------------------------------------------------------------" - echo "running $autoreconf in $amdir" - (cd $amdir && $autoreconf $autoreconf_args) || exit 1 - # Patching ltmain.sh - if [ -f $amdir/confdb/ltmain.sh ] ; then - echo_n "Patching ltmain.sh for compatibility with Intel compiler options... " - patch -N -s -l $amdir/confdb/ltmain.sh maint/patches/optional/confdb/intel-compiler.patch && : - if [ $? -eq 0 ] ; then - # Remove possible leftovers, which don't imply a failure - rm -f $amdir/confdb/ltmain.sh.orig - echo "done" - else - echo "failed" - fi - # Rebuild configure - (cd $amdir && $autoconf -f) || exit 1 - # Reset ltmain.sh timestamps to avoid confusing make - touch -r $amdir/confdb/ltversion.m4 $amdir/confdb/ltmain.sh - fi - # Patching libtool.m4 - # This works with libtool versions 2.4 - 2.4.2. - # Older versions are not supported to build mpich. - # Newer versions should have this patch already included. - if [ -f $amdir/confdb/libtool.m4 ] ; then - # There is no need to patch if we're not going to use Fortran. - ifort_patch_requires_rebuild=no - oracle_patch_requires_rebuild=no - flang_patch_requires_rebuild=no - arm_patch_requires_rebuild=no - ibm_patch_requires_rebuild=no - sys_lib_dlsearch_path_patch_requires_rebuild=no - macos_patch_requires_rebuild=no - echo_n "Patching libtool.m4 for system dynamic library search path..." - patch -N -s -l $amdir/confdb/libtool.m4 maint/patches/optional/confdb/sys_lib_dlsearch_path_spec.patch && : - if [ $? -eq 0 ] ; then - sys_lib_dlsearch_path_patch_requires_rebuild=yes - # Remove possible leftovers, which don't imply a failure - rm -f $amdir/confdb/libtool.m4.orig - echo "done" - else - echo "failed" - fi - echo_n "Patching libtool.m4 for compatibility macOS BigSur..." - patch -N -s -l $amdir/confdb/libtool.m4 maint/patches/optional/confdb/big-sur.patch && : - if [ $? -eq 0 ] ; then - macos_patch_requires_rebuild=yes - # Remove possible leftovers, which don't imply a failure - rm -f $amdir/confdb/libtool.m4.orig - echo "done" - else - echo "failed" - fi - if [ $do_bindings = "yes" ] ; then - echo_n "Patching libtool.m4 for compatibility with ifort on OSX... " - patch -N -s -l $amdir/confdb/libtool.m4 maint/patches/optional/confdb/darwin-ifort.patch && : - if [ $? -eq 0 ] ; then - ifort_patch_requires_rebuild=yes - # Remove possible leftovers, which don't imply a failure - rm -f $amdir/confdb/libtool.m4.orig - echo "done" - else - echo "failed" - fi - echo_n "Patching libtool.m4 for fort compatibility with Oracle Dev Studio 12.6..." - patch -N -s -l $amdir/confdb/libtool.m4 maint/patches/optional/confdb/oracle-fort.patch && : - if [ $? -eq 0 ] ; then - oracle_patch_requires_rebuild=yes - # Remove possible leftovers, which don't imply a failure - rm -f $amdir/confdb/libtool.m4.orig - echo "done" - else - echo "failed" - fi - echo_n "Patching libtool.m4 for compatibility with Flang..." - patch -N -s -l $amdir/confdb/libtool.m4 maint/patches/optional/confdb/flang.patch && : - if [ $? -eq 0 ] ; then - flang_patch_requires_rebuild=yes - # Remove possible leftovers, which don't imply a failure - rm -f $amdir/confdb/libtool.m4.orig - echo "done" - else - echo "failed" - fi - echo_n "Patching libtool.m4 for compatibility with Arm LLVM compilers..." - patch -N -s -l $amdir/confdb/libtool.m4 maint/patches/optional/confdb/arm-compiler.patch && : - if [ $? -eq 0 ] ; then - arm_patch_requires_rebuild=yes - # Remove possible leftovers, which don't imply a failure - rm -f $amdir/confdb/libtool.m4.orig - echo "done" - else - echo "failed" - fi - echo_n "Patching libtool.m4 for compatibility with IBM XL Fortran compilers..." - patch -N -s -l $amdir/confdb/libtool.m4 maint/patches/optional/confdb/ibm-xlf.patch && : - if [ $? -eq 0 ] ; then - ibm_patch_requires_rebuild=yes - # Remove possible leftovers, which don't imply a failure - rm -f $amdir/confdb/libtool.m4.orig - echo "done" - else - echo "failed" - fi - fi - - if [ $ifort_patch_requires_rebuild = "yes" ] || [ $oracle_patch_requires_rebuild = "yes" ] \ - || [ $arm_patch_requires_rebuild = "yes" ] || [ $ibm_patch_requires_rebuild = "yes" ] \ - || [ $sys_lib_dlsearch_path_patch_requires_rebuild = "yes" ] || [ $flang_patch_requires_rebuild = "yes" ] \ - || [ $macos_patch_requires_rebuild = "yes" ]; then - # Rebuild configure - (cd $amdir && $autoconf -f) || exit 1 - # Reset libtool.m4 timestamps to avoid confusing make - touch -r $amdir/confdb/ltversion.m4 $amdir/confdb/libtool.m4 - fi - fi - fi + fn_autoreconf_amdir $amdir done fi From e46ec68cc79893f85b705fcfc178c3d856297b82 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 22 Nov 2021 23:11:42 -0600 Subject: [PATCH 249/607] autogen: refactor binding generations --- autogen.sh | 85 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 48 insertions(+), 37 deletions(-) diff --git a/autogen.sh b/autogen.sh index 03b9be2a936..473c91eb8c1 100755 --- a/autogen.sh +++ b/autogen.sh @@ -207,6 +207,39 @@ fn_getcvars() { echo "failed" error "unable to extract control variables" exit 1 + fi +} + +fn_f77() { + echo_n "Building Fortran 77 interface... " + ( cd src/binding/fortran/mpif_h && chmod a+x ./buildiface && ./buildiface ) + $PYTHON maint/gen_binding_f77.py + echo "done" +} + +fn_f90() { + echo_n "Building Fortran 90 interface... " + # Remove any copy of mpi_base.f90 (this is used to handle the + # Double precision vs. Real*8 option + rm -f src/binding/fortran/use_mpi/mpi_base.f90.orig + ( cd src/binding/fortran/use_mpi && chmod a+x ./buildiface && ./buildiface ) + echo "done" +} + +fn_f08() { + echo_n "Building Fortran 08 interface... " + # Top-level files + ( cd src/binding/fortran/use_mpi_f08 && chmod a+x ./buildiface && ./buildiface ) + # generate src/binding/fortran/use_mpi_f08/wrappers_c/... + echo "done" +} + +fn_cxx() { + echo_n "Building C++ interface... " + ( cd src/binding/cxx && chmod a+x ./buildiface && + ./buildiface -nosep -initfile=./cxx.vlist ) + echo "done" +} # internal _patch_libtool() { @@ -287,10 +320,13 @@ echo "done" ######################################################################## # Default choices -do_bindings=yes +do_bindings=yes # if no, skips patching libtool for Fortran do_geterrmsgs=yes do_getcvars=yes do_f77=yes +do_f90=yes +do_f08=yes +do_cxx=yes do_build_configure=yes do_atdir_check=no do_atver_check=yes @@ -982,44 +1018,19 @@ echo "done" ######################################################################## # Create the bindings if necessary -if [ $do_bindings = "yes" ] ; then - if [ $do_f77 = "yes" ] ; then - build_f77=yes - build_f90=yes - build_f08=yes - fi - - if [ $build_f77 = "yes" ] ; then - echo_n "Building Fortran 77 interface... " - ( cd src/binding/fortran/mpif_h && chmod a+x ./buildiface && ./buildiface ) - $PYTHON maint/gen_binding_f77.py - echo "done" - fi - if [ $build_f90 = "yes" ] ; then - echo_n "Building Fortran 90 interface... " - # Remove any copy of mpi_base.f90 (this is used to handle the - # Double precision vs. Real*8 option - rm -f src/binding/fortran/use_mpi/mpi_base.f90.orig - ( cd src/binding/fortran/use_mpi && chmod a+x ./buildiface && ./buildiface ) - echo "done" - fi - if [ $build_f08 = "yes" ] ; then - echo_n "Building Fortran 08 interface... " - # Top-level files - ( cd src/binding/fortran/use_mpi_f08 && chmod a+x ./buildiface && ./buildiface ) - # generate src/binding/fortran/use_mpi_f08/wrappers_c/... - echo "done" - fi - - build_cxx=yes - if [ $build_cxx = "yes" ] ; then - echo_n "Building C++ interface... " - ( cd src/binding/cxx && chmod a+x ./buildiface && - ./buildiface -nosep -initfile=./cxx.vlist ) - echo "done" - fi +if [ $do_f77 = "yes" ] ; then + fn_f77 +fi +if [ $do_f90 = "yes" ] ; then + fn_f90 +fi +if [ $do_f08 = "yes" ] ; then + fn_f08 fi +if [ $do_cxx = "yes" ] ; then + fn_cxx +fi ######################################################################## ## Extract error messages From 48c2c8c966374e866473acd03a33114a61de61f5 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 25 Nov 2021 11:48:13 -0600 Subject: [PATCH 250/607] autogen: refactor fn_maint_version and fn_update_README --- autogen.sh | 53 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/autogen.sh b/autogen.sh index 473c91eb8c1..70605361378 100755 --- a/autogen.sh +++ b/autogen.sh @@ -210,6 +210,37 @@ fn_getcvars() { fi } +fn_maint_version() { + # build a substitute maint/Version script now that we store the single copy of + # this information in an m4 file for autoconf's benefit + echo_n "Generating a helper maint/Version... " + if $autom4te -l M4sugar maint/Version.base.m4 > maint/Version ; then + echo "done" + else + echo "error" + error "unable to correctly generate maint/Version shell helper" + fi +} + +fn_update_README() { + if test ! -f ./maint/Version ; then + fn_maint_version + fi + + echo_n "Updating the README... " + + # import MPICH_VERSION and LIBFABRIC_VERSION + . ./maint/Version + + if [ -f README.vin ] ; then + sed -e "s/%VERSION%/${MPICH_VERSION}/g" -e "s/%LIBFABRIC_VERSION%/${LIBFABRIC_VERSION}/g" README.vin > README + echo "done" + else + echo "error" + error "README.vin file not present, unable to update README version number (perhaps we are running in a release tarball source tree?)" + fi +} + fn_f77() { echo_n "Building Fortran 77 interface... " ( cd src/binding/fortran/mpif_h && chmod a+x ./buildiface && ./buildiface ) @@ -953,30 +984,12 @@ echo ######################################################################## ## Building maint/Version ######################################################################## - -# build a substitute maint/Version script now that we store the single copy of -# this information in an m4 file for autoconf's benefit -echo_n "Generating a helper maint/Version... " -if $autom4te -l M4sugar maint/Version.base.m4 > maint/Version ; then - echo "done" -else - echo "error" - error "unable to correctly generate maint/Version shell helper" -fi +fn_maint_version ######################################################################## ## Building the README ######################################################################## - -echo_n "Updating the README... " -. ./maint/Version -if [ -f README.vin ] ; then - sed -e "s/%VERSION%/${MPICH_VERSION}/g" -e "s/%LIBFABRIC_VERSION%/${LIBFABRIC_VERSION}/g" README.vin > README - echo "done" -else - echo "error" - error "README.vin file not present, unable to update README version number (perhaps we are running in a release tarball source tree?)" -fi +fn_update_README set -e From 14f7c05ec6aafe7c16907af388d13bf1b01820ac Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 25 Nov 2021 09:53:10 -0600 Subject: [PATCH 251/607] autogen: refactor fn_check_autotools --- autogen.sh | 433 +++++++++++++++++++++++++++-------------------------- 1 file changed, 220 insertions(+), 213 deletions(-) diff --git a/autogen.sh b/autogen.sh index 70605361378..dd667b64245 100755 --- a/autogen.sh +++ b/autogen.sh @@ -324,6 +324,225 @@ fn_autoreconf_amdir() { fi } +######################################################################## +## functions for checking prerequisites +######################################################################## + +fn_check_autotools() { + ProgHomeDir $autoconf autoconfdir + ProgHomeDir $automake automakedir + ProgHomeDir $libtoolize libtooldir + + echo_n "Checking if autotools are in the same location... " + if [ "$autoconfdir" = "$automakedir" -a "$autoconfdir" = "$libtooldir" ] ; then + same_atdir=yes + echo "yes, all in $autoconfdir" + else + same_atdir=no + echo "no" + echo " autoconf is in $autoconfdir" + echo " automake is in $automakedir" + echo " libtool is in $libtooldir" + # Emit a big warning message if $same_atdir = no. + warn "Autotools are in different locations. In rare occasion," + warn "resulting configure or makefile may fail in some unexpected ways." + fi + + ######################################################################## + ## Check if autoreconf can be patched to work + ## when autotools are not in the same location. + ## This test needs to be done before individual tests of autotools + ######################################################################## + + # If autotools are not in the same location, override autoreconf appropriately. + if [ "$same_atdir" != "yes" ] ; then + if [ -z "$libtooldir" ] ; then + ProgHomeDir $libtoolize libtooldir + fi + libtoolm4dir="$libtooldir/share/aclocal" + echo_n "Checking if $autoreconf accepts -I $libtoolm4dir... " + new_autoreconf_works=no + if [ -d "$libtoolm4dir" -a -f "$libtoolm4dir/libtool.m4" ] ; then + recreate_tmp + cat >.tmp/configure.ac <<_EOF +AC_INIT(foo,1.0) +AC_PROG_LIBTOOL +AC_OUTPUT +_EOF + AUTORECONF="$autoreconf -I $libtoolm4dir" + if (cd .tmp && $AUTORECONF -ivf >/dev/null 2>&1) ; then + new_autoreconf_works=yes + fi + rm -rf .tmp + fi + echo "$new_autoreconf_works" + # If autoreconf accepts -I correctly, use -I. + # If not, run libtoolize before autoreconf (i.e. for autoconf <= 2.63) + # This test is more general than checking the autoconf version. + if [ "$new_autoreconf_works" != "yes" ] ; then + echo_n "Checking if $autoreconf works after an additional $libtoolize step... " + new_autoreconf_works=no + recreate_tmp + # Need AC_CONFIG_ + cat >.tmp/configure.ac <<_EOF +AC_INIT(foo,1.0) +AC_CONFIG_AUX_DIR([m4]) +AC_CONFIG_MACRO_DIR([m4]) +AC_PROG_LIBTOOL +AC_OUTPUT +_EOF + cat >.tmp/Makefile.am <<_EOF +ACLOCAL_AMFLAGS = -I m4 +_EOF + AUTORECONF="eval $libtoolize && $autoreconf" + if (cd .tmp && $AUTORECONF -ivf >u.txt 2>&1) ; then + new_autoreconf_works=yes + fi + rm -rf .tmp + echo "$new_autoreconf_works" + fi + if [ "$new_autoreconf_works" = "yes" ] ; then + export AUTORECONF + autoreconf="$AUTORECONF" + else + # Since all autoreconf workarounds do not work, we need + # to require all autotools to be in the same directory. + do_atdir_check=yes + error "Since none of the autoreconf workaround works" + error "and autotools are not in the same directory, aborting..." + error "Updating autotools or putting all autotools in the same location" + error "may resolve the issue." + exit 1 + fi + fi + + if test $do_quick = "yes" ; then + : # skip autotool versions check in quick mode (since it is too slow) + else + ######################################################################## + ## Verify autoconf version + ######################################################################## + + echo_n "Checking for autoconf version... " + recreate_tmp + ver=2.67 + # petsc.mcs.anl.gov's /usr/bin/autoreconf is version 2.65 which returns OK + # if configure.ac has AC_PREREQ() withOUT AC_INIT. + # + # ~/> hostname + # petsc + # ~> /usr/bin/autoconf --version + # autoconf (GNU Autoconf) 2.65 + # .... + # ~/> cat configure.ac + # AC_PREREQ(2.68) + # ~/> /usr/bin/autoconf ; echo "rc=$?" + # configure.ac:1: error: Autoconf version 2.68 or higher is required + # configure.ac:1: the top level + # autom4te: /usr/bin/m4 failed with exit status: 63 + # rc=63 + # ~/> /usr/bin/autoreconf ; echo "rc=$?" + # rc=0 + cat > .tmp/configure.ac</dev/null 2>&1 ) ; then + echo ">= $ver" + else + echo "bad autoconf installation" + cat < .tmp/configure.ac<.tmp/Makefile.am +ACLOCAL_AMFLAGS = -I m4 +EOF + if [ ! -d .tmp/m4 ] ; then mkdir .tmp/m4 >/dev/null 2>&1 ; fi + if (cd .tmp && $autoreconf $autoreconf_args >/dev/null 2>&1 ) ; then + echo ">= $ver" + else + echo "bad automake installation" + cat <.tmp/configure.ac +AC_INIT(testver,1.0) +AC_CONFIG_AUX_DIR([m4]) +AC_CONFIG_MACRO_DIR([m4]) +m4_ifdef([LT_PREREQ],,[m4_fatal([LT_PREREQ not defined])]) +LT_PREREQ($ver) +LT_INIT() +AC_MSG_RESULT([A message]) +EOF + cat <.tmp/Makefile.am +ACLOCAL_AMFLAGS = -I m4 +EOF + if [ ! -d .tmp/m4 ] ; then mkdir .tmp/m4 >/dev/null 2>&1 ; fi + if (cd .tmp && $autoreconf $autoreconf_args >/dev/null 2>&1 ) ; then + echo ">= $ver" + else + echo "bad libtool installation" + cat <.tmp/configure.ac <<_EOF -AC_INIT(foo,1.0) -AC_PROG_LIBTOOL -AC_OUTPUT -_EOF - AUTORECONF="$autoreconf -I $libtoolm4dir" - if (cd .tmp && $AUTORECONF -ivf >/dev/null 2>&1) ; then - new_autoreconf_works=yes - fi - rm -rf .tmp - fi - echo "$new_autoreconf_works" - # If autoreconf accepts -I correctly, use -I. - # If not, run libtoolize before autoreconf (i.e. for autoconf <= 2.63) - # This test is more general than checking the autoconf version. - if [ "$new_autoreconf_works" != "yes" ] ; then - echo_n "Checking if $autoreconf works after an additional $libtoolize step... " - new_autoreconf_works=no - recreate_tmp - # Need AC_CONFIG_ - cat >.tmp/configure.ac <<_EOF -AC_INIT(foo,1.0) -AC_CONFIG_AUX_DIR([m4]) -AC_CONFIG_MACRO_DIR([m4]) -AC_PROG_LIBTOOL -AC_OUTPUT -_EOF - cat >.tmp/Makefile.am <<_EOF -ACLOCAL_AMFLAGS = -I m4 -_EOF - AUTORECONF="eval $libtoolize && $autoreconf" - if (cd .tmp && $AUTORECONF -ivf >u.txt 2>&1) ; then - new_autoreconf_works=yes - fi - rm -rf .tmp - echo "$new_autoreconf_works" - fi - if [ "$new_autoreconf_works" = "yes" ] ; then - export AUTORECONF - autoreconf="$AUTORECONF" - else - # Since all autoreconf workarounds do not work, we need - # to require all autotools to be in the same directory. - do_atdir_check=yes - error "Since none of the autoreconf workaround works" - error "and autotools are not in the same directory, aborting..." - error "Updating autotools or putting all autotools in the same location" - error "may resolve the issue." - exit 1 - fi -fi - -if test $do_quick = "yes" ; then - : # skip autotool versions check in quick mode (since it is too slow) -else - ######################################################################## - ## Verify autoconf version - ######################################################################## - - echo_n "Checking for autoconf version... " - recreate_tmp - ver=2.67 - # petsc.mcs.anl.gov's /usr/bin/autoreconf is version 2.65 which returns OK - # if configure.ac has AC_PREREQ() withOUT AC_INIT. - # - # ~/> hostname - # petsc - # ~> /usr/bin/autoconf --version - # autoconf (GNU Autoconf) 2.65 - # .... - # ~/> cat configure.ac - # AC_PREREQ(2.68) - # ~/> /usr/bin/autoconf ; echo "rc=$?" - # configure.ac:1: error: Autoconf version 2.68 or higher is required - # configure.ac:1: the top level - # autom4te: /usr/bin/m4 failed with exit status: 63 - # rc=63 - # ~/> /usr/bin/autoreconf ; echo "rc=$?" - # rc=0 - cat > .tmp/configure.ac</dev/null 2>&1 ) ; then - echo ">= $ver" - else - echo "bad autoconf installation" - cat < .tmp/configure.ac<.tmp/Makefile.am -ACLOCAL_AMFLAGS = -I m4 -EOF - if [ ! -d .tmp/m4 ] ; then mkdir .tmp/m4 >/dev/null 2>&1 ; fi - if (cd .tmp && $autoreconf $autoreconf_args >/dev/null 2>&1 ) ; then - echo ">= $ver" - else - echo "bad automake installation" - cat <.tmp/configure.ac -AC_INIT(testver,1.0) -AC_CONFIG_AUX_DIR([m4]) -AC_CONFIG_MACRO_DIR([m4]) -m4_ifdef([LT_PREREQ],,[m4_fatal([LT_PREREQ not defined])]) -LT_PREREQ($ver) -LT_INIT() -AC_MSG_RESULT([A message]) -EOF - cat <.tmp/Makefile.am -ACLOCAL_AMFLAGS = -I m4 -EOF - if [ ! -d .tmp/m4 ] ; then mkdir .tmp/m4 >/dev/null 2>&1 ; fi - if (cd .tmp && $autoreconf $autoreconf_args >/dev/null 2>&1 ) ; then - echo ">= $ver" - else - echo "bad libtool installation" - cat < Date: Thu, 25 Nov 2021 10:04:38 -0600 Subject: [PATCH 252/607] autogen: refactor functions to check prerequisite --- autogen.sh | 144 ++++++++++++++++++++++++----------------------------- 1 file changed, 65 insertions(+), 79 deletions(-) diff --git a/autogen.sh b/autogen.sh index dd667b64245..8529c094635 100755 --- a/autogen.sh +++ b/autogen.sh @@ -543,6 +543,69 @@ EOF fi } +fn_check_bash_find_patch_xargs() { + echo_n "Checking for bash... " + if test "`which bash 2>&1 > /dev/null ; echo $?`" = "0" ;then + echo "done" + else + echo "bash not found" ; + exit 1; + fi + + echo_n "Checking for UNIX find... " + find ./maint -name 'configure.ac' > /dev/null 2>&1 + if [ $? = 0 ] ; then + echo "done" + else + echo "not found (error)" + exit 1 + fi + + echo_n "Checking for UNIX patch... " + patch -v > /dev/null 2>&1 + if [ $? = 0 ] ; then + echo "done" + else + echo "not found (error)" + exit 1 + fi + + echo_n "Checking if xargs rm -rf works... " + if [ -d "`find ./maint -name __random_dir__`" ] ; then + error "found a directory named __random_dir__" + exit 1 + else + mkdir ./maint/__random_dir__ + find ./maint -name __random_dir__ | xargs rm -rf > /dev/null 2>&1 + if [ $? = 0 ] ; then + echo "yes" + else + echo "no (error)" + rm -rf ./maint/__random_dir__ + exit 1 + fi + fi +} + +fn_check_python3() { + echo_n "Checking for Python 3... " + PYTHON= + if test 3 = `python -c 'import sys; print(sys.version_info[0])'`; then + PYTHON=python + fi + + if test -z "$PYTHON" -a 3 = `python3 -c 'import sys; print(sys.version_info[0])'`; then + PYTHON=python3 + fi + + if test -z "$PYTHON" ; then + echo "not found" + exit 1 + else + echo "$PYTHON" + fi +} + # end of utility functions #----------------------------------------------------------------------- @@ -774,86 +837,9 @@ done fn_set_autotools fn_check_autotools -######################################################################## -## Checking for bash -######################################################################## - -echo_n "Checking for bash... " -if test "`which bash 2>&1 > /dev/null ; echo $?`" = "0" ;then - echo "done" -else - echo "bash not found" ; - exit 1; -fi - -######################################################################## -## Checking for UNIX find -######################################################################## - -echo_n "Checking for UNIX find... " -find ./maint -name 'configure.ac' > /dev/null 2>&1 -if [ $? = 0 ] ; then - echo "done" -else - echo "not found (error)" - exit 1 -fi - - -######################################################################## -## Checking for UNIX patch -######################################################################## - -echo_n "Checking for UNIX patch... " -patch -v > /dev/null 2>&1 -if [ $? = 0 ] ; then - echo "done" -else - echo "not found (error)" - exit 1 -fi - +fn_check_bash_find_patch_xargs +fn_check_python3 -######################################################################## -## Checking if xargs rm -rf works -######################################################################## - -echo_n "Checking if xargs rm -rf works... " -if [ -d "`find ./maint -name __random_dir__`" ] ; then - error "found a directory named __random_dir__" - exit 1 -else - mkdir ./maint/__random_dir__ - find ./maint -name __random_dir__ | xargs rm -rf > /dev/null 2>&1 - if [ $? = 0 ] ; then - echo "yes" - else - echo "no (error)" - rm -rf ./maint/__random_dir__ - exit 1 - fi -fi - -######################################################################## -## Check for Python 3 -######################################################################## - -echo_n "Checking for Python 3... " -PYTHON= -if test 3 = `python -c 'import sys; print(sys.version_info[0])'`; then - PYTHON=python -fi - -if test -z "$PYTHON" -a 3 = `python3 -c 'import sys; print(sys.version_info[0])'`; then - PYTHON=python3 -fi - -if test -z "$PYTHON" ; then - echo "not found" - exit 1 -else - echo "$PYTHON" -fi ######################################################################## ## Setup external packages From 01877e3c8e5e5474cabaa5fa81bafe52a45e08f8 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 5 Nov 2021 11:06:17 -0500 Subject: [PATCH 253/607] autogen: remove single step options and checks The current autogen does not make the steps clear, and it is confusing to run a single step. Remove the option and checks for now. TODO: refactor the single steps into individual functions. When -do=xxx is given, run that function and exit. --- autogen.sh | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/autogen.sh b/autogen.sh index 8529c094635..3b7a66a64f3 100755 --- a/autogen.sh +++ b/autogen.sh @@ -684,11 +684,6 @@ export autoreconf_args ## Read the command-line arguments ######################################################################## -# List of steps that we will consider (We do not include depend -# because the values for depend are not just yes/no) -AllSteps="geterrmsgs bindings f77 build_configure getparms" -stepsCleared=no - for arg in "$@" ; do case $arg in -quick) @@ -728,13 +723,6 @@ for arg in "$@" ; do echo "-do=$opt is unrecognized" exit 1 else - if [ $stepsCleared = no ] ; then - for step in $AllSteps ; do - var=do_$step - eval $var=no - done - stepsCleared=yes - fi var=do_$opt eval $var=yes fi @@ -812,13 +800,9 @@ for arg in "$@" ; do twice, as in autogen.sh && autogen.sh -distrib - Use --do=stepname to update only a single step. For example, - --do=build_configure only updates the configure scripts. The available - steps are: + -quick skips most of the modules autoconf. This is used when modules + are prebuilt and used specifically in CI testing to accelerate the build. EOF - for step in $AllSteps ; do - echo " $step" - done exit 1 ;; From 51a4fd9b14511315bc0149e88604bc748f8f3c45 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 25 Nov 2021 10:32:13 -0600 Subject: [PATCH 254/607] autogen: move global options to the front The global option variables are used in various step functions. Move them to the front of the script helps understanding the structure. --- autogen.sh | 154 +++++++++++++++++++++++++---------------------------- 1 file changed, 74 insertions(+), 80 deletions(-) diff --git a/autogen.sh b/autogen.sh index 3b7a66a64f3..ac00487e546 100755 --- a/autogen.sh +++ b/autogen.sh @@ -13,15 +13,6 @@ # mpich tree. This is not yet implemented. -######################################################################## -## Utility functions -######################################################################## - -recreate_tmp() { - rm -rf .tmp - mkdir .tmp 2>&1 >/dev/null -} - warn() { echo "===> WARNING: $@" } @@ -35,6 +26,80 @@ echo_n() { printf "%s" "$*" } +######################################################################## +## Checks to make sure we are running from the correct location +######################################################################## + +echo_n "Verifying the location of autogen.sh... " +if [ ! -d maint -o ! -s maint/version.m4 ] ; then + echo "must execute at top level directory for now" + exit 1 +fi +# Set the SRCROOTDIR to be used later and avoid "cd ../../"-like usage. +SRCROOTDIR=$PWD +echo "done" + +######################################################################## +## Initialize variables to default values (possibly from the environment) +######################################################################## + +# Default choices +do_bindings=yes # if no, skips patching libtool for Fortran +do_geterrmsgs=yes +do_getcvars=yes +do_f77=yes +do_f90=yes +do_f08=yes +do_cxx=yes +do_build_configure=yes +do_atdir_check=no +do_atver_check=yes +do_subcfg_m4=yes +do_hwloc=yes +do_izem=yes +do_ofi=yes +do_ucx=yes +do_json=yes +do_yaksa=yes +do_test=yes +do_hydra=yes +do_hydra2=yes +do_romio=yes + +do_quick=no +# Check -quick option. When enabled, skip as much as we can. +for arg in "$@" ; do + if test $arg = "-quick"; then + do_quick=yes + do_izem=no + do_ofi=no + do_ucx=no + do_yaksa=no + do_test=yes + do_hydra=yes + do_hydra2=no + do_romio=no + fi +done + +# Allow MAKE to be set from the environment +MAKE=${MAKE-make} + +# amdirs are the directories that make use of autoreconf +amdirs=". src/mpl" + +autoreconf_args="-if" +export autoreconf_args + +######################################################################## +## Utility functions +######################################################################## + +recreate_tmp() { + rm -rf .tmp + mkdir .tmp 2>&1 >/dev/null +} + # Assume Program's install-dir is /bin/. # Given program name as the 1st argument, # the install-dir is returned is returned in 2nd argument. @@ -609,77 +674,6 @@ fn_check_python3() { # end of utility functions #----------------------------------------------------------------------- -echo -echo "####################################" -echo "## Checking user environment" -echo "####################################" -echo - -######################################################################## -## Checks to make sure we are running from the correct location -######################################################################## - -echo_n "Verifying the location of autogen.sh... " -if [ ! -d maint -o ! -s maint/version.m4 ] ; then - echo "must execute at top level directory for now" - exit 1 -fi -# Set the SRCROOTDIR to be used later and avoid "cd ../../"-like usage. -SRCROOTDIR=$PWD -echo "done" - -######################################################################## -## Initialize variables to default values (possibly from the environment) -######################################################################## - -# Default choices -do_bindings=yes # if no, skips patching libtool for Fortran -do_geterrmsgs=yes -do_getcvars=yes -do_f77=yes -do_f90=yes -do_f08=yes -do_cxx=yes -do_build_configure=yes -do_atdir_check=no -do_atver_check=yes -do_subcfg_m4=yes -do_hwloc=yes -do_izem=yes -do_ofi=yes -do_ucx=yes -do_json=yes -do_yaksa=yes -do_test=yes -do_hydra=yes -do_hydra2=yes -do_romio=yes - -do_quick=no -# Check -quick option. When enabled, skip as much as we can. -for arg in "$@" ; do - if test $arg = "-quick"; then - do_quick=yes - do_izem=no - do_ofi=no - do_ucx=no - do_yaksa=no - do_test=yes - do_hydra=yes - do_hydra2=no - do_romio=no - fi -done - -# Allow MAKE to be set from the environment -MAKE=${MAKE-make} - -# amdirs are the directories that make use of autoreconf -amdirs=". src/mpl" - -autoreconf_args="-if" -export autoreconf_args - ######################################################################## ## Read the command-line arguments ######################################################################## From 894742438c7cbae30a1e3a26f660431f3404c21c Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 25 Nov 2021 10:51:34 -0600 Subject: [PATCH 255/607] autogen: indentation fix --- autogen.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/autogen.sh b/autogen.sh index ac00487e546..a2319e90096 100755 --- a/autogen.sh +++ b/autogen.sh @@ -755,16 +755,16 @@ for arg in "$@" ; do autotoolsdir=`echo "A$arg" | sed -e 's/.*=//'` ;; - -without-*|--without-*) - opt=`echo A$arg | sed -e 's/^A--*without-//'` - var=do_$opt - eval $var=no - ;; - -with-*|--with-*) - opt=`echo A$arg | sed -e 's/^A--*with-//'` - var=do_$opt - eval $var=yes - ;; + -without-*|--without-*) + opt=`echo A$arg | sed -e 's/^A--*without-//'` + var=do_$opt + eval $var=no + ;; + -with-*|--with-*) + opt=`echo A$arg | sed -e 's/^A--*with-//'` + var=do_$opt + eval $var=yes + ;; -help|--help|-usage|--usage) cat < Date: Thu, 25 Nov 2021 10:46:42 -0600 Subject: [PATCH 256/607] autogen: let -do=xxx execute a single step function Mixing the --with-xxx and -do=xxx options makes the script logic very complex since there are extensible steps and many implicit dependency conditions. Instead, let -do=xxx just execute a single step, which I believe it is the original intention of this option. We assume that when this option is used, the developer knows the dependency are already done or checked. --- autogen.sh | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/autogen.sh b/autogen.sh index a2319e90096..1af81c5196f 100755 --- a/autogen.sh +++ b/autogen.sh @@ -706,20 +706,14 @@ for arg in "$@" ; do -do=*|--do=*) opt=`echo A$arg | sed -e 's/^A--*do=//'` - case $opt in - build-configure|configure) opt=build_configure ;; - esac - var=do_$opt - - # Check that this opt is known - eval oldval=\$"$var" - if [ -z "$oldval" ] ; then + if type fn_$opt | grep -q 'function' ; then + echo Running step $opt... + fn_$opt + exit 0 + else echo "-do=$opt is unrecognized" exit 1 - else - var=do_$opt - eval $var=yes - fi + fi ;; -verbose-autoreconf|--verbose-autoreconf) From f65264dc94b94360ea3be3acea0eb733fcee616d Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 25 Nov 2021 10:59:17 -0600 Subject: [PATCH 257/607] autogen: consolidate --with-xxx options --- autogen.sh | 46 ++++++++++++++++++---------------------------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/autogen.sh b/autogen.sh index 1af81c5196f..b927a8f2254 100755 --- a/autogen.sh +++ b/autogen.sh @@ -45,7 +45,7 @@ echo "done" # Default choices do_bindings=yes # if no, skips patching libtool for Fortran -do_geterrmsgs=yes +do_errmsgs=yes do_getcvars=yes do_f77=yes do_f90=yes @@ -198,7 +198,7 @@ fn_maint_configure() { echo } -fn_geterrmsgs() { +fn_errmsgs() { if test ! -x maint/extracterrmsgs ; then fn_maint_configure fi @@ -721,30 +721,6 @@ for arg in "$@" ; do export autoreconf_args ;; - -with-errmsgs|--with-errmsgs) - do_geterrmsgs=yes - ;; - - -without-errmsgs|--without-errmsgs) - do_geterrmsgs=no - ;; - - -with-bindings|--with-bindings) - do_bindings=yes - ;; - - -without-bindings|--without-bindings) - do_bindings=no - ;; - - -with-f77|--with-f77) - do_f77=yes - ;; - - -without-f77|--without-f77) - do_f77=no - ;; - -with-autotools=*|--with-autotools=*) autotoolsdir=`echo "A$arg" | sed -e 's/.*=//'` ;; @@ -753,11 +729,25 @@ for arg in "$@" ; do opt=`echo A$arg | sed -e 's/^A--*without-//'` var=do_$opt eval $var=no + case "$opt" in + bindings) + do_f77=no + do_f90=no + do_f08=no + do_cxx=no + ;; + esac ;; + -with-*|--with-*) opt=`echo A$arg | sed -e 's/^A--*with-//'` var=do_$opt eval $var=yes + case "$opt" in + f77 | f90 | f08 | cxx) + do_bindings=yes + ;; + esac ;; -help|--help|-usage|--usage) @@ -1015,8 +1005,8 @@ fi ######################################################################## # Capture the error messages -if [ $do_geterrmsgs = "yes" ] ; then - fn_geterrmsgs +if [ $do_errmsgs = "yes" ] ; then + fn_errmsgs fi From 078282b06bb6cebec9d07dd2e6f551cc827c67ef Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 25 Nov 2021 11:37:17 -0600 Subject: [PATCH 258/607] autogen: make set_autotools a prerequisite function A prerequisite function is always checked to allow individual step function to be run indenpendently. --- autogen.sh | 101 ++++++++++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 47 deletions(-) diff --git a/autogen.sh b/autogen.sh index b927a8f2254..18df316f23f 100755 --- a/autogen.sh +++ b/autogen.sh @@ -133,62 +133,67 @@ sync_external () { } ######################################################################## -## Step functions +## prerequisite functions ######################################################################## -fn_set_autotools() { - if [ -n "$autotoolsdir" ] ; then - if [ -x $autotoolsdir/autoconf -a -x $autotoolsdir/autoheader ] ; then - autoconf=$autotoolsdir/autoconf - autoheader=$autotoolsdir/autoheader - autoreconf=$autotoolsdir/autoreconf - automake=$autotoolsdir/automake - autom4te=$autotoolsdir/autom4te - aclocal=$autotoolsdir/aclocal - if [ -x "$autotoolsdir/glibtoolize" ] ; then - libtoolize=$autotoolsdir/glibtoolize +autoconf= +set_autotools() { + if test -z "$autoconf" ; then + if [ -n "$autotoolsdir" ] ; then + if [ -x $autotoolsdir/autoconf -a -x $autotoolsdir/autoheader ] ; then + autoconf=$autotoolsdir/autoconf + autoheader=$autotoolsdir/autoheader + autoreconf=$autotoolsdir/autoreconf + automake=$autotoolsdir/automake + autom4te=$autotoolsdir/autom4te + aclocal=$autotoolsdir/aclocal + if [ -x "$autotoolsdir/glibtoolize" ] ; then + libtoolize=$autotoolsdir/glibtoolize + else + libtoolize=$autotoolsdir/libtoolize + fi + + AUTOCONF=$autoconf + AUTOHEADER=$autoheader + AUTORECONF=$autoreconf + AUTOMAKE=$automake + AUTOM4TE=$autom4te + ACLOCAL=$aclocal + LIBTOOLIZE=$libtoolize + + export AUTOCONF + export AUTOHEADER + export AUTORECONF + export AUTOM4TE + export AUTOMAKE + export ACLOCAL + export LIBTOOLIZE else - libtoolize=$autotoolsdir/libtoolize + echo "could not find executable autoconf and autoheader in $autotoolsdir" + exit 1 fi - - AUTOCONF=$autoconf - AUTOHEADER=$autoheader - AUTORECONF=$autoreconf - AUTOMAKE=$automake - AUTOM4TE=$autom4te - ACLOCAL=$aclocal - LIBTOOLIZE=$libtoolize - - export AUTOCONF - export AUTOHEADER - export AUTORECONF - export AUTOM4TE - export AUTOMAKE - export ACLOCAL - export LIBTOOLIZE - else - echo "could not find executable autoconf and autoheader in $autotoolsdir" - exit 1 - fi - else - autoconf=${AUTOCONF:-autoconf} - autoheader=${AUTOHEADER:-autoheader} - autoreconf=${AUTORECONF:-autoreconf} - autom4te=${AUTOM4TE:-autom4te} - automake=${AUTOMAKE:-automake} - aclocal=${ACLOCAL:-aclocal} - if test -z "${LIBTOOLIZE+set}" && ( glibtoolize --version ) >/dev/null 2>&1 ; then - libtoolize=glibtoolize else - libtoolize=${LIBTOOLIZE:-libtoolize} + autoconf=${AUTOCONF:-autoconf} + autoheader=${AUTOHEADER:-autoheader} + autoreconf=${AUTORECONF:-autoreconf} + autom4te=${AUTOM4TE:-autom4te} + automake=${AUTOMAKE:-automake} + aclocal=${ACLOCAL:-aclocal} + if test -z "${LIBTOOLIZE+set}" && ( glibtoolize --version ) >/dev/null 2>&1 ; then + libtoolize=glibtoolize + else + libtoolize=${LIBTOOLIZE:-libtoolize} + fi fi fi } +######################################################################## +## Step functions +######################################################################## + fn_maint_configure() { - if test -z "$autoconf" ; then - fn_set_autotools - fi + set_autotools echo echo "------------------------------------" echo "Initiating building required scripts" @@ -276,6 +281,7 @@ fn_getcvars() { } fn_maint_version() { + set_autotools # build a substitute maint/Version script now that we store the single copy of # this information in an m4 file for autoconf's benefit echo_n "Generating a helper maint/Version... " @@ -358,6 +364,7 @@ _patch_libtool() { fn_autoreconf_amdir() { _dir=$1 + set_autotools if [ -d "$_dir" -o -L "$_dir" ] ; then echo "------------------------------------------------------------------------" echo "running $autoreconf in $_dir" @@ -394,6 +401,7 @@ fn_autoreconf_amdir() { ######################################################################## fn_check_autotools() { + set_autotools ProgHomeDir $autoconf autoconfdir ProgHomeDir $automake automakedir ProgHomeDir $libtoolize libtooldir @@ -796,7 +804,6 @@ done ## Check for the location of autotools ######################################################################## -fn_set_autotools fn_check_autotools fn_check_bash_find_patch_xargs From e2a10214376d73ce3b6892889a20af0fb2e4ba91 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 25 Nov 2021 11:30:49 -0600 Subject: [PATCH 259/607] autogen: refactor python steps It can be useful to run inidividual api generation steps. Add the PYTHON check into each function so the dependency is managed automatically. --- autogen.sh | 88 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 37 deletions(-) diff --git a/autogen.sh b/autogen.sh index 18df316f23f..c5f50592952 100755 --- a/autogen.sh +++ b/autogen.sh @@ -188,6 +188,32 @@ set_autotools() { fi } +PYTHON= +check_python3() { + echo_n "Checking for Python 3... " + PYTHON= + if test 3 = `python -c 'import sys; print(sys.version_info[0])'`; then + PYTHON=python + fi + + if test -z "$PYTHON" -a 3 = `python3 -c 'import sys; print(sys.version_info[0])'`; then + PYTHON=python3 + fi + + if test -z "$PYTHON" ; then + echo "not found" + exit 1 + else + echo "$PYTHON" + fi +} + +set_PYTHON() { + if test -z "$PYTHON" ; then + check_python3 + fi +} + ######################################################################## ## Step functions ######################################################################## @@ -313,6 +339,7 @@ fn_update_README() { } fn_f77() { + set_PYTHON echo_n "Building Fortran 77 interface... " ( cd src/binding/fortran/mpif_h && chmod a+x ./buildiface && ./buildiface ) $PYTHON maint/gen_binding_f77.py @@ -343,6 +370,26 @@ fn_cxx() { echo "done" } +fn_ch4_api() { + set_PYTHON + echo_n "generating ch4 API boilerplates... " + $PYTHON ./maint/gen_ch4_api.py +} + +fn_gen_coll() { + set_PYTHON + echo_n "generating Collective functions..." + $PYTHON maint/gen_coll.py + echo "done" +} + +fn_gen_binding_c() { + set_PYTHON + echo_n "generating MPI C functions..." + $PYTHON maint/gen_binding_c.py + echo "done" +} + # internal _patch_libtool() { _file=$1 @@ -660,25 +707,6 @@ fn_check_bash_find_patch_xargs() { fi } -fn_check_python3() { - echo_n "Checking for Python 3... " - PYTHON= - if test 3 = `python -c 'import sys; print(sys.version_info[0])'`; then - PYTHON=python - fi - - if test -z "$PYTHON" -a 3 = `python3 -c 'import sys; print(sys.version_info[0])'`; then - PYTHON=python3 - fi - - if test -z "$PYTHON" ; then - echo "not found" - exit 1 - else - echo "$PYTHON" - fi -} - # end of utility functions #----------------------------------------------------------------------- @@ -807,7 +835,7 @@ done fn_check_autotools fn_check_bash_find_patch_xargs -fn_check_python3 +check_python3 ######################################################################## @@ -975,18 +1003,12 @@ echo "done" ######################################################################## ## Building Collective top-level code ######################################################################## - -echo_n "generating Collective functions..." -$PYTHON maint/gen_coll.py -echo "done" +fn_gen_coll ######################################################################## ## Building C interfaces ######################################################################## - -echo_n "generating MPI C functions..." -$PYTHON maint/gen_binding_c.py -echo "done" +fn_gen_binding_c ######################################################################## ## Building non-C interfaces @@ -1056,15 +1078,7 @@ if [ "$do_build_configure" = "yes" ] ; then done fi -echo -echo -echo "###########################################################" -echo "## Generating CH4 API boilerplates" -echo "###########################################################" -echo - -echo_n "generating ch4 API boilerplates... " -$PYTHON ./maint/gen_ch4_api.py +fn_ch4_api echo echo From b7ba89c6178481ac5a238c616b587571356725a7 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 25 Nov 2021 11:55:34 -0600 Subject: [PATCH 260/607] autogen: refactor gen_subcfg romio_glue and json_gen --- autogen.sh | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/autogen.sh b/autogen.sh index c5f50592952..7cc64b6fad5 100755 --- a/autogen.sh +++ b/autogen.sh @@ -338,6 +338,18 @@ fn_update_README() { fi } +fn_gen_subcfg_m4() { + echo_n "Creating subsys_include.m4... " + ./maint/gen_subcfg_m4 + echo "done" +} + +fn_romio_glue() { + echo_n "Building ROMIO glue code... " + ( cd src/glue/romio && chmod a+x ./all_romio_symbols && ./all_romio_symbols ../../mpi/romio/include/mpio.h.in ) + echo "done" +} + fn_f77() { set_PYTHON echo_n "Building Fortran 77 interface... " @@ -390,6 +402,12 @@ fn_gen_binding_c() { echo "done" } +fn_json_gen() { + echo_n "generating json char arrays... " + ./maint/tuning/coll/json_gen.sh + echo "done" +} + # internal _patch_libtool() { _file=$1 @@ -987,18 +1005,14 @@ set -e ## Building subsys_include.m4 ######################################################################## if [ "X$do_subcfg_m4" = Xyes ] ; then - echo_n "Creating subsys_include.m4... " - ./maint/gen_subcfg_m4 - echo "done" + fn_gen_subcfg_m4 fi ######################################################################## ## Building ROMIO glue code ######################################################################## -echo_n "Building ROMIO glue code... " -( cd src/glue/romio && chmod a+x ./all_romio_symbols && ./all_romio_symbols ../../mpi/romio/include/mpio.h.in ) -echo "done" +fn_romio_glue ######################################################################## ## Building Collective top-level code @@ -1080,13 +1094,4 @@ fi fn_ch4_api -echo -echo -echo "###########################################################" -echo "## Creating JSON char arrays" -echo "###########################################################" -echo - -echo_n "generating json char arrays... " -./maint/tuning/coll/json_gen.sh -echo "done" +fn_json_gen From 2f189f9cb5a67db28fc793138729a90ed658693f Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 25 Nov 2021 12:01:07 -0600 Subject: [PATCH 261/607] autogen: refactor fn_build_configure Having individula fn_autoreconf_amdir and fn_autogen_external does not fit the -do=xxx semantics. Refactor and use fn_build_configure instead. This brings the original -do=build_configure option back. --- autogen.sh | 53 +++++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/autogen.sh b/autogen.sh index 7cc64b6fad5..8da4de4a40c 100755 --- a/autogen.sh +++ b/autogen.sh @@ -427,9 +427,8 @@ _patch_libtool() { fi } -fn_autoreconf_amdir() { +autoreconf_amdir() { _dir=$1 - set_autotools if [ -d "$_dir" -o -L "$_dir" ] ; then echo "------------------------------------------------------------------------" echo "running $autoreconf in $_dir" @@ -461,6 +460,31 @@ fn_autoreconf_amdir() { fi } +autogen_external() { + _dir=$1 + if [ -d "$_dir" -o -L "$_dir" ] ; then + echo "------------------------------------------------------------------------" + echo "running third-party initialization in $_dir" + (cd $_dir && ./autogen.sh) || exit 1 + else + error "external directory $_dir missing" + exit 1 + fi +} + +fn_build_configure() { + set_autotools + if [ "$do_build_configure" = "yes" ] ; then + for external in $externals ; do + autogen_external $external + done + + for amdir in $amdirs ; do + autoreconf_amdir $amdir + done + fi +} + ######################################################################## ## functions for checking prerequisites ######################################################################## @@ -1064,33 +1088,10 @@ if test "$do_getcvars" = "yes" ; then fn_getcvars fi -echo -echo -echo "###########################################################" -echo "## Generating configure files" -echo "###########################################################" -echo - ######################################################################## ## Running autotools on non-simplemake directories ######################################################################## - -if [ "$do_build_configure" = "yes" ] ; then - for external in $externals ; do - if [ -d "$external" -o -L "$external" ] ; then - echo "------------------------------------------------------------------------" - echo "running third-party initialization in $external" - (cd $external && ./autogen.sh) || exit 1 - else - error "external directory $external missing" - exit 1 - fi - done - - for amdir in $amdirs ; do - fn_autoreconf_amdir $amdir - done -fi +fn_build_configure fn_ch4_api From eca7a33edee22eee1109e540d53db28423bc275a Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 25 Nov 2021 12:07:04 -0600 Subject: [PATCH 262/607] autogen: refactor set_externals Check and set externals array is a preprequisite function --- autogen.sh | 113 +++++++++++++++++++++++++++-------------------------- 1 file changed, 58 insertions(+), 55 deletions(-) diff --git a/autogen.sh b/autogen.sh index 8da4de4a40c..703abd81057 100755 --- a/autogen.sh +++ b/autogen.sh @@ -188,6 +188,61 @@ set_autotools() { fi } +externals= +set_externals() { + if test -z "$externals" ; then + #TODO: if necessary, run: git submodule update --init + + # hwloc is always required + check_submodule_presence modules/hwloc + + # external packages that require autogen.sh to be run for each of them + externals="test/mpi" + + if [ "yes" = "$do_hydra" ] ; then + externals="${externals} src/pm/hydra" + fi + + if [ "yes" = "$do_hydra2" ] ; then + externals="${externals} src/pm/hydra2" + fi + + if [ "yes" = "$do_romio" ] ; then + externals="${externals} src/mpi/romio" + fi + + if [ "yes" = "$do_hwloc" ] ; then + check_submodule_presence modules/hwloc + externals="${externals} modules/hwloc" + fi + + if [ "yes" = "$do_izem" ] ; then + check_submodule_presence modules/izem + externals="${externals} modules/izem" + fi + + if [ "yes" = "$do_ucx" ] ; then + check_submodule_presence modules/ucx + externals="${externals} modules/ucx" + fi + + if [ "yes" = "$do_ofi" ] ; then + check_submodule_presence modules/libfabric + externals="${externals} modules/libfabric" + fi + + if [ "yes" = "$do_json" ] ; then + check_submodule_presence "modules/json-c" + externals="${externals} modules/json-c" + fi + + if [ "yes" = "$do_yaksa" ] ; then + check_submodule_presence "modules/yaksa" + externals="${externals} modules/yaksa" + fi + fi +} + PYTHON= check_python3() { echo_n "Checking for Python 3... " @@ -475,8 +530,9 @@ autogen_external() { fn_build_configure() { set_autotools if [ "$do_build_configure" = "yes" ] ; then + set_externals for external in $externals ; do - autogen_external $external + autogen_external $external done for amdir in $amdirs ; do @@ -883,60 +939,7 @@ check_python3 ######################################################################## ## Setup external packages ######################################################################## - -echo -echo "###########################################################" -echo "## Checking submodules" -echo "###########################################################" -echo - -# hwloc is always required -check_submodule_presence modules/hwloc - -# external packages that require autogen.sh to be run for each of them -externals="test/mpi" - -if [ "yes" = "$do_hydra" ] ; then - externals="${externals} src/pm/hydra" -fi - -if [ "yes" = "$do_hydra2" ] ; then - externals="${externals} src/pm/hydra2" -fi - -if [ "yes" = "$do_romio" ] ; then - externals="${externals} src/mpi/romio" -fi - -if [ "yes" = "$do_hwloc" ] ; then - check_submodule_presence modules/hwloc - externals="${externals} modules/hwloc" -fi - -if [ "yes" = "$do_izem" ] ; then - check_submodule_presence modules/izem - externals="${externals} modules/izem" -fi - -if [ "yes" = "$do_ucx" ] ; then - check_submodule_presence modules/ucx - externals="${externals} modules/ucx" -fi - -if [ "yes" = "$do_ofi" ] ; then - check_submodule_presence modules/libfabric - externals="${externals} modules/libfabric" -fi - -if [ "yes" = "$do_json" ] ; then - check_submodule_presence "modules/json-c" - externals="${externals} modules/json-c" -fi - -if [ "yes" = "$do_yaksa" ] ; then - check_submodule_presence "modules/yaksa" - externals="${externals} modules/yaksa" -fi +set_externals ######################################################################## # This used to be an optionally installed hook to help with git-svn From 4ef8c92c1e7905411cad929debc42e89bd5f5977 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 25 Nov 2021 12:14:16 -0600 Subject: [PATCH 263/607] autogen: refactor fn_copy_confdb_etc --- autogen.sh | 167 ++++++++++++++++++++++++++--------------------------- 1 file changed, 82 insertions(+), 85 deletions(-) diff --git a/autogen.sh b/autogen.sh index 703abd81057..1c697ff4155 100755 --- a/autogen.sh +++ b/autogen.sh @@ -120,18 +120,6 @@ check_submodule_presence() { fi } -sync_external () { - srcdir=$1 - destdir=$2 - - echo "syncing '$srcdir' --> '$destdir'" - - # deletion prevents creating 'confdb/confdb' situation, also cleans - # stray files that may have crept in somehow - rm -rf "$destdir" - cp -pPR "$srcdir" "$destdir" -} - ######################################################################## ## prerequisite functions ######################################################################## @@ -273,6 +261,87 @@ set_PYTHON() { ## Step functions ######################################################################## +sync_external () { + srcdir=$1 + destdir=$2 + + echo "syncing '$srcdir' --> '$destdir'" + + # deletion prevents creating 'confdb/confdb' situation, also cleans + # stray files that may have crept in somehow + rm -rf "$destdir" + cp -pPR "$srcdir" "$destdir" +} + +fn_copy_confdb_etc() { + # This used to be an optionally installed hook to help with git-svn + # versions of the old SVN repo. Now that we are using git, this is our + # mechanism that replaces relative svn:externals paths, such as for + # "confdb" and "mpl". The basic plan is to delete the destdir and then + # copy all of the files, warts and all, from the source directory to the + # destination directory. + echo + echo "####################################" + echo "## Replicating confdb (and similar)" + echo "####################################" + echo + + confdb_dirs= + confdb_dirs="${confdb_dirs} src/mpl/confdb" + if test "$do_romio" = "yes" ; then + confdb_dirs="${confdb_dirs} src/mpi/romio/confdb" + if test "$do_quick" = "no" ; then + sync_external src/mpl src/mpi/romio/mpl + confdb_dirs="${confdb_dirs} src/mpi/romio/mpl/confdb" + fi + fi + if test "$do_hydra" = "yes" ; then + confdb_dirs="${confdb_dirs} src/pm/hydra/confdb" + if test "$do_quick" = "no" ; then + sync_external src/mpl src/pm/hydra/mpl + sync_external modules/hwloc src/pm/hydra/tools/topo/hwloc/hwloc + # remove .git directories to avoid confusing git clean + rm -rf src/pm/hydra/tools/topo/hwloc/hwloc/.git + confdb_dirs="${confdb_dirs} src/pm/hydra/mpl/confdb" + fi + fi + if test "$do_hydra2" = "yes" ; then + confdb_dirs="${confdb_dirs} src/pm/hydra2/confdb" + sync_external src/mpl src/pm/hydra2/mpl + sync_external modules/hwloc src/pm/hydra2/libhydra/topo/hwloc/hwloc + # remove .git directories to avoid confusing git clean + rm -rf src/pm/hydra2/libhydra/topo/hwloc/hwloc/.git + confdb_dirs="${confdb_dirs} src/pm/hydra2/mpl/confdb" + fi + if test "$do_test" = "yes" ; then + confdb_dirs="${confdb_dirs} test/mpi/confdb" + confdb_dirs="${confdb_dirs} test/mpi/dtpools/confdb" + fi + + # all the confdb directories, by various names + for destdir in $confdb_dirs ; do + sync_external confdb "$destdir" + done + + # a couple of other random files + if [ -f maint/version.m4 ] ; then + cp -pPR maint/version.m4 src/pm/hydra/version.m4 + cp -pPR maint/version.m4 src/pm/hydra2/version.m4 + cp -pPR maint/version.m4 src/mpi/romio/version.m4 + cp -pPR maint/version.m4 test/mpi/version.m4 + fi + + # Now sanity check that some of the above sync was successful + f="aclocal_cc.m4" + for d in $confdb_dirs ; do + if [ -f "$d/$f" ] ; then : + else + error "expected to find '$f' in '$d'" + exit 1 + fi + done +} + fn_maint_configure() { set_autotools echo @@ -942,79 +1011,7 @@ check_python3 set_externals ######################################################################## -# This used to be an optionally installed hook to help with git-svn -# versions of the old SVN repo. Now that we are using git, this is our -# mechanism that replaces relative svn:externals paths, such as for -# "confdb" and "mpl". The basic plan is to delete the destdir and then -# copy all of the files, warts and all, from the source directory to the -# destination directory. -echo -echo "####################################" -echo "## Replicating confdb (and similar)" -echo "####################################" -echo - -confdb_dirs= -confdb_dirs="${confdb_dirs} src/mpl/confdb" -if test "$do_romio" = "yes" ; then - confdb_dirs="${confdb_dirs} src/mpi/romio/confdb" - if test "$do_quick" = "no" ; then - sync_external src/mpl src/mpi/romio/mpl - confdb_dirs="${confdb_dirs} src/mpi/romio/mpl/confdb" - fi -fi -if test "$do_hydra" = "yes" ; then - confdb_dirs="${confdb_dirs} src/pm/hydra/confdb" - if test "$do_quick" = "no" ; then - sync_external src/mpl src/pm/hydra/mpl - sync_external modules/hwloc src/pm/hydra/tools/topo/hwloc/hwloc - # remove .git directories to avoid confusing git clean - rm -rf src/pm/hydra/tools/topo/hwloc/hwloc/.git - confdb_dirs="${confdb_dirs} src/pm/hydra/mpl/confdb" - fi -fi -if test "$do_hydra2" = "yes" ; then - confdb_dirs="${confdb_dirs} src/pm/hydra2/confdb" - sync_external src/mpl src/pm/hydra2/mpl - sync_external modules/hwloc src/pm/hydra2/libhydra/topo/hwloc/hwloc - # remove .git directories to avoid confusing git clean - rm -rf src/pm/hydra2/libhydra/topo/hwloc/hwloc/.git - confdb_dirs="${confdb_dirs} src/pm/hydra2/mpl/confdb" -fi -if test "$do_test" = "yes" ; then - confdb_dirs="${confdb_dirs} test/mpi/confdb" - confdb_dirs="${confdb_dirs} test/mpi/dtpools/confdb" -fi - -# all the confdb directories, by various names -for destdir in $confdb_dirs ; do - sync_external confdb "$destdir" -done - -# a couple of other random files -if [ -f maint/version.m4 ] ; then - cp -pPR maint/version.m4 src/pm/hydra/version.m4 - cp -pPR maint/version.m4 src/pm/hydra2/version.m4 - cp -pPR maint/version.m4 src/mpi/romio/version.m4 - cp -pPR maint/version.m4 test/mpi/version.m4 -fi - -# Now sanity check that some of the above sync was successful -f="aclocal_cc.m4" -for d in $confdb_dirs ; do - if [ -f "$d/$f" ] ; then : - else - error "expected to find '$f' in '$d'" - exit 1 - fi -done - -echo -echo -echo "###########################################################" -echo "## Autogenerating required files" -echo "###########################################################" -echo +fn_copy_confdb_etc ######################################################################## ## Building maint/Version From c8e80ad5d5ba3cee663af9d628801ddb18d8936c Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 25 Nov 2021 12:18:02 -0600 Subject: [PATCH 264/607] autogen: minor cleanup --- autogen.sh | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/autogen.sh b/autogen.sh index 1c697ff4155..8f58fb1faa3 100755 --- a/autogen.sh +++ b/autogen.sh @@ -44,7 +44,7 @@ echo "done" ######################################################################## # Default choices -do_bindings=yes # if no, skips patching libtool for Fortran +do_fortran=yes # if no, skips patching libtool for Fortran do_errmsgs=yes do_getcvars=yes do_f77=yes @@ -568,7 +568,7 @@ autoreconf_amdir() { _patch_libtool $_dir/confdb/ltmain.sh intel-compiler.patch _patch_libtool $_dir/confdb/libtool.m4 sys_lib_dlsearch_path_spec.patch _patch_libtool $_dir/confdb/libtool.m4 big-sur.patch - if test "$do_bindings" = "yes" ; then + if test "$do_fortran" = "yes" ; then _patch_libtool $_dir/confdb/libtool.m4 darwin-ifort.patch _patch_libtool $_dir/confdb/libtool.m4 oracle-fort.patch _patch_libtool $_dir/confdb/libtool.m4 flang.patch @@ -933,11 +933,10 @@ for arg in "$@" ; do var=do_$opt eval $var=no case "$opt" in - bindings) + fortran) do_f77=no do_f90=no do_f08=no - do_cxx=no ;; esac ;; @@ -947,8 +946,8 @@ for arg in "$@" ; do var=do_$opt eval $var=yes case "$opt" in - f77 | f90 | f08 | cxx) - do_bindings=yes + f77 | f90 | f08) + do_fortran=yes ;; esac ;; @@ -1000,16 +999,16 @@ done ######################################################################## fn_check_autotools - fn_check_bash_find_patch_xargs check_python3 - ######################################################################## ## Setup external packages ######################################################################## set_externals +######################################################################## +## duplicating confdb, mpl, version.m4 etc. ######################################################################## fn_copy_confdb_etc @@ -1070,8 +1069,6 @@ fi ######################################################################## ## Extract error messages ######################################################################## - -# Capture the error messages if [ $do_errmsgs = "yes" ] ; then fn_errmsgs fi @@ -1080,7 +1077,6 @@ fi ######################################################################## ## Build required scripts ######################################################################## - fn_maint_configure # new parameter code From 4fbb2e2336ad55e13ff0df17c9c194893612a947 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 22 Dec 2021 17:21:15 -0600 Subject: [PATCH 265/607] configure: FIX - source mpl/localdefs in PAC_CONFIG_MPL MPL may set additional CPPFLAGS and other variables that need be sourced into the caller configure script. Now that romio also calls PAC_CONFIG_MPL, we need make sure it doesn't link libmpl.la again since mpich already links it. --- confdb/aclocal_modules.m4 | 8 +++++++- src/mpi/romio/configure.ac | 5 +++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/confdb/aclocal_modules.m4 b/confdb/aclocal_modules.m4 index acae7a09453..d198051a71f 100644 --- a/confdb/aclocal_modules.m4 +++ b/confdb/aclocal_modules.m4 @@ -23,8 +23,14 @@ AC_DEFUN([PAC_CONFIG_MPL],[ ], [ dnl ---- sub-configure (e.g. hydra, romio) ---- if test "$FROM_MPICH" = "yes"; then - mpl_lib="$main_top_builddir/src/mpl/libmpl.la" + dnl skip ROMIO since mpich already links libmpl.la + m4_if(AC_PACKAGE_NAME, [ROMIO], [], [ + mpl_lib="$main_top_builddir/src/mpl/libmpl.la" + ]) mpl_includedir="-I$main_top_builddir/src/mpl/include -I$main_top_srcdir/src/mpl/include" + # source variables that are configured by MPL + AC_MSG_NOTICE([sourcing $main_top_srcdir/src/mpl/localdefs]) + . $main_top_builddir/src/mpl/localdefs else PAC_CONFIG_MPL_EMBEDDED mpl_srcdir="mpl_embedded_dir" diff --git a/src/mpi/romio/configure.ac b/src/mpi/romio/configure.ac index 2e81f43387f..03ece3c869d 100644 --- a/src/mpi/romio/configure.ac +++ b/src/mpi/romio/configure.ac @@ -148,8 +148,9 @@ else mpl_lib="-l${MPLLIBNAME}" fi else - # we are configuring romio inside mpich, just set mpl_includedir - mpl_includedir="-I$main_top_builddir/src/mpl/include -I$main_top_srcdir/src/mpl/include" + # we are configuring romio inside mpich. MPICH should configured MPL already, following + # macro will just set mpl_includedir and source mpl/localdefs if any. + PAC_CONFIG_MPL fi CFLAGS=${CFLAGS:-""} From 49b3bf44df9eeff944c808734f83a04a3d7c2c48 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 22 Dec 2021 17:25:02 -0600 Subject: [PATCH 266/607] romio/config: indentation fix Whitespace change for better readability. --- src/mpi/romio/configure.ac | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/mpi/romio/configure.ac b/src/mpi/romio/configure.ac index 03ece3c869d..1202458c479 100644 --- a/src/mpi/romio/configure.ac +++ b/src/mpi/romio/configure.ac @@ -131,22 +131,22 @@ AC_SUBST([mpl_libdir]) mpl_lib="" AC_SUBST([mpl_lib]) if test "$FROM_MPICH" = "no" ; then -if test "$with_mpl_prefix" = "embedded" ; then - mpl_srcdir="mpl" - mpl_dist_srcdir="mpl" - mpl_subdir_args="--disable-versioning --enable-embedded" - PAC_CONFIG_SUBDIR_ARGS([mpl],[$mpl_subdir_args],[],[AC_MSG_ERROR(MPL configure failed)]) - mpl_includedir='-I$(top_builddir)/mpl/include -I$(top_srcdir)/mpl/include' - mpl_lib="mpl/lib${MPLLIBNAME}.la" -else - # The user specified an already-installed MPL; just sanity check, don't - # subconfigure it - AS_IF([test -s "${with_mpl_prefix}/include/mplconfig.h"], - [:],[AC_MSG_ERROR([the MPL installation in "${with_mpl_prefix}" appears broken])]) - mpl_includedir="-I${with_mpl_prefix}/include" - mpl_libdir="-L${with_mpl_prefix}/lib" - mpl_lib="-l${MPLLIBNAME}" -fi + if test "$with_mpl_prefix" = "embedded" ; then + mpl_srcdir="mpl" + mpl_dist_srcdir="mpl" + mpl_subdir_args="--disable-versioning --enable-embedded" + PAC_CONFIG_SUBDIR_ARGS([mpl],[$mpl_subdir_args],[],[AC_MSG_ERROR(MPL configure failed)]) + mpl_includedir='-I$(top_builddir)/mpl/include -I$(top_srcdir)/mpl/include' + mpl_lib="mpl/lib${MPLLIBNAME}.la" + else + # The user specified an already-installed MPL; just sanity check, don't + # subconfigure it + AS_IF([test -s "${with_mpl_prefix}/include/mplconfig.h"], + [:],[AC_MSG_ERROR([the MPL installation in "${with_mpl_prefix}" appears broken])]) + mpl_includedir="-I${with_mpl_prefix}/include" + mpl_libdir="-L${with_mpl_prefix}/lib" + mpl_lib="-l${MPLLIBNAME}" + fi else # we are configuring romio inside mpich. MPICH should configured MPL already, following # macro will just set mpl_includedir and source mpl/localdefs if any. From 739b165fb60090efe1c3b632eb1261e3b7c7a41a Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Mon, 8 Nov 2021 14:53:41 -0600 Subject: [PATCH 267/607] test/mpi: Remove unnecessary AC_PROG_RANLIB Since we use libtool in the testsuite, autoreconf throws a warning: AC_PROG_RANLIB' is rendered obsolete by LT_INIT --- test/mpi/configure.ac | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index 7c9df2b0052..69c9a526ccb 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -618,9 +618,8 @@ fi AC_C_CONST AC_C_RESTRICT -# not using libtool for the test suite, so no LT_INIT. Instead, test here -# for Library programs -AC_PROG_RANLIB + +# Archiver for building utility libraries AM_PROG_AR # Check for --enable-strict From 7e08f9a6022f3cd6c2899fcabadd9228c8c1cf2d Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Mon, 8 Nov 2021 15:45:36 -0600 Subject: [PATCH 268/607] mtest: Convert utilities to libtool convenience libraries MTest utilities were built and linked with a complex set of rules that basically amounted to libtool convenience libraries. Now that we use libtool in the testsuite, convert them to simplify the process. --- test/mpi/Makefile_common.mtest | 8 +---- test/mpi/Makefile_cxx.mtest | 9 ++---- test/mpi/Makefile_f08.mtest | 14 ++++----- test/mpi/Makefile_f77.mtest | 14 ++++----- test/mpi/Makefile_f90.mtest | 14 ++++----- test/mpi/Makefile_single.mtest | 6 ++-- test/mpi/Makefile_threads.mtest | 6 ++-- test/mpi/datatype/Makefile.am | 4 ++- test/mpi/util/Makefile.am | 54 ++++++++++++++------------------- 9 files changed, 54 insertions(+), 75 deletions(-) diff --git a/test/mpi/Makefile_common.mtest b/test/mpi/Makefile_common.mtest index beec5466241..51cb34d1188 100644 --- a/test/mpi/Makefile_common.mtest +++ b/test/mpi/Makefile_common.mtest @@ -14,18 +14,12 @@ # AM_CPPFLAGS are used for C++ code as well AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include @cuda_CPPFLAGS@ @ze_CPPFLAGS@ @hip_CPPFLAGS@ AM_LDFLAGS = @cuda_LDFLAGS@ @ze_LDFLAGS@ @hip_LDFLAGS@ -LDADD = $(top_builddir)/util/mtest.$(OBJEXT) $(top_builddir)/util/mtest_common.$(OBJEXT) @cuda_LIBS@ @ze_LIBS@ @hip_LIBS@ +LDADD = @cuda_LIBS@ @ze_LIBS@ @hip_LIBS@ # Add libdtpools support AM_CPPFLAGS += -I$(top_srcdir)/dtpools/include LDADD += $(top_builddir)/dtpools/src/libdtpools.la -$(top_builddir)/util/mtest.$(OBJEXT): $(top_srcdir)/util/mtest.c - (cd $(top_builddir)/util && $(MAKE) mtest.$(OBJEXT)) - -$(top_builddir)/util/mtest_common.$(OBJEXT): $(top_srcdir)/util/mtest_common.c - (cd $(top_builddir)/util && $(MAKE) mtest_common.$(OBJEXT)) - $(top_builddir)/dtpools/src/libdtpools.la: (cd $(top_builddir)/dtpools && $(MAKE)) diff --git a/test/mpi/Makefile_cxx.mtest b/test/mpi/Makefile_cxx.mtest index 61a64ccaae4..20f0d6a6ddb 100644 --- a/test/mpi/Makefile_cxx.mtest +++ b/test/mpi/Makefile_cxx.mtest @@ -11,17 +11,14 @@ AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include @cuda_CPPFLAGS@ @ze_CPPFLAGS@ @hip_CPPFLAGS@ AM_LDFLAGS = @cuda_LDFLAGS@ @ze_LDFLAGS@ @hip_LDFLAGS@ -LDADD = $(top_builddir)/util/mtest_cxx.$(OBJEXT) $(top_builddir)/util/mtest_common.$(OBJEXT) @cuda_LIBS@ @ze_LIBS@ @hip_LIBS@ +LDADD = $(top_builddir)/util/libmtest_cxx.la @cuda_LIBS@ @ze_LIBS@ @hip_LIBS@ # Add libdtpools support AM_CPPFLAGS += -I$(top_srcdir)/dtpools/include LDADD += $(top_builddir)/dtpools/src/.libs/libdtpools.la -$(top_builddir)/util/mtest_cxx.$(OBJEXT): $(top_srcdir)/util/mtest_cxx.cxx - (cd $(top_builddir)/util && $(MAKE) mtest_cxx.$(OBJEXT)) - -$(top_builddir)/util/mtest_common.$(OBJEXT): $(top_srcdir)/util/mtest_common.c - (cd $(top_builddir)/util && $(MAKE) mtest_common.$(OBJEXT)) +$(top_builddir)/util/libmtest_cxx.la: + (cd $(top_builddir)/util && $(MAKE) libmtest_cxx.la) $(top_builddir)/dtpools/src/.libs/libdtpools.la: (cd $(top_builddir)/dtpools && $(MAKE)) diff --git a/test/mpi/Makefile_f08.mtest b/test/mpi/Makefile_f08.mtest index 47eb163faca..d5358d221d9 100644 --- a/test/mpi/Makefile_f08.mtest +++ b/test/mpi/Makefile_f08.mtest @@ -7,19 +7,17 @@ # F08 code itself AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include @cuda_CPPFLAGS@ @ze_CPPFLAGS@ @hip_CPPFLAGS@ -LDADD = $(top_builddir)/util/mtest_f08.$(OBJEXT) -mtest_c_objects = $(top_builddir)/util/mtest.$(OBJEXT) $(top_builddir)/util/mtest_single.$(OBJEXT) $(top_builddir)/util/mtest_common.$(OBJEXT) +LDADD = $(top_builddir)/util/libmtest_f08.la +mtest_c_objects = $(top_builddir)/util/libmtest_single.la # This is right for many platforms, but not all. The right fix involves a # configure test, but this version is no worse than the simplemake version was. AM_FFLAGS = -I. -$(top_builddir)/util/mtest_f08.$(OBJEXT): $(top_srcdir)/util/mtest_f08.f90 - (cd $(top_builddir)/util && $(MAKE) mtest_f08.$(OBJEXT)) -$(top_builddir)/util/mtest.$(OBJEXT): $(top_srcdir)/util/mtest.c - (cd $(top_builddir)/util && $(MAKE) mtest.$(OBJEXT)) -$(top_builddir)/util/mtest_single.$(OBJEXT): $(top_srcdir)/util/mtest_single.c - (cd $(top_builddir)/util && $(MAKE) mtest_single.$(OBJEXT)) +$(top_builddir)/util/libmtest_f08.la: + (cd $(top_builddir)/util && $(MAKE) libmtest_f08.la) +$(top_builddir)/util/libmtest_single.la: + (cd $(top_builddir)/util && $(MAKE) libmtest_single.la) testing: $(top_builddir)/runtests -srcdir=$(srcdir) -tests=testlist \ diff --git a/test/mpi/Makefile_f77.mtest b/test/mpi/Makefile_f77.mtest index ac6c9952c35..da9bef9a2c7 100644 --- a/test/mpi/Makefile_f77.mtest +++ b/test/mpi/Makefile_f77.mtest @@ -17,20 +17,18 @@ AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include @cuda_CPPFLAGS@ # configure test, but this version is no worse than the simplemake version was. AM_FFLAGS = -I. -LDADD = $(top_builddir)/util/mtest_f77.$(OBJEXT) -mtest_c_objects = $(top_builddir)/util/mtest.$(OBJEXT) $(top_builddir)/util/mtest_single.$(OBJEXT) $(top_builddir)/util/mtest_common.$(OBJEXT) +LDADD = $(top_builddir)/util/libmtest_f77.la +mtest_c_objects = $(top_builddir)/util/libmtest_single.la ## FIXME "DEPADD" is a simplemake concept, which we can handle on a per-target ## prog_DEPENDENCIES variable, but it would be better to figure out the right ## way to do this ##DEPADD = @MPILIBLOC@ ../util/mtest.$(OBJEXT) -$(top_builddir)/util/mtest_f77.$(OBJEXT): $(top_srcdir)/util/mtest_f77.f - (cd $(top_builddir)/util && $(MAKE) mtest_f77.$(OBJEXT)) -$(top_builddir)/util/mtest.$(OBJEXT): $(top_srcdir)/util/mtest.c - (cd $(top_builddir)/util && $(MAKE) mtest.$(OBJEXT)) -$(top_builddir)/util/mtest_single.$(OBJEXT): $(top_srcdir)/util/mtest_single.c - (cd $(top_builddir)/util && $(MAKE) mtest_single.$(OBJEXT)) +$(top_builddir)/util/libmtest_f77.la: + (cd $(top_builddir)/util && $(MAKE) libmtest_f77.la) +$(top_builddir)/util/libmtest_single.la: + (cd $(top_builddir)/util && $(MAKE) libmtest_single.la) testing: $(top_builddir)/runtests -srcdir=$(srcdir) -tests=testlist \ diff --git a/test/mpi/Makefile_f90.mtest b/test/mpi/Makefile_f90.mtest index ed37dbdf0f4..5a8b426d26c 100644 --- a/test/mpi/Makefile_f90.mtest +++ b/test/mpi/Makefile_f90.mtest @@ -7,19 +7,17 @@ # F90 code itself AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include @cuda_CPPFLAGS@ @ze_CPPFLAGS@ @hip_CPPFLAGS@ -LDADD = $(top_builddir)/util/mtest_f90.$(OBJEXT) -mtest_c_objects = $(top_builddir)/util/mtest.$(OBJEXT) $(top_builddir)/util/mtest_single.$(OBJEXT) $(top_builddir)/util/mtest_common.$(OBJEXT) +LDADD = $(top_builddir)/util/libmtest_f90.la +mtest_c_objects = $(top_builddir)/util/libmtest_single.la # This is right for many platforms, but not all. The right fix involves a # configure test, but this version is no worse than the simplemake version was. AM_FFLAGS = -I. -$(top_builddir)/util/mtest_f90.$(OBJEXT): $(top_srcdir)/util/mtest_f90.f90 - (cd $(top_builddir)/util && $(MAKE) mtest_f90.$(OBJEXT)) -$(top_builddir)/util/mtest.$(OBJEXT): $(top_srcdir)/util/mtest.c - (cd $(top_builddir)/util && $(MAKE) mtest.$(OBJEXT)) -$(top_builddir)/util/mtest_single.$(OBJEXT): $(top_srcdir)/util/mtest_single.c - (cd $(top_builddir)/util && $(MAKE) mtest_single.$(OBJEXT)) +$(top_builddir)/util/libmtest_f90.la: + (cd $(top_builddir)/util && $(MAKE) libmtest_f90.la) +$(top_builddir)/util/libmtest_single.la: + (cd $(top_builddir)/util && $(MAKE) libmtest_single.la) testing: $(top_builddir)/runtests -srcdir=$(srcdir) -tests=testlist \ diff --git a/test/mpi/Makefile_single.mtest b/test/mpi/Makefile_single.mtest index 4fc6bf1d870..543b1d483bb 100644 --- a/test/mpi/Makefile_single.mtest +++ b/test/mpi/Makefile_single.mtest @@ -12,7 +12,7 @@ include $(top_srcdir)/Makefile_common.mtest ## then add rules/vars for mtest_single.o -LDADD += $(top_builddir)/util/mtest_single.$(OBJEXT) +LDADD += $(top_builddir)/util/libmtest_single.la -$(top_builddir)/util/mtest_single.$(OBJEXT): $(top_srcdir)/util/mtest_single.c - (cd $(top_builddir)/util && $(MAKE) mtest_single.$(OBJEXT)) +$(top_builddir)/util/libmtest_single.la: + (cd $(top_builddir)/util && $(MAKE) libmtest_single.la) diff --git a/test/mpi/Makefile_threads.mtest b/test/mpi/Makefile_threads.mtest index a273a4b4478..4a5dfb9a45b 100644 --- a/test/mpi/Makefile_threads.mtest +++ b/test/mpi/Makefile_threads.mtest @@ -14,7 +14,7 @@ include $(top_srcdir)/Makefile_common.mtest AM_CPPFLAGS += -DMTEST_USE_THREAD ## then add rules/vars for mtest_thread.o -LDADD += $(top_builddir)/util/mtest_thread.$(OBJEXT) @threadlib@ +LDADD += $(top_builddir)/util/libmtest_thread.la @threadlib@ -$(top_builddir)/util/mtest_thread.$(OBJEXT): $(top_srcdir)/util/mtest_thread.c - (cd $(top_builddir)/util && $(MAKE) mtest_thread.$(OBJEXT)) +$(top_builddir)/util/libmtest_thread.la: + (cd $(top_builddir)/util && $(MAKE) libmtest_thread.la) diff --git a/test/mpi/datatype/Makefile.am b/test/mpi/datatype/Makefile.am index 3d1fea92355..4f4557f4047 100644 --- a/test/mpi/datatype/Makefile.am +++ b/test/mpi/datatype/Makefile.am @@ -88,7 +88,9 @@ noinst_PROGRAMS = \ # Some of the tests use a more comprehensive set of datatype tests. # These must specify a different LDADD that includes the object file # with these additional routines -LDADDDATA = $(top_builddir)/util/dtypes.$(OBJEXT) +LDADDDATA = $(top_builddir)/util/libdtypes.la +$(top_builddir)/util/libdtypes.la: + (cd $(top_builddir)/util && $(MAKE)) sendrecvt2_LDADD = $(LDADD) $(LDADDDATA) sendrecvt4_LDADD = $(LDADD) $(LDADDDATA) diff --git a/test/mpi/util/Makefile.am b/test/mpi/util/Makefile.am index 8cb08216c95..47e5b056983 100644 --- a/test/mpi/util/Makefile.am +++ b/test/mpi/util/Makefile.am @@ -5,60 +5,52 @@ AM_CPPFLAGS = -I$(srcdir)/../include -I../include -I$(srcdir)/../dtpools/include @cuda_CPPFLAGS@ @ze_CPPFLAGS@ @hip_CPPFLAGS@ -EXTRA_PROGRAMS = mtestcheck dtypes -mtestcheck_SOURCES = mtestcheck.c mtest.c mtest_common.c +noinst_LTLIBRARIES = libmtest.la +libmtest_la_SOURCES = mtest.c mtest_common.c -EXTRA_LIBRARIES = -all_objs = mtest.$(OBJEXT) dtypes.$(OBJEXT) +noinst_LTLIBRARIES += libdtypes.la +libdtypes_la_SOURCES = dtypes.c #---- CXX --------------------------------------------------------------------- if HAS_CXX -all_objs += mtest_cxx.$(OBJEXT) - ## list a dummy library that we don't actually build in order to cause automake ## to emit a rule for building mtest_cxx.o from mtest_cxx.cxx -EXTRA_LIBRARIES += libmtest_cxx.a -libmtest_cxx_a_SOURCES = mtest_cxx.cxx +noinst_LTLIBRARIES += libmtest_cxx.la +libmtest_cxx_la_SOURCES = mtest_cxx.cxx mtest_common.c endif #---- F77 --------------------------------------------------------------------- if HAS_F77 -all_objs += mtest_f77.$(OBJEXT) +noinst_LTLIBRARIES += libmtest_f77.la +libmtest_f77_la_SOURCES = mtest_f77.f + +endif -## another dummy library -EXTRA_LIBRARIES += libmtest_f77.a -libmtest_f77_a_SOURCES = mtest_f77.f +#---- F90 --------------------------------------------------------------------- +if HAS_F90 + +noinst_LTLIBRARIES += libmtest_f90.la +libmtest_f90_la_SOURCES = mtest_f90.f90 endif #---- F08 --------------------------------------------------------------------- if HAS_F08 -all_objs += mtest_f08.$(OBJEXT) - -## another dummy library -EXTRA_LIBRARIES += libmtest_f08.a -libmtest_f08_a_SOURCES = mtest_f08.f90 +noinst_LTLIBRARIES += libmtest_f08.la +libmtest_f08_la_SOURCES = mtest_f08.f90 endif #---- single --------------------------------------------------------------------- -all_objs += mtest_single.$(OBJEXT) - -## another dummy library -EXTRA_LIBRARIES += libmtest_single.a -libmtest_single_a_SOURCES = mtest_single.c +noinst_LTLIBRARIES += libmtest_single.la +libmtest_single_la_SOURCES = mtest_single.c +libmtest_single_la_LIBADD = libmtest.la #---- thread --------------------------------------------------------------------- -all_objs += mtest_thread.$(OBJEXT) - -## another dummy library -EXTRA_LIBRARIES += libmtest_thread.a -libmtest_thread_a_SOURCES = mtest_thread.c - -#---- all-local target ----------------------------------------------------------- - -all-local: $(all_objs) +noinst_LTLIBRARIES += libmtest_thread.la +libmtest_thread_la_SOURCES = mtest_thread.c +libmtest_thread_la_LIBADD = libmtest.la From e09fc1136f58bec91ceff9870ffecde828c42f8d Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Wed, 24 Nov 2021 10:30:31 -0600 Subject: [PATCH 269/607] mtest: Delete outdated FIXME comment --- test/mpi/Makefile_f77.mtest | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/mpi/Makefile_f77.mtest b/test/mpi/Makefile_f77.mtest index da9bef9a2c7..71aa172a350 100644 --- a/test/mpi/Makefile_f77.mtest +++ b/test/mpi/Makefile_f77.mtest @@ -20,11 +20,6 @@ AM_FFLAGS = -I. LDADD = $(top_builddir)/util/libmtest_f77.la mtest_c_objects = $(top_builddir)/util/libmtest_single.la -## FIXME "DEPADD" is a simplemake concept, which we can handle on a per-target -## prog_DEPENDENCIES variable, but it would be better to figure out the right -## way to do this -##DEPADD = @MPILIBLOC@ ../util/mtest.$(OBJEXT) - $(top_builddir)/util/libmtest_f77.la: (cd $(top_builddir)/util && $(MAKE) libmtest_f77.la) $(top_builddir)/util/libmtest_single.la: From 2afa90cda9196c3d1164dc10203e65f17049e57a Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Wed, 24 Nov 2021 10:49:58 -0600 Subject: [PATCH 270/607] mtest: Remove unused mtestcheck.c --- test/mpi/util/mtestcheck.c | 43 -------------------------------------- 1 file changed, 43 deletions(-) delete mode 100644 test/mpi/util/mtestcheck.c diff --git a/test/mpi/util/mtestcheck.c b/test/mpi/util/mtestcheck.c deleted file mode 100644 index a1494613a38..00000000000 --- a/test/mpi/util/mtestcheck.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) by Argonne National Laboratory - * See COPYRIGHT in top-level directory - */ - -#include "mpi.h" -#include -#include -#include "mpitest.h" - -int main(int argc, char *argv[]) -{ - int errs = 0; - MPI_Comm comm; - int minsize = 2, csize, count; - - MTest_Init(&argc, &argv); - - while (MTestGetIntracommGeneral(&comm, minsize, 1)) { - if (comm == MPI_COMM_NULL) - continue; - - MPI_Comm_size(comm, &csize); - count = 128000; - { - int *ap, *bp; - int root; - ap = (int *) malloc(count * sizeof(int)); - bp = (int *) malloc(count * sizeof(int)); - root = 0; - MPI_Reduce(ap, bp, count, MPI_INT, MPI_SUM, root, comm); - free(ap); - free(bp); - } - MTestFreeComm(&comm); - } - - MTest_Finalize(errs); - - MPI_Finalize(); - - return 0; -} From a338d6a29d2b6febd9fee8ee35d3e0b3bb83f6db Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 27 Dec 2021 09:04:29 -0600 Subject: [PATCH 271/607] typerep/yaksa: fix use of builtin_element_size If the datatype is from a flatted type, builtin_element_size can be garbage because the field is not copied in struct flatten_hdr. Obtain the builtin_element_size from basic_type instead. --- src/mpi/datatype/typerep/src/typerep_yaksa_pack.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c b/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c index cc47b1affbb..c0d3cdb992d 100644 --- a/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c +++ b/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c @@ -142,7 +142,10 @@ static int typerep_do_pack(const void *inbuf, MPI_Aint incount, MPI_Datatype dat MPIR_Datatype *dtp; MPIR_Datatype_get_ptr(datatype, dtp); is_contig = dtp->is_contig; - element_size = dtp->builtin_element_size; + /* NOTE: dtp->element_size may not be set if dtp is from a flattened type */ + if (dtp->basic_type != MPI_DATATYPE_NULL) { + element_size = MPIR_Datatype_get_basic_size(datatype); + } inbuf_ptr = MPIR_get_contig_ptr(inbuf, dtp->true_lb); total_size = incount * dtp->size; } From 84902a51df5330d979668900e9f3ab7b567cfe1b Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 27 Dec 2021 09:19:56 -0600 Subject: [PATCH 272/607] ch4/rma: add assertion in handle_get_acc_cmpl Add an assertion to check actual_pack_bytes from MPIR_Typerep_pack to catch potential errors. --- src/mpid/ch4/src/mpidig_rma_callbacks.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mpid/ch4/src/mpidig_rma_callbacks.c b/src/mpid/ch4/src/mpidig_rma_callbacks.c index 2d6efaddf9b..86dc8ef4432 100644 --- a/src/mpid/ch4/src/mpidig_rma_callbacks.c +++ b/src/mpid/ch4/src/mpidig_rma_callbacks.c @@ -806,6 +806,7 @@ static int handle_get_acc_cmpl(MPIR_Request * rreq) req-> areq.target_datatype), 0, original, result_data_sz, &actual_pack_bytes); + MPIR_Assert(actual_pack_bytes == result_data_sz); mpi_errno = MPIDIG_compute_acc_op(MPIDIG_REQUEST(rreq, req->areq.data), MPIDIG_REQUEST(rreq, req->areq.origin_count), From 936603eb86c79d5203d167844ec0896c46c83f9b Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 5 Jan 2022 15:01:58 -0600 Subject: [PATCH 273/607] python: load_mpix_txt to use correct path With vpath build, we need look in srcdir to find mpix.txt. --- maint/local_python/mpi_api.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/maint/local_python/mpi_api.py b/maint/local_python/mpi_api.py index b1b05f03d71..3c5a3ef8d49 100644 --- a/maint/local_python/mpi_api.py +++ b/maint/local_python/mpi_api.py @@ -51,7 +51,7 @@ def load_C_func_list(binding_dir="src/binding", silent=False): func_list.append(f) func_list.sort(key = lambda f: f['dir']) - load_mpix_txt() + load_mpix_txt("%s/mpix.txt" % binding_dir) return func_list @@ -93,11 +93,11 @@ def load_mpi_mapping(api_mapping_txt): key, val = RE.m.group(1, 2) G.default_descriptions[key] = val -def load_mpix_txt(): +def load_mpix_txt(mpix_txt): G.mpix_symbols = {} stage = "functions" - if os.path.exists("src/binding/mpix.txt"): - with open("src/binding/mpix.txt") as In: + if os.path.exists(mpix_txt): + with open(mpix_txt, "r") as In: for line in In: if RE.match(r'#\s*mpi.h\s+symbols', line): stage = "symbols" From 3063cf7e02c9c7761aae8e40742b16a26d06a7fc Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 6 Jan 2022 10:52:03 -0600 Subject: [PATCH 274/607] romio/test: fix resource in error return When we abort the test we need make sure to close the file handle, delete the temp file, and call MPI_Finalize. --- src/mpi/romio/test/external32.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/mpi/romio/test/external32.c b/src/mpi/romio/test/external32.c index 84b1a67e6d8..6f7ffb589de 100644 --- a/src/mpi/romio/test/external32.c +++ b/src/mpi/romio/test/external32.c @@ -6,6 +6,7 @@ #include #include #include "mpi.h" +#include #define TEST_LE 0x1 #define TEST_BE 0x2 @@ -23,10 +24,22 @@ static void handle_error(int errcode, char *str) } - -static void is_little_or_big_endian(const char *datarep, char *c, char *c_le, int len) +#define MAX_LEN 4 +static void is_little_or_big_endian(FILE * fileh_std, const char *datarep, char *c_le, int len) { - int i, is_le = 1, is_be = 1; + int i, j, is_le = 1, is_be = 1; + char c[MAX_LEN]; + + assert(len <= MAX_LEN); + + for (j = 0; j < len; j++) { + if (feof(fileh_std)) { + printf("unexpected eof, aborted\n"); + return; + } + fscanf(fileh_std, "%c", &c[j]); + } + for (i = 0; i < len; i++) { is_le = is_le && (c[i] == c_le[i]); is_be = is_be && (c[i] == c_le[len - 1 - i]); @@ -52,7 +65,7 @@ static void is_little_or_big_endian(const char *datarep, char *c, char *c_le, in int main(int argc, char *argv[]) { int sample_i = 123456789, i, j; - char sample_i_le[4] = { 0x15, 0xcd, 0x5b, 0x07 }, c[4]; + char sample_i_le[4] = { 0x15, 0xcd, 0x5b, 0x07 }; const char *datarep[3] = { "native", "external32", "internal" }; MPI_File fileh; int rank; @@ -87,14 +100,7 @@ int main(int argc, char *argv[]) MPI_Barrier(MPI_COMM_WORLD); if (rank == 0) { fileh_std = fopen(TEST_FILENAME, "r"); - for (j = 0; j < 4; j++) { - if (feof(fileh_std)) { - printf("unexpected eof, aborted\n"); - return (-1); - } - fscanf(fileh_std, "%c", &c[j]); - } - is_little_or_big_endian(datarep[i], c, sample_i_le, 4); + is_little_or_big_endian(fileh_std, datarep[i], sample_i_le, 4); fclose(fileh_std); } From a047227380575b99aee153c95525e70467263339 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 6 Jan 2022 10:59:52 -0600 Subject: [PATCH 275/607] pm: fix resource leak in MPIE_ReadMachines Make sure we free the memory and close the file on errors. --- src/pm/util/rm.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/pm/util/rm.c b/src/pm/util/rm.c index fb3dacd67bb..6d5190cad0d 100644 --- a/src/pm/util/rm.c +++ b/src/pm/util/rm.c @@ -208,7 +208,7 @@ MachineTable *MPIE_ReadMachines(const char *arch, int nNeeded, void *data) char machinesfile[PATH_MAX]; char dirname[PATH_MAX]; const char *path = getenv("MPIEXEC_MACHINES_PATH"); - MachineTable *mt; + MachineTable *mt = NULL; size_t len; int nFound = 0; @@ -253,19 +253,19 @@ MachineTable *MPIE_ReadMachines(const char *arch, int nNeeded, void *data) if (!fp) { MPL_error_printf("Could not open machines file %s\n", machinesfile); - return 0; + goto fn_fail; } mt = (MachineTable *) MPL_malloc(sizeof(MachineTable), MPL_MEM_PM); if (!mt) { MPL_internal_error_printf("Could not allocate machine table\n"); - return 0; + goto fn_fail; } /* This may be larger than needed if the machines file has * fewer entries than nNeeded */ mt->desc = (MachineDesc *) MPL_malloc(nNeeded * sizeof(MachineDesc), MPL_MEM_PM); if (!mt->desc) { - return 0; + goto fn_fail; } /* Order of fields @@ -374,7 +374,20 @@ MachineTable *MPIE_ReadMachines(const char *arch, int nNeeded, void *data) nNeeded--; } mt->nHosts = nFound; + + fn_exit: + fclose(fp); return mt; + + fn_fail: + if (mt) { + if (mt->desc) { + MPL_free(mt->desc); + } + MPL_free(mt); + mt = NULL; + } + goto fn_exit; } int MPIE_RMProcessArg(int argc, char *argv[], void *extra) From 7c1c31201083bfdd668fbeb8ec50c706c662e4ad Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Thu, 6 Jan 2022 10:03:47 -0600 Subject: [PATCH 276/607] ch4/ofi: Handle multiple buffered cq entries at a time Return as many buffered cq entries as possible in a single call to MPIDI_OFI_get_buffered, rather than doing them one by one. --- src/mpid/ch4/netmod/ofi/ofi_impl.h | 14 ++++++++------ src/mpid/ch4/netmod/ofi/ofi_progress.h | 4 ++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_impl.h b/src/mpid/ch4/netmod/ofi/ofi_impl.h index f2bd05dfb06..daa4e10ffe9 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_impl.h +++ b/src/mpid/ch4/netmod/ofi/ofi_impl.h @@ -706,26 +706,28 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_progress_do_queue(int vni) MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_buffered(int vni, struct fi_cq_tagged_entry *wc) { - int rc = 0; + int num = 0; - if (1) { + while (num < MPIDI_OFI_NUM_CQ_ENTRIES) { /* If the static list isn't empty, do so first */ if (CQ_S_HEAD != CQ_S_TAIL) { - wc[0] = CQ_S_LIST[CQ_S_TAIL]; + wc[num] = CQ_S_LIST[CQ_S_TAIL]; CQ_S_TAIL = (CQ_S_TAIL + 1) % MPIDI_OFI_NUM_CQ_BUFFERED; } /* If there's anything in the dynamic list, it goes second. */ else if (CQ_D_HEAD != NULL) { MPIDI_OFI_cq_list_t *cq_list_entry = CQ_D_HEAD; LL_DELETE(CQ_D_HEAD, CQ_D_TAIL, cq_list_entry); - wc[0] = cq_list_entry->cq_entry; + wc[num] = cq_list_entry->cq_entry; MPL_free(cq_list_entry); + } else { + break; } - rc = 1; + num++; } - return rc; + return num; } #undef CQ_S_LIST diff --git a/src/mpid/ch4/netmod/ofi/ofi_progress.h b/src/mpid/ch4/netmod/ofi/ofi_progress.h index 8326e07c0b2..ea819c5338c 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_progress.h +++ b/src/mpid/ch4/netmod/ofi/ofi_progress.h @@ -87,8 +87,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_NM_progress(int vci, int blocking) } if (unlikely(MPIDI_OFI_has_cq_buffered(vni))) { - ret = MPIDI_OFI_get_buffered(vni, wc); - mpi_errno = MPIDI_OFI_handle_cq_entries(vni, wc, 1); + int num = MPIDI_OFI_get_buffered(vni, wc); + mpi_errno = MPIDI_OFI_handle_cq_entries(vni, wc, num); } else if (likely(1)) { for (int nic = 0; nic < MPIDI_OFI_global.num_nics; nic++) { int ctx_idx = MPIDI_OFI_get_ctx_index(NULL, vni, nic); From e5308fdff1b8d9c396371a887d48508ff89971cf Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 6 Jan 2022 09:56:21 -0600 Subject: [PATCH 277/607] ch4: move declaration of cellsize for readability --- src/mpid/ch4/shm/posix/posix_coll_release_gather.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mpid/ch4/shm/posix/posix_coll_release_gather.h b/src/mpid/ch4/shm/posix/posix_coll_release_gather.h index fc6e92af33c..cb03bf67dd6 100644 --- a/src/mpid/ch4/shm/posix/posix_coll_release_gather.h +++ b/src/mpid/ch4/shm/posix/posix_coll_release_gather.h @@ -53,7 +53,6 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_mpi_bcast_release_gather(void *buffer, MPI_Aint lb, true_lb, true_extent, extent, type_size; void *ori_buffer = buffer; MPI_Datatype ori_datatype = datatype; - int cellsize = MPIDI_POSIX_RELEASE_GATHER_BCAST_CELLSIZE; /* If there is only one process or no data, return */ if (count == 0 || (MPIR_Comm_size(comm_ptr) == 1)) { @@ -105,6 +104,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_mpi_bcast_release_gather(void *buffer, } } } + + int cellsize = MPIDI_POSIX_RELEASE_GATHER_BCAST_CELLSIZE; #ifdef HAVE_ERROR_CHECKING /* When error checking is enabled, only (cellsize-(2*cacheline_size)) bytes are reserved for data. * Initial 2 cacheline_size bytes are reserved to put the amount of data being placed and the From ca3dae50c27942f9a23a69c3c948ee37295b89b5 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 22 Dec 2021 23:44:03 -0600 Subject: [PATCH 278/607] ch4: persist cvar values in comm_ptr in release_gather Because we initialize the release_gather structure once for each comm, we need make sure the parameters are consistent throughout the comm lifetime. CVARs may get updated during runtime. Thus we need initialize and transfer the CVARs into per-comm setting at init time. --- .../shm/posix/release_gather/release_gather.c | 82 ++++++++++--------- .../shm/posix/release_gather/release_gather.h | 26 +++--- .../release_gather/release_gather_types.h | 7 ++ 3 files changed, 66 insertions(+), 49 deletions(-) diff --git a/src/mpid/ch4/shm/posix/release_gather/release_gather.c b/src/mpid/ch4/shm/posix/release_gather/release_gather.c index 37d45775a41..d05c648975a 100644 --- a/src/mpid/ch4/shm/posix/release_gather/release_gather.c +++ b/src/mpid/ch4/shm/posix/release_gather/release_gather.c @@ -136,37 +136,27 @@ #include "topotree.h" #include "topotree_util.h" -#define RELEASE_GATHER_FIELD(comm, field) \ - MPIDI_POSIX_COMM(comm, release_gather).field - MPIDI_POSIX_release_gather_tree_type_t MPIDI_POSIX_Bcast_tree_type, MPIDI_POSIX_Reduce_tree_type; +static int get_tree_type(const char *tree_type_name) +{ + if (0 == strcmp(tree_type_name, "kary")) + return MPIDI_POSIX_RELEASE_GATHER_TREE_TYPE_KARY; + else if (0 == strcmp(tree_type_name, "knomial_1")) + return MPIDI_POSIX_RELEASE_GATHER_TREE_TYPE_KNOMIAL_1; + else if (0 == strcmp(tree_type_name, "knomial_2")) + return MPIDI_POSIX_RELEASE_GATHER_TREE_TYPE_KNOMIAL_2; + else + return MPIDI_POSIX_RELEASE_GATHER_TREE_TYPE_KARY; +} + /* Initialize the release_gather struct to NULL */ int MPIDI_POSIX_mpi_release_gather_comm_init_null(MPIR_Comm * comm_ptr) { MPIR_FUNC_ENTER; RELEASE_GATHER_FIELD(comm_ptr, num_collective_calls) = 0; - - if (0 == strcmp(MPIR_CVAR_BCAST_INTRANODE_TREE_TYPE, "kary")) - MPIDI_POSIX_Bcast_tree_type = MPIDI_POSIX_RELEASE_GATHER_TREE_TYPE_KARY; - else if (0 == strcmp(MPIR_CVAR_BCAST_INTRANODE_TREE_TYPE, "knomial_1")) - MPIDI_POSIX_Bcast_tree_type = MPIDI_POSIX_RELEASE_GATHER_TREE_TYPE_KNOMIAL_1; - else if (0 == strcmp(MPIR_CVAR_BCAST_INTRANODE_TREE_TYPE, "knomial_2")) - MPIDI_POSIX_Bcast_tree_type = MPIDI_POSIX_RELEASE_GATHER_TREE_TYPE_KNOMIAL_2; - else - MPIDI_POSIX_Bcast_tree_type = MPIDI_POSIX_RELEASE_GATHER_TREE_TYPE_KARY; - - if (0 == strcmp(MPIR_CVAR_REDUCE_INTRANODE_TREE_TYPE, "kary")) - MPIDI_POSIX_Reduce_tree_type = MPIDI_POSIX_RELEASE_GATHER_TREE_TYPE_KARY; - else if (0 == strcmp(MPIR_CVAR_REDUCE_INTRANODE_TREE_TYPE, "knomial_1")) - MPIDI_POSIX_Reduce_tree_type = MPIDI_POSIX_RELEASE_GATHER_TREE_TYPE_KNOMIAL_1; - else if (0 == strcmp(MPIR_CVAR_REDUCE_INTRANODE_TREE_TYPE, "knomial_2")) - MPIDI_POSIX_Reduce_tree_type = MPIDI_POSIX_RELEASE_GATHER_TREE_TYPE_KNOMIAL_2; - else - MPIDI_POSIX_Reduce_tree_type = MPIDI_POSIX_RELEASE_GATHER_TREE_TYPE_KARY; - RELEASE_GATHER_FIELD(comm_ptr, is_initialized) = 0; MPIR_FUNC_EXIT; @@ -202,6 +192,20 @@ int MPIDI_POSIX_mpi_release_gather_comm_init(MPIR_Comm * comm_ptr, * reduce buffer (divided into multiple cells) per rank. */ if (RELEASE_GATHER_FIELD(comm_ptr, is_initialized) == 0) { + RELEASE_GATHER_FIELD(comm_ptr, is_initialized) = 1; + /* CVARs may get updated. Turn them into per-comm settings */ + RELEASE_GATHER_FIELD(comm_ptr, bcast_tree_type) = + get_tree_type(MPIR_CVAR_BCAST_INTRANODE_TREE_TYPE); + RELEASE_GATHER_FIELD(comm_ptr, bcast_tree_kval) = MPIR_CVAR_BCAST_INTRANODE_TREE_KVAL; + RELEASE_GATHER_FIELD(comm_ptr, bcast_shm_size) = + MPIR_CVAR_BCAST_INTRANODE_BUFFER_TOTAL_SIZE; + RELEASE_GATHER_FIELD(comm_ptr, bcast_num_cells) = MPIR_CVAR_BCAST_INTRANODE_NUM_CELLS; + RELEASE_GATHER_FIELD(comm_ptr, reduce_tree_type) = + get_tree_type(MPIR_CVAR_REDUCE_INTRANODE_TREE_TYPE); + RELEASE_GATHER_FIELD(comm_ptr, reduce_tree_kval) = MPIR_CVAR_REDUCE_INTRANODE_TREE_KVAL; + RELEASE_GATHER_FIELD(comm_ptr, reduce_shm_size) = + MPIR_CVAR_REDUCE_INTRANODE_BUFFER_TOTAL_SIZE; + RELEASE_GATHER_FIELD(comm_ptr, reduce_num_cells) = MPIR_CVAR_REDUCE_INTRANODE_NUM_CELLS; /* release_gather based collectives have not been used before on this comm */ initialize_flags = true; if (operation == MPIDI_POSIX_RELEASE_GATHER_OPCODE_BCAST) { @@ -245,10 +249,10 @@ int MPIDI_POSIX_mpi_release_gather_comm_init(MPIR_Comm * comm_ptr, } if (initialize_bcast_buf) { - memory_to_be_allocated += MPIR_CVAR_BCAST_INTRANODE_BUFFER_TOTAL_SIZE; + memory_to_be_allocated += RELEASE_GATHER_FIELD(comm_ptr, bcast_shm_size); } if (initialize_reduce_buf) { - memory_to_be_allocated += (num_ranks * MPIR_CVAR_REDUCE_INTRANODE_BUFFER_TOTAL_SIZE); + memory_to_be_allocated += (num_ranks * RELEASE_GATHER_FIELD(comm_ptr, reduce_shm_size)); } if (rank == 0) { @@ -290,10 +294,11 @@ int MPIDI_POSIX_mpi_release_gather_comm_init(MPIR_Comm * comm_ptr, /* Topology aware trees are created only when the user has specified process binding */ if (MPIR_hwtopo_is_initialized()) { mpi_errno = - MPIDI_SHM_topology_tree_init(comm_ptr, 0, MPIR_CVAR_BCAST_INTRANODE_TREE_KVAL, + MPIDI_SHM_topology_tree_init(comm_ptr, 0, + RELEASE_GATHER_FIELD(comm_ptr, bcast_tree_kval), &release_gather_info_ptr->bcast_tree, &topotree_fail[0], - MPIR_CVAR_REDUCE_INTRANODE_TREE_KVAL, + RELEASE_GATHER_FIELD(comm_ptr, reduce_tree_kval), &release_gather_info_ptr->reduce_tree, &topotree_fail[1], &errflag); MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); @@ -322,8 +327,9 @@ int MPIDI_POSIX_mpi_release_gather_comm_init(MPIR_Comm * comm_ptr, if (topotree_fail[0] == 1) MPIR_Treealgo_tree_free(&release_gather_info_ptr->bcast_tree); mpi_errno = - MPIR_Treealgo_tree_create(rank, num_ranks, MPIDI_POSIX_Bcast_tree_type, - MPIR_CVAR_BCAST_INTRANODE_TREE_KVAL, 0, + MPIR_Treealgo_tree_create(rank, num_ranks, + RELEASE_GATHER_FIELD(comm_ptr, bcast_tree_type), + RELEASE_GATHER_FIELD(comm_ptr, bcast_tree_kval), 0, &release_gather_info_ptr->bcast_tree); MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); } @@ -332,14 +338,16 @@ int MPIDI_POSIX_mpi_release_gather_comm_init(MPIR_Comm * comm_ptr, if (topotree_fail[1] == 1) MPIR_Treealgo_tree_free(&release_gather_info_ptr->reduce_tree); mpi_errno = - MPIR_Treealgo_tree_create(rank, num_ranks, MPIDI_POSIX_Reduce_tree_type, - MPIR_CVAR_REDUCE_INTRANODE_TREE_KVAL, 0, + MPIR_Treealgo_tree_create(rank, num_ranks, + RELEASE_GATHER_FIELD(comm_ptr, reduce_tree_type), + RELEASE_GATHER_FIELD(comm_ptr, reduce_tree_kval), 0, &release_gather_info_ptr->reduce_tree); MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); } - release_gather_info_ptr->gather_state = release_gather_info_ptr->release_state - = MPIR_CVAR_BCAST_INTRANODE_NUM_CELLS + MPIR_CVAR_REDUCE_INTRANODE_NUM_CELLS; + release_gather_info_ptr->gather_state = release_gather_info_ptr->release_state = + RELEASE_GATHER_FIELD(comm_ptr, bcast_num_cells) + + RELEASE_GATHER_FIELD(comm_ptr, reduce_num_cells); release_gather_info_ptr->bcast_buf_addr = NULL; release_gather_info_ptr->reduce_buf_addr = NULL; @@ -374,15 +382,13 @@ int MPIDI_POSIX_mpi_release_gather_comm_init(MPIR_Comm * comm_ptr, } if (initialize_bcast_buf) { - RELEASE_GATHER_FIELD(comm_ptr, bcast_shm_size) = - MPIR_CVAR_BCAST_INTRANODE_BUFFER_TOTAL_SIZE; if (rank == 0) MPL_atomic_fetch_add_uint64(MPIDI_POSIX_shm_limit_counter, RELEASE_GATHER_FIELD(comm_ptr, bcast_shm_size)); /* Allocate the shared memory for bcast buffer */ mpi_errno = - MPIDU_shm_alloc(comm_ptr, MPIR_CVAR_BCAST_INTRANODE_BUFFER_TOTAL_SIZE, + MPIDU_shm_alloc(comm_ptr, RELEASE_GATHER_FIELD(comm_ptr, bcast_shm_size), (void **) &(RELEASE_GATHER_FIELD(comm_ptr, bcast_buf_addr)), &mapfail_flag); if (mapfail_flag) { @@ -397,14 +403,12 @@ int MPIDI_POSIX_mpi_release_gather_comm_init(MPIR_Comm * comm_ptr, RELEASE_GATHER_FIELD(comm_ptr, child_reduce_buf_addr) = MPL_malloc(num_ranks * sizeof(void *), MPL_MEM_COLL); - RELEASE_GATHER_FIELD(comm_ptr, reduce_shm_size) = - MPIR_CVAR_BCAST_INTRANODE_BUFFER_TOTAL_SIZE; if (rank == 0) MPL_atomic_fetch_add_uint64(MPIDI_POSIX_shm_limit_counter, RELEASE_GATHER_FIELD(comm_ptr, reduce_shm_size)); mpi_errno = - MPIDU_shm_alloc(comm_ptr, num_ranks * MPIR_CVAR_REDUCE_INTRANODE_BUFFER_TOTAL_SIZE, + MPIDU_shm_alloc(comm_ptr, num_ranks * RELEASE_GATHER_FIELD(comm_ptr, reduce_shm_size), (void **) &(RELEASE_GATHER_FIELD(comm_ptr, reduce_buf_addr)), &mapfail_flag); if (mapfail_flag) { @@ -422,7 +426,7 @@ int MPIDI_POSIX_mpi_release_gather_comm_init(MPIR_Comm * comm_ptr, (char *) RELEASE_GATHER_FIELD(comm_ptr, reduce_buf_addr) + ((*utarray_eltptr(RELEASE_GATHER_FIELD(comm_ptr, reduce_tree.children), i)) - * MPIR_CVAR_REDUCE_INTRANODE_BUFFER_TOTAL_SIZE); + * RELEASE_GATHER_FIELD(comm_ptr, reduce_shm_size)); } } diff --git a/src/mpid/ch4/shm/posix/release_gather/release_gather.h b/src/mpid/ch4/shm/posix/release_gather/release_gather.h index 641189c2bab..e6cf22c1980 100644 --- a/src/mpid/ch4/shm/posix/release_gather/release_gather.h +++ b/src/mpid/ch4/shm/posix/release_gather/release_gather.h @@ -11,6 +11,9 @@ extern MPL_shm_hnd_t shm_limit_handle; extern MPIDI_POSIX_release_gather_tree_type_t MPIDI_POSIX_Bcast_tree_type, MPIDI_POSIX_Reduce_tree_type; +#define RELEASE_GATHER_FIELD(comm, field) \ + MPIDI_POSIX_COMM(comm, release_gather).field + /* Blocking wait implementation */ /* "acquire" makes sure no writes/reads are reordered before this load */ #define MPIDI_POSIX_RELEASE_GATHER_WAIT_WHILE_LESS_THAN(ptr, value) \ @@ -41,12 +44,12 @@ extern MPIDI_POSIX_release_gather_tree_type_t MPIDI_POSIX_Bcast_tree_type, (buf * MPIDI_POSIX_RELEASE_GATHER_BCAST_CELLSIZE) #define MPIDI_POSIX_RELEASE_GATHER_REDUCE_DATA_ADDR(rank, buf) \ (((char *) release_gather_info_ptr->reduce_buf_addr) + \ - (rank * MPIR_CVAR_REDUCE_INTRANODE_BUFFER_TOTAL_SIZE) + \ + (rank * RELEASE_GATHER_FIELD(comm_ptr, reduce_shm_size)) + \ (buf * MPIDI_POSIX_RELEASE_GATHER_REDUCE_CELLSIZE)) #define MPIDI_POSIX_RELEASE_GATHER_BCAST_CELLSIZE \ - (MPIR_CVAR_BCAST_INTRANODE_BUFFER_TOTAL_SIZE / MPIR_CVAR_BCAST_INTRANODE_NUM_CELLS) + (RELEASE_GATHER_FIELD(comm_ptr, bcast_shm_size) / RELEASE_GATHER_FIELD(comm_ptr, bcast_num_cells)) #define MPIDI_POSIX_RELEASE_GATHER_REDUCE_CELLSIZE \ - (MPIR_CVAR_REDUCE_INTRANODE_BUFFER_TOTAL_SIZE / MPIR_CVAR_REDUCE_INTRANODE_NUM_CELLS) + (RELEASE_GATHER_FIELD(comm_ptr, reduce_shm_size) / RELEASE_GATHER_FIELD(comm_ptr, reduce_num_cells)) int MPIDI_POSIX_mpi_release_gather_comm_init_null(MPIR_Comm * comm_ptr); int MPIDI_POSIX_mpi_release_gather_comm_init(MPIR_Comm * comm_ptr, @@ -79,15 +82,16 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_mpi_release_gather_release(void *local_ * buffers can be used to pipeline the copying in and out of shared memory, and data is not * overwritten */ const int relaxation = - (operation == - MPIDI_POSIX_RELEASE_GATHER_OPCODE_REDUCE) ? MPIR_CVAR_REDUCE_INTRANODE_NUM_CELLS - 1 : 0; + (operation == MPIDI_POSIX_RELEASE_GATHER_OPCODE_REDUCE) ? + RELEASE_GATHER_FIELD(comm_ptr, reduce_num_cells) - 1 : 0; rank = MPIR_Comm_rank(comm_ptr); release_gather_info_ptr = &MPIDI_POSIX_COMM(comm_ptr, release_gather); release_gather_info_ptr->release_state++; if (operation == MPIDI_POSIX_RELEASE_GATHER_OPCODE_BCAST) { - segment = release_gather_info_ptr->release_state % MPIR_CVAR_BCAST_INTRANODE_NUM_CELLS; + segment = release_gather_info_ptr->release_state % + RELEASE_GATHER_FIELD(comm_ptr, bcast_num_cells); bcast_data_addr = MPIDI_POSIX_RELEASE_GATHER_BCAST_DATA_ADDR(segment); if (root != 0) { @@ -156,7 +160,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_mpi_release_gather_release(void *local_ if (operation == MPIDI_POSIX_RELEASE_GATHER_OPCODE_ALLREDUCE) { /* For allreduce, ranks directly copy the data from the reduce buffer of rank 0 */ - segment = release_gather_info_ptr->release_state % MPIR_CVAR_REDUCE_INTRANODE_NUM_CELLS; + segment = release_gather_info_ptr->release_state % + RELEASE_GATHER_FIELD(comm_ptr, reduce_num_cells); bcast_data_addr = MPIDI_POSIX_RELEASE_GATHER_REDUCE_DATA_ADDR(0, segment); } @@ -256,8 +261,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_mpi_release_gather_gather(const void *i * buffers can be used to pipeline the copying in and out of shared memory, and data is not * overwritten */ const int relaxation = - (operation == - MPIDI_POSIX_RELEASE_GATHER_OPCODE_BCAST) ? MPIR_CVAR_BCAST_INTRANODE_NUM_CELLS - 1 : 0; + (operation == MPIDI_POSIX_RELEASE_GATHER_OPCODE_BCAST) ? + RELEASE_GATHER_FIELD(comm_ptr, bcast_num_cells) - 1 : 0; uint64_t min_gather, child_gather_flag; UT_array *children; void *temp_recvbuf = NULL; @@ -269,7 +274,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_mpi_release_gather_gather(const void *i release_gather_info_ptr->gather_state++; min_gather = release_gather_info_ptr->gather_state; - segment = release_gather_info_ptr->gather_state % MPIR_CVAR_REDUCE_INTRANODE_NUM_CELLS; + segment = release_gather_info_ptr->gather_state % + RELEASE_GATHER_FIELD(comm_ptr, reduce_num_cells); if (operation == MPIDI_POSIX_RELEASE_GATHER_OPCODE_REDUCE || operation == MPIDI_POSIX_RELEASE_GATHER_OPCODE_ALLREDUCE) { diff --git a/src/mpid/ch4/shm/posix/release_gather/release_gather_types.h b/src/mpid/ch4/shm/posix/release_gather/release_gather_types.h index 4d84baa36bd..94b2de42993 100644 --- a/src/mpid/ch4/shm/posix/release_gather/release_gather_types.h +++ b/src/mpid/ch4/shm/posix/release_gather/release_gather_types.h @@ -35,6 +35,13 @@ typedef struct MPIDI_POSIX_release_gather_comm_t { void *flags_addr, *bcast_buf_addr, *reduce_buf_addr; void **child_reduce_buf_addr; MPL_atomic_uint64_t *release_flag_addr, *gather_flag_addr; + + /* parameters need persist for each communicator */ + int bcast_tree_type, bcast_tree_kval; + int bcast_num_cells; + + int reduce_tree_type, reduce_tree_kval; + int reduce_num_cells; } MPIDI_POSIX_release_gather_comm_t; #endif /* RELEASE_GATHER_TYPES_H_INCLUDED */ From 41d3820c652a246edd345d272f1834b48da0ff43 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 17 Dec 2021 12:38:31 -0600 Subject: [PATCH 279/607] maint/extractcvars: fix cvar description It was missing the newline in the output. --- maint/extractcvars.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maint/extractcvars.in b/maint/extractcvars.in index b4150c6f30e..673ae5bf7d7 100755 --- a/maint/extractcvars.in +++ b/maint/extractcvars.in @@ -299,7 +299,7 @@ foreach my $p (@cvars) { # Register the cvar my $desc = $p->{description}; $desc =~ s/"/\\"/g; - $desc =~ s/\n/\\\n/g; + $desc =~ s/\n/\\n"\n"/g; printf OUTPUT_C qq( MPIR_T_CVAR_REGISTER_STATIC(\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s);\n), qq( $mpi_dtype,), qq( ${uc_ns}_$p->{name}, /* name */), From c5609ce51fb1013b20feea99038bfdd108475ade Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 22 Dec 2021 18:01:52 -0600 Subject: [PATCH 280/607] test: add line info in coll/op_coll.c There are multiple tests and assertions in op_coll.c. Add line number in its assertion output so we can locate the failing test. --- test/mpi/coll/op_coll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/mpi/coll/op_coll.c b/test/mpi/coll/op_coll.c index 7ba33dc9ad5..24838e4472d 100644 --- a/test/mpi/coll/op_coll.c +++ b/test/mpi/coll/op_coll.c @@ -16,7 +16,7 @@ #define my_assert(cond_) \ do { \ if (!(cond_)) { \ - fprintf(stderr, "assertion (%s) failed, aborting\n", #cond_); \ + printf("assertion (%s) failed at line %d, aborting\n", #cond_, __LINE__); \ MPI_Abort(MPI_COMM_WORLD, 1); \ } \ } while (0) From 640b7d2d8cca0be1e59fd98aafb1f08104d88c88 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 20 Dec 2021 16:03:30 -0600 Subject: [PATCH 281/607] test: fix typos in coll_cvars.txt --- test/mpi/maint/coll_cvars.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/mpi/maint/coll_cvars.txt b/test/mpi/maint/coll_cvars.txt index 02da800ee38..a7a9e05844a 100644 --- a/test/mpi/maint/coll_cvars.txt +++ b/test/mpi/maint/coll_cvars.txt @@ -121,6 +121,8 @@ tests: neighbor_alltoallw: intra-blocking: neighb_alltoallw 4 + persistent: + p_neighb_alltoallw 4 reduce: intra-blocking: reduce 5 @@ -139,7 +141,6 @@ tests: redscat3 8 persistent: p_redscat 4 - redscat 4 reduce_scatter_block: intra-blocking: red_scat_block 4 @@ -155,7 +156,6 @@ tests: scan: intra-blocking: scantst 4 - op_coll 4 persistent: p_scan 4 scatter: From 0a73f03f078573b9089d22a25653f21b43df01d6 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 13 Dec 2021 21:10:09 -0600 Subject: [PATCH 282/607] test: do not use mpiversion option in testlist mpiversion option is not implemented in runtests. Simply add macro guard in the test code. This is consistent with other tests that require certain minimum MPI versions. TODO: The test should print some message, e.g. Skipped due to version requirement, so that the test report can reflect it. --- test/mpi/errors/pt2pt/testlist | 2 +- test/mpi/errors/pt2pt/truncmsg_mrecv.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/test/mpi/errors/pt2pt/testlist b/test/mpi/errors/pt2pt/testlist index e21ed1fd68b..eca0402fe21 100644 --- a/test/mpi/errors/pt2pt/testlist +++ b/test/mpi/errors/pt2pt/testlist @@ -2,7 +2,7 @@ proberank 1 truncmsg1 2 truncmsg1 2 env=MPIR_CVAR_CH4_OFI_EAGER_MAX_MSG_SIZE=16384 truncmsg2 2 -truncmsg_mrecv 2 mpiversion=3.0 +truncmsg_mrecv 2 # multiple completion ests errinstatts 2 errinstatta 2 diff --git a/test/mpi/errors/pt2pt/truncmsg_mrecv.c b/test/mpi/errors/pt2pt/truncmsg_mrecv.c index 70198f98cc0..19758a8562a 100644 --- a/test/mpi/errors/pt2pt/truncmsg_mrecv.c +++ b/test/mpi/errors/pt2pt/truncmsg_mrecv.c @@ -43,7 +43,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "Unable to allocate communication buffer of size %d\n", LongLen); MPI_Abort(MPI_COMM_WORLD, 1); } - +#if MTEST_HAVE_MIN_MPI_VERSION(3,0) if (testShort) { if (rank == source) { err = MPI_Send(buf, ShortLen, MPI_INT, dest, 0, MPI_COMM_WORLD); @@ -77,6 +77,7 @@ int main(int argc, char *argv[]) errs += checkTruncError(err, "long"); } } +#endif free(buf); MTest_Finalize(errs); From f77d6f71b902410ba99e9c01dd003f5afba7f0c0 Mon Sep 17 00:00:00 2001 From: Rob Latham Date: Thu, 6 Jan 2022 15:13:41 -0600 Subject: [PATCH 283/607] romio: clean up file system detection ROMIO file system checking had grown out of hand: - use AC_CHECK_MEMBERS instead of our ancient home-grown stat member checking logic. - abstract the "stat/statfs/statvfs" part from the rest of the code so we don't duplicate detection logic in three places - add a 'magic number' to the 'fstypes' struct so we can use that table multiple ways. check for more file systems --- src/mpi/romio/adio/common/ad_fstype.c | 389 ++++++++++---------------- src/mpi/romio/configure.ac | 181 +++--------- 2 files changed, 182 insertions(+), 388 deletions(-) diff --git a/src/mpi/romio/adio/common/ad_fstype.c b/src/mpi/romio/adio/common/ad_fstype.c index 1882644c7b0..ec8ee535b88 100644 --- a/src/mpi/romio/adio/common/ad_fstype.c +++ b/src/mpi/romio/adio/common/ad_fstype.c @@ -52,7 +52,6 @@ * Otherwise we'll fall back on some OS-specific approach. */ -#ifdef HAVE_STRUCT_STATFS #ifdef HAVE_SYS_VFS_H #include #endif @@ -64,24 +63,26 @@ #endif #ifdef HAVE_SYS_MOUNT_H #include +#endif +#ifdef HAVE_SYS_STAT_H +#include #endif /* On Linux platforms, linux/nfs_fs.h is all messed up and cannot be * reliably included. */ -#if defined(ROMIO_NFS) && !defined(NFS_SUPER_MAGIC) +#if !defined(NFS_SUPER_MAGIC) #define NFS_SUPER_MAGIC 0x6969 #endif -#if defined(ROMIO_PANFS) && !defined(PAN_KERNEL_FS_CLIENT_SUPER_MAGIC) +#if !defined(PAN_KERNEL_FS_CLIENT_SUPER_MAGIC) #define PAN_KERNEL_FS_CLIENT_SUPER_MAGIC 0xAAD7AAEA #endif -#endif -#if defined(ROMIO_XFS) && !defined(XFS_SUPER_MAGIC) +#if !defined(XFS_SUPER_MAGIC) #define XFS_SUPER_MAGIC 0x58465342 #endif -#if defined(ROMIO_XFS) && !defined(EXFS_SUPER_MAGIC) +#if !defined(EXFS_SUPER_MAGIC) #define EXFS_SUPER_MAGIC 0x45584653 #endif @@ -89,15 +90,21 @@ #define PVFS2_SUPER_MAGIC (0x20030528) #endif -#if defined(ROMIO_GPFS) && !defined(GPFS_SUPER_MAGIC) +#if !defined(GPFS_SUPER_MAGIC) #define GPFS_SUPER_MAGIC 0x47504653 #endif +#ifndef LL_SUPER_MAGIC +#define LL_SUPER_MAGIC 0x0BD00BD0 +#endif + #if !defined(DAOS_SUPER_MAGIC) #define DAOS_SUPER_MAGIC (0xDA05AD10) #endif -#ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE +#define UNKNOWN_SUPER_MAGIC (0xDEADBEEF) + +#ifdef HAVE_STRUCT_STATVFS_WITH_F_BASETYPE #ifdef HAVE_SYS_STATVFS_H #include #endif @@ -112,7 +119,7 @@ #endif #endif -#ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE +#ifdef HAVE_STRUCT_STAT_WITH_ST_FSTYPE #ifdef HAVE_SYS_TYPES_H #include #endif @@ -121,17 +128,19 @@ #endif #endif -/* ADIO_FileSysType_parentdir is only used if one of these is defined. - By including this test, we avoid warnings about unused static functions - from the compiler */ -#if defined(ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE) || \ - defined(HAVE_STRUCT_STATFS) || \ - defined(ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE) +#ifdef HAVE_STRUCT_STAT_WITH_ST_FSID +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_MOUNT_H +#include +#endif +#endif + #ifndef ROMIO_NTFS #define ROMIO_NEEDS_ADIOPARENTDIR static void ADIO_FileSysType_parentdir(const char *filename, char **dirnamep); #endif -#endif static void ADIO_FileSysType_prefix(const char *filename, int *fstype, ADIOI_Fns ** ops, int *error_code); static void ADIO_FileSysType_fncall(const char *filename, int *fstype, int *error_code); @@ -139,6 +148,7 @@ struct ADIO_FSTypes { ADIOI_Fns *fileops; /* function table */ int fstype; /* ADIO_xxx constant */ const char *prefix; /* file prefix */ + int64_t magic; /* identifier for file system, or UNKNOWN */ }; /* @@ -149,39 +159,45 @@ struct ADIO_FSTypes { */ static struct ADIO_FSTypes fstypes[] = { #ifdef ROMIO_UFS - {&ADIO_UFS_operations, ADIO_UFS, "ufs:"}, + {&ADIO_UFS_operations, ADIO_UFS, "ufs:", UNKNOWN_SUPER_MAGIC}, #endif #ifdef ROMIO_NFS - {&ADIO_NFS_operations, ADIO_NFS, "nfs:"}, + {&ADIO_NFS_operations, ADIO_NFS, "nfs:", NFS_SUPER_MAGIC}, #endif #ifdef ROMIO_XFS - {&ADIO_XFS_operations, ADIO_XFS, "xfs:"}, + {&ADIO_XFS_operations, ADIO_XFS, "xfs:", XFS_SUPER_MAGIC}, + /* rare, but could be on some systems. Both magic values use the same ROMIO + * driver, though */ + {&ADIO_XFS_operations, ADIO_XFS, "xfs:", EXFS_SUPER_MAGIC}, #endif #ifdef ROMIO_PVFS2 - {&ADIO_PVFS2_operations, ADIO_PVFS2, "pvfs2:"}, + {&ADIO_PVFS2_operations, ADIO_PVFS2, "pvfs2:", PVFS2_SUPER_MAGIC}, #endif #ifdef ROMIO_GPFS - {&ADIO_GPFS_operations, ADIO_GPFS, "gpfs:"}, + {&ADIO_GPFS_operations, ADIO_GPFS, "gpfs:", GPFS_SUPER_MAGIC}, #endif #ifdef ROMIO_PANFS - {&ADIO_PANFS_operations, ADIO_PANFS, "panfs:"}, + {&ADIO_PANFS_operations, ADIO_PANFS, "panfs:", PAN_KERNEL_FS_CLIENT_SUPER_MAGIC}, #endif #ifdef ROMIO_LUSTRE - {&ADIO_LUSTRE_operations, ADIO_LUSTRE, "lustre:"}, + {&ADIO_LUSTRE_operations, ADIO_LUSTRE, "lustre:", LL_SUPER_MAGIC}, #endif #ifdef ROMIO_DAOS - {&ADIO_DAOS_operations, ADIO_DAOS, "daos:"}, + {&ADIO_DAOS_operations, ADIO_DAOS, "daos:", DAOS_SUPER_MAGIC}, #endif #ifdef ROMIO_TESTFS - {&ADIO_TESTFS_operations, ADIO_TESTFS, "testfs:"}, + /* never selected automatically */ + {&ADIO_TESTFS_operations, ADIO_TESTFS, "testfs:", 0}, #endif #ifdef ROMIO_IME - {&ADIO_IME_operations, ADIO_IME, "ime:"}, + /* userspace driver only selected via prefix */ + {&ADIO_IME_operations, ADIO_IME, "ime:", 0}, #endif #ifdef ROMIO_QUOBYTEFS - {&ADIO_QUOBYTEFS_operations, ADIO_QUOBYTEFS, "quobyte:"}, + /* userspace driver only selected via prefix */ + {&ADIO_QUOBYTEFS_operations, ADIO_QUOBYTEFS, "quobyte:", 0}, #endif - {0, 0, 0} /* guard entry */ + {0, 0, 0, 0} /* guard entry */ }; @@ -272,6 +288,74 @@ static void ADIO_FileSysType_parentdir(const char *filename, char **dirnamep) } #endif /* ROMIO_NTFS */ + +static int romio_statfs(const char *filename, int64_t * file_id) +{ + + int err = 0; + +#ifdef HAVE_STRUCT_STATVFS_WITH_F_BASETYPE + /* rare: old solaris machines */ + struct statvfs vfsbuf; +#endif +#if defined(HAVE_STRUCT_STATFS_F_TYPE) || defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) + /* common fs-detection logic for any modern POSIX-compliant environment, + * with the one wrinkle that some platforms (Darwin, BSD) give us a file + * system as a string, not an identifier */ + struct statfs fsbuf; +#endif +#if defined (HAVE_STRUCT_STAT_ST_FSTYPE) + struct stat sbuf; +#endif + + *file_id = UNKNOWN_SUPER_MAGIC; + +#ifdef HAVE_STRUCT_STATVFS_WITH_F_BASETYPE + err = statvfs(filename, &vfsbuf); + if (err == 0) + *file_id = vfsbuf.f_basetype; +#endif + +/* remember above how I said 'statfs with f_type' was the common linux-y way to + * report file system type? Darwin (and probably the BSDs) *also* uses f_type + * but it is "reserved" and does not give us anything meaningful. Fine. If + * configure detects f_type we'll use it here and on those "reserved" platforms + * we'll ignore that result and check the f_fstypename field */ +#ifdef HAVE_STRUCT_STATFS_F_TYPE + err = statfs(filename, &fsbuf); + if (err == 0) + *file_id = fsbuf.f_type; +#endif + + +#if defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) || defined(HAVE_STRUCT_STAT_ST_FSTYPE) + /* these stat routines store the file system type in a string */ + char *fstype; +#ifdef HAVE_STRUCT_STATFS_F_FSTYPENAME + err = statfs(filename, &fsbuf); + fstype = fsbuf.f_fstypename; +#else + err = stat(filename, &sbuf); + fstype = sbuf.st_fstype; +#endif + if (err == 0) { + int i = 0; + /* any file system type not explicitly in the fstype table (ffs, hfs) + * will be "unknown" which ROMIO will service with ADIO_UFS */ + while (fstypes[i].fileops) { + /* '-1' to ignore the trailing colon */ + if (!strncasecmp(fstypes[i].prefix, fstype, strlen(fstypes[i].prefix) - 1)) { + *file_id = fstypes[i].magic; + } + i++; + } + } +#endif + + return err; + +} + /* ADIO_FileSysType_fncall - determines the file system type for a given file using a system-dependent function call @@ -291,32 +375,20 @@ Output Parameters: */ static void ADIO_FileSysType_fncall(const char *filename, int *fstype, int *error_code) { -#if defined (ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE) || defined (HAVE_STRUCT_STATFS) || defined (ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE) int err; -#endif - -#ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE - struct statvfs vfsbuf; -#endif -#ifdef HAVE_STRUCT_STATFS - struct statfs fsbuf; -#endif -#ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE - struct stat sbuf; -#endif + int64_t file_id; static char myname[] = "ADIO_RESOLVEFILETYPE_FNCALL"; + /* NFS can get stuck and end up returning ESTALE "forever" */ #define MAX_ESTALE_RETRY 10000 int retry_cnt; *error_code = MPI_SUCCESS; -#ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE - /* rare: old solaris machines */ retry_cnt = 0; do { - err = statvfs(filename, &vfsbuf); + err = romio_statfs(filename, &file_id); } while (err && (errno == ESTALE) && retry_cnt++ < MAX_ESTALE_RETRY); if (err) { @@ -329,60 +401,8 @@ static void ADIO_FileSysType_fncall(const char *filename, int *fstype, int *erro if (errno == ENOENT) { char *dir; ADIO_FileSysType_parentdir(filename, &dir); - err = statvfs(dir, &vfsbuf); - - ADIOI_Free(dir); - } else { - *error_code = ADIOI_Err_create_code(myname, filename, errno); - if (*error_code != MPI_SUCCESS) - return; - } - } - - /* --BEGIN ERROR HANDLING-- */ - if (err) { - *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, - myname, __LINE__, MPI_ERR_NO_SUCH_FILE, - "**filename", "**filename %s", filename); - return; - } - /* --END ERROR HANDLING-- */ - - /* FPRINTF(stderr, "%s\n", vfsbuf.f_basetype); */ - if (!strncmp(vfsbuf.f_basetype, "nfs", 3)) { - *fstype = ADIO_NFS; - return; - } - if (!strncmp(vfsbuf.f_basetype, "xfs", 3)) { - *fstype = ADIO_XFS; - return; - } -#ifdef ROMIO_UFS - /* if UFS support is enabled, default to that */ - *fstype = ADIO_UFS; - return; -#endif + err = romio_statfs(dir, &file_id); - /* --BEGIN ERROR HANDLING-- */ - *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, - myname, __LINE__, MPI_ERR_NO_SUCH_FILE, - "**filename", "**filename %s", filename); - /* --END ERROR HANDLING-- */ -#endif /* STATVFS APPROACH */ - -#if defined(HAVE_STRUCT_STATFS) && defined(HAVE_STATFS) - /* common automagic fs-detection logic for any modern POSX-compliant - * environment */ - retry_cnt = 0; - do { - err = statfs(filename, &fsbuf); - } while (err && (errno == ESTALE) && retry_cnt++ < MAX_ESTALE_RETRY); - - if (err) { - if (errno == ENOENT) { - char *dir; - ADIO_FileSysType_parentdir(filename, &dir); - err = statfs(dir, &fsbuf); ADIOI_Free(dir); } else { *error_code = ADIOI_Err_create_code(myname, filename, errno); @@ -400,163 +420,42 @@ static void ADIO_FileSysType_fncall(const char *filename, int *fstype, int *erro } /* --END ERROR HANDLING-- */ -#ifdef ROMIO_HAVE_STRUCT_STATFS_WITH_F_FSTYPENAME - /* less common: Darwin and OpenBSD */ - if (!strncmp("nfs", fsbuf.f_fstypename, 3)) { - *fstype = ADIO_NFS; - return; - } -#endif - - -#ifdef ROMIO_HAVE_STRUCT_STATFS_WITH_F_TYPE - -#ifdef ROMIO_GPFS - if (fsbuf.f_type == GPFS_SUPER_MAGIC) { - *fstype = ADIO_GPFS; - return; - } -#endif - - /* FPRINTF(stderr, "%d\n", fsbuf.f_type); */ -#ifdef NFS_SUPER_MAGIC - if (fsbuf.f_type == NFS_SUPER_MAGIC) { - *fstype = ADIO_NFS; - return; - } -#endif - -#ifdef ROMIO_LUSTRE -#ifndef LL_SUPER_MAGIC -#define LL_SUPER_MAGIC 0x0BD00BD0 -#endif - if (fsbuf.f_type == LL_SUPER_MAGIC) { - *fstype = ADIO_LUSTRE; - return; - } -#endif - -#ifdef DAOS_SUPER_MAGIC - if (fsbuf.f_type == DAOS_SUPER_MAGIC) { - *fstype = ADIO_DAOS; - return; - } -#endif - -#ifdef PAN_KERNEL_FS_CLIENT_SUPER_MAGIC - if (fsbuf.f_type == PAN_KERNEL_FS_CLIENT_SUPER_MAGIC) { - *fstype = ADIO_PANFS; - return; - } -#endif - -#ifdef MOUNT_NFS - if (fsbuf.f_type == MOUNT_NFS) { - *fstype = ADIO_NFS; - return; - } -#endif - -#ifdef MOUNT_PFS - if (fsbuf.f_type == MOUNT_PFS) { - *fstype = ADIO_PFS; - return; - } -#endif - -#ifdef PVFS_SUPER_MAGIC - if (fsbuf.f_type == PVFS_SUPER_MAGIC) { - *fstype = ADIO_PVFS; - return; - } -#endif - -#ifdef PVFS2_SUPER_MAGIC - if (fsbuf.f_type == PVFS2_SUPER_MAGIC) { - *fstype = ADIO_PVFS2; - return; - } -#endif - -#ifdef XFS_SUPER_MAGIC - if (fsbuf.f_type == XFS_SUPER_MAGIC || fsbuf.f_type == EXFS_SUPER_MAGIC) { - *fstype = ADIO_XFS; - return; - } -#endif - -#endif /*ROMIO_HAVE_STRUCT_STATFS_WITH_F_TYPE */ - -#ifdef ROMIO_UFS - /* if UFS support is enabled, default to that */ - *fstype = ADIO_UFS; - return; -#endif - /* --BEGIN ERROR HANDLING-- */ - *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, - myname, __LINE__, MPI_ERR_NO_SUCH_FILE, - "**filename", "**filename %s", filename); - /* --END ERROR HANDLING-- */ -#endif /* STATFS APPROACH */ - -#ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE - /* rare: maybe old NEC SX or SGI IRIX machines */ - retry_cnt = 0; - do { - err = stat(filename, &sbuf); - } while (err && (errno == ESTALE) && retry_cnt++ < MAX_ESTALE_RETRY); - - if (err) { - if (errno == ENOENT) { - char *dir; - ADIO_FileSysType_parentdir(filename, &dir); - err = stat(dir, &sbuf); - ADIOI_Free(dir); - } else { - *error_code = ADIOI_Err_create_code(myname, filename, errno); - if (*error_code != MPI_SUCCESS) - return; - } - } - - if (err) { - /* --BEGIN ERROR HANDLING-- */ - *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, - myname, __LINE__, MPI_ERR_NO_SUCH_FILE, - "**filename", "**filename %s", filename); - /* --END ERROR HANDLING-- */ - return; - } else { - if (!strcmp(sbuf.st_fstype, "nfs")) + switch (file_id) { + case NFS_SUPER_MAGIC: *fstype = ADIO_NFS; - else - *fstype = ADIO_SFS; /* assuming SX4 for now */ + return; + case XFS_SUPER_MAGIC: + case EXFS_SUPER_MAGIC: + *fstype = ADIO_XFS; + return; + case GPFS_SUPER_MAGIC: + *fstype = ADIO_GPFS; + return; + case LL_SUPER_MAGIC: + *fstype = ADIO_LUSTRE; + return; + case DAOS_SUPER_MAGIC: + *fstype = ADIO_DAOS; + return; + case PAN_KERNEL_FS_CLIENT_SUPER_MAGIC: + *fstype = ADIO_PANFS; + return; + case PVFS2_SUPER_MAGIC: + *fstype = ADIO_PVFS2; + return; + default: + /* UFS support if we don't know what else to use */ + *fstype = ADIO_UFS; + return; } -#endif /* STAT APPROACH */ - -#ifdef ROMIO_NTFS - MPL_UNREFERENCED_ARG(filename); - MPL_UNREFERENCED_ARG(error_code); - *fstype = ADIO_NTFS; /* only supported FS on Windows */ -#elif defined(ROMIO_NFS) - *fstype = ADIO_NFS; -#elif defined(ROMIO_UFS) - *fstype = ADIO_UFS; -#else - /* --BEGIN ERROR HANDLING-- */ - *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, - myname, __LINE__, MPI_ERR_NO_SUCH_FILE, - "**filename", "**filename %s", filename); - /* --END ERROR HANDLING-- */ -#endif } /* all proceeses opening, creating, or deleting a file end up invoking several * stat system calls (unless a fs prefix is given). Cary out this file system * detection in a more scalable way by having rank 0 stat the file and broadcast the result (fs type and error code) to the other mpi processes */ -static void ADIO_FileSysType_fncall_scalable(MPI_Comm comm, const char *filename, int *file_system, - int *error_code) +static void ADIO_FileSysType_fncall_scalable(MPI_Comm comm, const char *filename, + int *file_system, int *error_code) { int rank; int buf[2]; diff --git a/src/mpi/romio/configure.ac b/src/mpi/romio/configure.ac index 1202458c479..6d1a887490b 100644 --- a/src/mpi/romio/configure.ac +++ b/src/mpi/romio/configure.ac @@ -1225,149 +1225,44 @@ AS_CASE([$host_os], # # Check for statfs (many) and specifically f_fstypename field (BSD) # -AC_CHECK_HEADERS(sys/vfs.h sys/param.h sys/mount.h sys/statvfs.h) -AC_CHECK_FUNCS([statfs]) -AC_MSG_CHECKING([whether struct statfs properly defined]) -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #ifdef HAVE_SYS_VFS_H - #include - #endif - #ifdef HAVE_SYS_STATVFS_H - #include - #endif - #ifdef HAVE_SYS_PARAM_H - #include - #endif - #ifdef HAVE_SYS_MOUNT_H - #include - #endif - ]],[[ - struct statfs f; - ]])], - pac_cv_have_statfs=yes,pac_cv_have_statfs=no -) -AC_MSG_RESULT($pac_cv_have_statfs) -# At this point, we could check for whether defining -# __SWORD_TYPE as sizet_t or int/long (size of pointer) -# would help. FIXME - -if test "$pac_cv_have_statfs" = yes ; then - AC_DEFINE(HAVE_STRUCT_STATFS,1,[Define if struct statfs can be compiled]) -fi -AC_MSG_CHECKING([for f_type member of statfs structure]) -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #ifdef HAVE_SYS_VFS_H - #include - #endif - #ifdef HAVE_SYS_STATVFS_H - #include - #endif - #ifdef HAVE_SYS_PARAM_H - #include - #endif - #ifdef HAVE_SYS_MOUNT_H - #include - #endif - #ifdef HAVE_STRING_H - #include - #endif - ]],[[ - struct statfs f; - memset(&f, 0, sizeof(f)); - f.f_type = 0; - ]])], - pac_cv_have_statfs_f_type=yes, - pac_cv_have_statfs_f_type=no -) -AC_MSG_RESULT($pac_cv_have_statfs_f_type) -if test $pac_cv_have_statfs_f_type = yes ; then - AC_DEFINE(ROMIO_HAVE_STRUCT_STATFS_WITH_F_TYPE, 1,[Define if statfs has f_type]) -fi - - -AC_MSG_CHECKING([for f_fstypename member of statfs structure]) -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #ifdef HAVE_SYS_VFS_H - #include - #endif - #ifdef HAVE_SYS_STATVFS_H - #include - #endif - #ifdef HAVE_SYS_PARAM_H - #include - #endif - #ifdef HAVE_SYS_MOUNT_H - #include - #endif - #ifdef HAVE_STRING_H - #include - #endif - ]],[[ - struct statfs f; - memset(&f, 0, sizeof(f)); - strncmp("nfs", f.f_fstypename, 3); - ]])], - pac_cv_have_statfs_f_fstypename=yes, - pac_cv_have_statfs_f_fstypename=no -) -AC_MSG_RESULT($pac_cv_have_statfs_f_fstypename) -if test $pac_cv_have_statfs_f_fstypename = yes ; then - AC_DEFINE(ROMIO_HAVE_STRUCT_STATFS_WITH_F_FSTYPENAME, 1,[Define if statfs has f_fstypename]) -fi - -# -# Check for stat and st_fstype field (NEC SX4) -# -AC_CHECK_HEADERS(sys/stat.h sys/types.h unistd.h) -AC_CHECK_FUNCS(stat, - AC_DEFINE(HAVE_STAT, 1, Define if stat function is present) - AC_MSG_CHECKING([for st_fstype member of stat structure]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #ifdef HAVE_SYS_TYPES_H - #include - #endif - #ifdef HAVE_SYS_STAT_H - #include - #endif - #ifdef HAVE_UNISTD_H - #include - #endif - ]],[[ - struct stat s; - s.st_fstype = NULL; - ]])], - AC_MSG_RESULT(yes) - AC_DEFINE(ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE, 1, Define if struct stat has a st_fstype member), - AC_MSG_RESULT(no) - ) -) - -# -# Check for statvfs and f_basetype field (Solaris, Irix, AIX, etc.) -# -AC_CHECK_HEADERS(sys/types.h sys/statvfs.h sys/vfs.h) -AC_CHECK_FUNCS(statvfs, - AC_DEFINE(HAVE_STATVFS, 1, Define if statvfs function is present) - AC_MSG_CHECKING([for f_basetype member of statvfs structure]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #ifdef HAVE_SYS_TYPES_H - #include - #endif - #ifdef HAVE_SYS_VFS_H - #include - #endif - #ifdef HAVE_SYS_STATVFS_H - #include - #endif - ]], [[ - struct statvfs foo; - foo.f_basetype[0] = 'a'; - ]])], - AC_MSG_RESULT(yes) - AC_DEFINE(ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE, 1, defined if struct statvfs has a f_basetype member), - AC_MSG_RESULT(no) - ) -) +AC_CHECK_HEADERS(sys/vfs.h sys/param.h sys/mount.h sys/statvfs.h sys/stat.h sys/type.h unistd.h) +AC_CHECK_FUNCS([statvfs statfs stat]) +# Who would imagine so many different ways to determine "what kind of file system is this?" +# on old systems we used to check for statfs.f_fsid, but while it can be a file +# system type identifier it is more commonly used to generate a unique "fsid,inode" tuple +# struct statvfs.f_basetype -- Solaris, Irix, AIX +# struct statfs.f_fstypename -- BSD, NetBSD-3.0+, Darwin +# struct statfs.f_type -- Linux +# struct stat.st_fstype -- NEC SX4 (!!) + + +AC_CHECK_MEMBERS([struct statvfs.f_basetype, + struct statfs.f_fstypename, + struct statfs.f_type, + struct stat.st_fstype],[],[], + AC_INCLUDES_DEFAULT + [#ifdef HAVE_SYS_VFS_H + #include + #endif + #ifdef HAVE_SYS_PARAM_H + #include + #endif + #ifdef HAVE_SYS_MOUNT_H + #include + #endif + #ifdef HAVE_SYS_STATFS_H + #include + #endif + #ifdef HAVE_SYS_STAT_H + #include + #endif + #ifdef HAVE_SYS_TYPE_H + #include + #endif + #ifdef HAVE_UNISTD_H + #include + #endif + ]) AC_CHECK_TYPE([blksize_t],[],[AC_DEFINE_UNQUOTED([blksize_t],[__blksize_t],[Provide blksize_t if not available]) ], [[ #ifdef HAVE_SYS_TYPES_H From 55d12cfe3a1d5b6fe15b7154d604386f113f746f Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 6 Jan 2022 17:12:59 -0600 Subject: [PATCH 284/607] mpi: use pointers for array_of_statuses Apparently some compilers -- gcc-11.2 -- will differentiate between MPI_Status array_of_statuses[] and MPI_Status *array_of_statuses and warns if we pass MPI_STATUSES_IGNORE to the former. Note: the standard uses the latter form. --- maint/local_python/binding_common.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/maint/local_python/binding_common.py b/maint/local_python/binding_common.py index 542d1c38e4a..5d52649df5a 100644 --- a/maint/local_python/binding_common.py +++ b/maint/local_python/binding_common.py @@ -139,6 +139,10 @@ def get_C_param(param, func, mapping): else: # MPI_Init, MPI_Init_thread -> char ***argv want_star = 3 + elif kind == "STATUS" and param['length'] is not None: + # MPI_{Wait,Test}{all,some} + # gcc-11 warns when we pass MPI_STATUSES_IGNORE to MPI_Status statues[] + want_star = 1 elif not want_star: if is_pointer_type(param): if kind == "STRING_ARRAY": From 5b03b93a8bae93a73dce70fb0f82490ad13871a4 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 21 Dec 2021 15:38:08 -0600 Subject: [PATCH 285/607] mpl: Remove set but never used variable --- src/mpl/src/thread/mpl_thread_posix.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mpl/src/thread/mpl_thread_posix.c b/src/mpl/src/thread/mpl_thread_posix.c index a11326db2c2..44ec06aeca5 100644 --- a/src/mpl/src/thread/mpl_thread_posix.c +++ b/src/mpl/src/thread/mpl_thread_posix.c @@ -87,7 +87,7 @@ void MPL_thread_set_affinity(MPL_thread_id_t thread, int *affinity_arr, int affi int *errp) { #if defined(MPL_HAVE_PTHREAD_SETAFFINITY_NP) && defined(MPL_HAVE_CPU_SET_MACROS) - int err = MPL_SUCCESS, pthread_err; + int err = MPL_SUCCESS; int proc_idx, set_size = 0; cpu_set_t cpuset; __CPU_ZERO_S(sizeof(cpu_set_t), &cpuset); @@ -95,12 +95,12 @@ void MPL_thread_set_affinity(MPL_thread_id_t thread, int *affinity_arr, int affi for (proc_idx = 0; proc_idx < affinity_size; proc_idx++) __CPU_SET_S(affinity_arr[proc_idx], sizeof(cpu_set_t), &cpuset); - if ((pthread_err = pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset)) != 0) { + if (pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset) != 0) { err = MPL_ERR_THREAD; goto fn_exit; } - if ((pthread_err = pthread_getaffinity_np(thread, sizeof(cpu_set_t), &cpuset)) != 0) { + if (pthread_getaffinity_np(thread, sizeof(cpu_set_t), &cpuset) != 0) { err = MPL_ERR_THREAD; goto fn_exit; } From e4ccac1679217724ea8f59a48b20b0422a079db5 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Thu, 6 Jan 2022 11:09:36 -0600 Subject: [PATCH 286/607] pm/hydra: Remove unnecessary signal handler All this signal handler did was set a global variable that was never read again. --- src/pm/hydra/tools/demux/demux.c | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/src/pm/hydra/tools/demux/demux.c b/src/pm/hydra/tools/demux/demux.c index 99b43a7868a..c3dd1fb5019 100644 --- a/src/pm/hydra/tools/demux/demux.c +++ b/src/pm/hydra/tools/demux/demux.c @@ -10,23 +10,8 @@ int HYDT_dmxu_num_cb_fds = 0; struct HYDT_dmxu_callback *HYDT_dmxu_cb_list = NULL; struct HYDT_dmxu_fns HYDT_dmxu_fns; -static int got_sigttin = 0; static int stdin_valid; -#if defined(SIGTTIN) -static void signal_cb(int sig) -{ - HYDU_FUNC_ENTER(); - - if (sig == SIGTTIN) - got_sigttin = 1; - /* Ignore all other signals */ - - HYDU_FUNC_EXIT(); - return; -} -#endif /* SIGTTIN */ - HYD_status HYDT_dmx_init(char **demux) { HYD_status status = HYD_SUCCESS; @@ -249,7 +234,7 @@ HYD_status HYDT_dmxi_stdin_valid(int *out) */ #if defined(SIGTTIN) - status = HYDU_set_signal(SIGTTIN, signal_cb); + status = HYDU_set_signal(SIGTTIN, SIG_IGN); HYDU_ERR_POP(status, "unable to set SIGTTIN\n"); #endif /* SIGTTIN */ @@ -259,11 +244,6 @@ HYD_status HYDT_dmxi_stdin_valid(int *out) else *out = 0; -#if defined(SIGTTIN) - status = HYDU_set_signal(SIGTTIN, SIG_IGN); - HYDU_ERR_POP(status, "unable to set SIGTTIN\n"); -#endif /* SIGTTIN */ - fn_exit: HYDU_FUNC_EXIT(); return status; From b986872e0848ddafd7ad3dd533120b1abad6d3dc Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Thu, 6 Jan 2022 09:59:54 -0600 Subject: [PATCH 287/607] misc: Fix set but never used variables --- src/mpi/comm/commutil.c | 1 + src/mpi/errhan/errhan_impl.c | 23 +++++++++++++---------- src/mpi/errhan/errutil.c | 1 + src/mpid/ch4/netmod/ofi/ofi_am_impl.h | 4 ++-- src/mpid/ch4/src/init_comm.c | 2 +- src/mpid/ch4/src/mpidig_send.h | 3 +-- src/mpid/ch4/src/mpidig_send_utils.h | 3 +-- 7 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/mpi/comm/commutil.c b/src/mpi/comm/commutil.c index 4c04188b0ef..bb897a7ff66 100644 --- a/src/mpi/comm/commutil.c +++ b/src/mpi/comm/commutil.c @@ -1020,6 +1020,7 @@ int MPIR_Comm_delete_internal(MPIR_Comm * comm_ptr) /* Release the temporary reference added before the call to * attr_free */ MPIR_Object_release_ref(comm_ptr, &in_use); + MPIR_Assertp(in_use == 0); } /* If the attribute delete functions return failure, the diff --git a/src/mpi/errhan/errhan_impl.c b/src/mpi/errhan/errhan_impl.c index 91664d27112..dc070a75e01 100644 --- a/src/mpi/errhan/errhan_impl.c +++ b/src/mpi/errhan/errhan_impl.c @@ -256,7 +256,6 @@ static int call_errhandler(MPIR_Errhandler * errhandler, int errorcode, int hand int mpi_errno = MPI_SUCCESS; int kind = HANDLE_GET_MPI_KIND(handle); - int cxx_kind = 0; /* Check for predefined error handlers */ if (!errhandler || errhandler->handle == MPI_ERRORS_ARE_FATAL || @@ -295,16 +294,20 @@ static int call_errhandler(MPIR_Errhandler * errhandler, int errorcode, int hand break; #ifdef HAVE_CXX_BINDING case MPIR_LANG__CXX: - if (kind == MPIR_COMM) { - cxx_kind = 0; - } else if (kind == MPIR_WIN) { - cxx_kind = 2; - } else { - MPIR_Assert_error("kind not supported"); + { + int cxx_kind = 0; + if (kind == MPIR_COMM) { + cxx_kind = 0; + } else if (kind == MPIR_WIN) { + cxx_kind = 2; + } else { + MPIR_Assert_error("kind not supported"); + } + MPIR_Process.cxx_call_errfn(cxx_kind, &handle, &errorcode, + (void (*)(void)) errhandler-> + errfn.C_Comm_Handler_function); + break; } - MPIR_Process.cxx_call_errfn(cxx_kind, &handle, &errorcode, - (void (*)(void)) errhandler->errfn.C_Comm_Handler_function); - break; #endif #ifdef HAVE_FORTRAN_BINDING case MPIR_LANG__FORTRAN90: diff --git a/src/mpi/errhan/errutil.c b/src/mpi/errhan/errutil.c index 0cac05223e3..22abb4c7a0c 100644 --- a/src/mpi/errhan/errutil.c +++ b/src/mpi/errhan/errutil.c @@ -1749,6 +1749,7 @@ static void MPIR_Err_stack_init(void) int mpi_errno = MPI_SUCCESS; error_ring_mutex_create(&mpi_errno); + MPIR_Assertp(mpi_errno == MPI_SUCCESS); if (MPIR_CVAR_CHOP_ERROR_STACK < 0) { MPIR_CVAR_CHOP_ERROR_STACK = 80; diff --git a/src/mpid/ch4/netmod/ofi/ofi_am_impl.h b/src/mpid/ch4/netmod/ofi/ofi_am_impl.h index 25c35b63e7e..35f207fbee7 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_am_impl.h +++ b/src/mpid/ch4/netmod/ofi/ofi_am_impl.h @@ -374,7 +374,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_am_isend_pipeline(int rank, MPIR_Comm * c MPIDI_OFI_am_send_pipeline_request_t * send_req, int vni_src, int vni_dst) { - int mpi_errno = MPI_SUCCESS, c; + int mpi_errno = MPI_SUCCESS; MPIDI_OFI_am_header_t *msg_hdr; int nic = 0; int ctx_idx = MPIDI_OFI_get_ctx_index(comm, vni_src, nic); @@ -404,7 +404,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_am_isend_pipeline(int rank, MPIR_Comm * c msg_hdr->seqno = MPIDI_OFI_am_fetch_incr_send_seqno(vni_src, dst_addr); msg_hdr->fi_src_addr = MPIDI_OFI_rank_to_phys(MPIR_Process.rank, nic, vni_src, vni_src); - MPIR_cc_incr(sreq->cc_ptr, &c); + MPIR_cc_inc(sreq->cc_ptr); send_req->event_id = MPIDI_OFI_EVENT_AM_SEND_PIPELINE; MPI_Aint total_msg_sz = sizeof(*msg_hdr) + am_hdr_sz + seg_sz; diff --git a/src/mpid/ch4/src/init_comm.c b/src/mpid/ch4/src/init_comm.c index b971be79790..80eb39d92e8 100644 --- a/src/mpid/ch4/src/init_comm.c +++ b/src/mpid/ch4/src/init_comm.c @@ -64,7 +64,7 @@ void MPIDI_destroy_init_comm(MPIR_Comm ** comm_ptr) MPIDIU_release_lut(MPIDI_COMM(comm, map).irreg.lut.t); MPIDIG_destroy_comm(comm); MPIR_Object_release_ref(comm, &in_use); - MPIR_Assert(MPIR_Object_get_ref(comm) == 0); + MPIR_Assertp(in_use == 0); MPII_COMML_FORGET(comm); MPIR_Handle_obj_free(&MPIR_Comm_mem, comm); *comm_ptr = NULL; diff --git a/src/mpid/ch4/src/mpidig_send.h b/src/mpid/ch4/src/mpidig_send.h index 812c455401c..6503f3006e2 100644 --- a/src/mpid/ch4/src/mpidig_send.h +++ b/src/mpid/ch4/src/mpidig_send.h @@ -71,8 +71,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_isend_impl(const void *buf, MPI_Aint count, am_hdr.sreq_ptr = sreq; am_hdr.flags = flags; if (flags & MPIDIG_AM_SEND_FLAGS_SYNC) { - int c; - MPIR_cc_incr(sreq->cc_ptr, &c); /* expecting SSEND_ACK */ + MPIR_cc_inc(sreq->cc_ptr); /* expecting SSEND_ACK */ } MPI_Aint data_sz; MPIDI_Datatype_check_size(datatype, count, data_sz); diff --git a/src/mpid/ch4/src/mpidig_send_utils.h b/src/mpid/ch4/src/mpidig_send_utils.h index ac6d1edac84..f950aecbeef 100644 --- a/src/mpid/ch4/src/mpidig_send_utils.h +++ b/src/mpid/ch4/src/mpidig_send_utils.h @@ -13,7 +13,6 @@ MPL_STATIC_INLINE_PREFIX void MPIDIG_am_send_async_init(MPIR_Request * sreq, MPI_Datatype datatype, MPI_Aint data_sz) { - int c; MPIDIG_sreq_async_t *send_async = &MPIDIG_REQUEST(sreq, req->send_async); send_async->datatype = datatype; send_async->data_sz_left = data_sz; @@ -21,7 +20,7 @@ MPL_STATIC_INLINE_PREFIX void MPIDIG_am_send_async_init(MPIR_Request * sreq, MPI send_async->seg_issued = 0; send_async->seg_completed = 0; /* hold reference to the sreq and datatype at the start of send operation */ - MPIR_cc_incr(sreq->cc_ptr, &c); + MPIR_cc_inc(sreq->cc_ptr); MPIR_Datatype_add_ref_if_not_builtin(send_async->datatype); } From 2a83c693ad99aade9e120a3717fceea985432785 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Fri, 7 Jan 2022 12:22:54 -0600 Subject: [PATCH 288/607] misc: Remove unreachable break statements Each of these statements are unreachable due to either a goto or return statement preceeding them. --- src/mpi/coll/algorithms/treealgo/treealgo.c | 1 - src/mpi/datatype/get_elements_x.c | 6 ------ src/mpi/rma/rmatypeutil.c | 3 --- src/mpi_t/pvar_impl.c | 5 ----- src/mpid/ch4/netmod/ofi/ofi_events.c | 2 -- src/mpid/ch4/netmod/ofi/ofi_probe.h | 1 - src/mpid/ch4/shm/posix/posix_progress.h | 1 - 7 files changed, 19 deletions(-) diff --git a/src/mpi/coll/algorithms/treealgo/treealgo.c b/src/mpi/coll/algorithms/treealgo/treealgo.c index 95f6134f43f..5e570a35297 100644 --- a/src/mpi/coll/algorithms/treealgo/treealgo.c +++ b/src/mpi/coll/algorithms/treealgo/treealgo.c @@ -57,7 +57,6 @@ int MPIR_Treealgo_tree_create(int rank, int nranks, int tree_type, int k, int ro default: MPIR_ERR_SETANDJUMP1(mpi_errno, MPI_ERR_OTHER, "**treetype", "**treetype %d", tree_type); - break; } MPIR_FUNC_EXIT; diff --git a/src/mpi/datatype/get_elements_x.c b/src/mpi/datatype/get_elements_x.c index 3f69924fb7d..b71edaddcd1 100644 --- a/src/mpi/datatype/get_elements_x.c +++ b/src/mpi/datatype/get_elements_x.c @@ -164,7 +164,6 @@ static MPI_Count MPIR_Type_get_elements(MPI_Count * bytes_p, MPI_Count count, MP case MPI_COMBINER_DUP: case MPI_COMBINER_RESIZED: return MPIR_Type_get_elements(bytes_p, count, *types); - break; case MPI_COMBINER_CONTIGUOUS: case MPI_COMBINER_VECTOR: case MPI_COMBINER_HVECTOR: @@ -175,7 +174,6 @@ static MPI_Count MPIR_Type_get_elements(MPI_Count * bytes_p, MPI_Count count, MP } else { return MPIR_Type_get_elements(bytes_p, count * counts[0], *types); } - break; case MPI_COMBINER_INDEXED_BLOCK: case MPI_COMBINER_HINDEXED_BLOCK: if (cp->nr_counts == 0) { @@ -184,7 +182,6 @@ static MPI_Count MPIR_Type_get_elements(MPI_Count * bytes_p, MPI_Count count, MP } else { return MPIR_Type_get_elements(bytes_p, count * counts[0] * counts[1], *types); } - break; case MPI_COMBINER_INDEXED: case MPI_COMBINER_HINDEXED: { @@ -200,7 +197,6 @@ static MPI_Count MPIR_Type_get_elements(MPI_Count * bytes_p, MPI_Count count, MP } return MPIR_Type_get_elements(bytes_p, count * typecount, *types); } - break; case MPI_COMBINER_STRUCT: /* In this case we can't simply multiply the count of the next * type by the count of the current type, because we need to @@ -255,7 +251,6 @@ static MPI_Count MPIR_Type_get_elements(MPI_Count * bytes_p, MPI_Count count, MP } return nr_elements; } - break; case MPI_COMBINER_DARRAY: case MPI_COMBINER_F90_REAL: case MPI_COMBINER_F90_COMPLEX: @@ -267,7 +262,6 @@ static MPI_Count MPIR_Type_get_elements(MPI_Count * bytes_p, MPI_Count count, MP /* --BEGIN ERROR HANDLING-- */ MPIR_Assert(0); return -1; - break; /* --END ERROR HANDLING-- */ } } diff --git a/src/mpi/rma/rmatypeutil.c b/src/mpi/rma/rmatypeutil.c index 66d0957e8ce..ade9e46e102 100644 --- a/src/mpi/rma/rmatypeutil.c +++ b/src/mpi/rma/rmatypeutil.c @@ -29,11 +29,9 @@ int MPIR_Type_is_rma_atomic(MPI_Datatype type) MPIR_OP_TYPE_GROUP(LOGICAL_EXTRA) MPIR_OP_TYPE_GROUP(BYTE_EXTRA) return TRUE; - break; #undef MPIR_OP_TYPE_MACRO default: return FALSE; - break; } } @@ -61,7 +59,6 @@ int MPIR_Compare_equal(const void *a, const void *b, MPI_Datatype type) #undef MPIR_OP_TYPE_MACRO default: return FALSE; - break; } return FALSE; diff --git a/src/mpi_t/pvar_impl.c b/src/mpi_t/pvar_impl.c index 7b399e7112a..62d14a44e8c 100644 --- a/src/mpi_t/pvar_impl.c +++ b/src/mpi_t/pvar_impl.c @@ -238,7 +238,6 @@ int MPIR_T_pvar_read_impl(MPI_T_pvar_session session, MPI_T_pvar_handle handle, /* Code should never come here */ mpi_errno = MPI_ERR_INTERN; goto fn_fail; - break; } } else { /* A running SUM with callback. Read its current value into handle */ @@ -277,7 +276,6 @@ int MPIR_T_pvar_read_impl(MPI_T_pvar_session session, MPI_T_pvar_handle handle, /* Code should never come here */ mpi_errno = MPI_ERR_INTERN; goto fn_fail; - break; } } } else if (MPIR_T_pvar_is_sum(handle) && !MPIR_T_pvar_is_started(handle)) { @@ -312,7 +310,6 @@ int MPIR_T_pvar_read_impl(MPI_T_pvar_session session, MPI_T_pvar_handle handle, /* Code should never come here */ mpi_errno = MPI_ERR_INTERN; goto fn_fail; - break; } } else { /* For remaining handles, their current value are in the handle */ @@ -333,7 +330,6 @@ int MPIR_T_pvar_read_impl(MPI_T_pvar_session session, MPI_T_pvar_handle handle, /* Code should never come here */ mpi_errno = MPI_ERR_INTERN; goto fn_fail; - break; } } } else { @@ -536,7 +532,6 @@ int MPIR_T_pvar_stop_impl(MPI_T_pvar_session session, MPI_T_pvar_handle handle) /* Code should never come here */ mpi_errno = MPI_ERR_INTERN; goto fn_fail; - break; } } else if (MPIR_T_pvar_is_watermark(handle)) { diff --git a/src/mpid/ch4/netmod/ofi/ofi_events.c b/src/mpid/ch4/netmod/ofi/ofi_events.c index 9df23a18aca..50c8af3deda 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_events.c +++ b/src/mpid/ch4/netmod/ofi/ofi_events.c @@ -609,7 +609,6 @@ int MPIDI_OFI_handle_cq_error(int vni, int nic, ssize_t ret) MPIR_ERR_SETFATALANDJUMP4(mpi_errno, MPI_ERR_OTHER, "**ofid_poll", "**ofid_poll %s %d %s %s", __SHORT_FILE__, __LINE__, __func__, fi_strerror(e.err)); - break; } break; @@ -618,7 +617,6 @@ int MPIDI_OFI_handle_cq_error(int vni, int nic, ssize_t ret) MPIR_ERR_SETFATALANDJUMP4(mpi_errno, MPI_ERR_OTHER, "**ofid_poll", "**ofid_poll %s %d %s %s", __SHORT_FILE__, __LINE__, __func__, fi_strerror(errno)); - break; } fn_exit: diff --git a/src/mpid/ch4/netmod/ofi/ofi_probe.h b/src/mpid/ch4/netmod/ofi/ofi_probe.h index cae8b5fc38f..335c319dcb9 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_probe.h +++ b/src/mpid/ch4/netmod/ofi/ofi_probe.h @@ -88,7 +88,6 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_do_iprobe(int source, MPIDI_CH4_REQUEST_FREE(rreq); goto fn_exit; - break; case MPIDI_OFI_PEEK_FOUND: MPIR_Request_extract_status(rreq, status); diff --git a/src/mpid/ch4/shm/posix/posix_progress.h b/src/mpid/ch4/shm/posix/posix_progress.h index 4195630205e..a38032d39e8 100644 --- a/src/mpid/ch4/shm/posix/posix_progress.h +++ b/src/mpid/ch4/shm/posix/posix_progress.h @@ -58,7 +58,6 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_progress_recv(int vsi, int blocking) attr, NULL); MPIDI_POSIX_eager_recv_commit(&transaction); goto fn_exit; - break; case MPIDI_POSIX_AM_TYPE__PIPELINE: MPIDIG_global.target_msg_cbs[msg_hdr->handler_id] (am_hdr, NULL, payload_left, attr | MPIDIG_AM_ATTR__IS_ASYNC, From 61f9f546f6c6b2558fef7775c54de8e4abc8cbdf Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Fri, 7 Jan 2022 12:26:59 -0600 Subject: [PATCH 289/607] op: Fix large user function setting Casting a function pointer to void * is unsafe and is warned by some compilers. --- src/mpi/coll/op/op_impl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mpi/coll/op/op_impl.c b/src/mpi/coll/op/op_impl.c index 4d9a18ccb5f..6acacc46899 100644 --- a/src/mpi/coll/op/op_impl.c +++ b/src/mpi/coll/op/op_impl.c @@ -78,10 +78,13 @@ int MPIR_Op_create_impl(MPI_User_function * user_fn, int commute, MPIR_Op ** p_o int MPIR_Op_create_large_impl(MPI_User_function_c * user_fn, int commute, MPIR_Op ** p_op_ptr) { - int mpi_errno = MPIR_Op_create_impl((void *) user_fn, commute, p_op_ptr); + int mpi_errno = MPIR_Op_create_impl(NULL, commute, p_op_ptr); if (mpi_errno == MPI_SUCCESS) { (*p_op_ptr)->kind = commute ? MPIR_OP_KIND__USER_LARGE : MPIR_OP_KIND__USER_NONCOMMUTE_LARGE; + (*p_op_ptr)->function.c_large_function = (void (*)(const void *, void *, + const MPI_Count *, + const MPI_Datatype *)) user_fn; } return mpi_errno; } From 9378bd4ce82c8111f1620310f0b2e7c255fbd363 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Fri, 7 Jan 2022 12:28:28 -0600 Subject: [PATCH 290/607] comm: Fix sign conversion warning --- src/mpi/comm/contextid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mpi/comm/contextid.c b/src/mpi/comm/contextid.c index 534a8118f05..aa193cfbea7 100644 --- a/src/mpi/comm/contextid.c +++ b/src/mpi/comm/contextid.c @@ -1081,7 +1081,7 @@ int MPIR_Get_intercomm_contextid(MPIR_Comm * comm_ptr, MPIR_Context_id_t * conte /* MPIC routine uses an internal context id. The local leads (process 0) * exchange data */ - remote_context_id = -1; + remote_context_id = (MPIR_Context_id_t) - 1; if (comm_ptr->rank == 0) { mpi_errno = MPIC_Sendrecv(&mycontext_id, 1, MPIR_CONTEXT_ID_T_DATATYPE, 0, tag, &remote_context_id, 1, MPIR_CONTEXT_ID_T_DATATYPE, 0, tag, From 115c78094ef11398c015f9844685a0941c7a41c2 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Fri, 7 Jan 2022 12:29:09 -0600 Subject: [PATCH 291/607] ch4/ofi: Fix hint setting function These calls to MPIR_ERR_POP should actually be checking for errors with MPIR_ERR_CHECK. --- src/mpid/ch4/netmod/ofi/ofi_comm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mpid/ch4/netmod/ofi/ofi_comm.c b/src/mpid/ch4/netmod/ofi/ofi_comm.c index d56c9bf70f5..326d32aac56 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_comm.c +++ b/src/mpid/ch4/netmod/ofi/ofi_comm.c @@ -194,9 +194,9 @@ int MPIDI_OFI_comm_set_hints(MPIR_Comm * comm, MPIR_Info * info) int mpi_errno = MPI_SUCCESS; mpi_errno = update_multi_nic_hints(comm); - MPIR_ERR_POP(mpi_errno); + MPIR_ERR_CHECK(mpi_errno); mpi_errno = update_nic_preferences(comm); - MPIR_ERR_POP(mpi_errno); + MPIR_ERR_CHECK(mpi_errno); fn_exit: return mpi_errno; From d68ef7a157b7d770ab16813b641be89b5c110e65 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Fri, 7 Jan 2022 12:31:01 -0600 Subject: [PATCH 292/607] ch4: Fix max node id function The node id is supposed to be return via the user supplied pointer, not the return value. Note there are no longer any callers of this function, so it might make sense to just remove it from the ADI. --- src/mpid/ch4/src/ch4_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mpid/ch4/src/ch4_init.c b/src/mpid/ch4/src/ch4_init.c index cd7d45a70ad..98b55c25d31 100644 --- a/src/mpid/ch4/src/ch4_init.c +++ b/src/mpid/ch4/src/ch4_init.c @@ -795,7 +795,7 @@ int MPID_Get_max_node_id(MPIR_Comm * comm, int *max_id_p) int mpi_errno = MPI_SUCCESS; MPIR_FUNC_ENTER; - return MPIR_Process.num_nodes - 1; + *max_id_p = MPIR_Process.num_nodes - 1; MPIR_FUNC_EXIT; return mpi_errno; From 1eba9105ab68429918fff498b212027199d7db9d Mon Sep 17 00:00:00 2001 From: Sagar Thapaliya Date: Thu, 6 Jan 2022 17:10:59 -0600 Subject: [PATCH 293/607] ch4: fix comm hints overwrite bug Comm hints were registered every time a comm was created. This should be a one time setup during CH4 init. --- src/mpid/ch4/src/ch4_comm.c | 15 --------------- src/mpid/ch4/src/ch4_init.c | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/mpid/ch4/src/ch4_comm.c b/src/mpid/ch4/src/ch4_comm.c index cbb0ba377d2..bc6d42728d6 100644 --- a/src/mpid/ch4/src/ch4_comm.c +++ b/src/mpid/ch4/src/ch4_comm.c @@ -8,7 +8,6 @@ #include "ch4_comm.h" #include "ch4i_comm.h" -static void register_comm_hints(MPIR_Comm * comm); int MPID_Comm_reenable_anysource(MPIR_Comm * comm, MPIR_Group ** failed_group_ptr) { @@ -190,8 +189,6 @@ int MPID_Comm_commit_pre_hook(MPIR_Comm * comm) } } - register_comm_hints(comm); - mpi_errno = MPIDIG_init_comm(comm); MPIR_ERR_CHECK(mpi_errno); @@ -646,15 +643,3 @@ int MPID_Create_intercomm_from_lpids(MPIR_Comm * newcomm_ptr, int size, const ui fn_fail: goto fn_exit; } - -/* Register CH4-specific hints */ -static void register_comm_hints(MPIR_Comm * comm) -{ - /* Non-standard hints for VCI selection. Default value MPIDI_VCI_INVALID (-1) */ - MPIR_Comm_register_hint(MPIR_COMM_HINT_SENDER_VCI, "sender_vci", - MPIDI_set_comm_hint_sender_vci, MPIR_COMM_HINT_TYPE_INT, 0, -1); - MPIR_Comm_register_hint(MPIR_COMM_HINT_RECEIVER_VCI, "receiver_vci", - MPIDI_set_comm_hint_receiver_vci, MPIR_COMM_HINT_TYPE_INT, 0, -1); - MPIR_Comm_register_hint(MPIR_COMM_HINT_VCI, "vci", - MPIDI_set_comm_hint_vci, MPIR_COMM_HINT_TYPE_INT, 0, -1); -} diff --git a/src/mpid/ch4/src/ch4_init.c b/src/mpid/ch4/src/ch4_init.c index 98b55c25d31..cfafe7565bf 100644 --- a/src/mpid/ch4/src/ch4_init.c +++ b/src/mpid/ch4/src/ch4_init.c @@ -300,6 +300,20 @@ static int set_runtime_configurations(void) #error "Thread Granularity: Invalid" #endif +/* Register CH4-specific hints */ +static void register_comm_hints(void) +{ + /* Non-standard hints for VCI selection. */ + MPIR_Comm_register_hint(MPIR_COMM_HINT_SENDER_VCI, "sender_vci", + MPIDI_set_comm_hint_sender_vci, MPIR_COMM_HINT_TYPE_INT, 0, + MPIDI_VCI_INVALID); + MPIR_Comm_register_hint(MPIR_COMM_HINT_RECEIVER_VCI, "receiver_vci", + MPIDI_set_comm_hint_receiver_vci, MPIR_COMM_HINT_TYPE_INT, 0, + MPIDI_VCI_INVALID); + MPIR_Comm_register_hint(MPIR_COMM_HINT_VCI, "vci", MPIDI_set_comm_hint_vci, + MPIR_COMM_HINT_TYPE_INT, 0, MPIDI_VCI_INVALID); +} + int MPID_Init(int requested, int *provided) { int mpi_errno = MPI_SUCCESS; @@ -455,6 +469,8 @@ int MPID_Init(int requested, int *provided) MPIR_Process.attrs.appnum = MPIR_Process.appnum; MPIR_Process.attrs.io = MPI_ANY_SOURCE; + register_comm_hints(); + fn_exit: MPIR_FUNC_EXIT; return mpi_errno; From 3fddf9080b6d58a18a02af7228fd1e3c6ab3d04d Mon Sep 17 00:00:00 2001 From: Sagar Thapaliya Date: Thu, 6 Jan 2022 17:15:30 -0600 Subject: [PATCH 294/607] ch4: remove incorrect resetting of VCI hints VCI hints were being initialized to default values at an incorrect and unnecessary location. This was leading to wiping out the earlier set VCI hints. As a result, info hints were not applied when passed to the comm creation routines such as MPI_Comm_dup_with_info. This patch fixes this problem. --- src/mpid/ch4/src/ch4_comm.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/mpid/ch4/src/ch4_comm.c b/src/mpid/ch4/src/ch4_comm.c index bc6d42728d6..40aaa60e387 100644 --- a/src/mpid/ch4/src/ch4_comm.c +++ b/src/mpid/ch4/src/ch4_comm.c @@ -192,11 +192,6 @@ int MPID_Comm_commit_pre_hook(MPIR_Comm * comm) mpi_errno = MPIDIG_init_comm(comm); MPIR_ERR_CHECK(mpi_errno); - /* vci hints defaults */ - comm->hints[MPIR_COMM_HINT_SENDER_VCI] = MPIDI_VCI_INVALID; - comm->hints[MPIR_COMM_HINT_RECEIVER_VCI] = MPIDI_VCI_INVALID; - comm->hints[MPIR_COMM_HINT_VCI] = MPIDI_VCI_INVALID; - mpi_errno = MPIDI_NM_mpi_comm_commit_pre_hook(comm); MPIR_ERR_CHECK(mpi_errno); #ifndef MPIDI_CH4_DIRECT_NETMOD From 43dc1c0b3a3b6b030346e4a7ceab193c5642a696 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 7 Mar 2021 21:17:48 -0600 Subject: [PATCH 295/607] hydra: add parsing routines for pmi-args Singleton init will launch mpiexec with `-pmi-args port interface key pid`. This commit adds the parsing routines. --- src/pm/hydra/include/hydra_server.h | 3 +++ src/pm/hydra/ui/mpich/utils.c | 25 +++++++++++++++++++++++++ src/pm/hydra/ui/utils/uiu.c | 3 +++ 3 files changed, 31 insertions(+) diff --git a/src/pm/hydra/include/hydra_server.h b/src/pm/hydra/include/hydra_server.h index eeb5c492d26..c8c752ee21b 100644 --- a/src/pm/hydra/include/hydra_server.h +++ b/src/pm/hydra/include/hydra_server.h @@ -28,6 +28,9 @@ struct HYD_server_info_s { char *localhost; time_t time_start; + int singleton_port; + int singleton_pid; + HYD_status(*stdout_cb) (int pgid, int proxy_id, int rank, void *buf, int buflen); HYD_status(*stderr_cb) (int pgid, int proxy_id, int rank, void *buf, int buflen); diff --git a/src/pm/hydra/ui/mpich/utils.c b/src/pm/hydra/ui/mpich/utils.c index b4d69d3f923..d11b17ec6ea 100644 --- a/src/pm/hydra/ui/mpich/utils.c +++ b/src/pm/hydra/ui/mpich/utils.c @@ -1471,6 +1471,28 @@ static HYD_status skip_launch_node_fn(char *arg, char ***argv) goto fn_exit; } +static void pmi_args_help_fn(void) +{ + printf("\n"); + printf("-pmi-args port default_interface default_key pid:\n"); + printf(" Supply pmi-args when mpiexec is launched from singleton init.\n"); + printf(" Both port for mpiexec to connect back to the singleton process\n"); + printf(" and the pid of the singleton process are required. The interface\n"); + printf(" name and authentication key are ignored for now.\n"); +} + +static HYD_status pmi_args_fn(char *arg, char ***argv) +{ + HYD_status status = HYD_SUCCESS; + + HYD_server_info.singleton_port = atoi((*argv)[0]); + HYD_server_info.singleton_pid = atoi((*argv)[3]); + + (*argv) += 4; + + return status; +} + static void gpus_per_proc_help_fn(void) { printf("\n"); @@ -1881,5 +1903,8 @@ static struct HYD_arg_match_table match_table[] = { {"gpus-per-proc", gpus_per_proc_fn, gpus_per_proc_help_fn}, {"g", gpus_per_proc_fn, gpus_per_proc_help_fn}, + /* Singleton init */ + {"pmi_args", pmi_args_fn, pmi_args_help_fn}, + {"\0", NULL, NULL} }; diff --git a/src/pm/hydra/ui/utils/uiu.c b/src/pm/hydra/ui/utils/uiu.c index 07c60f49a9d..174534d70fd 100644 --- a/src/pm/hydra/ui/utils/uiu.c +++ b/src/pm/hydra/ui/utils/uiu.c @@ -27,6 +27,9 @@ void HYD_uiu_init_params(void) HYD_server_info.localhost = NULL; HYD_server_info.time_start = time(NULL); + HYD_server_info.singleton_port = 0; + HYD_server_info.singleton_pid = 0; + HYD_server_info.stdout_cb = NULL; HYD_server_info.stderr_cb = NULL; From ddb8f30922ea1dd3ed4c448e8a5f2430085db0ec Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 7 Mar 2021 23:24:33 -0600 Subject: [PATCH 296/607] hydra: pass singleton info to proxy via commandline --- src/pm/hydra/pm/pmiserv/pmiserv_utils.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/pm/hydra/pm/pmiserv/pmiserv_utils.c b/src/pm/hydra/pm/pmiserv/pmiserv_utils.c index 0d9457747af..2aabb432ffa 100644 --- a/src/pm/hydra/pm/pmiserv/pmiserv_utils.c +++ b/src/pm/hydra/pm/pmiserv/pmiserv_utils.c @@ -104,6 +104,14 @@ HYD_status HYD_pmcd_pmi_fill_in_proxy_args(struct HYD_string_stash *proxy_stash, HYD_STRING_STASH(*proxy_stash, HYDU_int_to_str(HYD_server_info.user_global.gpus_per_proc), status); + if (pgid == 0 && HYD_server_info.singleton_port > 0) { + HYD_STRING_STASH(*proxy_stash, MPL_strdup("--singleton-port"), status); + HYD_STRING_STASH(*proxy_stash, HYDU_int_to_str(HYD_server_info.singleton_port), status); + + HYD_STRING_STASH(*proxy_stash, MPL_strdup("--singleton-pid"), status); + HYD_STRING_STASH(*proxy_stash, HYDU_int_to_str(HYD_server_info.singleton_pid), status); + } + HYD_STRING_STASH(*proxy_stash, MPL_strdup("--proxy-id"), status); if (HYD_server_info.user_global.debug) { From 6d51feb6ed4996ab4aa987669a9361b4276be4bc Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 7 Mar 2021 23:50:25 -0600 Subject: [PATCH 297/607] hydra: fix segfaults when missing executables When we run mpiexec without an executables, exit with error rather than leave it and segfault. --- src/pm/hydra/utils/alloc/alloc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/pm/hydra/utils/alloc/alloc.c b/src/pm/hydra/utils/alloc/alloc.c index fe0214deb0d..11dfa0706ff 100644 --- a/src/pm/hydra/utils/alloc/alloc.c +++ b/src/pm/hydra/utils/alloc/alloc.c @@ -426,7 +426,7 @@ HYD_status HYDU_create_proxy_list(struct HYD_exec *exec_list, struct HYD_node *n } /* find dummy proxies and remove them */ - while (pg->proxy_list->exec_list == NULL) { + while (pg->proxy_list && pg->proxy_list->exec_list == NULL) { tmp = pg->proxy_list->next; pg->proxy_list->next = NULL; HYDU_free_proxy_list(pg->proxy_list); @@ -436,6 +436,12 @@ HYD_status HYDU_create_proxy_list(struct HYD_exec *exec_list, struct HYD_node *n HYDU_ERR_POP(status, "Missing executable.\n"); } } + + if (!pg->proxy_list) { + status = HYD_FAILURE; + HYDU_ERR_POP(status, "Missing executables\n"); + } + for (proxy = pg->proxy_list; proxy->next;) { if (proxy->next->exec_list == NULL) { tmp = proxy->next; From 0ad79623188c8ec145b605f0639d92a1e3cbf1b0 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 20 Mar 2021 18:31:48 -0500 Subject: [PATCH 298/607] hydra: add is_singleton to HYDU_create_proxy_list Need to know whether it is a singleton init to proceed without exec_list. --- src/pm/hydra/include/hydra.h | 2 +- src/pm/hydra/pm/pmiserv/pmiserv_pmi_v1.c | 4 +- src/pm/hydra/pm/pmiserv/pmiserv_pmi_v2.c | 4 +- src/pm/hydra/ui/mpich/mpiexec.c | 2 +- src/pm/hydra/utils/alloc/alloc.c | 49 +++++++++++++----------- 5 files changed, 32 insertions(+), 29 deletions(-) diff --git a/src/pm/hydra/include/hydra.h b/src/pm/hydra/include/hydra.h index 0cd2c12634a..75a68e9b478 100644 --- a/src/pm/hydra/include/hydra.h +++ b/src/pm/hydra/include/hydra.h @@ -503,7 +503,7 @@ void HYDU_free_proxy_list(struct HYD_proxy *proxy_list); HYD_status HYDU_alloc_exec(struct HYD_exec **exec); void HYDU_free_exec_list(struct HYD_exec *exec_list); HYD_status HYDU_create_proxy_list(struct HYD_exec *exec_list, struct HYD_node *node_list, - struct HYD_pg *pg); + struct HYD_pg *pg, bool is_singleton); HYD_status HYDU_correct_wdir(char **wdir); /* args */ diff --git a/src/pm/hydra/pm/pmiserv/pmiserv_pmi_v1.c b/src/pm/hydra/pm/pmiserv/pmiserv_pmi_v1.c index aaa5dcdc932..b06d23e8e89 100644 --- a/src/pm/hydra/pm/pmiserv/pmiserv_pmi_v1.c +++ b/src/pm/hydra/pm/pmiserv/pmiserv_pmi_v1.c @@ -539,10 +539,10 @@ static HYD_status fn_spawn(int fd, int pid, int pgid, char *args[]) /* Create the proxy list */ if (pg->user_node_list) { - status = HYDU_create_proxy_list(exec_list, pg->user_node_list, pg); + status = HYDU_create_proxy_list(exec_list, pg->user_node_list, pg, false); HYDU_ERR_POP(status, "error creating proxy list\n"); } else { - status = HYDU_create_proxy_list(exec_list, HYD_server_info.node_list, pg); + status = HYDU_create_proxy_list(exec_list, HYD_server_info.node_list, pg, false); HYDU_ERR_POP(status, "error creating proxy list\n"); } HYDU_free_exec_list(exec_list); diff --git a/src/pm/hydra/pm/pmiserv/pmiserv_pmi_v2.c b/src/pm/hydra/pm/pmiserv/pmiserv_pmi_v2.c index 55f184fc5f9..69b57e6e263 100644 --- a/src/pm/hydra/pm/pmiserv/pmiserv_pmi_v2.c +++ b/src/pm/hydra/pm/pmiserv/pmiserv_pmi_v2.c @@ -661,10 +661,10 @@ static HYD_status fn_spawn(int fd, int pid, int pgid, char *args[]) /* Create the proxy list */ if (pg->user_node_list) { - status = HYDU_create_proxy_list(exec_list, pg->user_node_list, pg); + status = HYDU_create_proxy_list(exec_list, pg->user_node_list, pg, false); HYDU_ERR_POP(status, "error creating proxy list\n"); } else { - status = HYDU_create_proxy_list(exec_list, HYD_server_info.node_list, pg); + status = HYDU_create_proxy_list(exec_list, HYD_server_info.node_list, pg, false); HYDU_ERR_POP(status, "error creating proxy list\n"); } HYDU_free_exec_list(exec_list); diff --git a/src/pm/hydra/ui/mpich/mpiexec.c b/src/pm/hydra/ui/mpich/mpiexec.c index 6d75b1a4a48..78b5c88b986 100644 --- a/src/pm/hydra/ui/mpich/mpiexec.c +++ b/src/pm/hydra/ui/mpich/mpiexec.c @@ -259,7 +259,7 @@ int main(int argc, char **argv) HYDU_ERR_POP(status, "unable to get the inherited env list\n"); status = HYDU_create_proxy_list(HYD_uii_mpx_exec_list, HYD_server_info.node_list, - &HYD_server_info.pg_list); + &HYD_server_info.pg_list, HYD_server_info.singleton_port > 0); HYDU_ERR_POP(status, "unable to create proxy list\n"); /* calculate the core count used by the PG */ diff --git a/src/pm/hydra/utils/alloc/alloc.c b/src/pm/hydra/utils/alloc/alloc.c index 11dfa0706ff..aa32fae13a2 100644 --- a/src/pm/hydra/utils/alloc/alloc.c +++ b/src/pm/hydra/utils/alloc/alloc.c @@ -312,7 +312,7 @@ static HYD_status add_exec_to_proxy(struct HYD_exec *exec, struct HYD_proxy *pro } HYD_status HYDU_create_proxy_list(struct HYD_exec *exec_list, struct HYD_node *node_list, - struct HYD_pg *pg) + struct HYD_pg *pg, bool is_singleton) { struct HYD_proxy *proxy = NULL, *last_proxy = NULL, *tmp; struct HYD_exec *exec; @@ -425,31 +425,34 @@ HYD_status HYDU_create_proxy_list(struct HYD_exec *exec_list, struct HYD_node *n } } - /* find dummy proxies and remove them */ - while (pg->proxy_list && pg->proxy_list->exec_list == NULL) { - tmp = pg->proxy_list->next; - pg->proxy_list->next = NULL; - HYDU_free_proxy_list(pg->proxy_list); - pg->proxy_list = tmp; - if (pg->proxy_list == NULL) { - status = HYD_FAILURE; - HYDU_ERR_POP(status, "Missing executable.\n"); + if (is_singleton) { + proxy = pg->proxy_list; + HYDU_ASSERT(proxy && proxy->exec_list == NULL && proxy->next == NULL, status); + proxy->proxy_process_count = 1; + proxy->node->active_processes = 1; + } else { + /* find dummy proxies and remove them */ + while (pg->proxy_list && pg->proxy_list->exec_list == NULL) { + tmp = pg->proxy_list->next; + pg->proxy_list->next = NULL; + HYDU_free_proxy_list(pg->proxy_list); + pg->proxy_list = tmp; } - } - if (!pg->proxy_list) { - status = HYD_FAILURE; - HYDU_ERR_POP(status, "Missing executables\n"); - } + if (!pg->proxy_list) { + status = HYD_FAILURE; + HYDU_ERR_POP(status, "Missing executables\n"); + } - for (proxy = pg->proxy_list; proxy->next;) { - if (proxy->next->exec_list == NULL) { - tmp = proxy->next; - proxy->next = proxy->next->next; - tmp->next = NULL; - HYDU_free_proxy_list(tmp); - } else { - proxy = proxy->next; + for (proxy = pg->proxy_list; proxy->next;) { + if (proxy->next->exec_list == NULL) { + tmp = proxy->next; + proxy->next = proxy->next->next; + tmp->next = NULL; + HYDU_free_proxy_list(tmp); + } else { + proxy = proxy->next; + } } } From 40e1a031e9b152b432366ade50ebcf42399a4514 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 20 Mar 2021 20:40:47 -0500 Subject: [PATCH 299/607] hydra: add singleton parsing to hydra_pmi_proxy --- src/pm/hydra/include/hydra.h | 2 ++ src/pm/hydra/pm/pmiserv/pmip_utils.c | 24 ++++++++++++++++++++++++ src/pm/hydra/utils/alloc/alloc.c | 2 ++ 3 files changed, 28 insertions(+) diff --git a/src/pm/hydra/include/hydra.h b/src/pm/hydra/include/hydra.h index 75a68e9b478..7120bb21c22 100644 --- a/src/pm/hydra/include/hydra.h +++ b/src/pm/hydra/include/hydra.h @@ -404,6 +404,8 @@ struct HYD_user_global { int pmi_port; int skip_launch_node; int gpus_per_proc; + int singleton_port; + int singleton_pid; struct HYD_env_global global_env; }; diff --git a/src/pm/hydra/pm/pmiserv/pmip_utils.c b/src/pm/hydra/pm/pmiserv/pmip_utils.c index e832fb9c913..6d0c72580b5 100644 --- a/src/pm/hydra/pm/pmiserv/pmip_utils.c +++ b/src/pm/hydra/pm/pmiserv/pmip_utils.c @@ -115,6 +115,28 @@ static HYD_status gpus_per_proc_fn(char *arg, char ***argv) return status; } +static HYD_status singleton_port_fn(char *arg, char ***argv) +{ + HYD_status status = HYD_SUCCESS; + + HYD_pmcd_pmip.user_global.singleton_port = atoi(**argv); + + (*argv)++; + + return status; +} + +static HYD_status singleton_pid_fn(char *arg, char ***argv) +{ + HYD_status status = HYD_SUCCESS; + + HYD_pmcd_pmip.user_global.singleton_pid = atoi(**argv); + + (*argv)++; + + return status; +} + static HYD_status rmk_fn(char *arg, char ***argv) { HYD_status status = HYD_SUCCESS; @@ -590,6 +612,8 @@ struct HYD_arg_match_table HYD_pmcd_pmip_match_table[] = { {"usize", usize_fn, NULL}, {"pmi-port", pmi_port_fn, NULL}, {"gpus-per-proc", gpus_per_proc_fn, NULL}, + {"singleton-port", singleton_port_fn, NULL}, + {"singleton-pid", singleton_pid_fn, NULL}, {"rmk", rmk_fn, NULL}, {"launcher", launcher_fn, NULL}, {"launcher-exec", launcher_exec_fn, NULL}, diff --git a/src/pm/hydra/utils/alloc/alloc.c b/src/pm/hydra/utils/alloc/alloc.c index aa32fae13a2..6ed76b8426b 100644 --- a/src/pm/hydra/utils/alloc/alloc.c +++ b/src/pm/hydra/utils/alloc/alloc.c @@ -26,6 +26,8 @@ void HYDU_init_user_global(struct HYD_user_global *user_global) user_global->pmi_port = -1; user_global->skip_launch_node = -1; user_global->gpus_per_proc = HYD_GPUS_PER_PROC_UNSET; + user_global->singleton_port = 0; + user_global->singleton_pid = 0; HYDU_init_global_env(&user_global->global_env); } From 83cc2765b3c94b31e9d5f9dc1173eda706e63bba Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 20 Mar 2021 22:48:44 -0500 Subject: [PATCH 300/607] hydra: add singleton_init Add singleton_init to handle singinit handshake. --- src/pm/hydra/pm/pmiserv/pmip_cb.c | 78 ++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 2 deletions(-) diff --git a/src/pm/hydra/pm/pmiserv/pmip_cb.c b/src/pm/hydra/pm/pmiserv/pmip_cb.c index f180cead998..06398cdf0cd 100644 --- a/src/pm/hydra/pm/pmiserv/pmip_cb.c +++ b/src/pm/hydra/pm/pmiserv/pmip_cb.c @@ -475,6 +475,75 @@ static int local_to_global_id(int local_id) return ret; } +static HYD_status singleton_init(void) +{ + HYD_status status = HYD_SUCCESS; + int sent, recvd, closed; + + HYD_pmcd_pmip.local.proxy_process_count = 1; + HYDU_MALLOC_OR_JUMP(HYD_pmcd_pmip.downstream.out, int *, sizeof(int), status); + HYDU_MALLOC_OR_JUMP(HYD_pmcd_pmip.downstream.err, int *, sizeof(int), status); + HYDU_MALLOC_OR_JUMP(HYD_pmcd_pmip.downstream.pid, int *, sizeof(int), status); + HYDU_MALLOC_OR_JUMP(HYD_pmcd_pmip.downstream.exit_status, int *, sizeof(int), status); + HYDU_MALLOC_OR_JUMP(HYD_pmcd_pmip.downstream.pmi_rank, int *, sizeof(int), status); + HYDU_MALLOC_OR_JUMP(HYD_pmcd_pmip.downstream.pmi_fd, int *, sizeof(int), status); + HYDU_MALLOC_OR_JUMP(HYD_pmcd_pmip.downstream.pmi_fd_active, int *, sizeof(int), status); + + HYD_pmcd_pmip.downstream.out[0] = 0; + HYD_pmcd_pmip.downstream.err[0] = 0; + HYD_pmcd_pmip.downstream.pid[0] = HYD_pmcd_pmip.user_global.singleton_pid; + HYD_pmcd_pmip.downstream.exit_status[0] = -1; + HYD_pmcd_pmip.downstream.pmi_rank[0] = 0; + HYD_pmcd_pmip.downstream.pmi_fd[0] = HYD_FD_UNSET; + HYD_pmcd_pmip.downstream.pmi_fd_active[0] = 1; + + int fd; + status = + HYDU_sock_connect("localhost", HYD_pmcd_pmip.user_global.singleton_port, &fd, 0, + HYD_CONNECT_DELAY); + HYDU_ERR_POP(status, "unable to connect to singleton process\n"); + + char msg[1024]; + strcpy(msg, "cmd=singinit authtype=none\n"); + status = HYDU_sock_write(fd, msg, strlen(msg), &sent, &closed, HYDU_SOCK_COMM_MSGWAIT); + HYDU_ERR_POP(status, "unable to send msg to singleton process\n"); + status = HYDU_sock_read(fd, msg, 1024, &recvd, &closed, HYDU_SOCK_COMM_NONE); + HYDU_ERR_POP(status, "unable to read msg from singleton process\n"); + MPL_snprintf(msg, 1024, "cmd=singinit_info versionok=yes stdio=no kvsname=%s\n", + HYD_pmcd_pmip.local.kvs->kvsname); + status = HYDU_sock_write(fd, msg, strlen(msg), &sent, &closed, HYDU_SOCK_COMM_MSGWAIT); + HYDU_ERR_POP(status, "unable to send msg to singleton process\n"); + + status = HYDT_dmx_register_fd(1, &fd, HYD_POLLIN, NULL, pmi_cb); + HYDU_ERR_POP(status, "unable to register fd\n"); + + /* Send the PID list upstream */ + struct HYD_pmcd_hdr hdr; + HYD_pmcd_init_header(&hdr); + hdr.cmd = PID_LIST; + status = + HYDU_sock_write(HYD_pmcd_pmip.upstream.control, &hdr, sizeof(hdr), &sent, &closed, + HYDU_SOCK_COMM_MSGWAIT); + HYDU_ERR_POP(status, "unable to send PID_LIST command upstream\n"); + HYDU_ASSERT(!closed, status); + + status = HYDU_sock_write(HYD_pmcd_pmip.upstream.control, + HYD_pmcd_pmip.downstream.pid, + HYD_pmcd_pmip.local.proxy_process_count * sizeof(int), &sent, + &closed, HYDU_SOCK_COMM_MSGWAIT); + HYDU_ERR_POP(status, "unable to send PID list upstream\n"); + HYDU_ASSERT(!closed, status); + + /* skip HYDT_dmx_register_fd */ + + fn_exit: + HYDU_FUNC_EXIT(); + return status; + + fn_fail: + goto fn_exit; +} + static HYD_status launch_procs(void) { int i, j, process_id, dummy; @@ -902,8 +971,13 @@ HYD_status HYD_pmcd_pmip_control_cmd_cb(int fd, HYD_event_t events, void *userp) status = procinfo(fd); HYDU_ERR_POP(status, "error parsing process info\n"); - status = launch_procs(); - HYDU_ERR_POP(status, "launch_procs returned error\n"); + if (HYD_pmcd_pmip.user_global.singleton_port > 0) { + status = singleton_init(); + HYDU_ERR_POP(status, "singleton_init returned error\n"); + } else { + status = launch_procs(); + HYDU_ERR_POP(status, "launch_procs returned error\n"); + } } else if (hdr.cmd == PMI_RESPONSE) { status = handle_pmi_response(fd, hdr); HYDU_ERR_POP(status, "unable to handle PMI response\n"); From 6c98a7aa2b3550a3daa8629b0dfbb4c17837e366 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 7 Jan 2022 18:04:17 -0600 Subject: [PATCH 301/607] ch3/nemesis: delay destroying window mutex On FreeBSD (at lease for ver 12.2), destroying the mutex and recreate the mutex, the new mutex will not work for inter-process. As workaround, delay destroying window mutex until finalize. --- .../channels/nemesis/include/mpidi_ch3_impl.h | 17 ++++ .../ch3/channels/nemesis/src/ch3_rma_shm.c | 87 ++++++++++++++++--- .../channels/nemesis/src/mpid_nem_finalize.c | 4 + .../ch3/channels/nemesis/src/mpid_nem_init.c | 4 + 4 files changed, 100 insertions(+), 12 deletions(-) diff --git a/src/mpid/ch3/channels/nemesis/include/mpidi_ch3_impl.h b/src/mpid/ch3/channels/nemesis/include/mpidi_ch3_impl.h index c7e9be58870..581632fc232 100644 --- a/src/mpid/ch3/channels/nemesis/include/mpidi_ch3_impl.h +++ b/src/mpid/ch3/channels/nemesis/include/mpidi_ch3_impl.h @@ -83,6 +83,8 @@ int MPID_nem_handle_pkt(MPIDI_VC_t *vc, char *buf, intptr_t buflen); /* Nemesis-provided RMA implementation */ int MPIDI_CH3_SHM_Win_shared_query(MPIR_Win *win_ptr, int target_rank, MPI_Aint *size, int *disp_unit, void *baseptr); int MPIDI_CH3_SHM_Win_free(MPIR_Win **win_ptr); +int MPIDI_CH3_SHM_Init(void); +int MPIDI_CH3_SHM_Finalize(void); /* Shared memory window atomic/accumulate mutex implementation */ @@ -114,6 +116,13 @@ int MPIDI_CH3_SHM_Win_free(MPIR_Win **win_ptr); MPIR_ERR_CHKANDJUMP1(pt_err, mpi_errno, MPI_ERR_OTHER, "**pthread_mutex", \ "**pthread_mutex %s", strerror(pt_err)); \ } while (0); + +#define MPIDI_CH3I_SHM_MUTEX_DESTROY_DIRECT(shm_mutex) \ + do { \ + int pt_err = pthread_mutex_destroy(shm_mutex); \ + MPIR_ERR_CHKANDJUMP1(pt_err, mpi_errno, MPI_ERR_OTHER, "**pthread_mutex", \ + "**pthread_mutex %s", strerror(pt_err)); \ + } while (0); #else #define HANDLE_WIN_MUTEX_ERROR() \ do { \ @@ -171,6 +180,14 @@ int MPIDI_CH3_SHM_Win_free(MPIR_Win **win_ptr); HANDLE_WIN_MUTEX_ERROR(); \ } \ } while (0); + +#define MPIDI_CH3I_SHM_MUTEX_DESTROY_DIRECT(shm_mutex) \ + do { \ + BOOL result = CloseHandle(*(shm_mutex)); \ + if (!result) { \ + HANDLE_WIN_MUTEX_ERROR(); \ + } \ + } while (0); #endif /* !defined(HAVE_WINDOWS_H) */ diff --git a/src/mpid/ch3/channels/nemesis/src/ch3_rma_shm.c b/src/mpid/ch3/channels/nemesis/src/ch3_rma_shm.c index 530b21fe91e..56a3046aa58 100644 --- a/src/mpid/ch3/channels/nemesis/src/ch3_rma_shm.c +++ b/src/mpid/ch3/channels/nemesis/src/ch3_rma_shm.c @@ -5,7 +5,7 @@ #include "mpidi_ch3_impl.h" #include "mpidrma.h" - +#include int MPIDI_CH3_SHM_Win_shared_query(MPIR_Win * win_ptr, int target_rank, MPI_Aint * size, int *disp_unit, void *baseptr) @@ -62,6 +62,79 @@ int MPIDI_CH3_SHM_Win_shared_query(MPIR_Win * win_ptr, int target_rank, MPI_Aint goto fn_exit; } +struct shm_mutex_entry { + int rank; + MPL_shm_hnd_t shm_hnd; + MPIDI_CH3I_SHM_MUTEX *shm_mutex; +}; + +static UT_icd shm_mutex_icd = {sizeof(struct shm_mutex_entry), NULL, NULL, NULL}; +static UT_array *shm_mutex_free_list; + +int MPIDI_CH3_SHM_Init(void) +{ + utarray_new(shm_mutex_free_list, &shm_mutex_icd, MPL_MEM_OTHER); + return 0; +} + +int MPIDI_CH3_SHM_Finalize(void) +{ + int mpi_errno = MPI_SUCCESS; + struct shm_mutex_entry *p; + + for (p = (struct shm_mutex_entry *) utarray_front(shm_mutex_free_list); p != NULL; + p = (struct shm_mutex_entry *) utarray_next(shm_mutex_free_list, p)) { + if (p->rank == 0) { + MPIDI_CH3I_SHM_MUTEX_DESTROY_DIRECT(p->shm_mutex); + } + + /* detach from shared memory segment */ + mpi_errno = MPL_shm_seg_detach(p->shm_hnd, (void **) &p->shm_mutex, + sizeof(MPIDI_CH3I_SHM_MUTEX)); + MPIR_ERR_CHECK(mpi_errno); + + MPL_shm_hnd_finalize(&p->shm_hnd); + } + utarray_free(shm_mutex_free_list); + + fn_exit: + return mpi_errno; + fn_fail: + goto fn_exit; +} + +static int delay_shm_mutex_destroy(int rank, MPIR_Win *win_ptr) +{ +#if 0 + /* On FreeBSD (tested on ver 12.2) destroying the mutex and recreate the mutex, + * which may result in the same address, the new mutex will not work for inter- + * process. To work around, we delay the destroy of mutex until finalize. */ + struct shm_mutex_entry entry; + entry.rank = rank; + entry.shm_hnd = win_ptr->shm_mutex_segment_handle; + entry.shm_mutex = win_ptr->shm_mutex; + utarray_push_back(shm_mutex_free_list, &entry, MPL_MEM_OTHER); + return 0; +#else + int mpi_errno = MPI_SUCCESS; + + if (rank == 0) { + MPIDI_CH3I_SHM_MUTEX_DESTROY_DIRECT(win_ptr->shm_mutex); + } + + /* detach from shared memory segment */ + mpi_errno = MPL_shm_seg_detach(win_ptr->shm_mutex_segment_handle, (void **) &win_ptr->shm_mutex, + sizeof(MPIDI_CH3I_SHM_MUTEX)); + MPIR_ERR_CHECK(mpi_errno); + + MPL_shm_hnd_finalize(&win_ptr->shm_mutex_segment_handle); + + fn_exit: + return mpi_errno; + fn_fail: + goto fn_exit; +#endif +} int MPIDI_CH3_SHM_Win_free(MPIR_Win ** win_ptr) { @@ -108,17 +181,7 @@ int MPIDI_CH3_SHM_Win_free(MPIR_Win ** win_ptr) node_comm_ptr = (*win_ptr)->comm_ptr->node_comm; MPIR_Assert(node_comm_ptr != NULL); - if (node_comm_ptr->rank == 0) { - MPIDI_CH3I_SHM_MUTEX_DESTROY(*win_ptr); - } - - /* detach from shared memory segment */ - mpi_errno = - MPL_shm_seg_detach((*win_ptr)->shm_mutex_segment_handle, - (void **) &(*win_ptr)->shm_mutex, sizeof(MPIDI_CH3I_SHM_MUTEX)); - MPIR_ERR_CHECK(mpi_errno); - - MPL_shm_hnd_finalize(&(*win_ptr)->shm_mutex_segment_handle); + delay_shm_mutex_destroy(node_comm_ptr->rank, *win_ptr); } /* Free shared memory region for window info */ diff --git a/src/mpid/ch3/channels/nemesis/src/mpid_nem_finalize.c b/src/mpid/ch3/channels/nemesis/src/mpid_nem_finalize.c index 9127deb5bf6..0ffa8a97968 100644 --- a/src/mpid/ch3/channels/nemesis/src/mpid_nem_finalize.c +++ b/src/mpid/ch3/channels/nemesis/src/mpid_nem_finalize.c @@ -11,6 +11,7 @@ #include "mpidi_nem_statistics.h" #include "mpidu_init_shm.h" +#include "mpidi_ch3_impl.h" int MPID_nem_finalize(void) { @@ -18,6 +19,9 @@ int MPID_nem_finalize(void) MPIR_FUNC_ENTER; + mpi_errno = MPIDI_CH3_SHM_Finalize(); + MPIR_ERR_CHECK(mpi_errno); + /* this test is not the right one */ /* MPIR_Assert(MPID_nem_queue_empty( MPID_nem_mem_region.RecvQ[MPID_nem_mem_region.rank])); */ diff --git a/src/mpid/ch3/channels/nemesis/src/mpid_nem_init.c b/src/mpid/ch3/channels/nemesis/src/mpid_nem_init.c index 700b88a5c89..2df6c945dd2 100644 --- a/src/mpid/ch3/channels/nemesis/src/mpid_nem_init.c +++ b/src/mpid/ch3/channels/nemesis/src/mpid_nem_init.c @@ -10,6 +10,7 @@ #include "mpidi_nem_statistics.h" #include "mpit.h" #include "mpidu_init_shm.h" +#include "mpidi_ch3_impl.h" /* === BEGIN_MPI_T_CVAR_INFO_BLOCK === @@ -406,6 +407,9 @@ MPID_nem_init(int pg_rank, MPIDI_PG_t *pg_p, int has_parent ATTRIBUTE((unused))) MPIR_ERR_CHECK(mpi_errno); #endif + mpi_errno = MPIDI_CH3_SHM_Init(); + MPIR_ERR_CHECK(mpi_errno); + #ifdef PAPI_MONITOR my_papi_start( pg_rank ); #endif /*PAPI_MONITOR */ From bc16b7f0e3fd68d2f82785957f2016f8ac4f2fdd Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 7 Jan 2022 18:14:23 -0600 Subject: [PATCH 302/607] test: refactor rma/atomic_rmw_gacc.c Move the test into a function. This prepares for running the test multiple times. --- test/mpi/rma/atomic_rmw_gacc.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/test/mpi/rma/atomic_rmw_gacc.c b/test/mpi/rma/atomic_rmw_gacc.c index ad2832b988e..250d9ffac96 100644 --- a/test/mpi/rma/atomic_rmw_gacc.c +++ b/test/mpi/rma/atomic_rmw_gacc.c @@ -74,20 +74,19 @@ static void checkResults(int loop_k, int *errors) } } -int main(int argc, char *argv[]) +static int test_atomic_rmw_gacc(void) { int i, k; int errors = 0; int my_buf_num = 0; /* to suppress warning */ MPI_Datatype origin_dtp, target_dtp; - MTest_Init(&argc, &argv); - MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if (size != 3) { /* run this test with three processes */ - goto exit_test; + printf("Run this test with three processes.\n"); + return 1; } MPI_Type_contiguous(OP_COUNT, MPI_INT, &origin_dtp); @@ -258,7 +257,17 @@ int main(int argc, char *argv[]) MPI_Type_free(&origin_dtp); MPI_Type_free(&target_dtp); - exit_test: + return errors; +} + +int main(int argc, char *argv[]) +{ + int errors = 0; + + MTest_Init(&argc, &argv); + + errors += test_atomic_rmw_gacc(); + MTest_Finalize(errors); return MTestReturnValue(errors); } From d47915a17615e403344b1418be74a66151e520e8 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 7 Jan 2022 18:15:39 -0600 Subject: [PATCH 303/607] test: run atomic_rmw_gacc multiple times Running this tests multiple times exposes issues with inter-process mutex on FreeBSD. --- test/mpi/rma/atomic_rmw_gacc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/test/mpi/rma/atomic_rmw_gacc.c b/test/mpi/rma/atomic_rmw_gacc.c index 250d9ffac96..c4164b94d95 100644 --- a/test/mpi/rma/atomic_rmw_gacc.c +++ b/test/mpi/rma/atomic_rmw_gacc.c @@ -266,6 +266,7 @@ int main(int argc, char *argv[]) MTest_Init(&argc, &argv); + errors += test_atomic_rmw_gacc(); errors += test_atomic_rmw_gacc(); MTest_Finalize(errors); From 37bd0cd1722e061bce2c89e72d20781bd76ae19a Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 7 Jan 2022 20:54:50 -0600 Subject: [PATCH 304/607] test: fix typos in atomic_rmw_gacc.c Correct the leftover "FOP" in the messages. --- test/mpi/rma/atomic_rmw_cas.c | 2 +- test/mpi/rma/atomic_rmw_gacc.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/mpi/rma/atomic_rmw_cas.c b/test/mpi/rma/atomic_rmw_cas.c index ae876fb5b80..421ad5af2a6 100644 --- a/test/mpi/rma/atomic_rmw_cas.c +++ b/test/mpi/rma/atomic_rmw_cas.c @@ -75,7 +75,7 @@ int main(int argc, char *argv[]) MPI_Barrier(MPI_COMM_WORLD); - /* perform FOP */ + /* perform CAS */ MPI_Win_lock_all(0, win); if (rank != dest) { MPI_Compare_and_swap(orig_buf, compare_buf, result_buf, MPI_INT, dest, 0, win); diff --git a/test/mpi/rma/atomic_rmw_gacc.c b/test/mpi/rma/atomic_rmw_gacc.c index c4164b94d95..c5f4e9e12d1 100644 --- a/test/mpi/rma/atomic_rmw_gacc.c +++ b/test/mpi/rma/atomic_rmw_gacc.c @@ -50,7 +50,7 @@ static void checkResults(int loop_k, int *errors) for (m = 0; m < OP_COUNT; m++) { if (check_buf[i * OP_COUNT + m] == result_buf[j * OP_COUNT + m]) { printf - ("LOOP=%d, rank=%d, FOP, both check_buf[%d] and result_buf[%d] equal to %d, expected to be different. \n", + ("LOOP=%d, rank=%d, GACC, both check_buf[%d] and result_buf[%d] equal to %d, expected to be different. \n", loop_k, rank, i * OP_COUNT + m, j * OP_COUNT + m, check_buf[i * OP_COUNT + m]); (*errors)++; @@ -65,7 +65,7 @@ static void checkResults(int loop_k, int *errors) /* check results on P1 */ for (i = 0; i < OP_COUNT; i++) { if (target_buf[i] != AM_BUF_NUM + SHM_BUF_NUM) { - printf("LOOP=%d, rank=%d, FOP, target_buf[%d] = %d, expected %d. \n", + printf("LOOP=%d, rank=%d, GACC, target_buf[%d] = %d, expected %d. \n", loop_k, rank, i, target_buf[i], AM_BUF_NUM + SHM_BUF_NUM); (*errors)++; } From 283606388a512a8d45aeeeb8d04fb513936e2368 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 7 Jan 2022 20:59:53 -0600 Subject: [PATCH 305/607] ch3/nemesis: workaround for the interprocess mutex issue This is only issue on FreeBSD. Ideally configure should detect and sets a flag when it is needed. --- src/mpid/ch3/channels/nemesis/src/ch3_rma_shm.c | 2 +- src/mpid/ch3/channels/nemesis/subconfigure.m4 | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/mpid/ch3/channels/nemesis/src/ch3_rma_shm.c b/src/mpid/ch3/channels/nemesis/src/ch3_rma_shm.c index 56a3046aa58..abd72199d9d 100644 --- a/src/mpid/ch3/channels/nemesis/src/ch3_rma_shm.c +++ b/src/mpid/ch3/channels/nemesis/src/ch3_rma_shm.c @@ -105,7 +105,7 @@ int MPIDI_CH3_SHM_Finalize(void) static int delay_shm_mutex_destroy(int rank, MPIR_Win *win_ptr) { -#if 0 +#ifdef DELAY_SHM_MUTEX_DESTROY /* On FreeBSD (tested on ver 12.2) destroying the mutex and recreate the mutex, * which may result in the same address, the new mutex will not work for inter- * process. To work around, we delay the destroy of mutex until finalize. */ diff --git a/src/mpid/ch3/channels/nemesis/subconfigure.m4 b/src/mpid/ch3/channels/nemesis/subconfigure.m4 index ad5de9d8f94..59aa54702c7 100644 --- a/src/mpid/ch3/channels/nemesis/subconfigure.m4 +++ b/src/mpid/ch3/channels/nemesis/subconfigure.m4 @@ -98,6 +98,12 @@ This turns off error checking and timing collection],,enable_fast=no) AC_CHECK_HEADERS(signal.h) AC_CHECK_FUNCS(signal) +case "$host_os" in + freebsd*) + AC_DEFINE(DELAY_SHM_MUTEX_DESTROY, 1, [Define to workaround interprocess mutex issue on FreeBSD]) + ;; +esac + nemesis_nets_dirs="" nemesis_nets_strings="" nemesis_nets_array="" From 8d55d411beb20d4a5f425e84da3ff34cb093a37f Mon Sep 17 00:00:00 2001 From: Wesley Bland Date: Tue, 4 Jan 2022 15:21:47 -0600 Subject: [PATCH 306/607] conf: Check for AVX support before using it --- configure.ac | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/configure.ac b/configure.ac index ba432427b9d..3a0d8479353 100644 --- a/configure.ac +++ b/configure.ac @@ -889,6 +889,9 @@ for option in $enable_fast ; do ;; alwaysinline) # No op in MPICH. See mpl/configure.ac ;; + avx) + enable_fast_avx_instr=yes + ;; all|yes) enable_fast_ndebug=yes enable_fast_opts=O2 @@ -896,6 +899,7 @@ for option in $enable_fast ; do none|no) enable_fast_ndebug=no enable_fast_opts=O0 + enable_fast_avx_instr=no ;; *) IFS="$save_IFS" @@ -932,6 +936,37 @@ if test -z "$enable_fast_no_strict_alignment" ; then AC_DEFINE(NEEDS_STRICT_ALIGNMENT,1,[Define if strict alignment memory access is required]) fi +if test "$enable_fast_avx_instr" = "yes" ; then + AC_CACHE_CHECK([whether -mavx is supported], pac_cv_found_avx, + [PAC_C_CHECK_COMPILER_OPTION([-mavx],pac_cv_found_avx=yes,pac_cv_found_avx=no)], + pac_cv_found_avx=no,pac_cv_found_avx=yes) + if test "$pac_cv_found_avx" = "yes" ; then + PAC_APPEND_FLAG([-mavx],[CFLAGS]) + + AC_CACHE_CHECK([whether _mm256_stream_si256 is supported], pac_cv_found__mm256_stream_si256,[ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + + int main(int argc, char **argv) { + char source[1024], dest[1024]; + for (int i = 0; i < 1024; i++) source[i] = 'a'; + + __m256i ymm0 = _mm256_loadu_si256((__m256i const *) source); + _mm256_stream_si256((__m256i *) dest, ymm0); + + if (dest[0] == source[0]) return 0; + else return 1; + } + ]])], pac_cv_found__mm256_stream_si256="yes", + pac_cv_found__mm256_stream_si256="no", + pac_cv_found__mm256_stream_si256="unknown") + ]) + fi + if test "$pac_cv_found__mm256_stream_si256" = "yes" ; then + AC_DEFINE(HAVE_MM256_STREAM_SI256,1,[Define if 256 bit streaming memcpy is available]) + fi +fi + # error-checking # Change default into the specific value of the default if test "$enable_error_checking" = "yes" ; then From d1d4a8cfd924d8618948664dd4a366f0bc0695d0 Mon Sep 17 00:00:00 2001 From: Wesley Bland Date: Mon, 11 Oct 2021 09:03:50 -0700 Subject: [PATCH 307/607] mpl: Add streaming copy The stream copy function is used when requested by the caller. The benefit of this function is that it does not bring the target memory into cache when doing a write. The is particularly important when writing data from one socket to memory physically located in space attached to another socket. --- src/mpl/include/mpl_trmem.h | 93 +++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/src/mpl/include/mpl_trmem.h b/src/mpl/include/mpl_trmem.h index 1d36f463d36..e882f75d748 100644 --- a/src/mpl/include/mpl_trmem.h +++ b/src/mpl/include/mpl_trmem.h @@ -230,6 +230,99 @@ typedef struct { Utility M*/ +#include "string.h" + +#ifdef HAVE_MM256_STREAM_SI256 +#include + +static inline void MPL_Memcpy_stream(void *dest, const void *src, size_t n) +{ + /* Anything less than 256 bytes is not worth optimizing */ + if (n <= 256) { + memcpy(dest, src, n); + return; + } + + char *d = (char *) dest; + const char *s = (const char *) src; + + /* Copy the first 63 bytes or less (if the address isn't 64-byte aligned) using a regular memcpy + * to make the rest faster */ + if (((uintptr_t) d) & 63) { + const uintptr_t t = 64 - (((uintptr_t) d) & 63); + memcpy(d, s, t); + d += t; + s += t; + n -= t; + } + + /* Copy 256 bytes at a time by unrolling a series of 32-byte streaming copies. */ + while (n >= 256) { + __m256i ymm0 = _mm256_loadu_si256((__m256i const *) (s + (32 * 0))); + __m256i ymm1 = _mm256_loadu_si256((__m256i const *) (s + (32 * 1))); + __m256i ymm2 = _mm256_loadu_si256((__m256i const *) (s + (32 * 2))); + __m256i ymm3 = _mm256_loadu_si256((__m256i const *) (s + (32 * 3))); + __m256i ymm4 = _mm256_loadu_si256((__m256i const *) (s + (32 * 4))); + __m256i ymm5 = _mm256_loadu_si256((__m256i const *) (s + (32 * 5))); + __m256i ymm6 = _mm256_loadu_si256((__m256i const *) (s + (32 * 6))); + __m256i ymm7 = _mm256_loadu_si256((__m256i const *) (s + (32 * 7))); + _mm256_stream_si256((__m256i *) (d + (32 * 0)), ymm0); + _mm256_stream_si256((__m256i *) (d + (32 * 1)), ymm1); + _mm256_stream_si256((__m256i *) (d + (32 * 2)), ymm2); + _mm256_stream_si256((__m256i *) (d + (32 * 3)), ymm3); + _mm256_stream_si256((__m256i *) (d + (32 * 4)), ymm4); + _mm256_stream_si256((__m256i *) (d + (32 * 5)), ymm5); + _mm256_stream_si256((__m256i *) (d + (32 * 6)), ymm6); + _mm256_stream_si256((__m256i *) (d + (32 * 7)), ymm7); + d += 256; + s += 256; + n -= 256; + } + + /* Once there are fewer than 256 bytes left to be copied, copy a chunk of 128 and 64 bytes (if + * applicable). */ + if (n >= 128) { + __m256i ymm0 = _mm256_loadu_si256((__m256i const *) (s + (32 * 0))); + __m256i ymm1 = _mm256_loadu_si256((__m256i const *) (s + (32 * 1))); + __m256i ymm2 = _mm256_loadu_si256((__m256i const *) (s + (32 * 2))); + __m256i ymm3 = _mm256_loadu_si256((__m256i const *) (s + (32 * 3))); + _mm256_stream_si256((__m256i *) (d + (32 * 0)), ymm0); + _mm256_stream_si256((__m256i *) (d + (32 * 1)), ymm1); + _mm256_stream_si256((__m256i *) (d + (32 * 2)), ymm2); + _mm256_stream_si256((__m256i *) (d + (32 * 3)), ymm3); + d += 128; + s += 128; + n -= 128; + } + + if (n >= 64) { + __m256i ymm0 = _mm256_loadu_si256((__m256i const *) (s + (32 * 0))); + __m256i ymm1 = _mm256_loadu_si256((__m256i const *) (s + (32 * 1))); + _mm256_stream_si256((__m256i *) (d + (32 * 0)), ymm0); + _mm256_stream_si256((__m256i *) (d + (32 * 1)), ymm1); + d += 64; + s += 64; + n -= 64; + } + + /* If there is any data left, copy it using a regular memcpy */ + if (n > 0) { + memcpy(d, s, (n & 63)); + } + + /* A memory fence is required after the streaming stores above. */ + _mm_sfence(); +} + +#else + +static inline void MPL_Memcpy_stream(void *dest, const void *src, size_t n) +{ + memcpy(dest, src, n); +} + +#endif + #ifdef MPL_USE_MEMORY_TRACING /* Define these as invalid C to catch their use in the code. From f4de0b39be0a7bc4457f2c27384faf545fed2029 Mon Sep 17 00:00:00 2001 From: Wesley Bland Date: Fri, 14 Jan 2022 11:50:47 -0600 Subject: [PATCH 308/607] mpir: Add checking wrapper for MPL streaming memcpy --- src/include/mpir_mem.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/include/mpir_mem.h b/src/include/mpir_mem.h index a7c144be5c4..147e67ef7bb 100644 --- a/src/include/mpir_mem.h +++ b/src/include/mpir_mem.h @@ -84,6 +84,12 @@ extern "C" { memcpy((dst), (src), (len)); \ } while (0) +#define MPIR_Memcpy_stream(dst, src, len) \ + do { \ + CHECK_MEMCPY((dst),(src),(len)); \ + MPL_Memcpy_stream((dst), (src), (len)); \ + } while (0) + /* Memory allocation macros. See document. */ /* Standard macro for generating error codes. We set the error to be From 7fc4a36290b9a3b0752071a122a342c0ea9fd28f Mon Sep 17 00:00:00 2001 From: Wesley Bland Date: Wed, 6 Oct 2021 10:40:12 -0500 Subject: [PATCH 309/607] typerep: Add hints for typerep functions The hints field will be used to indicate certain types of operations so the underlying datatype library can take advantage of this information. For now, this includes a streaming send hint to indicate that the message does not need to move into the local memory/cache. --- src/include/mpir_typerep.h | 20 ++++++----- .../coll/bcast/bcast_intra_pipelined_tree.c | 4 +-- src/mpi/coll/bcast/bcast_intra_tree.c | 4 +-- src/mpi/coll/helper_fns.c | 3 +- src/mpi/datatype/datatype_impl.c | 6 ++-- .../typerep/src/typerep_dataloop_pack.c | 19 +++++----- src/mpi/datatype/typerep/src/typerep_op.c | 2 +- .../datatype/typerep/src/typerep_yaksa_pack.c | 35 ++++++++++--------- src/mpi/misc/utils.c | 14 ++++---- src/mpi/pt2pt/bsendutil.c | 3 +- src/mpi/pt2pt/sendrecv.c | 5 +-- .../nemesis/include/mpid_nem_inline.h | 6 ++-- .../ch3/channels/nemesis/netmod/ofi/ofi_msg.c | 3 +- .../channels/nemesis/src/mpid_nem_lmt_shm.c | 5 +-- src/mpid/ch3/include/mpid_rma_shm.h | 6 ++-- src/mpid/ch3/src/ch3u_buffer.c | 12 ++++--- src/mpid/ch3/src/ch3u_eager.c | 5 +-- src/mpid/ch3/src/ch3u_handle_recv_pkt.c | 3 +- src/mpid/ch3/src/ch3u_handle_recv_req.c | 10 +++--- src/mpid/ch3/src/ch3u_request.c | 6 ++-- src/mpid/ch4/netmod/ofi/ofi_am_impl.h | 8 +++-- src/mpid/ch4/netmod/ofi/ofi_events.h | 2 +- src/mpid/ch4/netmod/ofi/ofi_rma.c | 4 +-- src/mpid/ch4/netmod/ofi/ofi_send.h | 5 +-- src/mpid/ch4/netmod/ucx/ucx_am.h | 2 +- src/mpid/ch4/netmod/ucx/ucx_datatype.c | 4 +-- src/mpid/ch4/netmod/ucx/ucx_rma.h | 2 +- src/mpid/ch4/shm/ipc/src/ipc_p2p.h | 3 +- .../ch4/shm/posix/eager/iqueue/iqueue_recv.h | 2 +- .../ch4/shm/posix/eager/iqueue/iqueue_send.h | 5 +-- src/mpid/ch4/shm/posix/posix_am_impl.h | 2 +- .../ch4/shm/posix/posix_coll_release_gather.h | 4 +-- src/mpid/ch4/shm/posix/posix_rma.h | 10 +++--- .../shm/posix/release_gather/release_gather.h | 13 +++---- src/mpid/ch4/src/mpidig_recv.h | 4 +-- src/mpid/ch4/src/mpidig_recv_utils.h | 17 +++++---- src/mpid/ch4/src/mpidig_rma.h | 5 +-- src/mpid/ch4/src/mpidig_rma_callbacks.c | 11 +++--- 38 files changed, 158 insertions(+), 116 deletions(-) diff --git a/src/include/mpir_typerep.h b/src/include/mpir_typerep.h index e53427bf49c..0d4b9ecb202 100644 --- a/src/include/mpir_typerep.h +++ b/src/include/mpir_typerep.h @@ -56,21 +56,25 @@ int MPIR_Typerep_to_iov_offset(const void *buf, MPI_Aint count, MPI_Datatype typ int MPIR_Typerep_iov_len(MPI_Aint count, MPI_Datatype type, MPI_Aint max_iov_bytes, MPI_Aint * iov_len); -int MPIR_Typerep_copy(void *outbuf, const void *inbuf, MPI_Aint num_bytes); +#define MPIR_TYPEREP_FLAG_NONE 0x0UL +#define MPIR_TYPEREP_FLAG_STREAM 0x1UL + +int MPIR_Typerep_copy(void *outbuf, const void *inbuf, MPI_Aint num_bytes, uint32_t flags); int MPIR_Typerep_pack(const void *inbuf, MPI_Aint incount, MPI_Datatype datatype, MPI_Aint inoffset, void *outbuf, MPI_Aint max_pack_bytes, - MPI_Aint * actual_pack_bytes); + MPI_Aint * actual_pack_bytes, uint32_t flags); int MPIR_Typerep_unpack(const void *inbuf, MPI_Aint insize, void *outbuf, MPI_Aint outcount, MPI_Datatype datatype, MPI_Aint outoffset, - MPI_Aint * actual_unpack_bytes); + MPI_Aint * actual_unpack_bytes, uint32_t flags); int MPIR_Typerep_icopy(void *outbuf, const void *inbuf, MPI_Aint num_bytes, - MPIR_Typerep_req * typereq_req); + MPIR_Typerep_req * typereq_req, uint32_t flags); int MPIR_Typerep_ipack(const void *inbuf, MPI_Aint incount, MPI_Datatype datatype, MPI_Aint inoffset, void *outbuf, MPI_Aint max_pack_bytes, - MPI_Aint * actual_pack_bytes, MPIR_Typerep_req * typereq_req); -int MPIR_Typerep_iunpack(const void *inbuf, MPI_Aint insize, - void *outbuf, MPI_Aint outcount, MPI_Datatype datatype, MPI_Aint outoffset, - MPI_Aint * actual_unpack_bytes, MPIR_Typerep_req * typereq_req); + MPI_Aint * actual_pack_bytes, MPIR_Typerep_req * typereq_req, + uint32_t flags); +int MPIR_Typerep_iunpack(const void *inbuf, MPI_Aint insize, void *outbuf, MPI_Aint outcount, + MPI_Datatype datatype, MPI_Aint outoffset, MPI_Aint * actual_unpack_bytes, + MPIR_Typerep_req * typereq_req, uint32_t flags); int MPIR_Typerep_wait(MPIR_Typerep_req typereq_req); int MPIR_Typerep_size_external32(MPI_Datatype type); diff --git a/src/mpi/coll/bcast/bcast_intra_pipelined_tree.c b/src/mpi/coll/bcast/bcast_intra_pipelined_tree.c index 0b3f11ecc6f..8a624608251 100644 --- a/src/mpi/coll/bcast/bcast_intra_pipelined_tree.c +++ b/src/mpi/coll/bcast/bcast_intra_pipelined_tree.c @@ -59,7 +59,7 @@ int MPIR_Bcast_intra_pipelined_tree(void *buffer, MPIR_CHKLMEM_MALLOC(sendbuf, void *, nbytes, mpi_errno, "sendbuf", MPL_MEM_BUFFER); if (rank == root) { mpi_errno = MPIR_Typerep_pack(buffer, count, datatype, 0, sendbuf, nbytes, - &actual_packed_unpacked_bytes); + &actual_packed_unpacked_bytes, MPIR_TYPEREP_FLAG_NONE); MPIR_ERR_CHECK(mpi_errno); } } @@ -225,7 +225,7 @@ int MPIR_Bcast_intra_pipelined_tree(void *buffer, if (!is_contig) { if (rank != root) { mpi_errno = MPIR_Typerep_unpack(sendbuf, nbytes, buffer, count, datatype, 0, - &actual_packed_unpacked_bytes); + &actual_packed_unpacked_bytes, MPIR_TYPEREP_FLAG_NONE); MPIR_ERR_CHECK(mpi_errno); } } diff --git a/src/mpi/coll/bcast/bcast_intra_tree.c b/src/mpi/coll/bcast/bcast_intra_tree.c index f944ab45d5e..9b33a583a17 100644 --- a/src/mpi/coll/bcast/bcast_intra_tree.c +++ b/src/mpi/coll/bcast/bcast_intra_tree.c @@ -57,7 +57,7 @@ int MPIR_Bcast_intra_tree(void *buffer, /* TODO: Pipeline the packing and communication */ if (rank == root) { mpi_errno = MPIR_Typerep_pack(buffer, count, datatype, 0, send_buf, nbytes, - &actual_packed_unpacked_bytes); + &actual_packed_unpacked_bytes, MPIR_TYPEREP_FLAG_NONE); MPIR_ERR_CHECK(mpi_errno); } count = count * type_size; @@ -148,7 +148,7 @@ int MPIR_Bcast_intra_tree(void *buffer, if (!is_contig) { if (rank != root) { mpi_errno = MPIR_Typerep_unpack(send_buf, nbytes, buffer, saved_count, datatype, 0, - &actual_packed_unpacked_bytes); + &actual_packed_unpacked_bytes, MPIR_TYPEREP_FLAG_NONE); MPIR_ERR_CHECK(mpi_errno); } } diff --git a/src/mpi/coll/helper_fns.c b/src/mpi/coll/helper_fns.c index 4d5ebef37d3..8bdbb644157 100644 --- a/src/mpi/coll/helper_fns.c +++ b/src/mpi/coll/helper_fns.c @@ -403,7 +403,8 @@ int MPIC_Sendrecv_replace(void *buf, MPI_Aint count, MPI_Datatype datatype, MPL_MEM_BUFFER); mpi_errno = - MPIR_Typerep_pack(buf, count, datatype, 0, tmpbuf, tmpbuf_size, &actual_pack_bytes); + MPIR_Typerep_pack(buf, count, datatype, 0, tmpbuf, tmpbuf_size, &actual_pack_bytes, + MPIR_TYPEREP_FLAG_NONE); MPIR_ERR_CHECK(mpi_errno); } diff --git a/src/mpi/datatype/datatype_impl.c b/src/mpi/datatype/datatype_impl.c index c0603da7674..2810e2d0cf2 100644 --- a/src/mpi/datatype/datatype_impl.c +++ b/src/mpi/datatype/datatype_impl.c @@ -68,7 +68,8 @@ int MPIR_Pack_impl(const void *inbuf, MPI_Aint incount, MPI_Datatype datatype, int mpi_errno = MPI_SUCCESS; MPI_Aint actual_pack_bytes; void *buf = (void *) ((char *) outbuf + *position); - mpi_errno = MPIR_Typerep_pack(inbuf, incount, datatype, 0, buf, outsize, &actual_pack_bytes); + mpi_errno = MPIR_Typerep_pack(inbuf, incount, datatype, 0, buf, outsize, &actual_pack_bytes, + MPIR_TYPEREP_FLAG_NONE); MPIR_ERR_CHECK(mpi_errno); *position += actual_pack_bytes; @@ -102,7 +103,8 @@ int MPIR_Unpack_impl(const void *inbuf, MPI_Aint insize, MPI_Aint * position, MPI_Aint actual_unpack_bytes; void *buf = (void *) ((char *) inbuf + *position); mpi_errno = - MPIR_Typerep_unpack(buf, insize, outbuf, outcount, datatype, 0, &actual_unpack_bytes); + MPIR_Typerep_unpack(buf, insize, outbuf, outcount, datatype, 0, &actual_unpack_bytes, + MPIR_TYPEREP_FLAG_NONE); MPIR_ERR_CHECK(mpi_errno); *position += actual_unpack_bytes; diff --git a/src/mpi/datatype/typerep/src/typerep_dataloop_pack.c b/src/mpi/datatype/typerep/src/typerep_dataloop_pack.c index 920b5a839b5..e9cb18c5f40 100644 --- a/src/mpi/datatype/typerep/src/typerep_dataloop_pack.c +++ b/src/mpi/datatype/typerep/src/typerep_dataloop_pack.c @@ -9,7 +9,7 @@ #include "typerep_internal.h" int MPIR_Typerep_icopy(void *outbuf, const void *inbuf, MPI_Aint num_bytes, - MPIR_Typerep_req * typereq_req) + MPIR_Typerep_req * typereq_req, uint32_t flags) { MPIR_FUNC_ENTER; @@ -19,14 +19,14 @@ int MPIR_Typerep_icopy(void *outbuf, const void *inbuf, MPI_Aint num_bytes, return MPI_SUCCESS; } -int MPIR_Typerep_copy(void *outbuf, const void *inbuf, MPI_Aint num_bytes) +int MPIR_Typerep_copy(void *outbuf, const void *inbuf, MPI_Aint num_bytes, uint32_t flags) { - return MPIR_Typerep_icopy(outbuf, inbuf, num_bytes, NULL); + return MPIR_Typerep_icopy(outbuf, inbuf, num_bytes, NULL, flags); } int MPIR_Typerep_ipack(const void *inbuf, MPI_Aint incount, MPI_Datatype datatype, MPI_Aint inoffset, void *outbuf, MPI_Aint max_pack_bytes, - MPI_Aint * actual_pack_bytes, MPIR_Typerep_req * typereq_req) + MPI_Aint * actual_pack_bytes, MPIR_Typerep_req * typereq_req, uint32_t flags) { int mpi_errno = MPI_SUCCESS; MPIR_Segment *segp; @@ -83,16 +83,17 @@ int MPIR_Typerep_ipack(const void *inbuf, MPI_Aint incount, MPI_Datatype datatyp int MPIR_Typerep_pack(const void *inbuf, MPI_Aint incount, MPI_Datatype datatype, MPI_Aint inoffset, void *outbuf, MPI_Aint max_pack_bytes, - MPI_Aint * actual_pack_bytes) + MPI_Aint * actual_pack_bytes, uint32_t flags) { return MPIR_Typerep_ipack(inbuf, incount, datatype, inoffset, outbuf, max_pack_bytes, - actual_pack_bytes, NULL); + actual_pack_bytes, NULL, flags); } int MPIR_Typerep_iunpack(const void *inbuf, MPI_Aint insize, void *outbuf, MPI_Aint outcount, MPI_Datatype datatype, MPI_Aint outoffset, - MPI_Aint * actual_unpack_bytes, MPIR_Typerep_req * typereq_req) + MPI_Aint * actual_unpack_bytes, MPIR_Typerep_req * typereq_req, + uint32_t flags) { int mpi_errno = MPI_SUCCESS; MPIR_Segment *segp; @@ -150,10 +151,10 @@ int MPIR_Typerep_iunpack(const void *inbuf, MPI_Aint insize, int MPIR_Typerep_unpack(const void *inbuf, MPI_Aint insize, void *outbuf, MPI_Aint outcount, MPI_Datatype datatype, MPI_Aint outoffset, - MPI_Aint * actual_unpack_bytes) + MPI_Aint * actual_unpack_bytes, uint32_t flags) { return MPIR_Typerep_iunpack(inbuf, insize, outbuf, outcount, datatype, outoffset, - actual_unpack_bytes, NULL); + actual_unpack_bytes, NULL, flags); } int MPIR_Typerep_wait(MPIR_Typerep_req typereq_req) diff --git a/src/mpi/datatype/typerep/src/typerep_op.c b/src/mpi/datatype/typerep/src/typerep_op.c index 5545a8bfcf1..a17bfc69c40 100644 --- a/src/mpi/datatype/typerep/src/typerep_op.c +++ b/src/mpi/datatype/typerep/src/typerep_op.c @@ -37,7 +37,7 @@ int MPII_Typerep_op_fallback(void *source_buf, MPI_Aint source_count, MPI_Dataty void *src_ptr = MPL_malloc(source_dtp_extent * source_count, MPL_MEM_OTHER); MPI_Aint unpack_size; MPIR_Typerep_unpack(source_buf, source_dtp_size * source_count, src_ptr, - source_count, source_dtp, 0, &unpack_size); + source_count, source_dtp, 0, &unpack_size, MPIR_TYPEREP_REQ_NULL); source_buf = src_ptr; source_unpacked = true; } diff --git a/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c b/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c index c0d3cdb992d..571f25ef281 100644 --- a/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c +++ b/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c @@ -60,7 +60,7 @@ /* When a returned typerep_req is expected, using the nonblocking yaksa routine and * return the request; otherwise use the blocking yaksa routine. */ static int typerep_do_copy(void *outbuf, const void *inbuf, MPI_Aint num_bytes, - MPIR_Typerep_req * typerep_req) + MPIR_Typerep_req * typerep_req, uint32_t flags) { MPIR_FUNC_ENTER; @@ -111,7 +111,8 @@ static int typerep_do_copy(void *outbuf, const void *inbuf, MPI_Aint num_bytes, * return the request; otherwise use the blocking yaksa routine. */ static int typerep_do_pack(const void *inbuf, MPI_Aint incount, MPI_Datatype datatype, MPI_Aint inoffset, void *outbuf, MPI_Aint max_pack_bytes, - MPI_Aint * actual_pack_bytes, MPIR_Typerep_req * typerep_req) + MPI_Aint * actual_pack_bytes, MPIR_Typerep_req * typerep_req, + uint32_t flags) { MPIR_FUNC_ENTER; @@ -239,7 +240,8 @@ int MPIR_Typerep_reduce_is_supported(MPI_Op op, MPI_Datatype datatype) * return the request; otherwise use the blocking yaksa routine. */ static int typerep_do_unpack(const void *inbuf, MPI_Aint insize, void *outbuf, MPI_Aint outcount, MPI_Datatype datatype, MPI_Aint outoffset, - MPI_Aint * actual_unpack_bytes, MPIR_Typerep_req * typerep_req) + MPI_Aint * actual_unpack_bytes, MPIR_Typerep_req * typerep_req, + uint32_t flags) { MPIR_FUNC_ENTER; @@ -316,23 +318,23 @@ static int typerep_do_unpack(const void *inbuf, MPI_Aint insize, void *outbuf, M } int MPIR_Typerep_icopy(void *outbuf, const void *inbuf, MPI_Aint num_bytes, - MPIR_Typerep_req * typerep_req) + MPIR_Typerep_req * typerep_req, uint32_t flags) { MPIR_FUNC_ENTER; int mpi_errno = MPI_SUCCESS; - mpi_errno = typerep_do_copy(outbuf, inbuf, num_bytes, typerep_req); + mpi_errno = typerep_do_copy(outbuf, inbuf, num_bytes, typerep_req, flags); MPIR_FUNC_EXIT; return mpi_errno; } -int MPIR_Typerep_copy(void *outbuf, const void *inbuf, MPI_Aint num_bytes) +int MPIR_Typerep_copy(void *outbuf, const void *inbuf, MPI_Aint num_bytes, uint32_t flags) { MPIR_FUNC_ENTER; int mpi_errno = MPI_SUCCESS; - mpi_errno = typerep_do_copy(outbuf, inbuf, num_bytes, NULL); + mpi_errno = typerep_do_copy(outbuf, inbuf, num_bytes, NULL, flags); MPIR_FUNC_EXIT; return mpi_errno; @@ -340,13 +342,13 @@ int MPIR_Typerep_copy(void *outbuf, const void *inbuf, MPI_Aint num_bytes) int MPIR_Typerep_ipack(const void *inbuf, MPI_Aint incount, MPI_Datatype datatype, MPI_Aint inoffset, void *outbuf, MPI_Aint max_pack_bytes, - MPI_Aint * actual_pack_bytes, MPIR_Typerep_req * typerep_req) + MPI_Aint * actual_pack_bytes, MPIR_Typerep_req * typerep_req, uint32_t flags) { MPIR_FUNC_ENTER; int mpi_errno = MPI_SUCCESS; mpi_errno = typerep_do_pack(inbuf, incount, datatype, inoffset, outbuf, max_pack_bytes, - actual_pack_bytes, typerep_req); + actual_pack_bytes, typerep_req, flags); MPIR_FUNC_EXIT; return mpi_errno; @@ -354,13 +356,13 @@ int MPIR_Typerep_ipack(const void *inbuf, MPI_Aint incount, MPI_Datatype datatyp int MPIR_Typerep_pack(const void *inbuf, MPI_Aint incount, MPI_Datatype datatype, MPI_Aint inoffset, void *outbuf, MPI_Aint max_pack_bytes, - MPI_Aint * actual_pack_bytes) + MPI_Aint * actual_pack_bytes, uint32_t flags) { MPIR_FUNC_ENTER; int mpi_errno = MPI_SUCCESS; mpi_errno = typerep_do_pack(inbuf, incount, datatype, inoffset, outbuf, max_pack_bytes, - actual_pack_bytes, NULL); + actual_pack_bytes, NULL, flags); MPIR_FUNC_EXIT; return mpi_errno; @@ -368,26 +370,27 @@ int MPIR_Typerep_pack(const void *inbuf, MPI_Aint incount, MPI_Datatype datatype int MPIR_Typerep_iunpack(const void *inbuf, MPI_Aint insize, void *outbuf, MPI_Aint outcount, MPI_Datatype datatype, MPI_Aint outoffset, MPI_Aint * actual_unpack_bytes, - MPIR_Typerep_req * typerep_req) + MPIR_Typerep_req * typerep_req, uint32_t flags) { MPIR_FUNC_ENTER; int mpi_errno = MPI_SUCCESS; mpi_errno = typerep_do_unpack(inbuf, insize, outbuf, outcount, datatype, outoffset, - actual_unpack_bytes, typerep_req); + actual_unpack_bytes, typerep_req, flags); MPIR_FUNC_EXIT; return mpi_errno; } int MPIR_Typerep_unpack(const void *inbuf, MPI_Aint insize, void *outbuf, MPI_Aint outcount, - MPI_Datatype datatype, MPI_Aint outoffset, MPI_Aint * actual_unpack_bytes) + MPI_Datatype datatype, MPI_Aint outoffset, MPI_Aint * actual_unpack_bytes, + uint32_t flags) { MPIR_FUNC_ENTER; int mpi_errno = MPI_SUCCESS; mpi_errno = typerep_do_unpack(inbuf, insize, outbuf, outcount, datatype, outoffset, - actual_unpack_bytes, NULL); + actual_unpack_bytes, NULL, flags); MPIR_FUNC_EXIT; return mpi_errno; @@ -485,7 +488,7 @@ int MPIR_Typerep_op(void *source_buf, MPI_Aint source_count, MPI_Datatype source void *src_ptr = MPL_malloc(data_sz, MPL_MEM_OTHER); MPI_Aint pack_size; MPIR_Typerep_pack(source_buf, source_count, source_dtp, 0, src_ptr, data_sz, - &pack_size); + &pack_size, MPIR_TYPEREP_REQ_NULL); MPIR_Assert(pack_size == data_sz); mpi_errno = typerep_op_unpack(src_ptr, target_buf, target_count, target_dtp, op, mapped_device); diff --git a/src/mpi/misc/utils.c b/src/mpi/misc/utils.c index ebd435c7251..f032a8157de 100644 --- a/src/mpi/misc/utils.c +++ b/src/mpi/misc/utils.c @@ -59,10 +59,12 @@ static int do_localcopy(const void *sendbuf, MPI_Aint sendcount, MPI_Datatype se MPI_Aint actual_unpack_bytes; if (typereq_req) { MPIR_Typerep_iunpack(MPIR_get_contig_ptr(sendbuf, sendtype_true_lb), copy_sz, recvbuf, - recvcount, recvtype, 0, &actual_unpack_bytes, typereq_req); + recvcount, recvtype, 0, &actual_unpack_bytes, typereq_req, + MPIR_TYPEREP_FLAG_NONE); } else { MPIR_Typerep_unpack(MPIR_get_contig_ptr(sendbuf, sendtype_true_lb), copy_sz, recvbuf, - recvcount, recvtype, 0, &actual_unpack_bytes); + recvcount, recvtype, 0, &actual_unpack_bytes, + MPIR_TYPEREP_FLAG_NONE); } MPIR_ERR_CHKANDJUMP(actual_unpack_bytes != copy_sz, mpi_errno, MPI_ERR_TYPE, "**dtypemismatch"); @@ -71,11 +73,11 @@ static int do_localcopy(const void *sendbuf, MPI_Aint sendcount, MPI_Datatype se if (typereq_req) { MPIR_Typerep_ipack(sendbuf, sendcount, sendtype, 0, MPIR_get_contig_ptr(recvbuf, recvtype_true_lb), copy_sz, - &actual_pack_bytes, typereq_req); + &actual_pack_bytes, typereq_req, MPIR_TYPEREP_FLAG_NONE); } else { MPIR_Typerep_pack(sendbuf, sendcount, sendtype, 0, MPIR_get_contig_ptr(recvbuf, recvtype_true_lb), copy_sz, - &actual_pack_bytes); + &actual_pack_bytes, MPIR_TYPEREP_FLAG_NONE); } MPIR_ERR_CHKANDJUMP(actual_pack_bytes != copy_sz, mpi_errno, MPI_ERR_TYPE, "**dtypemismatch"); @@ -109,14 +111,14 @@ static int do_localcopy(const void *sendbuf, MPI_Aint sendcount, MPI_Datatype se MPI_Aint actual_pack_bytes; MPIR_Typerep_pack(sendbuf, sendcount, sendtype, sfirst, buf, - max_pack_bytes, &actual_pack_bytes); + max_pack_bytes, &actual_pack_bytes, MPIR_TYPEREP_FLAG_NONE); MPIR_Assert(actual_pack_bytes > 0); sfirst += actual_pack_bytes; MPI_Aint actual_unpack_bytes; MPIR_Typerep_unpack(buf, actual_pack_bytes, recvbuf, recvcount, recvtype, - rfirst, &actual_unpack_bytes); + rfirst, &actual_unpack_bytes, MPIR_TYPEREP_FLAG_NONE); MPIR_Assert(actual_unpack_bytes > 0); rfirst += actual_unpack_bytes; diff --git a/src/mpi/pt2pt/bsendutil.c b/src/mpi/pt2pt/bsendutil.c index db1788122e5..0d69c6db667 100644 --- a/src/mpi/pt2pt/bsendutil.c +++ b/src/mpi/pt2pt/bsendutil.c @@ -258,7 +258,8 @@ int MPIR_Bsend_isend(const void *buf, int count, MPI_Datatype dtype, MPI_Aint actual_pack_bytes; void *pbuf = (void *) ((char *) p->msg.msgbuf + p->msg.count); mpi_errno = - MPIR_Typerep_pack(buf, count, dtype, 0, pbuf, packsize, &actual_pack_bytes); + MPIR_Typerep_pack(buf, count, dtype, 0, pbuf, packsize, &actual_pack_bytes, + MPIR_TYPEREP_FLAG_NONE); MPIR_ERR_CHECK(mpi_errno); p->msg.count += actual_pack_bytes; } else { diff --git a/src/mpi/pt2pt/sendrecv.c b/src/mpi/pt2pt/sendrecv.c index 0193a70a275..916c00fb384 100644 --- a/src/mpi/pt2pt/sendrecv.c +++ b/src/mpi/pt2pt/sendrecv.c @@ -111,7 +111,8 @@ int MPIR_Sendrecv_replace_impl(void *buf, MPI_Aint count, MPI_Datatype datatype, "temporary send buffer", MPL_MEM_BUFFER); mpi_errno = - MPIR_Typerep_pack(buf, count, datatype, 0, tmpbuf, tmpbuf_size, &actual_pack_bytes); + MPIR_Typerep_pack(buf, count, datatype, 0, tmpbuf, tmpbuf_size, &actual_pack_bytes, + MPIR_TYPEREP_FLAG_NONE); MPIR_ERR_CHECK(mpi_errno); } @@ -254,7 +255,7 @@ int MPIR_Isendrecv_replace_impl(void *buf, MPI_Aint count, MPI_Datatype datatype } mpi_errno = MPIR_Typerep_pack(buf, count, datatype, 0, tmpbuf, tmpbuf_size, - &actual_pack_bytes); + &actual_pack_bytes, MPIR_TYPEREP_FLAG_NONE); MPIR_ERR_CHECK(mpi_errno); MPIR_Assert(tmpbuf_size == actual_pack_bytes); } diff --git a/src/mpid/ch3/channels/nemesis/include/mpid_nem_inline.h b/src/mpid/ch3/channels/nemesis/include/mpid_nem_inline.h index 08cffac5599..b8d99ea564b 100644 --- a/src/mpid/ch3/channels/nemesis/include/mpid_nem_inline.h +++ b/src/mpid/ch3/channels/nemesis/include/mpid_nem_inline.h @@ -505,7 +505,7 @@ MPID_nem_mpich_send_seg_header (void *buf, MPI_Aint count, MPI_Datatype datatype MPI_Aint actual_pack_bytes; MPIR_Typerep_pack(buf, count, datatype, *msg_offset, (char *)cell_ptr->payload + sizeof(MPIDI_CH3_Pkt_t), - msgsize - *msg_offset, &actual_pack_bytes); + msgsize - *msg_offset, &actual_pack_bytes, MPIR_TYPEREP_FLAG_NONE); MPIR_Assert(actual_pack_bytes == msgsize - *msg_offset); MPL_atomic_release_store_int(&pbox->flag, 1); @@ -560,7 +560,7 @@ MPID_nem_mpich_send_seg_header (void *buf, MPI_Aint count, MPI_Datatype datatype MPI_Aint actual_pack_bytes; MPIR_Typerep_pack(buf, count, datatype, *msg_offset, (char *)el->payload + buf_offset, - max_pack_bytes, &actual_pack_bytes); + max_pack_bytes, &actual_pack_bytes, MPIR_TYPEREP_FLAG_NONE); datalen = buf_offset + actual_pack_bytes; *msg_offset += actual_pack_bytes; @@ -645,7 +645,7 @@ MPID_nem_mpich_send_seg (void *buf, MPI_Aint count, MPI_Datatype datatype, MPI_Aint actual_pack_bytes; MPIR_Typerep_pack(buf, count, datatype, *msg_offset, (char *)el->payload, - max_pack_bytes, &actual_pack_bytes); + max_pack_bytes, &actual_pack_bytes, MPIR_TYPEREP_FLAG_NONE); datalen = actual_pack_bytes; *msg_offset += actual_pack_bytes; diff --git a/src/mpid/ch3/channels/nemesis/netmod/ofi/ofi_msg.c b/src/mpid/ch3/channels/nemesis/netmod/ofi/ofi_msg.c index 49c9cd4aa9f..5bb47d42a6b 100644 --- a/src/mpid/ch3/channels/nemesis/netmod/ofi/ofi_msg.c +++ b/src/mpid/ch3/channels/nemesis/netmod/ofi/ofi_msg.c @@ -326,7 +326,8 @@ int MPID_nem_ofi_SendNoncontig(MPIDI_VC_t * vc, MPIR_Request * sreq, void *hdr, MPI_Aint actual_pack_bytes; MPIR_Typerep_pack(sreq->dev.user_buf, sreq->dev.user_count, sreq->dev.datatype, sreq->dev.msg_offset, pack_buffer + buf_offset, - sreq->dev.msgsize - sreq->dev.msg_offset, &actual_pack_bytes); + sreq->dev.msgsize - sreq->dev.msg_offset, &actual_pack_bytes, + MPIR_TYPEREP_FLAG_NONE); MPIR_Assert(actual_pack_bytes == sreq->dev.msgsize - sreq->dev.msg_offset); START_COMM(); diff --git a/src/mpid/ch3/channels/nemesis/src/mpid_nem_lmt_shm.c b/src/mpid/ch3/channels/nemesis/src/mpid_nem_lmt_shm.c index 39d0059eff3..9e91cb81b9e 100644 --- a/src/mpid/ch3/channels/nemesis/src/mpid_nem_lmt_shm.c +++ b/src/mpid/ch3/channels/nemesis/src/mpid_nem_lmt_shm.c @@ -456,7 +456,8 @@ static int lmt_shm_send_progress(MPIDI_VC_t *vc, MPIR_Request *req, int *done) MPI_Aint actual_pack_bytes; MPIR_Typerep_pack(req->dev.user_buf, req->dev.user_count, req->dev.datatype, first, - (void *)copy_buf->buf[buf_num], max_pack_bytes, &actual_pack_bytes); + (void *)copy_buf->buf[buf_num], max_pack_bytes, &actual_pack_bytes, + MPIR_TYPEREP_FLAG_NONE); MPL_atomic_write_barrier(); MPIR_Assign_trunc(copy_buf->len[buf_num].val, actual_pack_bytes, int); @@ -545,7 +546,7 @@ static int lmt_shm_recv_progress(MPIDI_VC_t *vc, MPIR_Request *req, int *done) MPI_Aint actual_unpack_bytes; MPIR_Typerep_unpack(src_buf, last - first, req->dev.user_buf, req->dev.user_count, req->dev.datatype, - first, &actual_unpack_bytes); + first, &actual_unpack_bytes, MPIR_TYPEREP_FLAG_NONE); last = first + actual_unpack_bytes; MPL_DBG_MSG_FMT(MPIDI_CH3_DBG_CHANNEL, VERBOSE, (MPL_DBG_FDEST, "recvd data. last=%" PRIdPTR " data_sz=%" PRIdPTR, last, data_sz)); diff --git a/src/mpid/ch3/include/mpid_rma_shm.h b/src/mpid/ch3/include/mpid_rma_shm.h index 95b950f237e..e4dfcdb812b 100644 --- a/src/mpid/ch3/include/mpid_rma_shm.h +++ b/src/mpid/ch3/include/mpid_rma_shm.h @@ -353,7 +353,8 @@ static inline int MPIDI_CH3I_Shm_acc_op(const void *origin_addr, int origin_coun MPI_Aint actual_pack_bytes; MPIR_Typerep_pack(origin_addr, origin_count, origin_datatype, - stream_offset, packed_buf, stream_size, &actual_pack_bytes); + stream_offset, packed_buf, stream_size, &actual_pack_bytes, + MPIR_TYPEREP_FLAG_NONE); MPIR_Assert(actual_pack_bytes == stream_size); if (shm_op) { @@ -473,7 +474,8 @@ static inline int MPIDI_CH3I_Shm_get_acc_op(const void *origin_addr, int origin_ MPI_Aint actual_pack_bytes; MPIR_Typerep_pack(origin_addr, origin_count, origin_datatype, - stream_offset, packed_buf, stream_size, &actual_pack_bytes); + stream_offset, packed_buf, stream_size, &actual_pack_bytes, + MPIR_TYPEREP_FLAG_NONE); MPIR_Assert(actual_pack_bytes == stream_size); MPIR_Assert(stream_count == (int) stream_count); diff --git a/src/mpid/ch3/src/ch3u_buffer.c b/src/mpid/ch3/src/ch3u_buffer.c index d581b914d24..44978e32186 100644 --- a/src/mpid/ch3/src/ch3u_buffer.c +++ b/src/mpid/ch3/src/ch3u_buffer.c @@ -72,7 +72,8 @@ void MPIDI_CH3U_Buffer_copy( else if (sdt_contig) { MPI_Aint actual_unpack_bytes; - MPIR_Typerep_unpack(MPIR_get_contig_ptr(sbuf, sdt_true_lb), sdata_sz, rbuf, rcount, rdt, 0, &actual_unpack_bytes); + MPIR_Typerep_unpack(MPIR_get_contig_ptr(sbuf, sdt_true_lb), sdata_sz, rbuf, rcount, rdt, 0, + &actual_unpack_bytes, MPIR_TYPEREP_FLAG_NONE); /* --BEGIN ERROR HANDLING-- */ if (actual_unpack_bytes != sdata_sz) { @@ -84,7 +85,8 @@ void MPIDI_CH3U_Buffer_copy( else if (rdt_contig) { MPI_Aint actual_pack_bytes; - MPIR_Typerep_pack(sbuf, scount, sdt, 0, MPIR_get_contig_ptr(rbuf, rdt_true_lb), sdata_sz, &actual_pack_bytes); + MPIR_Typerep_pack(sbuf, scount, sdt, 0, MPIR_get_contig_ptr(rbuf, rdt_true_lb), sdata_sz, + &actual_pack_bytes, MPIR_TYPEREP_FLAG_NONE); /* --BEGIN ERROR HANDLING-- */ if (actual_pack_bytes != sdata_sz) { @@ -134,8 +136,10 @@ void MPIDI_CH3U_Buffer_copy( if (max_pack_bytes == 0) break; - MPIR_Typerep_pack(sbuf, scount, sdt, sfirst, buf, max_pack_bytes, &actual_pack_bytes); - MPIR_Typerep_unpack(buf, actual_pack_bytes, rbuf, rcount, rdt, rfirst, &actual_unpack_bytes); + MPIR_Typerep_pack(sbuf, scount, sdt, sfirst, buf, max_pack_bytes, &actual_pack_bytes, + MPIR_TYPEREP_FLAG_NONE); + MPIR_Typerep_unpack(buf, actual_pack_bytes, rbuf, rcount, rdt, rfirst, &actual_unpack_bytes, + MPIR_TYPEREP_FLAG_NONE); MPIR_Assert(actual_pack_bytes == actual_unpack_bytes); sfirst += actual_pack_bytes; diff --git a/src/mpid/ch3/src/ch3u_eager.c b/src/mpid/ch3/src/ch3u_eager.c index 0a1be3798fb..0d2392d8dd9 100644 --- a/src/mpid/ch3/src/ch3u_eager.c +++ b/src/mpid/ch3/src/ch3u_eager.c @@ -394,8 +394,9 @@ int MPIDI_CH3_PktHandler_EagerShortSend( MPIDI_VC_t *vc, MPIDI_CH3_Pkt_t *pkt, v recv_data_sz = rreq->dev.recv_data_sz; MPI_Aint actual_unpack_bytes; - MPIR_Typerep_unpack(eagershort_pkt->data, recv_data_sz, rreq->dev.user_buf, - rreq->dev.user_count, rreq->dev.datatype, 0, &actual_unpack_bytes); + MPIR_Typerep_unpack(eagershort_pkt->data, recv_data_sz, rreq->dev.user_buf, + rreq->dev.user_count, rreq->dev.datatype, 0, &actual_unpack_bytes, + MPIR_TYPEREP_FLAG_NONE); if (actual_unpack_bytes != recv_data_sz) { /* --BEGIN ERROR HANDLING-- */ diff --git a/src/mpid/ch3/src/ch3u_handle_recv_pkt.c b/src/mpid/ch3/src/ch3u_handle_recv_pkt.c index 73ad88144b0..91f0ac41ad9 100644 --- a/src/mpid/ch3/src/ch3u_handle_recv_pkt.c +++ b/src/mpid/ch3/src/ch3u_handle_recv_pkt.c @@ -172,7 +172,8 @@ int MPIDI_CH3U_Receive_data_found(MPIR_Request *rreq, void *buf, intptr_t *bufle MPI_Aint actual_unpack_bytes; MPIR_Typerep_unpack(buf, data_sz, rreq->dev.user_buf, rreq->dev.user_count, - rreq->dev.datatype, rreq->dev.msg_offset, &actual_unpack_bytes); + rreq->dev.datatype, rreq->dev.msg_offset, &actual_unpack_bytes, + MPIR_TYPEREP_FLAG_NONE); /* --BEGIN ERROR HANDLING-- */ if (actual_unpack_bytes != data_sz) diff --git a/src/mpid/ch3/src/ch3u_handle_recv_req.c b/src/mpid/ch3/src/ch3u_handle_recv_req.c index 55abb64d1b4..640676e7d86 100644 --- a/src/mpid/ch3/src/ch3u_handle_recv_req.c +++ b/src/mpid/ch3/src/ch3u_handle_recv_req.c @@ -308,7 +308,8 @@ int MPIDI_CH3_ReqHandler_GaccumRecvComplete(MPIDI_VC_t * vc, MPIR_Request * rreq else { MPI_Aint actual_pack_bytes; MPIR_Typerep_pack(rreq->dev.real_user_buf, rreq->dev.user_count, rreq->dev.datatype, - stream_offset, resp_req->dev.user_buf, stream_data_len, &actual_pack_bytes); + stream_offset, resp_req->dev.user_buf, stream_data_len, &actual_pack_bytes, + MPIR_TYPEREP_FLAG_NONE); MPIR_Assert(actual_pack_bytes == stream_data_len); } @@ -433,7 +434,7 @@ int MPIDI_CH3_ReqHandler_FOPRecvComplete(MPIDI_VC_t * vc, MPIR_Request * rreq, i else { MPI_Aint actual_pack_bytes; MPIR_Typerep_pack(rreq->dev.real_user_buf, 1, rreq->dev.datatype, 0, resp_req->dev.user_buf, - type_size, &actual_pack_bytes); + type_size, &actual_pack_bytes, MPIR_TYPEREP_FLAG_NONE); MPIR_Assert(actual_pack_bytes == type_size); } @@ -1283,7 +1284,8 @@ static inline int perform_get_acc_in_lock_queue(MPIR_Win * win_ptr, else { MPI_Aint actual_pack_bytes; MPIR_Typerep_pack(get_accum_pkt->addr, get_accum_pkt->count, get_accum_pkt->datatype, - 0, sreq->dev.user_buf, type_size * recv_count, &actual_pack_bytes); + 0, sreq->dev.user_buf, type_size * recv_count, &actual_pack_bytes, + MPIR_TYPEREP_FLAG_NONE); MPIR_Assert(actual_pack_bytes == type_size * recv_count); } @@ -1422,7 +1424,7 @@ static inline int perform_fop_in_lock_queue(MPIR_Win * win_ptr, else { MPI_Aint actual_pack_bytes; MPIR_Typerep_pack(fop_pkt->addr, 1, fop_pkt->datatype, 0, resp_req->dev.user_buf, - type_size, &actual_pack_bytes); + type_size, &actual_pack_bytes, MPIR_TYPEREP_FLAG_NONE); MPIR_Assert(actual_pack_bytes == type_size); } diff --git a/src/mpid/ch3/src/ch3u_request.c b/src/mpid/ch3/src/ch3u_request.c index 60d1a1e1179..4a4f67148ca 100644 --- a/src/mpid/ch3/src/ch3u_request.c +++ b/src/mpid/ch3/src/ch3u_request.c @@ -159,7 +159,7 @@ int MPIDI_CH3U_Request_load_send_iov(MPIR_Request * const sreq, MPIR_Typerep_pack(sreq->dev.user_buf, sreq->dev.user_count, sreq->dev.datatype, sreq->dev.msg_offset, (char*) sreq->dev.tmpbuf + iov_data_copied, - max_pack_bytes, &actual_pack_bytes); + max_pack_bytes, &actual_pack_bytes, MPIR_TYPEREP_FLAG_NONE); last = sreq->dev.msg_offset + actual_pack_bytes; iov[0].iov_base = (void *)sreq->dev.tmpbuf; @@ -418,7 +418,7 @@ int MPIDI_CH3U_Request_unpack_srbuf(MPIR_Request * rreq) MPI_Aint actual_unpack_bytes; MPIR_Typerep_unpack(rreq->dev.tmpbuf, tmpbuf_last - rreq->dev.msg_offset, rreq->dev.user_buf, rreq->dev.user_count, rreq->dev.datatype, - rreq->dev.msg_offset, &actual_unpack_bytes); + rreq->dev.msg_offset, &actual_unpack_bytes, MPIR_TYPEREP_FLAG_NONE); last = rreq->dev.msg_offset + actual_unpack_bytes; if (last == 0 || last == rreq->dev.msg_offset) @@ -528,7 +528,7 @@ int MPIDI_CH3U_Request_unpack_uebuf(MPIR_Request * rreq) MPI_Aint actual_unpack_bytes; MPIR_Typerep_unpack(rreq->dev.tmpbuf, unpack_sz, rreq->dev.user_buf, rreq->dev.user_count, - rreq->dev.datatype, 0, &actual_unpack_bytes); + rreq->dev.datatype, 0, &actual_unpack_bytes, MPIR_TYPEREP_FLAG_NONE); if (actual_unpack_bytes != unpack_sz) { diff --git a/src/mpid/ch4/netmod/ofi/ofi_am_impl.h b/src/mpid/ch4/netmod/ofi/ofi_am_impl.h index 35f207fbee7..7d469572bf7 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_am_impl.h +++ b/src/mpid/ch4/netmod/ofi/ofi_am_impl.h @@ -352,7 +352,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_am_isend_short(int rank, MPIR_Comm * comm } MPI_Aint packed_size; - mpi_errno = MPIR_Typerep_pack(buf, count, datatype, 0, p_am_data, data_sz, &packed_size); + mpi_errno = MPIR_Typerep_pack(buf, count, datatype, 0, p_am_data, data_sz, &packed_size, + MPIR_TYPEREP_FLAG_NONE); MPIR_ERR_CHECK(mpi_errno); MPIR_Assert(packed_size == data_sz); @@ -411,7 +412,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_am_isend_pipeline(int rank, MPIR_Comm * c MPIR_Memcpy(send_req->am_hdr, MPIDI_OFI_AM_SREQ_HDR(sreq, am_hdr), am_hdr_sz); MPI_Aint packed_size; mpi_errno = MPIR_Typerep_pack(buf, count, datatype, offset, - send_req->am_data, seg_sz, &packed_size); + send_req->am_data, seg_sz, &packed_size, MPIR_TYPEREP_FLAG_NONE); MPIR_ERR_CHECK(mpi_errno); MPIR_Assert(packed_size == seg_sz); @@ -763,7 +764,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_do_am_isend_rdma_read(int rank, MPIR_Comm * step when we work on ZCOPY protocol support. Basically, if the src buf and datatype needs * packing, we should not be doing RDMA read. */ MPIR_gpu_malloc_host((void **) &send_buf, data_sz); - mpi_errno = MPIR_Typerep_pack(buf, count, datatype, 0, send_buf, data_sz, &last); + mpi_errno = MPIR_Typerep_pack(buf, count, datatype, 0, send_buf, data_sz, &last, + MPIR_TYPEREP_FLAG_NONE); MPIR_ERR_CHECK(mpi_errno); MPIR_Assert(data_sz == last); diff --git a/src/mpid/ch4/netmod/ofi/ofi_events.h b/src/mpid/ch4/netmod/ofi/ofi_events.h index f88a3060cdb..d179c8b7201 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_events.h +++ b/src/mpid/ch4/netmod/ofi/ofi_events.h @@ -85,7 +85,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_recv_event(int vni, struct fi_cq_tagged_e MPIDI_OFI_REQUEST(rreq, noncontig.pack.buf), MPIDI_OFI_REQUEST(rreq, noncontig.pack.count), MPIDI_OFI_REQUEST(rreq, noncontig.pack.datatype), 0, - &actual_unpack_bytes); + &actual_unpack_bytes, MPIR_TYPEREP_FLAG_NONE); MPIR_gpu_free_host(MPIDI_OFI_REQUEST(rreq, noncontig.pack.pack_buffer)); if (actual_unpack_bytes != (MPI_Aint) count) { rreq->status.MPI_ERROR = diff --git a/src/mpid/ch4/netmod/ofi/ofi_rma.c b/src/mpid/ch4/netmod/ofi/ofi_rma.c index 3d17595a8da..8bcd3f662b2 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_rma.c +++ b/src/mpid/ch4/netmod/ofi/ofi_rma.c @@ -37,7 +37,7 @@ void MPIDI_OFI_complete_chunks(MPIDI_OFI_win_request_t * winreq) chunk->unpack_size, winreq->noncontig.get.origin.addr, winreq->noncontig.get.origin.count, winreq->noncontig.get.origin.datatype, chunk->unpack_offset, - &actual_unpack_bytes); + &actual_unpack_bytes, MPIR_TYPEREP_FLAG_NONE); MPIR_Assert(chunk->unpack_size == actual_unpack_bytes); } @@ -223,7 +223,7 @@ static int issue_packed_put(MPIR_Win * win, MPIDI_OFI_win_request_t * req) MPIR_Typerep_pack(req->noncontig.put.origin.addr, req->noncontig.put.origin.count, req->noncontig.put.origin.datatype, req->noncontig.put.origin.pack_offset, pack_buffer, - msg_len, &actual_pack_bytes); + msg_len, &actual_pack_bytes, MPIR_TYPEREP_FLAG_NONE); MPIR_Assert(msg_len == actual_pack_bytes); MPIDI_OFI_pack_chunk *chunk = create_chunk(pack_buffer, 0, 0, req); diff --git a/src/mpid/ch4/netmod/ofi/ofi_send.h b/src/mpid/ch4/netmod/ofi/ofi_send.h index 0a0f6e269c4..1716ca21266 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_send.h +++ b/src/mpid/ch4/netmod/ofi/ofi_send.h @@ -262,7 +262,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_send_normal(const void *buf, MPI_Aint cou MPI_Aint actual_pack_bytes; MPIR_Typerep_pack(buf, count, datatype, 0, MPIDI_OFI_REQUEST(sreq, noncontig.pack.pack_buffer), data_sz, - &actual_pack_bytes); + &actual_pack_bytes, MPIR_TYPEREP_FLAG_NONE); send_buf = MPIDI_OFI_REQUEST(sreq, noncontig.pack.pack_buffer); } else { MPIDI_OFI_REQUEST(sreq, noncontig.pack.pack_buffer) = NULL; @@ -416,7 +416,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_send(const void *buf, MPI_Aint count, MPI /* Force pack for GPU buffer. */ void *host_buf = NULL; MPIR_gpu_malloc_host(&host_buf, data_sz); - MPIR_Typerep_pack(buf, count, datatype, 0, host_buf, data_sz, &actual_pack_bytes); + MPIR_Typerep_pack(buf, count, datatype, 0, host_buf, data_sz, &actual_pack_bytes, + MPIR_TYPEREP_FLAG_NONE); MPIR_Assert(actual_pack_bytes == data_sz); send_buf = host_buf; } diff --git a/src/mpid/ch4/netmod/ucx/ucx_am.h b/src/mpid/ch4/netmod/ucx/ucx_am.h index 4bc1a092a68..35818ee5f87 100644 --- a/src/mpid/ch4/netmod/ucx/ucx_am.h +++ b/src/mpid/ch4/netmod/ucx/ucx_am.h @@ -103,7 +103,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_NM_am_isend(int rank, MPI_Aint actual_pack_bytes; mpi_errno = MPIR_Typerep_pack(data, count, datatype, 0, send_buf + am_hdr_sz + sizeof(ucx_hdr), - data_sz, &actual_pack_bytes); + data_sz, &actual_pack_bytes, MPIR_TYPEREP_FLAG_NONE); MPIR_ERR_CHECK(mpi_errno); MPIR_Assert(actual_pack_bytes == data_sz); diff --git a/src/mpid/ch4/netmod/ucx/ucx_datatype.c b/src/mpid/ch4/netmod/ucx/ucx_datatype.c index 939ecefd58d..b95687be8c4 100644 --- a/src/mpid/ch4/netmod/ucx/ucx_datatype.c +++ b/src/mpid/ch4/netmod/ucx/ucx_datatype.c @@ -69,7 +69,7 @@ static size_t pack(void *state, size_t offset, void *dest, size_t max_length) MPI_Aint actual_pack_bytes; MPIR_Typerep_pack(pack_state->buffer, pack_state->count, pack_state->datatype, offset, - dest, max_length, &actual_pack_bytes); + dest, max_length, &actual_pack_bytes, MPIR_TYPEREP_FLAG_NONE); return actual_pack_bytes; } @@ -85,7 +85,7 @@ static ucs_status_t unpack(void *state, size_t offset, const void *src, size_t c max_unpack_bytes = MPL_MIN(packsize, count); MPIR_Typerep_unpack(src, max_unpack_bytes, pack_state->buffer, pack_state->count, - pack_state->datatype, offset, &actual_unpack_bytes); + pack_state->datatype, offset, &actual_unpack_bytes, MPIR_TYPEREP_FLAG_NONE); if (unlikely(actual_unpack_bytes != max_unpack_bytes)) { return UCS_ERR_MESSAGE_TRUNCATED; } diff --git a/src/mpid/ch4/netmod/ucx/ucx_rma.h b/src/mpid/ch4/netmod/ucx/ucx_rma.h index b5d581d8496..75d7bd52e69 100644 --- a/src/mpid/ch4/netmod/ucx/ucx_rma.h +++ b/src/mpid/ch4/netmod/ucx/ucx_rma.h @@ -105,7 +105,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_UCX_noncontig_put(const void *origin_addr, MPI_Aint actual_pack_bytes; mpi_errno = MPIR_Typerep_pack(origin_addr, origin_count, origin_datatype, 0, buffer, size, - &actual_pack_bytes); + &actual_pack_bytes, MPIR_TYPEREP_FLAG_NONE); MPIR_ERR_CHECK(mpi_errno); MPIR_Assert(actual_pack_bytes == size); diff --git a/src/mpid/ch4/shm/ipc/src/ipc_p2p.h b/src/mpid/ch4/shm/ipc/src/ipc_p2p.h index 56795ac5fee..2875d7f041d 100644 --- a/src/mpid/ch4/shm/ipc/src/ipc_p2p.h +++ b/src/mpid/ch4/shm/ipc/src/ipc_p2p.h @@ -133,7 +133,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_IPCI_copy_data(MPIDI_IPC_hdr * ipc_hdr, MPIR_ mpi_errno = MPIR_Typerep_unpack(src_buf, src_data_sz, MPIDIG_REQUEST(rreq, buffer), MPIDIG_REQUEST(rreq, count), - MPIDIG_REQUEST(rreq, datatype), 0, &actual_unpack_bytes); + MPIDIG_REQUEST(rreq, datatype), 0, &actual_unpack_bytes, + MPIR_TYPEREP_FLAG_NONE); MPIR_ERR_CHECK(mpi_errno); MPIR_Assert(actual_unpack_bytes == src_data_sz); } else { diff --git a/src/mpid/ch4/shm/posix/eager/iqueue/iqueue_recv.h b/src/mpid/ch4/shm/posix/eager/iqueue/iqueue_recv.h index 5741abf69c8..dfed9c8173e 100644 --- a/src/mpid/ch4/shm/posix/eager/iqueue/iqueue_recv.h +++ b/src/mpid/ch4/shm/posix/eager/iqueue/iqueue_recv.h @@ -53,7 +53,7 @@ MPL_STATIC_INLINE_PREFIX void MPIDI_POSIX_eager_recv_memcpy(MPIDI_POSIX_eager_recv_transaction_t * transaction, void *dst, const void *src, size_t size) { - MPIR_Typerep_copy(dst, src, size); + MPIR_Typerep_copy(dst, src, size, MPIR_TYPEREP_FLAG_NONE); } MPL_STATIC_INLINE_PREFIX void diff --git a/src/mpid/ch4/shm/posix/eager/iqueue/iqueue_send.h b/src/mpid/ch4/shm/posix/eager/iqueue/iqueue_send.h index 4cefbba501e..f8d0043be38 100644 --- a/src/mpid/ch4/shm/posix/eager/iqueue/iqueue_send.h +++ b/src/mpid/ch4/shm/posix/eager/iqueue/iqueue_send.h @@ -83,7 +83,7 @@ MPIDI_POSIX_eager_send(int grank, MPIDI_POSIX_am_header_t * msg_hdr, const void cell->am_header = *msg_hdr; cell->type = MPIDI_POSIX_EAGER_IQUEUE_CELL_TYPE_HDR; /* send am_hdr if this is the first segment */ - MPIR_Typerep_copy(payload, am_hdr, am_hdr_sz); + MPIR_Typerep_copy(payload, am_hdr, am_hdr_sz, MPIR_TYPEREP_FLAG_STREAM); /* make sure the data region starts at the boundary of MAX_ALIGNMENT */ payload = payload + resized_am_hdr_sz; cell->payload_size += resized_am_hdr_sz; @@ -99,7 +99,8 @@ MPIDI_POSIX_eager_send(int grank, MPIDI_POSIX_am_header_t * msg_hdr, const void * not reliable because the derived datatype could have zero block size which contains no * data. */ if (bytes_sent) { - MPIR_Typerep_pack(buf, count, datatype, offset, payload, available, &packed_size); + MPIR_Typerep_pack(buf, count, datatype, offset, payload, available, &packed_size, + MPIR_TYPEREP_FLAG_STREAM); cell->payload_size += packed_size; *bytes_sent = packed_size; } diff --git a/src/mpid/ch4/shm/posix/posix_am_impl.h b/src/mpid/ch4/shm/posix/posix_am_impl.h index 282178400cb..5f5bc23addf 100644 --- a/src/mpid/ch4/shm/posix/posix_am_impl.h +++ b/src/mpid/ch4/shm/posix/posix_am_impl.h @@ -53,7 +53,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_am_init_req_hdr(const void *am_hdr, } if (am_hdr) { - MPIR_Typerep_copy(req_hdr->am_hdr, am_hdr, am_hdr_sz); + MPIR_Typerep_copy(req_hdr->am_hdr, am_hdr, am_hdr_sz, MPIR_TYPEREP_FLAG_NONE); } *req_hdr_ptr = req_hdr; diff --git a/src/mpid/ch4/shm/posix/posix_coll_release_gather.h b/src/mpid/ch4/shm/posix/posix_coll_release_gather.h index cb03bf67dd6..5fc925c421d 100644 --- a/src/mpid/ch4/shm/posix/posix_coll_release_gather.h +++ b/src/mpid/ch4/shm/posix/posix_coll_release_gather.h @@ -99,7 +99,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_mpi_bcast_release_gather(void *buffer, /* Root packs the data before sending, for non contiguous datatypes */ mpi_errno = MPIR_Typerep_pack(ori_buffer, ori_count, ori_datatype, 0, buffer, count, - &actual_packed_unpacked_bytes); + &actual_packed_unpacked_bytes, MPIR_TYPEREP_FLAG_NONE); MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); } } @@ -151,7 +151,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_mpi_bcast_release_gather(void *buffer, /* Non-root unpack the data if expecting non-contiguous datatypes */ mpi_errno = MPIR_Typerep_unpack(buffer, count, ori_buffer, ori_count, ori_datatype, 0, - &actual_packed_unpacked_bytes); + &actual_packed_unpacked_bytes, MPIR_TYPEREP_FLAG_NONE); MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); } MPL_free(buffer); diff --git a/src/mpid/ch4/shm/posix/posix_rma.h b/src/mpid/ch4/shm/posix/posix_rma.h index e30dd816863..fc2ec83c131 100644 --- a/src/mpid/ch4/shm/posix/posix_rma.h +++ b/src/mpid/ch4/shm/posix/posix_rma.h @@ -63,8 +63,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_compute_accumulate(void *origin_addr, MPIR_ERR_CHKANDJUMP(packed_buf == NULL, mpi_errno, MPI_ERR_NO_MEM, "**nomem"); MPI_Aint actual_pack_bytes; - mpi_errno = MPIR_Typerep_pack(origin_addr, origin_count, origin_datatype, 0, - packed_buf, total_len, &actual_pack_bytes); + mpi_errno = MPIR_Typerep_pack(origin_addr, origin_count, origin_datatype, 0, packed_buf, + total_len, &actual_pack_bytes, MPIR_TYPEREP_FLAG_NONE); MPIR_ERR_CHECK(mpi_errno); MPIR_Assert(actual_pack_bytes == total_len); @@ -479,9 +479,9 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_mpi_compare_and_swap(const void *origin MPID_THREAD_CS_ENTER(VCI, MPIDI_VCI(vci).lock); } - MPIR_Typerep_copy(result_addr, target_addr, dtype_sz); + MPIR_Typerep_copy(result_addr, target_addr, dtype_sz, MPIR_TYPEREP_FLAG_NONE); if (MPIR_Compare_equal(compare_addr, target_addr, datatype)) { - MPIR_Typerep_copy(target_addr, origin_addr, dtype_sz); + MPIR_Typerep_copy(target_addr, origin_addr, dtype_sz, MPIR_TYPEREP_FLAG_NONE); } if (winattr & MPIDI_WINATTR_SHM_ALLOCATED) { @@ -649,7 +649,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_mpi_fetch_and_op(const void *origin_add MPID_THREAD_CS_ENTER(VCI, MPIDI_VCI(vci).lock); } - MPIR_Typerep_copy(result_addr, target_addr, dtype_sz); + MPIR_Typerep_copy(result_addr, target_addr, dtype_sz, MPIR_TYPEREP_FLAG_NONE); if (op != MPI_NO_OP) { /* We need to make sure op is valid here. diff --git a/src/mpid/ch4/shm/posix/release_gather/release_gather.h b/src/mpid/ch4/shm/posix/release_gather/release_gather.h index e6cf22c1980..861e0922b54 100644 --- a/src/mpid/ch4/shm/posix/release_gather/release_gather.h +++ b/src/mpid/ch4/shm/posix/release_gather/release_gather.h @@ -113,13 +113,14 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_mpi_release_gather_release(void *local_ datatype, root, MPIR_BCAST_TAG, comm_ptr, &status, errflag); MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); MPIR_Get_count_impl(&status, MPI_BYTE, &recv_bytes); - MPIR_Typerep_copy(bcast_data_addr, &recv_bytes, sizeof(int)); + MPIR_Typerep_copy(bcast_data_addr, &recv_bytes, sizeof(int), + MPIR_TYPEREP_FLAG_NONE); /* It is necessary to copy the errflag as well to handle the case when non-root * becomes temporary root as part of compositions (or smp aware colls). These temp * roots might expect same data as other ranks but different from the actual root. * So only datasize mismatch handling is not sufficient */ MPIR_Typerep_copy((char *) bcast_data_addr + MPIDU_SHM_CACHE_LINE_LEN, errflag, - sizeof(MPIR_Errflag_t)); + sizeof(MPIR_Errflag_t), MPIR_TYPEREP_FLAG_NONE); if ((int) recv_bytes != count) { /* It is OK to compare with count because datatype is always MPI_BYTE for Bcast */ *errflag = MPIR_ERR_OTHER; @@ -139,13 +140,13 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_mpi_release_gather_release(void *local_ /* When error checking is enabled, place the datasize in shm_buf first, followed by the * errflag, followed by the actual data with an offset of (2*cacheline_size) bytes from * the starting address */ - MPIR_Typerep_copy(bcast_data_addr, &count, sizeof(int)); + MPIR_Typerep_copy(bcast_data_addr, &count, sizeof(int), MPIR_TYPEREP_FLAG_NONE); /* It is necessary to copy the errflag as well to handle the case when non-root * becomes root as part of compositions (or smp aware colls). These roots might * expect same data as other ranks but different from the actual root. So only * datasize mismatch handling is not sufficient */ MPIR_Typerep_copy((char *) bcast_data_addr + MPIDU_SHM_CACHE_LINE_LEN, errflag, - sizeof(MPIR_Errflag_t)); + sizeof(MPIR_Errflag_t), MPIR_TYPEREP_FLAG_NONE); mpi_errno = MPIR_Localcopy(local_buf, count, datatype, (char *) bcast_data_addr + 2 * MPIDU_SHM_CACHE_LINE_LEN, count, @@ -205,9 +206,9 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_mpi_release_gather_release(void *local_ * expecting. Also, the errflag is copied out. In case of mismatch mpi_errno is set. * Actual data starts after (2*cacheline_size) bytes */ int recv_bytes, recv_errflag; - MPIR_Typerep_copy(&recv_bytes, bcast_data_addr, sizeof(int)); + MPIR_Typerep_copy(&recv_bytes, bcast_data_addr, sizeof(int), MPIR_TYPEREP_FLAG_NONE); MPIR_Typerep_copy(&recv_errflag, (char *) bcast_data_addr + MPIDU_SHM_CACHE_LINE_LEN, - sizeof(int)); + sizeof(int), MPIR_TYPEREP_FLAG_NONE); if (recv_bytes != count || recv_errflag != MPI_SUCCESS) { /* It is OK to compare with count because datatype is always MPI_BYTE for Bcast */ *errflag = MPIR_ERR_OTHER; diff --git a/src/mpid/ch4/src/mpidig_recv.h b/src/mpid/ch4/src/mpidig_recv.h index 54a6789b151..4b2a64d7d1b 100644 --- a/src/mpid/ch4/src/mpidig_recv.h +++ b/src/mpid/ch4/src/mpidig_recv.h @@ -72,7 +72,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_copy_from_unexp_req(MPIR_Request * req, void if (!dt_contig) { MPI_Aint actual_unpack_bytes; MPIR_Typerep_unpack(MPIDIG_REQUEST(req, buffer), nbytes, user_buf, user_count, - user_datatype, 0, &actual_unpack_bytes); + user_datatype, 0, &actual_unpack_bytes, MPIR_TYPEREP_FLAG_NONE); if (actual_unpack_bytes != nbytes) { mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, __FUNCTION__, __LINE__, @@ -85,7 +85,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_copy_from_unexp_req(MPIR_Request * req, void * the absolute address of the buffer (e.g. buf == MPI_BOTTOM). */ char *addr = MPIR_get_contig_ptr(user_buf, dt_true_lb); - MPIR_Typerep_copy(addr, MPIDIG_REQUEST(req, buffer), nbytes); + MPIR_Typerep_copy(addr, MPIDIG_REQUEST(req, buffer), nbytes, MPIR_TYPEREP_FLAG_NONE); } } diff --git a/src/mpid/ch4/src/mpidig_recv_utils.h b/src/mpid/ch4/src/mpidig_recv_utils.h index 52683273758..ad6454d5dcb 100644 --- a/src/mpid/ch4/src/mpidig_recv_utils.h +++ b/src/mpid/ch4/src/mpidig_recv_utils.h @@ -172,7 +172,8 @@ MPL_STATIC_INLINE_PREFIX void MPIDIG_recv_copy(void *in_data, MPIR_Request * rre MPIR_Typerep_unpack(in_data, in_data_sz, MPIDIG_REQUEST(rreq, buffer), MPIDIG_REQUEST(rreq, count), - MPIDIG_REQUEST(rreq, datatype), 0, &actual_unpack_bytes); + MPIDIG_REQUEST(rreq, datatype), + 0, &actual_unpack_bytes, MPIR_TYPEREP_FLAG_NONE); if (!rreq->status.MPI_ERROR && in_data_sz > actual_unpack_bytes) { /* Truncation error has been checked at MPIDIG_recv_type_init. * If the receive buffer had enough space, but we still @@ -195,7 +196,7 @@ MPL_STATIC_INLINE_PREFIX void MPIDIG_recv_copy(void *in_data, MPIR_Request * rre } data_sz = MPL_MIN(data_sz, in_data_sz); - MPIR_Typerep_copy(data, in_data, data_sz); + MPIR_Typerep_copy(data, in_data, data_sz, MPIR_TYPEREP_FLAG_NONE); MPIR_STATUS_SET_COUNT(rreq->status, data_sz); } else { /* noncontig case */ @@ -206,7 +207,8 @@ MPL_STATIC_INLINE_PREFIX void MPIDIG_recv_copy(void *in_data, MPIR_Request * rre int rem = in_data_sz; for (int i = 0; i < iov_len && rem > 0; i++) { int curr_len = MPL_MIN(rem, iov[i].iov_len); - MPIR_Typerep_copy(iov[i].iov_base, (char *) in_data + done, curr_len); + MPIR_Typerep_copy(iov[i].iov_base, (char *) in_data + done, curr_len, + MPIR_TYPEREP_FLAG_NONE); rem -= curr_len; done += curr_len; } @@ -272,7 +274,8 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_recv_copy_seg(void *payload, MPI_Aint payloa MPIR_Typerep_unpack(payload, payload_sz, MPIDIG_REQUEST(rreq, buffer), MPIDIG_REQUEST(rreq, count), - MPIDIG_REQUEST(rreq, datatype), p->offset, &actual_unpack_bytes); + MPIDIG_REQUEST(rreq, datatype), + p->offset, &actual_unpack_bytes, MPIR_TYPEREP_FLAG_NONE); p->offset += payload_sz; if (payload_sz > actual_unpack_bytes) { /* basic element size mismatch */ @@ -294,14 +297,16 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_recv_copy_seg(void *payload, MPI_Aint payloa int iov_done = 0; for (int i = 0; i < p->iov_num; i++) { if (payload_sz < p->iov_ptr[i].iov_len) { - MPIR_Typerep_copy(p->iov_ptr[i].iov_base, payload, payload_sz); + MPIR_Typerep_copy(p->iov_ptr[i].iov_base, payload, payload_sz, + MPIR_TYPEREP_FLAG_NONE); p->iov_ptr[i].iov_base = (char *) p->iov_ptr[i].iov_base + payload_sz; p->iov_ptr[i].iov_len -= payload_sz; /* not done */ break; } else { /* fill one iov */ - MPIR_Typerep_copy(p->iov_ptr[i].iov_base, payload, p->iov_ptr[i].iov_len); + MPIR_Typerep_copy(p->iov_ptr[i].iov_base, payload, p->iov_ptr[i].iov_len, + MPIR_TYPEREP_FLAG_NONE); payload = (char *) payload + p->iov_ptr[i].iov_len; payload_sz -= p->iov_ptr[i].iov_len; iov_done++; diff --git a/src/mpid/ch4/src/mpidig_rma.h b/src/mpid/ch4/src/mpidig_rma.h index cad2aca7108..1f3c8d1e2fb 100644 --- a/src/mpid/ch4/src/mpidig_rma.h +++ b/src/mpid/ch4/src/mpidig_rma.h @@ -776,8 +776,9 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_mpi_compare_and_swap(const void *origin_addr p_data = MPL_malloc(data_sz * 2, MPL_MEM_BUFFER); MPIR_Assert(p_data); - MPIR_Typerep_copy(p_data, (char *) origin_addr, data_sz); - MPIR_Typerep_copy((char *) p_data + data_sz, (char *) compare_addr, data_sz); + MPIR_Typerep_copy(p_data, (char *) origin_addr, data_sz, MPIR_TYPEREP_FLAG_NONE); + MPIR_Typerep_copy((char *) p_data + data_sz, (char *) compare_addr, data_sz, + MPIR_TYPEREP_FLAG_NONE); sreq = MPIDIG_request_create(MPIR_REQUEST_KIND__RMA, 1, vci, vci); MPIR_ERR_CHKANDSTMT(sreq == NULL, mpi_errno, MPIX_ERR_NOREQ, goto fn_fail, "**nomemreq"); diff --git a/src/mpid/ch4/src/mpidig_rma_callbacks.c b/src/mpid/ch4/src/mpidig_rma_callbacks.c index 86dc8ef4432..400fbb1b83e 100644 --- a/src/mpid/ch4/src/mpidig_rma_callbacks.c +++ b/src/mpid/ch4/src/mpidig_rma_callbacks.c @@ -805,7 +805,7 @@ static int handle_get_acc_cmpl(MPIR_Request * rreq) MPIDIG_REQUEST(rreq, req->areq.target_count), MPIDIG_REQUEST(rreq, req-> areq.target_datatype), - 0, original, result_data_sz, &actual_pack_bytes); + 0, original, result_data_sz, &actual_pack_bytes, MPIR_TYPEREP_FLAG_NONE); MPIR_Assert(actual_pack_bytes == result_data_sz); mpi_errno = MPIDIG_compute_acc_op(MPIDIG_REQUEST(rreq, req->areq.data), @@ -1062,10 +1062,13 @@ static int cswap_target_cmpl_cb(MPIR_Request * rreq) if (MPIR_Compare_equal((void *) MPIDIG_REQUEST(rreq, buffer), compare_addr, MPIDIG_REQUEST(rreq, datatype))) { - MPIR_Typerep_copy(compare_addr, (void *) MPIDIG_REQUEST(rreq, buffer), data_sz); - MPIR_Typerep_copy((void *) MPIDIG_REQUEST(rreq, buffer), origin_addr, data_sz); + MPIR_Typerep_copy(compare_addr, (void *) MPIDIG_REQUEST(rreq, buffer), data_sz, + MPIR_TYPEREP_FLAG_NONE); + MPIR_Typerep_copy((void *) MPIDIG_REQUEST(rreq, buffer), origin_addr, data_sz, + MPIR_TYPEREP_FLAG_NONE); } else { - MPIR_Typerep_copy(compare_addr, (void *) MPIDIG_REQUEST(rreq, buffer), data_sz); + MPIR_Typerep_copy(compare_addr, (void *) MPIDIG_REQUEST(rreq, buffer), data_sz, + MPIR_TYPEREP_FLAG_NONE); } #ifndef MPIDI_CH4_DIRECT_NETMOD From 58409d6ac9d8a17b7a2fef4758a14c5205f5f28b Mon Sep 17 00:00:00 2001 From: Wesley Bland Date: Fri, 14 Jan 2022 11:51:13 -0600 Subject: [PATCH 310/607] mpi/datatype: Use streaming memcpy when requested --- src/mpi/datatype/typerep/src/typerep_dataloop_pack.c | 6 +++++- src/mpi/datatype/typerep/src/typerep_yaksa_pack.c | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/mpi/datatype/typerep/src/typerep_dataloop_pack.c b/src/mpi/datatype/typerep/src/typerep_dataloop_pack.c index e9cb18c5f40..7e7b306f9d5 100644 --- a/src/mpi/datatype/typerep/src/typerep_dataloop_pack.c +++ b/src/mpi/datatype/typerep/src/typerep_dataloop_pack.c @@ -13,7 +13,11 @@ int MPIR_Typerep_icopy(void *outbuf, const void *inbuf, MPI_Aint num_bytes, { MPIR_FUNC_ENTER; - MPIR_Memcpy(outbuf, inbuf, num_bytes); + if (flags & MPIR_TYPEREP_FLAG_STREAM) { + MPIR_Memcpy_stream(outbuf, inbuf, num_bytes); + } else { + MPIR_Memcpy(outbuf, inbuf, num_bytes); + } MPIR_FUNC_EXIT; return MPI_SUCCESS; diff --git a/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c b/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c index 571f25ef281..1c6e6585355 100644 --- a/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c +++ b/src/mpi/datatype/typerep/src/typerep_yaksa_pack.c @@ -159,7 +159,11 @@ static int typerep_do_pack(const void *inbuf, MPI_Aint incount, MPI_Datatype dat MPI_Aint real_bytes = MPL_MIN(total_size - inoffset, max_pack_bytes); /* Make sure we never pack partial element */ real_bytes -= real_bytes % element_size; - MPIR_Memcpy(outbuf, MPIR_get_contig_ptr(inbuf_ptr, inoffset), real_bytes); + if (flags & MPIR_TYPEREP_FLAG_STREAM) { + MPIR_Memcpy_stream(outbuf, MPIR_get_contig_ptr(inbuf_ptr, inoffset), real_bytes); + } else { + MPIR_Memcpy(outbuf, MPIR_get_contig_ptr(inbuf_ptr, inoffset), real_bytes); + } *actual_pack_bytes = real_bytes; goto fn_exit; } From 33e8f398df7ef468148f791abbe722c4ef0a2627 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 4 Nov 2021 21:29:06 -0500 Subject: [PATCH 311/607] maint: add prebuild_modules.sh This script pre-build modules and create modules.tar.gz. If we copy this tarball to a build directory, both autogen.sh and configure will skip the modules in the build steps. This is to accelerate the repeated CI build. --- maint/prebuild_modules.sh | 74 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100755 maint/prebuild_modules.sh diff --git a/maint/prebuild_modules.sh b/maint/prebuild_modules.sh new file mode 100755 index 00000000000..4a61e24e583 --- /dev/null +++ b/maint/prebuild_modules.sh @@ -0,0 +1,74 @@ +#! /usr/bin/env bash +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +# Prebuild modules into modules.tar.gz. Copy the tarball to a fresh git cloned repository, +# both autogen.sh and configure will skip them in the build process. +# +# This is to accelerate repeated CI testing. +# + +git submodule update --init + +make_it_lean () { + rm -rf .git + find . -name '*.o' | xargs rm -f +} + +pushd modules/hwloc +./autogen.sh +./configure CFLAGS=-fvisibility=hidden \ + --enable-embedded-mode --enable-visibility=no \ + --disable-libxml2 --disable-nvml --disable-cuda --disable-opencl --disable-rsmi +make +make_it_lean +popd + +pushd modules/json-c +./autogen.sh +./configure --enable-embedded --disable-werror +make +make_it_lean +popd + +pushd modules/yaksa +extra_option= +if test -d "$CUDA_DIR" ; then + extra_option=--with-cuda=$CUDA_DIR +fi +./autogen.sh +./configure --enable-embedded $extra_option +make +make_it_lean +popd + +pushd modules/libfabric +extra_option= +if test $(uname) = "FreeBSD" ; then + extra_option='--disable-verbs' +fi +./autogen.sh +./configure --enable-embedded $extra_option +make +make_it_lean +popd + +# ucx need make install to work, which need replace all hardcoded paths to work +pushd modules/ucx +./autogen.sh +if false ; then + # skip for now + ./configure --prefix=/MODPREFIX --disable-static + make + find . -name '*.la' | xargs --verbose sed -i "s,$PWD,MODDIR,g" +fi +make_it_lean +popd + +# Add a flag to mark modules as pre-built. Remove the flag file to allow configure +# reconfigure and rebuild modules. +touch modules/PREBUILT + +tar czf modules.tar.gz modules From caff74542576ea67128bf8153dee72ec5c0df386 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 4 Nov 2021 21:36:28 -0500 Subject: [PATCH 312/607] autogen: untar modules.tar.gz in quick mode --- autogen.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/autogen.sh b/autogen.sh index 8f58fb1faa3..33a48e70cb9 100755 --- a/autogen.sh +++ b/autogen.sh @@ -79,6 +79,12 @@ for arg in "$@" ; do do_hydra=yes do_hydra2=no do_romio=no + + if test -e 'modules.tar.gz' -a ! -e 'modules/PREBUILT' ; then + echo_n "Untaring modules.tar.gz... " + tar xf modules.tar.gz + echo "done" + fi fi done From f834314286c4ed7e359240fa60a23f2e0fa4d016 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 4 Nov 2021 19:52:55 -0500 Subject: [PATCH 313/607] autogen: skip hwloc and json-c in quick mode --- autogen.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/autogen.sh b/autogen.sh index 33a48e70cb9..0d2d233919c 100755 --- a/autogen.sh +++ b/autogen.sh @@ -71,6 +71,8 @@ do_quick=no for arg in "$@" ; do if test $arg = "-quick"; then do_quick=yes + do_hwloc=no + do_json=no do_izem=no do_ofi=no do_ucx=no From c29993b35016c0d2abe75c4950e51e0b197577fa Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 4 Nov 2021 20:13:08 -0500 Subject: [PATCH 314/607] configure: skip configure submodules if already built When using embedded modules, check whether the corresponding convenience library already exists and skip the configure if it does. Note: the prebuilt module Makefiles contains absolute paths that may be different from the current working dir. Thus we have to remove the module subdir from the Makefile as well. This works as long as we do not need to re-configure the pre-built submodules. If we ever need to re-configure submodules, simply remove the la files, e.g. find modules '*.la' | xargs rm and rerun configure. --- confdb/aclocal_modules.m4 | 10 ++++--- configure.ac | 28 +++++++++++++------- src/mpi/datatype/typerep/src/subconfigure.m4 | 19 ++++++------- src/mpid/ch4/netmod/ofi/subconfigure.m4 | 24 +++++++++-------- src/mpid/ch4/netmod/ucx/subconfigure.m4 | 24 ++++++++++------- 5 files changed, 62 insertions(+), 43 deletions(-) diff --git a/confdb/aclocal_modules.m4 b/confdb/aclocal_modules.m4 index d198051a71f..2f879aeb5a6 100644 --- a/confdb/aclocal_modules.m4 +++ b/confdb/aclocal_modules.m4 @@ -84,9 +84,13 @@ AC_DEFUN([PAC_CONFIG_HWLOC],[ if test "$with_hwloc" = "embedded" ; then m4_if(hwloc_embedded_dir, [modules/hwloc], [ dnl ---- the main MPICH configure ---- - PAC_CONFIG_HWLOC_EMBEDDED([$VISIBILITY_CFLAGS]) - hwlocsrcdir="${main_top_builddir}/modules/hwloc" - hwloclib="${main_top_builddir}/modules/hwloc/hwloc/libhwloc_embedded.la" + hwloclib="modules/hwloc/hwloc/libhwloc_embedded.la" + if test -e "${use_top_srcdir}/modules/PREBUILT" -a -e "$hwloclib"; then + hwlocsrcdir="" + else + hwlocsrcdir="${main_top_builddir}/modules/hwloc" + PAC_CONFIG_HWLOC_EMBEDDED([$VISIBILITY_CFLAGS]) + fi PAC_APPEND_FLAG([-I${use_top_srcdir}/modules/hwloc/include],[CPPFLAGS]) PAC_APPEND_FLAG([-I${main_top_builddir}/modules/hwloc/include],[CPPFLAGS]) diff --git a/configure.ac b/configure.ac index 3a0d8479353..7ecdbcb7444 100644 --- a/configure.ac +++ b/configure.ac @@ -1083,10 +1083,14 @@ PAC_CHECK_HEADER_LIB_EXPLICIT([zm],[lock/zm_ticket.h],[$ZMLIBNAME],[zm_ticket_in if test "$enable_izem_queue" != "no" && test "$enable_izem_queue" != "none"; then if test "$with_zm" = "embedded" ; then if test -e "${use_top_srcdir}/modules/izem" ; then - zm_subdir_args="--enable-embedded" - PAC_CONFIG_SUBDIR_ARGS([modules/izem],[$zm_subdir_args],[],[AC_MSG_ERROR(Izem configure failed)]) - zmsrcdir="${main_top_builddir}/modules/izem" - zmlib="${main_top_builddir}/modules/izem/src/lib${ZMLIBNAME}.la" + zmlib="modules/izem/src/lib${ZMLIBNAME}.la" + if test -e "${use_top_srcdir}/modules/PREBUILT" -a -e "$zmlib"; then + zmsrcdir="" + else + zm_subdir_args="--enable-embedded" + PAC_CONFIG_SUBDIR_ARGS([modules/izem],[$zm_subdir_args],[],[AC_MSG_ERROR(Izem configure failed)]) + zmsrcdir="${main_top_builddir}/modules/izem" + fi PAC_APPEND_FLAG([-I${use_top_srcdir}/modules/izem/src/include],[CPPFLAGS]) PAC_APPEND_FLAG([-I${main_top_builddir}/modules/izem/src/include],[CPPFLAGS]) else @@ -1103,12 +1107,16 @@ AC_SUBST([jsonsrcdir]) jsonlib="" AC_SUBST([jsonlib]) -PAC_PUSH_ALL_FLAGS() -PAC_RESET_ALL_FLAGS() -PAC_CONFIG_SUBDIR_ARGS([modules/json-c],[--enable-embedded --disable-werror],[],[AC_MSG_ERROR(json-c configure failed)]) -PAC_POP_ALL_FLAGS() -jsonsrcdir="${main_top_builddir}/modules/json-c" -jsonlib="${main_top_builddir}/modules/json-c/libjson-c.la" +jsonlib="modules/json-c/libjson-c.la" +if test -e "${use_top_srcdir}/modules/PREBUILT" -a -e "$jsonlib"; then + jsonsrcdir="" +else + PAC_PUSH_ALL_FLAGS() + PAC_RESET_ALL_FLAGS() + PAC_CONFIG_SUBDIR_ARGS([modules/json-c],[--enable-embedded --disable-werror],[],[AC_MSG_ERROR(json-c configure failed)]) + PAC_POP_ALL_FLAGS() + jsonsrcdir="${main_top_builddir}/modules/json-c" +fi PAC_APPEND_FLAG([-I${use_top_srcdir}/modules/json-c],[CPPFLAGS]) PAC_APPEND_FLAG([-I${main_top_builddir}/modules/json-c],[CPPFLAGS]) diff --git a/src/mpi/datatype/typerep/src/subconfigure.m4 b/src/mpi/datatype/typerep/src/subconfigure.m4 index 61b37772d2d..e72262a08ac 100644 --- a/src/mpi/datatype/typerep/src/subconfigure.m4 +++ b/src/mpi/datatype/typerep/src/subconfigure.m4 @@ -46,17 +46,18 @@ AM_COND_IF([BUILD_YAKSA_ENGINE], [ m4_define([yaksa_embedded_dir],[modules/yaksa]) PAC_CHECK_HEADER_LIB_EXPLICIT([yaksa],[yaksa.h],[$YAKSALIBNAME],[yaksa_init]) if test "$with_yaksa" = "embedded" ; then - PAC_PUSH_ALL_FLAGS() - PAC_RESET_ALL_FLAGS() - # no need for libtool versioning when embedding YAKSA - yaksa_subdir_args="--enable-embedded" - PAC_CONFIG_SUBDIR_ARGS([modules/yaksa],[$yaksa_subdir_args],[],[AC_MSG_ERROR(YAKSA configure failed)]) - PAC_POP_ALL_FLAGS() + yaksalib="modules/yaksa/lib${YAKSALIBNAME}.la" + if test ! -e "$yaksalib" ; then + PAC_PUSH_ALL_FLAGS() + PAC_RESET_ALL_FLAGS() + # no need for libtool versioning when embedding YAKSA + yaksa_subdir_args="--enable-embedded" + PAC_CONFIG_SUBDIR_ARGS([modules/yaksa],[$yaksa_subdir_args],[],[AC_MSG_ERROR(YAKSA configure failed)]) + PAC_POP_ALL_FLAGS() + yaksasrcdir="modules/yaksa" + fi PAC_APPEND_FLAG([-I${main_top_builddir}/modules/yaksa/src/frontend/include], [CPPFLAGS]) PAC_APPEND_FLAG([-I${use_top_srcdir}/modules/yaksa/src/frontend/include], [CPPFLAGS]) - - yaksasrcdir="modules/yaksa" - yaksalib="modules/yaksa/lib${YAKSALIBNAME}.la" fi ]) diff --git a/src/mpid/ch4/netmod/ofi/subconfigure.m4 b/src/mpid/ch4/netmod/ofi/subconfigure.m4 index 83891a0ab18..ccb011ecf55 100644 --- a/src/mpid/ch4/netmod/ofi/subconfigure.m4 +++ b/src/mpid/ch4/netmod/ofi/subconfigure.m4 @@ -303,14 +303,19 @@ AM_COND_IF([BUILD_CH4_NETMOD_OFI],[ AC_MSG_NOTICE([Enabling direct embedded provider: ${ofi_direct_provider}]) fi - ofi_subdir_args="$ofi_subdir_args $prov_config" - - dnl Unset all of these env vars so they don't pollute the libfabric configuration - PAC_PUSH_ALL_FLAGS() - PAC_RESET_ALL_FLAGS() - CFLAGS="$CFLAGS $VISIBILITY_CFLAGS" - PAC_CONFIG_SUBDIR_ARGS([modules/libfabric],[$ofi_subdir_args],[],[AC_MSG_ERROR(libfabric configure failed)]) - PAC_POP_ALL_FLAGS() + ofilib="modules/libfabric/src/libfabric.la" + if test -e "${use_top_srcdir}/modules/PREBUILT" -a -e "$ofilib"; then + ofisrcdir="" + else + ofi_subdir_args="$ofi_subdir_args $prov_config" + dnl Unset all of these env vars so they don't pollute the libfabric configuration + PAC_PUSH_ALL_FLAGS() + PAC_RESET_ALL_FLAGS() + CFLAGS="$CFLAGS $VISIBILITY_CFLAGS" + PAC_CONFIG_SUBDIR_ARGS([modules/libfabric],[$ofi_subdir_args],[],[AC_MSG_ERROR(libfabric configure failed)]) + PAC_POP_ALL_FLAGS() + ofisrcdir="${main_top_builddir}/modules/libfabric" + fi PAC_APPEND_FLAG([-I${main_top_builddir}/modules/libfabric/include], [CPPFLAGS]) PAC_APPEND_FLAG([-I${use_top_srcdir}/modules/libfabric/include], [CPPFLAGS]) @@ -319,9 +324,6 @@ AM_COND_IF([BUILD_CH4_NETMOD_OFI],[ PAC_APPEND_FLAG([-I${use_top_srcdir}/modules/libfabric/prov/${ofi_direct_provider}/include], [CPPFLAGS]) PAC_APPEND_FLAG([-DFABRIC_DIRECT],[CPPFLAGS]) fi - - ofisrcdir="${main_top_builddir}/modules/libfabric" - ofilib="modules/libfabric/src/libfabric.la" else AC_MSG_NOTICE([CH4 OFI Netmod: Using an external libfabric]) PAC_LIBS_ADD([-lfabric]) diff --git a/src/mpid/ch4/netmod/ucx/subconfigure.m4 b/src/mpid/ch4/netmod/ucx/subconfigure.m4 index c8659879827..b7e3b701a19 100644 --- a/src/mpid/ch4/netmod/ucx/subconfigure.m4 +++ b/src/mpid/ch4/netmod/ucx/subconfigure.m4 @@ -39,21 +39,25 @@ AM_COND_IF([BUILD_CH4_NETMOD_UCX],[ with_ucx=embedded fi if test "$with_ucx" = "embedded" ; then - PAC_PUSH_ALL_FLAGS() - PAC_RESET_ALL_FLAGS() - if test "$enable_fast" = "yes" -o "$enable_fast" = "all" ; then - # add flags from contrib/configure-release and contrib/configure-opt scripts in the ucx source - ucx_opt_flags="--disable-logging --disable-debug --disable-assertions --disable-params-check --enable-optimizations" + ucxlib="modules/ucx/src/ucp/libucp.la" + if test -e "${use_top_srcdir}/modules/PREBUILT" -a -e "$ucxlib"; then + ucxdir="" else - ucx_opt_flags="" + PAC_PUSH_ALL_FLAGS() + PAC_RESET_ALL_FLAGS() + if test "$enable_fast" = "yes" -o "$enable_fast" = "all" ; then + # add flags from contrib/configure-release and contrib/configure-opt scripts in the ucx source + ucx_opt_flags="--disable-logging --disable-debug --disable-assertions --disable-params-check --enable-optimizations" + else + ucx_opt_flags="" + fi + PAC_CONFIG_SUBDIR_ARGS([modules/ucx],[--disable-static --enable-embedded --with-java=no $ucx_opt_flags],[],[AC_MSG_ERROR(ucx configure failed)]) + PAC_POP_ALL_FLAGS() + ucxdir="modules/ucx" fi - PAC_CONFIG_SUBDIR_ARGS([modules/ucx],[--disable-static --enable-embedded --with-java=no $ucx_opt_flags],[],[AC_MSG_ERROR(ucx configure failed)]) - PAC_POP_ALL_FLAGS() PAC_APPEND_FLAG([-I${main_top_builddir}/modules/ucx/src], [CPPFLAGS]) PAC_APPEND_FLAG([-I${use_top_srcdir}/modules/ucx/src], [CPPFLAGS]) - ucxdir="modules/ucx" - ucxlib="modules/ucx/src/ucp/libucp.la" else dnl PAC_PROBE_HEADER_LIB must've been successful AC_MSG_NOTICE([CH4 UCX Netmod: Using an external ucx]) From e127db3f69932177fc37092a2a36300ac2dca232 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 17 Jan 2022 23:29:25 -0600 Subject: [PATCH 315/607] configure: avoid AC_TYPE_INT8_T etc The autoconf macro AC_TYPE_INT8_T will typedef int8_t signed char, which does not serve our purpose. Directly use AC_CHECK_SIZEOF instead. --- configure.ac | 54 +++++++++++++++++++++------------------------------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/configure.ac b/configure.ac index 7ecdbcb7444..f8ae09b6210 100644 --- a/configure.ac +++ b/configure.ac @@ -2802,10 +2802,6 @@ AC_CHECK_ALIGNOF(long long) AC_CHECK_ALIGNOF(long double) AC_CHECK_ALIGNOF(short) AC_CHECK_ALIGNOF(int) -AC_CHECK_ALIGNOF(int8_t) -AC_CHECK_ALIGNOF(int16_t) -AC_CHECK_ALIGNOF(int32_t) -AC_CHECK_ALIGNOF(int64_t) AC_CHECK_ALIGNOF(bool) AC_CHECK_ALIGNOF(wchar_t) @@ -2816,50 +2812,44 @@ AC_DEFINE(HAVE_SYS_BITYPES_H,1,[Define if sys/bitypes.h exists])]) # A C99 compliant compiler should have inttypes.h for fixed-size int types AC_CHECK_HEADERS(inttypes.h stdint.h) -# Check for types -AC_TYPE_INT8_T -AC_TYPE_INT16_T -AC_TYPE_INT32_T -AC_TYPE_INT64_T +AC_CHECK_SIZEOF(int8_t) +AC_CHECK_SIZEOF(int16_t) +AC_CHECK_SIZEOF(int32_t) +AC_CHECK_SIZEOF(int64_t) + +AC_CHECK_SIZEOF(uint8_t) +AC_CHECK_SIZEOF(uint16_t) +AC_CHECK_SIZEOF(uint32_t) +AC_CHECK_SIZEOF(uint64_t) -# Temporary issue in autoconf integer type checking (remove when -# autoconf fixes this or provides a workaround for it) -if test "$ac_cv_c_int8_t" != no ; then +AC_CHECK_ALIGNOF(int8_t) +AC_CHECK_ALIGNOF(int16_t) +AC_CHECK_ALIGNOF(int32_t) +AC_CHECK_ALIGNOF(int64_t) + +if test "$ac_cv_sizeof_int8_t" -eq 1 ; then AC_DEFINE(HAVE_INT8_T,1,[Define if int8_t is supported by the C compiler]) fi -if test "$ac_cv_c_int16_t" != no ; then +if test "$ac_cv_sizeof_int16_t" -eq 2 ; then AC_DEFINE(HAVE_INT16_T,1,[Define if int16_t is supported by the C compiler]) fi -if test "$ac_cv_c_int32_t" != no ; then +if test "$ac_cv_sizeof_int32_t" -eq 4 ; then AC_DEFINE(HAVE_INT32_T,1,[Define if int32_t is supported by the C compiler]) fi -if test "$ac_cv_c_int64_t" != no ; then +if test "$ac_cv_sizeof_int64_t" -eq 8 ; then AC_DEFINE(HAVE_INT64_T,1,[Define if int64_t is supported by the C compiler]) fi -# The following make these definitions: -# define _UINT_T 1 -# if uint_t is available. E.g., define _UINT8_T as 1 if uint8_t is available -# if not available, define uint_t as the related C type, e.g., -# define uint8_t unsigned char -# -AC_TYPE_UINT8_T -AC_TYPE_UINT16_T -AC_TYPE_UINT32_T -AC_TYPE_UINT64_T - -# Temporary issue in autoconf integer type checking (remove when -# autoconf fixes this or provides a workaround for it) -if test "$ac_cv_c_uint8_t" != no ; then +if test "$ac_cv_sizeof_uint8_t" -eq 1 ; then AC_DEFINE(HAVE_UINT8_T,1,[Define if uint8_t is supported by the C compiler]) fi -if test "$ac_cv_c_uint16_t" != no ; then +if test "$ac_cv_sizeof_uint16_t" -eq 2 ; then AC_DEFINE(HAVE_UINT16_T,1,[Define if uint16_t is supported by the C compiler]) fi -if test "$ac_cv_c_uint32_t" != no ; then +if test "$ac_cv_sizeof_uint32_t" -eq 4 ; then AC_DEFINE(HAVE_UINT32_T,1,[Define if uint32_t is supported by the C compiler]) fi -if test "$ac_cv_c_uint64_t" != no ; then +if test "$ac_cv_sizeof_uint64_t" -eq 8 ; then AC_DEFINE(HAVE_UINT64_T,1,[Define if uint64_t is supported by the C compiler]) fi From 96fa0bd308da318df7fb0ef30b3c1e5456c88c1b Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 18 Jan 2022 10:35:59 -0600 Subject: [PATCH 316/607] maint: Add libtool.m4 patch for NVIDIA HPC Compilers Patch adapted from the libtool patches list. https://lists.gnu.org/archive/html/libtool-patches/2020-08/msg00000.html. --- autogen.sh | 1 + maint/patches/optional/confdb/hpc-sdk.patch | 50 +++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 maint/patches/optional/confdb/hpc-sdk.patch diff --git a/autogen.sh b/autogen.sh index 0d2d233919c..9a053f86ffd 100755 --- a/autogen.sh +++ b/autogen.sh @@ -576,6 +576,7 @@ autoreconf_amdir() { _patch_libtool $_dir/confdb/ltmain.sh intel-compiler.patch _patch_libtool $_dir/confdb/libtool.m4 sys_lib_dlsearch_path_spec.patch _patch_libtool $_dir/confdb/libtool.m4 big-sur.patch + _patch_libtool $_dir/confdb/libtool.m4 hpc-sdk.patch if test "$do_fortran" = "yes" ; then _patch_libtool $_dir/confdb/libtool.m4 darwin-ifort.patch _patch_libtool $_dir/confdb/libtool.m4 oracle-fort.patch diff --git a/maint/patches/optional/confdb/hpc-sdk.patch b/maint/patches/optional/confdb/hpc-sdk.patch new file mode 100644 index 00000000000..fb5ad74d2e9 --- /dev/null +++ b/maint/patches/optional/confdb/hpc-sdk.patch @@ -0,0 +1,50 @@ +--- a/m4/libtool.m4 ++++ b/m4/libtool.m4 +@@ -4400,8 +4400,8 @@ m4_if([$1], [CXX], [ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; +- pgCC* | pgcpp*) +- # Portland Group C++ compiler ++ pgCC* | pgcpp* | pgc\+\+* | nvc\+\+*) ++ # NVIDIA HPC C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' +@@ -4737,9 +4737,8 @@ m4_if([$1], [CXX], [ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; +- pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) +- # Portland Group compilers (*not* the Pentium gcc compiler, +- # which looks to be a dead project) ++ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran* | nvc | nvfortran*) ++ # NVIDIA HPC Compilers + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' +@@ -4779,7 +4778,7 @@ m4_if([$1], [CXX], [ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; +- *Portland\ Group*) ++ *Portland\ Group* | *NVIDIA\ Compilers* | *PGI\ Compilers*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' +@@ -5207,12 +5206,12 @@ _LT_EOF + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in +- pgcc*) # Portland Group C compiler ++ pgcc* | nvc) # NVIDIA HPC C++ Compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; +- pgf77* | pgf90* | pgf95* | pgfortran*) +- # Portland Group f77 and f90 compilers ++ pgf77* | pgf90* | pgf95* | pgfortran* | nvfortran*) ++ # NVIDIA HPC Fortran Compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 From abf7ae7766f5bd33438b9260500e6794bd3d80e7 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 18 Jan 2022 16:03:52 -0600 Subject: [PATCH 317/607] modules: update yaksa pmodels/yaksa#207: Silence warnings in non-debug builds pmodels/yaksa#209: Fix for building with NVIDIA HPC Compilers --- modules/yaksa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/yaksa b/modules/yaksa index e41b372c74a..6e4211e1cbd 160000 --- a/modules/yaksa +++ b/modules/yaksa @@ -1 +1 @@ -Subproject commit e41b372c74a45a604e8f3851a36b392fd5a06001 +Subproject commit 6e4211e1cbd4710b2c87216eaaab8e5ed6234768 From d06be8c7e69b0066247c5a7c4f154375caabb850 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Thu, 20 Jan 2022 14:34:59 -0600 Subject: [PATCH 318/607] ch4/ofi: Add missing setting to GNI capability set The GNI capability set was missed when adding the optimized memory regions setting. --- src/mpid/ch4/netmod/ofi/ofi_capability_sets.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mpid/ch4/netmod/ofi/ofi_capability_sets.h b/src/mpid/ch4/netmod/ofi/ofi_capability_sets.h index f1b41bd9f01..0a5171e8184 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_capability_sets.h +++ b/src/mpid/ch4/netmod/ofi/ofi_capability_sets.h @@ -531,6 +531,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_ENABLE_PT2PT_NOPACK_GNI MPIDI_OFI_ON #define MPIDI_OFI_ENABLE_HMEM_GNI MPIDI_OFI_OFF #define MPIDI_OFI_NUM_AM_BUFFERS_GNI MPIDI_OFI_MAX_NUM_AM_BUFFERS +#define MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS_GNI (0) #define MPIDI_OFI_CONTEXT_BITS_GNI (16) #define MPIDI_OFI_SOURCE_BITS_GNI (24) #define MPIDI_OFI_TAG_BITS_GNI (20) @@ -559,6 +560,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_OFI_get_set_number(const char *set_name) #define MPIDI_OFI_ENABLE_PT2PT_NOPACK MPIDI_OFI_ENABLE_PT2PT_NOPACK_GNI #define MPIDI_OFI_ENABLE_HMEM MPIDI_OFI_ENABLE_HMEM_GNI #define MPIDI_OFI_NUM_AM_BUFFERS MPIDI_OFI_NUM_AM_BUFFERS_GNI +#define MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS MPIDI_OFI_NUM_OPTIMIZED_MEMORY_REGIONS_GNI #define MPIDI_OFI_PROTOCOL_MASK (0xE000000000000000ULL) #define MPIDI_OFI_CONTEXT_MASK (0x0FFFF00000000000ULL) #define MPIDI_OFI_SOURCE_MASK (0x00000FFFFFF00000ULL) /* GNI does not support immediate data From 784879b13df33abbea052f80d8784b2b805a5a33 Mon Sep 17 00:00:00 2001 From: Wesley Bland Date: Mon, 15 Nov 2021 14:01:48 -0600 Subject: [PATCH 319/607] mpidu/genq: Create an MPMC queue option Adding a MPMC queue for later use with the free queues. This is very similar to the existing MPSC queue, but with an additional compare an swap when there is contention. --- src/mpid/common/genq/mpidu_genq_shmem_queue.c | 2 + src/mpid/common/genq/mpidu_genq_shmem_queue.h | 93 ++++++++++++++++++- 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/src/mpid/common/genq/mpidu_genq_shmem_queue.c b/src/mpid/common/genq/mpidu_genq_shmem_queue.c index 757d9c98f5f..439366fc384 100644 --- a/src/mpid/common/genq/mpidu_genq_shmem_queue.c +++ b/src/mpid/common/genq/mpidu_genq_shmem_queue.c @@ -22,6 +22,8 @@ int MPIDU_genq_shmem_queue_init(MPIDU_genq_shmem_queue_t queue, int flags) rc = MPIDU_genqi_inv_mpsc_init(queue_obj); } else if (flags == MPIDU_GENQ_SHMEM_QUEUE_TYPE__NEM_MPSC) { rc = MPIDU_genqi_nem_mpsc_init(queue_obj); + } else if (flags == MPIDU_GENQ_SHMEM_QUEUE_TYPE__NEM_MPMC) { + rc = MPIDU_genqi_nem_mpmc_init(queue_obj); } else { MPIR_Assert_error("Invalid GenQ flag"); } diff --git a/src/mpid/common/genq/mpidu_genq_shmem_queue.h b/src/mpid/common/genq/mpidu_genq_shmem_queue.h index c666001fa94..6940bb3bc4d 100644 --- a/src/mpid/common/genq/mpidu_genq_shmem_queue.h +++ b/src/mpid/common/genq/mpidu_genq_shmem_queue.h @@ -13,11 +13,13 @@ #include #define MPIDU_GENQ_SHMEM_QUEUE_TYPE__MPSC MPIDU_GENQ_SHMEM_QUEUE_TYPE__NEM_MPSC +#define MPIDU_GENQ_SHMEM_QUEUE_TYPE__MPMC MPIDU_GENQ_SHMEM_QUEUE_TYPE__NEM_MPMC typedef enum { MPIDU_GENQ_SHMEM_QUEUE_TYPE__SERIAL, MPIDU_GENQ_SHMEM_QUEUE_TYPE__INV_MPSC, MPIDU_GENQ_SHMEM_QUEUE_TYPE__NEM_MPSC, + MPIDU_GENQ_SHMEM_QUEUE_TYPE__NEM_MPMC, } MPIDU_genq_shmem_queue_type_e; /* SERIAL */ @@ -64,7 +66,7 @@ static inline int MPIDU_genqi_serial_enqueue(MPIDU_genqi_shmem_pool_s * pool_obj return 0; } -/* NEMESIS QUEUE */ +/* NEMESIS MPSC QUEUE */ static inline int MPIDU_genqi_nem_mpsc_init(MPIDU_genq_shmem_queue_u * queue) { @@ -129,6 +131,91 @@ static inline int MPIDU_genqi_nem_mpsc_enqueue(MPIDU_genqi_shmem_pool_s * pool_o return 0; } +/* NEMESIS MPMC QUEUE */ + +static inline int MPIDU_genqi_nem_mpmc_init(MPIDU_genq_shmem_queue_u * queue) +{ + MPL_atomic_store_ptr(&queue->q.head.m, NULL); + MPL_atomic_store_ptr(&queue->q.tail.m, NULL); + return 0; +} + +static inline int MPIDU_genqi_nem_mpmc_dequeue(MPIDU_genqi_shmem_pool_s * pool_obj, + MPIDU_genq_shmem_queue_u * queue, void **cell) +{ + int counter = 0; + + /* Add an inner loop here to avoid going all the way around the progress engine in the case of + * contention on this lock. If this is heavily contended, eventually this will give up and kick + * back out to the full progress engine. */ + while (counter++ <= 20) { + void *handle = MPL_atomic_load_ptr(&queue->q.head.m); + if (!handle) { + /* queue is empty */ + *cell = NULL; + break; + } else { + MPIDU_genqi_shmem_cell_header_s *cell_h = NULL; + cell_h = HANDLE_TO_HEADER(pool_obj, handle); + *cell = HEADER_TO_CELL(cell_h); + + void *next_handle = MPL_atomic_load_ptr(&cell_h->u.nem_queue.next_m); + if (next_handle != NULL) { + /* just dequeue the head */ + if (MPL_atomic_cas_ptr(&queue->q.head.m, handle, next_handle) != handle) { + /* Multiple head dequeues at the same time. Give up holding the head of the queue + * and start over. */ + *cell = NULL; + continue; + } + } else { + /* single element, tail == head, + * have to make sure no enqueuing is in progress */ + if (MPL_atomic_cas_ptr(&queue->q.head.m, handle, NULL) != handle) { + /* Conflicts over head/tail pointers. Give up holding the head of the queue and + * start over. */ + *cell = NULL; + continue; + } + if (MPL_atomic_cas_ptr(&queue->q.tail.m, handle, NULL) == handle) { + /* no enqueuing in progress, we are done */ + } else { + /* busy wait for the enqueuing to finish */ + do { + next_handle = MPL_atomic_load_ptr(&cell_h->u.nem_queue.next_m); + } while (next_handle == NULL); + /* then set the header */ + MPL_atomic_store_ptr(&queue->q.head.m, next_handle); + } + } + } + } + + return 0; +} + +static inline int MPIDU_genqi_nem_mpmc_enqueue(MPIDU_genqi_shmem_pool_s * pool_obj, + MPIDU_genq_shmem_queue_u * queue, void *cell) +{ + MPIDU_genqi_shmem_cell_header_s *cell_h = CELL_TO_HEADER(cell); + MPL_atomic_store_ptr(&cell_h->u.nem_queue.next_m, NULL); + + void *handle = (void *) cell_h->handle; + + void *tail_handle = NULL; + tail_handle = MPL_atomic_swap_ptr(&queue->q.tail.m, handle); + if (tail_handle == NULL) { + /* queue was empty */ + MPL_atomic_store_ptr(&queue->q.head.m, handle); + } else { + MPIDU_genqi_shmem_cell_header_s *tail_cell_h = NULL; + tail_cell_h = HANDLE_TO_HEADER(pool_obj, tail_handle); + MPL_atomic_store_ptr(&tail_cell_h->u.nem_queue.next_m, handle); + } + return 0; +} + + /* INVERSE QUEUE */ static inline int MPIDU_genqi_inv_mpsc_init(MPIDU_genq_shmem_queue_u * queue) @@ -231,6 +318,8 @@ static inline int MPIDU_genq_shmem_queue_dequeue(MPIDU_genq_shmem_pool_t pool, rc = MPIDU_genqi_inv_mpsc_dequeue(pool_obj, queue_obj, cell); } else if (flags == MPIDU_GENQ_SHMEM_QUEUE_TYPE__NEM_MPSC) { rc = MPIDU_genqi_nem_mpsc_dequeue(pool_obj, queue_obj, cell); + } else if (flags == MPIDU_GENQ_SHMEM_QUEUE_TYPE__NEM_MPMC) { + rc = MPIDU_genqi_nem_mpmc_dequeue(pool_obj, queue_obj, cell); } else { MPIR_Assert_error("Invalid GenQ flag"); } @@ -254,6 +343,8 @@ static inline int MPIDU_genq_shmem_queue_enqueue(MPIDU_genq_shmem_pool_t pool, rc = MPIDU_genqi_inv_mpsc_enqueue(pool_obj, queue_obj, cell); } else if (flags == MPIDU_GENQ_SHMEM_QUEUE_TYPE__NEM_MPSC) { rc = MPIDU_genqi_nem_mpsc_enqueue(pool_obj, queue_obj, cell); + } else if (flags == MPIDU_GENQ_SHMEM_QUEUE_TYPE__NEM_MPMC) { + rc = MPIDU_genqi_nem_mpmc_enqueue(pool_obj, queue_obj, cell); } else { MPIR_Assert_error("Invalid GenQ flag"); } From b32b699d4e27b96dc75760b8f3521ae9eb31db74 Mon Sep 17 00:00:00 2001 From: Wesley Bland Date: Fri, 14 Jan 2022 08:36:01 -0600 Subject: [PATCH 320/607] mpidu/genq: Use the new MPMC queue for free queues This is necessary in order to allow the free queues to be used for either the sender or the receiver. For receiver-side free queues, this could have been accomplished with an SPMC queue, but implementing that has a very similar cost as an MPMC queue, so we'll use that instead. Having the MPMC queue also gives us the most flexibility. --- src/mpid/common/genq/mpidu_genq_shmem_pool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mpid/common/genq/mpidu_genq_shmem_pool.c b/src/mpid/common/genq/mpidu_genq_shmem_pool.c index e40b4a34fc4..fe52f4b6a12 100644 --- a/src/mpid/common/genq/mpidu_genq_shmem_pool.c +++ b/src/mpid/common/genq/mpidu_genq_shmem_pool.c @@ -87,7 +87,7 @@ int MPIDU_genq_shmem_pool_create_unsafe(uintptr_t cell_size, uintptr_t cells_per (MPIDU_genq_shmem_queue_u *) ((char *) pool_obj->slab + total_cells_size); rc = MPIDU_genq_shmem_queue_init(&pool_obj->free_queues[rank], - MPIDU_GENQ_SHMEM_QUEUE_TYPE__MPSC); + MPIDU_GENQ_SHMEM_QUEUE_TYPE__MPMC); MPIR_ERR_CHECK(rc); rc = cell_block_alloc(pool_obj, rank); From 1c83823078c112d1db04470384e3c896a71f9b3d Mon Sep 17 00:00:00 2001 From: Wesley Bland Date: Tue, 16 Nov 2021 08:55:52 -0600 Subject: [PATCH 321/607] mpidu/genq: Use first-touch for memory binding Force genq cells to be placed in the memory closest to the processes to which they are assigned by memsetting them to 0. This will ensure that when copying data into them, they won't be migrated to the process that is writing the data and will instead stay with the process that will read the memory. --- src/mpid/common/genq/mpidu_genq_shmem_pool.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mpid/common/genq/mpidu_genq_shmem_pool.c b/src/mpid/common/genq/mpidu_genq_shmem_pool.c index fe52f4b6a12..e13dc01856b 100644 --- a/src/mpid/common/genq/mpidu_genq_shmem_pool.c +++ b/src/mpid/common/genq/mpidu_genq_shmem_pool.c @@ -31,6 +31,11 @@ static int cell_block_alloc(MPIDU_genqi_shmem_pool_s * pool, int block_idx) /* init cell headers */ int idx = block_idx * pool->cells_per_proc; for (int i = 0; i < pool->cells_per_proc; i++) { + /* Have the "host" process for each cell zero-out the cell contents to force the first-touch + * policy to make the pages resident to that process. */ + memset((char *) pool->cell_header_base + (idx + i) * pool->cell_alloc_size, 0, + pool->cell_alloc_size); + pool->cell_headers[i] = (MPIDU_genqi_shmem_cell_header_s *) ((char *) pool->cell_header_base + (idx + i) * pool->cell_alloc_size); From 2ecd538978602ea8aaa3961d6009f14f80aa242e Mon Sep 17 00:00:00 2001 From: Wesley Bland Date: Mon, 15 Nov 2021 14:02:18 -0600 Subject: [PATCH 322/607] mpidu/genq: Add param to specify genq pool Allow the caller of the function to get a cell out of a genq to specify which process's pool to grab the cell from. Currently, the only user of this function is the iqueue code so for now, it will keep the current behavior of getting a cell from the sending process. --- src/mpid/ch4/shm/posix/eager/iqueue/iqueue_send.h | 3 ++- src/mpid/common/genq/mpidu_genq_shmem_pool.h | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/mpid/ch4/shm/posix/eager/iqueue/iqueue_send.h b/src/mpid/ch4/shm/posix/eager/iqueue/iqueue_send.h index f8d0043be38..cc6f1962708 100644 --- a/src/mpid/ch4/shm/posix/eager/iqueue/iqueue_send.h +++ b/src/mpid/ch4/shm/posix/eager/iqueue/iqueue_send.h @@ -53,7 +53,8 @@ MPIDI_POSIX_eager_send(int grank, MPIDI_POSIX_am_header_t * msg_hdr, const void transport = MPIDI_POSIX_eager_iqueue_get_transport(src_vsi, dst_vsi); /* Try to get a new cell to hold the message */ - MPIDU_genq_shmem_pool_cell_alloc(transport->cell_pool, (void **) &cell); + MPIDU_genq_shmem_pool_cell_alloc(transport->cell_pool, (void **) &cell, + MPIR_Process.local_rank); /* If a cell wasn't available, let the caller know that we weren't able to send the message * immediately. */ diff --git a/src/mpid/common/genq/mpidu_genq_shmem_pool.h b/src/mpid/common/genq/mpidu_genq_shmem_pool.h index fc8df61b046..e034635681e 100644 --- a/src/mpid/common/genq/mpidu_genq_shmem_pool.h +++ b/src/mpid/common/genq/mpidu_genq_shmem_pool.h @@ -19,7 +19,8 @@ int MPIDU_genq_shmem_pool_create_unsafe(uintptr_t cell_size, uintptr_t cells_per MPIDU_genq_shmem_pool_t * pool); int MPIDU_genq_shmem_pool_destroy_unsafe(MPIDU_genq_shmem_pool_t pool); -static inline int MPIDU_genq_shmem_pool_cell_alloc(MPIDU_genq_shmem_pool_t pool, void **cell) +static inline int MPIDU_genq_shmem_pool_cell_alloc(MPIDU_genq_shmem_pool_t pool, void **cell, + int block_idx) { int rc = MPI_SUCCESS; MPIDU_genqi_shmem_pool_s *pool_obj = (MPIDU_genqi_shmem_pool_s *) pool; @@ -28,7 +29,7 @@ static inline int MPIDU_genq_shmem_pool_cell_alloc(MPIDU_genq_shmem_pool_t pool, MPIR_FUNC_ENTER; - rc = MPIDU_genq_shmem_queue_dequeue(pool, &pool_obj->free_queues[pool_obj->rank], cell); + rc = MPIDU_genq_shmem_queue_dequeue(pool, &pool_obj->free_queues[block_idx], cell); MPIR_ERR_CHECK(rc); fn_exit: From 16c140a607da627eb6e4f5e0b962e57feedbe181 Mon Sep 17 00:00:00 2001 From: Wesley Bland Date: Mon, 15 Nov 2021 14:02:35 -0600 Subject: [PATCH 323/607] ch4/iqueue: Use remote pool instead of local When grabbing a cell for an iqueue send, grab a cell from the poll of the receiving process instead of the sending process. This will ensure that when using a streaming send, the data will remain resident in the memory of the receiving process and will not be brought into the cache of the sending process. --- src/mpid/ch4/shm/posix/eager/iqueue/iqueue_send.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mpid/ch4/shm/posix/eager/iqueue/iqueue_send.h b/src/mpid/ch4/shm/posix/eager/iqueue/iqueue_send.h index cc6f1962708..601fec8e9a7 100644 --- a/src/mpid/ch4/shm/posix/eager/iqueue/iqueue_send.h +++ b/src/mpid/ch4/shm/posix/eager/iqueue/iqueue_send.h @@ -53,8 +53,7 @@ MPIDI_POSIX_eager_send(int grank, MPIDI_POSIX_am_header_t * msg_hdr, const void transport = MPIDI_POSIX_eager_iqueue_get_transport(src_vsi, dst_vsi); /* Try to get a new cell to hold the message */ - MPIDU_genq_shmem_pool_cell_alloc(transport->cell_pool, (void **) &cell, - MPIR_Process.local_rank); + MPIDU_genq_shmem_pool_cell_alloc(transport->cell_pool, (void **) &cell, grank); /* If a cell wasn't available, let the caller know that we weren't able to send the message * immediately. */ From 656a40b730cfe10d36a50abb27879b515ac88bdf Mon Sep 17 00:00:00 2001 From: Wesley Bland Date: Thu, 20 Jan 2022 08:54:12 -0600 Subject: [PATCH 324/607] mpid: Create CVAR to control sender/recevier-side free queues This CVAR will determine whether to use sender-side or receiver-side free queues and adjust the locking mechanism appropriately to match. This is added to avoid the performance impact of changing to an MPMC queue for the genq free queues, though after further investigation, it may not be necessary. --- .../ch4/shm/posix/eager/iqueue/iqueue_send.h | 6 +++- src/mpid/common/genq/mpidu_genq_shmem_pool.c | 36 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/mpid/ch4/shm/posix/eager/iqueue/iqueue_send.h b/src/mpid/ch4/shm/posix/eager/iqueue/iqueue_send.h index 601fec8e9a7..64f5d058d49 100644 --- a/src/mpid/ch4/shm/posix/eager/iqueue/iqueue_send.h +++ b/src/mpid/ch4/shm/posix/eager/iqueue/iqueue_send.h @@ -53,7 +53,11 @@ MPIDI_POSIX_eager_send(int grank, MPIDI_POSIX_am_header_t * msg_hdr, const void transport = MPIDI_POSIX_eager_iqueue_get_transport(src_vsi, dst_vsi); /* Try to get a new cell to hold the message */ - MPIDU_genq_shmem_pool_cell_alloc(transport->cell_pool, (void **) &cell, grank); + /* Select the appropriate pool depending on whether we are using sender-side or receiver-side + * queuing. */ + MPIDU_genq_shmem_pool_cell_alloc(transport->cell_pool, (void **) &cell, + MPIR_CVAR_GENQ_SHMEM_POOL_FREE_QUEUE_SENDER_SIDE ? + MPIR_Process.local_rank : grank); /* If a cell wasn't available, let the caller know that we weren't able to send the message * immediately. */ diff --git a/src/mpid/common/genq/mpidu_genq_shmem_pool.c b/src/mpid/common/genq/mpidu_genq_shmem_pool.c index e13dc01856b..6d1f4613803 100644 --- a/src/mpid/common/genq/mpidu_genq_shmem_pool.c +++ b/src/mpid/common/genq/mpidu_genq_shmem_pool.c @@ -12,6 +12,38 @@ #include #include +/* +=== BEGIN_MPI_T_CVAR_INFO_BLOCK === + +cvars: + - name : MPIR_CVAR_GENQ_SHMEM_POOL_FREE_QUEUE_SENDER_SIDE + category : CH4 + type : boolean + default : true + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + The genq shmem code allocates pools of cells on each process and, when needed, a cell is + removed from the pool and passed to another process. This can happen by either removing a + cell from the pool of the sending process or from the pool of the receiving process. This + CVAR determines which pool to use. If true, the cell will come from the sender-side. If + false, the cell will com from the receiver-side. + + There are specific advantages of using receiver-side cells when combined with the "avx" fast + configure option, which allows MPICH to use AVX streaming copy intrintrinsics, when + available, to avoid polluting the cache of the sender with the data being copied to the + receiver. Using receiver-side cells does have the trade-off of requiring an MPMC lock for + the free queue rather than an MPSC lock, which is used for sender-side cells. Initial + performance analysis shows that using the MPMC lock in this case had no significant + performance loss. + + By default, the queue will continue to use sender-side queues until the performance impact + is verified. + +=== END_MPI_T_CVAR_INFO_BLOCK === +*/ + #define RESIZE_TO_MAX_ALIGN(x) \ ((((x) / MAX_ALIGNMENT) + !!((x) % MAX_ALIGNMENT)) * MAX_ALIGNMENT) @@ -91,7 +123,11 @@ int MPIDU_genq_shmem_pool_create_unsafe(uintptr_t cell_size, uintptr_t cells_per pool_obj->free_queues = (MPIDU_genq_shmem_queue_u *) ((char *) pool_obj->slab + total_cells_size); + /* If using sender-side queuing, use an MPSC lock. If using recevier-side queuing, an MPMC lock + * is needed. */ rc = MPIDU_genq_shmem_queue_init(&pool_obj->free_queues[rank], + MPIR_CVAR_GENQ_SHMEM_POOL_FREE_QUEUE_SENDER_SIDE ? + MPIDU_GENQ_SHMEM_QUEUE_TYPE__MPSC : MPIDU_GENQ_SHMEM_QUEUE_TYPE__MPMC); MPIR_ERR_CHECK(rc); From 2eb4273b07ca3f5185b78f6b82f1cbd64d28c2f7 Mon Sep 17 00:00:00 2001 From: "Islam, Nusrat" Date: Mon, 10 Jan 2022 09:33:52 -0600 Subject: [PATCH 325/607] coll: high radix tree-based blocking allreduce --- src/mpi/coll/allreduce/Makefile.mk | 3 +- src/mpi/coll/allreduce/allreduce_intra_tree.c | 193 ++++++++++++++++++ src/mpi/coll/coll_algorithms.txt | 3 + src/mpi/coll/cvars.txt | 51 +++++ src/mpi/coll/include/coll_impl.h | 1 + src/mpi/coll/include/csel_container.h | 9 + src/mpi/coll/src/coll_impl.c | 9 + src/mpi/coll/src/csel_container.c | 21 ++ 8 files changed, 289 insertions(+), 1 deletion(-) create mode 100644 src/mpi/coll/allreduce/allreduce_intra_tree.c diff --git a/src/mpi/coll/allreduce/Makefile.mk b/src/mpi/coll/allreduce/Makefile.mk index b6d44264dce..01029f0a9cd 100644 --- a/src/mpi/coll/allreduce/Makefile.mk +++ b/src/mpi/coll/allreduce/Makefile.mk @@ -12,4 +12,5 @@ mpi_core_sources += \ src/mpi/coll/allreduce/allreduce_intra_recursive_doubling.c \ src/mpi/coll/allreduce/allreduce_intra_reduce_scatter_allgather.c \ src/mpi/coll/allreduce/allreduce_intra_smp.c \ - src/mpi/coll/allreduce/allreduce_inter_reduce_exchange_bcast.c + src/mpi/coll/allreduce/allreduce_inter_reduce_exchange_bcast.c \ + src/mpi/coll/allreduce/allreduce_intra_tree.c diff --git a/src/mpi/coll/allreduce/allreduce_intra_tree.c b/src/mpi/coll/allreduce/allreduce_intra_tree.c new file mode 100644 index 00000000000..a83e0abb4ad --- /dev/null +++ b/src/mpi/coll/allreduce/allreduce_intra_tree.c @@ -0,0 +1,193 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * Copyright (C) by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + * + */ + + +#include "mpiimpl.h" +#include "algo_common.h" +#include "treealgo.h" + +int MPIR_Allreduce_intra_tree(const void *sendbuf, + void *recvbuf, + MPI_Aint count, + MPI_Datatype datatype, + MPI_Op op, MPIR_Comm * comm_ptr, + int tree_type, int k, int chunk_size, + int buffer_per_child, MPIR_Errflag_t * errflag) +{ + int comm_size, rank; + int mpi_errno = MPI_SUCCESS, mpi_errno_ret = MPI_SUCCESS; + int is_commutative; + MPI_Aint true_extent, type_lb; + void **child_buffer = NULL; /* Buffer array in which data from children is received */ + void *reduce_buffer; /* Buffer in which allreduced data is present */ + MPIR_Treealgo_tree_t my_tree; + + MPI_Aint num_chunks, chunk_size_floor, chunk_size_ceil; + int offset = 0; + size_t extent, type_size; + int num_children; + int root = 0; + bool is_tree_leaf; + int i, j, tag; + + MPIR_Request **reqs; + int num_reqs = 0; + + comm_size = MPIR_Comm_size(comm_ptr); + rank = MPIR_Comm_rank(comm_ptr); + + MPIR_Datatype_get_size_macro(datatype, type_size); + MPIR_Datatype_get_extent_macro(datatype, extent); + MPIR_Type_get_true_extent_impl(datatype, &type_lb, &true_extent); + extent = MPL_MAX(extent, true_extent); + is_commutative = MPIR_Op_is_commutative(op); + + MPIR_CHKLMEM_DECL(2); + + /* copy local data into recvbuf */ + if (sendbuf != MPI_IN_PLACE) { + mpi_errno = MPIR_Localcopy(sendbuf, count, datatype, recvbuf, count, datatype); + MPIR_ERR_CHECK(mpi_errno); + } + + /* calculate chunking information for pipelining */ + MPIR_Algo_calculate_pipeline_chunk_info(chunk_size, type_size, count, &num_chunks, + &chunk_size_floor, &chunk_size_ceil); + /* print chunking information */ + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, (MPL_DBG_FDEST, + "Allreduce pipeline info: chunk_size=%d count=%ld num_chunks=%ld chunk_size_floor=%ld chunk_size_ceil=%ld ", + chunk_size, count, num_chunks, + chunk_size_floor, chunk_size_ceil)); + + + if (!is_commutative) { + /* because kary and knomial_2 trees cannot handle non-commutative operations */ + if (tree_type == MPIR_TREE_TYPE_KNOMIAL_2 || tree_type == MPIR_TREE_TYPE_KARY) { + tree_type = MPIR_TREE_TYPE_KNOMIAL_1; + } + } + /* initialize the tree */ + mpi_errno = MPIR_Treealgo_tree_create(rank, comm_size, tree_type, k, root, &my_tree); + MPIR_ERR_CHECK(mpi_errno); + num_children = my_tree.num_children; + + /* identify my location in the tree */ + is_tree_leaf = (num_children == 0) ? 1 : 0; + + if (!is_tree_leaf) { + MPIR_CHKLMEM_MALLOC(child_buffer, void **, sizeof(void *) * num_children, mpi_errno, + "child_buffer", MPL_MEM_BUFFER); + child_buffer[0] = MPL_malloc(extent * count, MPL_MEM_BUFFER); + MPIR_ERR_CHKANDJUMP(!child_buffer[0], mpi_errno, MPI_ERR_OTHER, "**nomem"); + + child_buffer[0] = (void *) ((char *) child_buffer[0] - type_lb); + MPIR_ERR_CHKANDJUMP(!child_buffer[0], mpi_errno, MPI_ERR_OTHER, "**nomem"); + for (i = 1; i < num_children; i++) { + if (buffer_per_child) { + child_buffer[i] = MPL_malloc(extent * count, MPL_MEM_BUFFER); + MPIR_ERR_CHKANDJUMP(!child_buffer[i], mpi_errno, MPI_ERR_OTHER, "**nomem"); + child_buffer[i] = (void *) ((char *) child_buffer[i] - type_lb); + MPIR_ERR_CHKANDJUMP(!child_buffer[i], mpi_errno, MPI_ERR_OTHER, "**nomem"); + } else { + child_buffer[i] = child_buffer[0]; + } + } + } + reduce_buffer = recvbuf; + + MPIR_CHKLMEM_MALLOC(reqs, MPIR_Request **, + (num_children * num_chunks + num_chunks + 10) * sizeof(MPIR_Request *), + mpi_errno, "reqs", MPL_MEM_BUFFER); + + for (j = 0; j < num_chunks; j++) { + int msgsize = (j == 0) ? chunk_size_floor : chunk_size_ceil; + void *reduce_address = (char *) reduce_buffer + offset * extent; + MPIR_ERR_CHKANDJUMP(!reduce_address, mpi_errno, MPI_ERR_OTHER, "**nomem"); + + mpi_errno = MPIR_Sched_next_tag(comm_ptr, &tag); + MPIR_ERR_CHECK(mpi_errno); + + for (i = 0; i < num_children; i++) { + void *recv_address = (char *) child_buffer[i] + offset * extent; + MPIR_ERR_CHKANDJUMP(!recv_address, mpi_errno, MPI_ERR_OTHER, "**nomem"); + int child = *(int *) utarray_eltptr(my_tree.children, i); + MPIR_ERR_CHKANDJUMP(!child, mpi_errno, MPI_ERR_OTHER, "**nomem"); + + mpi_errno = + MPIC_Recv(recv_address, msgsize, datatype, child, MPIR_ALLREDUCE_TAG, comm_ptr, + MPI_STATUS_IGNORE, errflag); + /* for communication errors, just record the error but continue */ + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); + + if (is_commutative) { + mpi_errno = MPIR_Reduce_local(recv_address, reduce_address, msgsize, datatype, op); + MPIR_ERR_CHECK(mpi_errno); + + } else { + mpi_errno = MPIR_Reduce_local(reduce_address, recv_address, msgsize, datatype, op); + MPIR_ERR_CHECK(mpi_errno); + + mpi_errno = + MPIR_Localcopy(recv_address, msgsize, datatype, reduce_address, msgsize, + datatype); + MPIR_ERR_CHECK(mpi_errno); + } + + } + if (rank != root) { /* send data to the parent */ + mpi_errno = + MPIC_Isend(reduce_address, msgsize, datatype, my_tree.parent, MPIR_ALLREDUCE_TAG, + comm_ptr, &reqs[num_reqs++], errflag); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); + } + + if (my_tree.parent != -1) { + mpi_errno = MPIC_Recv(reduce_address, msgsize, + datatype, my_tree.parent, MPIR_ALLREDUCE_TAG, comm_ptr, + MPI_STATUS_IGNORE, errflag); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); + } + if (num_children) { + for (i = 0; i < num_children; i++) { + int child = *(int *) utarray_eltptr(my_tree.children, i); + MPIR_ERR_CHKANDJUMP(!child, mpi_errno, MPI_ERR_OTHER, "**nomem"); + MPIR_Assert(child != 0); + mpi_errno = MPIC_Isend(reduce_address, msgsize, + datatype, child, + MPIR_ALLREDUCE_TAG, comm_ptr, &reqs[num_reqs++], errflag); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); + } + } + + offset += msgsize; + } + + if (num_reqs > 0) { + mpi_errno = MPIC_Waitall(num_reqs, reqs, MPI_STATUSES_IGNORE, errflag); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); + } + + if (!is_tree_leaf) { + MPL_free(child_buffer[0]); + for (i = 1; i < num_children; i++) { + if (buffer_per_child) { + MPL_free(child_buffer[i]); + } + } + } + MPIR_Treealgo_tree_free(&my_tree); + MPIR_CHKLMEM_FREEALL(); + + fn_exit: + if (mpi_errno_ret) + mpi_errno = mpi_errno_ret; + else if (*errflag != MPIR_ERR_NONE) + MPIR_ERR_SET(mpi_errno, *errflag, "**coll_fail"); + return mpi_errno; + fn_fail: + goto fn_exit; +} diff --git a/src/mpi/coll/coll_algorithms.txt b/src/mpi/coll/coll_algorithms.txt index b02054f21d0..8ebdda34e2f 100644 --- a/src/mpi/coll/coll_algorithms.txt +++ b/src/mpi/coll/coll_algorithms.txt @@ -315,6 +315,9 @@ allreduce-intra: recursive_doubling reduce_scatter_allgather restrictions: size-ge-pof2, builtin-op + tree + extra_params: tree_type, k, chunk_size, buffer_per_child + cvar_params: TREE_TYPE, TREE_KVAL, TREE_PIPELINE_CHUNK_SIZE, TREE_BUFFER_PER_CHILD allreduce-inter: reduce_exchange_bcast iallreduce-intra: diff --git a/src/mpi/coll/cvars.txt b/src/mpi/coll/cvars.txt index 5fdf5d7716d..60d000cdbd1 100644 --- a/src/mpi/coll/cvars.txt +++ b/src/mpi/coll/cvars.txt @@ -1186,6 +1186,57 @@ cvars: smp - Force smp algorithm recursive_doubling - Force recursive doubling algorithm reduce_scatter_allgather - Force reduce scatter allgather algorithm + tree - Force pipelined tree algorithm + + - name : MPIR_CVAR_ALLREDUCE_TREE_TYPE + category : COLLECTIVE + type : string + default : knomial_1 + class : device + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + Tree type for tree based allreduce + knomial_1 is default as it supports both commutative and non-commutative reduce operations + kary - kary tree type + knomial_1 - knomial_1 tree type (tree grows starting from the left of the root) + knomial_2 - knomial_2 tree type (tree grows starting from the right of the root) + + - name : MPIR_CVAR_ALLREDUCE_TREE_KVAL + category : COLLECTIVE + type : int + default : 2 + class : device + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + Indicates the branching factor for kary or knomial trees. + + - name : MPIR_CVAR_ALLREDUCE_TREE_PIPELINE_CHUNK_SIZE + category : COLLECTIVE + type : int + default : 0 + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + Maximum chunk size (in bytes) for pipelining in tree based + allreduce. Default value is 0, that is, no pipelining by default + + - name : MPIR_CVAR_ALLREDUCE_TREE_BUFFER_PER_CHILD + category : COLLECTIVE + type : boolean + default : 0 + class : device + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + If set to true, a rank in tree_kary and tree_knomial algorithms will allocate + a dedicated buffer for every child it receives data from. This would mean more + memory consumption but it would allow preposting of the receives and hence reduce + the number of unexpected messages. If set to false, there is only one buffer that is + used to receive the data from all the children. The receives are therefore serialized, + that is, only one receive can be posted at a time. - name : MPIR_CVAR_ALLREDUCE_INTER_ALGORITHM category : COLLECTIVE diff --git a/src/mpi/coll/include/coll_impl.h b/src/mpi/coll/include/coll_impl.h index 84390c45ca6..dc4286f9355 100644 --- a/src/mpi/coll/include/coll_impl.h +++ b/src/mpi/coll/include/coll_impl.h @@ -37,6 +37,7 @@ extern int MPIR_Nbc_progress_hook_id; extern MPIR_Tree_type_t MPIR_Iallreduce_tree_type; +extern MPIR_Tree_type_t MPIR_Allreduce_tree_type; extern MPIR_Tree_type_t MPIR_Ireduce_tree_type; extern MPIR_Tree_type_t MPIR_Ibcast_tree_type; extern MPIR_Tree_type_t MPIR_Bcast_tree_type; diff --git a/src/mpi/coll/include/csel_container.h b/src/mpi/coll/include/csel_container.h index 8cc31580302..7ff24035e39 100644 --- a/src/mpi/coll/include/csel_container.h +++ b/src/mpi/coll/include/csel_container.h @@ -24,6 +24,7 @@ typedef enum { MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_intra_recursive_doubling, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_intra_reduce_scatter_allgather, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_intra_smp, + MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_intra_tree, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_inter_reduce_exchange_bcast, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_allcomm_nb, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Alltoall_intra_brucks, @@ -321,6 +322,14 @@ typedef struct { int k; } intra_tsp_recexch; } ireduce_scatter_block; + struct { + struct { + int tree_type; + int k; + int chunk_size; + int buffer_per_child; + } intra_tree; + } allreduce; struct { struct { int k; diff --git a/src/mpi/coll/src/coll_impl.c b/src/mpi/coll/src/coll_impl.c index f250ea2b2f9..4b9e6cc0d2f 100644 --- a/src/mpi/coll/src/coll_impl.c +++ b/src/mpi/coll/src/coll_impl.c @@ -59,6 +59,7 @@ categories : int MPIR_Nbc_progress_hook_id = 0; MPIR_Tree_type_t MPIR_Iallreduce_tree_type = MPIR_TREE_TYPE_KARY; +MPIR_Tree_type_t MPIR_Allreduce_tree_type = MPIR_TREE_TYPE_KARY; MPIR_Tree_type_t MPIR_Ibcast_tree_type = MPIR_TREE_TYPE_KARY; MPIR_Tree_type_t MPIR_Bcast_tree_type = MPIR_TREE_TYPE_KARY; MPIR_Tree_type_t MPIR_Ireduce_tree_type = MPIR_TREE_TYPE_KARY; @@ -77,6 +78,14 @@ int MPII_Coll_init(void) else if (0 == strcmp(MPIR_CVAR_IALLREDUCE_TREE_TYPE, "knomial_2")) MPIR_Iallreduce_tree_type = MPIR_TREE_TYPE_KNOMIAL_2; + /* Allreduce */ + if (0 == strcmp(MPIR_CVAR_ALLREDUCE_TREE_TYPE, "knomial_1")) + MPIR_Allreduce_tree_type = MPIR_TREE_TYPE_KNOMIAL_1; + else if (0 == strcmp(MPIR_CVAR_ALLREDUCE_TREE_TYPE, "knomial_2")) + MPIR_Allreduce_tree_type = MPIR_TREE_TYPE_KNOMIAL_2; + else + MPIR_Allreduce_tree_type = MPIR_TREE_TYPE_KARY; + /* Ibcast */ if (0 == strcmp(MPIR_CVAR_IBCAST_TREE_TYPE, "kary")) MPIR_Ibcast_tree_type = MPIR_TREE_TYPE_KARY; diff --git a/src/mpi/coll/src/csel_container.c b/src/mpi/coll/src/csel_container.c index e3064e8a415..453ee8c45d6 100644 --- a/src/mpi/coll/src/csel_container.c +++ b/src/mpi/coll/src/csel_container.c @@ -133,6 +133,24 @@ static void parse_container_params(struct json_object *obj, MPII_Csel_container_ } break; + case MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_intra_tree: + { + json_object_object_foreach(obj, key, val) { + ckey = MPL_strdup_no_spaces(key); + if (!strncmp(ckey, "buffer_per_child=", strlen("buffer_per_child="))) + cnt->u.allreduce.intra_tree.buffer_per_child = + atoi(ckey + strlen("buffer_per_child=")); + else if (!strncmp(ckey, "k=", strlen("k="))) + cnt->u.allreduce.intra_tree.k = atoi(ckey + strlen("k=")); + else if (!strncmp(ckey, "tree_type=", strlen("tree_type="))) + cnt->u.allreduce.intra_tree.tree_type = atoi(ckey + strlen("tree_type=")); + else if (!strncmp(ckey, "chunk_size=", strlen("chunk_size="))) + cnt->u.allreduce.intra_tree.chunk_size = atoi(ckey + strlen("chunk_size=")); + MPL_free(ckey); + } + } + break; + case MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ibcast_intra_tsp_scatterv_recexch_allgatherv: { json_object_object_foreach(obj, key, val) { @@ -184,6 +202,7 @@ static void parse_container_params(struct json_object *obj, MPII_Csel_container_ } break; + default: /* Algorithm does not have parameters */ break; @@ -226,6 +245,8 @@ void *MPII_Create_container(struct json_object *obj) MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_intra_reduce_scatter_allgather; else if (!strcmp(ckey, "algorithm=MPIR_Allreduce_intra_smp")) cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_intra_smp; + else if (!strcmp(ckey, "algorithm=MPIR_Allreduce_intra_tree")) + cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_intra_tree; else if (!strcmp(ckey, "algorithm=MPIR_Allreduce_inter_reduce_exchange_bcast")) cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_inter_reduce_exchange_bcast; From 16fe1d159cc4e29b6db0ba65e82dfb27d7df945a Mon Sep 17 00:00:00 2001 From: "Islam, Nusrat" Date: Mon, 10 Jan 2022 09:41:21 -0600 Subject: [PATCH 326/607] test: add allreduce tests for pipelined tree algorithm --- test/mpi/maint/coll_cvars.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/mpi/maint/coll_cvars.txt b/test/mpi/maint/coll_cvars.txt index a7a9e05844a..6379fbdd59e 100644 --- a/test/mpi/maint/coll_cvars.txt +++ b/test/mpi/maint/coll_cvars.txt @@ -222,6 +222,10 @@ algorithms: smp recursive_doubling reduce_scatter_allgather + tree + .MPIR_CVAR_ALLREDUCE_TREE_TYPE=knomial_1,knomial_2,kary + .MPIR_CVAR_ALLREDUCE_TREE_KVAL=2,3,4 + .MPIR_CVAR_ALLREDUCE_TREE_PIPELINE_CHUNK_SIZE=4096,8192 posix:release_gather .MPIR_CVAR_COLL_SHM_LIMIT_PER_NODE=131072 .MPIR_CVAR_REDUCE_INTRANODE_BUFFER_TOTAL_SIZE=16384 From 55a7323e913dff91d2e1614edfdde44d50869c51 Mon Sep 17 00:00:00 2001 From: Rob Latham Date: Thu, 20 Jan 2022 15:47:07 -0600 Subject: [PATCH 327/607] romio: fix buggy file system detection After the file system detection rework, ROMIO was finding file systems it had heard about (e.g. xfs) but then reporting "UNSUPPORTED" if the support for that file system was not requested at configure time. Relax file system detection to pick UFS (generic unix-like file system) in more cases if ROMIO does not know how to use anything more optimized. Fixes: pmodels/mpich#5772 --- src/mpi/romio/adio/common/ad_fstype.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/mpi/romio/adio/common/ad_fstype.c b/src/mpi/romio/adio/common/ad_fstype.c index ec8ee535b88..0ce487bf8f2 100644 --- a/src/mpi/romio/adio/common/ad_fstype.c +++ b/src/mpi/romio/adio/common/ad_fstype.c @@ -421,28 +421,42 @@ static void ADIO_FileSysType_fncall(const char *filename, int *fstype, int *erro /* --END ERROR HANDLING-- */ switch (file_id) { +#ifdef ROMIO_NFS case NFS_SUPER_MAGIC: *fstype = ADIO_NFS; return; +#endif +#ifdef ROMIO_XFS case XFS_SUPER_MAGIC: case EXFS_SUPER_MAGIC: *fstype = ADIO_XFS; return; +#endif +#ifdef ROMIO_GPFS case GPFS_SUPER_MAGIC: *fstype = ADIO_GPFS; return; +#endif +#ifdef ROMIO_LUSTRE case LL_SUPER_MAGIC: *fstype = ADIO_LUSTRE; return; +#endif +#ifdef ROMIO_DAOS case DAOS_SUPER_MAGIC: *fstype = ADIO_DAOS; return; +#endif +#ifdef ROMIO_PANFS case PAN_KERNEL_FS_CLIENT_SUPER_MAGIC: *fstype = ADIO_PANFS; return; +#endif +#ifdef ROMIO_PVFS2 case PVFS2_SUPER_MAGIC: *fstype = ADIO_PVFS2; return; +#endif default: /* UFS support if we don't know what else to use */ *fstype = ADIO_UFS; From 9c7c07b6202e22b4d6a247e1a1b50c5b88d9703c Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 16 Nov 2021 23:50:59 -0600 Subject: [PATCH 328/607] python: extend linebreak for fortran declarations Extend linebreak for general line with comma separations. This is to allow using linebreaking for Fortran declarations. --- maint/local_python/binding_common.py | 24 ++++++++++++++---------- maint/local_python/binding_f08.py | 16 ++++++++-------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/maint/local_python/binding_common.py b/maint/local_python/binding_common.py index 5d52649df5a..f53603e5c05 100644 --- a/maint/local_python/binding_common.py +++ b/maint/local_python/binding_common.py @@ -55,14 +55,9 @@ def split_line_with_break(s, tail, N=100): if RE.match(r'(\s*)', s): n_lead = len(RE.m.group(1)) + 4 - if len(s) < N: - tlist.append(s) - n = len(s) - elif RE.match(r'(.*?\()(.*)', s): - # line with function pattern, match indent at opening parenthesis - s_lead, s_next = RE.m.group(1,2) - n_lead = len(s_lead) - + # ------------- + def break_s_next(s_lead, s_next): + nonlocal tlist, n for a in s_next.split(', '): if n == 0: # first line @@ -86,10 +81,19 @@ def split_line_with_break(s, tail, N=100): tlist = [' ' * n_lead, a] n = n_lead + len(a) # leave last segment with tail - else: - # only break long function declaration or call for now + + # ------------- + if len(s) < N: tlist.append(s) n = len(s) + elif RE.match(r'(.*?\()(.*)', s): + # line with function pattern, match indent at opening parenthesis + s_lead, s_next = RE.m.group(1,2) + n_lead = len(s_lead) + + break_s_next(s_lead, s_next) + else: + break_s_next('', s) # tail is mostly for "__attribute__ ((weak, alias(...))));", # which contains , that we do not desire to break diff --git a/maint/local_python/binding_f08.py b/maint/local_python/binding_f08.py index ee4fa7fab9b..d027edf779c 100644 --- a/maint/local_python/binding_f08.py +++ b/maint/local_python/binding_f08.py @@ -921,21 +921,21 @@ def dump_F_uses(uses): else: mpi_c_list_2.append(a) if iso_c_binding_list: - G.out.append("USE, intrinsic :: iso_c_binding, ONLY : %s" % ', '.join(iso_c_binding_list)) + dump_fortran_line("USE, intrinsic :: iso_c_binding, ONLY : %s" % ', '.join(iso_c_binding_list)) if mpi_f08_list_1: - G.out.append("USE :: mpi_f08_types, ONLY : %s" % ', '.join(mpi_f08_list_1)) + dump_fortran_line("USE :: mpi_f08_types, ONLY : %s" % ', '.join(mpi_f08_list_1)) if mpi_f08_list_2: - G.out.append("USE :: mpi_f08_compile_constants, ONLY : %s" % ', '.join(mpi_f08_list_2)) + dump_fortran_line("USE :: mpi_f08_compile_constants, ONLY : %s" % ', '.join(mpi_f08_list_2)) if mpi_f08_list_3: - G.out.append("USE :: mpi_f08_link_constants, ONLY : %s" % ', '.join(mpi_f08_list_3)) + dump_fortran_line("USE :: mpi_f08_link_constants, ONLY : %s" % ', '.join(mpi_f08_list_3)) if mpi_f08_list_4: - G.out.append("USE :: mpi_f08_callbacks, ONLY : %s" % ', '.join(mpi_f08_list_4)) + dump_fortran_line("USE :: mpi_f08_callbacks, ONLY : %s" % ', '.join(mpi_f08_list_4)) if mpi_c_list_1: - G.out.append("USE :: mpi_c_interface_types, ONLY : %s" % ', '.join(mpi_c_list_1)) + dump_fortran_line("USE :: mpi_c_interface_types, ONLY : %s" % ', '.join(mpi_c_list_1)) if mpi_c_list_2: - G.out.append("USE :: mpi_c_interface, ONLY : %s" % ', '.join(mpi_c_list_2)) + dump_fortran_line("USE :: mpi_c_interface, ONLY : %s" % ', '.join(mpi_c_list_2)) if mpi_c_list_3: - G.out.append("USE :: mpi_c_interface_glue, ONLY : %s" % ', '.join(mpi_c_list_3)) + dump_fortran_line("USE :: mpi_c_interface_glue, ONLY : %s" % ', '.join(mpi_c_list_3)) def dump_F_if_open(cond): G.out.append("IF (%s) THEN" % cond) From 6d8c5496a19405e75068e65181ece283b2579b26 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 16 Nov 2021 23:08:41 -0600 Subject: [PATCH 329/607] f08: use wrapper c function for pointer constants The mechanism for external linkage of global variable from fortran dynamic library to C dynamic library is fragile despite the fortran specification. For example, currently this mechanism does not work on osx. Rather than adding more hacking and work arounds, avoid the mess by simply getting the symbol using a C function. The f08 interoperability using C functions is fairly robust. --- maint/local_python/binding_f08.py | 16 ++--- .../use_mpi_f08/mpi_f08_link_constants.f90 | 63 ++++++++++++++++--- .../fortran/use_mpi_f08/wrappers_c/cdesc.c | 6 -- .../fortran/use_mpi_f08/wrappers_c/cdesc.h | 14 +++-- .../fortran/use_mpi_f08/wrappers_c/utils.c | 35 +++++++++++ src/mpi/init/init_bindings.c | 13 ---- src/mpi/init/mpi_init.h | 1 - src/mpi/init/mpir_init.c | 1 - 8 files changed, 104 insertions(+), 45 deletions(-) diff --git a/maint/local_python/binding_f08.py b/maint/local_python/binding_f08.py index d027edf779c..dd7a9f2cdc0 100644 --- a/maint/local_python/binding_f08.py +++ b/maint/local_python/binding_f08.py @@ -350,7 +350,7 @@ def process_status(p): if p['length'] is not None: # always output parameter uses['MPI_STATUSES_IGNORE'] = 1 - uses['MPIR_C_MPI_STATUSES_IGNORE'] = 1 + uses['MPIR_F08_get_MPI_STATUSES_IGNORE_c'] = 1 need_check_status_ignore = p arg_1 = ":STATUS:" arg_2 = ":STATUS:" @@ -364,7 +364,7 @@ def process_status(p): if p['param_direction'] == 'out': need_check_status_ignore = p uses['MPI_STATUS_IGNORE'] = 1 - uses['MPIR_C_MPI_STATUS_IGNORE'] = 1 + uses['MPIR_F08_get_MPI_STATUS_IGNORE_c'] = 1 arg_1 = ":STATUS:" arg_2 = ":STATUS:" p['_status_convert'] = "status = status_c" @@ -440,18 +440,18 @@ def process_array_check(p): if check: uses['c_associated'] = 1 uses[check] = 1 - uses['MPIR_C_%s' % check] = 1 + uses['MPIR_F08_get_%s_c' % check] = 1 convert_list_pre.append("IF (c_associated(%s, c_loc(%s))) THEN" % (arg_1, check)) - convert_list_pre.append(" %s = MPIR_C_%s" % (arg_1, check)) + convert_list_pre.append(" %s = MPIR_F08_get_%s_c()" % (arg_1, check)) if check == "MPI_ERRCODES_IGNORE": convert_list_pre.append(" has_errcodes_ignore = .true.") elif check == "MPI_UNWEIGHTED": # also need check MPI_WEIGHTS_EMPTY check = "MPI_WEIGHTS_EMPTY" uses[check] = 1 - uses['MPIR_C_%s' % check] = 1 + uses['MPIR_F08_get_%s_c' % check] = 1 convert_list_pre.append("ELSE IF (c_associated(%s, c_loc(%s))) THEN" % (arg_1, check)) - convert_list_pre.append(" %s = MPIR_C_%s" % (arg_1, check)) + convert_list_pre.append(" %s = MPIR_F08_get_%s_c()" % (arg_1, check)) convert_list_pre.append("ELSE") convert_list_pre.append(" %s = c_loc(%s)" % (arg_1, p['name'])) convert_list_pre.append(" has_%s = .true." % p['name']) @@ -688,7 +688,7 @@ def dump_call(s, check_int_kind): else: ignore = 'MPI_STATUSES_IGNORE' dump_F_if_open("c_associated(c_loc(%s), c_loc(%s))" % (p['name'], ignore)) - s2 = re.sub(r':STATUS:', "MPIR_C_%s" % ignore, s) + s2 = re.sub(r':STATUS:', "MPIR_F08_get_%s_c()" % ignore, s) dump_fortran_line(s2) dump_F_else() if check_int_kind: @@ -908,7 +908,7 @@ def dump_F_uses(uses): mpi_c_list_3.append(a) elif re.match(r'MPI_\w+_(function|FN|FN_NULL)(_c)?$', a, re.IGNORECASE): mpi_f08_list_4.append(a) - elif re.search(r'(STATUS.*IGNORE|ARGV.*NULL|ERRCODES_IGNORE|_UNWEIGHTED|WEIGHTS_EMPTY|MPI_IN_PLACE|MPI_BOTTOM)$', a, re.IGNORECASE): + elif re.search(r'(STATUS.*IGNORE|ARGV.*NULL|ERRCODES_IGNORE|_UNWEIGHTED|WEIGHTS_EMPTY|MPI_IN_PLACE|MPI_BOTTOM)', a, re.IGNORECASE): mpi_f08_list_3.append(a) elif re.match(r'MPI_[A-Z_]+$', a): mpi_f08_list_2.append(a) diff --git a/src/binding/fortran/use_mpi_f08/mpi_f08_link_constants.f90 b/src/binding/fortran/use_mpi_f08/mpi_f08_link_constants.f90 index bcf6ca639de..5167a89c461 100644 --- a/src/binding/fortran/use_mpi_f08/mpi_f08_link_constants.f90 +++ b/src/binding/fortran/use_mpi_f08/mpi_f08_link_constants.f90 @@ -24,9 +24,6 @@ module mpi_f08_link_constants type(MPI_Status), bind(C, name="MPIR_F08_MPI_STATUS_IGNORE_OBJ"), target :: MPI_STATUS_IGNORE type(MPI_Status), dimension(1), bind(C, name="MPIR_F08_MPI_STATUSES_IGNORE_OBJ"), target :: MPI_STATUSES_IGNORE -type(c_ptr), bind(C, name="MPIR_C_MPI_STATUS_IGNORE") :: MPIR_C_MPI_STATUS_IGNORE -type(c_ptr), bind(C, name="MPIR_C_MPI_STATUSES_IGNORE") :: MPIR_C_MPI_STATUSES_IGNORE - ! Though these two variables are required by MPI-3 Standard, they are not used in MPICH type(c_ptr), bind(C, name="MPI_F08_STATUS_IGNORE") :: MPI_F08_STATUS_IGNORE ! Point to MPI_STATUS_IGNORE type(c_ptr), bind(C, name="MPI_F08_STATUSES_IGNORE") :: MPI_F08_STATUSES_IGNORE ! Point to MPI_STATUSES_IGNORE @@ -41,9 +38,6 @@ module mpi_f08_link_constants character(len=1), dimension(1), target :: MPI_ARGV_NULL character(len=1), dimension(1,1), target :: MPI_ARGVS_NULL -type(c_ptr), bind(C, name="MPIR_C_MPI_ARGV_NULL") :: MPIR_C_MPI_ARGV_NULL -type(c_ptr), bind(C, name="MPIR_C_MPI_ARGVS_NULL") :: MPIR_C_MPI_ARGVS_NULL - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! @@ -51,7 +45,6 @@ module mpi_f08_link_constants ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! integer, dimension(1), target :: MPI_ERRCODES_IGNORE -type(c_ptr), bind(C, name="MPIR_C_MPI_ERRCODES_IGNORE") :: MPIR_C_MPI_ERRCODES_IGNORE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -64,9 +57,6 @@ module mpi_f08_link_constants integer, dimension(1), target :: MPI_UNWEIGHTED integer, dimension(1), target :: MPI_WEIGHTS_EMPTY -type(c_ptr), protected, bind(C, name="MPIR_C_MPI_UNWEIGHTED") :: MPIR_C_MPI_UNWEIGHTED -type(c_ptr), protected, bind(C, name="MPIR_C_MPI_WEIGHTS_EMPTY") :: MPIR_C_MPI_WEIGHTS_EMPTY - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! ! MPI_IN_PLACE @@ -83,4 +73,57 @@ module mpi_f08_link_constants ! A.1.1 p. 663 integer(c_int), bind(C, name="MPIR_F08_MPI_BOTTOM"), target :: MPI_BOTTOM +INTERFACE + +FUNCTION MPIR_F08_get_MPI_STATUS_IGNORE_c() & + bind (C, name="MPIR_F08_get_MPI_STATUS_IGNORE") result(p) + USE, intrinsic :: iso_c_binding, ONLY : c_ptr + IMPLICIT NONE + TYPE(c_ptr) :: p +END FUNCTION + +FUNCTION MPIR_F08_get_MPI_STATUSES_IGNORE_c() & + bind (C, name="MPIR_F08_get_MPI_STATUSES_IGNORE") result(p) + USE, intrinsic :: iso_c_binding, ONLY : c_ptr + IMPLICIT NONE + TYPE(c_ptr) :: p +END FUNCTION + +FUNCTION MPIR_F08_get_MPI_ARGV_NULL_c() & + bind (C, name="MPIR_F08_get_MPI_ARGV_NULL") result(p) + USE, intrinsic :: iso_c_binding, ONLY : c_ptr + IMPLICIT NONE + TYPE(c_ptr) :: p +END FUNCTION + +FUNCTION MPIR_F08_get_MPI_ARGVS_NULL_c() & + bind (C, name="MPIR_F08_get_MPI_ARGVS_NULL") result(p) + USE, intrinsic :: iso_c_binding, ONLY : c_ptr + IMPLICIT NONE + TYPE(c_ptr) :: p +END FUNCTION + +FUNCTION MPIR_F08_get_MPI_ERRCODES_IGNORE_c() & + bind (C, name="MPIR_F08_get_MPI_ERRCODES_IGNORE") result(p) + USE, intrinsic :: iso_c_binding, ONLY : c_ptr + IMPLICIT NONE + TYPE(c_ptr) :: p +END FUNCTION + +FUNCTION MPIR_F08_get_MPI_UNWEIGHTED_c() & + bind (C, name="MPIR_F08_get_MPI_UNWEIGHTED") result(p) + USE, intrinsic :: iso_c_binding, ONLY : c_ptr + IMPLICIT NONE + TYPE(c_ptr) :: p +END FUNCTION + +FUNCTION MPIR_F08_get_MPI_WEIGHTS_EMPTY_c() & + bind (C, name="MPIR_F08_get_MPI_WEIGHTS_EMPTY") result(p) + USE, intrinsic :: iso_c_binding, ONLY : c_ptr + IMPLICIT NONE + TYPE(c_ptr) :: p +END FUNCTION + +END INTERFACE + end module mpi_f08_link_constants diff --git a/src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.c b/src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.c index d55247287fc..70226dc939a 100644 --- a/src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.c +++ b/src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.c @@ -6,12 +6,6 @@ #include "cdesc.h" #include -MPI_Status *MPIR_C_MPI_STATUS_IGNORE = MPI_STATUS_IGNORE; -MPI_Status *MPIR_C_MPI_STATUSES_IGNORE = MPI_STATUSES_IGNORE; -char **MPIR_C_MPI_ARGV_NULL = MPI_ARGV_NULL; -char ***MPIR_C_MPI_ARGVS_NULL = MPI_ARGVS_NULL; -int *MPIR_C_MPI_ERRCODES_IGNORE = MPI_ERRCODES_IGNORE; - /* Fortran 2008 specifies a maximum rank of 15 */ #define MAX_RANK (15) diff --git a/src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.h b/src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.h index fe460c767d2..fcfccefff95 100644 --- a/src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.h +++ b/src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.h @@ -16,12 +16,6 @@ #define MPIO_Request MPI_Request #endif -extern MPI_Status *MPIR_C_MPI_STATUS_IGNORE; -extern MPI_Status *MPIR_C_MPI_STATUSES_IGNORE; -extern char **MPIR_C_MPI_ARGV_NULL; -extern char ***MPIR_C_MPI_ARGVS_NULL; -extern int *MPIR_C_MPI_ERRCODES_IGNORE; - extern int cdesc_create_datatype(CFI_cdesc_t * cdesc, MPI_Aint oldcount, MPI_Datatype oldtype, MPI_Datatype * newtype); extern int MPIR_Fortran_array_of_string_f2c(const char *strs_f, char ***strs_c, int str_len, @@ -36,4 +30,12 @@ extern int MPIR_Comm_spawn_multiple_c(int count, char *array_of_commands_f, char int argv_elem_len); extern int MPIR_F_sync_reg_cdesc(CFI_cdesc_t * buf); +void *MPIR_F08_get_MPI_STATUS_IGNORE(void); +void *MPIR_F08_get_MPI_STATUSES_IGNORE(void); +void *MPIR_F08_get_MPI_ARGV_NULL(void); +void *MPIR_F08_get_MPI_ARGVS_NULL(void); +void *MPIR_F08_get_MPI_ERRCODES_IGNORE(void); +void *MPIR_F08_get_MPI_UNWEIGHTED(void); +void *MPIR_F08_get_MPI_WEIGHTS_EMPTY(void); + #endif /* CDESC_H_INCLUDED */ diff --git a/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c b/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c index 241c7455334..665232da057 100644 --- a/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c +++ b/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c @@ -93,3 +93,38 @@ extern int MPIR_Fortran_array_of_string_f2c(const char *strs_f, char ***strs_c, fn_fail: goto fn_exit; } + +void *MPIR_F08_get_MPI_STATUS_IGNORE(void) +{ + return (void *) MPI_STATUS_IGNORE; +} + +void *MPIR_F08_get_MPI_STATUSES_IGNORE(void) +{ + return (void *) MPI_STATUSES_IGNORE; +} + +void *MPIR_F08_get_MPI_ARGV_NULL(void) +{ + return (void *) MPI_ARGV_NULL; +} + +void *MPIR_F08_get_MPI_ARGVS_NULL(void) +{ + return (void *) MPI_ARGVS_NULL; +} + +void *MPIR_F08_get_MPI_ERRCODES_IGNORE(void) +{ + return (void *) MPI_ERRCODES_IGNORE; +} + +void *MPIR_F08_get_MPI_UNWEIGHTED(void) +{ + return (void *) MPI_UNWEIGHTED; +} + +void *MPIR_F08_get_MPI_WEIGHTS_EMPTY(void) +{ + return (void *) MPI_WEIGHTS_EMPTY; +} diff --git a/src/mpi/init/init_bindings.c b/src/mpi/init/init_bindings.c index 2f5da0a3eec..85fb67d2388 100644 --- a/src/mpi/init/init_bindings.c +++ b/src/mpi/init/init_bindings.c @@ -23,9 +23,6 @@ void MPII_init_binding_cxx(void) /* ** F08 binding **************/ #ifdef HAVE_F08_BINDING -int *MPIR_C_MPI_UNWEIGHTED MPICH_API_PUBLIC; -int *MPIR_C_MPI_WEIGHTS_EMPTY MPICH_API_PUBLIC; - MPI_F08_status MPIR_F08_MPI_STATUS_IGNORE_OBJ; MPI_F08_status MPIR_F08_MPI_STATUSES_IGNORE_OBJ[1]; int MPIR_F08_MPI_IN_PLACE; @@ -35,14 +32,4 @@ int MPIR_F08_MPI_BOTTOM; MPI_F08_status *MPI_F08_STATUS_IGNORE = &MPIR_F08_MPI_STATUS_IGNORE_OBJ; MPI_F08_status *MPI_F08_STATUSES_IGNORE = &MPIR_F08_MPI_STATUSES_IGNORE_OBJ[0]; -void MPII_init_binding_f08(void) -{ - MPIR_C_MPI_UNWEIGHTED = MPI_UNWEIGHTED; - MPIR_C_MPI_WEIGHTS_EMPTY = MPI_WEIGHTS_EMPTY; -} - -#else -void MPII_init_binding_f08(void) -{ -} #endif diff --git a/src/mpi/init/mpi_init.h b/src/mpi/init/mpi_init.h index f5558c08995..6c95c193867 100644 --- a/src/mpi/init/mpi_init.h +++ b/src/mpi/init/mpi_init.h @@ -54,7 +54,6 @@ int MPII_init_tag_ub(void); void MPII_init_windows(void); void MPII_init_binding_cxx(void); -void MPII_init_binding_f08(void); void MPII_pre_init_dbg_logging(int *argc, char ***argv); void MPII_init_dbg_logging(void); diff --git a/src/mpi/init/mpir_init.c b/src/mpi/init/mpir_init.c index 16c302afa56..54699093988 100644 --- a/src/mpi/init/mpir_init.c +++ b/src/mpi/init/mpir_init.c @@ -159,7 +159,6 @@ int MPII_Init_thread(int *argc, char ***argv, int user_required, int *provided, MPII_nettopo_init(); MPII_init_windows(); MPII_init_binding_cxx(); - MPII_init_binding_f08(); mpi_errno = MPII_init_local_proc_attrs(&required); MPIR_ERR_CHECK(mpi_errno); From fe5751b65012c51bc07c2db26aac75ace1952e40 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 17 Nov 2021 00:00:22 -0600 Subject: [PATCH 330/607] xfail: remove osx f08 xfails These are due to link constants issues, addressed in this PR. --- test/mpi/maint/jenkins/xfail.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/test/mpi/maint/jenkins/xfail.conf b/test/mpi/maint/jenkins/xfail.conf index 356f7b95af0..ac33f85c122 100644 --- a/test/mpi/maint/jenkins/xfail.conf +++ b/test/mpi/maint/jenkins/xfail.conf @@ -44,7 +44,6 @@ * * * * osx /^fileerrretx/ xfail=ticket0 errors/cxx/io/testlist * * * * osx /^throwtestfilex/ xfail=ticket0 errors/cxx/io/testlist * gnu debug ch3:tcp osx /^namepubx/ xfail=issue3506 cxx/spawn/testlist -* * * * osx /^dgraph_unwgtf90/ xfail=issue4374 f08/topo/testlist ################################################################################ # xfail large count tests on 32 bit architectures (cannot allocate such large memory) * * * * freebsd32 /^getfence1 [0-9]* arg=-type=.* arg=-count=16000000/ xfail=ticket0 rma/testlist.dtp From 6cddfcad46a5379d8dc4585946efa216004cc7ce Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 30 Nov 2021 12:21:09 -0600 Subject: [PATCH 331/607] f08: move MPIR_F08_MPI_IN_PLACE and MPIR_F08_MPI_BOTTOM Both symbols are not used by the C binding and can be contained in the Fortran binding. This avoids the issue of resolving common symbols depending on the behavior of dynamic linker. --- src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.h | 3 +++ src/binding/fortran/use_mpi_f08/wrappers_c/utils.c | 3 +++ src/include/mpi.h.in | 2 -- src/mpi/init/init_bindings.c | 2 -- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.h b/src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.h index fcfccefff95..372b04bb344 100644 --- a/src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.h +++ b/src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.h @@ -16,6 +16,9 @@ #define MPIO_Request MPI_Request #endif +extern int MPIR_F08_MPI_IN_PLACE; +extern int MPIR_F08_MPI_BOTTOM; + extern int cdesc_create_datatype(CFI_cdesc_t * cdesc, MPI_Aint oldcount, MPI_Datatype oldtype, MPI_Datatype * newtype); extern int MPIR_Fortran_array_of_string_f2c(const char *strs_f, char ***strs_c, int str_len, diff --git a/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c b/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c index 665232da057..28a3cc1e57a 100644 --- a/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c +++ b/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c @@ -6,6 +6,9 @@ #include "cdesc.h" #include +int MPIR_F08_MPI_IN_PLACE MPICH_API_PUBLIC; +int MPIR_F08_MPI_BOTTOM MPICH_API_PUBLIC; + /* Convert an array of strings in Fortran Format to an array of strings in C format (i.e., char* a[]). diff --git a/src/include/mpi.h.in b/src/include/mpi.h.in index d82c5dd6734..23fb3b36fcd 100644 --- a/src/include/mpi.h.in +++ b/src/include/mpi.h.in @@ -794,8 +794,6 @@ typedef struct { extern MPI_F08_status MPIR_F08_MPI_STATUS_IGNORE_OBJ MPICH_API_PUBLIC; extern MPI_F08_status MPIR_F08_MPI_STATUSES_IGNORE_OBJ[1] MPICH_API_PUBLIC; -extern int MPIR_F08_MPI_IN_PLACE MPICH_API_PUBLIC; -extern int MPIR_F08_MPI_BOTTOM MPICH_API_PUBLIC; /* Pointers to above objects */ extern MPI_F08_status *MPI_F08_STATUS_IGNORE MPICH_API_PUBLIC; diff --git a/src/mpi/init/init_bindings.c b/src/mpi/init/init_bindings.c index 85fb67d2388..d1e8236748e 100644 --- a/src/mpi/init/init_bindings.c +++ b/src/mpi/init/init_bindings.c @@ -25,8 +25,6 @@ void MPII_init_binding_cxx(void) #ifdef HAVE_F08_BINDING MPI_F08_status MPIR_F08_MPI_STATUS_IGNORE_OBJ; MPI_F08_status MPIR_F08_MPI_STATUSES_IGNORE_OBJ[1]; -int MPIR_F08_MPI_IN_PLACE; -int MPIR_F08_MPI_BOTTOM; /* Although the two STATUS pointers are required but the MPI3.0, they are not used in MPICH F08 binding */ MPI_F08_status *MPI_F08_STATUS_IGNORE = &MPIR_F08_MPI_STATUS_IGNORE_OBJ; From 9791151547013f7fe6ae6861b3ce895180151345 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 30 Nov 2021 21:20:42 -0600 Subject: [PATCH 332/607] f08: move MPI_F08_STATUS[ES]_IGNORE into fortran bindings Both MPI_F08_STATUS_IGNORE and MPI_F08_STATUSES_IGNORE don't need live in the C Binding since application is not suppose to use them unless the fortran binding is linked. Move them to the fortran binding avoids the linkage dependency on dynamic linker, which appears very fragile and currently does not work on osx. Both symbols are C symbols, thus there is no need to declare them in mpi_f08_link_constants.f90. The original comment -- "Although ..., they are not used in ..." is misleading. The two symbols are for application use, regardless whether implementation use it or not. Define the symbols in mpi.h as external is safe. User is not supposed to use it unless they link with fortran binding, i.e. libmpifort.so, which will resolve the symbol. --- .../fortran/use_mpi_f08/mpi_f08_link_constants.f90 | 4 ---- src/binding/fortran/use_mpi_f08/wrappers_c/utils.c | 9 +++++++++ src/include/mpi.h.in | 9 +++------ src/mpi/init/init_bindings.c | 11 ----------- 4 files changed, 12 insertions(+), 21 deletions(-) diff --git a/src/binding/fortran/use_mpi_f08/mpi_f08_link_constants.f90 b/src/binding/fortran/use_mpi_f08/mpi_f08_link_constants.f90 index 5167a89c461..a753ee4a5c7 100644 --- a/src/binding/fortran/use_mpi_f08/mpi_f08_link_constants.f90 +++ b/src/binding/fortran/use_mpi_f08/mpi_f08_link_constants.f90 @@ -24,10 +24,6 @@ module mpi_f08_link_constants type(MPI_Status), bind(C, name="MPIR_F08_MPI_STATUS_IGNORE_OBJ"), target :: MPI_STATUS_IGNORE type(MPI_Status), dimension(1), bind(C, name="MPIR_F08_MPI_STATUSES_IGNORE_OBJ"), target :: MPI_STATUSES_IGNORE -! Though these two variables are required by MPI-3 Standard, they are not used in MPICH -type(c_ptr), bind(C, name="MPI_F08_STATUS_IGNORE") :: MPI_F08_STATUS_IGNORE ! Point to MPI_STATUS_IGNORE -type(c_ptr), bind(C, name="MPI_F08_STATUSES_IGNORE") :: MPI_F08_STATUSES_IGNORE ! Point to MPI_STATUSES_IGNORE - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! diff --git a/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c b/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c index 28a3cc1e57a..029a7064907 100644 --- a/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c +++ b/src/binding/fortran/use_mpi_f08/wrappers_c/utils.c @@ -9,6 +9,15 @@ int MPIR_F08_MPI_IN_PLACE MPICH_API_PUBLIC; int MPIR_F08_MPI_BOTTOM MPICH_API_PUBLIC; +/* MPI_F08_STATUS_IGNORE and MPI_F08_STATUSES_IGNORE are required by MPI-3.0. + * the obj variables are linked in mpi_f08_link_constants module via bind(c). + */ +MPI_F08_status MPIR_F08_MPI_STATUS_IGNORE_OBJ MPICH_API_PUBLIC; +MPI_F08_status MPIR_F08_MPI_STATUSES_IGNORE_OBJ[1] MPICH_API_PUBLIC; + +MPI_F08_status *MPI_F08_STATUS_IGNORE MPICH_API_PUBLIC = &MPIR_F08_MPI_STATUS_IGNORE_OBJ; +MPI_F08_status *MPI_F08_STATUSES_IGNORE MPICH_API_PUBLIC = &MPIR_F08_MPI_STATUSES_IGNORE_OBJ[0]; + /* Convert an array of strings in Fortran Format to an array of strings in C format (i.e., char* a[]). diff --git a/src/include/mpi.h.in b/src/include/mpi.h.in index 23fb3b36fcd..1c15032a0a2 100644 --- a/src/include/mpi.h.in +++ b/src/include/mpi.h.in @@ -792,12 +792,9 @@ typedef struct { #define MPI_F_TAG 3 #define MPI_F_ERROR 4 -extern MPI_F08_status MPIR_F08_MPI_STATUS_IGNORE_OBJ MPICH_API_PUBLIC; -extern MPI_F08_status MPIR_F08_MPI_STATUSES_IGNORE_OBJ[1] MPICH_API_PUBLIC; - -/* Pointers to above objects */ -extern MPI_F08_status *MPI_F08_STATUS_IGNORE MPICH_API_PUBLIC; -extern MPI_F08_status *MPI_F08_STATUSES_IGNORE MPICH_API_PUBLIC; +/* Provided in libmpifort.so */ +extern MPI_F08_status *MPI_F08_STATUS_IGNORE; +extern MPI_F08_status *MPI_F08_STATUSES_IGNORE; /* For supported thread levels */ #define MPI_THREAD_SINGLE 0 diff --git a/src/mpi/init/init_bindings.c b/src/mpi/init/init_bindings.c index d1e8236748e..4fdb6a3928c 100644 --- a/src/mpi/init/init_bindings.c +++ b/src/mpi/init/init_bindings.c @@ -20,14 +20,3 @@ void MPII_init_binding_cxx(void) MPIR_Process.cxx_call_op_fn = 0; #endif } - -/* ** F08 binding **************/ -#ifdef HAVE_F08_BINDING -MPI_F08_status MPIR_F08_MPI_STATUS_IGNORE_OBJ; -MPI_F08_status MPIR_F08_MPI_STATUSES_IGNORE_OBJ[1]; - -/* Although the two STATUS pointers are required but the MPI3.0, they are not used in MPICH F08 binding */ -MPI_F08_status *MPI_F08_STATUS_IGNORE = &MPIR_F08_MPI_STATUS_IGNORE_OBJ; -MPI_F08_status *MPI_F08_STATUSES_IGNORE = &MPIR_F08_MPI_STATUSES_IGNORE_OBJ[0]; - -#endif From 11d681f0928d533af96b392a3b614606821d19d9 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 1 Dec 2021 10:08:50 -0600 Subject: [PATCH 333/607] f08: include mpichconf.h in cdesc.h This is needed for `HAVE_VISIBILITY` option. It is also necessary to honor the configure for any potential system features. --- src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.h b/src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.h index 372b04bb344..1ea7b00147e 100644 --- a/src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.h +++ b/src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.h @@ -6,6 +6,7 @@ #ifndef CDESC_H_INCLUDED #define CDESC_H_INCLUDED +#include "mpichconf.h" #include #include #include From 3cbd706ec26164e12dc156d1664c2c7ebe154f10 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 1 Dec 2021 10:12:08 -0600 Subject: [PATCH 334/607] f08: avoid using MPIR_Assert Use assert to avoid including the whole mpich internal header stack. --- src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.c b/src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.c index 70226dc939a..9d8d9120297 100644 --- a/src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.c +++ b/src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.c @@ -5,6 +5,7 @@ #include "cdesc.h" #include +#include /* Fortran 2008 specifies a maximum rank of 15 */ #define MAX_RANK (15) @@ -24,12 +25,12 @@ int cdesc_create_datatype(CFI_cdesc_t * cdesc, MPI_Aint oldcount, MPI_Datatype o #ifdef HAVE_ERROR_CHECKING { int size; - MPIR_Assert(cdesc->rank <= MAX_RANK); + assert(cdesc->rank <= MAX_RANK); PMPI_Type_size(oldtype, &size); /* When cdesc->elem_len != size, things suddenly become complicated. Generally, it is hard to create * a composite datatype based on two datatypes. Currently we don't support it and doubt it is useful. */ - MPIR_Assert(cdesc->elem_len == size); + assert(cdesc->elem_len == size); } #endif From 98ee19777c7674c68d54668cd0b305abd8b98ccc Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 21 Jan 2022 12:25:37 -0600 Subject: [PATCH 335/607] session: fix hint thread_level The hint was named mpi_thread_level_support in the early draft. It changed to thread_level in the final standard. --- src/mpi/init/init_impl.c | 2 +- test/mpi/init/session.c | 2 +- test/mpi/threads/init/mult_session.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mpi/init/init_impl.c b/src/mpi/init/init_impl.c index db2071f52b0..1214951cc74 100644 --- a/src/mpi/init/init_impl.c +++ b/src/mpi/init/init_impl.c @@ -234,7 +234,7 @@ int MPIR_Session_get_info_impl(MPIR_Session * session_ptr, MPIR_Info ** info_p_p /* Multiple session may run in threads concurrently, so significant work is needed to support * per-session MPI_THREAD_SINGLE */ /* TODO: support per-session MPI_THREAD_SINGLE and optimize */ - mpi_errno = MPIR_Info_set_impl(*info_p_p, "mpi_thread_support_level", "MPI_THREAD_MULTIPLE"); + mpi_errno = MPIR_Info_set_impl(*info_p_p, "thread_level", "MPI_THREAD_MULTIPLE"); MPIR_ERR_CHECK(mpi_errno); fn_exit: diff --git a/test/mpi/init/session.c b/test/mpi/init/session.c index 96609f24517..c7dbdf6536a 100644 --- a/test/mpi/init/session.c +++ b/test/mpi/init/session.c @@ -80,7 +80,7 @@ void library_foo_init(void) int rc, flag; int ret = 0; const char pset_name[] = "mpi://WORLD"; - const char mt_key[] = "mpi_thread_support_level"; + const char mt_key[] = "thread_level"; const char mt_value[] = "MPI_THREAD_MULTIPLE"; char out_value[100]; /* large enough */ diff --git a/test/mpi/threads/init/mult_session.c b/test/mpi/threads/init/mult_session.c index bce82e4ac52..9eda51b0172 100644 --- a/test/mpi/threads/init/mult_session.c +++ b/test/mpi/threads/init/mult_session.c @@ -90,7 +90,7 @@ static bool library_foo_init(int thread_idx, MPI_Session * p_session, MPI_Comm * /* check we got thread support level foo library needs */ MPI_Info tinfo = MPI_INFO_NULL; - const char mt_key[] = "mpi_thread_support_level"; + const char mt_key[] = "thread_level"; const char mt_value[] = "MPI_THREAD_MULTIPLE"; rc = MPI_Session_get_info(*p_session, &tinfo); if (rc != MPI_SUCCESS) { From 1431cfb4c11e05d9f190d91dcc324ccfdb77ee39 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Fri, 21 Jan 2022 10:08:31 -0600 Subject: [PATCH 336/607] modules: update yaksa pmodels/yaksa#210: more fixes for nvc/nvcc support pmodels/yaksa#211: support new ampere compute capability --- modules/yaksa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/yaksa b/modules/yaksa index 6e4211e1cbd..8f0f232b4f5 160000 --- a/modules/yaksa +++ b/modules/yaksa @@ -1 +1 @@ -Subproject commit 6e4211e1cbd4710b2c87216eaaab8e5ed6234768 +Subproject commit 8f0f232b4f57c087ab42ad6599df6a565422a3a0 From 88298f539c03099ae49949ee760ee5aad1c47dde Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 19 Jan 2022 10:25:34 -0600 Subject: [PATCH 337/607] configure: add no-dist option to automake The default dist target doesn't work for us. Disable it to prevent confusions. TODO: add our own dist target that either call maint/release.pl or replace release.pl. --- configure.ac | 2 +- src/pm/hydra/configure.ac | 2 +- test/mpi/configure.ac | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index f8ae09b6210..70ba472a0df 100644 --- a/configure.ac +++ b/configure.ac @@ -650,7 +650,7 @@ dnl We would like to pass -Werror, but we are cheating in the "examples/" dnl directory and overriding the user-flags like CFLAGS, which automake-1.12 dnl warns about. Long-term we may need to use a hand-written Makefile.in or dnl something else in this special dir. -AM_INIT_AUTOMAKE([-Wall -Wno-portability-recursive foreign 1.12.3 silent-rules subdir-objects]) +AM_INIT_AUTOMAKE([-Wall -Wno-portability-recursive foreign 1.12.3 silent-rules subdir-objects no-dist]) AM_MAINTAINER_MODE([enable]) AM_PROG_AR diff --git a/src/pm/hydra/configure.ac b/src/pm/hydra/configure.ac index 3370eb1d28e..c296339d7d2 100644 --- a/src/pm/hydra/configure.ac +++ b/src/pm/hydra/configure.ac @@ -27,7 +27,7 @@ AM_PROG_CC_C_O # ordering reasons AC_USE_SYSTEM_EXTENSIONS -AM_INIT_AUTOMAKE([-Wall -Wno-portability-recursive -Werror foreign 1.12.3 subdir-objects]) +AM_INIT_AUTOMAKE([-Wall -Wno-portability-recursive -Werror foreign 1.12.3 subdir-objects no-dist]) AM_PROG_AR diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index 69c9a526ccb..fe1f2f4ce31 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -40,7 +40,7 @@ AC_CONFIG_MACRO_DIR([confdb]) dnl echo "RUNNING CONFIGURE FOR MPI TESTS" -AM_INIT_AUTOMAKE([-Wall -Werror -Wno-portability-recursive foreign 1.12.3 silent-rules subdir-objects]) +AM_INIT_AUTOMAKE([-Wall -Werror -Wno-portability-recursive foreign 1.12.3 silent-rules subdir-objects no-dist]) AM_MAINTAINER_MODE([enable]) # Non-verbose make by default From 0125ebce9898ada1d5af8c2dfe574a28b26081a8 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 19 Jan 2022 11:10:29 -0600 Subject: [PATCH 338/607] Makefile: add pseudo dist target When user `make dist`, show some message to point them to use release.pl. --- Makefile.am | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Makefile.am b/Makefile.am index bfd917c8ca4..d2dea25cd7e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -616,6 +616,11 @@ include $(top_srcdir)/doc/Makefile.mk # -local targets install-data-local: $(INSTALL_DATA_LOCAL_TARGETS) +# the dist target created by automake won't work. Direct user to use release.pl +dist: + @echo "To create release tarball, use:" ; \ + echo " maint/release.pl --branch=[git_ref_to_use] --version=[version] --git-repo=[path_to_git_repository]" + # sometimes helpful when debugging macros to see the preprocessed output. # Also using '-CC' because comments provide useful landmarks From 05ba94a49db0ddc9676df5b9fff824535750d7c2 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 19 Jan 2022 11:52:44 -0600 Subject: [PATCH 339/607] maint: create mpich-testsuite tarball in release.pl This allows user to independently use mpich testsuite. --- maint/release.pl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/maint/release.pl b/maint/release.pl index 3918e0390e2..9fda053c45b 100755 --- a/maint/release.pl +++ b/maint/release.pl @@ -288,5 +288,13 @@ sub run_cmd run_cmd("cp -a hydra-${version}.tar.gz ${root}/"); print("done\n\n"); +# Create the testsuite tarball +print("===> Creating the final mpich-testsuite tarball... "); +my $target = "mpich-testsuite-$version"; +run_cmd("cp -a ${expdir}/test/mpi $target"); +run_cmd("tar -czvf $target.tar.gz $target"); +run_cmd("cp -a $target.tar.gz ${root}/"); +print("done\n\n"); + # make sure we are outside of the tempdir so that the CLEANUP logic can run chdir("${tdir}/.."); From 6ad9b7a88d6dd1ce0c4f1d7b8a29d902d2f63670 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 19 Jan 2022 12:57:20 -0600 Subject: [PATCH 340/607] test: update test/mpi/README Slight changes to provide a simple usage case. --- test/mpi/README | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/test/mpi/README b/test/mpi/README index 5babf58bd59..1ea7f810366 100644 --- a/test/mpi/README +++ b/test/mpi/README @@ -1,11 +1,15 @@ MPICH Test Suite -This test suite is a *supplement* to other test suites, including the -original MPICH testsuite, the Intel testsuite, and the IBM MPI test suite -(or test suites derived from that test, including the MPI C++ tests). +This test suite is the main test suite used by MPICH. However, it is designed +to be usable to test any MPI implementations. -Building the Test Suite +Using the Test Suite ======================= +The simple version: + +./configure +make testing + In many cases, configure will find the MPI implementation automatically. In some cases, it will need some help. For example: From c98072339377341a17be6d81095239013aeec044 Mon Sep 17 00:00:00 2001 From: Gregor Corbin Date: Wed, 26 Jan 2022 17:39:49 +0100 Subject: [PATCH 341/607] test/mpi/f08: Replace 'use mpi' by 'use mpi_f08' --- test/mpi/f08/attr/commattrf08.f90 | 10 +++++---- test/mpi/f08/pt2pt/irsendf08.f90 | 24 ++++++++++---------- test/mpi/f08/pt2pt/isendf08.f90 | 20 +++++++++-------- test/mpi/f08/pt2pt/issendf08.f90 | 23 ++++++++++--------- test/mpi/f08/pt2pt/prsendf08.f90 | 19 ++++++++-------- test/mpi/f08/pt2pt/psendf08.f90 | 31 ++++++++++---------------- test/mpi/f08/pt2pt/pssendf08.f90 | 25 +++++++++++---------- test/mpi/f08/pt2pt/rsendf08.f90 | 22 +++++++++--------- test/mpi/f08/pt2pt/sendf08.f90 | 14 +++++++----- test/mpi/f08/pt2pt/sendrecvf08.f90 | 13 ++++++----- test/mpi/f08/pt2pt/sendrecvreplf08.f90 | 13 ++++++----- test/mpi/f08/pt2pt/ssendf08.f90 | 25 +++++++++++---------- test/mpi/f08/pt2pt/utilsf08.f90 | 16 +++++++------ test/mpi/f08/rma/winattrf08.f90 | 16 ++++++++----- test/mpi/f08/rma/winerrf08.f90 | 5 +++-- 15 files changed, 146 insertions(+), 130 deletions(-) diff --git a/test/mpi/f08/attr/commattrf08.f90 b/test/mpi/f08/attr/commattrf08.f90 index 9d23822098e..0c3956f356b 100644 --- a/test/mpi/f08/attr/commattrf08.f90 +++ b/test/mpi/f08/attr/commattrf08.f90 @@ -118,8 +118,9 @@ program main ! subroutine mycopyfn( oldcomm, keyval, extrastate, valin, valout, & & flag, ierr ) - use mpi - integer oldcomm, keyval, ierr + use mpi_f08 + type(MPI_Comm) oldcomm + integer keyval, ierr integer (kind=MPI_ADDRESS_KIND) extrastate, valin, valout, val logical flag @@ -139,8 +140,9 @@ subroutine mycopyfn( oldcomm, keyval, extrastate, valin, valout, & end ! subroutine mydelfn( comm, keyval, val, extrastate, ierr ) - use mpi - integer comm, keyval, ierr + use mpi_f08 + type(MPI_Comm) comm + integer keyval, ierr integer (kind=MPI_ADDRESS_KIND) extrastate, valin, valout, val integer callcount, delcount diff --git a/test/mpi/f08/pt2pt/irsendf08.f90 b/test/mpi/f08/pt2pt/irsendf08.f90 index b568b475220..8315d207e05 100644 --- a/test/mpi/f08/pt2pt/irsendf08.f90 +++ b/test/mpi/f08/pt2pt/irsendf08.f90 @@ -3,15 +3,14 @@ ! See COPYRIGHT in top-level directory ! -! This file created from test/mpi/f77/pt2pt/irsendf.f with f77tof90 -! ! This program is based on the allpair.f test from the MPICH-1 test ! (test/pt2pt/allpair.f), which in turn was inspired by a bug report from ! fsset@corelli.lerc.nasa.gov (Scott Townsend) program isend - use mpi - integer ierr, errs, comm + use mpi_f08 + type(MPI_Comm) comm + integer ierr, errs logical mtestGetIntraComm logical verbose common /flags/ verbose @@ -31,14 +30,16 @@ program isend end ! subroutine test_pair_irsend( comm, errs ) - use mpi - integer comm, errs + use mpi_f08 + type(MPI_Comm) comm + integer errs integer rank, size, ierr, next, prev, tag, count, index, i integer TEST_SIZE - integer dupcom + type(MPI_Comm) dupcom parameter (TEST_SIZE=2000) - integer status(MPI_STATUS_SIZE), requests(2) - integer statuses(MPI_STATUS_SIZE,2) + type(MPI_Status) status + type(MPI_Request) requests(2) + type(MPI_Status) statuses(2) logical flag real send_buf(TEST_SIZE), recv_buf(TEST_SIZE) logical verbose @@ -80,12 +81,11 @@ subroutine test_pair_irsend( comm, errs ) ! index = -1 do while (index .ne. 1) - call MPI_Waitany(2, requests, index, statuses, ierr) + call MPI_Waitany(2, requests, index, statuses(1), ierr) end do -! call rq_check( requests(1), 1, 'irsend and irecv' ) ! - call msg_check( recv_buf, next, tag, count, statuses, & + call msg_check( recv_buf, next, tag, count, statuses(1), & & TEST_SIZE, 'irsend and irecv', errs ) ! else if (prev .eq. 0) then diff --git a/test/mpi/f08/pt2pt/isendf08.f90 b/test/mpi/f08/pt2pt/isendf08.f90 index 4904a944cec..6381ed06930 100644 --- a/test/mpi/f08/pt2pt/isendf08.f90 +++ b/test/mpi/f08/pt2pt/isendf08.f90 @@ -2,16 +2,15 @@ ! Copyright (C) by Argonne National Laboratory ! See COPYRIGHT in top-level directory ! - -! This file created from test/mpi/f77/pt2pt/isendf.f with f77tof90 ! ! This program is based on the allpair.f test from the MPICH-1 test ! (test/pt2pt/allpair.f), which in turn was inspired by a bug report from ! fsset@corelli.lerc.nasa.gov (Scott Townsend) program isend - use mpi - integer ierr, errs, comm + use mpi_f08 + integer ierr, errs + type(MPI_Comm) comm logical mtestGetIntraComm logical verbose common /flags/ verbose @@ -31,13 +30,16 @@ program isend end ! subroutine test_pair_isend( comm, errs ) - use mpi - integer comm, errs + use mpi_f08 + type(MPI_Comm) comm + integer errs + integer rank, size, ierr, next, prev, tag, count integer TEST_SIZE parameter (TEST_SIZE=2000) - integer status(MPI_STATUS_SIZE), requests(2) - integer statuses(MPI_STATUS_SIZE,2) + type(MPI_Status) status + type(MPI_Request) requests(2) + type(MPI_Status) statuses(2) real send_buf(TEST_SIZE), recv_buf(TEST_SIZE) logical verbose common /flags/ verbose @@ -75,7 +77,7 @@ subroutine test_pair_isend( comm, errs ) ! call rq_check( requests, 2, 'isend and irecv' ) ! - call msg_check( recv_buf, next, tag, count, statuses(1,1), & + call msg_check( recv_buf, next, tag, count, statuses(1), & & TEST_SIZE, 'isend and irecv', errs ) ! else if (prev .eq. 0) then diff --git a/test/mpi/f08/pt2pt/issendf08.f90 b/test/mpi/f08/pt2pt/issendf08.f90 index d99261eaad8..a2b15b34df2 100644 --- a/test/mpi/f08/pt2pt/issendf08.f90 +++ b/test/mpi/f08/pt2pt/issendf08.f90 @@ -3,15 +3,15 @@ ! See COPYRIGHT in top-level directory ! -! This file created from test/mpi/f77/pt2pt/issendf.f with f77tof90 ! ! This program is based on the allpair.f test from the MPICH-1 test ! (test/pt2pt/allpair.f), which in turn was inspired by a bug report from ! fsset@corelli.lerc.nasa.gov (Scott Townsend) program issend - use mpi - integer ierr, errs, comm + use mpi_f08 + type(MPI_Comm) comm + integer ierr, errs logical mtestGetIntraComm logical verbose common /flags/ verbose @@ -31,13 +31,15 @@ program issend end ! subroutine test_pair_issend( comm, errs ) - use mpi - integer comm, errs + use mpi_f08 + type(MPI_Comm) comm + integer errs integer rank, size, ierr, next, prev, tag, count, index integer TEST_SIZE parameter (TEST_SIZE=2000) - integer status(MPI_STATUS_SIZE), requests(2) - integer statuses(MPI_STATUS_SIZE,2) + type(MPI_Status) status + type(MPI_Request) requests(2) + type(MPI_Status) statuses(2) logical flag real send_buf(TEST_SIZE), recv_buf(TEST_SIZE) logical verbose @@ -79,7 +81,7 @@ subroutine test_pair_issend( comm, errs ) ! call rq_check( requests, 2, 'issend and irecv (testall)' ) ! - call msg_check( recv_buf, next, tag, count, statuses(1,1), & + call msg_check( recv_buf, next, tag, count, statuses(1), & & TEST_SIZE, 'issend and recv (testall)', errs ) ! else if (prev .eq. 0) then @@ -96,8 +98,9 @@ subroutine test_pair_issend( comm, errs ) ! flag = .FALSE. do while (.not. flag) - call MPI_Testany(1, requests(1), index, flag, & - & statuses(1,1), ierr) +! MPI_Testany expects an array of requests, therefore we give it the size 1 slice requests(1:1) instead of requests(1) + call MPI_Testany(1, requests(1:1), index, flag, & + & statuses(1), ierr) end do ! call rq_check( requests, 1, 'issend and recv (testany)' ) diff --git a/test/mpi/f08/pt2pt/prsendf08.f90 b/test/mpi/f08/pt2pt/prsendf08.f90 index 4dd7b7c2fde..b24b8d3ccd9 100644 --- a/test/mpi/f08/pt2pt/prsendf08.f90 +++ b/test/mpi/f08/pt2pt/prsendf08.f90 @@ -3,15 +3,14 @@ ! See COPYRIGHT in top-level directory ! -! This file created from test/mpi/f77/pt2pt/prsendf.f with f77tof90 -! ! This program is based on the allpair.f test from the MPICH-1 test ! (test/pt2pt/allpair.f), which in turn was inspired by a bug report from ! fsset@corelli.lerc.nasa.gov (Scott Townsend) program prsend - use mpi - integer ierr, errs, comm + use mpi_f08 + type(MPI_Comm) comm + integer ierr, errs logical mtestGetIntraComm logical verbose common /flags/ verbose @@ -31,14 +30,16 @@ program prsend end ! subroutine test_pair_prsend( comm, errs ) - use mpi - integer comm, errs + use mpi_f08 + type(MPI_Comm) comm + integer errs integer rank, size, ierr, next, prev, tag, count, index, i integer outcount, indices(2) integer TEST_SIZE parameter (TEST_SIZE=2000) - integer statuses(MPI_STATUS_SIZE,2), requests(2) - integer status(MPI_STATUS_SIZE) + type(MPI_Status) statuses(2) + type(MPI_Request) requests(2) + type(MPI_Status) status logical flag real send_buf(TEST_SIZE), recv_buf(TEST_SIZE) logical verbose @@ -85,7 +86,7 @@ subroutine test_pair_prsend( comm, errs ) do i = 1,outcount if (indices(i) .eq. 2) then call msg_check( recv_buf, next, tag, count, & - & statuses(1,i), TEST_SIZE, 'waitsome', errs ) + & statuses(i), TEST_SIZE, 'waitsome', errs ) index = 2 end if end do diff --git a/test/mpi/f08/pt2pt/psendf08.f90 b/test/mpi/f08/pt2pt/psendf08.f90 index 56d0fe6e96f..0d146d84503 100644 --- a/test/mpi/f08/pt2pt/psendf08.f90 +++ b/test/mpi/f08/pt2pt/psendf08.f90 @@ -2,23 +2,18 @@ ! Copyright (C) by Argonne National Laboratory ! See COPYRIGHT in top-level directory ! - -! This file created from test/mpi/f77/pt2pt/psendf.f with f77tof90 ! ! This program is based on the allpair.f test from the MPICH-1 test ! (test/pt2pt/allpair.f), which in turn was inspired by a bug report from ! fsset@corelli.lerc.nasa.gov (Scott Townsend) program psend - use mpi - integer ierr, errs, comm + use mpi_f08 + type(MPI_Comm) comm + integer ierr, errs logical mtestGetIntraComm - logical verbose - common /flags/ verbose errs = 0 - verbose = .false. -! verbose = .true. call MTest_Init( ierr ) do while ( mtestGetIntraComm( comm, 2, .false. ) ) @@ -31,20 +26,18 @@ program psend end ! subroutine test_pair_psend( comm, errs ) - use mpi - integer comm, errs + use mpi_f08 + type(MPI_Comm) comm + integer errs + integer rank, size, ierr, next, prev, tag, count, i integer TEST_SIZE parameter (TEST_SIZE=2000) - integer status(MPI_STATUS_SIZE) - integer statuses(MPI_STATUS_SIZE,2), requests(2) + + type(MPI_Status) status + type(MPI_Status) statuses(2) + type(MPI_Request) requests(2) real send_buf(TEST_SIZE), recv_buf(TEST_SIZE) - logical verbose - common /flags/ verbose -! - if (verbose) then - print *, ' Persistent send and recv' - endif ! call mpi_comm_rank( comm, rank, ierr ) call mpi_comm_size( comm, size, ierr ) @@ -72,7 +65,7 @@ subroutine test_pair_psend( comm, errs ) call MPI_Startall(2, requests, ierr) call MPI_Waitall(2, requests, statuses, ierr) ! - call msg_check( recv_buf, next, tag, count, statuses(1,2), & + call msg_check( recv_buf, next, tag, count, statuses(2), & & TEST_SIZE, 'persistent send/recv', errs ) ! call MPI_Request_free(requests(1), ierr) diff --git a/test/mpi/f08/pt2pt/pssendf08.f90 b/test/mpi/f08/pt2pt/pssendf08.f90 index 9f31239e331..7656ab627f3 100644 --- a/test/mpi/f08/pt2pt/pssendf08.f90 +++ b/test/mpi/f08/pt2pt/pssendf08.f90 @@ -3,15 +3,14 @@ ! See COPYRIGHT in top-level directory ! -! This file created from test/mpi/f77/pt2pt/pssendf.f with f77tof90 -! ! This program is based on the allpair.f test from the MPICH-1 test ! (test/pt2pt/allpair.f), which in turn was inspired by a bug report from ! fsset@corelli.lerc.nasa.gov (Scott Townsend) program pssend - use mpi - integer ierr, errs, comm + use mpi_f08 + type(MPI_Comm) comm + integer ierr, errs logical mtestGetIntraComm logical verbose common /flags/ verbose @@ -31,14 +30,16 @@ program pssend end ! subroutine test_pair_pssend( comm, errs ) - use mpi - integer comm, errs + use mpi_f08 + type(MPI_Comm) comm + integer errs integer rank, size, ierr, next, prev, tag, count, index, i integer outcount, indices(2) integer TEST_SIZE parameter (TEST_SIZE=2000) - integer statuses(MPI_STATUS_SIZE,2), requests(2) - integer status(MPI_STATUS_SIZE) + type(MPI_Status) statuses(2) + type(MPI_Request) requests(2) + type(MPI_Status) status logical flag real send_buf(TEST_SIZE), recv_buf(TEST_SIZE) logical verbose @@ -81,7 +82,7 @@ subroutine test_pair_pssend( comm, errs ) do i = 1,outcount if (indices(i) .eq. 1) then call msg_check( recv_buf, next, tag, count, & - & statuses(1,i), TEST_SIZE, 'testsome', errs ) + & statuses(i), TEST_SIZE, 'testsome', errs ) index = 1 end if end do @@ -98,10 +99,10 @@ subroutine test_pair_pssend( comm, errs ) ! flag = .FALSE. do while (.not. flag) - call MPI_Testany(1, requests(1), index, flag, & - & statuses(1,1), ierr) + call MPI_Testany(1, requests(1:1), index, flag, & + & statuses(1), ierr) end do - call msg_check( recv_buf, prev, tag, count, statuses(1,1), & + call msg_check( recv_buf, prev, tag, count, statuses(1), & & TEST_SIZE, 'testany', errs ) do i = 1,count diff --git a/test/mpi/f08/pt2pt/rsendf08.f90 b/test/mpi/f08/pt2pt/rsendf08.f90 index 4494009ffc8..005fddde7bf 100644 --- a/test/mpi/f08/pt2pt/rsendf08.f90 +++ b/test/mpi/f08/pt2pt/rsendf08.f90 @@ -3,15 +3,15 @@ ! See COPYRIGHT in top-level directory ! -! This file created from test/mpi/f77/pt2pt/rsendf.f with f77tof90 ! ! This program is based on the allpair.f test from the MPICH-1 test ! (test/pt2pt/allpair.f), which in turn was inspired by a bug report from ! fsset@corelli.lerc.nasa.gov (Scott Townsend) program rsend - use mpi - integer ierr, errs, comm + use mpi_f08 + type(MPI_Comm) comm + integer ierr, errs logical mtestGetIntraComm logical verbose common /flags/ verbose @@ -31,12 +31,14 @@ program rsend end ! subroutine test_pair_rsend( comm, errs ) - use mpi - integer comm, errs + use mpi_f08 + type(MPI_Comm) comm + integer errs integer rank, size, ierr, next, prev, tag, count, i integer TEST_SIZE parameter (TEST_SIZE=2000) - integer status(MPI_STATUS_SIZE), requests(1) + type(MPI_Status) status + type(MPI_Request) requests(1) real send_buf(TEST_SIZE), recv_buf(TEST_SIZE) logical verbose common /flags/ verbose @@ -71,15 +73,15 @@ subroutine test_pair_rsend( comm, errs ) ! call MPI_Probe(MPI_ANY_SOURCE, tag, comm, status, ierr) ! - if (status(MPI_SOURCE) .ne. next) then + if (status%MPI_SOURCE .ne. next) then print *, 'Rsend: Incorrect source, expected', next, & - & ', got', status(MPI_SOURCE) + & ', got', status%MPI_SOURCE errs = errs + 1 end if ! - if (status(MPI_TAG) .ne. tag) then + if (status%MPI_TAG .ne. tag) then print *, 'Rsend: Incorrect tag, expected', tag, & - & ', got', status(MPI_TAG) + & ', got', status%MPI_TAG errs = errs + 1 end if ! diff --git a/test/mpi/f08/pt2pt/sendf08.f90 b/test/mpi/f08/pt2pt/sendf08.f90 index d61ce93e399..bd87a8f04e6 100644 --- a/test/mpi/f08/pt2pt/sendf08.f90 +++ b/test/mpi/f08/pt2pt/sendf08.f90 @@ -3,15 +3,15 @@ ! See COPYRIGHT in top-level directory ! -! This file created from test/mpi/f77/pt2pt/sendf.f with f77tof90 ! ! This program is based on the allpair.f test from the MPICH-1 test ! (test/pt2pt/allpair.f), which in turn was inspired by a bug report from ! fsset@corelli.lerc.nasa.gov (Scott Townsend) program send - use mpi - integer ierr, errs, comm + use mpi_f08 + integer ierr, errs + type(MPI_Comm) comm logical mtestGetIntraComm logical verbose common /flags/ verbose @@ -31,12 +31,14 @@ program send end ! subroutine test_pair_send( comm, errs ) - use mpi - integer comm, errs + use mpi_f08 + type(MPI_Comm) comm + integer errs + integer rank, size, ierr, next, prev, tag, count integer TEST_SIZE parameter (TEST_SIZE=2000) - integer status(MPI_STATUS_SIZE) + type(MPI_Status) status real send_buf(TEST_SIZE), recv_buf(TEST_SIZE) logical verbose common /flags/ verbose diff --git a/test/mpi/f08/pt2pt/sendrecvf08.f90 b/test/mpi/f08/pt2pt/sendrecvf08.f90 index 3d11095b372..83feb5bb199 100644 --- a/test/mpi/f08/pt2pt/sendrecvf08.f90 +++ b/test/mpi/f08/pt2pt/sendrecvf08.f90 @@ -3,15 +3,15 @@ ! See COPYRIGHT in top-level directory ! -! This file created from test/mpi/f77/pt2pt/sendrecvf.f with f77tof90 ! ! This program is based on the allpair.f test from the MPICH-1 test ! (test/pt2pt/allpair.f), which in turn was inspired by a bug report from ! fsset@corelli.lerc.nasa.gov (Scott Townsend) program sendrecv - use mpi - integer ierr, errs, comm + use mpi_f08 + type(MPI_Comm) comm + integer ierr, errs logical mtestGetIntraComm logical verbose common /flags/ verbose @@ -31,12 +31,13 @@ program sendrecv end ! subroutine test_pair_sendrecv( comm, errs ) - use mpi - integer comm, errs + use mpi_f08 + type(MPI_Comm) comm + integer errs integer rank, size, ierr, next, prev, tag, count integer TEST_SIZE parameter (TEST_SIZE=2000) - integer status(MPI_STATUS_SIZE) + type(MPI_Status) status real send_buf(TEST_SIZE), recv_buf(TEST_SIZE) logical verbose common /flags/ verbose diff --git a/test/mpi/f08/pt2pt/sendrecvreplf08.f90 b/test/mpi/f08/pt2pt/sendrecvreplf08.f90 index 330dc5054c9..fede991aff5 100644 --- a/test/mpi/f08/pt2pt/sendrecvreplf08.f90 +++ b/test/mpi/f08/pt2pt/sendrecvreplf08.f90 @@ -3,15 +3,15 @@ ! See COPYRIGHT in top-level directory ! -! This file created from test/mpi/f77/pt2pt/sendrecvreplf.f with f77tof90 ! ! This program is based on the allpair.f test from the MPICH-1 test ! (test/pt2pt/allpair.f), which in turn was inspired by a bug report from ! fsset@corelli.lerc.nasa.gov (Scott Townsend) program sendrecvrepl - use mpi - integer ierr, errs, comm + use mpi_f08 + type(MPI_Comm) comm + integer ierr, errs logical mtestGetIntraComm logical verbose common /flags/ verbose @@ -31,12 +31,13 @@ program sendrecvrepl end ! subroutine test_pair_sendrecvrepl( comm, errs ) - use mpi - integer comm, errs + use mpi_f08 + type(MPI_Comm) comm + integer errs integer rank, size, ierr, next, prev, tag, count, i integer TEST_SIZE parameter (TEST_SIZE=2000) - integer status(MPI_STATUS_SIZE) + type(MPI_Status) status real send_buf(TEST_SIZE), recv_buf(TEST_SIZE) logical verbose common /flags/ verbose diff --git a/test/mpi/f08/pt2pt/ssendf08.f90 b/test/mpi/f08/pt2pt/ssendf08.f90 index c73c33827cf..d4ac837aeda 100644 --- a/test/mpi/f08/pt2pt/ssendf08.f90 +++ b/test/mpi/f08/pt2pt/ssendf08.f90 @@ -3,15 +3,15 @@ ! See COPYRIGHT in top-level directory ! -! This file created from test/mpi/f77/pt2pt/ssendf.f with f77tof90 ! ! This program is based on the allpair.f test from the MPICH-1 test ! (test/pt2pt/allpair.f), which in turn was inspired by a bug report from ! fsset@corelli.lerc.nasa.gov (Scott Townsend) program ssend - use mpi - integer ierr, errs, comm + use mpi_f08 + type(MPI_Comm) comm + integer ierr, errs logical mtestGetIntraComm logical verbose common /flags/ verbose @@ -31,12 +31,13 @@ program ssend end ! subroutine test_pair_ssend( comm, errs ) - use mpi - integer comm, errs + use mpi_f08 + type(MPI_Comm) comm + integer errs integer rank, size, ierr, next, prev, tag, count, i integer TEST_SIZE parameter (TEST_SIZE=2000) - integer status(MPI_STATUS_SIZE) + type(MPI_Status) status logical flag real send_buf(TEST_SIZE), recv_buf(TEST_SIZE) logical verbose @@ -69,8 +70,8 @@ subroutine test_pair_ssend( comm, errs ) ! if (flag) then print *, 'Ssend: Iprobe succeeded! source', & - & status(MPI_SOURCE), & - & ', tag', status(MPI_TAG) + & status%MPI_SOURCE, & + & ', tag', status%MPI_TAG errs = errs + 1 end if ! @@ -82,15 +83,15 @@ subroutine test_pair_ssend( comm, errs ) & comm, flag, status, ierr) end do ! - if (status(MPI_SOURCE) .ne. next) then + if (status%MPI_SOURCE .ne. next) then print *, 'Ssend: Incorrect source, expected', next, & - & ', got', status(MPI_SOURCE) + & ', got', status%MPI_SOURCE errs = errs + 1 end if ! - if (status(MPI_TAG) .ne. tag) then + if (status%MPI_TAG .ne. tag) then print *, 'Ssend: Incorrect tag, expected', tag, & - & ', got', status(MPI_TAG) + & ', got', status%MPI_TAG errs = errs + 1 end if ! diff --git a/test/mpi/f08/pt2pt/utilsf08.f90 b/test/mpi/f08/pt2pt/utilsf08.f90 index e8c82501d81..14a3e322ef4 100644 --- a/test/mpi/f08/pt2pt/utilsf08.f90 +++ b/test/mpi/f08/pt2pt/utilsf08.f90 @@ -4,6 +4,7 @@ ! ! This file created from test/mpi/f77/pt2pt/utilsf.f with f77tof90 +! Then manually adapted for use mpi_f08 !------------------------------------------------------------------------------ ! @@ -12,18 +13,19 @@ !------------------------------------------------------------------------------ subroutine msg_check( recv_buf, source, tag, count, status, n, & & name, errs ) - use mpi + use mpi_f08 integer n, errs real recv_buf(n) - integer source, tag, count, rank, status(MPI_STATUS_SIZE) + integer source, tag, count, rank + type(MPI_Status) status character*(*) name logical foundError integer ierr, recv_src, recv_tag, recv_count foundError = .false. - recv_src = status(MPI_SOURCE) - recv_tag = status(MPI_TAG) + recv_src = status%MPI_SOURCE + recv_tag = status%MPI_TAG call MPI_Comm_rank( MPI_COMM_WORLD, rank, ierr ) call MPI_Get_count(status, MPI_REAL, recv_count, ierr) @@ -56,8 +58,9 @@ subroutine msg_check( recv_buf, source, tag, count, status, n, & ! !------------------------------------------------------------------------------ subroutine rq_check( requests, n, msg ) - use mpi - integer n, requests(n) + use mpi_f08 + integer n + type(MPI_Request) requests(n) character*(*) msg integer i ! @@ -105,7 +108,6 @@ subroutine clear_test_data(buf, n) ! !------------------------------------------------------------------------------ subroutine verify_test_data( buf, count, n, name, errs ) - use mpi integer n, errs real buf(n) character *(*) name diff --git a/test/mpi/f08/rma/winattrf08.f90 b/test/mpi/f08/rma/winattrf08.f90 index 20e8d92a32d..721cbfc34d0 100644 --- a/test/mpi/f08/rma/winattrf08.f90 +++ b/test/mpi/f08/rma/winattrf08.f90 @@ -6,11 +6,13 @@ ! This file created from test/mpi/f77/rma/winattrf.f with f77tof90 program main - use mpi + use mpi_f08 integer errs, ierr integer (kind=MPI_ADDRESS_KIND) extrastate, valin, valout, val - integer comm, win, buf(10) + type(MPI_Comm) comm + type(MPI_Win) win + integer buf(10) integer curcount, keyval logical flag external mycopyfn, mydelfn @@ -147,8 +149,9 @@ program main ! (and because of alias rules, can be) no MPI_Win_dup function subroutine mycopyfn( oldwin, keyval, extrastate, valin, valout, & & flag, ierr ) - use mpi - integer oldwin, keyval, ierr + use mpi_f08 + type(MPI_Win) oldwin + integer keyval, ierr integer (kind=MPI_ADDRESS_KIND) extrastate, valin, valout, val logical flag @@ -165,8 +168,9 @@ subroutine mycopyfn( oldwin, keyval, extrastate, valin, valout, & end ! subroutine mydelfn( win, keyval, val, extrastate, ierr ) - use mpi - integer win, keyval, ierr + use mpi_f08 + type(MPI_Win) win + integer keyval, ierr integer (kind=MPI_ADDRESS_KIND) extrastate, valin, valout, val integer callcount, delcount diff --git a/test/mpi/f08/rma/winerrf08.f90 b/test/mpi/f08/rma/winerrf08.f90 index 99248f18aed..9c0af5c54e3 100644 --- a/test/mpi/f08/rma/winerrf08.f90 +++ b/test/mpi/f08/rma/winerrf08.f90 @@ -116,8 +116,9 @@ program main end ! subroutine myerrhanfunc( win, errcode ) - use mpi - integer win, errcode + use mpi_f08 + type(MPI_Win) win + integer errcode integer rlen, ierr integer callcount, codesSeen(3) character*(MPI_MAX_ERROR_STRING) errstring From 23d669ac152a819416ff7cb8ed882d3b25e8bc9c Mon Sep 17 00:00:00 2001 From: Gregor Corbin Date: Wed, 26 Jan 2022 17:41:16 +0100 Subject: [PATCH 342/607] test/mpi/f08: Delete createf90.f90 This file is not included in the testlist and is superseded by createf08.f90 which already has 'use mpi_f08'. --- test/mpi/f08/datatype/createf90.f90 | 68 ----------------------------- 1 file changed, 68 deletions(-) delete mode 100644 test/mpi/f08/datatype/createf90.f90 diff --git a/test/mpi/f08/datatype/createf90.f90 b/test/mpi/f08/datatype/createf90.f90 deleted file mode 100644 index 313e1c7bbe1..00000000000 --- a/test/mpi/f08/datatype/createf90.f90 +++ /dev/null @@ -1,68 +0,0 @@ -! -! Copyright (C) by Argonne National Laboratory -! See COPYRIGHT in top-level directory -! - - program main - use mpi - integer ierr - integer errs - integer nints, nadds, ndtypes, combiner - integer nparms(2), dummy(1) - integer (kind=MPI_ADDRESS_KIND) adummy(1) - integer ntype1, nsize, ntype2, ntype3, i -! -! Test the Type_create_f90_xxx routines -! - errs = 0 - call mtest_init( ierr ) - -! integers with up to 9 are 4 bytes integers; r of 4 are 2 byte, -! and r of 2 is 1 byte - call mpi_type_create_f90_integer( 9, ntype1, ierr ) -! -! Check with get contents and envelope... - call mpi_type_get_envelope( ntype1, nints, nadds, ndtypes, & - combiner, ierr ) - if (nadds .ne. 0) then - errs = errs + 1 - print *, "There should be no addresses on created type (r=9)" - endif - if (ndtypes .ne. 0) then - errs = errs + 1 - print *, "There should be no datatypes on created type (r=9)" - endif - if (nints .ne. 1) then - errs = errs + 1 - print *, "There should be exactly 1 integer on create type (r=9)" - endif - if (combiner .ne. MPI_COMBINER_F90_INTEGER) then - errs = errs + 1 - print *, "The combiner should be INTEGER, not ", combiner - endif - if (nints .eq. 1) then - call mpi_type_get_contents( ntype1, 1, 0, 0, & - nparms, adummy, dummy, ierr ) - if (nparms(1) .ne. 9) then - errs = errs + 1 - print *, "parameter was ", nparms(1), " should be 9" - endif - endif - - call mpi_type_create_f90_integer( 8, ntype2, ierr ) - if (ntype1 .eq. ntype2) then - errs = errs + 1 - print *, "Types with r = 8 and r = 9 are the same, ", & - "should be distinct" - endif - -! -! Check that we don't create new types each time. This test will fail only -! if the MPI implementation checks for un-freed types or runs out of space - do i=1, 100000 - call mpi_type_create_f90_integer( 8, ntype3, ierr ) - enddo - - call mtest_finalize( errs ) - - end From 865eb0d484073555bec7b86b04392f43f351b006 Mon Sep 17 00:00:00 2001 From: Gregor Corbin Date: Mon, 17 Jan 2022 09:36:15 +0100 Subject: [PATCH 343/607] test/mpi/f08: Fix potential handle leaks Apply the changes from issue #3962 to the F08 tests --- test/mpi/f08/pt2pt/irsendf08.f90 | 18 ++++++++++-------- test/mpi/f08/pt2pt/prsendf08.f90 | 8 ++++---- test/mpi/f08/pt2pt/pssendf08.f90 | 7 ++++--- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/test/mpi/f08/pt2pt/irsendf08.f90 b/test/mpi/f08/pt2pt/irsendf08.f90 index 8315d207e05..6837e6b8524 100644 --- a/test/mpi/f08/pt2pt/irsendf08.f90 +++ b/test/mpi/f08/pt2pt/irsendf08.f90 @@ -33,7 +33,7 @@ subroutine test_pair_irsend( comm, errs ) use mpi_f08 type(MPI_Comm) comm integer errs - integer rank, size, ierr, next, prev, tag, count, index, i + integer rank, size, ierr, next, prev, tag, count, index, completed, i integer TEST_SIZE type(MPI_Comm) dupcom parameter (TEST_SIZE=2000) @@ -79,14 +79,16 @@ subroutine test_pair_irsend( comm, errs ) call MPI_Irsend(send_buf, count, MPI_REAL, next, tag, & & comm, requests(2), ierr) ! - index = -1 - do while (index .ne. 1) - call MPI_Waitany(2, requests, index, statuses(1), ierr) + completed = 0 + do while (completed .lt. 2) + call MPI_Waitany(2, requests, index, statuses(1),ierr) + if (index .eq. 1) then + call rq_check( requests(1), 1, 'irsend and irecv' ) + call msg_check( recv_buf, next, tag, count, statuses(1), & + & TEST_SIZE, 'irsend and irecv', errs ) + end if + completed = completed + 1 end do - call rq_check( requests(1), 1, 'irsend and irecv' ) -! - call msg_check( recv_buf, next, tag, count, statuses(1), & - & TEST_SIZE, 'irsend and irecv', errs ) ! else if (prev .eq. 0) then ! diff --git a/test/mpi/f08/pt2pt/prsendf08.f90 b/test/mpi/f08/pt2pt/prsendf08.f90 index b24b8d3ccd9..a36d7fce6df 100644 --- a/test/mpi/f08/pt2pt/prsendf08.f90 +++ b/test/mpi/f08/pt2pt/prsendf08.f90 @@ -43,6 +43,7 @@ subroutine test_pair_prsend( comm, errs ) logical flag real send_buf(TEST_SIZE), recv_buf(TEST_SIZE) logical verbose + integer completed common /flags/ verbose ! if (verbose) then @@ -78,17 +79,16 @@ subroutine test_pair_prsend( comm, errs ) ! call MPI_Startall(2, requests, ierr) ! - index = -1 -! - do while (index .ne. 2) + completed = 0 + do while (completed .lt. 2) call MPI_Waitsome(2, requests, outcount, & & indices, statuses, ierr) do i = 1,outcount if (indices(i) .eq. 2) then call msg_check( recv_buf, next, tag, count, & & statuses(i), TEST_SIZE, 'waitsome', errs ) - index = 2 end if + completed = completed + 1 end do end do ! diff --git a/test/mpi/f08/pt2pt/pssendf08.f90 b/test/mpi/f08/pt2pt/pssendf08.f90 index 7656ab627f3..a5fe6639d37 100644 --- a/test/mpi/f08/pt2pt/pssendf08.f90 +++ b/test/mpi/f08/pt2pt/pssendf08.f90 @@ -43,6 +43,7 @@ subroutine test_pair_pssend( comm, errs ) logical flag real send_buf(TEST_SIZE), recv_buf(TEST_SIZE) logical verbose + integer completed common /flags/ verbose ! if (verbose) then @@ -75,16 +76,16 @@ subroutine test_pair_pssend( comm, errs ) ! call MPI_Startall(2, requests, ierr) ! - index = -1 - do while (index .ne. 1) + completed = 0 + do while (completed .lt. 2) call MPI_Testsome(2, requests, outcount, & & indices, statuses, ierr) do i = 1,outcount if (indices(i) .eq. 1) then call msg_check( recv_buf, next, tag, count, & & statuses(i), TEST_SIZE, 'testsome', errs ) - index = 1 end if + completed = completed + 1 end do end do ! From 5576fc5c93d57377e34978d0111b50855bcc748f Mon Sep 17 00:00:00 2001 From: Gregor Corbin Date: Mon, 17 Jan 2022 09:58:55 +0100 Subject: [PATCH 344/607] test/mpi/f08: Test indices returned by MPI_Waitsome etc --- test/mpi/f08/pt2pt/irsendf08.f90 | 3 +++ test/mpi/f08/pt2pt/prsendf08.f90 | 3 +++ test/mpi/f08/pt2pt/pssendf08.f90 | 3 +++ 3 files changed, 9 insertions(+) diff --git a/test/mpi/f08/pt2pt/irsendf08.f90 b/test/mpi/f08/pt2pt/irsendf08.f90 index 6837e6b8524..bbdbe0570b9 100644 --- a/test/mpi/f08/pt2pt/irsendf08.f90 +++ b/test/mpi/f08/pt2pt/irsendf08.f90 @@ -82,6 +82,9 @@ subroutine test_pair_irsend( comm, errs ) completed = 0 do while (completed .lt. 2) call MPI_Waitany(2, requests, index, statuses(1),ierr) + if (index .lt. 1 .or. index .gt. 2) then + print *, "Invalid index in MPI_Waitany:", index + end if if (index .eq. 1) then call rq_check( requests(1), 1, 'irsend and irecv' ) call msg_check( recv_buf, next, tag, count, statuses(1), & diff --git a/test/mpi/f08/pt2pt/prsendf08.f90 b/test/mpi/f08/pt2pt/prsendf08.f90 index a36d7fce6df..4a3578bf4b1 100644 --- a/test/mpi/f08/pt2pt/prsendf08.f90 +++ b/test/mpi/f08/pt2pt/prsendf08.f90 @@ -84,6 +84,9 @@ subroutine test_pair_prsend( comm, errs ) call MPI_Waitsome(2, requests, outcount, & & indices, statuses, ierr) do i = 1,outcount + if (indices(i) .lt. 1 .or. indices(i) .gt. 2) then + print *, "Invalid index in array_of_indices of MPI_Waitsome:", indices(i) + end if if (indices(i) .eq. 2) then call msg_check( recv_buf, next, tag, count, & & statuses(i), TEST_SIZE, 'waitsome', errs ) diff --git a/test/mpi/f08/pt2pt/pssendf08.f90 b/test/mpi/f08/pt2pt/pssendf08.f90 index a5fe6639d37..aeb48e94c14 100644 --- a/test/mpi/f08/pt2pt/pssendf08.f90 +++ b/test/mpi/f08/pt2pt/pssendf08.f90 @@ -81,6 +81,9 @@ subroutine test_pair_pssend( comm, errs ) call MPI_Testsome(2, requests, outcount, & & indices, statuses, ierr) do i = 1,outcount + if (indices(i) .lt. 1 .or. indices(i) .gt. 2) then + print *, "Invalid index in array_of_indices of MPI_Testsome:", indices(i) + end if if (indices(i) .eq. 1) then call msg_check( recv_buf, next, tag, count, & & statuses(i), TEST_SIZE, 'testsome', errs ) From a0b1700b65af5e088ae9c6242a961a47a47a4e12 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Mon, 29 Nov 2021 15:26:44 -0600 Subject: [PATCH 345/607] test/mpi/fortran: Fix tests that did not finalize The AddressSanitizer complained that these tests leaked memory because MPI was not properly finalized. Use mtest utilities to avoid open coding the error reporting logic at the end of the tests. --- test/mpi/f08/attr/fandcattrf08.f90 | 8 ++------ test/mpi/f08/io/c2f2ciof90.f90 | 18 ++++-------------- test/mpi/f08/misc/sizeof2.f90 | 8 ++------ test/mpi/f08/rma/c2f2cwinf08.f90 | 17 +++-------------- test/mpi/f08/timer/wtimef90.f90 | 8 ++++---- 5 files changed, 15 insertions(+), 44 deletions(-) diff --git a/test/mpi/f08/attr/fandcattrf08.f90 b/test/mpi/f08/attr/fandcattrf08.f90 index 1ea40ef6513..0f85a479f47 100644 --- a/test/mpi/f08/attr/fandcattrf08.f90 +++ b/test/mpi/f08/attr/fandcattrf08.f90 @@ -23,7 +23,7 @@ program main delcount = 0 errs = 0 - call mpi_init(ierr) + call mtest_init(ierr) commextra = 1001 call mpi_comm_create_keyval( mycopyfn, mydelfn, & & fcomm2_keyval, commextra, ierr ) @@ -48,11 +48,7 @@ program main call mpi_type_free_keyval( ctype2_keyval, ierr ) call mpi_win_free_keyval( cwin2_keyval, ierr ) - if (errs .eq. 0) then - print *, ' No Errors' - else - print *, ' Found ', errs, ' errors' - endif + call mtest_finalize( errs ) end ! diff --git a/test/mpi/f08/io/c2f2ciof90.f90 b/test/mpi/f08/io/c2f2ciof90.f90 index e8b9547bc40..c4da206d803 100644 --- a/test/mpi/f08/io/c2f2ciof90.f90 +++ b/test/mpi/f08/io/c2f2ciof90.f90 @@ -6,7 +6,7 @@ ! Test just the MPI-IO FILE object program main use mpi_f08 - integer errs, toterrs, ierr + integer errs, ierr integer wrank type(MPI_Group) wgroup integer fsize, frank @@ -18,7 +18,7 @@ program main errs = 0 - call mpi_init( ierr ) + call mtest_init( ierr ) call mpi_comm_rank( MPI_COMM_WORLD, wrank, ierr ) call mpi_comm_group( MPI_COMM_WORLD, wgroup, ierr ) @@ -44,18 +44,8 @@ program main call mpi_group_free( group, ierr ) call mpi_group_free( wgroup, ierr ) call mpi_file_close( file, ierr ) -! -! Summarize the errors -! - call mpi_allreduce( errs, toterrs, 1, MPI_INTEGER, MPI_SUM, & - & MPI_COMM_WORLD, ierr ) - if (wrank .eq. 0) then - if (toterrs .eq. 0) then - print *, ' No Errors' - else - print *, ' Found ', toterrs, ' errors' - endif - endif + + call mtest_finalize( errs ) end diff --git a/test/mpi/f08/misc/sizeof2.f90 b/test/mpi/f08/misc/sizeof2.f90 index eef302e374c..d6453715d6e 100644 --- a/test/mpi/f08/misc/sizeof2.f90 +++ b/test/mpi/f08/misc/sizeof2.f90 @@ -13,7 +13,7 @@ program main complex c errs = 0 - call mpi_init(ierr) + call mtest_init(ierr) size1 = storage_size(errs) / 8 call mpi_type_size( MPI_INTEGER, size2, ierr ) if (size1 .ne. size2) then @@ -49,10 +49,6 @@ program main print *, "real array size is ", size2, " storage_size claims ", size1 endif - if (errs .gt. 0) then - print *, ' Found ', errs, ' errors' - else - print *, ' No Errors' - endif + call mtest_finalize( errs ) end program main diff --git a/test/mpi/f08/rma/c2f2cwinf08.f90 b/test/mpi/f08/rma/c2f2cwinf08.f90 index e8d1e9ffb10..8c2bcfcb947 100644 --- a/test/mpi/f08/rma/c2f2cwinf08.f90 +++ b/test/mpi/f08/rma/c2f2cwinf08.f90 @@ -9,7 +9,7 @@ ! program main use mpi_f08 - integer errs, toterrs, ierr + integer errs, ierr integer wrank, wsize integer wgroup, info, req TYPE(MPI_Win) win @@ -20,7 +20,7 @@ program main errs = 0 - call mpi_init( ierr ) + call mtest_init( ierr ) ! ! Test passing a Fortran MPI object to C @@ -38,18 +38,7 @@ program main ! displacement unit 1 call mpi_win_free( win, ierr ) -! -! Summarize the errors -! - call mpi_allreduce( errs, toterrs, 1, MPI_INTEGER, MPI_SUM, & - & MPI_COMM_WORLD, ierr ) - if (wrank .eq. 0) then - if (toterrs .eq. 0) then - print *, ' No Errors' - else - print *, ' Found ', toterrs, ' errors' - endif - endif + call mtest_finalize( errs ) end diff --git a/test/mpi/f08/timer/wtimef90.f90 b/test/mpi/f08/timer/wtimef90.f90 index f7ce3d64521..190a35e5781 100644 --- a/test/mpi/f08/timer/wtimef90.f90 +++ b/test/mpi/f08/timer/wtimef90.f90 @@ -13,7 +13,7 @@ program main integer err double precision time1 - call mpi_init(err) + call mtest_init(err) time1 = mpi_wtime() time1 = time1 + mpi_wtick() @@ -24,9 +24,9 @@ program main ! including these operations ensures that a buggy compiler doesn't ! pass this test by mistake). if (time1 .lt. 0.0d0) then - print *, ' Negative time result' - else - print *, ' No Errors' + err = 1 endif + call mtest_finalize(err) + end From f194fc8d81428173969f09c6c11146417a9c0a7a Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 30 Nov 2021 15:04:42 -0600 Subject: [PATCH 346/607] test/mpi/fortran: Use mtest_init for consistency These tests used mpi_init paired with mtest_finalize. This works, but could cause issues in in the future if mtest_finalize comes to rely on something setup in mtest_init. --- test/mpi/f08/ext/c2f2cf90.f90 | 2 +- test/mpi/f77/attr/commattr4f.f | 2 +- test/mpi/f77/ext/c2f2cf.f | 2 +- test/mpi/f77/io/c2f2ciof.f | 2 +- test/mpi/f77/rma/c2f2cwinf.f | 2 +- test/mpi/f90/attr/fandcattrf90.f90 | 2 +- test/mpi/f90/misc/sizeof2.f90 | 2 +- test/mpi/f90/timer/wtimef90.f90 | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/mpi/f08/ext/c2f2cf90.f90 b/test/mpi/f08/ext/c2f2cf90.f90 index ed9efef6df7..2e19d1b69bf 100644 --- a/test/mpi/f08/ext/c2f2cf90.f90 +++ b/test/mpi/f08/ext/c2f2cf90.f90 @@ -27,7 +27,7 @@ program main logical flag errs = 0 - call mpi_init( ierr ) + call mtest_init( ierr ) ! ! Test passing a Fortran MPI object to C diff --git a/test/mpi/f77/attr/commattr4f.f b/test/mpi/f77/attr/commattr4f.f index 86df0432b88..94f216a7f75 100644 --- a/test/mpi/f77/attr/commattr4f.f +++ b/test/mpi/f77/attr/commattr4f.f @@ -18,7 +18,7 @@ program main C C initialize the mpi environment C - call mpi_init(ierr) + call mtest_init(ierr) call mpi_comm_create_keyval(MPI_COMM_DUP_FN, $ MPI_NULL_DELETE_FN, diff --git a/test/mpi/f77/ext/c2f2cf.f b/test/mpi/f77/ext/c2f2cf.f index 3c31edd2bed..4bb83c43317 100644 --- a/test/mpi/f77/ext/c2f2cf.f +++ b/test/mpi/f77/ext/c2f2cf.f @@ -17,7 +17,7 @@ program main logical flag errs = 0 - call mpi_init( ierr ) + call mtest_init( ierr ) C C Test passing a Fortran MPI object to C diff --git a/test/mpi/f77/io/c2f2ciof.f b/test/mpi/f77/io/c2f2ciof.f index 431c68343d0..464e0bba3cb 100644 --- a/test/mpi/f77/io/c2f2ciof.f +++ b/test/mpi/f77/io/c2f2ciof.f @@ -16,7 +16,7 @@ program main errs = 0 - call mpi_init( ierr ) + call mtest_init( ierr ) call mpi_comm_rank( MPI_COMM_WORLD, wrank, ierr ) call mpi_comm_group( MPI_COMM_WORLD, wgroup, ierr ) diff --git a/test/mpi/f77/rma/c2f2cwinf.f b/test/mpi/f77/rma/c2f2cwinf.f index 679b5f1afc6..367a15691d6 100644 --- a/test/mpi/f77/rma/c2f2cwinf.f +++ b/test/mpi/f77/rma/c2f2cwinf.f @@ -15,7 +15,7 @@ program main include 'addsize.h' errs = 0 - call mpi_init( ierr ) + call mtest_init( ierr ) C C Test passing a Fortran MPI object to C diff --git a/test/mpi/f90/attr/fandcattrf90.f90 b/test/mpi/f90/attr/fandcattrf90.f90 index 0846a8857ee..df25118b25e 100644 --- a/test/mpi/f90/attr/fandcattrf90.f90 +++ b/test/mpi/f90/attr/fandcattrf90.f90 @@ -22,7 +22,7 @@ program main delcount = 0 errs = 0 - call mpi_init(ierr) + call mtest_init(ierr) commextra = 1001 call mpi_comm_create_keyval( mycopyfn, mydelfn, & & fcomm2_keyval, commextra, ierr ) diff --git a/test/mpi/f90/misc/sizeof2.f90 b/test/mpi/f90/misc/sizeof2.f90 index fe1eb4985c3..4fb5655b7eb 100644 --- a/test/mpi/f90/misc/sizeof2.f90 +++ b/test/mpi/f90/misc/sizeof2.f90 @@ -13,7 +13,7 @@ program main complex c errs = 0 - call mpi_init(ierr) + call mtest_init(ierr) call mpi_sizeof( errs, size1, ierr ) call mpi_type_size( MPI_INTEGER, size2, ierr ) if (size1 .ne. size2) then diff --git a/test/mpi/f90/timer/wtimef90.f90 b/test/mpi/f90/timer/wtimef90.f90 index 1a0096c94c0..f81f9cdd39f 100644 --- a/test/mpi/f90/timer/wtimef90.f90 +++ b/test/mpi/f90/timer/wtimef90.f90 @@ -13,7 +13,7 @@ program main integer err double precision time1 - call mpi_init(err) + call mtest_init(err) time1 = mpi_wtime() time1 = time1 + mpi_wtick() From 6dc8b9884b8cd255482b63f2d8d7e86588ff5ab4 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 14 Jan 2022 10:30:45 -0600 Subject: [PATCH 347/607] f08: convert INDEX on input/output Fortran uses 1-based indexing while C uses 0-based. We need add conversions on input and output. --- maint/local_python/binding_f08.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/maint/local_python/binding_f08.py b/maint/local_python/binding_f08.py index dd7a9f2cdc0..e6dfb660a2f 100644 --- a/maint/local_python/binding_f08.py +++ b/maint/local_python/binding_f08.py @@ -310,6 +310,14 @@ def process_logical(p): convert_list_post.append("%s = (%s /= 0)" % (p['name'], arg)) return (arg, arg) + def process_index(p): + arg = "%s_c" % p['name'] + if p['param_direction'] == 'in' or p['param_direction'] == 'inout': + convert_list_pre.append("%s = %s - 1" % (arg, p['name'])) + if p['param_direction'] == 'out' or p['param_direction'] == 'inout': + convert_list_post.append("%s = %s + 1" % (p['name'], arg)) + return (arg, arg) + def process_string(p): arg = "%s_c" % p['name'] @@ -481,6 +489,13 @@ def process_array(p): convert_list_pre.append("%s = merge(1, 0, %s)" % (arg_2, p['name'])) if RE.match(r'out|inout', p['param_direction']): convert_list_post.append("%s = (%s /= 0)" % (p['name'], arg_2)) + elif p['_array_convert'] == "INDEX": + arg_1 = "%s_c" % p['name'] + arg_2 = "%s_c" % p['name'] + if RE.match(r'MPI_(Wait|Test)some', func['name'], re.IGNORECASE): + convert_list_post.append("%s(1:outcount) = %s(1:outcount) + 1" % (p['name'], arg_2)) + else: + raise Exception("Unexpected in process_array: %s" % func['name']) elif RE.match(r'allocate:(.+)', p['_array_convert']): # The length variable name is_MPI_VAL = (RE.m.group(1) == 'MPI_VAL') @@ -625,6 +640,8 @@ def post_string_len(v): (arg_1, arg_2) = process_array(p) elif p['kind'] == "LOGICAL" or p['kind'] == "LOGICAL_BOOLEAN": (arg_1, arg_2) = process_logical(p) + elif p['kind'] == "INDEX" and re.match(r'MPI_(Test|Wait)any', func['name'], re.IGNORECASE): + (arg_1, arg_2) = process_index(p) elif f08_mapping[p['kind']] == "PROCEDURE": (arg_1, arg_2) = process_procedure(p) elif p['kind'] == 'FILE': @@ -1522,6 +1539,9 @@ def get_array_decl(): c_type = "c_" + t[0].upper() + t[1:].lower() p['_array_convert'] = "MPI_VAL" return "INTEGER(%s) :: %s_c(%s)" % (c_type, p['name'], length) + elif p['kind'] == "INDEX" and re.match(r'MPI_(Test|Wait)some', func['name'], re.IGNORECASE): + p['_array_convert'] = "INDEX" + return "INTEGER(c_int) :: %s_c(%s)" % (p['name'], length) elif p['kind'] == "LOGICAL": p['_array_convert'] = "LOGICAL" return "INTEGER(c_int) :: %s_c(%s)" % (p['name'], length) From 0a79a08aaead39bb8d7d9b48f419528085b0954c Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 27 Jan 2022 10:30:01 -0600 Subject: [PATCH 348/607] f08: better exception text The original text was slightly confusing. --- maint/local_python/binding_f08.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maint/local_python/binding_f08.py b/maint/local_python/binding_f08.py index e6dfb660a2f..36b032f4e74 100644 --- a/maint/local_python/binding_f08.py +++ b/maint/local_python/binding_f08.py @@ -495,7 +495,7 @@ def process_array(p): if RE.match(r'MPI_(Wait|Test)some', func['name'], re.IGNORECASE): convert_list_post.append("%s(1:outcount) = %s(1:outcount) + 1" % (p['name'], arg_2)) else: - raise Exception("Unexpected in process_array: %s" % func['name']) + raise Exception("Unexpected function encountered in process_array: %s" % func['name']) elif RE.match(r'allocate:(.+)', p['_array_convert']): # The length variable name is_MPI_VAL = (RE.m.group(1) == 'MPI_VAL') From 5b6f05e6e0b1aa181ac75144ed1c8cb7cbe08449 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 25 Jan 2022 22:18:14 -0600 Subject: [PATCH 349/607] confdb: add PAC_C_NO_COMMON Add macro to check and apply -fno-common. This will fix the static linking issues on macos due to missing common symbols in static library. --- confdb/aclocal_cc.m4 | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/confdb/aclocal_cc.m4 b/confdb/aclocal_cc.m4 index d30e809fe20..fefd2c3d694 100644 --- a/confdb/aclocal_cc.m4 +++ b/confdb/aclocal_cc.m4 @@ -1597,3 +1597,20 @@ AC_DEFUN([PAC_ARG_ATOMIC_PRIMITIVES], [ lock - Mutex-based synchronization no|none - atomic operations are performed without synchronization ],,with_mpl_atomic_primitives=auto)]) + +dnl +dnl Check whether C compiler accepts -fno-common, if yes, add to CFLAGS. +dnl +dnl NOTE: standard C does not need common symbols. Use of common symbols +dnl may bring issues on some systems, e.g. macos building static libraries. +dnl As an anecodote, gcc starting with gcc-10 default to -fno-common. +dnl +dnl In the past we have added unnecessary initializers to global variables +dnl to force not to generate common symbols. This macro obviates those fixes. +dnl +AC_DEFUN([PAC_C_NO_COMMON],[ + # TODO: check if -fno-common is the default and skip + PAC_C_CHECK_COMPILER_OPTION([-fno-common], + [PAC_APPEND_FLAG([-fno-common], [CFLAGS])], + [:]) +]) From 35cb3085f2f2842a6c5e60a0c1dd36192cdb1d29 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 25 Jan 2022 22:21:23 -0600 Subject: [PATCH 350/607] configure: apply PAC_C_NO_COMMON This should fix the osx static linking issue. --- configure.ac | 1 + src/mpi/romio/configure.ac | 1 + src/mpl/configure.ac | 1 + src/pm/hydra/configure.ac | 1 + 4 files changed, 4 insertions(+) diff --git a/configure.ac b/configure.ac index 70ba472a0df..cfec2dec810 100644 --- a/configure.ac +++ b/configure.ac @@ -643,6 +643,7 @@ fi PAC_POP_FLAG([CFLAGS]) AC_USE_SYSTEM_EXTENSIONS +PAC_C_NO_COMMON dnl now that autoconf and core compilers are setup, init automake and libtool dnl diff --git a/src/mpi/romio/configure.ac b/src/mpi/romio/configure.ac index 6d1a887490b..ed801b2f235 100644 --- a/src/mpi/romio/configure.ac +++ b/src/mpi/romio/configure.ac @@ -37,6 +37,7 @@ PAC_CHECK_VISIBILITY AC_SUBST(VISIBILITY_CFLAGS) AC_USE_SYSTEM_EXTENSIONS +PAC_C_NO_COMMON AM_PROG_AR diff --git a/src/mpl/configure.ac b/src/mpl/configure.ac index 5240f5a8c07..84a53ee3213 100644 --- a/src/mpl/configure.ac +++ b/src/mpl/configure.ac @@ -20,6 +20,7 @@ AC_PROG_CC_C99 AM_PROG_CC_C_O AC_USE_SYSTEM_EXTENSIONS +PAC_C_NO_COMMON AM_PROG_AR diff --git a/src/pm/hydra/configure.ac b/src/pm/hydra/configure.ac index c296339d7d2..679fc023403 100644 --- a/src/pm/hydra/configure.ac +++ b/src/pm/hydra/configure.ac @@ -26,6 +26,7 @@ AM_PROG_CC_C_O # also needed by hwloc in embedded mode, must also come early for expansion # ordering reasons AC_USE_SYSTEM_EXTENSIONS +PAC_C_NO_COMMON AM_INIT_AUTOMAKE([-Wall -Wno-portability-recursive -Werror foreign 1.12.3 subdir-objects no-dist]) From a684f0fd9ca1b09ac36d1f03b848cba0a4b53581 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 26 Jan 2022 21:31:27 -0600 Subject: [PATCH 351/607] confdb: only add -fno-common on macos So far, only macos has issues with common symbols when building static libraries. --- confdb/aclocal_cc.m4 | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/confdb/aclocal_cc.m4 b/confdb/aclocal_cc.m4 index fefd2c3d694..4f5e8394f5a 100644 --- a/confdb/aclocal_cc.m4 +++ b/confdb/aclocal_cc.m4 @@ -1599,7 +1599,7 @@ AC_DEFUN([PAC_ARG_ATOMIC_PRIMITIVES], [ ],,with_mpl_atomic_primitives=auto)]) dnl -dnl Check whether C compiler accepts -fno-common, if yes, add to CFLAGS. +dnl On macos, check whether C compiler accepts -fno-common, if yes, add to CFLAGS. dnl dnl NOTE: standard C does not need common symbols. Use of common symbols dnl may bring issues on some systems, e.g. macos building static libraries. @@ -1609,8 +1609,12 @@ dnl In the past we have added unnecessary initializers to global variables dnl to force not to generate common symbols. This macro obviates those fixes. dnl AC_DEFUN([PAC_C_NO_COMMON],[ - # TODO: check if -fno-common is the default and skip - PAC_C_CHECK_COMPILER_OPTION([-fno-common], - [PAC_APPEND_FLAG([-fno-common], [CFLAGS])], - [:]) + # Add -fno-common on macos to bypass its bad handling of common symbols + case $host in + *-*-darwin*) + PAC_C_CHECK_COMPILER_OPTION([-fno-common], + [PAC_APPEND_FLAG([-fno-common], [CFLAGS])], + [:]) + ;; + esac ]) From 63a2b0e431e50cdf9b01ed0098c7eda790c67775 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 20 Jan 2022 10:43:33 -0600 Subject: [PATCH 352/607] mpl: add MPL_log2 We need calculate power of 2 or log of 2 often. Add the MPL routine that may use the builtin instruction when available. --- confdb/aclocal_cc.m4 | 15 +++++++++++++++ src/mpl/configure.ac | 1 + src/mpl/include/mpl_math.h | 29 ++++++++++++++++++++++------- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/confdb/aclocal_cc.m4 b/confdb/aclocal_cc.m4 index 4f5e8394f5a..21920501833 100644 --- a/confdb/aclocal_cc.m4 +++ b/confdb/aclocal_cc.m4 @@ -1512,6 +1512,21 @@ if test x$have_builtin_expect = xyes ; then fi ]) +dnl +dnl Will AC_DEFINE([HAVE_BUILTIN_CLZ]) if the compiler supports __builtin_clz. +dnl +AC_DEFUN([PAC_C_BUILTIN_CLZ],[ + AC_MSG_CHECKING([if C compiler supports __builtin_clz]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[[ + return __builtin_clz(0) + ]])], [ + AC_DEFINE([HAVE_BUILTIN_CLZ], [1], [Define to 1 if the compiler supports __builtin_clz.]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + dnl dnl PAC_C_STATIC_ASSERT - Test whether C11 _Static_assert is supported dnl diff --git a/src/mpl/configure.ac b/src/mpl/configure.ac index 84a53ee3213..87e53fc6fc2 100644 --- a/src/mpl/configure.ac +++ b/src/mpl/configure.ac @@ -57,6 +57,7 @@ AC_C_INLINE PAC_C_MACRO_VA_ARGS PAC_C_BUILTIN_EXPECT +PAC_C_BUILTIN_CLZ PAC_C_STATIC_ASSERT AC_ARG_ENABLE(embedded, diff --git a/src/mpl/include/mpl_math.h b/src/mpl/include/mpl_math.h index 7d19653c486..547b7c4269e 100644 --- a/src/mpl/include/mpl_math.h +++ b/src/mpl/include/mpl_math.h @@ -14,16 +14,31 @@ extern "C" { #define MPL_DIV_ROUNDUP(total, chunk) ((total + (chunk - 1)) / chunk) -/* Returns the nearest (smaller than or equal to) power of two of a number*/ -static inline int MPL_pof2(int number) +/* Returns int(log2(number)) */ +static inline int MPL_log2(int number) { - int pof2 = 1; +#ifndef MPL_HAVE_BUILTIN_CLZ + int p = 0; - while (pof2 <= number) - pof2 <<= 1; - pof2 >>= 1; + while (number > 0) { + number >>= 1; + p++; + } + return p - 1; +#else + /* NOTE: if number < 0, the result is undefined. Add assertion if necessary. */ + return sizeof(unsigned int) * 8 - __builtin_clz((unsigned int) number) - 1; +#endif +} - return pof2; +/* Returns the nearest (smaller than or equal to) power of two of a number*/ +static inline int MPL_pof2(int number) +{ + if (number > 0) { + return 1 << MPL_log2(number); + } else { + return 0; + } } /* Returns non-zero if val is a power of two. If ceil_pof2 is non-NULL, it sets From 3190baf0d10591de519ae311ae3fa4658a994fba Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 20 Jan 2022 10:59:52 -0600 Subject: [PATCH 353/607] mpl: remove the extra param from MPL_is_pof2 The extra return of ceil_pof2 is never needed. It clutters code and prevent optimization of MPL_is_pof2 since otherwise, it can just return __buitin_popcount(val) == 1. --- src/mpi/coll/bcast/bcast_intra_smp.c | 2 +- src/mpi/coll/ialltoall/ialltoall_intra_sched_pairwise.c | 2 +- ...bcast_intra_sched_scatter_recursive_doubling_allgather.c | 2 +- src/mpi/coll/mpir_coll_sched_auto.c | 6 +++--- src/mpl/include/mpl_math.h | 6 ++---- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/mpi/coll/bcast/bcast_intra_smp.c b/src/mpi/coll/bcast/bcast_intra_smp.c index 60865ac721d..cfe935137fa 100644 --- a/src/mpi/coll/bcast/bcast_intra_smp.c +++ b/src/mpi/coll/bcast/bcast_intra_smp.c @@ -110,7 +110,7 @@ int MPIR_Bcast_intra_smp(void *buffer, MPI_Aint count, MPI_Datatype datatype, in /* supposedly... * smp+doubling good for pof2 * reg+ring better for non-pof2 */ - if (nbytes < MPIR_CVAR_BCAST_LONG_MSG_SIZE && MPL_is_pof2(comm_ptr->local_size, NULL)) { + if (nbytes < MPIR_CVAR_BCAST_LONG_MSG_SIZE && MPL_is_pof2(comm_ptr->local_size)) { /* medium-sized msg and pof2 np */ /* perform the intranode broadcast on the root's node */ diff --git a/src/mpi/coll/ialltoall/ialltoall_intra_sched_pairwise.c b/src/mpi/coll/ialltoall/ialltoall_intra_sched_pairwise.c index e7f61d64bc3..1f953411065 100644 --- a/src/mpi/coll/ialltoall/ialltoall_intra_sched_pairwise.c +++ b/src/mpi/coll/ialltoall/ialltoall_intra_sched_pairwise.c @@ -49,7 +49,7 @@ int MPIR_Ialltoall_intra_sched_pairwise(const void *sendbuf, MPI_Aint sendcount, recvcount, recvtype, s); MPIR_ERR_CHECK(mpi_errno); - is_pof2 = MPL_is_pof2(comm_size, NULL); + is_pof2 = MPL_is_pof2(comm_size); /* Do the pairwise exchanges */ for (i = 1; i < comm_size; i++) { diff --git a/src/mpi/coll/ibcast/ibcast_intra_sched_scatter_recursive_doubling_allgather.c b/src/mpi/coll/ibcast/ibcast_intra_sched_scatter_recursive_doubling_allgather.c index 6359dad81fa..cd55ea2fc79 100644 --- a/src/mpi/coll/ibcast/ibcast_intra_sched_scatter_recursive_doubling_allgather.c +++ b/src/mpi/coll/ibcast/ibcast_intra_sched_scatter_recursive_doubling_allgather.c @@ -69,7 +69,7 @@ int MPIR_Ibcast_intra_sched_scatter_recursive_doubling_allgather(void *buffer, M #ifdef HAVE_ERROR_CHECKING /* This algorithm can currently handle only power of 2 cases, * non-power of 2 is still experimental */ - MPIR_Assert(MPL_is_pof2(comm_size, NULL)); + MPIR_Assert(MPL_is_pof2(comm_size)); #endif /* HAVE_ERROR_CHECKING */ if (HANDLE_IS_BUILTIN(datatype)) { diff --git a/src/mpi/coll/mpir_coll_sched_auto.c b/src/mpi/coll/mpir_coll_sched_auto.c index 35e6c508b9c..d2125b40610 100644 --- a/src/mpi/coll/mpir_coll_sched_auto.c +++ b/src/mpi/coll/mpir_coll_sched_auto.c @@ -59,7 +59,7 @@ int MPIR_Ibcast_intra_sched_auto(void *buffer, MPI_Aint count, MPI_Datatype data MPIR_ERR_CHECK(mpi_errno); } else { /* (nbytes >= MPIR_CVAR_BCAST_SHORT_MSG_SIZE) && (comm_size >= MPIR_CVAR_BCAST_MIN_PROCS) */ - if ((nbytes < MPIR_CVAR_BCAST_LONG_MSG_SIZE) && (MPL_is_pof2(comm_size, NULL))) { + if ((nbytes < MPIR_CVAR_BCAST_LONG_MSG_SIZE) && (MPL_is_pof2(comm_size))) { mpi_errno = MPIR_Ibcast_intra_sched_scatter_recursive_doubling_allgather(buffer, count, datatype, root, @@ -678,7 +678,7 @@ int MPIR_Ireduce_scatter_intra_sched_auto(const void *sendbuf, void *recvbuf, } } - if (MPL_is_pof2(comm_size, NULL) && is_block_regular) { + if (MPL_is_pof2(comm_size) && is_block_regular) { /* noncommutative, pof2 size, and block regular */ mpi_errno = MPIR_Ireduce_scatter_intra_sched_noncommutative(sendbuf, recvbuf, recvcounts, @@ -744,7 +744,7 @@ int MPIR_Ireduce_scatter_block_intra_sched_auto(const void *sendbuf, void *recvb MPIR_ERR_CHECK(mpi_errno); } else { /* (!is_commutative) */ - if (MPL_is_pof2(comm_size, NULL)) { + if (MPL_is_pof2(comm_size)) { /* noncommutative, pof2 size */ mpi_errno = MPIR_Ireduce_scatter_block_intra_sched_noncommutative(sendbuf, recvbuf, recvcount, diff --git a/src/mpl/include/mpl_math.h b/src/mpl/include/mpl_math.h index 547b7c4269e..29736ab9480 100644 --- a/src/mpl/include/mpl_math.h +++ b/src/mpl/include/mpl_math.h @@ -41,10 +41,8 @@ static inline int MPL_pof2(int number) } } -/* Returns non-zero if val is a power of two. If ceil_pof2 is non-NULL, it sets - *ceil_pof2 to the power of two that is just larger than or equal to val. - That is, it rounds up to the nearest power of two. */ -static inline int MPL_is_pof2(int val, int *ceil_pof2) +/* Returns non-zero if val is a power of two. */ +static inline int MPL_is_pof2(int val) { int pof2 = 1; From ba339cf071a1d2f6da1b81f0ec62efe6a58f9e29 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 20 Jan 2022 11:04:56 -0600 Subject: [PATCH 354/607] mpl: optimize MPL_is_pof2 using __builtin_popcount Use __builtin_popcount when it is available. --- confdb/aclocal_cc.m4 | 15 +++++++++++++++ src/mpl/configure.ac | 1 + src/mpl/include/mpl_math.h | 6 ++++-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/confdb/aclocal_cc.m4 b/confdb/aclocal_cc.m4 index 21920501833..762ad36f003 100644 --- a/confdb/aclocal_cc.m4 +++ b/confdb/aclocal_cc.m4 @@ -1527,6 +1527,21 @@ AC_DEFUN([PAC_C_BUILTIN_CLZ],[ ]) ]) +dnl +dnl Will AC_DEFINE([HAVE_BUILTIN_POPCOUNT]) if the compiler supports __builtin_clz. +dnl +AC_DEFUN([PAC_C_BUILTIN_POPCOUNT],[ + AC_MSG_CHECKING([if C compiler supports __builtin_popcount]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[[ + return __builtin_popcount(0) + ]])], [ + AC_DEFINE([HAVE_BUILTIN_POPCOUNT], [1], [Define to 1 if the compiler supports __builtin_popcount.]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + dnl dnl PAC_C_STATIC_ASSERT - Test whether C11 _Static_assert is supported dnl diff --git a/src/mpl/configure.ac b/src/mpl/configure.ac index 87e53fc6fc2..d45b7b92af0 100644 --- a/src/mpl/configure.ac +++ b/src/mpl/configure.ac @@ -58,6 +58,7 @@ AC_C_INLINE PAC_C_MACRO_VA_ARGS PAC_C_BUILTIN_EXPECT PAC_C_BUILTIN_CLZ +PAC_C_BUILTIN_POPCOUNT PAC_C_STATIC_ASSERT AC_ARG_ENABLE(embedded, diff --git a/src/mpl/include/mpl_math.h b/src/mpl/include/mpl_math.h index 29736ab9480..65ace4b4208 100644 --- a/src/mpl/include/mpl_math.h +++ b/src/mpl/include/mpl_math.h @@ -44,17 +44,19 @@ static inline int MPL_pof2(int number) /* Returns non-zero if val is a power of two. */ static inline int MPL_is_pof2(int val) { +#ifndef MPL_HAVE_BUILTIN_POPCOUNT int pof2 = 1; while (pof2 < val) pof2 *= 2; - if (ceil_pof2) - *ceil_pof2 = pof2; if (pof2 == val) return 1; else return 0; +#else + return __builtin_popcount((unsigned int) val) == 1; +#endif } /* Routing to calculate base^exp for integers */ From 0e33c94ab80641d24e182661bbe31124636c1839 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 20 Jan 2022 11:26:36 -0600 Subject: [PATCH 355/607] coll: use MPL_pof2 and MPL_log2 Use MPL_pof2 and MPL_log2 where we can. This reduces code clutter and provide optimization when it is available. --- src/mpi/coll/alltoall/alltoall_intra_pairwise.c | 13 ++++--------- .../ireduce_scatter_intra_sched_noncommutative.c | 12 +++--------- ...educe_scatter_block_intra_sched_noncommutative.c | 12 +++--------- ...ce_scatter_block_intra_sched_recursive_halving.c | 6 +----- .../reduce_scatter_intra_noncommutative.c | 12 +++--------- .../reduce_scatter_intra_recursive_doubling.c | 5 +++-- .../reduce_scatter_block_intra_noncommutative.c | 12 +++--------- 7 files changed, 20 insertions(+), 52 deletions(-) diff --git a/src/mpi/coll/alltoall/alltoall_intra_pairwise.c b/src/mpi/coll/alltoall/alltoall_intra_pairwise.c index f2d43421d2b..738ac80ccf6 100644 --- a/src/mpi/coll/alltoall/alltoall_intra_pairwise.c +++ b/src/mpi/coll/alltoall/alltoall_intra_pairwise.c @@ -30,7 +30,7 @@ int MPIR_Alltoall_intra_pairwise(const void *sendbuf, MPI_Datatype recvtype, MPIR_Comm * comm_ptr, MPIR_Errflag_t * errflag) { - int comm_size, i, pof2; + int comm_size, i; MPI_Aint sendtype_extent, recvtype_extent; int mpi_errno = MPI_SUCCESS, src, dst, rank; int mpi_errno_ret = MPI_SUCCESS; @@ -56,17 +56,12 @@ int MPIR_Alltoall_intra_pairwise(const void *sendbuf, MPIR_ERR_CHECK(mpi_errno); /* Is comm_size a power-of-two? */ - i = 1; - while (i < comm_size) - i *= 2; - if (i == comm_size) - pof2 = 1; - else - pof2 = 0; + int is_pof2; + is_pof2 = MPL_is_pof2(comm_size); /* Do the pairwise exchanges */ for (i = 1; i < comm_size; i++) { - if (pof2 == 1) { + if (is_pof2) { /* use exclusive-or algorithm */ src = dst = rank ^ i; } else { diff --git a/src/mpi/coll/ireduce_scatter/ireduce_scatter_intra_sched_noncommutative.c b/src/mpi/coll/ireduce_scatter/ireduce_scatter_intra_sched_noncommutative.c index 7f0b5207568..c72aeff97ea 100644 --- a/src/mpi/coll/ireduce_scatter/ireduce_scatter_intra_sched_noncommutative.c +++ b/src/mpi/coll/ireduce_scatter/ireduce_scatter_intra_sched_noncommutative.c @@ -28,7 +28,6 @@ int MPIR_Ireduce_scatter_intra_sched_noncommutative(const void *sendbuf, void *r int mpi_errno = MPI_SUCCESS; int comm_size = comm_ptr->local_size; int rank = comm_ptr->rank; - int pof2; int log2_comm_size; int i, k; int recv_offset, send_offset; @@ -41,16 +40,9 @@ int MPIR_Ireduce_scatter_intra_sched_noncommutative(const void *sendbuf, void *r MPIR_Type_get_true_extent_impl(datatype, &true_lb, &true_extent); - pof2 = 1; - log2_comm_size = 0; - while (pof2 < comm_size) { - pof2 <<= 1; - ++log2_comm_size; - } - #ifdef HAVE_ERROR_CHECKING /* begin error checking */ - MPIR_Assert(pof2 == comm_size); /* FIXME this version only works for power of 2 procs */ + MPIR_Assert(MPL_is_pof2(comm_size)); /* FIXME this version only works for power of 2 procs */ for (i = 0; i < (comm_size - 1); ++i) { MPIR_Assert(recvcounts[i] == recvcounts[i + 1]); @@ -58,6 +50,8 @@ int MPIR_Ireduce_scatter_intra_sched_noncommutative(const void *sendbuf, void *r /* end error checking */ #endif + log2_comm_size = MPL_log2(comm_size); + /* size of a block (count of datatype per block, NOT bytes per block) */ block_size = recvcounts[0]; total_count = block_size * comm_size; diff --git a/src/mpi/coll/ireduce_scatter_block/ireduce_scatter_block_intra_sched_noncommutative.c b/src/mpi/coll/ireduce_scatter_block/ireduce_scatter_block_intra_sched_noncommutative.c index d4bdf727d4d..eab86a5dad7 100644 --- a/src/mpi/coll/ireduce_scatter_block/ireduce_scatter_block_intra_sched_noncommutative.c +++ b/src/mpi/coll/ireduce_scatter_block/ireduce_scatter_block_intra_sched_noncommutative.c @@ -17,7 +17,6 @@ int MPIR_Ireduce_scatter_block_intra_sched_noncommutative(const void *sendbuf, v int mpi_errno = MPI_SUCCESS; int comm_size = comm_ptr->local_size; int rank = comm_ptr->rank; - int pof2; int log2_comm_size; int i, k; int recv_offset, send_offset; @@ -30,19 +29,14 @@ int MPIR_Ireduce_scatter_block_intra_sched_noncommutative(const void *sendbuf, v MPIR_Type_get_true_extent_impl(datatype, &true_lb, &true_extent); - pof2 = 1; - log2_comm_size = 0; - while (pof2 < comm_size) { - pof2 <<= 1; - ++log2_comm_size; - } - #ifdef HAVE_ERROR_CHECKING /* begin error checking */ - MPIR_Assert(pof2 == comm_size); /* FIXME this version only works for power of 2 procs */ + MPIR_Assert(MPL_pof2(comm_size)); /* FIXME this version only works for power of 2 procs */ /* end error checking */ #endif + log2_comm_size = MPL_log2(comm_size); + /* size of a block (count of datatype per block, NOT bytes per block) */ block_size = recvcount; total_count = block_size * comm_size; diff --git a/src/mpi/coll/ireduce_scatter_block/ireduce_scatter_block_intra_sched_recursive_halving.c b/src/mpi/coll/ireduce_scatter_block/ireduce_scatter_block_intra_sched_recursive_halving.c index 56da15028bc..f8c723f7a52 100644 --- a/src/mpi/coll/ireduce_scatter_block/ireduce_scatter_block_intra_sched_recursive_halving.c +++ b/src/mpi/coll/ireduce_scatter_block/ireduce_scatter_block_intra_sched_recursive_halving.c @@ -66,11 +66,7 @@ int MPIR_Ireduce_scatter_block_intra_sched_recursive_halving(const void *sendbuf MPIR_ERR_CHECK(mpi_errno); MPIR_SCHED_BARRIER(s); - pof2 = 1; - while (pof2 <= comm_size) - pof2 <<= 1; - pof2 >>= 1; - + pof2 = MPL_pof2(comm_size); rem = comm_size - pof2; /* In the non-power-of-two case, all even-numbered diff --git a/src/mpi/coll/reduce_scatter/reduce_scatter_intra_noncommutative.c b/src/mpi/coll/reduce_scatter/reduce_scatter_intra_noncommutative.c index 979b46aa738..3e1bd82c635 100644 --- a/src/mpi/coll/reduce_scatter/reduce_scatter_intra_noncommutative.c +++ b/src/mpi/coll/reduce_scatter/reduce_scatter_intra_noncommutative.c @@ -29,7 +29,6 @@ int MPIR_Reduce_scatter_intra_noncommutative(const void *sendbuf, void *recvbuf, int mpi_errno_ret = MPI_SUCCESS; int comm_size = comm_ptr->local_size; int rank = comm_ptr->rank; - int pof2; int log2_comm_size; int i, k; int recv_offset, send_offset; @@ -43,16 +42,9 @@ int MPIR_Reduce_scatter_intra_noncommutative(const void *sendbuf, void *recvbuf, MPIR_Type_get_true_extent_impl(datatype, &true_lb, &true_extent); - pof2 = 1; - log2_comm_size = 0; - while (pof2 < comm_size) { - pof2 <<= 1; - ++log2_comm_size; - } - #ifdef HAVE_ERROR_CHECKING /* begin error checking */ - MPIR_Assert(pof2 == comm_size); /* FIXME this version only works for power of 2 procs */ + MPIR_Assert(MPL_is_pof2(comm_size)); /* FIXME this version only works for power of 2 procs */ for (i = 0; i < (comm_size - 1); ++i) { MPIR_Assert(recvcounts[i] == recvcounts[i + 1]); @@ -60,6 +52,8 @@ int MPIR_Reduce_scatter_intra_noncommutative(const void *sendbuf, void *recvbuf, /* end error checking */ #endif + log2_comm_size = MPL_log2(comm_size); + /* size of a block (count of datatype per block, NOT bytes per block) */ block_size = recvcounts[0]; total_count = block_size * comm_size; diff --git a/src/mpi/coll/reduce_scatter/reduce_scatter_intra_recursive_doubling.c b/src/mpi/coll/reduce_scatter/reduce_scatter_intra_recursive_doubling.c index 61c4ec3c3d6..7b21fcc7550 100644 --- a/src/mpi/coll/reduce_scatter/reduce_scatter_intra_recursive_doubling.c +++ b/src/mpi/coll/reduce_scatter/reduce_scatter_intra_recursive_doubling.c @@ -56,9 +56,10 @@ int MPIR_Reduce_scatter_intra_recursive_doubling(const void *sendbuf, void *recv } /* slightly retask pof2 to mean pof2 equal or greater, not always greater as it is above */ - pof2 = 1; - while (pof2 < comm_size) + pof2 = MPL_pof2(comm_size); + if (pof2 < comm_size) { pof2 <<= 1; + } /* need to allocate temporary buffer to receive incoming data */ MPIR_CHKLMEM_MALLOC(tmp_recvbuf, void *, total_count * (MPL_MAX(true_extent, extent)), diff --git a/src/mpi/coll/reduce_scatter_block/reduce_scatter_block_intra_noncommutative.c b/src/mpi/coll/reduce_scatter_block/reduce_scatter_block_intra_noncommutative.c index 72fa67290be..cdb31fb1861 100644 --- a/src/mpi/coll/reduce_scatter_block/reduce_scatter_block_intra_noncommutative.c +++ b/src/mpi/coll/reduce_scatter_block/reduce_scatter_block_intra_noncommutative.c @@ -31,7 +31,6 @@ int MPIR_Reduce_scatter_block_intra_noncommutative(const void *sendbuf, int mpi_errno_ret = MPI_SUCCESS; int comm_size = comm_ptr->local_size; int rank = comm_ptr->rank; - int pof2; int log2_comm_size; int i, k; int recv_offset, send_offset; @@ -45,19 +44,14 @@ int MPIR_Reduce_scatter_block_intra_noncommutative(const void *sendbuf, MPIR_Type_get_true_extent_impl(datatype, &true_lb, &true_extent); - pof2 = 1; - log2_comm_size = 0; - while (pof2 < comm_size) { - pof2 <<= 1; - ++log2_comm_size; - } - #ifdef HAVE_ERROR_CHECKING /* begin error checking */ - MPIR_Assert(pof2 == comm_size); /* FIXME this version only works for power of 2 procs */ + MPIR_Assert(MPL_is_pof2(comm_size)); /* FIXME this version only works for power of 2 procs */ /* end error checking */ #endif + log2_comm_size = MPL_log2(comm_size); + /* size of a block (count of datatype per block, NOT bytes per block) */ block_size = recvcount; total_count = block_size * comm_size; From de162f37ab06f986a45d39f568fae75fea972688 Mon Sep 17 00:00:00 2001 From: wkliao Date: Sun, 5 Jul 2020 03:21:16 -0500 Subject: [PATCH 356/607] ROMIO: make ADIOI_Optimize_flattened static ADIOI_Optimize_flattened is called only in flatten.c --- src/mpi/romio/adio/common/flatten.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mpi/romio/adio/common/flatten.c b/src/mpi/romio/adio/common/flatten.c index 57c3411cb34..e48fb9a8bb0 100644 --- a/src/mpi/romio/adio/common/flatten.c +++ b/src/mpi/romio/adio/common/flatten.c @@ -55,7 +55,7 @@ static void flatlist_node_grow(ADIOI_Flatlist_node * flat, int idx) } } -void ADIOI_Optimize_flattened(ADIOI_Flatlist_node * flat_type); +static void ADIOI_Optimize_flattened(ADIOI_Flatlist_node * flat_type); /* flatten datatype and add it to Flatlist */ ADIOI_Flatlist_node *ADIOI_Flatten_datatype(MPI_Datatype datatype) { @@ -1182,7 +1182,7 @@ MPI_Count ADIOI_Count_contiguous_blocks(MPI_Datatype datatype, MPI_Count * curr_ * went in, the flattened representation should no longer have zero-length * blocks except for UB and LB markers. */ -void ADIOI_Optimize_flattened(ADIOI_Flatlist_node * flat_type) +static void ADIOI_Optimize_flattened(ADIOI_Flatlist_node * flat_type) { int i, j, opt_blocks; ADIO_Offset *opt_blocklens; From 8837a1a145f7531cb86fe4e78d3f38863376ae4b Mon Sep 17 00:00:00 2001 From: wkliao Date: Sun, 5 Jul 2020 03:27:57 -0500 Subject: [PATCH 357/607] ROMIO: remove use of deprecated MPI_LB MPI_UB Replace MPI_Type_extent with MPI_Type_get_extent as MPI_Type_extent is deprecated. --- src/mpi/romio/adio/common/flatten.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/mpi/romio/adio/common/flatten.c b/src/mpi/romio/adio/common/flatten.c index e48fb9a8bb0..4e3126023ed 100644 --- a/src/mpi/romio/adio/common/flatten.c +++ b/src/mpi/romio/adio/common/flatten.c @@ -155,6 +155,7 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat, MPI_Count i, j, old_size, prev_index, basic_num, num, nonzeroth; MPI_Aint lb, old_extent; /* Assume extents are non-negative */ int *ints; + MPI_Aint lb; MPI_Aint *adds; /* Make no assumptions about +/- sign on these */ MPI_Datatype *types; MPI_Type_get_envelope(datatype, &nints, &nadds, &ntypes, &combiner); @@ -732,17 +733,13 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat, /* simplest case, current type is basic or contiguous types */ /* By using ADIO_Offset we preserve +/- sign and * avoid >2G integer arithmetic problems */ - if (ints[1 + n] > 0 || types[n] == MPI_LB || types[n] == MPI_UB) { + if (ints[1 + n] > 0) { ADIO_Offset blocklength = ints[1 + n]; j = *curr_index; flatlist_node_grow(flat, j); flat->indices[j] = st_offset + adds[n]; MPI_Type_size_x(types[n], &old_size); flat->blocklens[j] = blocklength * old_size; - if (types[n] == MPI_LB) - flat->lb_idx = j; - if (types[n] == MPI_UB) - flat->ub_idx = j; #ifdef FLATTEN_DEBUG DBG_FPRINTF(stderr, "ADIOI_Flatten:: simple adds[%#X] " MPI_AINT_FMT_HEX_SPEC From 97e9840797d08ce6db5b47d95927329339689209 Mon Sep 17 00:00:00 2001 From: wkliao Date: Sun, 5 Jul 2020 03:37:17 -0500 Subject: [PATCH 358/607] ROMIO: skip zero-length datatype combiners --- src/mpi/romio/adio/common/flatten.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/mpi/romio/adio/common/flatten.c b/src/mpi/romio/adio/common/flatten.c index 4e3126023ed..151517b7dec 100644 --- a/src/mpi/romio/adio/common/flatten.c +++ b/src/mpi/romio/adio/common/flatten.c @@ -155,7 +155,6 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat, MPI_Count i, j, old_size, prev_index, basic_num, num, nonzeroth; MPI_Aint lb, old_extent; /* Assume extents are non-negative */ int *ints; - MPI_Aint lb; MPI_Aint *adds; /* Make no assumptions about +/- sign on these */ MPI_Datatype *types; MPI_Type_get_envelope(datatype, &nints, &nadds, &ntypes, &combiner); @@ -201,9 +200,10 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat, #endif #ifdef MPIIMPL_HAVE_MPI_COMBINER_SUBARRAY case MPI_COMBINER_SUBARRAY: - { + if (ints[0] > 0) { int dims = ints[0]; MPI_Datatype stype; + #ifdef FLATTEN_DEBUG DBG_FPRINTF(stderr, "ADIOI_Flatten:: MPI_COMBINER_SUBARRAY\n"); #endif @@ -221,9 +221,10 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat, #endif #ifdef MPIIMPL_HAVE_MPI_COMBINER_DARRAY case MPI_COMBINER_DARRAY: - { + if (ints[2] > 0) { int dims = ints[2]; MPI_Datatype dtype; + #ifdef FLATTEN_DEBUG DBG_FPRINTF(stderr, "ADIOI_Flatten:: MPI_COMBINER_DARRAY\n"); #endif @@ -257,6 +258,9 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat, #ifdef FLATTEN_DEBUG DBG_FPRINTF(stderr, "ADIOI_Flatten:: MPI_COMBINER_CONTIGUOUS\n"); #endif + if (ints[0] == 0) + break; + top_count = ints[0]; MPI_Type_get_envelope(types[0], &old_nints, &old_nadds, &old_ntypes, &old_combiner); ADIOI_Datatype_iscontig(types[0], &old_is_contig); @@ -309,6 +313,9 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat, #ifdef FLATTEN_DEBUG DBG_FPRINTF(stderr, "ADIOI_Flatten:: MPI_COMBINER_VECTOR\n"); #endif + if (ints[0] == 0) + break; + top_count = ints[0]; MPI_Type_get_envelope(types[0], &old_nints, &old_nadds, &old_ntypes, &old_combiner); ADIOI_Datatype_iscontig(types[0], &old_is_contig); @@ -376,6 +383,9 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat, #ifdef FLATTEN_DEBUG DBG_FPRINTF(stderr, "ADIOI_Flatten:: MPI_COMBINER_HVECTOR_INTEGER\n"); #endif + if (ints[0] == 0) + break; + top_count = ints[0]; MPI_Type_get_envelope(types[0], &old_nints, &old_nadds, &old_ntypes, &old_combiner); ADIOI_Datatype_iscontig(types[0], &old_is_contig); @@ -441,6 +451,9 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat, #ifdef FLATTEN_DEBUG DBG_FPRINTF(stderr, "ADIOI_Flatten:: MPI_COMBINER_INDEXED\n"); #endif + if (ints[0] == 0) + break; + top_count = ints[0]; MPI_Type_get_envelope(types[0], &old_nints, &old_nadds, &old_ntypes, &old_combiner); ADIOI_Datatype_iscontig(types[0], &old_is_contig); @@ -543,6 +556,9 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat, #ifdef FLATTEN_DEBUG DBG_FPRINTF(stderr, "ADIOI_Flatten:: MPI_COMBINER_INDEXED_BLOCK\n"); #endif + if (ints[0] == 0) + break; + top_count = ints[0]; MPI_Type_get_envelope(types[0], &old_nints, &old_nadds, &old_ntypes, &old_combiner); ADIOI_Datatype_iscontig(types[0], &old_is_contig); @@ -633,6 +649,9 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat, #ifdef FLATTEN_DEBUG DBG_FPRINTF(stderr, "ADIOI_Flatten:: MPI_COMBINER_HINDEXED_INTEGER\n"); #endif + if (ints[0] == 0) + break; + top_count = ints[0]; MPI_Type_get_envelope(types[0], &old_nints, &old_nadds, &old_ntypes, &old_combiner); ADIOI_Datatype_iscontig(types[0], &old_is_contig); @@ -720,6 +739,9 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat, #ifdef FLATTEN_DEBUG DBG_FPRINTF(stderr, "ADIOI_Flatten:: MPI_COMBINER_STRUCT_INTEGER\n"); #endif + if (ints[0] == 0) + break; + top_count = ints[0]; for (n = 0; n < top_count; n++) { MPI_Type_get_envelope(types[n], &old_nints, &old_nadds, &old_ntypes, &old_combiner); From f425e38aca58af8104fd33918ee8ec7f00f6c1a5 Mon Sep 17 00:00:00 2001 From: wkliao Date: Sun, 5 Jul 2020 03:43:15 -0500 Subject: [PATCH 359/607] ROMIO: guard 3 datatype cominers introduced in MPI 3 MPI_COMBINER_HVECTOR_INTEGER MPI_COMBINER_HINDEXED_INTEGER MPI_COMBINER_STRUCT_INTEGER --- src/mpi/romio/adio/common/flatten.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/mpi/romio/adio/common/flatten.c b/src/mpi/romio/adio/common/flatten.c index 151517b7dec..cda26ba942b 100644 --- a/src/mpi/romio/adio/common/flatten.c +++ b/src/mpi/romio/adio/common/flatten.c @@ -379,9 +379,11 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat, break; case MPI_COMBINER_HVECTOR: +#if MPI_VERSION < 3 case MPI_COMBINER_HVECTOR_INTEGER: #ifdef FLATTEN_DEBUG DBG_FPRINTF(stderr, "ADIOI_Flatten:: MPI_COMBINER_HVECTOR_INTEGER\n"); +#endif #endif if (ints[0] == 0) break; @@ -645,9 +647,11 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat, break; case MPI_COMBINER_HINDEXED: +#if MPI_VERSION < 3 case MPI_COMBINER_HINDEXED_INTEGER: #ifdef FLATTEN_DEBUG DBG_FPRINTF(stderr, "ADIOI_Flatten:: MPI_COMBINER_HINDEXED_INTEGER\n"); +#endif #endif if (ints[0] == 0) break; @@ -735,9 +739,11 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat, break; case MPI_COMBINER_STRUCT: +#if MPI_VERSION < 3 case MPI_COMBINER_STRUCT_INTEGER: #ifdef FLATTEN_DEBUG DBG_FPRINTF(stderr, "ADIOI_Flatten:: MPI_COMBINER_STRUCT_INTEGER\n"); +#endif #endif if (ints[0] == 0) break; @@ -1020,7 +1026,9 @@ MPI_Count ADIOI_Count_contiguous_blocks(MPI_Datatype datatype, MPI_Count * curr_ case MPI_COMBINER_VECTOR: case MPI_COMBINER_HVECTOR: +#if MPI_VERSION < 3 case MPI_COMBINER_HVECTOR_INTEGER: +#endif top_count = ints[0]; MPI_Type_get_envelope(types[0], &old_nints, &old_nadds, &old_ntypes, &old_combiner); ADIOI_Datatype_iscontig(types[0], &old_is_contig); @@ -1054,7 +1062,9 @@ MPI_Count ADIOI_Count_contiguous_blocks(MPI_Datatype datatype, MPI_Count * curr_ case MPI_COMBINER_INDEXED: case MPI_COMBINER_HINDEXED: +#if MPI_VERSION < 3 case MPI_COMBINER_HINDEXED_INTEGER: +#endif top_count = ints[0]; MPI_Type_get_envelope(types[0], &old_nints, &old_nadds, &old_ntypes, &old_combiner); ADIOI_Datatype_iscontig(types[0], &old_is_contig); @@ -1120,7 +1130,9 @@ MPI_Count ADIOI_Count_contiguous_blocks(MPI_Datatype datatype, MPI_Count * curr_ break; case MPI_COMBINER_STRUCT: +#if MPI_VERSION < 3 case MPI_COMBINER_STRUCT_INTEGER: +#endif top_count = ints[0]; count = 0; for (n = 0; n < top_count; n++) { From 3a3f7ec7d05464bdf18b19f664bf1520eeb2d2b5 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 27 Jan 2022 11:20:18 -0600 Subject: [PATCH 360/607] config: do not add flat_namespace option by default We added -Wl,-flat_namespace when we used to depend on common symbols to be shared across libmpifort.so and libmpi.so. This is no longer the case. This flag is added to the mpicxx wrapper scripts and have side effects on all dynamic libraries users may use. It is better we do not add it by default. I imagine if user use another Fortran library that built with MPI may still need this option to make the constants, e.g. MPI_IN_PLACE, to work. --- configure.ac | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/configure.ac b/configure.ac index cfec2dec810..b56742a7691 100644 --- a/configure.ac +++ b/configure.ac @@ -559,17 +559,15 @@ fi AC_SUBST(ENABLE_QMPI) AC_ARG_ENABLE([two-level-namespace], - [AS_HELP_STRING([--enable-two-level-namespace], - [(Darwin only) Build shared libraries and programs - built with the mpicc/mpifort/etc. compiler - wrappers with '-Wl,-commons,use_dylibs' and - without '-Wl,-flat_namespace'. This may make the - MPICH installation and MPI programs more - compatible with other libraries. Only enable - this option if you really know what these linker - options imply.])], + [AS_HELP_STRING([--disable-two-level-namespace], + [(Darwin only) Add `-Wl,-flat_namespace` to + mpicc/mpifort/etc. compiler wrappers. + This may fix some issues due to not resolving + MPI constants, such as MPI_IN_PLACE. + Try disable this option if you encounter these issues + on Mac OS.])], [], - [enable_two_level_namespace=no]) + [enable_two_level_namespace=yes]) AC_ARG_ENABLE(multi-aliases, AS_HELP_STRING([--enable-multi-aliases], From 71730bf5102318265ea6c9d249142fd7f2b697cd Mon Sep 17 00:00:00 2001 From: Taru Doodi Date: Wed, 15 Dec 2021 16:45:52 -0600 Subject: [PATCH 361/607] coll: Add k brucks blocking Alltoall algorithm --- src/mpi/coll/alltoall/Makefile.mk | 1 + .../coll/alltoall/alltoall_intra_k_brucks.c | 334 ++++++++++++++++++ 2 files changed, 335 insertions(+) create mode 100644 src/mpi/coll/alltoall/alltoall_intra_k_brucks.c diff --git a/src/mpi/coll/alltoall/Makefile.mk b/src/mpi/coll/alltoall/Makefile.mk index 3d06dec1e91..4b13038dcce 100644 --- a/src/mpi/coll/alltoall/Makefile.mk +++ b/src/mpi/coll/alltoall/Makefile.mk @@ -11,6 +11,7 @@ mpi_core_sources += \ src/mpi/coll/alltoall/alltoall_allcomm_nb.c \ src/mpi/coll/alltoall/alltoall_intra_pairwise_sendrecv_replace.c \ src/mpi/coll/alltoall/alltoall_intra_brucks.c \ + src/mpi/coll/alltoall/alltoall_intra_k_brucks.c \ src/mpi/coll/alltoall/alltoall_intra_scattered.c \ src/mpi/coll/alltoall/alltoall_intra_pairwise.c \ src/mpi/coll/alltoall/alltoall_inter_pairwise_exchange.c diff --git a/src/mpi/coll/alltoall/alltoall_intra_k_brucks.c b/src/mpi/coll/alltoall/alltoall_intra_k_brucks.c new file mode 100644 index 00000000000..8d6ce67da17 --- /dev/null +++ b/src/mpi/coll/alltoall/alltoall_intra_k_brucks.c @@ -0,0 +1,334 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpiimpl.h" + +/* +=== BEGIN_MPI_T_CVAR_INFO_BLOCK === + +cvars: + - name : MPIR_CVAR_ALLTOALL_BRUCKS_KVAL + category : COLLECTIVE + type : int + default : 2 + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + radix (k) value for generic transport brucks based alltoall + +=== END_MPI_T_CVAR_INFO_BLOCK === +*/ + +/* Brucks Pack, UnPack (PUP) utility function + * This functions packs (unpacks) non-contiguous (contiguous) + * data from (to) rbuf to (from) pupbuf. It goes to every offset + * that has the value "digitval" at the "phase"th digit in the + * base k representation of the offset. The argument pow_k_phase + * is MPL_ipow(k, phase) where phase corresponds to the phase in + * the brucks algorithm. */ +static int +brucks_sched_pup(int pack, void *rbuf, void *pupbuf, MPI_Datatype rtype, int count, + int pow_k_phase, int k, int digitval, int comm_size, int *pupsize) +{ + MPI_Aint type_extent, type_lb, type_true_extent; + int offset, nconsecutive_occurrences, delta; + int mpi_errno = MPI_SUCCESS; + + MPIR_Datatype_get_extent_macro(rtype, type_extent); + MPIR_Type_get_true_extent_impl(rtype, &type_lb, &type_true_extent); + type_extent = MPL_MAX(type_extent, type_true_extent); + + /* first offset where the phase'th bit has value digitval */ + offset = pow_k_phase * digitval; + /* number of consecutive occurrences of digitval */ + nconsecutive_occurrences = pow_k_phase; + /* distance between non-consecutive occurrences of digitval */ + delta = (k - 1) * pow_k_phase; + + *pupsize = 0; /* points to the first empty location in pupbuf */ + while (offset < comm_size) { + if (pack) { + mpi_errno = MPIR_Localcopy((char *) rbuf + offset * count * type_extent, count, rtype, + (char *) pupbuf + *pupsize, count, rtype); + if (mpi_errno) { + MPIR_ERR_POP(mpi_errno); + } + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, + (MPL_DBG_FDEST, "packing rbuf+%ld to pupbuf+%d\n", + offset * count * type_extent, *pupsize)); + } else { + mpi_errno = MPIR_Localcopy((char *) pupbuf + *pupsize, count, rtype, + (char *) rbuf + offset * count * type_extent, count, rtype); + if (mpi_errno) { + MPIR_ERR_POP(mpi_errno); + } + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, + (MPL_DBG_FDEST, "unpacking from pupbuf+%d to rbuf+%ld\n", *pupsize, + offset * count * type_extent)); + } + + offset += 1; + nconsecutive_occurrences -= 1; + + if (nconsecutive_occurrences == 0) { /* consecutive occurrences are over */ + offset += delta; + nconsecutive_occurrences = pow_k_phase; + } + + *pupsize += count * type_extent; + } + fn_exit: + return mpi_errno; + fn_fail: + goto fn_exit; +} + + +/* Algorithm: Bruck's algorithm with radix k + * + * This algorithm is used for small message sizes. It is a modified version + * from the IEEE TPDS Nov 97 paper by Jehoshua Bruck et al. It modifies + * the original bruck algorithm to work with any radix k(k >= 2). It takes + * logk(p) 'phases' to complete and performs (k - 1) sends and recvs + * per 'phase'. When working with radix k, it reads the index of each + * data location in base k. At each substep j, where 0 < j < k, in a phase, + * it packs and sends (recvs and unpacks) the data whose 'phase'th least + * significant digit is j. + * For cases when p is a perfect power of k, + * Cost = logk(p) * alpha + (n/p) * (p - 1) * logk(p) * beta + * where n is the total amount of data a process needs to send to all + * other processes. The algorithm also works for non power of k cases. + * */ + +int MPIR_Alltoall_intra_k_brucks(const void *sendbuf, + MPI_Aint sendcnt, + MPI_Datatype sendtype, + void *recvbuf, + MPI_Aint recvcnt, + MPI_Datatype recvtype, MPIR_Comm * comm, int k, + MPIR_Errflag_t * errflag) +{ + int mpi_errno = MPI_SUCCESS; + int i, j; + int rank, size; + int nphases, max; + int p_of_k; /* largest power of k that is smaller than 'size' */ + int is_inplace; + MPI_Aint s_extent, s_lb, r_extent, r_lb; + MPI_Aint s_true_extent, r_true_extent; + int delta, src, dst; + void **tmp_sbuf = NULL, **tmp_rbuf = NULL; + int packsize; + void *tmp_buf = NULL; + const void *senddata; + MPIR_Request **reqs; + int num_reqs = 0; + + MPIR_CHKLMEM_DECL(4); + + MPIR_CHKLMEM_MALLOC(reqs, MPIR_Request **, (2 * (k - 1) * sizeof(MPIR_Request *)), mpi_errno, + "reqs", MPL_MEM_BUFFER); + + is_inplace = (sendbuf == MPI_IN_PLACE); + + rank = MPIR_Comm_rank(comm); + size = MPIR_Comm_size(comm); + + nphases = 0; + max = size - 1; + + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, + (MPL_DBG_FDEST, "alltoall_blocking_brucks: num_ranks: %d, k: %d \n", size, k)); + /* calculate the number of bits required to represent a rank in base k */ + while (max) { + nphases++; + max /= k; + } + + /* calculate largest power of k that is smaller than 'size'. + * This is used for allocating temporary space for sending + * and receiving data. */ + p_of_k = 1; + for (i = 0; i < nphases - 1; i++) { + p_of_k *= k; + } + + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, (MPL_DBG_FDEST, "Num phases: %d\n", nphases)); + + if (is_inplace) { + sendcnt = recvcnt; + sendtype = recvtype; + } + + MPIR_Datatype_get_extent_macro(sendtype, s_extent); + MPIR_Type_get_true_extent_impl(sendtype, &s_lb, &s_true_extent); + s_extent = MPL_MAX(s_extent, s_true_extent); + + MPIR_Datatype_get_extent_macro(recvtype, r_extent); + MPIR_Type_get_true_extent_impl(recvtype, &r_lb, &r_true_extent); + r_extent = MPL_MAX(r_extent, r_true_extent); + +#ifdef MPL_USE_DBG_LOGGING + { + MPI_Aint s_type_size; + MPIR_Datatype_get_size_macro(sendtype, s_type_size); + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, + (MPL_DBG_FDEST, + "send_type_size: %ld, send_type_extent: %ld, send_count: %ld\n", + s_type_size, s_extent, sendcnt)); + } +#endif + /* temporary buffer used for rotation, so used as sendbuf when inplace is true */ + MPIR_CHKLMEM_MALLOC(tmp_buf, void *, recvcnt * size * r_extent, mpi_errno, "tmp_buf", + MPL_MEM_COLL); + + if (is_inplace) { + mpi_errno = + MPIR_Localcopy(recvbuf, size * recvcnt, recvtype, tmp_buf, size * recvcnt, recvtype); + if (mpi_errno) { + MPIR_ERR_POP(mpi_errno); + } + senddata = tmp_buf; + } else { + senddata = sendbuf; + } + + /* Step 1: rotate the data locally */ + mpi_errno = MPIR_Localcopy((void *) ((char *) senddata + rank * sendcnt * s_extent), + (size - rank) * sendcnt, sendtype, recvbuf, + (size - rank) * recvcnt, recvtype); + if (mpi_errno) { + MPIR_ERR_POP(mpi_errno); + } + mpi_errno = MPIR_Localcopy(senddata, rank * sendcnt, sendtype, + (void *) ((char *) recvbuf + (size - rank) * recvcnt * r_extent), + rank * recvcnt, recvtype); + if (mpi_errno) { + MPIR_ERR_POP(mpi_errno); + } + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, (MPL_DBG_FDEST, "Step 1 data rotation scheduled\n")); + + /* Step 2: Allocate buffer space for packing/receiving data for every phase */ + delta = 1; + + MPIR_CHKLMEM_MALLOC(tmp_sbuf, void **, sizeof(void *) * (k - 1), mpi_errno, "tmp_sbuf", + MPL_MEM_COLL); + MPIR_CHKLMEM_MALLOC(tmp_rbuf, void **, sizeof(void *) * (k - 1), mpi_errno, "tmp_rbuf", + MPL_MEM_COLL); + + for (j = 0; j < k - 1; j++) { + tmp_sbuf[j] = (void *) MPL_malloc(r_extent * recvcnt * p_of_k, MPL_MEM_COLL); + MPIR_ERR_CHKANDJUMP(!tmp_sbuf[j], mpi_errno, MPI_ERR_OTHER, "**nomem"); + tmp_rbuf[j] = (void *) MPL_malloc(r_extent * recvcnt * p_of_k, MPL_MEM_COLL); + MPIR_ERR_CHKANDJUMP(!tmp_rbuf[j], mpi_errno, MPI_ERR_OTHER, "**nomem"); + } + + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, + (MPL_DBG_FDEST, "Allocated temporary buffer space for packing\n")); + + packsize = 0; + + /* Post (k - 1) sends/recvs for each of the nphases */ + for (i = 0; i < nphases; i++) { + num_reqs = 0; + for (j = 1; j < k; j++) { /* for every non-zero value of digitval */ + if (delta * j >= size) /* if the first location exceeds comm size, nothing is to be sent */ + break; + + src = (rank - delta * j + size) % size; + dst = (rank + delta * j) % size; + + /* pack data to be sent */ + mpi_errno = + brucks_sched_pup(1, recvbuf, tmp_sbuf[j - 1], recvtype, recvcnt, delta, k, j, + size, &packsize); + if (mpi_errno) { + MPIR_ERR_POP(mpi_errno); + } + + mpi_errno = + MPIC_Irecv(tmp_rbuf[j - 1], packsize, MPI_BYTE, src, MPIR_ALLTOALL_TAG, comm, + &reqs[num_reqs++]); + if (mpi_errno) { + MPIR_ERR_POP(mpi_errno); + } + + mpi_errno = + MPIC_Isend(tmp_sbuf[j - 1], packsize, MPI_BYTE, dst, MPIR_ALLTOALL_TAG, comm, + &reqs[num_reqs++], errflag); + if (mpi_errno) { + MPIR_ERR_POP(mpi_errno); + } + } + + MPIC_Waitall(num_reqs, reqs, MPI_STATUSES_IGNORE, errflag); + + for (j = 1; j < k; j++) { + if (delta * j >= size) /* if the first location exceeds comm size, nothing is to be sent */ + break; + + /* Unpack received data */ + mpi_errno = + brucks_sched_pup(0, recvbuf, tmp_rbuf[j - 1], recvtype, recvcnt, delta, k, j, + size, &packsize); + if (mpi_errno) { + MPIR_ERR_POP(mpi_errno); + } + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, + (MPL_DBG_FDEST, "phase %d, digit %d unpacking scheduled\n", i, j)); + } + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, (MPL_DBG_FDEST, "phase %d scheduled\n", i)); + + delta *= k; + } + + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, (MPL_DBG_FDEST, "Step 2 scheduled\n")); + + /* Step 3: rotate the buffer */ + /* TODO: MPICH implementation does some lower_bound adjustment here for + * derived datatypes, skipping that for now, will come back + * to it later on - will require adding API for getting true_lb */ + + mpi_errno = MPIR_Localcopy((void *) ((char *) recvbuf + (rank + 1) * recvcnt * r_extent), + (size - rank - 1) * recvcnt, recvtype, tmp_buf, + (size - rank - 1) * recvcnt, recvtype); + if (mpi_errno) { + MPIR_ERR_POP(mpi_errno); + } + mpi_errno = MPIR_Localcopy(recvbuf, (rank + 1) * recvcnt, recvtype, + (void *) ((char *) tmp_buf + + (size - rank - 1) * recvcnt * r_extent), + (rank + 1) * recvcnt, recvtype); + if (mpi_errno) { + MPIR_ERR_POP(mpi_errno); + } + + /* invert the buffer now to get the result in desired order */ + for (i = 0; i < size; i++) { + mpi_errno = MPIR_Localcopy((char *) tmp_buf + i * recvcnt * r_extent, recvcnt, recvtype, + (void *) ((char *) recvbuf + + (size - i - 1) * recvcnt * r_extent), recvcnt, + recvtype); + if (mpi_errno) { + MPIR_ERR_POP(mpi_errno); + } + } + + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, + (MPL_DBG_FDEST, "Step 3: data rearrangement scheduled\n")); + + for (i = 0; i < k - 1; i++) { + MPL_free(tmp_sbuf[i]); + MPL_free(tmp_rbuf[i]); + } + + MPIR_CHKLMEM_FREEALL(); + + fn_exit: + return mpi_errno; + fn_fail: + goto fn_exit; +} From c179cc9ce5e235f066b7fda2042b6e3c44ca398a Mon Sep 17 00:00:00 2001 From: Taru Doodi Date: Tue, 11 Jan 2022 13:53:45 -0600 Subject: [PATCH 362/607] coll: Add CVARs for blocking Alltoall high radix brucks --- src/mpi/coll/coll_algorithms.txt | 4 ++++ src/mpi/coll/cvars.txt | 11 +++++++++++ src/mpi/coll/include/csel_container.h | 6 ++++++ src/mpi/coll/src/csel_container.c | 12 ++++++++++++ 4 files changed, 33 insertions(+) diff --git a/src/mpi/coll/coll_algorithms.txt b/src/mpi/coll/coll_algorithms.txt index 8ebdda34e2f..a1147f56df4 100644 --- a/src/mpi/coll/coll_algorithms.txt +++ b/src/mpi/coll/coll_algorithms.txt @@ -210,6 +210,10 @@ iallgatherv-inter: alltoall-intra: brucks restrictions: noinplace + k_brucks + restrictions: noinplace + extra_params: k + cvar_params: BRUCKS_KVAL pairwise restrictions: noinplace pairwise_sendrecv_replace diff --git a/src/mpi/coll/cvars.txt b/src/mpi/coll/cvars.txt index 60d000cdbd1..ff5c1e46c71 100644 --- a/src/mpi/coll/cvars.txt +++ b/src/mpi/coll/cvars.txt @@ -826,11 +826,22 @@ cvars: Variable to select alltoall algorithm auto - Internal algorithm selection (can be overridden with MPIR_CVAR_COLL_SELECTION_TUNING_JSON_FILE) brucks - Force brucks algorithm + k_brucks - Force Force radix k brucks algorithm nb - Force nonblocking algorithm pairwise - Force pairwise algorithm pairwise_sendrecv_replace - Force pairwise sendrecv replace algorithm scattered - Force scattered algorithm + - name : MPIR_CVAR_ALLTOALL_BRUCKS_KVAL + category : COLLECTIVE + type : int + default : 2 + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + radix (k) value for generic transport brucks based alltoall + - name : MPIR_CVAR_ALLTOALL_INTER_ALGORITHM category : COLLECTIVE type : enum diff --git a/src/mpi/coll/include/csel_container.h b/src/mpi/coll/include/csel_container.h index 7ff24035e39..a208a99167d 100644 --- a/src/mpi/coll/include/csel_container.h +++ b/src/mpi/coll/include/csel_container.h @@ -28,6 +28,7 @@ typedef enum { MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_inter_reduce_exchange_bcast, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_allcomm_nb, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Alltoall_intra_brucks, + MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Alltoall_intra_k_brucks, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Alltoall_intra_pairwise, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Alltoall_intra_pairwise_sendrecv_replace, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Alltoall_intra_scattered, @@ -295,6 +296,11 @@ typedef struct { int recv_pre_posted; } intra_pipelined_tree; } bcast; + struct { + struct { + int k; + } intra_k_brucks; + } alltoall; struct { struct { int k; diff --git a/src/mpi/coll/src/csel_container.c b/src/mpi/coll/src/csel_container.c index 453ee8c45d6..df760d149d4 100644 --- a/src/mpi/coll/src/csel_container.c +++ b/src/mpi/coll/src/csel_container.c @@ -202,6 +202,16 @@ static void parse_container_params(struct json_object *obj, MPII_Csel_container_ } break; + case MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Alltoall_intra_k_brucks: + { + json_object_object_foreach(obj, key, val) { + ckey = MPL_strdup_no_spaces(key); + if (!strncmp(ckey, "k=", strlen("k="))) + cnt->u.alltoall.intra_k_brucks.k = atoi(ckey + strlen("k=")); + MPL_free(ckey); + } + } + break; default: /* Algorithm does not have parameters */ @@ -254,6 +264,8 @@ void *MPII_Create_container(struct json_object *obj) cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_allcomm_nb; else if (!strcmp(ckey, "algorithm=MPIR_Alltoall_intra_brucks")) cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Alltoall_intra_brucks; + else if (!strcmp(ckey, "algorithm=MPIR_Alltoall_intra_k_brucks")) + cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Alltoall_intra_k_brucks; else if (!strcmp(ckey, "algorithm=MPIR_Alltoall_intra_pairwise")) cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Alltoall_intra_pairwise; else if (!strcmp(ckey, "algorithm=MPIR_Alltoall_intra_pairwise_sendrecv_replace")) From 71925f147b9cfc86b5e27ad1dcfc57e4a63c77f9 Mon Sep 17 00:00:00 2001 From: Taru Doodi Date: Tue, 11 Jan 2022 14:01:15 -0600 Subject: [PATCH 363/607] test: Add tests for k_brucks blocking alltoall --- test/mpi/maint/coll_cvars.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/mpi/maint/coll_cvars.txt b/test/mpi/maint/coll_cvars.txt index 6379fbdd59e..7112fca416e 100644 --- a/test/mpi/maint/coll_cvars.txt +++ b/test/mpi/maint/coll_cvars.txt @@ -251,6 +251,8 @@ algorithms: sched_pairwise_exchange intra-blocking: brucks + k_brucks + .MPIR_CVAR_ALLTOALL_BRUCKS_KVAL=2,3,4 pairwise pairwise_sendrecv_replace scattered From 5a3dbdb4c293f87b88897a8ba0ef670b92c86eb4 Mon Sep 17 00:00:00 2001 From: Taru Doodi Date: Tue, 18 Jan 2022 21:55:56 -0600 Subject: [PATCH 364/607] coll: Add k brucks blocking Allgather algorithm --- src/mpi/coll/allgather/Makefile.mk | 1 + .../coll/allgather/allgather_intra_k_brucks.c | 197 ++++++++++++++++++ 2 files changed, 198 insertions(+) create mode 100644 src/mpi/coll/allgather/allgather_intra_k_brucks.c diff --git a/src/mpi/coll/allgather/Makefile.mk b/src/mpi/coll/allgather/Makefile.mk index 3f1c361f9f1..b97bdf4d758 100644 --- a/src/mpi/coll/allgather/Makefile.mk +++ b/src/mpi/coll/allgather/Makefile.mk @@ -11,5 +11,6 @@ mpi_core_sources += \ src/mpi/coll/allgather/allgather_allcomm_nb.c \ src/mpi/coll/allgather/allgather_intra_recursive_doubling.c \ src/mpi/coll/allgather/allgather_intra_brucks.c \ + src/mpi/coll/allgather/allgather_intra_k_brucks.c \ src/mpi/coll/allgather/allgather_intra_ring.c \ src/mpi/coll/allgather/allgather_inter_local_gather_remote_bcast.c diff --git a/src/mpi/coll/allgather/allgather_intra_k_brucks.c b/src/mpi/coll/allgather/allgather_intra_k_brucks.c new file mode 100644 index 00000000000..5712f09b78f --- /dev/null +++ b/src/mpi/coll/allgather/allgather_intra_k_brucks.c @@ -0,0 +1,197 @@ +/* + * Copyright (C) by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + * + */ + +#include "mpiimpl.h" + +/* Algorithm: Bruck's + * + * This algorithm is based from the IEEE TPDS Nov 97 paper by Jehoshua Bruck + * et al. It is a variant of the disemmination algorithm for barrier. + * steps.It modifies the original bruck algorithm to work with any radix + * k(k >= 2). It takes logk(p) 'phases' to complete and performs (k - 1) + * sends and recvs per 'phase'. + * For cases when p is a perfect power of k, + * Cost = logk(p) * alpha + (n/p) * (p - 1) * logk(p) * beta + * where n is the total amount of data a process needs to send to all + * other processes. The algorithm also works for non power of k cases. + */ + +int +MPIR_Allgather_intra_k_brucks(const void *sendbuf, MPI_Aint sendcount, + MPI_Datatype sendtype, void *recvbuf, + MPI_Aint recvcount, MPI_Datatype recvtype, MPIR_Comm * comm, int k, + MPIR_Errflag_t * errflag) +{ + int mpi_errno = MPI_SUCCESS; + int i, j; + int nphases = 0; + int count, left_count; + int src, dst, p_of_k = 0; /* Largest power of k that is smaller than 'size' */ + + int rank = MPIR_Comm_rank(comm); + int size = MPIR_Comm_size(comm); + int is_inplace = (sendbuf == MPI_IN_PLACE); + int max = size - 1; + MPIR_Request **reqs; + int num_reqs = 0; + + MPI_Aint sendtype_extent, sendtype_lb; + MPI_Aint recvtype_extent, recvtype_lb; + MPI_Aint sendtype_true_extent, recvtype_true_extent; + +#ifdef MPL_USE_DBG_LOGGING + MPI_Aint recvtype_size, sendtype_size; +#endif + + int delta = 1; + void *tmp_recvbuf = NULL; + MPIR_CHKLMEM_DECL(2); + MPIR_CHKLMEM_MALLOC(reqs, MPIR_Request **, (2 * (k - 1) * sizeof(MPIR_Request *)), mpi_errno, + "reqs", MPL_MEM_BUFFER); + + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, (MPL_DBG_FDEST, + "Allgather_brucks_radix_k algorithm: num_ranks: %d, k: %d", + size, k)); + + if (is_inplace) { + sendcount = recvcount; + sendtype = recvtype; + } + + /* get datatype info of sendtype and recvtype */ + MPIR_Datatype_get_extent_macro(sendtype, sendtype_extent); + MPIR_Type_get_true_extent_impl(sendtype, &sendtype_lb, &sendtype_true_extent); + sendtype_extent = MPL_MAX(sendtype_extent, sendtype_true_extent); + + MPIR_Datatype_get_extent_macro(recvtype, recvtype_extent); + MPIR_Type_get_true_extent_impl(recvtype, &recvtype_lb, &recvtype_true_extent); + recvtype_extent = MPL_MAX(recvtype_extent, recvtype_true_extent); + +#ifdef MPL_USE_DBG_LOGGING + MPIR_Datatype_get_size_macro(sendtype, sendtype_size); + MPIR_Datatype_get_size_macro(recvtype, recvtype_size); + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, (MPL_DBG_FDEST, + "send_type_size: %zu, send_type_extent: %zu, send_count: %ld", + sendtype_size, sendtype_extent, sendcount)); + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, (MPL_DBG_FDEST, + "recv_type_size: %zu, recv_type_extent: %zu, recv_count: %ld", + recvtype_size, recvtype_extent, recvcount)); +#endif + + while (max) { + nphases++; + max /= k; + } + + /* Check if size is power of k */ + if (MPL_ipow(k, nphases) == size) + p_of_k = 1; + + /* All ranks except `rank 0` need a temporary buffer where it recvs the data. + * This makes the rotation in the final step easier. */ + if (rank == 0) + tmp_recvbuf = recvbuf; + else { + tmp_recvbuf = (int *) MPL_malloc(size * recvcount * recvtype_extent, MPL_MEM_COLL); + MPIR_ERR_CHKANDJUMP(!tmp_recvbuf, mpi_errno, MPI_ERR_OTHER, "**nomem"); + } + + /* Step1: copy own data from sendbuf to top of recvbuf. */ + if (is_inplace && rank != 0) { + mpi_errno = MPIR_Localcopy((char *) recvbuf + rank * recvcount * recvtype_extent, + recvcount, recvtype, tmp_recvbuf, recvcount, recvtype); + } else if (!is_inplace) { + mpi_errno = MPIR_Localcopy(sendbuf, sendcount, sendtype, tmp_recvbuf, recvcount, recvtype); + } + if (mpi_errno) { + MPIR_ERR_POP(mpi_errno); + } + + /* All following sends/recvs and copies depend on this dtcopy */ + + for (i = 0; i < nphases; i++) { + num_reqs = 0; + for (j = 1; j < k; j++) { + if (delta * j >= size) /* If the first location exceeds comm size, nothing is to be sent. */ + break; + + dst = (int) (size + (rank - delta * j)) % size; + src = (int) (rank + delta * j) % size; + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, (MPL_DBG_FDEST, + "Phase%d/%d:j:%d: src:%d, dst:%d", + i, nphases, j, src, dst)); + + /* Amount of data sent in each cycle = k^i, where i = phase_number. + * if (size != MPL_ipow(k, power_of_k) send less data in the last phase. + * This might differ for the different values of j in the last phase. */ + if ((i == (nphases - 1)) && (!p_of_k)) { + count = recvcount * delta; + left_count = recvcount * (size - delta * j); + if (j == k - 1) + count = left_count; + else + count = MPL_MIN(count, left_count); + } else { + count = recvcount * delta; + } + + /* Receive at the exact location. */ + mpi_errno = MPIC_Irecv((char *) tmp_recvbuf + j * recvcount * delta * recvtype_extent, + count, recvtype, src, MPIR_ALLGATHER_TAG, comm, + &reqs[num_reqs++]); + if (mpi_errno) { + MPIR_ERR_POP(mpi_errno); + } + + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, (MPL_DBG_FDEST, + "Phase#%d:, k:%d Recv at:%p for count:%d", i, + k, ((char *) tmp_recvbuf + + j * recvcount * delta * recvtype_extent), + count)); + + /* Send from the start of recv till `count` amount of data. */ + mpi_errno = + MPIC_Isend(tmp_recvbuf, count, recvtype, dst, MPIR_ALLGATHER_TAG, comm, + &reqs[num_reqs++], errflag); + if (mpi_errno) { + MPIR_ERR_POP(mpi_errno); + } + + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, (MPL_DBG_FDEST, + "Phase#%d:, k:%d Send from:%p for count:%d", + i, k, tmp_recvbuf, count)); + + } + MPIC_Waitall(num_reqs, reqs, MPI_STATUSES_IGNORE, errflag); + delta *= k; + } + + if (rank != 0) { /* No shift required for rank 0 */ + mpi_errno = + MPIR_Localcopy((char *) tmp_recvbuf + (size - rank) * recvcount * recvtype_extent, + rank * recvcount, recvtype, (char *) recvbuf, rank * recvcount, + recvtype); + if (mpi_errno) { + MPIR_ERR_POP(mpi_errno); + } + + mpi_errno = MPIR_Localcopy((char *) tmp_recvbuf, (size - rank) * recvcount, recvtype, + (char *) recvbuf + rank * recvcount * recvtype_extent, + (size - rank) * recvcount, recvtype); + if (mpi_errno) { + MPIR_ERR_POP(mpi_errno); + } + } + + if (rank != 0) + MPL_free(tmp_recvbuf); + MPIR_CHKLMEM_FREEALL(); + + fn_exit: + return mpi_errno; + fn_fail: + goto fn_exit; +} From a2517811abdffc000b38f98962fe5c269d04a463 Mon Sep 17 00:00:00 2001 From: Taru Doodi Date: Tue, 18 Jan 2022 22:31:39 -0600 Subject: [PATCH 365/607] coll: Add CVARs for blocking Allgather high radix brucks --- src/mpi/coll/coll_algorithms.txt | 3 +++ src/mpi/coll/cvars.txt | 11 +++++++++++ src/mpi/coll/include/csel_container.h | 6 ++++++ src/mpi/coll/src/csel_container.c | 13 +++++++++++++ 4 files changed, 33 insertions(+) diff --git a/src/mpi/coll/coll_algorithms.txt b/src/mpi/coll/coll_algorithms.txt index a1147f56df4..d0b4effa2ad 100644 --- a/src/mpi/coll/coll_algorithms.txt +++ b/src/mpi/coll/coll_algorithms.txt @@ -149,6 +149,9 @@ iscatterv-inter: allgather-intra: brucks + k_brucks + extra_params: k + cvar_params: BRUCKS_KVAL recursive_doubling restrictions: power-of-two ring diff --git a/src/mpi/coll/cvars.txt b/src/mpi/coll/cvars.txt index ff5c1e46c71..a372d78bc3f 100644 --- a/src/mpi/coll/cvars.txt +++ b/src/mpi/coll/cvars.txt @@ -618,10 +618,21 @@ cvars: Variable to select allgather algorithm auto - Internal algorithm selection (can be overridden with MPIR_CVAR_COLL_SELECTION_TUNING_JSON_FILE) brucks - Force brucks algorithm + k_brucks - Force brucks algorithm nb - Force nonblocking algorithm recursive_doubling - Force recursive doubling algorithm ring - Force ring algorithm + - name : MPIR_CVAR_ALLGATHER_BRUCKS_KVAL + category : COLLECTIVE + type : int + default : 2 + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + radix (k) value for generic transport brucks based allgather + - name : MPIR_CVAR_ALLGATHER_INTER_ALGORITHM category : COLLECTIVE type : enum diff --git a/src/mpi/coll/include/csel_container.h b/src/mpi/coll/include/csel_container.h index a208a99167d..051f6d0349b 100644 --- a/src/mpi/coll/include/csel_container.h +++ b/src/mpi/coll/include/csel_container.h @@ -12,6 +12,7 @@ void *MPII_Create_container(struct json_object *obj); typedef enum { MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allgather_intra_brucks, + MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allgather_intra_k_brucks, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allgather_intra_recursive_doubling, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allgather_intra_ring, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allgather_inter_local_gather_remote_bcast, @@ -296,6 +297,11 @@ typedef struct { int recv_pre_posted; } intra_pipelined_tree; } bcast; + struct { + struct { + int k; + } intra_k_brucks; + } allgather; struct { struct { int k; diff --git a/src/mpi/coll/src/csel_container.c b/src/mpi/coll/src/csel_container.c index df760d149d4..193c2df5f8c 100644 --- a/src/mpi/coll/src/csel_container.c +++ b/src/mpi/coll/src/csel_container.c @@ -202,6 +202,17 @@ static void parse_container_params(struct json_object *obj, MPII_Csel_container_ } break; + case MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allgather_intra_k_brucks: + { + json_object_object_foreach(obj, key, val) { + ckey = MPL_strdup_no_spaces(key); + if (!strncmp(ckey, "k=", strlen("k="))) + cnt->u.alltoall.intra_k_brucks.k = atoi(ckey + strlen("k=")); + MPL_free(ckey); + } + } + break; + case MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Alltoall_intra_k_brucks: { json_object_object_foreach(obj, key, val) { @@ -228,6 +239,8 @@ void *MPII_Create_container(struct json_object *obj) if (!strcmp(ckey, "algorithm=MPIR_Allgather_intra_brucks")) cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allgather_intra_brucks; + else if (!strcmp(ckey, "algorithm=MPIR_Allgather_intra_k_brucks")) + cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allgather_intra_k_brucks; else if (!strcmp(ckey, "algorithm=MPIR_Allgather_intra_recursive_doubling")) cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allgather_intra_recursive_doubling; else if (!strcmp(ckey, "algorithm=MPIR_Allgather_intra_ring")) From 3dafc5f4c35604853f78f345b787153bd43daa99 Mon Sep 17 00:00:00 2001 From: Taru Doodi Date: Tue, 18 Jan 2022 22:35:16 -0600 Subject: [PATCH 366/607] test: Add tests for k_brucks blocking allgather --- test/mpi/maint/coll_cvars.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/mpi/maint/coll_cvars.txt b/test/mpi/maint/coll_cvars.txt index 7112fca416e..fc280703a0e 100644 --- a/test/mpi/maint/coll_cvars.txt +++ b/test/mpi/maint/coll_cvars.txt @@ -180,6 +180,8 @@ algorithms: sched_local_gather_remote_bcast intra-blocking: brucks + k_brucks + .MPIR_CVAR_ALLGATHER_BRUCKS_KVAL=2,3,4 recursive_doubling ring intra-nonblocking: From 40357ce743b8a4a47942ce0f55ec1030b0cabed8 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 10 Dec 2021 16:09:51 -0600 Subject: [PATCH 367/607] runtests: remove mpix test options The mpix=true option is not used and functionally the same as strict=false. Remove to simplify. --- test/mpi/runtests.in | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/test/mpi/runtests.in b/test/mpi/runtests.in index a9b2c96fda3..870ff08b871 100755 --- a/test/mpi/runtests.in +++ b/test/mpi/runtests.in @@ -495,7 +495,6 @@ sub RunList { my $programname = $args[0]; my $np = ""; my $requiresStrict = ""; - my $requiresMPIX = ""; if ($#args >= 1) { $np = $args[1]; } # Process the key=value arguments @@ -518,9 +517,6 @@ sub RunList { elsif ($key eq "strict") { $requiresStrict = $value } - elsif ($key eq "mpix") { - $requiresMPIX = $value - } else { print STDERR "Unrecognized key $key in $listfileSource\n"; } @@ -572,13 +568,6 @@ sub RunList { next; } - if (lc($requiresMPIX) eq "true" && lc($MPIHasMPIX) eq "no") { - unless (-d $programname) { - SkippedTest($programname, $np, $test_opt, $curdir, "tests MPIX extensions, MPIX testing disabled"); - } - next; - } - if (-d $programname) { # If a directory, go into the that directory and # look for a new list file From 86b5cccb7915bed8736fff00a078ea22ee8fb075 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 9 Dec 2021 20:41:35 -0600 Subject: [PATCH 368/607] runtests: skip substitutions via configure Use explicit options rather than autoconf substitutions. It is more flexible and removes the script dependency on configure. --- test/mpi/.gitignore | 1 - test/mpi/Makefile_common.mtest | 4 ++-- test/mpi/Makefile_cxx.mtest | 2 +- test/mpi/Makefile_f08.mtest | 2 +- test/mpi/Makefile_f77.mtest | 2 +- test/mpi/Makefile_f90.mtest | 2 +- test/mpi/configure.ac | 18 ++++++------------ test/mpi/{runtests.in => runtests} | 25 +++++++++++++++---------- 8 files changed, 27 insertions(+), 29 deletions(-) rename test/mpi/{runtests.in => runtests} (98%) diff --git a/test/mpi/.gitignore b/test/mpi/.gitignore index acc0e16f0a1..4a8e1f9d290 100644 --- a/test/mpi/.gitignore +++ b/test/mpi/.gitignore @@ -1516,7 +1516,6 @@ /rma/wintest /rma/wintest_shm /rma/win_zero -/runtests /spawn/concurrent_spawns /spawn/disconnect /spawn/disconnect2 diff --git a/test/mpi/Makefile_common.mtest b/test/mpi/Makefile_common.mtest index 51cb34d1188..2b6427247c0 100644 --- a/test/mpi/Makefile_common.mtest +++ b/test/mpi/Makefile_common.mtest @@ -36,8 +36,8 @@ endif SUMMARY_BASENAME ?= summary testing: - $(top_builddir)/runtests -srcdir=$(srcdir) -tests=$(TESTLIST) -testdirs=$(TESTDIRS) \ - -mpiexec="${MPIEXEC}" -xmlfile=$(SUMMARY_BASENAME).xml \ + $(top_srcdir)/runtests -srcdir=$(srcdir) -tests=$(TESTLIST) -testdirs=$(TESTDIRS) \ + -mpiexec="${MPIEXEC}" $(RUNTESTS_OPTS) -xmlfile=$(SUMMARY_BASENAME).xml \ -tapfile=$(SUMMARY_BASENAME).tap -junitfile=$(SUMMARY_BASENAME).junit.xml CLEANFILES = $(SUMMARY_BASENAME).xml $(SUMMARY_BASENAME).tap $(SUMMARY_BASENAME).junit.xml diff --git a/test/mpi/Makefile_cxx.mtest b/test/mpi/Makefile_cxx.mtest index 20f0d6a6ddb..daa8677371c 100644 --- a/test/mpi/Makefile_cxx.mtest +++ b/test/mpi/Makefile_cxx.mtest @@ -24,7 +24,7 @@ $(top_builddir)/dtpools/src/.libs/libdtpools.la: (cd $(top_builddir)/dtpools && $(MAKE)) testing: - $(top_builddir)/runtests -srcdir=$(srcdir) -tests=testlist,testlist.dtp \ + $(top_srcdir)/runtests -srcdir=$(srcdir) -tests=testlist,testlist.dtp \ -mpiexec=${MPIEXEC} -xmlfile=summary.xml CLEANFILES = summary.xml summary.tap diff --git a/test/mpi/Makefile_f08.mtest b/test/mpi/Makefile_f08.mtest index d5358d221d9..724c9110771 100644 --- a/test/mpi/Makefile_f08.mtest +++ b/test/mpi/Makefile_f08.mtest @@ -20,7 +20,7 @@ $(top_builddir)/util/libmtest_single.la: (cd $(top_builddir)/util && $(MAKE) libmtest_single.la) testing: - $(top_builddir)/runtests -srcdir=$(srcdir) -tests=testlist \ + $(top_srcdir)/runtests -srcdir=$(srcdir) -tests=testlist \ -mpiexec=${MPIEXEC} -xmlfile=summary.xml -tapfile=summary.tap -junitfile=summary.junit.xml CLEANFILES = summary.xml summary.tap summary.junit.xml diff --git a/test/mpi/Makefile_f77.mtest b/test/mpi/Makefile_f77.mtest index 71aa172a350..f46eca2ac9d 100644 --- a/test/mpi/Makefile_f77.mtest +++ b/test/mpi/Makefile_f77.mtest @@ -26,7 +26,7 @@ $(top_builddir)/util/libmtest_single.la: (cd $(top_builddir)/util && $(MAKE) libmtest_single.la) testing: - $(top_builddir)/runtests -srcdir=$(srcdir) -tests=testlist \ + $(top_srcdir)/runtests -srcdir=$(srcdir) -tests=testlist \ -mpiexec=${MPIEXEC} -xmlfile=summary.xml -tapfile=summary.tap -junitfile=summary.junit.xml CLEANFILES = summary.xml summary.tap summary.junit.xml diff --git a/test/mpi/Makefile_f90.mtest b/test/mpi/Makefile_f90.mtest index 5a8b426d26c..2a938aae6e2 100644 --- a/test/mpi/Makefile_f90.mtest +++ b/test/mpi/Makefile_f90.mtest @@ -20,7 +20,7 @@ $(top_builddir)/util/libmtest_single.la: (cd $(top_builddir)/util && $(MAKE) libmtest_single.la) testing: - $(top_builddir)/runtests -srcdir=$(srcdir) -tests=testlist \ + $(top_srcdir)/runtests -srcdir=$(srcdir) -tests=testlist \ -mpiexec=${MPIEXEC} -xmlfile=summary.xml -tapfile=summary.tap -junitfile=summary.junit.xml CLEANFILES = summary.xml summary.tap summary.junit.xml diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index fe1f2f4ce31..5ba8a7b5468 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -141,6 +141,10 @@ fi AC_SUBST(DTP_SWITCH) +# runtests options +RUNTESTS_OPTS= +AC_SUBST(RUNTESTS_OPTS) + AC_ARG_ENABLE(cxx, [AC_HELP_STRING([--enable-cxx],[Turn on C++ tests (default)])],,[enable_cxx=yes]) @@ -491,11 +495,9 @@ AC_SUBST(ckpointdir) # # Only run xfail tests if enabled -RUN_XFAIL=false if test "$enable_xfail" = "yes" ; then - RUN_XFAIL=true + RUNTESTS_OPTS="$RUNTESTS_OPTS -runxfail" fi -AC_SUBST(RUN_XFAIL) PAC_LOAD_BASE_CACHE PAC_VPATH_CHECK() @@ -552,10 +554,8 @@ if test "$enable_checkfaults" = "yes" ; then fi AC_SUBST(faultsdir) # -MPI_IS_STRICT=false -AC_SUBST(MPI_IS_STRICT) if test "$enable_strictmpi" = "yes" ; then - MPI_IS_STRICT=true + RUNTESTS_OPTS="$RUNTESTS_OPTS -strict" AC_DEFINE(USE_STRICT_MPI,1,[Define if only operations defined in MPI should be tested]) fi # @@ -1467,11 +1467,6 @@ AC_SUBST(MPIEXEC) AC_SUBST(MAKE) if test -z "$MPILIBNAME" ; then MPILIBNAME=mpich ; fi AC_SUBST(MPILIBNAME) -dnl MPI_SOURCE may be set as an environment variable giving the location -dnl of the MPI implementation. This is used only in runtests to include -dnl the location of the source of the MPI implementation into the XML -dnl summary file -AC_SUBST(MPI_SOURCE) # We need either mpiexec or mpirun. If we don't find them, # the user will need to determine how to run a program @@ -1492,7 +1487,6 @@ AC_CONFIG_COMMANDS([chmod],[ dnl Note that this format for AC_OUTPUT can cause problems for autoconf dnl run under cygwin AC_OUTPUT(maint/testmerge \ - runtests \ checktests \ Makefile \ basic/Makefile \ diff --git a/test/mpi/runtests.in b/test/mpi/runtests similarity index 98% rename from test/mpi/runtests.in rename to test/mpi/runtests index 870ff08b871..be81282f606 100755 --- a/test/mpi/runtests.in +++ b/test/mpi/runtests @@ -1,4 +1,4 @@ -#! @PERL@ +#!/usr/bin/env perl ## ## Copyright (C) by Argonne National Laboratory ## See COPYRIGHT in top-level directory @@ -56,6 +56,9 @@ $g_opt->{memory_multiplier} = 1; # No of simutaneous jobs $g_opt->{cleanup} = 1; # Whether to remove the compiled programs $g_opt->{start_time} = time(); # So we can track accumulative test duration $g_opt->{has_gpu_test} = 0; # will set MPIR_CVAR_ENABLE_GPU for optimizations +$g_opt->{strict} = 0; # will skip tests marked as "strict=false" +$g_opt->{runxfail} = 0; # will run xfailed tests +$g_opt->{exeext} = ""; # Total number of tests checked and run our $g_total_run = 0; @@ -66,7 +69,7 @@ our $g_total_seen = 0; our $g_num_timeout; our $g_num_timeout_thresh = 5; -$mpiexec = "@MPIEXEC@"; # Name of mpiexec program (including path, if necessary) +$mpiexec = "mpiexec"; # Name of mpiexec program (including path, if necessary) # ppnMax is the maximum number of processes per node. -1 means ignore. # ppnArg is the argument to use to mpiexec - format is "string%d"; e.g., # "-ppn %d" @@ -76,9 +79,6 @@ $ppnMax = -1; # in seconds. The format is "string%d", e.g., "-t %d" for Cray aprun $timelimitArg=""; # -$testIsStrict = "@MPI_IS_STRICT@"; -$MPIhasMPIX = "@MPI_HAS_MPIX@"; -$runxfail = "@RUN_XFAIL@"; $np_arg = "-n"; # Name of argument to specify the number of processes $err_count = 0; # Number of programs that failed. $skip_count = 0; # Number of programs skipped @@ -225,6 +225,8 @@ foreach $_ (@ARGV) { elsif (/--?batchdir=(.*)/) { $batrundir = $1; } elsif (/--?batch/) { $batchRun = 1; } elsif (/--?timeoutarg=(.*)/) { $timeoutArgPattern = $1; } + elsif (/--?strict/) { $g_opt->{strict} = 1; } + elsif (/--?runxfail/) { $g_opt->{runxfail} = 1; } elsif (/--?xmlfile=(.*)/) { $xmlfile = $1; if (! ($xmlfile =~ /^\//)) { @@ -245,7 +247,6 @@ foreach $_ (@ARGV) { print XMLOUT "$newline"; print XMLOUT "$newline"; print XMLOUT "$date$newline"; - print XMLOUT "@MPI_SOURCE@$newline"; } elsif (/--?noxmlclose/) { $closeXMLOutput = 0; @@ -545,21 +546,21 @@ sub RunList { # Check whether strict is required by MPI but not by the # test (use strict=false for tests that use non-standard extensions) - if (lc($requiresStrict) eq "false" && lc($testIsStrict) eq "true") { + if (lc($requiresStrict) eq "false" && $g_opt->{strict}) { unless (-d $programname) { SkippedTest($programname, $np, $test_opt, $curdir, "non-strict test, strict MPI mode requested"); } next; } - if (lc($testIsStrict) eq "true") { + if ($g_opt->{strict}) { # Strict MPI testing was requested, so assume that a non-MPICH MPI # implementation is being tested and the "xfail" implementation # assumptions do not hold. delete($test_opt->{xfail}); } - if ($test_opt->{xfail} && $runxfail eq "false") { + if ($test_opt->{xfail} && !$g_opt->{runxfail}) { # Skip xfail tests if they are not configured. Strict MPI tests that are # marked xfail will still run with --enable-strictmpi. unless (-d $programname) { @@ -971,6 +972,10 @@ sub AddMPIProgram { # Return value is 0 on success, non zero on failure sub BuildMPIProgram { my ($programname, $test_opt) = @_; + # whether we need append '.exe' + if ($g_opt->{exeext}) { + $programname .= $g_opt->{exeext}; + } my $rc = 0; if ($verbose) { print STDERR "making $programname\n"; } @@ -979,7 +984,7 @@ sub BuildMPIProgram { } else { $test_opt->{need_remove} = 0; } - my $output = `make $programname@EXEEXT@ 2>&1`; + my $output = `make $programname 2>&1`; $rc = $?; if ($rc > 255) { $rc >>= 8; } if (! -x $programname) { From 223310bcc49e0ab37f4744141f5d9cb011ae9066 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 9 Dec 2021 20:56:58 -0600 Subject: [PATCH 369/607] runtests: change g_opt from reference to direct hash It is unnecessary to use reference. --- test/mpi/runtests | 52 +++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/test/mpi/runtests b/test/mpi/runtests index be81282f606..6aca819377d 100755 --- a/test/mpi/runtests +++ b/test/mpi/runtests @@ -50,15 +50,15 @@ use Time::HiRes qw(gettimeofday tv_interval); use Fcntl qw(:flock); # Global variables -our $g_opt = {}; # global options. TODO: migrate global option vars into the hash -$g_opt->{memory_total} = 20; # Total memory in GB -$g_opt->{memory_multiplier} = 1; # No of simutaneous jobs -$g_opt->{cleanup} = 1; # Whether to remove the compiled programs -$g_opt->{start_time} = time(); # So we can track accumulative test duration -$g_opt->{has_gpu_test} = 0; # will set MPIR_CVAR_ENABLE_GPU for optimizations -$g_opt->{strict} = 0; # will skip tests marked as "strict=false" -$g_opt->{runxfail} = 0; # will run xfailed tests -$g_opt->{exeext} = ""; +our %g_opt; # global options. TODO: migrate global option vars into the hash +$g_opt{memory_total} = 20; # Total memory in GB +$g_opt{memory_multiplier} = 1; # No of simutaneous jobs +$g_opt{cleanup} = 1; # Whether to remove the compiled programs +$g_opt{start_time} = time(); # So we can track accumulative test duration +$g_opt{has_gpu_test} = 0; # will set MPIR_CVAR_ENABLE_GPU for optimizations +$g_opt{strict} = 0; # will skip tests marked as "strict=false" +$g_opt{runxfail} = 0; # will run xfailed tests +$g_opt{exeext} = ""; # Total number of tests checked and run our $g_total_run = 0; @@ -162,7 +162,7 @@ if (defined($ENV{"MPITEST_TIMEOUT_MULTIPLIER"})) { for my $key ("memory_total", "memory_multiplier", "cleanup") { my $k = "MPITEST_".uc($key); if (defined($ENV{$k})) { - $g_opt->{$key} = $ENV{$k}; + $g_opt{$key} = $ENV{$k}; } } @@ -199,7 +199,7 @@ if (defined($ENV{'MPITEST_TIMELIMITARG'})) { $timelimitArg = $ENV{'MPITEST_TIMELIMITARG'}; } if (defined($ENV{'MPITEST_MPIEXECARG'})) { - $g_opt->{mpiexecargs} = $ENV{'MPITEST_MPIEXECARG'}; + $g_opt{mpiexecargs} = $ENV{'MPITEST_MPIEXECARG'}; } #--------------------------------------------------------------------------- @@ -225,8 +225,8 @@ foreach $_ (@ARGV) { elsif (/--?batchdir=(.*)/) { $batrundir = $1; } elsif (/--?batch/) { $batchRun = 1; } elsif (/--?timeoutarg=(.*)/) { $timeoutArgPattern = $1; } - elsif (/--?strict/) { $g_opt->{strict} = 1; } - elsif (/--?runxfail/) { $g_opt->{runxfail} = 1; } + elsif (/--?strict/) { $g_opt{strict} = 1; } + elsif (/--?runxfail/) { $g_opt{runxfail} = 1; } elsif (/--?xmlfile=(.*)/) { $xmlfile = $1; if (! ($xmlfile =~ /^\//)) { @@ -315,7 +315,7 @@ else { # Process any files if ($listfiles =~ /testlist\.gpu/) { - $g_opt->{has_gpu_test} = 1; + $g_opt{has_gpu_test} = 1; } if ($listfiles eq "") { @@ -449,7 +449,7 @@ sub RunList { next; } # add a timestamp to have a quick idea of how long the tests ran - my @tm_list = gmtime(time() - $g_opt->{start_time}); + my @tm_list = gmtime(time() - $g_opt{start_time}); my $timestamp = sprintf("%02d:%02d:%02d", $tm_list[2], $tm_list[1], $tm_list[0]); print "Looking in $curdir/$_f \t[$timestamp]\n" if $debug; open( $LIST, "<$listfileSource" ) || die "Could not open $listfileSource\n"; @@ -485,7 +485,7 @@ sub RunList { # for examples of using the key=value form my @args = split(/\s+/,$_); my $test_opt = {args=>[], envs=>[], mpiexecargs=>[]}; - if ($g_opt->{has_gpu_test}) { + if ($g_opt{has_gpu_test}) { if ($_f ne "testlist.gpu") { push @{$test_opt->{envs}}, "MPIR_CVAR_ENABLE_GPU=0"; } else { @@ -546,21 +546,21 @@ sub RunList { # Check whether strict is required by MPI but not by the # test (use strict=false for tests that use non-standard extensions) - if (lc($requiresStrict) eq "false" && $g_opt->{strict}) { + if (lc($requiresStrict) eq "false" && $g_opt{strict}) { unless (-d $programname) { SkippedTest($programname, $np, $test_opt, $curdir, "non-strict test, strict MPI mode requested"); } next; } - if ($g_opt->{strict}) { + if ($g_opt{strict}) { # Strict MPI testing was requested, so assume that a non-MPICH MPI # implementation is being tested and the "xfail" implementation # assumptions do not hold. delete($test_opt->{xfail}); } - if ($test_opt->{xfail} && !$g_opt->{runxfail}) { + if ($test_opt->{xfail} && !$g_opt{runxfail}) { # Skip xfail tests if they are not configured. Strict MPI tests that are # marked xfail will still run with --enable-strictmpi. unless (-d $programname) { @@ -695,8 +695,8 @@ sub RunMPIProgram { my $progArgs = join(' ', @{$test_opt->{args}}); my $progEnv = join(' ', @{$test_opt->{envs}}); my $mpiexecArgs = join(' ', @{$test_opt->{mpiexecargs}}); - if (!$mpiexecArgs and $g_opt->{mpiexecargs}) { - $mpiexecArgs = $g_opt->{mpiexecargs}; + if (!$mpiexecArgs and $g_opt{mpiexecargs}) { + $mpiexecArgs = $g_opt{mpiexecargs}; } my $found_error = 0; @@ -759,10 +759,10 @@ sub RunMPIProgram { } elsif ($test_opt->{mem}) { # implicit lock by checking memory annotation $lockfile="/tmp/runtests-mem.lock"; - if ($test_opt->{mem} > $g_opt->{memory_total}) { + if ($test_opt->{mem} > $g_opt{memory_total}) { SkippedTest($programname, $np, $test_opt, $curdir, "xfail due to memory requirement"); next; - } elsif ($test_opt->{mem} * $g_opt->{memory_multiplier} > $g_opt->{memory_total} ) { + } elsif ($test_opt->{mem} * $g_opt{memory_multiplier} > $g_opt{memory_total} ) { $got_lock = get_lock($lockfile, LOCK_EX); } else { $got_lock = get_lock($lockfile, LOCK_SH); @@ -973,8 +973,8 @@ sub AddMPIProgram { sub BuildMPIProgram { my ($programname, $test_opt) = @_; # whether we need append '.exe' - if ($g_opt->{exeext}) { - $programname .= $g_opt->{exeext}; + if ($g_opt{exeext}) { + $programname .= $g_opt{exeext}; } my $rc = 0; @@ -1026,7 +1026,7 @@ sub CleanUpAfterRun { } } else { - if ($test_opt->{need_remove} && $g_opt->{cleanup}) { + if ($test_opt->{need_remove} && $g_opt{cleanup}) { unlink $programname, "$programname.o"; } $test_opt->{need_remove} = 0; From 0038eaa28e440bd3e550e7617c8b3607fe527340 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 9 Dec 2021 21:10:05 -0600 Subject: [PATCH 370/607] runtests: cleanup the mpiexec argument Move the option to g_opt hash. Remove the error check since mpiexec is always set and never will be empty. Avoid duplication of long cmd string. --- test/mpi/runtests | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/test/mpi/runtests b/test/mpi/runtests index 6aca819377d..81872e8c96f 100755 --- a/test/mpi/runtests +++ b/test/mpi/runtests @@ -59,6 +59,7 @@ $g_opt{has_gpu_test} = 0; # will set MPIR_CVAR_ENABLE_GPU for optimization $g_opt{strict} = 0; # will skip tests marked as "strict=false" $g_opt{runxfail} = 0; # will run xfailed tests $g_opt{exeext} = ""; +$g_opt{mpiexec} = "mpiexec"; # Name of mpiexec program (including path, if necessary) # Total number of tests checked and run our $g_total_run = 0; @@ -69,7 +70,6 @@ our $g_total_seen = 0; our $g_num_timeout; our $g_num_timeout_thresh = 5; -$mpiexec = "mpiexec"; # Name of mpiexec program (including path, if necessary) # ppnMax is the maximum number of processes per node. -1 means ignore. # ppnArg is the argument to use to mpiexec - format is "string%d"; e.g., # "-ppn %d" @@ -209,7 +209,7 @@ foreach $_ (@ARGV) { if (/--?mpiexec=(.*)/) { # Use mpiexec as given - it may be in the path, and # we don't want to bother to try and find it. - $mpiexec = $1; + $g_opt{mpiexec} = $1; } elsif (/--?np=(\d+)/) { $np_default = $1; } elsif (/--?maxnp=(\d+)/) { $np_max = $1; } @@ -303,13 +303,6 @@ if ($batchRun) { } open( BATOUT, ">$batrundir/runtests.batch" ) || die "Could not open $batrundir/runtests.batch\n"; } -else { - # We must have mpiexec - if ("$mpiexec" eq "") { - print STDERR "No mpiexec found!\n"; - exit(1); - } -} # # Process any files @@ -769,8 +762,9 @@ sub RunMPIProgram { } } + my $cmd = "$g_opt{mpiexec} $np_arg $np $extraArgs $mpiexecArgs $program_wrapper ./$programname $progArgs"; print STDOUT "Env includes $progEnv\n" if $verbose; - print STDOUT "$mpiexec $np_arg $np $extraArgs $mpiexecArgs $program_wrapper ./$programname $progArgs\n" if $verbose; + print STDOUT "$cmd\n" if $verbose; print STDOUT "." if $showProgress; # Save and restore the environment if necessary before running mpiexec. my %saveEnv; @@ -786,7 +780,7 @@ sub RunMPIProgram { } } my $start_time = gettimeofday(); - open ( MPIOUT, "$mpiexec $np_arg $np $extraArgs $mpiexecArgs $program_wrapper ./$programname $progArgs 2>&1 |" ) || + open ( MPIOUT, "$cmd 2>&1 |" ) || die "Could not run ./$programname\n"; if ($test_opt->{envs}) { %ENV = %saveEnv; @@ -808,7 +802,7 @@ sub RunMPIProgram { } else { if ($verbose) { - $inline = "$mpiexec $np_arg $np $extraArgs $mpiexecArgs $program_wrapper ./$programname\n"; + $inline = "$cmd\n"; } else { $inline = ""; @@ -944,8 +938,9 @@ sub AddMPIProgram { } + my $cmd = "$g_opt{mpiexec} $np_arg $np $extraArgs $program_wrapper ./$programname $progArgs"; print STDOUT "Env includes $progEnv\n" if $verbose; - print STDOUT "$mpiexec $np_arg $np $extraArgs $program_wrapper ./$programname $progArgs\n" if $verbose; + print STDOUT "$cmd\n" if $verbose; print STDOUT "." if $showProgress; # Save and restore the environment if necessary before running mpiexec. if ($progEnv ne "") { @@ -962,9 +957,9 @@ sub AddMPIProgram { # and ensure that the output goes "into the right place". $testCount++; rename $programname, "$batrundir/$programname"; - print BATOUT "echo \"# $mpiexec $np_arg $np $extraArgs $mpiexecArgs $program_wrapper $curdir/$programname $progArgs\" > runtests.$testCount.out\n"; + print BATOUT "echo \"# $cmd\" > runtests.$testCount.out\n"; # Some programs expect to run in the same directory as the executable - print BATOUT "$mpiexec $np_arg $np $extraArgs $mpiexecArgs $program_wrapper ./$programname $progArgs >> runtests.$testCount.out 2>&1\n"; + print BATOUT "$cmd >> runtests.$testCount.out 2>&1\n"; print BATOUT "echo \$? > runtests.$testCount.status\n"; } @@ -1101,7 +1096,7 @@ sub TestStatus { $found_error = 1; $err_count ++; } - $inline .= "$mpiexec returned a zero status but the program returned a nonzero status\n"; + $inline .= "$g_opt{mpiexec} returned a zero status but the program returned a nonzero status\n"; } return ($found_error,$inline); } @@ -1153,7 +1148,7 @@ sub TestStatusNoErrors { $found_error = 1; $err_count ++; } - $inline .= "$mpiexec returned a zero status but the program required a non-zero status\n"; + $inline .= "$g_opt{mpiexec} returned a zero status but the program required a non-zero status\n"; } return ($found_error,$inline); } @@ -1185,7 +1180,7 @@ sub TestErrFatal { $found_error = 1; $err_count ++; } - $inline .= "$mpiexec returned a zero status but the program returned a nonzero status\n"; + $inline .= "$g_opt{mpiexec} returned a zero status but the program returned a nonzero status\n"; } return ($found_error,$inline); } From 9460e3d62e8e58dff9d81cb62c97fe32b342f100 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 9 Dec 2021 21:58:37 -0600 Subject: [PATCH 371/607] runtests: cleanup get_mpiexec_wrapper Reduce code duplication. --- test/mpi/runtests | 148 ++++++++++++++++++++-------------------------- 1 file changed, 64 insertions(+), 84 deletions(-) diff --git a/test/mpi/runtests b/test/mpi/runtests index 81872e8c96f..1a57dad3170 100755 --- a/test/mpi/runtests +++ b/test/mpi/runtests @@ -517,6 +517,14 @@ sub RunList { } } + # Set a default timeout on tests (3 minutes for now) + my $timeout = $defaultTimeLimit; + if (defined($test_opt->{timeLimit}) && $test_opt->{timeLimit} =~ /^\d+$/) { + $timeout = $test_opt->{timeLimit}; + } + $timeout *= $defaultTimeLimitMultiplier; + $test_opt->{_timeout} = $timeout; + if (defined $test_opt->{xfail} and !$test_opt->{xfail}) { print STDERR "\"xfail=\" requires an argument\n"; } @@ -676,45 +684,21 @@ sub ProcessImplicitList { close PGMS; } } -# Run the program. -# ToDo: Add a way to limit the time that any particular program may run. -# The arguments are -# name of program, number of processes, name of routine to check results -# init for testing, timelimit, and any additional program arguments -# If the 3rd arg is not present, the a default that simply checks that the -# return status is 0 and that the output is " No Errors" is used. -sub RunMPIProgram { - my ($programname,$np,$test_opt) = @_; + +sub get_mpiexec_wrapper { + my ($np, $test_opt) = @_; + my $progArgs = join(' ', @{$test_opt->{args}}); - my $progEnv = join(' ', @{$test_opt->{envs}}); my $mpiexecArgs = join(' ', @{$test_opt->{mpiexecargs}}); if (!$mpiexecArgs and $g_opt{mpiexecargs}) { $mpiexecArgs = $g_opt{mpiexecargs}; } - - my $found_error = 0; - my $found_noerror = 0; - my $inline = ""; my $extraArgs = ""; - my $runtime = 0; - - &RunPreMsg( $programname, $np, $test_opt, $curdir ); - - unlink "err"; - - # Set a default timeout on tests (3 minutes for now) - my $timeout = $defaultTimeLimit; - if (defined($test_opt->{timeLimit}) && $test_opt->{timeLimit} =~ /^\d+$/) { - $timeout = $test_opt->{timeLimit}; - } - $timeout *= $defaultTimeLimitMultiplier; - $test_opt->{_timeout} = $timeout; - $ENV{"MPIEXEC_TIMEOUT"} = $timeout; + # # Handle the ppn (processes per node) option. - $ppnargs = ""; if ($ppnArg ne "" && $ppnMax > 0) { - $ppnargs = $ppnArg; + my $ppnargs = $ppnArg; $nn = $ppnMax; # Some systems require setting the number of processes per node # no greater than the total number of processes (e.g., aprun on Cray) @@ -723,14 +707,50 @@ sub RunMPIProgram { $extraArgs .= " " . $ppnargs; } + my $timeout = $test_opt->{_timeout}; + + # For non-MPICH versions of mpiexec, a timeout may require a different + # environment variable or command line option (e.g., for Cray aprun, + # the option -t must be given, there is no environment variable + # to set the timeout. + if (defined($timeoutArgPattern) && $timeoutArgPattern ne "") { + my $timeArg = $timeoutArgPattern; + $timeoutArg =~ s//$timeout/; + $extraArgs .= $timeoutArg + } + + # # Handle the timelimit option. if ($timelimitArg ne "" && $timeout> 0) { - $tlargs = ""; - $tlargs = $timelimitArg; + my $tlargs = $timelimitArg; $tlargs =~ s/\%d/$timeout/; $extraArgs .= " " . $tlargs; } + return "$g_opt{mpiexec} $np_arg $np $extraArgs $mpiexecArgs $program_wrapper"; +} + +# Run the program. +# ToDo: Add a way to limit the time that any particular program may run. +# The arguments are +# name of program, number of processes, name of routine to check results +# init for testing, timelimit, and any additional program arguments +# If the 3rd arg is not present, the a default that simply checks that the +# return status is 0 and that the output is " No Errors" is used. +sub RunMPIProgram { + my ($programname,$np,$test_opt) = @_; + + my $found_error = 0; + my $found_noerror = 0; + my $inline = ""; + my $runtime = 0; + + &RunPreMsg( $programname, $np, $test_opt, $curdir ); + + unlink "err"; + + $ENV{"MPIEXEC_TIMEOUT"} = $test_opt->{_timeout}; + # Run the optional setup routine. For example, the timeout tests could # be set to a shorter timeout. # FIXME: bad practice, remove @@ -762,7 +782,9 @@ sub RunMPIProgram { } } - my $cmd = "$g_opt{mpiexec} $np_arg $np $extraArgs $mpiexecArgs $program_wrapper ./$programname $progArgs"; + my $wrapper = get_mpiexec_wrapper($np, $test_opt); + my $cmd = "$wrapper ./$programname $progArgs"; + my $progEnv = join(' ', @{$test_opt->{envs}}); print STDOUT "Env includes $progEnv\n" if $verbose; print STDOUT "$cmd\n" if $verbose; print STDOUT "." if $showProgress; @@ -860,7 +882,7 @@ sub RunMPIProgram { } if ($found_error) { - &RunTestFailed( $programname, $np, $test_opt, $timeout, $curdir, $inline, $runtime ); + &RunTestFailed( $programname, $np, $test_opt, $curdir, $inline, $runtime ); } else { &RunTestPassed( $programname, $np, $test_opt, $curdir, $runtime ); @@ -872,9 +894,6 @@ sub RunMPIProgram { # into a file, and recording the output status of the run. sub AddMPIProgram { my ($programname,$np,$test_opt) = @_; - my $progArgs = join(' ', @{$test_opt->{args}}); - my $progEnv = join(' ', @{$test_opt->{envs}}); - my $mpiexecArgs = join(' ', @{$test_opt->{mpiexecargs}}); if (! -x $programname) { print STDERR "Could not find $programname!"; @@ -888,16 +907,7 @@ sub AddMPIProgram { return; } - # Set a default timeout on tests (3 minutes for now) - my $timeout = $defaultTimeLimit; - if (defined($test_opt->{timeLimit}) && $test_opt->{timeLimit} =~ /^\d+$/) { - # On some systems, there is no effective time limit on - # individual mpi program runs. In that case, we may - # want to treat these also as "run manually". - $timeout = $test_opt->{timeLimit}; - } - $timeout *= $defaultTimeLimitMultiplier; - print BATOUT "export MPIEXEC_TIMEOUT=$timeout\n"; + print BATOUT "export MPIEXEC_TIMEOUT=$test_opt->{_timeout}\n"; # Run the optional setup routine. For example, the timeout tests could # be set to a shorter timeout. @@ -906,39 +916,9 @@ sub AddMPIProgram { $test_opt->{init}->(); } - # For non-MPICH versions of mpiexec, a timeout may require a different - # environment variable or command line option (e.g., for Cray aprun, - # the option -t must be given, there is no environment variable - # to set the timeout. - $extraArgs = ""; - if (defined($timeoutArgPattern) && $timeoutArgPattern ne "") { - my $timeArg = $timeoutArgPattern; - $timeoutArg =~ s//$timeout/; - $extraArgs .= $timeoutArg - } - - # Handle the ppn (processes per node) option. - $ppnargs = ""; - if ($ppnArg ne "" && $ppnMax > 0) { - $ppnargs = $ppnArg; - $nn = $ppnMax; - # Some systems require setting the number of processes per node - # no greater than the total number of processes (e.g., aprun on Cray) - if ($nn > $np) { $nn = $np; } - $ppnargs =~ s/\%d/$nn/; - $extraArgs .= " " . $ppnargs; - } - - # Handle the timelimit option. - if ($timelimitArg ne "" && $timeout> 0) { - $tlargs = ""; - $tlargs = $timelimitArg; - $tlargs =~ s/\%d/$timeout/; - $extraArgs .= " " . $tlargs; - } - - - my $cmd = "$g_opt{mpiexec} $np_arg $np $extraArgs $program_wrapper ./$programname $progArgs"; + my $wrapper = get_mpiexec_wrapper($np, $test_opt); + my $cmd = "$wrapper ./$programname $progArgs"; + my $progEnv = join(' ', @{$test_opt->{envs}}); print STDOUT "Env includes $progEnv\n" if $verbose; print STDOUT "$cmd\n" if $verbose; print STDOUT "." if $showProgress; @@ -992,7 +972,7 @@ sub BuildMPIProgram { # in the summary file (which is otherwise written by the # RunMPIProgram step) &RunPreMsg( $programname, $np, $test_opt, $curdir ); - &RunTestFailed( $programname, $np, $test_opt, $timeout, $curdir, "Failed to build $programname; $output" ); + &RunTestFailed( $programname, $np, $test_opt, $curdir, "Failed to build $programname; $output" ); &RunPostMsg( $programname, $np, $test_opt, $curdir ); } return $rc; @@ -1225,7 +1205,7 @@ sub RunTestPassed { } } sub RunTestFailed { - my ($programname, $np, $test_opt, $timeout, $workdir, $output, $runtime) = @_; + my ($programname, $np, $test_opt, $workdir, $output, $runtime) = @_; my $progArgs = join(' ', @{$test_opt->{args}}); my $progEnv = join(' ', @{$test_opt->{envs}}); @@ -1262,7 +1242,7 @@ sub RunTestFailed { print TAPOUT " Directory: $workdir\n"; print TAPOUT " File: $programname\n"; print TAPOUT " Num-procs: $np\n"; - print TAPOUT " Timeout: $timeout\n"; + print TAPOUT " Timeout: $test_opt->{_timeout}\n"; print TAPOUT " Date: \"" . localtime() . "\"\n"; # The following would be nice, but it leads to unfortunate formatting in @@ -1305,7 +1285,7 @@ sub RunTestFailed { print JUNITOUT " Directory: $workdir\n"; print JUNITOUT " File: $programname\n"; print JUNITOUT " Num-procs: $np\n"; - print JUNITOUT " Timeout: $timeout\n"; + print JUNITOUT " Timeout: $test_opt->{_timeout}\n"; print JUNITOUT " Date: \"" . localtime() . "\"\n"; print JUNITOUT " ...\n"; From 9a95ae59264768154478a489a78ea8995ee4d5f8 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 17 Dec 2021 07:04:30 -0600 Subject: [PATCH 372/607] runtests: set $g_cwd and $g_topsrcdir Remember the working directory and top source directory. --- test/mpi/runtests | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/mpi/runtests b/test/mpi/runtests index 1a57dad3170..28e8bb3cfe4 100755 --- a/test/mpi/runtests +++ b/test/mpi/runtests @@ -49,6 +49,14 @@ use Time::HiRes qw(gettimeofday tv_interval); # Import flock constants use Fcntl qw(:flock); +use Cwd; +my $g_cwd = getcwd(); + +my $g_topsrcdir = "."; +if ($0 =~ /(.*)\/runtests$/) { + $g_topsrcdir = $1; +} + # Global variables our %g_opt; # global options. TODO: migrate global option vars into the hash $g_opt{memory_total} = 20; # Total memory in GB From 2d03140980417ef61e0e68df2d584d14f74c7ff9 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 9 Dec 2021 22:11:34 -0600 Subject: [PATCH 373/607] runtests: use strict Use strict to prevent many potential errors. Move the option variables into %g_opt hash to signify options. --- test/mpi/runtests | 477 ++++++++++++++++++++++------------------------ 1 file changed, 230 insertions(+), 247 deletions(-) diff --git a/test/mpi/runtests b/test/mpi/runtests index 28e8bb3cfe4..decf5747fe9 100755 --- a/test/mpi/runtests +++ b/test/mpi/runtests @@ -26,7 +26,7 @@ # # The format of a list file is # programname number-of-processes -# If number-of-processes is missing, $np_default is used (this is 2 but can +# If number-of-processes is missing, $g_opt{np_default} is used (this is 2 but can # be overridden with -np=new-value) # # Special feature: @@ -40,6 +40,7 @@ # can specify a different file name. # # Import the mkpath command +use strict; use File::Path; use File::Copy qw(move); @@ -68,69 +69,67 @@ $g_opt{strict} = 0; # will skip tests marked as "strict=false" $g_opt{runxfail} = 0; # will run xfailed tests $g_opt{exeext} = ""; $g_opt{mpiexec} = "mpiexec"; # Name of mpiexec program (including path, if necessary) - -# Total number of tests checked and run -our $g_total_run = 0; -our $g_total_seen = 0; -# When every tests result in timeout, it means the code has deadlocks or some major issues, -# waiting for all tests to finish is rather unnecessary. We'll keep a counter for number -# of timeouts, and abore after too many timeout failure. -our $g_num_timeout; -our $g_num_timeout_thresh = 5; +$g_opt{program_wrapper} = ''; # ppnMax is the maximum number of processes per node. -1 means ignore. # ppnArg is the argument to use to mpiexec - format is "string%d"; e.g., # "-ppn %d" -$ppnArg = ""; -$ppnMax = -1; -# timelimitArg is the argument to use to mpiexec to set the timelimit +$g_opt{ppnArg} = ""; +$g_opt{ppnMax} = -1; +# timelimitarg is the argument to use to mpiexec to set the timelimit # in seconds. The format is "string%d", e.g., "-t %d" for Cray aprun -$timelimitArg=""; +$g_opt{timelimitarg} = ""; +$g_opt{timeoutarg} = ""; # -$np_arg = "-n"; # Name of argument to specify the number of processes -$err_count = 0; # Number of programs that failed. -$skip_count = 0; # Number of programs skipped -$np_default = 2; # Default number of processes to use -$np_max = -1; # Maximum number of processes to use (overrides any - # value in the test list files. -1 is Infinity -$defaultTimeLimit = 180; # default timeout in seconds -$defaultTimeLimitMultiplier = 1.0; # default multiplier for timeout limit - -$srcdir = "."; # Used to set the source dir for testlist files - -$curdir = "."; # used to track the relative current directory +$g_opt{np_arg} = "-n"; # Name of argument to specify the number of processes +$g_opt{np_default} = 2; # Default number of processes to use +$g_opt{np_max} = -1; # Maximum number of processes to use (overrides any + # value in the test list files. -1 is Infinity +$g_opt{defaultTimeLimit} = 180; # default timeout in seconds +$g_opt{defaultTimeLimitMultiplier} = 1.0; # default multiplier for timeout limit + +$g_opt{verbose} = 0; # Set to true to get more output +$g_opt{debug} = 1; +$g_opt{showprogress} = 0; # Set to true to get a "." with each run program. +$g_opt{newline} = "\r\n"; # Set to \r\n for Windows-friendly, \n for Unix only +$g_opt{batchRun} = 0; # Set to true to batch the execution of the tests + # (i.e., run them together, then test output, + # rather than build/run/check for each test) +$g_opt{batrundir} = "."; # Set to the directory into which to run the examples +$g_opt{srcdir} = "."; # Used to set the source dir for testlist files +$g_opt{curdir} = "."; # Used to track the relative current directory +$g_opt{stopfile} = ".stopfile"; # Touch this file to abort the testing # Output forms -$xmloutput = 0; # Set to true to get xml output (also specify file) -$closeXMLOutput = 1; # Set to false to leave XML output file open to - # accept additional data -$verbose = 0; # Set to true to get more output -$showProgress = 0; # Set to true to get a "." with each run program. -$newline = "\r\n"; # Set to \r\n for Windows-friendly, \n for Unix only -$batchRun = 0; # Set to true to batch the execution of the tests - # (i.e., run them together, then test output, - # rather than build/run/check for each test) -$testCount = 0; # Used with batchRun to count tests. -$batrundir = "."; # Set to the directory into which to run the examples +$g_opt{xmlfile} = ''; +$g_opt{noxmlclose} = 0; # Set to 1 to leave XML output file open to + # accept additional data # TAP (Test Anything Protocol) output -my $tapoutput = 0; -my $tapfile = ''; -my $tapfullfile = ''; +$g_opt{tapfile} = ''; # Junit format output -my $junitoutput = 0; -my $junitfile = ''; -my $junitfullfile = ''; +$g_opt{junitfile} = ''; + +my $xmloutput; +my $tapoutput; +my $junitoutput; -$debug = 1; +# Total number of tests checked and run +our $g_total_run = 0; +our $g_total_seen = 0; +# When every tests result in timeout, it means the code has deadlocks or some major issues, +# waiting for all tests to finish is rather unnecessary. We'll keep a counter for number +# of timeouts, and abore after too many timeout failure. +our $g_num_timeout; +our $g_num_timeout_thresh = 5; -$depth = 0; # This is used to manage multiple open list files +my $err_count = 0; # Number of programs that failed. +my $skip_count = 0; # Number of programs skipped +my $testCount = 0; # Used with batchRun to count tests. # Build flags -my $program_wrapper = ''; - #--------------------------------------------------------------------------- # Get some arguments from the environment # Currently, only the following are understood: @@ -146,25 +145,21 @@ my $program_wrapper = ''; # this way.) #--------------------------------------------------------------------------- if ( defined($ENV{"VERBOSE"}) || defined($ENV{"V"}) || defined($ENV{"RUNTESTS_VERBOSE"}) ) { - $verbose = 1; + $g_opt{verbose} = 1; } if ( defined($ENV{"RUNTESTS_SHOWPROGRESS"} ) ) { - $showProgress = 1; + $g_opt{showprogress} = 1; } if (defined($ENV{"MPITEST_STOPTEST"})) { - $stopfile = $ENV{"MPITEST_STOPTEST"}; -} -else { - $stopfile = `pwd` . "/.stoptest"; - $stopfile =~ s/\r*\n*//g; # Remove any newlines (from pwd) + $g_opt{stopfile} = $ENV{"MPITEST_STOPTEST"}; } if (defined($ENV{"MPITEST_TIMEOUT"})) { - $defaultTimeLimit = $ENV{"MPITEST_TIMEOUT"}; + $g_opt{defaultTimeLimit} = $ENV{"MPITEST_TIMEOUT"}; } if (defined($ENV{"MPITEST_TIMEOUT_MULTIPLIER"})) { - $defaultTimeLimitMultiplier = $ENV{"MPITEST_TIMEOUT_MULTIPLIER"}; + $g_opt{defaultTimeLimitMultiplier} = $ENV{"MPITEST_TIMEOUT_MULTIPLIER"}; } for my $key ("memory_total", "memory_multiplier", "cleanup") { @@ -176,35 +171,35 @@ for my $key ("memory_total", "memory_multiplier", "cleanup") { # Define this to leave the XML output file open to receive additional data if (defined($ENV{'NOXMLCLOSE'}) && $ENV{'NOXMLCLOSE'} eq 'YES') { - $closeXMLOutput = 0; + $g_opt{noxmlclose} = 1; } if (defined($ENV{'MPITEST_PROGRAM_WRAPPER'})) { - $program_wrapper = $ENV{'MPITEST_PROGRAM_WRAPPER'}; + $g_opt{program_wrapper} = $ENV{'MPITEST_PROGRAM_WRAPPER'}; } if (defined($ENV{'MPITEST_BATCH'})) { if ($ENV{'MPITEST_BATCH'} eq 'YES' || $ENV{'MPITEST_BATCH'} eq 'yes') { - $batchRun = 1; + $g_opt{batchRun} = 1; } elsif ($ENV{'MPITEST_BATCH'} eq 'NO' || $ENV{'MPITEST_BATCH'} eq 'no') { - $batchRun = 0; + $g_opt{batchRun} = 0; } else { print STDERR "Unrecognized value for MPITEST_BATCH = $ENV{'MPITEST_BATCH'}\n"; } } if (defined($ENV{'MPITEST_BATCHDIR'})) { - $batrundir = $ENV{'MPITEST_BATCHDIR'}; + $g_opt{batrundir} = $ENV{'MPITEST_BATCHDIR'}; } # PPN support if (defined($ENV{'MPITEST_PPNARG'})) { - $ppnArg = $ENV{'MPITEST_PPNARG'}; + $g_opt{ppnArg} = $ENV{'MPITEST_PPNARG'}; } if (defined($ENV{'MPITEST_PPNMAX'})) { - $ppnMax = $ENV{'MPITEST_PPNMAX'}; + $g_opt{ppnMax} = $ENV{'MPITEST_PPNMAX'}; } if (defined($ENV{'MPITEST_TIMELIMITARG'})) { - $timelimitArg = $ENV{'MPITEST_TIMELIMITARG'}; + $g_opt{timelimitarg} = $ENV{'MPITEST_TIMELIMITARG'}; } if (defined($ENV{'MPITEST_MPIEXECARG'})) { $g_opt{mpiexecargs} = $ENV{'MPITEST_MPIEXECARG'}; @@ -219,58 +214,42 @@ foreach $_ (@ARGV) { # we don't want to bother to try and find it. $g_opt{mpiexec} = $1; } - elsif (/--?np=(\d+)/) { $np_default = $1; } - elsif (/--?maxnp=(\d+)/) { $np_max = $1; } - elsif (/--?ppnarg=(.*)/) { $ppnArg = $1; } - elsif (/--?ppn=(\d+)/) { $ppnMax = $1; } - elsif (/--?timelimitarg=(.*)/) { $timelimitArg = $1; } - elsif (/--?tests=(.*)/) { $listfiles = $1; } - elsif (/--?testdirs=(.*)/) { $testdirs = $1; } - elsif (/--?srcdir=(.*)/) { $srcdir = $1; } - elsif (/--?verbose/) { $verbose = 1; } - elsif (/--?showprogress/) { $showProgress = 1; } - elsif (/--?debug/) { $debug = 1; } - elsif (/--?batchdir=(.*)/) { $batrundir = $1; } - elsif (/--?batch/) { $batchRun = 1; } - elsif (/--?timeoutarg=(.*)/) { $timeoutArgPattern = $1; } + elsif (/--?np=(\d+)/) { $g_opt{np_default} = $1; } + elsif (/--?maxnp=(\d+)/) { $g_opt{np_max} = $1; } + elsif (/--?ppnarg=(.*)/) { $g_opt{ppnArg} = $1; } + elsif (/--?ppn=(\d+)/) { $g_opt{ppnMax} = $1; } + elsif (/--?timelimitarg=(.*)/) { $g_opt{timelimitarg} = $1; } + elsif (/--?tests=(.*)/) { $g_opt{listfiles} = $1; } + elsif (/--?testdirs=(.*)/) { $g_opt{testdirs} = $1; } + elsif (/--?srcdir=(.*)/) { $g_opt{srcdir} = $1; } + elsif (/--?verbose/) { $g_opt{verbose} = 1; } + elsif (/--?showprogress/) { $g_opt{showprogress} = 1; } + elsif (/--?debug/) { $g_opt{debug} = 1; } + elsif (/--?batchdir=(.*)/) { $g_opt{batrundir} = $1; } + elsif (/--?batch/) { $g_opt{batchRun} = 1; } + elsif (/--?timeoutarg=(.*)/) { $g_opt{timeoutarg} = $1; } elsif (/--?strict/) { $g_opt{strict} = 1; } elsif (/--?runxfail/) { $g_opt{runxfail} = 1; } elsif (/--?xmlfile=(.*)/) { - $xmlfile = $1; - if (! ($xmlfile =~ /^\//)) { - $thisdir = `pwd`; - chop $thisdir; - $xmlfullfile = $thisdir . "/" . $xmlfile ; - } - else { - $xmlfullfile = $xmlfile; - } + $g_opt{xmlfile} = $1; $xmloutput = 1; - open( XMLOUT, ">$xmlfile" ) || die "Cannot open $xmlfile\n"; + open( XMLOUT, ">$g_opt{xmlfile}" ) || die "Cannot open $g_opt{xmlfile}\n"; my $date = `date "+%Y-%m-%d-%H-%M"`; $date =~ s/\r?\n//; # MPISOURCE can be used to describe the source of MPI for this # test. - print XMLOUT "$newline"; - print XMLOUT "$newline"; - print XMLOUT "$newline"; - print XMLOUT "$date$newline"; + print XMLOUT "$g_opt{newline}"; + print XMLOUT "$g_opt{newline}"; + print XMLOUT "$g_opt{newline}"; + print XMLOUT "$date$g_opt{newline}"; } elsif (/--?noxmlclose/) { - $closeXMLOutput = 0; + $g_opt{noxmlclose} = 1; } elsif (/--?tapfile=(.*)/) { - $tapfile = $1; - if ($tapfile !~ m|^/|) { - $thisdir = `pwd`; - chomp $thisdir; - $tapfullfile = $thisdir . "/" . $tapfile ; - } - else { - $tapfullfile = $tapfile; - } + $g_opt{tapfile} = $1; $tapoutput = 1; - open( TAPOUT, ">$tapfile" ) || die "Cannot open $tapfile\n"; + open( TAPOUT, ">$g_opt{tapfile}" ) || die "Cannot open $g_opt{tapfile}\n"; my $date = `date "+%Y-%m-%d-%H-%M"`; $date =~ s/\r?\n//; print TAPOUT "TAP version 13\n"; @@ -280,17 +259,9 @@ foreach $_ (@ARGV) { # not print a test plan line like "1..450" until the very end } elsif (/--?junitfile=(.*)/) { - $junitfile = $1; - if ($junitfile !~ m|^/|) { - $thisdir = `pwd`; - chomp $thisdir; - $junitfullfile = $thisdir . "/" . $junitfile ; - } - else { - $junitfullfile = $junitfile; - } + $g_opt{junitfile} = $1; $junitoutput = 1; - open( JUNITOUT, ">$junitfile" ) || die "Cannot open $junitfile\n"; + open( JUNITOUT, ">$g_opt{junitfile}" ) || die "Cannot open $g_opt{junitfile}\n"; } else { print STDERR "Unrecognized argument $_\n"; @@ -305,41 +276,45 @@ foreach $_ (@ARGV) { } # Perform any post argument processing -if ($batchRun) { - if (! -d $batrundir) { - mkpath $batrundir || die "Could not create $batrundir\n"; + +$g_opt{srcdir} = Cwd::abs_path($g_opt{srcdir}); +$g_opt{stopfile} = Cwd::abs_path($g_opt{stopfile}); + +if ($g_opt{batchRun}) { + if (! -d $g_opt{batrundir}) { + mkpath $g_opt{batrundir} || die "Could not create $g_opt{batrundir}\n"; } - open( BATOUT, ">$batrundir/runtests.batch" ) || die "Could not open $batrundir/runtests.batch\n"; + open( BATOUT, ">$g_opt{batrundir}/runtests.batch" ) || die "Could not open $g_opt{batrundir}/runtests.batch\n"; } # # Process any files -if ($listfiles =~ /testlist\.gpu/) { +if ($g_opt{listfiles} =~ /testlist\.gpu/) { $g_opt{has_gpu_test} = 1; } -if ($listfiles eq "") { - if ($batchRun) { +if ($g_opt{listfiles} eq "") { + if ($g_opt{batchRun}) { print STDERR "An implicit list of tests is not permitted in batch mode. See README for more details\n"; exit(1); } else { - &ProcessImplicitList; + &ProcessImplicitList($g_opt{curdir}); } } -elsif ($testdirs ne "") { - my @all_testdirs = split /,\s*/, $testdirs; +elsif ($g_opt{testdirs} ne "") { + my @all_testdirs = split /,\s*/, $g_opt{testdirs}; foreach my $_d (@all_testdirs) { - &ProcessDir( $_d, $listfiles ); + &ProcessDir($_d, $g_opt{listfiles}, "."); } } else { - &RunList( $listfiles ); + &RunList($g_opt{listfiles}, "."); } -if ($xmloutput && $closeXMLOutput) { - print XMLOUT "$newline"; +if ($xmloutput && !$g_opt{noxmlclose}) { + print XMLOUT "$g_opt{newline}"; close XMLOUT; } @@ -357,8 +332,8 @@ if ($junitoutput) { # the second pass: insert the header # Note: the field "errors" is not used now, but reserved for future uses. - open my $JUNITIN, '<', $junitfile or die "Can't read old file: $!"; - open my $JUNITOUTNEW, '>', "$junitfile.new" or die "Can't write new file: $!"; + open my $JUNITIN, '<', $g_opt{junitfile} or die "Can't read old file: $!"; + open my $JUNITOUTNEW, '>', "$g_opt{junitfile}.new" or die "Can't write new file: $!"; my $date = `date "+%Y-%m-%d-%H-%M"`; $date =~ s/\r?\n//; print $JUNITOUTNEW "\n"; @@ -373,18 +348,19 @@ if ($junitoutput) { } close $JUNITIN; close $JUNITOUTNEW; - move("$junitfile.new","$junitfile"); + move("$g_opt{junitfile}.new","$g_opt{junitfile}"); } # Output a summary: -if ($batchRun) { - print "Programs created along with a runtest.batch file in $batrundir\n"; +if ($g_opt{batchRun}) { + print "Programs created along with a runtest.batch file in $g_opt{batrundir}\n"; print "Run that script and then use checktests to summarize the results\n"; } else { if ($err_count) { print "$err_count tests failed out of $g_total_run\n"; if ($xmloutput) { + my $xmlfullfile = get_fullfile($g_opt{xmlfile}); print "Details in $xmlfullfile\n"; } } @@ -392,9 +368,11 @@ else { print " All $g_total_run tests passed!\n"; } if ($tapoutput) { + my $tapfullfile = get_fullfile($g_opt{tapfile}); print "TAP formatted results in $tapfullfile\n"; } if ($junitoutput) { + my $junitfullfile = get_fullfile($g_opt{tapfile}); print "JUNIT formatted results in $junitfullfile\n"; } } @@ -405,28 +383,22 @@ else { # Enter a new directory and process a list file. # ProcessDir( directory-name, list-file-name ) sub ProcessDir { - my $dir = $_[0]; $dir =~ s/\/$//; - my $listfile = $_[1]; - my $savedir = `pwd`; - my $savecurdir = $curdir; - my $savesrcdir = $srcdir; + my ($dir, $listfile, $curdir) = @_; - chop $savedir; - if (substr($srcdir,0,3) eq "../") { - $srcdir = "../$srcdir"; - } + $dir =~ s/\/$//; + $curdir .= "/$dir"; - print "Processing directory $dir\n" if ($verbose || $debug); + my $savedir = cwd(); + + print "Processing directory $dir\n" if ($g_opt{verbose} || $g_opt{debug}); unless(chdir $dir) { die "Error: Cannot find directory $dir"; } - $curdir .= "/$dir"; - &RunList( $listfile ); - print "\n" if $showProgress; # Terminate line from progress output + &RunList($listfile, $curdir); + + print "\n" if $g_opt{showprogress}; # Terminate line from progress output chdir $savedir; - $curdir = $savecurdir; - $srcdir = $savesrcdir; } # --------------------------------------------------------------------------- # Run the programs listed in the file given as the argument. @@ -435,15 +407,14 @@ sub ProcessDir { # If the second value is not given, the default value is used. # sub RunList { - my $LIST = "LIST$depth"; $depth++; - my $listfile = $_[0]; + my ($listfile, $curdir) = @_; # eg: runtests -tests='testlist,testlist.dtp' my @all_listfiles = split /,\s*/, $listfile; foreach my $_f (@all_listfiles){ my $listfileSource = $_f; - if (! -s "$_f" && -s "$srcdir/$curdir/$_f" ) { - $listfileSource = "$srcdir/$curdir/$_f"; + if (! -s "$_f" && -s "$g_opt{srcdir}/$curdir/$_f" ) { + $listfileSource = "$g_opt{srcdir}/$curdir/$_f"; } if (!-f $listfileSource && $_f ne "testlist") { # just skip, do not complain missing unless it is "testlist" @@ -452,13 +423,13 @@ sub RunList { # add a timestamp to have a quick idea of how long the tests ran my @tm_list = gmtime(time() - $g_opt{start_time}); my $timestamp = sprintf("%02d:%02d:%02d", $tm_list[2], $tm_list[1], $tm_list[0]); - print "Looking in $curdir/$_f \t[$timestamp]\n" if $debug; - open( $LIST, "<$listfileSource" ) || die "Could not open $listfileSource\n"; + print "Looking in $curdir/$_f \t[$timestamp]\n" if $g_opt{debug}; + open my $LIST, "<$listfileSource" || die "Could not open $listfileSource\n"; while (<$LIST>) { # Check for stop file - if (-s $stopfile) { + if (-s $g_opt{stopfile}) { # Exit because we found a stopfile - print STDERR "Terminating test because stopfile $stopfile found\n"; + print STDERR "Terminating test because stopfile $g_opt{stopfile} found\n"; last; } if ($g_num_timeout >= $g_num_timeout_thresh && $g_num_timeout / $g_total_run > 0.5) { @@ -526,11 +497,11 @@ sub RunList { } # Set a default timeout on tests (3 minutes for now) - my $timeout = $defaultTimeLimit; + my $timeout = $g_opt{defaultTimeLimit}; if (defined($test_opt->{timeLimit}) && $test_opt->{timeLimit} =~ /^\d+$/) { $timeout = $test_opt->{timeLimit}; } - $timeout *= $defaultTimeLimitMultiplier; + $timeout *= $g_opt{defaultTimeLimitMultiplier}; $test_opt->{_timeout} = $timeout; if (defined $test_opt->{xfail} and !$test_opt->{xfail}) { @@ -540,8 +511,8 @@ sub RunList { # skip empty lines if ($programname eq "") { next; } - if ($np eq "") { $np = $np_default; } - if ($np_max > 0 && $np > $np_max) { $np = $np_max; } + if ($np eq "") { $np = $g_opt{np_default}; } + if ($g_opt{np_max} > 0 && $np > $g_opt{np_max}) { $np = $g_opt{np_max}; } # allows us to accurately output TAP test numbers without disturbing the # original totals that have traditionally been reported @@ -581,7 +552,7 @@ sub RunList { if (-d $programname) { # If a directory, go into the that directory and # look for a new list file - &ProcessDir( $programname, $listfile ); + &ProcessDir($programname, $listfile, $curdir); } else { $g_total_run++; @@ -592,21 +563,20 @@ sub RunList { $programname = $2; chdir $1 or warn "Can't chdir $1\n"; } - if (&BuildMPIProgram( $programname, $test_opt ) == 0) { - if ($batchRun == 1) { - &AddMPIProgram( $programname, $np, $test_opt ); + if (&BuildMPIProgram($programname, $np, $test_opt, $curdir) == 0) { + if ($g_opt{batchRun} == 1) { + &AddMPIProgram($programname, $np, $test_opt, $curdir); } else { - &RunMPIProgram( $programname, $np, $test_opt ); + &RunMPIProgram($programname, $np, $test_opt, $curdir); } } elsif ($test_opt->{xfail} eq '') { # We expected to run this program, so failure to build # is an error - $found_error = 1; $err_count++; } - if ($batchRun == 0) { + if ($g_opt{batchRun} == 0) { &CleanUpAfterRun( $programname, $test_opt ); } if ($save_dir) { @@ -621,16 +591,19 @@ sub RunList { # This routine tries to run all of the files in the current # directory sub ProcessImplicitList { + my $curdir = shift; + # The default is to run every file in the current directory. # If there are no built programs, build and run every file # WARNING: This assumes that anything executable should be run as # an MPI test. - $found_exec = 0; - $found_src = 0; + my $found_exec = 0; + my $found_src = 0; + my $err_count = 0; open (PGMS, "ls -1 |" ) || die "Cannot list directory\n"; while () { s/\r?\n//; - $programname = $_; + my $programname = $_; if (-d $programname) { next; } # Ignore directories if ($programname eq "runtests") { next; } # Ignore self if ($programname eq "checktests") { next; } # Ignore helper @@ -643,48 +616,48 @@ sub ProcessImplicitList { my $default_test_opt = {args=>[], envs=>[], mpiexecargs=>[]}; if ($found_exec) { - print "Found executables\n" if $debug; + print "Found executables\n" if $g_opt{debug}; open (PGMS, "ls -1 |" ) || die "Cannot list programs\n"; while () { # Check for stop file - if (-s $stopfile) { + if (-s $g_opt{stopfile}) { # Exit because we found a stopfile - print STDERR "Terminating test because stopfile $stopfile found\n"; + print STDERR "Terminating test because stopfile $g_opt{stopfile} found\n"; last; } s/\r?\n//; - $programname = $_; + my $programname = $_; if (-d $programname) { next; } # Ignore directories if ($programname eq "runtests") { next; } # Ignore self if (-x $programname) { $g_total_run++; - &RunMPIProgram( $programname, $np_default, $default_test_opt); + &RunMPIProgram( $programname, $g_opt{np_default}, $default_test_opt, $curdir); } } close PGMS; } elsif ($found_src) { - print "Found source files\n" if $debug; + print "Found source files\n" if $g_opt{debug}; open (PGMS, "ls -1 *.c |" ) || die "Cannot list programs\n"; while () { - if (-s $stopfile) { + if (-s $g_opt{stopfile}) { # Exit because we found a stopfile - print STDERR "Terminating test because stopfile $stopfile found\n"; + print STDERR "Terminating test because stopfile $g_opt{stopfile} found\n"; last; } s/\r?\n//; - $programname = $_; + my $programname = $_; # Skip messages from ls about no files if (! -s $programname) { next; } $programname =~ s/\.c//; $g_total_run++; - if (&BuildMPIProgram( $programname, "") == 0) { - &RunMPIProgram( $programname, $np_default, $default_test_opt); + my $np = $g_opt{np_default}; + if (&BuildMPIProgram($programname, $np, "", $curdir) == 0) { + &RunMPIProgram($programname, $np, $default_test_opt, $curdir); } else { # We expected to run this program, so failure to build # is an error - $found_error = 1; $err_count++; } &CleanUpAfterRun( $programname, $default_test_opt ); @@ -696,7 +669,6 @@ sub ProcessImplicitList { sub get_mpiexec_wrapper { my ($np, $test_opt) = @_; - my $progArgs = join(' ', @{$test_opt->{args}}); my $mpiexecArgs = join(' ', @{$test_opt->{mpiexecargs}}); if (!$mpiexecArgs and $g_opt{mpiexecargs}) { $mpiexecArgs = $g_opt{mpiexecargs}; @@ -705,9 +677,9 @@ sub get_mpiexec_wrapper { # # Handle the ppn (processes per node) option. - if ($ppnArg ne "" && $ppnMax > 0) { - my $ppnargs = $ppnArg; - $nn = $ppnMax; + if ($g_opt{ppnArg} ne "" && $g_opt{ppnMax} > 0) { + my $ppnargs = $g_opt{ppnArg}; + my $nn = $g_opt{ppnMax}; # Some systems require setting the number of processes per node # no greater than the total number of processes (e.g., aprun on Cray) if ($nn > $np) { $nn = $np; } @@ -721,21 +693,21 @@ sub get_mpiexec_wrapper { # environment variable or command line option (e.g., for Cray aprun, # the option -t must be given, there is no environment variable # to set the timeout. - if (defined($timeoutArgPattern) && $timeoutArgPattern ne "") { - my $timeArg = $timeoutArgPattern; + if (defined($g_opt{timeoutarg}) && $g_opt{timeoutarg} ne "") { + my $timeoutArg = $g_opt{timeoutarg}; $timeoutArg =~ s//$timeout/; $extraArgs .= $timeoutArg } # # Handle the timelimit option. - if ($timelimitArg ne "" && $timeout> 0) { - my $tlargs = $timelimitArg; + if ($g_opt{timelimitarg} ne "" && $timeout> 0) { + my $tlargs = $g_opt{timelimitarg}; $tlargs =~ s/\%d/$timeout/; $extraArgs .= " " . $tlargs; } - return "$g_opt{mpiexec} $np_arg $np $extraArgs $mpiexecArgs $program_wrapper"; + return "$g_opt{mpiexec} $g_opt{np_arg} $np $extraArgs $mpiexecArgs $g_opt{program_wrapper}"; } # Run the program. @@ -746,7 +718,7 @@ sub get_mpiexec_wrapper { # If the 3rd arg is not present, the a default that simply checks that the # return status is 0 and that the output is " No Errors" is used. sub RunMPIProgram { - my ($programname,$np,$test_opt) = @_; + my ($programname,$np,$test_opt, $curdir) = @_; my $found_error = 0; my $found_noerror = 0; @@ -791,11 +763,12 @@ sub RunMPIProgram { } my $wrapper = get_mpiexec_wrapper($np, $test_opt); + my $progArgs = join(' ', @{$test_opt->{args}}); my $cmd = "$wrapper ./$programname $progArgs"; my $progEnv = join(' ', @{$test_opt->{envs}}); - print STDOUT "Env includes $progEnv\n" if $verbose; - print STDOUT "$cmd\n" if $verbose; - print STDOUT "." if $showProgress; + print STDOUT "Env includes $progEnv\n" if $g_opt{verbose}; + print STDOUT "$cmd\n" if $g_opt{verbose}; + print STDOUT "." if $g_opt{showprogress}; # Save and restore the environment if necessary before running mpiexec. my %saveEnv; if ($test_opt->{envs}) { @@ -810,7 +783,7 @@ sub RunMPIProgram { } } my $start_time = gettimeofday(); - open ( MPIOUT, "$cmd 2>&1 |" ) || + open my $MPIOUT, "$cmd 2>&1 |" || die "Could not run ./$programname\n"; if ($test_opt->{envs}) { %ENV = %saveEnv; @@ -825,20 +798,20 @@ sub RunMPIProgram { my $F = $test_actions{$test_opt->{resultTest}}; if ($F) { - ($found_error, $inline) = $F->( MPIOUT, $programname ); + ($found_error, $inline) = $F->($MPIOUT, $programname ); } else { die "resultTest $test_opt->{resultTest} not defined!\n"; } } else { - if ($verbose) { + if ($g_opt{verbose}) { $inline = "$cmd\n"; } else { $inline = ""; } - while () { - print STDOUT $_ if $verbose; + while (<$MPIOUT>) { + print STDOUT $_ if $g_opt{verbose}; # Skip FORTRAN STOP if (/FORTRAN STOP/) { next; } $inline .= $_; @@ -863,16 +836,16 @@ sub RunMPIProgram { $err_count ++; } } - $rc = close ( MPIOUT ); + my $rc = close ($MPIOUT); my $end_time = gettimeofday(); # seconds in floating point $runtime = $end_time - $start_time; - print STDOUT "Runtime: $runtime\n" if $verbose; + print STDOUT "Runtime: $runtime\n" if $g_opt{verbose}; if ($rc == 0) { # Only generate a message if we think that the program # passed the test. if (!$found_error) { - $run_status = $?; - $signal_num = $run_status & 127; + my $run_status = $?; + my $signal_num = $run_status & 127; if ($run_status > 255) { $run_status >>= 8; } print STDERR "Program $programname exited with non-zero status $run_status\n"; if ($signal_num != 0) { @@ -901,7 +874,7 @@ sub RunMPIProgram { # This version simply writes the mpiexec command out, with the output going # into a file, and recording the output status of the run. sub AddMPIProgram { - my ($programname,$np,$test_opt) = @_; + my ($programname, $np, $test_opt, $curdir) = @_; if (! -x $programname) { print STDERR "Could not find $programname!"; @@ -925,11 +898,12 @@ sub AddMPIProgram { } my $wrapper = get_mpiexec_wrapper($np, $test_opt); + my $progArgs = join(' ', @{$test_opt->{args}}); my $cmd = "$wrapper ./$programname $progArgs"; my $progEnv = join(' ', @{$test_opt->{envs}}); - print STDOUT "Env includes $progEnv\n" if $verbose; - print STDOUT "$cmd\n" if $verbose; - print STDOUT "." if $showProgress; + print STDOUT "Env includes $progEnv\n" if $g_opt{verbose}; + print STDOUT "$cmd\n" if $g_opt{verbose}; + print STDOUT "." if $g_opt{showprogress}; # Save and restore the environment if necessary before running mpiexec. if ($progEnv ne "") { # Need to fix: @@ -944,7 +918,7 @@ sub AddMPIProgram { # which they can be run; this avoids complex code to change directories # and ensure that the output goes "into the right place". $testCount++; - rename $programname, "$batrundir/$programname"; + rename $programname, "$g_opt{batrundir}/$programname"; print BATOUT "echo \"# $cmd\" > runtests.$testCount.out\n"; # Some programs expect to run in the same directory as the executable print BATOUT "$cmd >> runtests.$testCount.out 2>&1\n"; @@ -954,14 +928,14 @@ sub AddMPIProgram { # # Return value is 0 on success, non zero on failure sub BuildMPIProgram { - my ($programname, $test_opt) = @_; + my ($programname, $np, $test_opt, $curdir) = @_; # whether we need append '.exe' if ($g_opt{exeext}) { $programname .= $g_opt{exeext}; } my $rc = 0; - if ($verbose) { print STDERR "making $programname\n"; } + if ($g_opt{verbose}) { print STDERR "making $programname\n"; } if (! -x $programname) { $test_opt->{need_remove} = 1; } else { @@ -993,10 +967,10 @@ sub CleanUpAfterRun { # issue a warning and leave the application. Of course, this # check is complicated by the lack of a standard access to the # running processes for this user in Unix. - @stillRunning = &FindRunning( $programname ); + my @stillRunning = &FindRunning( $programname ); if ($#stillRunning > -1) { - if ($verbose) { + if ($g_opt{verbose}) { print STDERR "Some programs ($programname) may still be running:\npids = "; for (my $i=0; $i <= $#stillRunning; $i++ ) { print STDERR $stillRunning[$i] . " "; @@ -1034,7 +1008,7 @@ sub FindRunning { while () { if (/$programname/) { - @fields = split(/\s+/); + my @fields = split(/\s+/); my $pid = $fields[$pidloc]; # Check that we've found a numeric pid if ($pid =~ /^\d+$/) { @@ -1057,7 +1031,7 @@ sub TestStatus { my $inline = ""; while (<$MPIOUT>) { - #print STDOUT $_ if $verbose; + #print STDOUT $_ if $g_opt{verbose}; # Skip FORTRAN STOP if (/FORTRAN STOP/) { next; } $inline .= $_; @@ -1072,10 +1046,10 @@ sub TestStatus { } } } - $rc = close ( MPIOUT ); + my $rc = close ($MPIOUT); if ($rc == 0) { - $run_status = $?; - $signal_num = $run_status & 127; + my $run_status = $?; + my $signal_num = $run_status & 127; if ($run_status > 255) { $run_status >>= 8; } } else { @@ -1101,8 +1075,8 @@ sub TestStatusNoErrors { my $found_noerror = 0; my $inline = ""; - while () { - print STDOUT $_ if $verbose; + while (<$MPIOUT>) { + print STDOUT $_ if $g_opt{verbose}; # Skip FORTRAN STOP if (/FORTRAN STOP/) { next; } $inline .= $_; @@ -1124,10 +1098,10 @@ sub TestStatusNoErrors { $err_count ++; } } - $rc = close ( MPIOUT ); + my $rc = close ($MPIOUT); if ($rc == 0) { - $run_status = $?; - $signal_num = $run_status & 127; + my $run_status = $?; + my $signal_num = $run_status & 127; if ($run_status > 255) { $run_status >>= 8; } } else { @@ -1150,16 +1124,16 @@ sub TestErrFatal { my $inline = ""; while (<$MPIOUT>) { - #print STDOUT $_ if $verbose; + #print STDOUT $_ if $g_opt{verbose}; # Skip FORTRAN STOP if (/FORTRAN STOP/) { next; } $inline .= $_; # ALL output is allowed. } - $rc = close ( MPIOUT ); + my $rc = close ($MPIOUT); if ($rc == 0) { - $run_status = $?; - $signal_num = $run_status & 127; + my $run_status = $?; + my $signal_num = $run_status & 127; if ($run_status > 255) { $run_status >>= 8; } } else { @@ -1184,16 +1158,16 @@ sub RunPreMsg { my $progArgs = join(' ', @{$test_opt->{args}}); if ($xmloutput) { - print XMLOUT "$newline$programname$newline"; - print XMLOUT "$progArgs$newline"; - print XMLOUT "$np$newline"; - print XMLOUT "$workdir$newline"; + print XMLOUT "$g_opt{newline}$programname$g_opt{newline}"; + print XMLOUT "$progArgs$g_opt{newline}"; + print XMLOUT "$np$g_opt{newline}"; + print XMLOUT "$workdir$g_opt{newline}"; } } sub RunPostMsg { my ($programname, $np, $test_opt, $workdir) = @_; if ($xmloutput) { - print XMLOUT "$newline"; + print XMLOUT "$g_opt{newline}"; } } sub RunTestPassed { @@ -1202,14 +1176,14 @@ sub RunTestPassed { my $progEnv = join(' ', @{$test_opt->{envs}}); if ($xmloutput) { - print XMLOUT "pass$newline"; - print XMLOUT "$newline"; + print XMLOUT "pass$g_opt{newline}"; + print XMLOUT "$g_opt{newline}"; } if ($tapoutput) { - print TAPOUT "ok ${total_run} - $workdir/$programname ${np} # time=$runtime\n"; + print TAPOUT "ok $g_total_run - $workdir/$programname ${np} # time=$runtime\n"; } if ($junitoutput) { - print JUNITOUT " \n"; + print JUNITOUT " \n"; } } sub RunTestFailed { @@ -1235,9 +1209,9 @@ sub RunTestFailed { $xout =~ s/\*AMP\*/&/g; # TODO: Also capture any non-printing characters (XML doesn't like them # either). - print XMLOUT "$newline"; - print XMLOUT "fail$newline"; - print XMLOUT "$newline$xout$newline"; + print XMLOUT "$g_opt{newline}"; + print XMLOUT "fail$g_opt{newline}"; + print XMLOUT "$g_opt{newline}$xout$g_opt{newline}"; } if ($tapoutput) { @@ -1245,7 +1219,7 @@ sub RunTestFailed { if ($test_opt->{xfail}) { $xfailstr = " # TODO $test_opt->{xfail}"; } - print TAPOUT "not ok ${total_run} - $workdir/$programname ${np}${xfailstr} # time=$runtime\n"; + print TAPOUT "not ok $g_total_run - $workdir/$programname ${np}${xfailstr} # time=$runtime\n"; print TAPOUT " ---\n"; print TAPOUT " Directory: $workdir\n"; print TAPOUT " File: $programname\n"; @@ -1285,10 +1259,10 @@ sub RunTestFailed { $xfailstr = " # TODO $test_opt->{xfail}"; $testtag = "skipped"; } - print JUNITOUT " \n"; + print JUNITOUT " \n"; print JUNITOUT " <${testtag} type=\"TestFailed\"\n"; - print JUNITOUT " message=\"not ok ${total_run} - $workdir/$programname ${np}${xfailstr}\">\n"; + print JUNITOUT " \n"; print JUNITOUT " \n"; - print JUNITOUT " message=\"$reason\">\n"; + print JUNITOUT " message=\"$reason\">\n"; print JUNITOUT " \n"; } @@ -1341,11 +1315,20 @@ sub InitQuickTimeout { # ---------------------------------------------------------------------------- # util routines +sub get_fullfile { + my $file = shift; + if ($file =~ /^\//) { + return $file; + } else { + return $g_cwd . "/" . $file; + } +} + # file locking using flock: the lock is acquired while the file is open and # released when file is closed (or process is terminated and OS closes the file) sub get_lock { my ($lockfile, $lock_type) = @_; - if ($verbose) { + if ($g_opt{verbose}) { print "Taking lock [$lockfile], type $lock_type\n"; } if (! -e $lockfile) { @@ -1371,7 +1354,7 @@ sub get_lock { sub relese_lock { my ($lockfile) = @_; - if ($verbose) { + if ($g_opt{verbose}) { print "Releasing lock [$lockfile]\n"; } close(LOCK); From f0822802c00523b61d4b45b6f1bdb90ce64fd445 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 11 Dec 2021 09:36:34 -0600 Subject: [PATCH 374/607] runtests: refactor TestNormal --- test/mpi/runtests | 147 +++++++++++++++++++++++----------------------- 1 file changed, 74 insertions(+), 73 deletions(-) diff --git a/test/mpi/runtests b/test/mpi/runtests index decf5747fe9..e6fd4f342db 100755 --- a/test/mpi/runtests +++ b/test/mpi/runtests @@ -372,7 +372,7 @@ else { print "TAP formatted results in $tapfullfile\n"; } if ($junitoutput) { - my $junitfullfile = get_fullfile($g_opt{tapfile}); + my $junitfullfile = get_fullfile($g_opt{junitfile}); print "JUNIT formatted results in $junitfullfile\n"; } } @@ -720,11 +720,6 @@ sub get_mpiexec_wrapper { sub RunMPIProgram { my ($programname,$np,$test_opt, $curdir) = @_; - my $found_error = 0; - my $found_noerror = 0; - my $inline = ""; - my $runtime = 0; - &RunPreMsg( $programname, $np, $test_opt, $curdir ); unlink "err"; @@ -788,75 +783,16 @@ sub RunMPIProgram { if ($test_opt->{envs}) { %ENV = %saveEnv; } - if ($test_opt->{resultTest}) { - # Read and process the output - my %test_actions = ( - TestStatus => \&TestStatus, - TestStatusNoErrors => \&TestStatusNoErrors, - TestErrFatal => \&TestErrFatal, - ); - - my $F = $test_actions{$test_opt->{resultTest}}; - if ($F) { - ($found_error, $inline) = $F->($MPIOUT, $programname ); - } else { - die "resultTest $test_opt->{resultTest} not defined!\n"; - } - } - else { - if ($g_opt{verbose}) { - $inline = "$cmd\n"; - } - else { - $inline = ""; - } - while (<$MPIOUT>) { - print STDOUT $_ if $g_opt{verbose}; - # Skip FORTRAN STOP - if (/FORTRAN STOP/) { next; } - $inline .= $_; - if (/^\s*No [Ee]rrors\s*$/ && $found_noerror == 0) { - $found_noerror = 1; - } - elsif (/^srun: error: .*: signal: Communication connection failure/) { - # skip - } - elsif (!/^\s*Test Passed\s*$/ && !/requesting checkpoint\s*$/ && !/checkpoint completed\s*$/) { - print STDERR "Unexpected output in $programname: $_"; - if (!$found_error) { - $found_error = 1; - $err_count ++; - } - } - } - if ($found_noerror == 0) { - print STDERR "Program $programname exited without No Errors\n"; - if (!$found_error) { - $found_error = 1; - $err_count ++; - } - } - my $rc = close ($MPIOUT); - my $end_time = gettimeofday(); # seconds in floating point - $runtime = $end_time - $start_time; - print STDOUT "Runtime: $runtime\n" if $g_opt{verbose}; - if ($rc == 0) { - # Only generate a message if we think that the program - # passed the test. - if (!$found_error) { - my $run_status = $?; - my $signal_num = $run_status & 127; - if ($run_status > 255) { $run_status >>= 8; } - print STDERR "Program $programname exited with non-zero status $run_status\n"; - if ($signal_num != 0) { - print STDERR "Program $programname exited with signal $signal_num\n"; - } - $found_error = 1; - $err_count ++; - } - } + my $F = get_resultTest($test_opt->{resultTest}); + my ($found_error, $inline) = $F->($MPIOUT, $programname); + if ($g_opt{verbose}) { + $inline = "$cmd\n$inline"; } + my $end_time = gettimeofday(); # seconds in floating point + my $runtime = $end_time - $start_time; + print STDOUT "Runtime: $runtime\n" if $g_opt{verbose}; + # release lock if needed if ($got_lock) { relese_lock($lockfile); @@ -1020,6 +956,71 @@ sub FindRunning { return @pids; } + +# ---------------------------------------------------------------------------- +sub get_resultTest { + my $resultTest = shift; + if (!$resultTest) { + return \&TestNormal; + } elsif ($resultTest eq "TestStatus") { + return \&TestStatus; + } elsif ($resultTest eq "TestStatusNoErrors") { + return \&TestStatusNoErrors; + } elsif ($resultTest eq "TestErrFatal") { + return \&TestErrFatal; + } else { + die "resultTest $resultTest not defined!\n"; + } +} + +sub TestNormal { + my ($MPIOUT, $programname) = @_; + my $found_error = 0; + my $found_noerror = 0; + my $inline = ""; + while (<$MPIOUT>) { + print STDOUT $_ if $g_opt{verbose}; + # Skip FORTRAN STOP + if (/FORTRAN STOP/) { next; } + $inline .= $_; + if (/^\s*No [Ee]rrors\s*$/ && $found_noerror == 0) { + $found_noerror = 1; + } + elsif (/^srun: error: .*: signal: Communication connection failure/) { + # skip + } + elsif (!/^\s*Test Passed\s*$/ && !/requesting checkpoint\s*$/ && !/checkpoint completed\s*$/) { + print STDERR "Unexpected output in $programname: $_"; + if (!$found_error) { + $found_error = 1; + $err_count ++; + } + } + } + if ($found_noerror == 0) { + print STDERR "Program $programname exited without No Errors\n"; + if (!$found_error) { + $found_error = 1; + $err_count ++; + } + } + my $rc = close ($MPIOUT); + if ($rc == 0) { + # Only generate a message if we think that the program + # passed the test. + if (!$found_error) { + my $run_status = $?; + my $signal_num = $run_status & 127; + if ($run_status > 255) { $run_status >>= 8; } + print STDERR "Program $programname exited with non-zero status $run_status\n"; + if ($signal_num != 0) { + print STDERR "Program $programname exited with signal $signal_num\n"; + } + $found_error = 1; + $err_count ++; + } + } +} # ---------------------------------------------------------------------------- # # TestStatus is a special test that reports success *only* when the From 13db3af82a1fd3730550e565d6139bfd25f5681a Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 13 Dec 2021 10:15:35 -0600 Subject: [PATCH 375/607] runtests: let test_opt hash contain all test information This cleans up the code. It also provides the flexibility to separating the loading of tests from testlists from building or running the tests. --- test/mpi/runtests | 84 +++++++++++++++++++++++++++++++---------------- 1 file changed, 56 insertions(+), 28 deletions(-) diff --git a/test/mpi/runtests b/test/mpi/runtests index e6fd4f342db..1fce949532d 100755 --- a/test/mpi/runtests +++ b/test/mpi/runtests @@ -514,6 +514,10 @@ sub RunList { if ($np eq "") { $np = $g_opt{np_default}; } if ($g_opt{np_max} > 0 && $np > $g_opt{np_max}) { $np = $g_opt{np_max}; } + $test_opt->{name} = $programname; + $test_opt->{np} = $np; + $test_opt->{dir} = $curdir; + # allows us to accurately output TAP test numbers without disturbing the # original totals that have traditionally been reported # @@ -528,7 +532,7 @@ sub RunList { # test (use strict=false for tests that use non-standard extensions) if (lc($requiresStrict) eq "false" && $g_opt{strict}) { unless (-d $programname) { - SkippedTest($programname, $np, $test_opt, $curdir, "non-strict test, strict MPI mode requested"); + SkippedTest($test_opt, "non-strict test, strict MPI mode requested"); } next; } @@ -544,7 +548,7 @@ sub RunList { # Skip xfail tests if they are not configured. Strict MPI tests that are # marked xfail will still run with --enable-strictmpi. unless (-d $programname) { - SkippedTest($programname, $np, $test_opt, $curdir, "xfail tests disabled"); + SkippedTest($test_opt, "xfail tests disabled"); } next; } @@ -563,12 +567,12 @@ sub RunList { $programname = $2; chdir $1 or warn "Can't chdir $1\n"; } - if (&BuildMPIProgram($programname, $np, $test_opt, $curdir) == 0) { + if (&BuildMPIProgram($test_opt) == 0) { if ($g_opt{batchRun} == 1) { - &AddMPIProgram($programname, $np, $test_opt, $curdir); + &AddMPIProgram($test_opt); } else { - &RunMPIProgram($programname, $np, $test_opt, $curdir); + &RunMPIProgram($test_opt); } } elsif ($test_opt->{xfail} eq '') { @@ -577,7 +581,7 @@ sub RunList { $err_count++; } if ($g_opt{batchRun} == 0) { - &CleanUpAfterRun( $programname, $test_opt ); + &CleanUpAfterRun($test_opt); } if ($save_dir) { chdir $save_dir; @@ -614,7 +618,6 @@ sub ProcessImplicitList { } close PGMS; - my $default_test_opt = {args=>[], envs=>[], mpiexecargs=>[]}; if ($found_exec) { print "Found executables\n" if $g_opt{debug}; open (PGMS, "ls -1 |" ) || die "Cannot list programs\n"; @@ -631,7 +634,8 @@ sub ProcessImplicitList { if ($programname eq "runtests") { next; } # Ignore self if (-x $programname) { $g_total_run++; - &RunMPIProgram( $programname, $g_opt{np_default}, $default_test_opt, $curdir); + my $test_opt = {name=>$programname, np=>$g_opt{np_default}, dir=>$curdir, args=>[], envs=>[], mpiexecargs=>[]}; + &RunMPIProgram($test_opt); } } close PGMS; @@ -652,15 +656,16 @@ sub ProcessImplicitList { $programname =~ s/\.c//; $g_total_run++; my $np = $g_opt{np_default}; - if (&BuildMPIProgram($programname, $np, "", $curdir) == 0) { - &RunMPIProgram($programname, $np, $default_test_opt, $curdir); + my $test_opt = {name=>$programname, np=>$np, dir=>$curdir}; + if (&BuildMPIProgram($test_opt) == 0) { + &RunMPIProgram($test_opt); } else { # We expected to run this program, so failure to build # is an error $err_count++; } - &CleanUpAfterRun( $programname, $default_test_opt ); + &CleanUpAfterRun($test_opt); } close PGMS; } @@ -718,9 +723,12 @@ sub get_mpiexec_wrapper { # If the 3rd arg is not present, the a default that simply checks that the # return status is 0 and that the output is " No Errors" is used. sub RunMPIProgram { - my ($programname,$np,$test_opt, $curdir) = @_; + my ($test_opt) = @_; + my $programname = $test_opt->{name}; + my $np = $test_opt->{np}; + my $curdir = $test_opt->{dir}; - &RunPreMsg( $programname, $np, $test_opt, $curdir ); + &RunPreMsg($test_opt); unlink "err"; @@ -748,7 +756,7 @@ sub RunMPIProgram { # implicit lock by checking memory annotation $lockfile="/tmp/runtests-mem.lock"; if ($test_opt->{mem} > $g_opt{memory_total}) { - SkippedTest($programname, $np, $test_opt, $curdir, "xfail due to memory requirement"); + SkippedTest($test_opt, "xfail due to memory requirement"); next; } elsif ($test_opt->{mem} * $g_opt{memory_multiplier} > $g_opt{memory_total} ) { $got_lock = get_lock($lockfile, LOCK_EX); @@ -799,18 +807,21 @@ sub RunMPIProgram { } if ($found_error) { - &RunTestFailed( $programname, $np, $test_opt, $curdir, $inline, $runtime ); + &RunTestFailed($test_opt, $inline, $runtime ); } else { - &RunTestPassed( $programname, $np, $test_opt, $curdir, $runtime ); + &RunTestPassed($test_opt, $runtime); } - &RunPostMsg( $programname, $np, $test_opt, $curdir ); + &RunPostMsg($test_opt); } # This version simply writes the mpiexec command out, with the output going # into a file, and recording the output status of the run. sub AddMPIProgram { - my ($programname, $np, $test_opt, $curdir) = @_; + my ($test_opt) = @_; + my $programname = $test_opt->{name}; + my $np = $test_opt->{np}; + my $curdir = $test_opt->{dir}; if (! -x $programname) { print STDERR "Could not find $programname!"; @@ -864,7 +875,9 @@ sub AddMPIProgram { # # Return value is 0 on success, non zero on failure sub BuildMPIProgram { - my ($programname, $np, $test_opt, $curdir) = @_; + my ($test_opt) = @_; + my $programname = $test_opt->{name}; + # whether we need append '.exe' if ($g_opt{exeext}) { $programname .= $g_opt{exeext}; @@ -889,15 +902,16 @@ sub BuildMPIProgram { # This will ensure that failures to build will end up # in the summary file (which is otherwise written by the # RunMPIProgram step) - &RunPreMsg( $programname, $np, $test_opt, $curdir ); - &RunTestFailed( $programname, $np, $test_opt, $curdir, "Failed to build $programname; $output" ); - &RunPostMsg( $programname, $np, $test_opt, $curdir ); + &RunPreMsg($test_opt); + &RunTestFailed($test_opt, "Failed to build $programname; $output", 0); + &RunPostMsg($test_opt); } return $rc; } sub CleanUpAfterRun { - my ($programname, $test_opt) = @_; + my ($test_opt) = @_; + my $programname = $test_opt->{name}; # Check for that this program has exited. If it is still running, # issue a warning and leave the application. Of course, this @@ -1155,7 +1169,11 @@ sub TestErrFatal { # RunPostMsg - Call at end of each test # sub RunPreMsg { - my ($programname,$np,$test_opt,$workdir) = @_; + my ($test_opt) = @_; + my $programname = $test_opt->{name}; + my $np = $test_opt->{np}; + my $workdir = $test_opt->{dir}; + my $progArgs = join(' ', @{$test_opt->{args}}); if ($xmloutput) { @@ -1166,13 +1184,17 @@ sub RunPreMsg { } } sub RunPostMsg { - my ($programname, $np, $test_opt, $workdir) = @_; + my ($test_opt) = @_; if ($xmloutput) { print XMLOUT "$g_opt{newline}"; } } sub RunTestPassed { - my ($programname, $np, $test_opt, $workdir, $runtime) = @_; + my ($test_opt, $runtime) = @_; + my $programname = $test_opt->{name}; + my $np = $test_opt->{np}; + my $workdir = $test_opt->{dir}; + my $progArgs = join(' ', @{$test_opt->{args}}); my $progEnv = join(' ', @{$test_opt->{envs}}); @@ -1188,7 +1210,10 @@ sub RunTestPassed { } } sub RunTestFailed { - my ($programname, $np, $test_opt, $workdir, $output, $runtime) = @_; + my ($test_opt, $output, $runtime) = @_; + my $programname = $test_opt->{name}; + my $np = $test_opt->{np}; + my $workdir = $test_opt->{dir}; my $progArgs = join(' ', @{$test_opt->{args}}); my $progEnv = join(' ', @{$test_opt->{envs}}); @@ -1288,7 +1313,10 @@ sub RunTestFailed { } sub SkippedTest { - my ($programname, $np, $test_opt, $workdir, $reason) = @_; + my ($test_opt, $reason) = @_; + my $programname = $test_opt->{name}; + my $np = $test_opt->{np}; + my $workdir = $test_opt->{dir}; my $progArgs = join(' ', @{$test_opt->{args}}); my $progEnv = join(' ', @{$test_opt->{envs}}); From ac5cb16fbe6a5dc3901b59cf8359744f6c97a305 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 13 Dec 2021 21:35:39 -0600 Subject: [PATCH 376/607] runtests: separate loading tests from running tests --- test/mpi/runtests | 205 ++++++++++++++++++++++------------------------ 1 file changed, 97 insertions(+), 108 deletions(-) diff --git a/test/mpi/runtests b/test/mpi/runtests index 1fce949532d..444a90329e6 100755 --- a/test/mpi/runtests +++ b/test/mpi/runtests @@ -97,7 +97,6 @@ $g_opt{batchRun} = 0; # Set to true to batch the execution of the test # rather than build/run/check for each test) $g_opt{batrundir} = "."; # Set to the directory into which to run the examples $g_opt{srcdir} = "."; # Used to set the source dir for testlist files -$g_opt{curdir} = "."; # Used to track the relative current directory $g_opt{stopfile} = ".stopfile"; # Touch this file to abort the testing # Output forms @@ -294,25 +293,26 @@ if ($g_opt{listfiles} =~ /testlist\.gpu/) { $g_opt{has_gpu_test} = 1; } +my @all_tests; if ($g_opt{listfiles} eq "") { if ($g_opt{batchRun}) { print STDERR "An implicit list of tests is not permitted in batch mode. See README for more details\n"; exit(1); } - else { - &ProcessImplicitList($g_opt{curdir}); - } + LoadImplicitTests(".", \@all_tests); } elsif ($g_opt{testdirs} ne "") { my @all_testdirs = split /,\s*/, $g_opt{testdirs}; foreach my $_d (@all_testdirs) { - &ProcessDir($_d, $g_opt{listfiles}, "."); + LoadTests("./$_d", \@all_tests); } } else { - &RunList($g_opt{listfiles}, "."); + LoadTests(".", \@all_tests); } +RunTests(\@all_tests); + if ($xmloutput && !$g_opt{noxmlclose}) { print XMLOUT "$g_opt{newline}"; close XMLOUT; @@ -376,73 +376,43 @@ else { print "JUNIT formatted results in $junitfullfile\n"; } } -# +# # --------------------------------------------------------------------------- # Routines # -# Enter a new directory and process a list file. -# ProcessDir( directory-name, list-file-name ) -sub ProcessDir { - my ($dir, $listfile, $curdir) = @_; - - $dir =~ s/\/$//; - $curdir .= "/$dir"; - - my $savedir = cwd(); - - print "Processing directory $dir\n" if ($g_opt{verbose} || $g_opt{debug}); - unless(chdir $dir) { - die "Error: Cannot find directory $dir"; - } - - &RunList($listfile, $curdir); - - print "\n" if $g_opt{showprogress}; # Terminate line from progress output - chdir $savedir; -} -# --------------------------------------------------------------------------- # Run the programs listed in the file given as the argument. # This file describes the tests in the format # programname number-of-processes [ key=value ... ] # If the second value is not given, the default value is used. # -sub RunList { - my ($listfile, $curdir) = @_; - +sub LoadTests { + my ($curdir, $all_tests) = @_; + print "Load tests in $curdir\n" if $g_opt{debug}; # eg: runtests -tests='testlist,testlist.dtp' - my @all_listfiles = split /,\s*/, $listfile; + my @all_listfiles = split /,\s*/, $g_opt{listfiles}; foreach my $_f (@all_listfiles){ - my $listfileSource = $_f; - if (! -s "$_f" && -s "$g_opt{srcdir}/$curdir/$_f" ) { + die if "$curdir/$_f"=~/attr\/attr/; + my $listfileSource = "$curdir/$_f"; + if (! -s "$listfileSource" && -s "$g_opt{srcdir}/$listfileSource" ) { $listfileSource = "$g_opt{srcdir}/$curdir/$_f"; } if (!-f $listfileSource && $_f ne "testlist") { # just skip, do not complain missing unless it is "testlist" next; } - # add a timestamp to have a quick idea of how long the tests ran - my @tm_list = gmtime(time() - $g_opt{start_time}); - my $timestamp = sprintf("%02d:%02d:%02d", $tm_list[2], $tm_list[1], $tm_list[0]); - print "Looking in $curdir/$_f \t[$timestamp]\n" if $g_opt{debug}; open my $LIST, "<$listfileSource" || die "Could not open $listfileSource\n"; while (<$LIST>) { - # Check for stop file - if (-s $g_opt{stopfile}) { - # Exit because we found a stopfile - print STDERR "Terminating test because stopfile $g_opt{stopfile} found\n"; - last; - } - if ($g_num_timeout >= $g_num_timeout_thresh && $g_num_timeout / $g_total_run > 0.5) { - # Too many timeout failures - print STDERR "Terminating test because of too many timeout failures\n"; - last; - } # Skip comments s/#.*//g; # Remove any trailing newlines/returns s/\r?\n//; # Remove any leading whitespace s/^\s*//; + + # Skip empty lines + if (/^\s*$/) { + next; + } # Some tests require that support routines are built first # This is specified with !: if (/^\s*\!([^:]*):(.*)/) { @@ -451,11 +421,19 @@ sub RunList { `cd $1 && make $2`; next; } + # List file entries have the form: # program [ np [ name=value ... ] ] # See files errhan/testlist, init/testlist, and spawn/testlist # for examples of using the key=value form my @args = split(/\s+/,$_); + my $programname = $args[0]; + + if (-d "$curdir/$programname") { + LoadTests("$curdir/$programname", $all_tests); + next; + } + my $test_opt = {args=>[], envs=>[], mpiexecargs=>[]}; if ($g_opt{has_gpu_test}) { if ($_f ne "testlist.gpu") { @@ -465,7 +443,6 @@ sub RunList { } } - my $programname = $args[0]; my $np = ""; my $requiresStrict = ""; @@ -517,23 +494,20 @@ sub RunList { $test_opt->{name} = $programname; $test_opt->{np} = $np; $test_opt->{dir} = $curdir; + if ($test_opt->{name} =~/^(\S+)\/(\S+)$/) { + # TODO: allow absolute path + $test_opt->{dir} .= "/$1"; + $test_opt->{name} = $2; + } # allows us to accurately output TAP test numbers without disturbing the # original totals that have traditionally been reported - # - # These "unless" blocks are ugly, but permit us to honor skipping - # criteria for directories as well without counting directories as tests - # in our XML/TAP output. - unless (-d $programname) { - $g_total_seen++; - } + $g_total_seen++; # Check whether strict is required by MPI but not by the # test (use strict=false for tests that use non-standard extensions) if (lc($requiresStrict) eq "false" && $g_opt{strict}) { - unless (-d $programname) { - SkippedTest($test_opt, "non-strict test, strict MPI mode requested"); - } + SkippedTest($test_opt, "non-strict test, strict MPI mode requested"); next; } @@ -547,55 +521,77 @@ sub RunList { if ($test_opt->{xfail} && !$g_opt{runxfail}) { # Skip xfail tests if they are not configured. Strict MPI tests that are # marked xfail will still run with --enable-strictmpi. - unless (-d $programname) { - SkippedTest($test_opt, "xfail tests disabled"); - } + SkippedTest($test_opt, "xfail tests disabled"); next; } - if (-d $programname) { - # If a directory, go into the that directory and - # look for a new list file - &ProcessDir($programname, $listfile, $curdir); + push @$all_tests, $test_opt; + } + close( $LIST ); + } +} + +sub RunTests { + my ($all_tests) = @_; + + my $curdir; + my $cwd; + foreach my $test_opt (@$all_tests) { + # Check for stop file + if (-s $g_opt{stopfile}) { + # Exit because we found a stopfile + print STDERR "Terminating test because stopfile $g_opt{stopfile} found\n"; + last; + } + + # Check for too many TIMEOUTs + if ($g_num_timeout >= $g_num_timeout_thresh && $g_num_timeout / $g_total_run > 0.5) { + # Too many timeout failures + print STDERR "Terminating test because of too many timeout failures\n"; + last; + } + + $g_total_run++; + if ($test_opt->{dir} ne $curdir) { + $curdir = $test_opt->{dir}; + if (!$cwd) { + $cwd = getcwd(); + } else { + # $curdir is relave to $cwd + chdir $cwd or die "Can't chdir $cwd\n"; + } + # add a timestamp to have a quick idea of how long the tests ran + my @tm_list = gmtime(time() - $g_opt{start_time}); + my $timestamp = sprintf("%02d:%02d:%02d", $tm_list[2], $tm_list[1], $tm_list[0]); + print "Running tests in $curdir [$timestamp]\n" if $g_opt{debug}; + chdir $curdir or die "Can't chdir $curdir\n"; + } + if (&BuildMPIProgram($test_opt) == 0) { + if ($g_opt{batchRun} == 1) { + &AddMPIProgram($test_opt); } else { - $g_total_run++; - my $save_dir; - if ($programname =~/^(\S+)\/(\S+)$/) { - $save_dir = `pwd`; - chomp $save_dir; - $programname = $2; - chdir $1 or warn "Can't chdir $1\n"; - } - if (&BuildMPIProgram($test_opt) == 0) { - if ($g_opt{batchRun} == 1) { - &AddMPIProgram($test_opt); - } - else { - &RunMPIProgram($test_opt); - } - } - elsif ($test_opt->{xfail} eq '') { - # We expected to run this program, so failure to build - # is an error - $err_count++; - } - if ($g_opt{batchRun} == 0) { - &CleanUpAfterRun($test_opt); - } - if ($save_dir) { - chdir $save_dir; - } + &RunMPIProgram($test_opt); } } - close( $LIST ); + elsif ($test_opt->{xfail} eq '') { + # We expected to run this program, so failure to build + # is an error + $err_count++; + } + if ($g_opt{batchRun} == 0) { + &CleanUpAfterRun($test_opt); + } + } + if ($cwd) { + chdir $cwd; } } # -# This routine tries to run all of the files in the current +# This routine tries to load tests from all of the files in the current # directory -sub ProcessImplicitList { - my $curdir = shift; +sub LoadImplicitTests { + my ($curdir, $all_tests) = @_; # The default is to run every file in the current directory. # If there are no built programs, build and run every file @@ -635,7 +631,7 @@ sub ProcessImplicitList { if (-x $programname) { $g_total_run++; my $test_opt = {name=>$programname, np=>$g_opt{np_default}, dir=>$curdir, args=>[], envs=>[], mpiexecargs=>[]}; - &RunMPIProgram($test_opt); + push @$all_tests, $test_opt; } } close PGMS; @@ -657,15 +653,7 @@ sub ProcessImplicitList { $g_total_run++; my $np = $g_opt{np_default}; my $test_opt = {name=>$programname, np=>$np, dir=>$curdir}; - if (&BuildMPIProgram($test_opt) == 0) { - &RunMPIProgram($test_opt); - } - else { - # We expected to run this program, so failure to build - # is an error - $err_count++; - } - &CleanUpAfterRun($test_opt); + push @$all_tests, $test_opt; } close PGMS; } @@ -1034,6 +1022,7 @@ sub TestNormal { $err_count ++; } } + return ($found_error, $inline); } # ---------------------------------------------------------------------------- # From 94c57e7cacdccbee418cb8a6541de12acec073af Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 17 Dec 2021 07:26:49 -0600 Subject: [PATCH 377/607] runtests: add report of total runtime --- test/mpi/runtests | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/mpi/runtests b/test/mpi/runtests index 444a90329e6..4d0f5bf32a8 100755 --- a/test/mpi/runtests +++ b/test/mpi/runtests @@ -58,6 +58,8 @@ if ($0 =~ /(.*)\/runtests$/) { $g_topsrcdir = $1; } +my $g_starttime = time(); + # Global variables our %g_opt; # global options. TODO: migrate global option vars into the hash $g_opt{memory_total} = 20; # Total memory in GB @@ -357,15 +359,17 @@ if ($g_opt{batchRun}) { print "Run that script and then use checktests to summarize the results\n"; } else { + my $t = time() - $g_starttime; + my $total_runtime = sprintf "total runtime: %d min %d sec", $t / 60, $t % 60; if ($err_count) { - print "$err_count tests failed out of $g_total_run\n"; + print "$err_count tests failed out of $g_total_run ($total_runtime)\n"; if ($xmloutput) { my $xmlfullfile = get_fullfile($g_opt{xmlfile}); print "Details in $xmlfullfile\n"; } } else { - print " All $g_total_run tests passed!\n"; + print " All $g_total_run tests passed! ($total_runtime)\n"; } if ($tapoutput) { my $tapfullfile = get_fullfile($g_opt{tapfile}); From e99eaeba654f70c033eaaf129e1a83c56aeb7762 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 17 Dec 2021 08:44:51 -0600 Subject: [PATCH 378/607] runtests: clean up global variable naming Consistently use prefix g_ to name global variables. It is not necessary to use our since it is not a module. Update g_err_count in RunTestFailed. --- test/mpi/runtests | 57 +++++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 34 deletions(-) diff --git a/test/mpi/runtests b/test/mpi/runtests index 4d0f5bf32a8..93770a09584 100755 --- a/test/mpi/runtests +++ b/test/mpi/runtests @@ -61,7 +61,7 @@ if ($0 =~ /(.*)\/runtests$/) { my $g_starttime = time(); # Global variables -our %g_opt; # global options. TODO: migrate global option vars into the hash +my %g_opt; # global options. TODO: migrate global option vars into the hash $g_opt{memory_total} = 20; # Total memory in GB $g_opt{memory_multiplier} = 1; # No of simutaneous jobs $g_opt{cleanup} = 1; # Whether to remove the compiled programs @@ -117,17 +117,17 @@ my $tapoutput; my $junitoutput; # Total number of tests checked and run -our $g_total_run = 0; -our $g_total_seen = 0; +my $g_total_run = 0; +my $g_total_seen = 0; # When every tests result in timeout, it means the code has deadlocks or some major issues, # waiting for all tests to finish is rather unnecessary. We'll keep a counter for number # of timeouts, and abore after too many timeout failure. -our $g_num_timeout; -our $g_num_timeout_thresh = 5; +my $g_num_timeout; +my $g_num_timeout_thresh = 5; -my $err_count = 0; # Number of programs that failed. -my $skip_count = 0; # Number of programs skipped -my $testCount = 0; # Used with batchRun to count tests. +my $g_err_count = 0; # Number of programs that failed. +my $g_skip_count = 0; # Number of programs skipped +my $g_testCount = 0; # Used with batchRun to count tests. # Build flags @@ -339,9 +339,9 @@ if ($junitoutput) { my $date = `date "+%Y-%m-%d-%H-%M"`; $date =~ s/\r?\n//; print $JUNITOUTNEW "\n"; - print $JUNITOUTNEW " \n"; @@ -361,8 +361,8 @@ if ($g_opt{batchRun}) { else { my $t = time() - $g_starttime; my $total_runtime = sprintf "total runtime: %d min %d sec", $t / 60, $t % 60; - if ($err_count) { - print "$err_count tests failed out of $g_total_run ($total_runtime)\n"; + if ($g_err_count) { + print "$g_err_count tests failed out of $g_total_run ($total_runtime)\n"; if ($xmloutput) { my $xmlfullfile = get_fullfile($g_opt{xmlfile}); print "Details in $xmlfullfile\n"; @@ -578,11 +578,6 @@ sub RunTests { &RunMPIProgram($test_opt); } } - elsif ($test_opt->{xfail} eq '') { - # We expected to run this program, so failure to build - # is an error - $err_count++; - } if ($g_opt{batchRun} == 0) { &CleanUpAfterRun($test_opt); } @@ -603,7 +598,6 @@ sub LoadImplicitTests { # an MPI test. my $found_exec = 0; my $found_src = 0; - my $err_count = 0; open (PGMS, "ls -1 |" ) || die "Cannot list directory\n"; while () { s/\r?\n//; @@ -666,8 +660,10 @@ sub LoadImplicitTests { sub get_mpiexec_wrapper { my ($np, $test_opt) = @_; - my $mpiexecArgs = join(' ', @{$test_opt->{mpiexecargs}}); - if (!$mpiexecArgs and $g_opt{mpiexecargs}) { + my $mpiexecArgs; + if ($test_opt->{mpiexecargs} and @{$test_opt->{mpiexecargs}}) { + $mpiexecArgs = join(' ', @{$test_opt->{mpiexecargs}}); + } elsif ($g_opt{mpiexecargs}) { $mpiexecArgs = $g_opt{mpiexecargs}; } my $extraArgs = ""; @@ -856,12 +852,12 @@ sub AddMPIProgram { # The approach here is to move the test codes to a single directory from # which they can be run; this avoids complex code to change directories # and ensure that the output goes "into the right place". - $testCount++; + $g_testCount++; rename $programname, "$g_opt{batrundir}/$programname"; - print BATOUT "echo \"# $cmd\" > runtests.$testCount.out\n"; + print BATOUT "echo \"# $cmd\" > runtests.$g_testCount.out\n"; # Some programs expect to run in the same directory as the executable - print BATOUT "$cmd >> runtests.$testCount.out 2>&1\n"; - print BATOUT "echo \$? > runtests.$testCount.status\n"; + print BATOUT "$cmd >> runtests.$g_testCount.out 2>&1\n"; + print BATOUT "echo \$? > runtests.$g_testCount.status\n"; } # @@ -999,7 +995,6 @@ sub TestNormal { print STDERR "Unexpected output in $programname: $_"; if (!$found_error) { $found_error = 1; - $err_count ++; } } } @@ -1007,7 +1002,6 @@ sub TestNormal { print STDERR "Program $programname exited without No Errors\n"; if (!$found_error) { $found_error = 1; - $err_count ++; } } my $rc = close ($MPIOUT); @@ -1023,7 +1017,6 @@ sub TestNormal { print STDERR "Program $programname exited with signal $signal_num\n"; } $found_error = 1; - $err_count ++; } } return ($found_error, $inline); @@ -1050,7 +1043,6 @@ sub TestStatus { print STDERR "Unexpected output in $programname: $_"; if (!$found_error) { $found_error = 1; - $err_count ++; } } } @@ -1064,7 +1056,6 @@ sub TestStatus { # This test *requires* non-zero return codes if (!$found_error) { $found_error = 1; - $err_count ++; } $inline .= "$g_opt{mpiexec} returned a zero status but the program returned a nonzero status\n"; } @@ -1095,7 +1086,6 @@ sub TestStatusNoErrors { print STDERR "Unexpected output in $programname: $_"; if (!$found_error) { $found_error = 1; - $err_count ++; } } } @@ -1103,7 +1093,6 @@ sub TestStatusNoErrors { print STDERR "Program $programname exited without No Errors\n"; if (!$found_error) { $found_error = 1; - $err_count ++; } } my $rc = close ($MPIOUT); @@ -1116,7 +1105,6 @@ sub TestStatusNoErrors { # This test *requires* non-zero return codes if (!$found_error) { $found_error = 1; - $err_count ++; } $inline .= "$g_opt{mpiexec} returned a zero status but the program required a non-zero status\n"; } @@ -1148,7 +1136,6 @@ sub TestErrFatal { # This test *requires* non-zero return codes if (!$found_error) { $found_error = 1; - $err_count ++; } $inline .= "$g_opt{mpiexec} returned a zero status but the program returned a nonzero status\n"; } @@ -1303,6 +1290,8 @@ sub RunTestFailed { print JUNITOUT " ]]>\n"; print JUNITOUT " \n"; } + + $g_err_count++; } sub SkippedTest { @@ -1325,7 +1314,7 @@ sub SkippedTest { print JUNITOUT " \n"; } - $skip_count++; + $g_skip_count++; } # ---------------------------------------------------------------------------- From 2a2b2a3782c73a8cfad30e7f14dbf75547357ccc Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 23 Dec 2021 14:48:24 -0600 Subject: [PATCH 379/607] runtests: update global counters consistently Only update global test counters in one of the three test reporting routines to ensure consistency. --- test/mpi/runtests | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/test/mpi/runtests b/test/mpi/runtests index 93770a09584..4283d70f298 100755 --- a/test/mpi/runtests +++ b/test/mpi/runtests @@ -117,16 +117,18 @@ my $tapoutput; my $junitoutput; # Total number of tests checked and run -my $g_total_run = 0; -my $g_total_seen = 0; +my $g_total_seen = 0; # $g_ok_count + $g_err_count + $g_skip_count +my $g_total_run = 0; # $g_ok_count + $g_err_count +my $g_ok_count = 0; # Number of programs that succeeded. +my $g_err_count = 0; # Number of programs that failed. +my $g_skip_count = 0; # Number of programs skipped + # When every tests result in timeout, it means the code has deadlocks or some major issues, # waiting for all tests to finish is rather unnecessary. We'll keep a counter for number # of timeouts, and abore after too many timeout failure. my $g_num_timeout; my $g_num_timeout_thresh = 5; -my $g_err_count = 0; # Number of programs that failed. -my $g_skip_count = 0; # Number of programs skipped my $g_testCount = 0; # Used with batchRun to count tests. # Build flags @@ -504,10 +506,6 @@ sub LoadTests { $test_opt->{name} = $2; } - # allows us to accurately output TAP test numbers without disturbing the - # original totals that have traditionally been reported - $g_total_seen++; - # Check whether strict is required by MPI but not by the # test (use strict=false for tests that use non-standard extensions) if (lc($requiresStrict) eq "false" && $g_opt{strict}) { @@ -554,8 +552,6 @@ sub RunTests { print STDERR "Terminating test because of too many timeout failures\n"; last; } - - $g_total_run++; if ($test_opt->{dir} ne $curdir) { $curdir = $test_opt->{dir}; if (!$cwd) { @@ -627,7 +623,6 @@ sub LoadImplicitTests { if (-d $programname) { next; } # Ignore directories if ($programname eq "runtests") { next; } # Ignore self if (-x $programname) { - $g_total_run++; my $test_opt = {name=>$programname, np=>$g_opt{np_default}, dir=>$curdir, args=>[], envs=>[], mpiexecargs=>[]}; push @$all_tests, $test_opt; } @@ -648,7 +643,6 @@ sub LoadImplicitTests { # Skip messages from ls about no files if (! -s $programname) { next; } $programname =~ s/\.c//; - $g_total_run++; my $np = $g_opt{np_default}; my $test_opt = {name=>$programname, np=>$np, dir=>$curdir}; push @$all_tests, $test_opt; @@ -1178,12 +1172,16 @@ sub RunTestPassed { my $progArgs = join(' ', @{$test_opt->{args}}); my $progEnv = join(' ', @{$test_opt->{envs}}); + $g_total_seen++; + $g_total_run++; + $g_ok_count++; + if ($xmloutput) { print XMLOUT "pass$g_opt{newline}"; print XMLOUT "$g_opt{newline}"; } if ($tapoutput) { - print TAPOUT "ok $g_total_run - $workdir/$programname ${np} # time=$runtime\n"; + print TAPOUT "ok $g_total_seen - $workdir/$programname ${np} # time=$runtime\n"; } if ($junitoutput) { print JUNITOUT " \n"; @@ -1197,6 +1195,10 @@ sub RunTestFailed { my $progArgs = join(' ', @{$test_opt->{args}}); my $progEnv = join(' ', @{$test_opt->{envs}}); + $g_total_seen++; + $g_total_run++; + $g_err_count++; + # count # of timeout when tests are configured with sufficient timeLimit if ($test_opt->{_timeout} > 60) { if ($runtime - $test_opt->{_timeout} >= -10) { @@ -1225,7 +1227,7 @@ sub RunTestFailed { if ($test_opt->{xfail}) { $xfailstr = " # TODO $test_opt->{xfail}"; } - print TAPOUT "not ok $g_total_run - $workdir/$programname ${np}${xfailstr} # time=$runtime\n"; + print TAPOUT "not ok $g_total_seen - $workdir/$programname ${np}${xfailstr} # time=$runtime\n"; print TAPOUT " ---\n"; print TAPOUT " Directory: $workdir\n"; print TAPOUT " File: $programname\n"; @@ -1290,8 +1292,6 @@ sub RunTestFailed { print JUNITOUT " ]]>\n"; print JUNITOUT " \n"; } - - $g_err_count++; } sub SkippedTest { @@ -1302,6 +1302,9 @@ sub SkippedTest { my $progArgs = join(' ', @{$test_opt->{args}}); my $progEnv = join(' ', @{$test_opt->{envs}}); + $g_total_seen++; + $g_skip_count++; + # simply omit from the XML output if ($tapoutput) { @@ -1313,8 +1316,6 @@ sub SkippedTest { print JUNITOUT " message=\"$reason\">\n"; print JUNITOUT " \n"; } - - $g_skip_count++; } # ---------------------------------------------------------------------------- From 9528191b883ebcc7aafe47668879a78df580c768 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 10 Jan 2022 14:52:46 -0600 Subject: [PATCH 380/607] runtests: pick up MPIEXEC environment variable This provide an alternative of way of customize mpiexec path in addition to using the command line option -mpiexec=path/to/mpiexec. --- test/mpi/configure.ac | 12 ------------ test/mpi/runtests | 3 +++ 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index 5ba8a7b5468..a4de99589a6 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -349,7 +349,6 @@ PAC_GET_EXENAME("mpicc", MPICC_NAME) PAC_GET_EXENAME("mpif77", MPIF77_NAME) PAC_GET_EXENAME("mpifort", MPIFORT_NAME) PAC_GET_EXENAME("mpicxx", MPICXX_NAME) -PAC_GET_EXENAME("mpiexec", MPIEXEC_NAME) if test -n "$with_mpi" ; then if test -z "$MPICC" ; then @@ -372,9 +371,6 @@ if test -n "$with_mpi" ; then else CXX=$MPICXX fi - if test -z "$MPIEXEC" ; then - MPIEXEC=$with_mpi/bin/$MPIEXEC_NAME - fi else # Try to use mpicc etc names if test -z "$MPICC" ; then @@ -403,9 +399,6 @@ else if test "x$MPICXX" != "x" ; then CXX=$MPICXX fi - if test -z "$MPIEXEC" ; then - AC_PATH_PROG(MPIEXEC,$MPIEXEC_NAME) - fi fi # Make sure we export CC before configuring DTPools, since MPI is @@ -1463,15 +1456,10 @@ AC_PATH_PROG(PERL,perl) AC_SUBST(PERL) AC_SUBST(otherlangs) AC_SUBST(threadsdir) -AC_SUBST(MPIEXEC) AC_SUBST(MAKE) if test -z "$MPILIBNAME" ; then MPILIBNAME=mpich ; fi AC_SUBST(MPILIBNAME) -# We need either mpiexec or mpirun. If we don't find them, -# the user will need to determine how to run a program -AC_PATH_PROG(MPIEXEC,$MPIEXEC_NAME) - # TODO: use variables such as has_f77 etc. instead of double use $f77dir etc. AM_CONDITIONAL([HAS_F77], [test $f77dir = f77]) AM_CONDITIONAL([HAS_F90], [test $f90dir = f90]) diff --git a/test/mpi/runtests b/test/mpi/runtests index 4283d70f298..4bd4439bc62 100755 --- a/test/mpi/runtests +++ b/test/mpi/runtests @@ -204,6 +204,9 @@ if (defined($ENV{'MPITEST_PPNMAX'})) { if (defined($ENV{'MPITEST_TIMELIMITARG'})) { $g_opt{timelimitarg} = $ENV{'MPITEST_TIMELIMITARG'}; } +if (defined($ENV{'MPIEXEC'})) { + $g_opt{mpiexec} = $ENV{'MPIEXEC'}; +} if (defined($ENV{'MPITEST_MPIEXECARG'})) { $g_opt{mpiexecargs} = $ENV{'MPITEST_MPIEXECARG'}; } From a3c5d0310f76f788e99e978b58807d7dab996420 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 10 Jan 2022 14:55:09 -0600 Subject: [PATCH 381/607] runtests: update comment reflecting the code refactoring --- test/mpi/runtests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/mpi/runtests b/test/mpi/runtests index 4bd4439bc62..faf38e6c54a 100755 --- a/test/mpi/runtests +++ b/test/mpi/runtests @@ -389,7 +389,7 @@ else { # --------------------------------------------------------------------------- # Routines # -# Run the programs listed in the file given as the argument. +# Load tests listed in the file given as the argument. # This file describes the tests in the format # programname number-of-processes [ key=value ... ] # If the second value is not given, the default value is used. From 350a85ce3393092774d5648dcc4d3f92e9349eb6 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Mon, 31 Jan 2022 14:06:55 -0600 Subject: [PATCH 382/607] ch4/config: Fix netmod detection The macro used to probe ucx or libfabric availability sets pac_have_xxx on output. Fix if branches to check the right variable. --- src/mpid/ch4/subconfigure.m4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mpid/ch4/subconfigure.m4 b/src/mpid/ch4/subconfigure.m4 index 6ae15861a28..3e3a0dd3968 100644 --- a/src/mpid/ch4/subconfigure.m4 +++ b/src/mpid/ch4/subconfigure.m4 @@ -37,10 +37,10 @@ if test -z "${device_args}" ; then AS_CASE([$host_os], [linux*],[ dnl attempt to choose a netmod from the installed libraries - if test $have_ucx = "yes" -a $have_libfabric = "no" ; then + if test $pac_have_ucx = "yes" -a $pac_have_libfabric = "no" ; then pac_ch4_choice="ucx-have-ucx" ch4_netmods=ucx - elif test $have_ucx = "no" -a $have_libfabric = "yes" ; then + elif test $pac_have_ucx = "no" -a $pac_have_libfabric = "yes" ; then pac_ch4_choice="ofi-have-libfabric" ch4_netmods=ofi else From 3d351d49a07b401a35cb0e9b76fb077edca64eb9 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 18 Jan 2022 19:18:25 -0600 Subject: [PATCH 383/607] configure: add -fPIE flag when linking with Fortran While gcc always compile into PIE objects, other compilers may switch it off, for example, clang under -O2. This prevents linking with Fortran, which apparently requires PIE objects. --- confdb/aclocal_f77.m4 | 54 +++++++++++++++++++++++++++++++++---------- configure.ac | 3 +++ 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/confdb/aclocal_f77.m4 b/confdb/aclocal_f77.m4 index 0f673f81f0a..324944f09cb 100644 --- a/confdb/aclocal_f77.m4 +++ b/confdb/aclocal_f77.m4 @@ -1,3 +1,32 @@ +dnl +dnl Check PIE cflags and use it whenever we are linking C objects with Fortran. +dnl +dnl To link C objects with Fortran compiler, the objects often require to be +dnl PIE objects. Some compiler may produce non-PIE objects unless explicit +dnl option is given, for example, clang under -O2. Note that this is +dnl unnecessary when compiler is configured to set PIE by default, such as +dnl gcc on Debian/Ubuntu systems. Setting -fPIE during config test on such +dnl system should not make a difference. +dnl +AC_DEFUN([PAC_C_CHECK_fPIE_OK], [ + PAC_C_CHECK_COMPILER_OPTION([-fPIE], [fPIE_OK=yes], [fPIE_OK=no]) +]) + +AC_DEFUN([PAC_LANG_PUSH_C_PIE], [ + AC_LANG_PUSH([C]) + if test "$fPIE_OK" = "yes" ; then + PAC_PUSH_FLAG(CFLAGS) + CFLAGS="$CFLAGS -fPIE" + fi +]) + +AC_DEFUN([PAC_LANG_POP_C_PIE], [ + if test "$fPIE_OK" = "yes" ; then + PAC_POP_FLAG(CFLAGS) + fi + AC_LANG_POP([C]) +]) + dnl dnl/*D dnl PAC_PROG_F77_NAME_MANGLE - Determine how the Fortran compiler mangles @@ -78,7 +107,7 @@ dnl # it may be that the programs have to be linked with the Fortran compiler, # not the C compiler. Try reversing the language used for the test if test "$pac_found" != "yes" ; then - AC_LANG_PUSH([C]) + PAC_LANG_PUSH_C_PIE for call in "" __stdcall ; do for sym in my_name_ my_name__ my_name MY_NAME MY_name MY_name_ NONE ; do AC_COMPILE_IFELSE([ @@ -101,7 +130,7 @@ if test "$pac_found" != "yes" ; then done test "$pac_found" = "yes" && break done - AC_LANG_POP([C]) + PAC_LANG_POP_C_PIE fi if test "$pac_found" = "yes" ; then case ${sym} in @@ -285,6 +314,7 @@ AC_DEFINE_UNQUOTED(PAC_TYPE_NAME,$PAC_CV_NAME,[Define size of PAC_TYPE_NAME]) undefine([PAC_TYPE_NAME]) undefine([PAC_CV_NAME]) ]) + dnl dnl This version uses a Fortran program to link programs. dnl This is necessary because some compilers provide shared libraries @@ -306,7 +336,7 @@ dnl ifelse([$2],[], dnl [AC_MSG_WARN([No value provided for size of $1 when cross-compiling])], dnl [eval PAC_CV_NAME=$2]) dnl fi -AC_LANG_PUSH([C]) +PAC_LANG_PUSH_C_PIE AC_COMPILE_IFELSE([ AC_LANG_SOURCE([ #include @@ -359,7 +389,7 @@ int cisize_(char *i1p, char *i2p) { ],[ AC_MSG_WARN([Unable to compile the C routine for finding the size of a $1]) ]) -AC_LANG_POP([C]) +PAC_LANG_POP_C_PIE ]) dnl Endof ac_cache_check if test "$PAC_CV_NAME" = "-9999" ; then @@ -807,7 +837,7 @@ pac_linkwithC=no dnl Use F77 as a linker to compile a Fortran main and C subprogram. if test "$pac_linkwithC" != "yes" ; then - AC_LANG_PUSH([C]) + PAC_LANG_PUSH_C_PIE AC_COMPILE_IFELSE([],[ PAC_RUNLOG([mv conftest.$OBJEXT pac_conftest.$OBJEXT]) saved_LIBS="$LIBS" @@ -821,7 +851,7 @@ if test "$pac_linkwithC" != "yes" ; then LIBS="$saved_LIBS" rm -f pac_conftest.$OBJEXT ]) - AC_LANG_POP([C]) + PAC_LANG_POP_C_PIE fi dnl Use C as a linker and FLIBS to compile a Fortran main and C subprogram. @@ -925,7 +955,7 @@ esac AC_CACHE_CHECK([for libraries to link Fortran main with C stdio routines], pac_cv_prog_f77_and_c_stdio_libs,[ pac_cv_prog_f77_and_c_stdio_libs=unknown -AC_LANG_PUSH([C]) +PAC_LANG_PUSH_C_PIE AC_COMPILE_IFELSE([ AC_LANG_SOURCE([ #include @@ -958,7 +988,7 @@ int $confname(int a) { LIBS="$saved_LIBS" rm -f pac_conftest.$OBJEXT ]) -AC_LANG_POP([C]) +PAC_LANG_POP_C_PIE ]) dnl Endof ac_cache_check if test "$pac_cv_prog_f77_and_c_stdio_libs" != "none" \ @@ -1060,7 +1090,7 @@ pac_linkwithC=no dnl Use F77 as a linker to compile a Fortran main and C subprogram. if test "$pac_linkwithC" != "yes" ; then - AC_LANG_PUSH([C]) + PAC_LANG_PUSH_C_PIE AC_COMPILE_IFELSE([],[ PAC_RUNLOG([mv conftest.$OBJEXT pac_conftest.$OBJEXT]) saved_LIBS="$LIBS" @@ -1076,7 +1106,7 @@ if test "$pac_linkwithC" != "yes" ; then rm -f pac_conftest.$OBJEXT fi ]) - AC_LANG_POP([C]) + PAC_LANG_POP_C_PIE fi dnl Use C as a linker and FLIBS to compile a Fortran main and C subprogram. @@ -1313,7 +1343,7 @@ pac_mpi_fint="$1" AC_MSG_CHECKING([for values of Fortran logicals]) AC_CACHE_VAL(pac_cv_prog_f77_true_false_value,[ pac_cv_prog_f77_true_false_value="" -AC_LANG_PUSH([C]) +PAC_LANG_PUSH_C_PIE AC_COMPILE_IFELSE([ AC_LANG_SOURCE([ #include @@ -1362,7 +1392,7 @@ void ftest_( $pac_mpi_fint *itrue, $pac_mpi_fint *ifalse ) LIBS="$saved_LIBS" rm -f pac_conftest.$OBJEXT ]) -AC_LANG_POP([C]) +PAC_LANG_POP_C_PIE ]) dnl Endof ac_cache_val if test "X$pac_cv_prog_f77_true_false_value" != "X" ; then diff --git a/configure.ac b/configure.ac index b56742a7691..44cb77d6b09 100644 --- a/configure.ac +++ b/configure.ac @@ -746,6 +746,9 @@ PAC_ARG_CACHING # it may influence the output of the other tests PAC_ARG_STRICT +# To link C objects with Fortran main program may require -fPIE option +PAC_C_CHECK_fPIE_OK + # ----------------------------------------------------------------------------- # First check that we have a clean build if we are doing a VPATH build PAC_VPATH_CHECK(src/include/mpi.h src/env/mpicc,lib) From 75ded2b692cb55ccfe6a74527751dab63f6c5613 Mon Sep 17 00:00:00 2001 From: Sriraj Date: Mon, 17 Jan 2022 10:24:51 -0600 Subject: [PATCH 384/607] coll: Add recursive koupling based allreduce Author: Rubasri Kalidas --- src/include/mpir_comm.h | 12 + .../coll/algorithms/recexchalgo/recexchalgo.c | 27 + src/mpi/coll/allreduce/Makefile.mk | 5 +- .../coll/allreduce/allreduce_intra_recexch.c | 460 ++++++++++++++++++ src/mpi/coll/coll_algorithms.txt | 3 + src/mpi/coll/cvars.txt | 22 + src/mpi/coll/include/csel_container.h | 5 + src/mpi/coll/src/coll_impl.c | 10 + src/mpi/coll/src/csel_container.c | 16 + 9 files changed, 558 insertions(+), 2 deletions(-) create mode 100644 src/mpi/coll/allreduce/allreduce_intra_recexch.c diff --git a/src/include/mpir_comm.h b/src/include/mpir_comm.h index b5e8fc47fc4..fdc3a5bd335 100644 --- a/src/include/mpir_comm.h +++ b/src/include/mpir_comm.h @@ -10,6 +10,9 @@ #include "../mpid/common/hcoll/hcollpre.h" #endif +/* Maximum radix up to which the nbrs from + * recursive exchange algorithm will be stored in the communicator */ +#define MAX_RADIX 8 /*E MPIR_Comm_kind_t - Name the two types of communicators E*/ @@ -219,6 +222,15 @@ struct MPIR_Comm { int pof2; /* Nearest (smaller than or equal to) power of 2 * to the number of ranks in the communicator. * To be used during collective communication */ + int pofk[MAX_RADIX - 1]; + int k[MAX_RADIX - 1]; + int step1_sendto[MAX_RADIX - 1]; + int step1_nrecvs[MAX_RADIX - 1]; + int *step1_recvfrom[MAX_RADIX - 1]; + int step2_nphases[MAX_RADIX - 1]; + int **step2_nbrs[MAX_RADIX - 1]; + int nbrs_defined[MAX_RADIX - 1]; + void **recexch_allreduce_nbr_buffer; } coll; void *csel_comm; /* collective selector handle */ diff --git a/src/mpi/coll/algorithms/recexchalgo/recexchalgo.c b/src/mpi/coll/algorithms/recexchalgo/recexchalgo.c index 62d06f74f18..80935aafffb 100644 --- a/src/mpi/coll/algorithms/recexchalgo/recexchalgo.c +++ b/src/mpi/coll/algorithms/recexchalgo/recexchalgo.c @@ -17,6 +17,14 @@ int MPII_Recexchalgo_init(void) int MPII_Recexchalgo_comm_init(MPIR_Comm * comm) { int mpi_errno = MPI_SUCCESS; + int i = 0; + + for (i = 0; i < MAX_RADIX - 1; i++) { + comm->coll.nbrs_defined[i] = 0; + comm->coll.step1_recvfrom[i] = NULL; + comm->coll.step2_nbrs[i] = NULL; + } + comm->coll.recexch_allreduce_nbr_buffer = NULL; return mpi_errno; } @@ -26,6 +34,25 @@ int MPII_Recexchalgo_comm_cleanup(MPIR_Comm * comm) { int mpi_errno = MPI_SUCCESS; + int i = 0, j = 0; + + for (i = 0; i < MAX_RADIX - 1; i++) { + /* free the memory */ + if (comm->coll.step2_nbrs[i]) { + for (j = 0; j < comm->coll.step2_nphases[i]; j++) + MPL_free(comm->coll.step2_nbrs[i][j]); + MPL_free(comm->coll.step2_nbrs[i]); + } + if (comm->coll.step1_recvfrom[i]) + MPL_free(comm->coll.step1_recvfrom[i]); + } + + if (comm->coll.recexch_allreduce_nbr_buffer) { + for (j = 0; j < 2 * (MAX_RADIX - 1); j++) + MPL_free(comm->coll.recexch_allreduce_nbr_buffer[j]); + MPL_free(comm->coll.recexch_allreduce_nbr_buffer); + } + return mpi_errno; } diff --git a/src/mpi/coll/allreduce/Makefile.mk b/src/mpi/coll/allreduce/Makefile.mk index 01029f0a9cd..6eb5a97ea30 100644 --- a/src/mpi/coll/allreduce/Makefile.mk +++ b/src/mpi/coll/allreduce/Makefile.mk @@ -12,5 +12,6 @@ mpi_core_sources += \ src/mpi/coll/allreduce/allreduce_intra_recursive_doubling.c \ src/mpi/coll/allreduce/allreduce_intra_reduce_scatter_allgather.c \ src/mpi/coll/allreduce/allreduce_intra_smp.c \ - src/mpi/coll/allreduce/allreduce_inter_reduce_exchange_bcast.c \ - src/mpi/coll/allreduce/allreduce_intra_tree.c + src/mpi/coll/allreduce/allreduce_intra_tree.c \ + src/mpi/coll/allreduce/allreduce_intra_recexch.c \ + src/mpi/coll/allreduce/allreduce_inter_reduce_exchange_bcast.c diff --git a/src/mpi/coll/allreduce/allreduce_intra_recexch.c b/src/mpi/coll/allreduce/allreduce_intra_recexch.c new file mode 100644 index 00000000000..8c8ca62bef4 --- /dev/null +++ b/src/mpi/coll/allreduce/allreduce_intra_recexch.c @@ -0,0 +1,460 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * Copyright (C) by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + * + */ + +#include "mpiimpl.h" +#include "recexchalgo.h" +#include "algo_common.h" + + +int MPIR_Allreduce_intra_recexch(const void *sendbuf, + void *recvbuf, + MPI_Aint count, + MPI_Datatype datatype, + MPI_Op op, MPIR_Comm * comm, int k, int single_phase_recv, + MPIR_Errflag_t * errflag) +{ + int mpi_errno = MPI_SUCCESS, mpi_errno_ret = MPI_SUCCESS; + int is_commutative, rank, nranks, nbr, myidx; + int buf = 0; + MPI_Aint true_extent, true_lb, extent; + int step1_sendto = -1, step1_nrecvs = 0, *step1_recvfrom = NULL; + int step2_nphases = 0, **step2_nbrs; + int i, j, phase, p_of_k, T; + bool in_step2 = true; + void **nbr_buffer = NULL; + int index = 0, comm_alloc = 1; + MPIR_Request *sreqs[MAX_RADIX], *rreqs[MAX_RADIX * 2]; + MPIR_Request **send_reqs = NULL, **recv_reqs = NULL; + int send_nreq = 0, recv_nreq = 0, total_phases = 0; + + rank = comm->rank; + nranks = comm->local_size; + is_commutative = MPIR_Op_is_commutative(op); + + /* if there is only 1 rank, copy data from sendbuf + * to recvbuf and exit */ + if (nranks == 1) { + if (sendbuf != MPI_IN_PLACE) + mpi_errno = MPIR_Localcopy(sendbuf, count, datatype, recvbuf, count, datatype); + return mpi_errno; + } + + /* need to allocate temporary buffer to store incoming data */ + MPIR_Type_get_true_extent_impl(datatype, &true_lb, &true_extent); + MPIR_Datatype_get_extent_macro(datatype, extent); + extent = MPL_MAX(extent, true_extent); + + /* copy local data into recvbuf */ + if (sendbuf != MPI_IN_PLACE && count > 0) { + mpi_errno = MPIR_Localcopy(sendbuf, count, datatype, recvbuf, count, datatype); + if (mpi_errno) + MPIR_ERR_POP(mpi_errno); + } + + /* If k value is greater than the maximum radix for which nbrs + * are stored in comm, generate nbrs here in the function. Otherwise, + * get the nbrs information stored in the communicator */ + if (k > MAX_RADIX) { + comm_alloc = 0; + /* get the neighbors, the function allocates the required memory */ + MPII_Recexchalgo_get_neighbors(rank, nranks, &k, &step1_sendto, + &step1_recvfrom, &step1_nrecvs, + &step2_nbrs, &step2_nphases, &p_of_k, &T); + /* Allocate requests */ + if (step1_sendto == -1) { + recv_reqs = + (MPIR_Request **) MPL_malloc((k - 1) * 2 * sizeof(MPIR_Request *), MPL_MEM_BUFFER); + MPIR_ERR_CHKANDJUMP(!recv_reqs, mpi_errno, MPI_ERR_OTHER, "**nomem"); + send_reqs = + (MPIR_Request **) MPL_malloc((k - 1) * sizeof(MPIR_Request *), MPL_MEM_BUFFER); + MPIR_ERR_CHKANDJUMP(!send_reqs, mpi_errno, MPI_ERR_OTHER, "**nomem"); + } + } else { + index = k - 2; /* we calculate starting k = 2 */ + /* If this is the first time a recursive exchange is called with k, populate the nbr calculation in + * the communicator */ + if (comm->coll.nbrs_defined[index] == 0) { + comm->coll.nbrs_defined[index] = 1; + comm->coll.k[index] = k; + comm->coll.step1_sendto[index] = -1; + comm->coll.step1_nrecvs[index] = 0; + comm->coll.step2_nphases[index] = 0; + mpi_errno = MPII_Recexchalgo_get_neighbors(rank, nranks, &comm->coll.k[index], + &comm->coll.step1_sendto[index], + &comm->coll.step1_recvfrom[index], + &comm->coll.step1_nrecvs[index], + &comm->coll.step2_nbrs[index], + &comm->coll.step2_nphases[index], + &comm->coll.pofk[index], &T); + } + k = comm->coll.k[index]; + p_of_k = comm->coll.pofk[index]; + step1_sendto = comm->coll.step1_sendto[index]; + step1_recvfrom = comm->coll.step1_recvfrom[index]; + step1_nrecvs = comm->coll.step1_nrecvs[index]; + step2_nbrs = comm->coll.step2_nbrs[index]; + step2_nphases = comm->coll.step2_nphases[index]; + + recv_reqs = rreqs; + send_reqs = sreqs; + } + /* lazy allocation of 8K recv buffer. If the message size is 8K and if the buffer has not been + * allocated before, do a lazy allocation here. We do this allocation here since the K value could be updated + * after the get_nbrs computation */ + if (k <= MAX_RADIX && (step1_sendto == -1) && count * extent <= 8192 && + comm->coll.recexch_allreduce_nbr_buffer == NULL) { + comm->coll.recexch_allreduce_nbr_buffer = + (void **) MPL_malloc(sizeof(void *) * 2 * (MAX_RADIX - 1), MPL_MEM_COLL); + MPIR_ERR_CHKANDJUMP(!comm->coll.recexch_allreduce_nbr_buffer, mpi_errno, MPI_ERR_OTHER, + "**nomem"); + for (j = 0; j < 2 * (MAX_RADIX - 1); j++) { + /* allocate buffer for 8K */ + comm->coll.recexch_allreduce_nbr_buffer[j] = MPL_malloc(8192, MPL_MEM_COLL); + MPIR_ERR_CHKANDJUMP(!comm->coll.recexch_allreduce_nbr_buffer[j], mpi_errno, + MPI_ERR_OTHER, "**nomem"); + } + } + if (k <= MAX_RADIX && step1_sendto == -1 && count * extent <= 8192) { + nbr_buffer = comm->coll.recexch_allreduce_nbr_buffer; + } + + /* get nearest power-of-two less than or equal to comm_size */ + in_step2 = (step1_sendto == -1); /* whether this rank participates in Step 2 */ + + if (in_step2 && (k > MAX_RADIX || count * extent > 8192)) { + if (single_phase_recv) { /* create recvs for single phase */ + nbr_buffer = (void **) MPL_malloc(sizeof(void *) * (k - 1), MPL_MEM_COLL); + MPIR_ERR_CHKANDJUMP(!nbr_buffer, mpi_errno, MPI_ERR_OTHER, "**nomem"); + for (j = 0; j < (k - 1); j++) { + nbr_buffer[j] = MPL_malloc(count * extent, MPL_MEM_COLL); + MPIR_ERR_CHKANDJUMP(!nbr_buffer[j], mpi_errno, MPI_ERR_OTHER, "**nomem"); + nbr_buffer[j] = (void *) ((char *) nbr_buffer[j] - true_lb); + } + } else { /* create buffers for 2 phases */ + nbr_buffer = (void **) MPL_malloc(sizeof(void *) * 2 * (k - 1), MPL_MEM_COLL); + MPIR_ERR_CHKANDJUMP(!nbr_buffer, mpi_errno, MPI_ERR_OTHER, "**nomem"); + for (j = 0; j < 2 * (k - 1); j++) { + nbr_buffer[j] = MPL_malloc(count * extent, MPL_MEM_COLL); + MPIR_ERR_CHKANDJUMP(!nbr_buffer[j], mpi_errno, MPI_ERR_OTHER, "**nomem"); + nbr_buffer[j] = (void *) ((char *) nbr_buffer[j] - true_lb); + } + } + } + + if (!in_step2) { /* even */ + /* non-participating rank sends the data to a participating rank */ + mpi_errno = MPIC_Send(recvbuf, count, + datatype, step1_sendto, MPIR_ALLREDUCE_TAG, comm, errflag); + if (mpi_errno) { + /* for communication errors, just record the error but continue */ + *errflag = + MPIX_ERR_PROC_FAILED == + MPIR_ERR_GET_CLASS(mpi_errno) ? MPIR_ERR_PROC_FAILED : MPIR_ERR_OTHER; + MPIR_ERR_SET(mpi_errno, *errflag, "**fail"); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + + } else { /* odd */ + if (step1_nrecvs) { + for (i = 0; i < step1_nrecvs; i++) { /* participating rank gets data from non-partcipating ranks */ + mpi_errno = MPIC_Irecv(nbr_buffer[i], count, + datatype, step1_recvfrom[i], + MPIR_ALLREDUCE_TAG, comm, &recv_reqs[recv_nreq++]); + if (mpi_errno) { + /* for communication errors, just record the error but continue */ + *errflag = + MPIX_ERR_PROC_FAILED == + MPIR_ERR_GET_CLASS(mpi_errno) ? MPIR_ERR_PROC_FAILED : MPIR_ERR_OTHER; + MPIR_ERR_SET(mpi_errno, *errflag, "**fail"); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + } + mpi_errno = MPIC_Waitall(recv_nreq, recv_reqs, MPI_STATUSES_IGNORE, errflag); + if (mpi_errno && mpi_errno != MPI_ERR_IN_STATUS) + MPIR_ERR_POP(mpi_errno); + + /* Do reduction of reduced data */ + for (i = 0; i < step1_nrecvs && count > 0; i++) { /* participating rank gets data from non-partcipating ranks */ + mpi_errno = MPIR_Reduce_local(nbr_buffer[i], recvbuf, count, datatype, op); + if (mpi_errno) { + /* for communication errors, just record the error but continue */ + *errflag = + MPIX_ERR_PROC_FAILED == + MPIR_ERR_GET_CLASS(mpi_errno) ? MPIR_ERR_PROC_FAILED : MPIR_ERR_OTHER; + MPIR_ERR_SET(mpi_errno, *errflag, "**fail"); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + } + } + } + + + /* step2 */ + if (!is_commutative && in_step2 && count > 0) { + /* sort the neighbor list so that receives can be posted in order */ + for (phase = 0; phase < step2_nphases; phase++) + qsort(step2_nbrs[phase], k - 1, sizeof(int), MPII_Algo_compare_int); + } + + /* step2 sends and reduces */ + for (phase = 0; phase < step2_nphases && in_step2; phase++) { + buf = 0; + recv_nreq = 0; + total_phases = (single_phase_recv) ? 1 : 2; + for (j = 0; j < total_phases && (j + phase) < step2_nphases; j++) { + for (i = 0; i < (k - 1); i++) { + nbr = step2_nbrs[phase + j][i]; + mpi_errno = + MPIC_Irecv(nbr_buffer[buf++], count, datatype, nbr, MPIR_ALLREDUCE_TAG, + comm, &recv_reqs[recv_nreq++]); + if (mpi_errno) { + /* for communication errors, just record the error but continue */ + *errflag = + MPIX_ERR_PROC_FAILED == + MPIR_ERR_GET_CLASS(mpi_errno) ? MPIR_ERR_PROC_FAILED : MPIR_ERR_OTHER; + MPIR_ERR_SET(mpi_errno, *errflag, "**fail"); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + } + } + + send_nreq = 0; + myidx = 0; + /* send data to all the neighbors */ + for (i = 0; i < k - 1; i++) { + nbr = step2_nbrs[phase][i]; + mpi_errno = MPIC_Isend(recvbuf, count, datatype, nbr, MPIR_ALLREDUCE_TAG, comm, + &send_reqs[send_nreq++], errflag); + if (mpi_errno) { + /* for communication errors, just record the error but continue */ + *errflag = + MPIX_ERR_PROC_FAILED == + MPIR_ERR_GET_CLASS(mpi_errno) ? MPIR_ERR_PROC_FAILED : MPIR_ERR_OTHER; + MPIR_ERR_SET(mpi_errno, *errflag, "**fail"); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + if (rank > nbr) { + myidx = i + 1; + } + } + + mpi_errno = MPIC_Waitall(send_nreq, send_reqs, MPI_STATUSES_IGNORE, errflag); + if (mpi_errno && mpi_errno != MPI_ERR_IN_STATUS) + MPIR_ERR_POP(mpi_errno); + + buf = myidx - 1; + mpi_errno = MPIC_Waitall((k - 1), recv_reqs, MPI_STATUSES_IGNORE, errflag); + if (mpi_errno && mpi_errno != MPI_ERR_IN_STATUS) + MPIR_ERR_POP(mpi_errno); + + for (i = myidx - 1; i >= 0 && count > 0; i--, buf--) { + mpi_errno = MPIR_Reduce_local(nbr_buffer[buf], recvbuf, count, datatype, op); + if (mpi_errno) { + /* for communication errors, just record the error but continue */ + *errflag = + MPIX_ERR_PROC_FAILED == + MPIR_ERR_GET_CLASS(mpi_errno) ? MPIR_ERR_PROC_FAILED : MPIR_ERR_OTHER; + MPIR_ERR_SET(mpi_errno, *errflag, "**fail"); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + } + + buf = myidx; + for (i = myidx; i < k - 1 && count > 0; i++, buf++) { + if (is_commutative) { + mpi_errno = MPIR_Reduce_local(nbr_buffer[buf], recvbuf, count, datatype, op); + if (mpi_errno) { + /* for communication errors, just record the error but continue */ + *errflag = + MPIX_ERR_PROC_FAILED == + MPIR_ERR_GET_CLASS(mpi_errno) ? MPIR_ERR_PROC_FAILED : MPIR_ERR_OTHER; + MPIR_ERR_SET(mpi_errno, *errflag, "**fail"); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + } else { + mpi_errno = MPIR_Reduce_local(recvbuf, nbr_buffer[buf], count, datatype, op); + if (mpi_errno) { + /* for communication errors, just record the error but continue */ + *errflag = + MPIX_ERR_PROC_FAILED == + MPIR_ERR_GET_CLASS(mpi_errno) ? MPIR_ERR_PROC_FAILED : MPIR_ERR_OTHER; + MPIR_ERR_SET(mpi_errno, *errflag, "**fail"); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + + mpi_errno = + MPIR_Localcopy(nbr_buffer[buf], count, datatype, recvbuf, count, datatype); + if (mpi_errno) { + /* for communication errors, just record the error but continue */ + *errflag = + MPIX_ERR_PROC_FAILED == + MPIR_ERR_GET_CLASS(mpi_errno) ? MPIR_ERR_PROC_FAILED : MPIR_ERR_OTHER; + MPIR_ERR_SET(mpi_errno, *errflag, "**fail"); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + } + } + + if (single_phase_recv == false) { /* post sends and do reduction for the 2nd phase */ + phase++; + if (phase < step2_nphases) { + send_nreq = 0; + myidx = 0; + /* send data to all the neighbors */ + for (i = 0; i < k - 1; i++) { + nbr = step2_nbrs[phase][i]; + + mpi_errno = + MPIC_Isend(recvbuf, count, datatype, nbr, MPIR_ALLREDUCE_TAG, comm, + &send_reqs[send_nreq++], errflag); + if (mpi_errno) { + /* for communication errors, just record the error but continue */ + *errflag = + MPIX_ERR_PROC_FAILED == + MPIR_ERR_GET_CLASS(mpi_errno) ? MPIR_ERR_PROC_FAILED : MPIR_ERR_OTHER; + MPIR_ERR_SET(mpi_errno, *errflag, "**fail"); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + if (rank > nbr) { + myidx = i + 1; + } + } + + mpi_errno = MPIC_Waitall(send_nreq, send_reqs, MPI_STATUSES_IGNORE, errflag); + if (mpi_errno && mpi_errno != MPI_ERR_IN_STATUS) + MPIR_ERR_POP(mpi_errno); + + mpi_errno = + MPIC_Waitall((k - 1), recv_reqs + (k - 1), MPI_STATUSES_IGNORE, errflag); + if (mpi_errno && mpi_errno != MPI_ERR_IN_STATUS) + MPIR_ERR_POP(mpi_errno); + + buf = (k - 1) + myidx - 1; + for (i = myidx - 1; i >= 0 && count > 0; i--, buf--) { + mpi_errno = MPIR_Reduce_local(nbr_buffer[buf], recvbuf, count, datatype, op); + if (mpi_errno) { + /* for communication errors, just record the error but continue */ + *errflag = + MPIX_ERR_PROC_FAILED == + MPIR_ERR_GET_CLASS(mpi_errno) ? MPIR_ERR_PROC_FAILED : MPIR_ERR_OTHER; + MPIR_ERR_SET(mpi_errno, *errflag, "**fail"); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + } + + buf = (k - 1) + myidx; + for (i = myidx; i < k - 1 && count > 0; i++, buf++) { + if (is_commutative) { + mpi_errno = + MPIR_Reduce_local(nbr_buffer[buf], recvbuf, count, datatype, op); + if (mpi_errno) { + /* for communication errors, just record the error but continue */ + *errflag = + MPIX_ERR_PROC_FAILED == + MPIR_ERR_GET_CLASS(mpi_errno) ? MPIR_ERR_PROC_FAILED : + MPIR_ERR_OTHER; + MPIR_ERR_SET(mpi_errno, *errflag, "**fail"); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + } else { + mpi_errno = + MPIR_Reduce_local(recvbuf, nbr_buffer[buf], count, datatype, op); + if (mpi_errno) { + /* for communication errors, just record the error but continue */ + *errflag = + MPIX_ERR_PROC_FAILED == + MPIR_ERR_GET_CLASS(mpi_errno) ? MPIR_ERR_PROC_FAILED : + MPIR_ERR_OTHER; + MPIR_ERR_SET(mpi_errno, *errflag, "**fail"); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + mpi_errno = + MPIR_Localcopy(nbr_buffer[buf], count, datatype, recvbuf, count, + datatype); + if (mpi_errno) { + /* for communication errors, just record the error but continue */ + *errflag = + MPIX_ERR_PROC_FAILED == + MPIR_ERR_GET_CLASS(mpi_errno) ? MPIR_ERR_PROC_FAILED : + MPIR_ERR_OTHER; + MPIR_ERR_SET(mpi_errno, *errflag, "**fail"); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + } + } + } + } + } + + /* Step 3: This is reverse of Step 1. Rans that participated in Step 2 + * send the data to non-partcipating rans */ + if (step1_sendto != -1) { /* I am a Step 2 non-participating rank */ + mpi_errno = MPIC_Recv(recvbuf, count, datatype, step1_sendto, MPIR_ALLREDUCE_TAG, comm, + MPI_STATUS_IGNORE, errflag); + if (mpi_errno) { + /* for communication errors, just record the error but continue */ + *errflag = + MPIX_ERR_PROC_FAILED == + MPIR_ERR_GET_CLASS(mpi_errno) ? MPIR_ERR_PROC_FAILED : MPIR_ERR_OTHER; + MPIR_ERR_SET(mpi_errno, *errflag, "**fail"); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + } else { + for (i = 0; i < step1_nrecvs; i++) { + mpi_errno = + MPIC_Isend(recvbuf, count, datatype, step1_recvfrom[i], MPIR_ALLREDUCE_TAG, + comm, &send_reqs[i], errflag); + if (mpi_errno) { + /* for communication errors, just record the error but continue */ + *errflag = + MPIX_ERR_PROC_FAILED == + MPIR_ERR_GET_CLASS(mpi_errno) ? MPIR_ERR_PROC_FAILED : MPIR_ERR_OTHER; + MPIR_ERR_SET(mpi_errno, *errflag, "**fail"); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + } + + mpi_errno = MPIC_Waitall(i, send_reqs, MPI_STATUSES_IGNORE, errflag); + if (mpi_errno && mpi_errno != MPI_ERR_IN_STATUS) + MPIR_ERR_POP(mpi_errno); + } + + if (in_step2 && (k > MAX_RADIX || count * extent > 8192)) { + if (single_phase_recv == true) { + for (j = 0; j < (k - 1); j++) { + nbr_buffer[j] = (void *) ((char *) nbr_buffer[j] + true_lb); + MPL_free(nbr_buffer[j]); + } + } else { + for (j = 0; j < 2 * (k - 1); j++) { + nbr_buffer[j] = (void *) ((char *) nbr_buffer[j] + true_lb); + MPL_free(nbr_buffer[j]); + } + } + MPL_free(nbr_buffer); + } + + if (!comm_alloc) { + /* free the memory */ + for (i = 0; i < step2_nphases; i++) + MPL_free(step2_nbrs[i]); + MPL_free(step2_nbrs); + MPL_free(step1_recvfrom); + if (in_step2) { + MPL_free(recv_reqs); + MPL_free(send_reqs); + } + } + fn_exit: + if (mpi_errno_ret) + mpi_errno = mpi_errno_ret; + else if (*errflag != MPIR_ERR_NONE) + MPIR_ERR_SET(mpi_errno, *errflag, "**coll_fail"); + return mpi_errno; + fn_fail: + goto fn_exit; +} diff --git a/src/mpi/coll/coll_algorithms.txt b/src/mpi/coll/coll_algorithms.txt index d0b4effa2ad..414e180d1e9 100644 --- a/src/mpi/coll/coll_algorithms.txt +++ b/src/mpi/coll/coll_algorithms.txt @@ -325,6 +325,9 @@ allreduce-intra: tree extra_params: tree_type, k, chunk_size, buffer_per_child cvar_params: TREE_TYPE, TREE_KVAL, TREE_PIPELINE_CHUNK_SIZE, TREE_BUFFER_PER_CHILD + recexch + extra_params: k, single_phase_recv + cvar_params: RECEXCH_KVAL, RECEXCH_SINGLE_PHASE_RECV allreduce-inter: reduce_exchange_bcast iallreduce-intra: diff --git a/src/mpi/coll/cvars.txt b/src/mpi/coll/cvars.txt index a372d78bc3f..15470cf4a73 100644 --- a/src/mpi/coll/cvars.txt +++ b/src/mpi/coll/cvars.txt @@ -1209,6 +1209,7 @@ cvars: recursive_doubling - Force recursive doubling algorithm reduce_scatter_allgather - Force reduce scatter allgather algorithm tree - Force pipelined tree algorithm + recexch - Force generic transport recursive exchange algorithm - name : MPIR_CVAR_ALLREDUCE_TREE_TYPE category : COLLECTIVE @@ -1260,6 +1261,27 @@ cvars: used to receive the data from all the children. The receives are therefore serialized, that is, only one receive can be posted at a time. + - name : MPIR_CVAR_ALLREDUCE_RECEXCH_KVAL + category : COLLECTIVE + type : int + default : 2 + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + k value for recursive exchange based allreduce + + - name : MPIR_CVAR_ALLREDUCE_RECEXCH_SINGLE_PHASE_RECV + category : COLLECTIVE + type : boolean + default : false + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + This CVAR controls whether the recv is posted for one phase or two phases + in recexch algos. By default, we post the recvs for 2 phases. + - name : MPIR_CVAR_ALLREDUCE_INTER_ALGORITHM category : COLLECTIVE type : enum diff --git a/src/mpi/coll/include/csel_container.h b/src/mpi/coll/include/csel_container.h index 051f6d0349b..aa1c1f9457a 100644 --- a/src/mpi/coll/include/csel_container.h +++ b/src/mpi/coll/include/csel_container.h @@ -26,6 +26,7 @@ typedef enum { MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_intra_reduce_scatter_allgather, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_intra_smp, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_intra_tree, + MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_intra_recexch, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_inter_reduce_exchange_bcast, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_allcomm_nb, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Alltoall_intra_brucks, @@ -341,6 +342,10 @@ typedef struct { int chunk_size; int buffer_per_child; } intra_tree; + struct { + int k; + bool single_phase_recv; + } intra_recexch; } allreduce; struct { struct { diff --git a/src/mpi/coll/src/coll_impl.c b/src/mpi/coll/src/coll_impl.c index 4b9e6cc0d2f..ee65befa7a0 100644 --- a/src/mpi/coll/src/coll_impl.c +++ b/src/mpi/coll/src/coll_impl.c @@ -192,6 +192,11 @@ int MPIR_Coll_comm_init(MPIR_Comm * comm) mpi_errno = MPII_TSP_comm_init(comm); MPIR_ERR_CHECK(mpi_errno); + /* initialize algorithms */ + mpi_errno = MPII_Recexchalgo_comm_init(comm); + if (mpi_errno) + MPIR_ERR_POP(mpi_errno); + mpi_errno = MPIR_Csel_prune(MPIR_Csel_root, comm, &comm->csel_comm); MPIR_ERR_CHECK(mpi_errno); @@ -219,6 +224,11 @@ int MPII_Coll_comm_cleanup(MPIR_Comm * comm) mpi_errno = MPII_TSP_comm_cleanup(comm); MPIR_ERR_CHECK(mpi_errno); + /* initialize algorithms */ + mpi_errno = MPII_Recexchalgo_comm_cleanup(comm); + if (mpi_errno) + MPIR_ERR_POP(mpi_errno); + fn_exit: return mpi_errno; fn_fail: diff --git a/src/mpi/coll/src/csel_container.c b/src/mpi/coll/src/csel_container.c index 193c2df5f8c..8819c09ec21 100644 --- a/src/mpi/coll/src/csel_container.c +++ b/src/mpi/coll/src/csel_container.c @@ -151,6 +151,20 @@ static void parse_container_params(struct json_object *obj, MPII_Csel_container_ } break; + case MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_intra_recexch: + { + json_object_object_foreach(obj, key, val) { + ckey = MPL_strdup_no_spaces(key); + if (!strncmp(ckey, "k=", strlen("k="))) + cnt->u.allreduce.intra_recexch.k = atoi(ckey + strlen("k=")); + else if (!strncmp(ckey, "single_phase_recv=", strlen("single_phase_recv="))) + cnt->u.allreduce.intra_recexch.single_phase_recv = + atoi(ckey + strlen("single_phase_recv=")); + MPL_free(ckey); + } + } + break; + case MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ibcast_intra_tsp_scatterv_recexch_allgatherv: { json_object_object_foreach(obj, key, val) { @@ -270,6 +284,8 @@ void *MPII_Create_container(struct json_object *obj) cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_intra_smp; else if (!strcmp(ckey, "algorithm=MPIR_Allreduce_intra_tree")) cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_intra_tree; + else if (!strcmp(ckey, "algorithm=MPIR_Allreduce_intra_recexch")) + cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_intra_recexch; else if (!strcmp(ckey, "algorithm=MPIR_Allreduce_inter_reduce_exchange_bcast")) cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_inter_reduce_exchange_bcast; From 80546419b9be9429f73c98318bc9cd00b1c23310 Mon Sep 17 00:00:00 2001 From: Sriraj Date: Mon, 31 Jan 2022 14:55:22 -0600 Subject: [PATCH 385/607] test: Add tests for recursive koupling based allreduce --- test/mpi/maint/coll_cvars.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/mpi/maint/coll_cvars.txt b/test/mpi/maint/coll_cvars.txt index fc280703a0e..359b21ec59c 100644 --- a/test/mpi/maint/coll_cvars.txt +++ b/test/mpi/maint/coll_cvars.txt @@ -228,6 +228,9 @@ algorithms: .MPIR_CVAR_ALLREDUCE_TREE_TYPE=knomial_1,knomial_2,kary .MPIR_CVAR_ALLREDUCE_TREE_KVAL=2,3,4 .MPIR_CVAR_ALLREDUCE_TREE_PIPELINE_CHUNK_SIZE=4096,8192 + recexch + .MPIR_CVAR_ALLREDUCE_RECEXCH_KVAL=2,3,4,5,9 + .MPIR_CVAR_ALLREDUCE_RECEXCH_SINGLE_PHASE_RECV=0,1 posix:release_gather .MPIR_CVAR_COLL_SHM_LIMIT_PER_NODE=131072 .MPIR_CVAR_REDUCE_INTRANODE_BUFFER_TOTAL_SIZE=16384 From 88795b93bbdef2e1e5e3b9b1af078ae6c8354dcd Mon Sep 17 00:00:00 2001 From: Gengbin Zheng Date: Wed, 19 Jan 2022 15:10:40 -0600 Subject: [PATCH 386/607] mpi/coll: add TSP-based recursive exchange algorithm for iBarrier Add generic transport based recursive exchange algorithm for iBarrier. --- src/mpi/coll/coll_algorithms.txt | 3 +++ src/mpi/coll/cvars.txt | 1 + src/mpi/coll/ibarrier/Makefile.mk | 3 ++- .../ibarrier/ibarrier_intra_tsp_recexch.c | 27 +++++++++++++++++++ test/mpi/maint/coll_cvars.txt | 1 + 5 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 src/mpi/coll/ibarrier/ibarrier_intra_tsp_recexch.c diff --git a/src/mpi/coll/coll_algorithms.txt b/src/mpi/coll/coll_algorithms.txt index 414e180d1e9..1bf51c80d27 100644 --- a/src/mpi/coll/coll_algorithms.txt +++ b/src/mpi/coll/coll_algorithms.txt @@ -46,6 +46,9 @@ barrier-inter: bcast ibarrier-intra: sched_recursive_doubling + tsp_recexch + extra_params: k + cvar_params: RECEXCH_KVAL ibarrier-inter: sched_bcast diff --git a/src/mpi/coll/cvars.txt b/src/mpi/coll/cvars.txt index 15470cf4a73..da67df25c4b 100644 --- a/src/mpi/coll/cvars.txt +++ b/src/mpi/coll/cvars.txt @@ -56,6 +56,7 @@ cvars: auto - Internal algorithm selection (can be overridden with MPIR_CVAR_COLL_SELECTION_TUNING_JSON_FILE) sched_auto - Internal algorithm selection for sched-based algorithms sched_recursive_doubling - Force recursive doubling algorithm + tsp_recexch - Force generic transport based recursive exchange algorithm - name : MPIR_CVAR_IBARRIER_INTER_ALGORITHM category : COLLECTIVE diff --git a/src/mpi/coll/ibarrier/Makefile.mk b/src/mpi/coll/ibarrier/Makefile.mk index 466da054d6a..4ec3f5dff5c 100644 --- a/src/mpi/coll/ibarrier/Makefile.mk +++ b/src/mpi/coll/ibarrier/Makefile.mk @@ -9,4 +9,5 @@ mpi_core_sources += \ src/mpi/coll/ibarrier/ibarrier_intra_sched_recursive_doubling.c \ - src/mpi/coll/ibarrier/ibarrier_inter_sched_bcast.c + src/mpi/coll/ibarrier/ibarrier_inter_sched_bcast.c \ + src/mpi/coll/ibarrier/ibarrier_intra_tsp_recexch.c diff --git a/src/mpi/coll/ibarrier/ibarrier_intra_tsp_recexch.c b/src/mpi/coll/ibarrier/ibarrier_intra_tsp_recexch.c new file mode 100644 index 00000000000..31e2f1de567 --- /dev/null +++ b/src/mpi/coll/ibarrier/ibarrier_intra_tsp_recexch.c @@ -0,0 +1,27 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpiimpl.h" + +/* Routine to schedule a disdem based barrier with radix k */ +int MPIR_TSP_Ibarrier_sched_intra_recexch(MPIR_Comm * comm, int k, MPIR_TSP_sched_t sched) +{ + int mpi_errno = MPI_SUCCESS; + void *recvbuf = NULL; + MPIR_FUNC_ENTER; + + mpi_errno = + MPIR_TSP_Iallreduce_sched_intra_recexch(MPI_IN_PLACE, recvbuf, 0, MPI_BYTE, MPI_SUM, + comm, + MPIR_IALLREDUCE_RECEXCH_TYPE_MULTIPLE_BUFFER, + k, sched); + MPIR_ERR_CHECK(mpi_errno); + + fn_exit: + MPIR_FUNC_EXIT; + return mpi_errno; + fn_fail: + goto fn_exit; +} diff --git a/test/mpi/maint/coll_cvars.txt b/test/mpi/maint/coll_cvars.txt index 359b21ec59c..322d7fec57a 100644 --- a/test/mpi/maint/coll_cvars.txt +++ b/test/mpi/maint/coll_cvars.txt @@ -312,6 +312,7 @@ algorithms: intra-nonblocking: sched_recursive_doubling tsp_recexch + .MPIR_CVAR_IBARRIER_RECEXCH_KVAL=2,3,4,8 bcast: inter-blocking: remote_send_local_bcast From c2c5d448609457485f53a5c76eb8abce4ca8b208 Mon Sep 17 00:00:00 2001 From: Gengbin Zheng Date: Wed, 19 Jan 2022 15:17:14 -0600 Subject: [PATCH 387/607] mpi/coll: add TSP-based dissemination algorithm for Ibarrier Add generic transport based dissemination algorithm for ibarrier --- src/mpi/coll/coll_algorithms.txt | 3 + src/mpi/coll/cvars.txt | 11 +++ src/mpi/coll/ibarrier/Makefile.mk | 3 +- .../coll/ibarrier/ibarrier_intra_tsp_dissem.c | 77 +++++++++++++++++++ src/mpi/coll/include/csel_container.h | 4 + src/mpi/coll/src/csel_container.c | 2 + test/mpi/maint/coll_cvars.txt | 2 + 7 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 src/mpi/coll/ibarrier/ibarrier_intra_tsp_dissem.c diff --git a/src/mpi/coll/coll_algorithms.txt b/src/mpi/coll/coll_algorithms.txt index 1bf51c80d27..2ab2c373bdf 100644 --- a/src/mpi/coll/coll_algorithms.txt +++ b/src/mpi/coll/coll_algorithms.txt @@ -49,6 +49,9 @@ ibarrier-intra: tsp_recexch extra_params: k cvar_params: RECEXCH_KVAL + tsp_k_dissemination + extra_params: k + cvar_params: DISSEM_KVAL ibarrier-inter: sched_bcast diff --git a/src/mpi/coll/cvars.txt b/src/mpi/coll/cvars.txt index da67df25c4b..74cfac7b223 100644 --- a/src/mpi/coll/cvars.txt +++ b/src/mpi/coll/cvars.txt @@ -44,6 +44,16 @@ cvars: description : >- k value for recursive exchange based ibarrier + - name : MPIR_CVAR_IBARRIER_DISSEM_KVAL + category : COLLECTIVE + type : int + default : 2 + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + k value for dissemination exchange based ibarrier + - name : MPIR_CVAR_IBARRIER_INTRA_ALGORITHM category : COLLECTIVE type : enum @@ -57,6 +67,7 @@ cvars: sched_auto - Internal algorithm selection for sched-based algorithms sched_recursive_doubling - Force recursive doubling algorithm tsp_recexch - Force generic transport based recursive exchange algorithm + tsp_k_dissemination - Force generic transport based high-radix dissemination algorithm - name : MPIR_CVAR_IBARRIER_INTER_ALGORITHM category : COLLECTIVE diff --git a/src/mpi/coll/ibarrier/Makefile.mk b/src/mpi/coll/ibarrier/Makefile.mk index 4ec3f5dff5c..93e9c5b5e97 100644 --- a/src/mpi/coll/ibarrier/Makefile.mk +++ b/src/mpi/coll/ibarrier/Makefile.mk @@ -10,4 +10,5 @@ mpi_core_sources += \ src/mpi/coll/ibarrier/ibarrier_intra_sched_recursive_doubling.c \ src/mpi/coll/ibarrier/ibarrier_inter_sched_bcast.c \ - src/mpi/coll/ibarrier/ibarrier_intra_tsp_recexch.c + src/mpi/coll/ibarrier/ibarrier_intra_tsp_recexch.c \ + src/mpi/coll/ibarrier/ibarrier_intra_tsp_dissem.c diff --git a/src/mpi/coll/ibarrier/ibarrier_intra_tsp_dissem.c b/src/mpi/coll/ibarrier/ibarrier_intra_tsp_dissem.c new file mode 100644 index 00000000000..05486921b24 --- /dev/null +++ b/src/mpi/coll/ibarrier/ibarrier_intra_tsp_dissem.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpiimpl.h" + +/* Routine to schedule a disdem based barrier with radix k */ +int MPIR_TSP_Ibarrier_sched_intra_k_dissemination(MPIR_Comm * comm, int k, MPIR_TSP_sched_t sched) +{ + int mpi_errno = MPI_SUCCESS; + int mpi_errno_ret ATTRIBUTE((unused)) = MPI_SUCCESS; + MPIR_Errflag_t errflag ATTRIBUTE((unused)) = MPIR_ERR_NONE; + int i, j, nranks, rank; + int p_of_k, shift, to, from; /* minimum power of k that is greater than or equal to number of ranks */ + int nphases = 0; + int tag, vtx_id; + int *recv_ids = NULL; + MPIR_CHKLMEM_DECL(1); + + MPIR_FUNC_ENTER; + + nranks = MPIR_Comm_size(comm); + rank = MPIR_Comm_rank(comm); + + mpi_errno = MPIR_Sched_next_tag(comm, &tag); + if (mpi_errno) + MPIR_ERR_POP(mpi_errno); + + p_of_k = 1; + while (p_of_k < nranks) { + p_of_k *= k; + nphases++; + } + + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, + (MPL_DBG_FDEST, "dissem barrier - number of phases = %d\n", nphases)); + + MPIR_CHKLMEM_MALLOC(recv_ids, int *, sizeof(int) * nphases * (k - 1), mpi_errno, "recv_ids", MPL_MEM_COLL); /* to store size of subtree of each child */ + shift = 1; + for (i = 0; i < nphases; i++) { + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, + (MPL_DBG_FDEST, "dissem barrier - start scheduling phase %d\n", i)); + for (j = 1; j < k; j++) { + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, (MPL_DBG_FDEST, "shift = %d \n", shift)); + to = (rank + j * shift) % nranks; + from = (rank - j * shift) % nranks; + if (from < 0) + from += nranks; + + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, + (MPL_DBG_FDEST, "dissem barrier - scheduling recv from %d\n", from)); + mpi_errno = + MPIR_TSP_sched_irecv(NULL, 0, MPI_BYTE, from, tag, comm, sched, 0, NULL, + &recv_ids[i * (k - 1) + j - 1]); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); + + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, + (MPL_DBG_FDEST, "dissem barrier - scheduling send to %d\n", to)); + mpi_errno = + MPIR_TSP_sched_isend(NULL, 0, MPI_BYTE, to, tag, comm, sched, i * (k - 1), recv_ids, + &vtx_id); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); + + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, + (MPL_DBG_FDEST, "dissem barrier - scheduled phase %d\n", i)); + } + shift *= k; + } + + fn_exit: + MPIR_CHKLMEM_FREEALL(); + MPIR_FUNC_EXIT; + return mpi_errno; + fn_fail: + goto fn_exit; +} diff --git a/src/mpi/coll/include/csel_container.h b/src/mpi/coll/include/csel_container.h index aa1c1f9457a..e6630a19175 100644 --- a/src/mpi/coll/include/csel_container.h +++ b/src/mpi/coll/include/csel_container.h @@ -111,6 +111,7 @@ typedef enum { MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ialltoallw_inter_sched_pairwise_exchange, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ibarrier_intra_sched_recursive_doubling, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ibarrier_intra_tsp_recexch, + MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ibarrier_intra_tsp_k_dissemination, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ibarrier_inter_sched_bcast, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ibcast_intra_tsp_tree, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ibcast_intra_tsp_scatterv_recexch_allgatherv, @@ -269,6 +270,9 @@ typedef struct { struct { int k; } intra_tsp_recexch; + struct { + int k; + } intra_tsp_k_dissemination; } ibarrier; struct { struct { diff --git a/src/mpi/coll/src/csel_container.c b/src/mpi/coll/src/csel_container.c index 8819c09ec21..3131b4ff1cb 100644 --- a/src/mpi/coll/src/csel_container.c +++ b/src/mpi/coll/src/csel_container.c @@ -481,6 +481,8 @@ void *MPII_Create_container(struct json_object *obj) MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ibarrier_intra_sched_recursive_doubling; else if (!strcmp(ckey, "algorithm=MPIR_Ibarrier_intra_tsp_recexch")) cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ibarrier_intra_tsp_recexch; + else if (!strcmp(ckey, "algorithm=MPIR_Ibarrier_intra_tsp_k_dissem")) + cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ibarrier_intra_tsp_k_dissemination; else if (!strcmp(ckey, "algorithm=MPIR_Ibarrier_inter_sched_bcast")) cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ibarrier_inter_sched_bcast; else if (!strcmp(ckey, "algorithm=MPIR_Ibcast_intra_tsp_tree")) diff --git a/test/mpi/maint/coll_cvars.txt b/test/mpi/maint/coll_cvars.txt index 322d7fec57a..e478b9dfe21 100644 --- a/test/mpi/maint/coll_cvars.txt +++ b/test/mpi/maint/coll_cvars.txt @@ -313,6 +313,8 @@ algorithms: sched_recursive_doubling tsp_recexch .MPIR_CVAR_IBARRIER_RECEXCH_KVAL=2,3,4,8 + tsp_k_dissemination + .MPIR_CVAR_IBARRIER_DISSEM_KVAL=2,3,4,8 bcast: inter-blocking: remote_send_local_bcast From 53a9c5188d4f9ae1f2c7561fd10fc8b31f9b9ed4 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 21 Jan 2022 11:33:42 -0600 Subject: [PATCH 388/607] f08: generate interface for MPI_F_sync_reg MPI_F_sync_reg was not generated in mpi_f08.f90. Although the internal routines were included, it is missing the interface. This is a dummy function that we can easily generate. --- maint/gen_binding_f08.py | 3 +-- maint/local_python/binding_f08.py | 22 +++++++++++-------- src/binding/fortran/use_mpi_f08/Makefile.mk | 2 -- .../use_mpi_f08/wrappers_c/Makefile.mk | 1 - .../fortran/use_mpi_f08/wrappers_c/cdesc.h | 1 - .../use_mpi_f08/wrappers_c/f_sync_reg_c.c | 15 ------------- .../wrappers_f/f_sync_reg_f08ts.f90 | 18 --------------- .../wrappers_f/pf_sync_reg_f08ts.f90 | 18 --------------- 8 files changed, 14 insertions(+), 66 deletions(-) delete mode 100644 src/binding/fortran/use_mpi_f08/wrappers_c/f_sync_reg_c.c delete mode 100644 src/binding/fortran/use_mpi_f08/wrappers_f/f_sync_reg_f08ts.f90 delete mode 100644 src/binding/fortran/use_mpi_f08/wrappers_f/pf_sync_reg_f08ts.f90 diff --git a/maint/gen_binding_f08.py b/maint/gen_binding_f08.py index 4543aa6ea90..9e5ad28263b 100644 --- a/maint/gen_binding_f08.py +++ b/maint/gen_binding_f08.py @@ -26,6 +26,7 @@ def main(): # FIXME: until romio interface is generated func_list.extend(get_mpiio_func_list()) func_list.extend(get_type_create_f90_func_list()) + func_list.append(G.FUNCS['mpi_f_sync_reg']) skip_large_list = [] # skip File large count functions because it is not implemented yet @@ -87,8 +88,6 @@ def main(): dump_mpi_c_interface_cdesc(func, False) if func['_need_large']: dump_mpi_c_interface_cdesc(func, True) - f_sync_reg = {'name':"MPI_F_sync_reg", 'parameters':[{'name':"buf", 'kind':"BUFFER", 't':'', 'large_only':None, 'param_direction':"in"}]} - dump_mpi_c_interface_cdesc(f_sync_reg, False) dump_interface_module_close("mpi_c_interface_cdesc") f = "%s/mpi_c_interface_cdesc.f90" % f08_dir dump_f90_file(f, G.out) diff --git a/maint/local_python/binding_f08.py b/maint/local_python/binding_f08.py index 36b032f4e74..58c854f6806 100644 --- a/maint/local_python/binding_f08.py +++ b/maint/local_python/binding_f08.py @@ -138,15 +138,19 @@ def dump_p(p): G.out.append("#else") G.out.append("INDENT"); G.out.append("int err = MPI_SUCCESS;") - for l in vardecl_list: - G.out.append(l) - G.out.append("") - for l in code_list: - G.out.append(l) - G.out.append("err = %s(%s);" % (get_function_name(func, is_large), ', '.join(c_arg_list))) - G.out.append("") - for l in end_list: - G.out.append(l) + if re.match(r'MPI_F_sync_reg', func['name'], re.IGNORECASE): + # dummy + pass + else: + for l in vardecl_list: + G.out.append(l) + G.out.append("") + for l in code_list: + G.out.append(l) + G.out.append("err = %s(%s);" % (get_function_name(func, is_large), ', '.join(c_arg_list))) + G.out.append("") + for l in end_list: + G.out.append(l) G.out.append("return err;") G.out.append("DEDENT") if re.match(r'MPI_File_', func['name']): diff --git a/src/binding/fortran/use_mpi_f08/Makefile.mk b/src/binding/fortran/use_mpi_f08/Makefile.mk index 53a2bf19798..d803f4652b2 100644 --- a/src/binding/fortran/use_mpi_f08/Makefile.mk +++ b/src/binding/fortran/use_mpi_f08/Makefile.mk @@ -53,8 +53,6 @@ BUILT_SOURCES += $(f08_module_files) CLEANFILES += $(f08_module_files) mpi_fc_sources += \ - src/binding/fortran/use_mpi_f08/wrappers_f/f_sync_reg_f08ts.f90 \ - src/binding/fortran/use_mpi_f08/wrappers_f/pf_sync_reg_f08ts.f90 \ src/binding/fortran/use_mpi_f08/wrappers_f/f08ts.f90 \ src/binding/fortran/use_mpi_f08/wrappers_f/pf08ts.f90 diff --git a/src/binding/fortran/use_mpi_f08/wrappers_c/Makefile.mk b/src/binding/fortran/use_mpi_f08/wrappers_c/Makefile.mk index e21abacdcfa..da6d3ad4d6c 100644 --- a/src/binding/fortran/use_mpi_f08/wrappers_c/Makefile.mk +++ b/src/binding/fortran/use_mpi_f08/wrappers_c/Makefile.mk @@ -9,7 +9,6 @@ mpi_fc_sources += \ src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.c \ src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_c.c \ src/binding/fortran/use_mpi_f08/wrappers_c/comm_spawn_multiple_c.c \ - src/binding/fortran/use_mpi_f08/wrappers_c/f_sync_reg_c.c \ src/binding/fortran/use_mpi_f08/wrappers_c/utils.c AM_CPPFLAGS += -I${main_top_srcdir}/src/binding/fortran/use_mpi_f08/wrappers_c -Isrc/binding/fortran/use_mpi_f08/wrappers_c diff --git a/src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.h b/src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.h index 1ea7b00147e..52997e28a1d 100644 --- a/src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.h +++ b/src/binding/fortran/use_mpi_f08/wrappers_c/cdesc.h @@ -32,7 +32,6 @@ extern int MPIR_Comm_spawn_multiple_c(int count, char *array_of_commands_f, char int root, MPI_Comm comm, MPI_Comm * intercomm, int *array_of_errcodes, int commands_elem_len, int argv_elem_len); -extern int MPIR_F_sync_reg_cdesc(CFI_cdesc_t * buf); void *MPIR_F08_get_MPI_STATUS_IGNORE(void); void *MPIR_F08_get_MPI_STATUSES_IGNORE(void); diff --git a/src/binding/fortran/use_mpi_f08/wrappers_c/f_sync_reg_c.c b/src/binding/fortran/use_mpi_f08/wrappers_c/f_sync_reg_c.c deleted file mode 100644 index 2ae72d6a1e6..00000000000 --- a/src/binding/fortran/use_mpi_f08/wrappers_c/f_sync_reg_c.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) by Argonne National Laboratory - * See COPYRIGHT in top-level directory - */ - -#include "cdesc.h" - -int MPIR_F_sync_reg_cdesc(CFI_cdesc_t * buf) -{ - int err = MPI_SUCCESS; - - /* Intentionally left empty */ - - return err; -} diff --git a/src/binding/fortran/use_mpi_f08/wrappers_f/f_sync_reg_f08ts.f90 b/src/binding/fortran/use_mpi_f08/wrappers_f/f_sync_reg_f08ts.f90 deleted file mode 100644 index 02618a9dee1..00000000000 --- a/src/binding/fortran/use_mpi_f08/wrappers_f/f_sync_reg_f08ts.f90 +++ /dev/null @@ -1,18 +0,0 @@ -! -! Copyright (C) by Argonne National Laboratory -! See COPYRIGHT in top-level directory -! - -subroutine MPI_F_sync_reg_f08ts(buf) - use, intrinsic :: iso_c_binding, only : c_int - use :: mpi_c_interface, only : MPIR_F_sync_reg_cdesc - - implicit none - - type(*), dimension(..) :: buf - - integer(c_int) :: ierror_c - - ierror_c = MPIR_F_sync_reg_cdesc(buf) - -end subroutine MPI_F_sync_reg_f08ts diff --git a/src/binding/fortran/use_mpi_f08/wrappers_f/pf_sync_reg_f08ts.f90 b/src/binding/fortran/use_mpi_f08/wrappers_f/pf_sync_reg_f08ts.f90 deleted file mode 100644 index fa6998c387a..00000000000 --- a/src/binding/fortran/use_mpi_f08/wrappers_f/pf_sync_reg_f08ts.f90 +++ /dev/null @@ -1,18 +0,0 @@ -! -! Copyright (C) by Argonne National Laboratory -! See COPYRIGHT in top-level directory -! - -subroutine PMPIR_F_sync_reg_f08ts(buf) - use, intrinsic :: iso_c_binding, only : c_int - use :: mpi_c_interface, only : MPIR_F_sync_reg_cdesc - - implicit none - - type(*), dimension(..) :: buf - - integer(c_int) :: ierror_c - - ierror_c = MPIR_F_sync_reg_cdesc(buf) - -end subroutine PMPIR_F_sync_reg_f08ts From c28dcd282220d7544eb04ab2b9546966c9d3573b Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 21 Jan 2022 12:09:23 -0600 Subject: [PATCH 389/607] f77: add MPI_F_sync_reg This function was missing. We just need add a dummy implementation. --- maint/gen_binding_f77.py | 1 + maint/local_python/binding_f77.py | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/maint/gen_binding_f77.py b/maint/gen_binding_f77.py index 374ad60e400..4b19e52eb51 100644 --- a/maint/gen_binding_f77.py +++ b/maint/gen_binding_f77.py @@ -27,6 +27,7 @@ def main(): func_list.extend(get_mpiio_func_list()) func_list.extend(get_f77_dummy_func_list()) func_list.extend(get_type_create_f90_func_list()) + func_list.append(G.FUNCS['mpi_f_sync_reg']) # preprocess for func in func_list: diff --git a/maint/local_python/binding_f77.py b/maint/local_python/binding_f77.py index 4cd54bdc953..2f72d67b71f 100644 --- a/maint/local_python/binding_f77.py +++ b/maint/local_python/binding_f77.py @@ -41,6 +41,8 @@ def dump_f77_c_func(func): need_ATTR_AINT = True elif re.match(r'MPI.*_(DUP|DELETE|COPY)_FN|MPI_CONVERSION_FN_NULL', func['name'], re.IGNORECASE): is_custom_fn = True + elif re.match(r'MPI_F_sync_reg', func['name'], re.IGNORECASE): + is_custom_fn = True if len(func['parameters']) > 0: last_p = func['parameters'][-1] @@ -537,6 +539,8 @@ def dump_custom_functions(func): G.out.append("*%s = MPI_SUCCESS;" % err) elif re.match(r'MPI.*_NULL_DELETE_FN', func['name'], re.IGNORECASE): G.out.append("*%s = MPI_SUCCESS;" % err) + elif re.match(r'MPI_F_sync_reg', func['name'], re.IGNORECASE): + G.out.append("*ierr = MPI_SUCCESS;") else: raise Exception("Unhandled dummy function - %s" % func['name']) From 88abd722a42b4c4974cb2c9c959917becb24f804 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 26 May 2021 17:40:21 -0500 Subject: [PATCH 390/607] binding/c: generate C bindings in a single source $PYTHON maint/gen_binding_c.py -single-source will generate a single src/binding/c/c_binding.c. This expedites the compilation by 20%. --- maint/gen_binding_c.py | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/maint/gen_binding_c.py b/maint/gen_binding_c.py index 1e5ff9b6d86..9721528c154 100644 --- a/maint/gen_binding_c.py +++ b/maint/gen_binding_c.py @@ -10,6 +10,9 @@ import glob def main(): + # currently support: -single-source + G.parse_cmdline() + binding_dir = G.get_srcdir_path("src/binding") c_dir = "src/binding/c" func_list = load_C_func_list(binding_dir) @@ -31,8 +34,17 @@ def main(): G.mpi_declares.append(get_declare_function(func, False, "proto")) # -- Generating code -- - for func in func_list: + G.out = [] + # internal function to dump G.out into filepath + def dump_out(file_path): + G.check_write_path(file_path) + dump_c_file(file_path, G.out) + # add to mpi_sources for dump_Makefile_mk() + G.mpi_sources.append(file_path) G.out = [] + + # ---- + for func in func_list: G.err_codes = {} # dumps the code to G.out array @@ -44,13 +56,14 @@ def main(): else: dump_mpi_c(func, False) - file_path = get_func_file_path(func, c_dir) - G.check_write_path(file_path) - dump_c_file(file_path, G.out) - - # add to mpi_sources for dump_Makefile_mk() - G.mpi_sources.append(file_path) + if 'single-source' not in G.opts: + # dump individual functions in separate source files + dump_out(get_func_file_path(func, c_dir)) + if 'single-source' in G.opts: + # otherwise, dump all functions in binding.c + dump_out(c_dir + "/c_binding.c") + # -- Dump other files -- G.check_write_path(c_dir) G.check_write_path("src/include") G.check_write_path("src/mpi_t") From 3ebb447e8a9a272982490306b18247b0a71e8337 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 23 Jan 2022 09:39:45 -0600 Subject: [PATCH 391/607] autogen: in quick mode generate single c binding source This will accelerate the compilation. --- autogen.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/autogen.sh b/autogen.sh index 9a053f86ffd..4027c407d8a 100755 --- a/autogen.sh +++ b/autogen.sh @@ -530,7 +530,11 @@ fn_gen_coll() { fn_gen_binding_c() { set_PYTHON echo_n "generating MPI C functions..." - $PYTHON maint/gen_binding_c.py + if test "$do_quick" = "no" ; then + $PYTHON maint/gen_binding_c.py + else + $PYTHON maint/gen_binding_c.py -single-source + fi echo "done" } From ccd6f036a1da3092a0f075ce594926065d19164f Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 1 Feb 2022 15:58:28 -0600 Subject: [PATCH 392/607] autogen: skip autotools version check in quick mode For CI jobs where we always test with a pre-configured environment, checking autotools versions are unnecessary. Since the checking is very slow, it makes sense to skip them with `-quick` option. --- autogen.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/autogen.sh b/autogen.sh index 4027c407d8a..a6cdc78238a 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1011,7 +1011,11 @@ done ## Check for the location of autotools ######################################################################## -fn_check_autotools +if test "$do_quick" = "no" ; then + fn_check_autotools +else + set_autotools +fi fn_check_bash_find_patch_xargs check_python3 From b4e30d93df271b4139d122bfaf33d08710d2a35e Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 25 Jan 2022 00:01:06 -0600 Subject: [PATCH 393/607] mpl: fix double duplicate definition of PATH_MAX We define PATH_MAX if PATH_MAX is not defined. Sometime limits.h defines it but we didn't include limits.h first. This result in we defining PATH_MAX first and limits.h included later and defines it again, resulting in duplcated define warnings. Fix this by include first. --- src/mpl/include/mpl_base.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mpl/include/mpl_base.h b/src/mpl/include/mpl_base.h index b412ed2afe6..ec3184a694f 100644 --- a/src/mpl/include/mpl_base.h +++ b/src/mpl/include/mpl_base.h @@ -16,6 +16,7 @@ #include #include #include +#include #if defined MPL_HAVE_CTYPE_H #include From f5645abd8418fdfad8fd41ba0a2b873ebba4489e Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 28 Jan 2022 14:42:52 -0600 Subject: [PATCH 394/607] coll: gen_coll to consolidate extra_params Consolidate extra_const_params with extra_params and cvar_params in coll_algorithms.txt. This simplifies the interface and allows custom ordering of the extra parameters. --- maint/gen_coll.py | 64 ++++++++++++++++++-------------- src/mpi/coll/coll_algorithms.txt | 51 +++++++++++-------------- 2 files changed, 58 insertions(+), 57 deletions(-) diff --git a/maint/gen_coll.py b/maint/gen_coll.py index abacf98043c..18a45f7ade1 100644 --- a/maint/gen_coll.py +++ b/maint/gen_coll.py @@ -600,37 +600,45 @@ def get_params_and_args(func): def get_algo_extra_args(algo, kind): (func_name, commkind) = algo['func-commkind'].split('-') - if kind == "csel": - prefix = "cnt->u.%s.%s_%s." % (func_name, commkind, algo['name']) - extra_args = re.sub(r'(\w+)', r"%s\1" % prefix, algo['extra_params']) - elif kind == "cvar": - prefix = "MPIR_CVAR_%s_" % func_name.upper() - extra_args = re.sub(r'(\w+)', r"%s\1" % prefix, algo['cvar_params']) - if re.match(r"%sTREE_TYPE" % prefix, extra_args): - newname = "MPIR_%s_tree_type" % func_name.capitalize() - extra_args = re.sub(r"%sTREE_TYPE" % prefix, newname, extra_args) - elif re.match(r"%sTHROTTLE" % prefix, extra_args): - newname = "MPIR_CVAR_ALLTOALL_THROTTLE" - extra_args = re.sub(r"%sTHROTTLE" % prefix, newname, extra_args) - else: - raise Exception("Wrong kind!") + extra_params = algo['extra_params'].replace(' ', '').split(',') + cvar_params = algo['cvar_params'].replace(' ', '').split(',') + if len(extra_params) != len(cvar_params): + raise Exception("algorithm %s-%s-%s: extra_params and cvar_params sizes mismatch!" % (func_name, commkind, algo['name'])) + + out_list = [] + for i in range(len(extra_params)): + if RE.match(r'\w+=(.+)', extra_params[i]): + # constant parameter + out_list.append(RE.m.group(1)) + else: + if kind == "csel": + prefix = "cnt->u.%s.%s_%s." % (func_name, commkind, algo['name']) + out_list.append(prefix + extra_params[i]) + elif kind == "cvar": + prefix = "MPIR_CVAR_%s_" % func_name.upper() + tmp = prefix + cvar_params[i] + if re.match(r"%sTREE_TYPE" % prefix, tmp): + newname = "MPIR_%s_tree_type" % func_name.capitalize() + tmp = re.sub(r"%sTREE_TYPE" % prefix, newname, tmp) + elif re.match(r"%sTHROTTLE" % prefix, tmp): + newname = "MPIR_CVAR_ALLTOALL_THROTTLE" + tmp = re.sub(r"%sTHROTTLE" % prefix, newname, tmp) + out_list.append(tmp) + else: + raise Exception("Wrong kind!") - if 'extra_const_params' in algo: - extra_const_args = re.sub(r'(\w+=)', '', algo['extra_const_params']) - return extra_const_args + ', ' + extra_args - else: - return extra_args + return ', '.join(out_list) def get_algo_extra_params(algo): - extra_args = [] - if 'extra_const_params' in algo: - t = re.sub(r'=[^,\s]+', '', algo['extra_const_params']) - extra_args.extend(t.replace(' ', '').split(',')) - extra_args.extend(algo['extra_params'].replace(' ', '').split(',')) - extra_params = [] - for a in extra_args: - extra_params.append("int " + a) - return ', '.join(extra_params) + extra_params = algo['extra_params'].replace(' ', '').split(',') + out_list = [] + for a in extra_params: + if RE.match(r'(\w+)=.+', a): + # constant parameter + out_list.append("int " + RE.m.group(1)) + else: + out_list.append("int " + a) + return ', '.join(out_list) # additional wrappers def get_algo_args(args, algo, kind): diff --git a/src/mpi/coll/coll_algorithms.txt b/src/mpi/coll/coll_algorithms.txt index 2ab2c373bdf..edca0b068af 100644 --- a/src/mpi/coll/coll_algorithms.txt +++ b/src/mpi/coll/coll_algorithms.txt @@ -33,10 +33,12 @@ # parameters. For csel selections, they are supplied int the container structure (with # field name listed in extraparams). For CVAR direct algorithm, they are supplied with # CVAR names listed in cvar_params (without the common prefix). +# Both extra_params and cvar_params must have the same number of parameters and with +# the same order. In addition, some of the extra parameter can be constant by specify +# a initialization, e.g. param1=val. Rather than repeating the same constant in the +# cvar_params, we can use `-` as placeholder for the corresponding constant param. # * func_name: # Some algorithm use another algorithm or use a different function name. -# * extra_const_params: -# Some algorithm may need extra params that are not depend on csel container or variable CVARs. barrier-intra: dissemination @@ -83,9 +85,8 @@ ibcast-intra: cvar_params: SCATTERV_KVAL, ALLGATHERV_RECEXCH_KVAL tsp_ring func_name: tree - extra_const_params: tree_type=MPIR_TREE_TYPE_KARY, k=1 - extra_params: chunk_size - cvar_params: RING_CHUNK_SIZE + extra_params: tree_type=MPIR_TREE_TYPE_KARY, k=1, chunk_size + cvar_params: -, -, RING_CHUNK_SIZE bcast-inter: remote_send_local_bcast ibcast-inter: @@ -174,14 +175,12 @@ iallgather-intra: cvar_params: BRUCKS_KVAL tsp_recexch_doubling func_name: recexch - extra_const_params: recexch_type=MPIR_IALLGATHER_RECEXCH_TYPE_DISTANCE_DOUBLING - extra_params: k - cvar_params: RECEXCH_KVAL + extra_params: recexch_type=MPIR_IALLGATHER_RECEXCH_TYPE_DISTANCE_DOUBLING, k + cvar_params: -, RECEXCH_KVAL tsp_recexch_halving func_name: recexch - extra_const_params: recexch_type=MPIR_IALLGATHER_RECEXCH_TYPE_DISTANCE_HALVING - extra_params: k - cvar_params: RECEXCH_KVAL + extra_params: recexch_type=MPIR_IALLGATHER_RECEXCH_TYPE_DISTANCE_HALVING, k + cvar_params: -, RECEXCH_KVAL iallgather-inter: sched_local_gather_remote_bcast @@ -200,15 +199,13 @@ iallgatherv-intra: tsp_recexch_doubling restrictions: displs-ordered func_name: recexch - extra_const_params: recexch_type=MPIR_IALLGATHERV_RECEXCH_TYPE_DISTANCE_DOUBLING - extra_params: k - cvar_params: RECEXCH_KVAL + extra_params: recexch_type=MPIR_IALLGATHERV_RECEXCH_TYPE_DISTANCE_DOUBLING, k + cvar_params: -, RECEXCH_KVAL tsp_recexch_halving restrictions: displs-ordered func_name: recexch - extra_const_params: recexch_type=MPIR_IALLGATHERV_RECEXCH_TYPE_DISTANCE_HALVING - extra_params: k - cvar_params: RECEXCH_KVAL + extra_params: recexch_type=MPIR_IALLGATHERV_RECEXCH_TYPE_DISTANCE_HALVING, k + cvar_params: -, RECEXCH_KVAL tsp_ring tsp_brucks extra_params: k @@ -316,9 +313,8 @@ ireduce-intra: cvar_params: TREE_TYPE, TREE_KVAL, TREE_PIPELINE_CHUNK_SIZE, TREE_BUFFER_PER_CHILD tsp_ring func_name: tree - extra_const_params: tree_type=MPIR_TREE_TYPE_KARY, k=1 - extra_params: chunk_size, buffer_per_child - cvar_params: RING_CHUNK_SIZE, TREE_BUFFER_PER_CHILD + extra_params: tree_type=MPIR_TREE_TYPE_KARY, k=1, chunk_size, buffer_per_child + cvar_params: -, -, RING_CHUNK_SIZE, TREE_BUFFER_PER_CHILD ireduce-inter: sched_local_reduce_remote_send @@ -345,14 +341,12 @@ iallreduce-intra: restrictions: size-ge-pof2, builtin-op tsp_recexch_single_buffer func_name: recexch - extra_const_params: recexch_type=MPIR_IALLREDUCE_RECEXCH_TYPE_SINGLE_BUFFER - extra_params: k - cvar_params: RECEXCH_KVAL + extra_params: recexch_type=MPIR_IALLREDUCE_RECEXCH_TYPE_SINGLE_BUFFER, k + cvar_params: -, RECEXCH_KVAL tsp_recexch_multiple_buffer func_name: recexch - extra_const_params: recexch_type=MPIR_IALLREDUCE_RECEXCH_TYPE_MULTIPLE_BUFFER - extra_params: k - cvar_params: RECEXCH_KVAL + extra_params: recexch_type=MPIR_IALLREDUCE_RECEXCH_TYPE_MULTIPLE_BUFFER, k + cvar_params: -, RECEXCH_KVAL tsp_tree extra_params: tree_type, k, chunk_size, buffer_per_child cvar_params: TREE_TYPE, TREE_KVAL, TREE_PIPELINE_CHUNK_SIZE, TREE_BUFFER_PER_CHILD @@ -384,9 +378,8 @@ ireduce_scatter-intra: restrictions: commutative tsp_recexch restrictions: commutative - extra_const_params: recexch_type=IREDUCE_SCATTER_RECEXCH_TYPE_DISTANCE_DOUBLING - extra_params: k - cvar_params: RECEXCH_KVAL + extra_params: recexch_type=IREDUCE_SCATTER_RECEXCH_TYPE_DISTANCE_DOUBLING, k + cvar_params: -, RECEXCH_KVAL ireduce_scatter-inter: sched_remote_reduce_local_scatterv From 65d3611f5451cb5df7098904951ed3a6f519b51e Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 26 Jan 2022 22:07:34 -0600 Subject: [PATCH 395/607] init: fix missing initialization when init after session_init Some initialization steps are only carried out during world MPI_Init. When we run MPI_Init after MPI_Session_init, some of these world-only steps was mistakenly skipped. Make sure we check and run these steps. --- src/mpi/init/mpir_init.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/mpi/init/mpir_init.c b/src/mpi/init/mpir_init.c index 54699093988..ce8e89a7fef 100644 --- a/src/mpi/init/mpir_init.c +++ b/src/mpi/init/mpir_init.c @@ -276,6 +276,16 @@ int MPII_Init_thread(int *argc, char ***argv, int user_required, int *provided, fn_exit: if (is_world_model) { + if (!MPIR_Process.comm_world) { + mpi_errno = MPIR_init_comm_world(); + MPIR_ERR_CHECK(mpi_errno); + } + + if (!MPIR_Process.comm_self) { + mpi_errno = MPIR_init_comm_self(); + MPIR_ERR_CHECK(mpi_errno); + } + MPII_world_set_initilized(); mpi_errno = MPII_init_async(); From 578fc5b466804e8a012ab86b828930c009cc1e00 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Fri, 4 Feb 2022 13:16:30 -0600 Subject: [PATCH 396/607] configure: Fix prebuilt yaksa configuration configure was skipping yaksa reconfiguration even when prebuilt modules were not in use. --- src/mpi/datatype/typerep/src/subconfigure.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mpi/datatype/typerep/src/subconfigure.m4 b/src/mpi/datatype/typerep/src/subconfigure.m4 index e72262a08ac..3da3b5673ca 100644 --- a/src/mpi/datatype/typerep/src/subconfigure.m4 +++ b/src/mpi/datatype/typerep/src/subconfigure.m4 @@ -47,7 +47,7 @@ m4_define([yaksa_embedded_dir],[modules/yaksa]) PAC_CHECK_HEADER_LIB_EXPLICIT([yaksa],[yaksa.h],[$YAKSALIBNAME],[yaksa_init]) if test "$with_yaksa" = "embedded" ; then yaksalib="modules/yaksa/lib${YAKSALIBNAME}.la" - if test ! -e "$yaksalib" ; then + if test ! -e "${use_top_srcdir}/modules/PREBUILT" -o ! -e "$yaksalib"; then PAC_PUSH_ALL_FLAGS() PAC_RESET_ALL_FLAGS() # no need for libtool versioning when embedding YAKSA From 6050781ae858a87367e45aee9f9f52c75b7b8039 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 3 Feb 2022 10:57:46 -0600 Subject: [PATCH 397/607] test: check empty mpiexec When supplied with empty --mpiexec= option to runtests, it may cause weird test failure messages. Add a sanity check to prevent that. --- test/mpi/runtests | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/mpi/runtests b/test/mpi/runtests index faf38e6c54a..1c36d49d4b5 100755 --- a/test/mpi/runtests +++ b/test/mpi/runtests @@ -281,6 +281,10 @@ foreach $_ (@ARGV) { } } +if (!$g_opt{mpiexec}) { + die "Missing mpiexec. Did you supplied empty MPIEXEC environment or empty --mpiexec= option?\n"; +} + # Perform any post argument processing $g_opt{srcdir} = Cwd::abs_path($g_opt{srcdir}); From a40b5da677614143b01ae2d71dd91590a3f11c0d Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 3 Feb 2022 11:10:40 -0600 Subject: [PATCH 398/607] test: check and set MPIEXEC variable This prevents empty -mpiexec= option in the make testing rule. --- test/mpi/configure.ac | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index a4de99589a6..6f865bf4bfe 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -349,6 +349,7 @@ PAC_GET_EXENAME("mpicc", MPICC_NAME) PAC_GET_EXENAME("mpif77", MPIF77_NAME) PAC_GET_EXENAME("mpifort", MPIFORT_NAME) PAC_GET_EXENAME("mpicxx", MPICXX_NAME) +PAC_GET_EXENAME("mpiexec", MPIEXEC_NAME) if test -n "$with_mpi" ; then if test -z "$MPICC" ; then @@ -371,6 +372,9 @@ if test -n "$with_mpi" ; then else CXX=$MPICXX fi + if test -z "$MPIEXEC" ; then + MPIEXEC=$with_mpi/bin/$MPIEXEC_NAME + fi else # Try to use mpicc etc names if test -z "$MPICC" ; then @@ -399,7 +403,12 @@ else if test "x$MPICXX" != "x" ; then CXX=$MPICXX fi + if test -z "$MPIEXEC" ; then + AC_PATH_PROG(MPIEXEC,$MPIEXEC_NAME mpiexec) + fi fi +dnl MPIEXEC is used in the Makefile testing target. +AC_SUBST([MPIEXEC]) # Make sure we export CC before configuring DTPools, since MPI is # needed to build the library. From 4fc981306cf575149a3ffc828d25905310541187 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 18 Nov 2021 08:12:42 -0600 Subject: [PATCH 399/607] binding: update custom_mapping.txt Add F90 mappings. --- src/binding/custom_mapping.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/binding/custom_mapping.txt b/src/binding/custom_mapping.txt index 30beddbc7da..0c42550e3fc 100644 --- a/src/binding/custom_mapping.txt +++ b/src/binding/custom_mapping.txt @@ -5,6 +5,14 @@ LIS_KIND_MAP: GPU_TYPE: integer GREQUEST_CLASS: None +SMALL_F90_KIND_MAP: + GPU_TYPE: INTEGER + GREQUEST_CLASS: INTEGER + +BIG_F90_KIND_MAP: + GPU_TYPE: INTEGER + GREQUEST_CLASS: INTEGER + SMALL_F08_KIND_MAP: GPU_TYPE: INTEGER GREQUEST_CLASS: INTEGER From ba311bc652e73c0de5e4f9e00645b3fe405923df Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 28 Nov 2021 09:25:26 -0600 Subject: [PATCH 400/607] f77: generate mpix functions New API functions are using MPIX prefix in C bindings. This patch makes them available in Fortran bindings with consistent mpix prefix. --- maint/local_python/binding_f77.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/maint/local_python/binding_f77.py b/maint/local_python/binding_f77.py index 2f72d67b71f..6da5768890a 100644 --- a/maint/local_python/binding_f77.py +++ b/maint/local_python/binding_f77.py @@ -9,12 +9,8 @@ import re -def get_f77_name(func): - name = func['name'] - return name - def dump_f77_c_func(func): - name = get_f77_name(func).lower() + func_name = get_function_name(func) f_mapping = get_kind_map('F90') c_mapping = get_kind_map('C') @@ -828,7 +824,7 @@ def process_func_parameters(): process_func_parameters() - c_func_name = func['name'] + c_func_name = func_name if need_ATTR_AINT: if RE.match(r'MPI_Attr_(get|put)', func['name'], re.IGNORECASE): if RE.m.group(1) == 'put': @@ -868,7 +864,7 @@ def process_func_parameters(): if c_param_list_end: param_str += ' ' + ' '.join(c_param_list_end) - use_name = dump_profiling(name, param_str, return_type) + use_name = dump_profiling(func_name, param_str, return_type) G.out.append("") dump_mpi_decl_begin(use_name, param_str, return_type) @@ -1122,8 +1118,6 @@ def dump_fortran_line(s): def check_func_directives(func): if 'dir' in func and func['dir'] == "mpit": func['_skip_fortran'] = 1 - elif 'mpix' in func: - func['_skip_fortran'] = 1 elif RE.match(r'mpix_grequest_', func['name'], re.IGNORECASE): func['_skip_fortran'] = 1 elif RE.match(r'mpi_\w+_(f|f08|c)2(f|f08|c)$', func['name'], re.IGNORECASE): From b3268719403e45a6aa16c25ca1624360cda08d6b Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 26 Nov 2021 21:33:06 -0600 Subject: [PATCH 401/607] f08: move status_fields and handle_list to __init__.py So that f90 bindings can use the list too. Keep the array in global ensures they are consistent. --- maint/local_python/__init__.py | 3 +++ maint/local_python/binding_f08.py | 18 ++++++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/maint/local_python/__init__.py b/maint/local_python/__init__.py index a8ee2a98c1e..56a1e2ecc16 100644 --- a/maint/local_python/__init__.py +++ b/maint/local_python/__init__.py @@ -56,6 +56,9 @@ def check_write_path(path): impl_declares = [] mpi_errnames = [] + status_fields = ["count_lo", "count_hi_and_cancelled", "MPI_SOURCE", "MPI_TAG", "MPI_ERROR"] + handle_list = ["Comm", "Datatype", "Errhandler", "File", "Group", "Info", "Op", "Request", "Win", "Message", "Session"] + handle_mpir_types = { 'COMMUNICATOR': "MPIR_Comm", 'GROUP': "MPIR_Group", diff --git a/maint/local_python/binding_f08.py b/maint/local_python/binding_f08.py index 58c854f6806..4c65197e7d3 100644 --- a/maint/local_python/binding_f08.py +++ b/maint/local_python/binding_f08.py @@ -988,16 +988,14 @@ def dump_fortran_line(s): G.out.extend(tlist) # ---- mpi_f08_types.f90 ------------------------- -G.f08_handle_list = ["Comm", "Datatype", "Errhandler", "File", "Group", "Info", "Op", "Request", "Win", "Message", "Session"] G.f08_sizeof_list = ["character", "logical", "xint8", "xint16", "xint32", "xint64", "xreal32", "xreal64", "xreal128", "xcomplex32", "xcomplex64", "xcomplex128"] def dump_mpi_f08_types(): - status_fields = ["count_lo", "count_hi_and_cancelled", "MPI_SOURCE", "MPI_TAG", "MPI_ERROR"] def dump_status_type(): # Status need be consistent with mpi.h G.out.append("") G.out.append("TYPE, bind(C) :: MPI_Status") - for field in status_fields: + for field in G.status_fields: G.out.append(" INTEGER :: %s" % field) G.out.append("END TYPE MPI_Status") G.out.append("") @@ -1034,9 +1032,9 @@ def field(t, name, idx): if idx < 2: return "%s(%d)" % (name, idx + 1) else: - return "%s(%s)" % (name, status_fields[idx]) + return "%s(%s)" % (name, G.status_fields[idx]) else: - return "%s%%%s" % (name, status_fields[idx]) + return "%s%%%s" % (name, G.status_fields[idx]) # body of the status conversion routines def dump_convert(in_type, in_name, out_type, out_name, res): @@ -1114,7 +1112,7 @@ def dump_convert_mpi(in_type, out_type, prefix): dump_convert_mpi("c", "f08", prefix) def dump_handle_types(): - for a in G.f08_handle_list: + for a in G.handle_list: G.out.append("") G.out.append("TYPE, bind(C) :: MPI_%s" % a) G.out.append(" INTEGER :: MPI_VAL") @@ -1128,13 +1126,13 @@ def dump_handle_interface(): op_sym = "/=" G.out.append("") G.out.append("INTERFACE operator(%s)" % op_sym) - for a in G.f08_handle_list: + for a in G.handle_list: G.out.append(" module procedure MPI_%s_%s" % (a, op)) G.out.append(" module procedure MPI_%s_f08_%s_f" % (a, op)) G.out.append(" module procedure MPI_%s_f_%s_f08" % (a, op)) G.out.append("END INTERFACE") G.out.append("") - for a in G.f08_handle_list: + for a in G.handle_list: G.out.append("private :: MPI_%s_%s" % (a, op)) G.out.append("private :: MPI_%s_f08_%s_f" % (a, op)) G.out.append("private :: MPI_%s_f_%s_f08" % (a, op)) @@ -1142,7 +1140,7 @@ def dump_handle_interface(): def dump_handle_routines(): for op in ["eq", "neq"]: G.out.append("") - for a in G.f08_handle_list: + for a in G.handle_list: # e.g. MPI_Comm_eq G.out.append("") G.out.append("FUNCTION MPI_%s_%s(x, y) result(res)" % (a, op)) @@ -1168,7 +1166,7 @@ def dump_handle_routines(): G.out.append(" res = (f08%MPI_VAL /= f)") G.out.append("END FUNCTION %s" % func_name) # e.g. MPI_Comm_f2c - for a in G.f08_handle_list: + for a in G.handle_list: if a == "File": continue for p in [("f", "c"), ("c", "f")]: From 76b64271a7c4723df0e1cf72a2453502b2a503af Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 27 Nov 2021 22:18:08 -0600 Subject: [PATCH 402/607] mpif_h: MPI_UNWEIGHTED and MPI_WEIGHTS_EMPTY as array Both constants need be typed as array or the compiler won't compile once we added the interface in mpi.f90. --- src/binding/fortran/mpif_h/buildiface | 4 ++-- src/binding/fortran/mpif_h/setbotf.f.in | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/binding/fortran/mpif_h/buildiface b/src/binding/fortran/mpif_h/buildiface index 019855a7da7..b68cb0f1bc2 100755 --- a/src/binding/fortran/mpif_h/buildiface +++ b/src/binding/fortran/mpif_h/buildiface @@ -350,8 +350,8 @@ if ($write_mpif) { } # # Finally, the special symbols - print MPIFFD " INTEGER MPI_BOTTOM, MPI_IN_PLACE, MPI_UNWEIGHTED\n"; - print MPIFFD " INTEGER MPI_WEIGHTS_EMPTY\n"; + print MPIFFD " INTEGER MPI_BOTTOM, MPI_IN_PLACE, MPI_UNWEIGHTED(1)\n"; + print MPIFFD " INTEGER MPI_WEIGHTS_EMPTY(1)\n"; # And the external names. This are necessary to # ensure that these are passed as routines, not implicitly-defined diff --git a/src/binding/fortran/mpif_h/setbotf.f.in b/src/binding/fortran/mpif_h/setbotf.f.in index a880c795bec..21949df784b 100644 --- a/src/binding/fortran/mpif_h/setbotf.f.in +++ b/src/binding/fortran/mpif_h/setbotf.f.in @@ -8,7 +8,7 @@ ! STATUS_IGNORE, STATUSES_IGNORE integer si(mpi_status_size), ssi(mpi_status_size,1) ! BOTTOM, IN_PLACE, UNWEIGHTED, WEIGHTED, ERRCODES_IGNORE - integer bt, ip, uw, we, ecsi(1) + integer bt, ip, uw(1), we(1), ecsi(1) ! ARGVS_NULL, ARGV_NULL character*1 asn(1,1), an(1) common /MPIFCMB5/ uw From 6b5772af52b186630413931cffdc031a0ea78154 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 17 Nov 2021 15:15:58 -0600 Subject: [PATCH 403/607] binding/f90: add f90 binding generation python scripts --- maint/gen_binding_f90.py | 62 +++++++ maint/local_python/binding_f90.py | 267 ++++++++++++++++++++++++++++++ 2 files changed, 329 insertions(+) create mode 100644 maint/gen_binding_f90.py create mode 100644 maint/local_python/binding_f90.py diff --git a/maint/gen_binding_f90.py b/maint/gen_binding_f90.py new file mode 100644 index 00000000000..fe11937e7c2 --- /dev/null +++ b/maint/gen_binding_f90.py @@ -0,0 +1,62 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +from local_python import MPI_API_Global as G +from local_python.mpi_api import * +from local_python.binding_common import * +from local_python.binding_f90 import * +from local_python import RE +import os + +def main(): + G.parse_cmdline() + + binding_dir = G.get_srcdir_path("src/binding") + f90_dir = "src/binding/fortran/use_mpi" + func_list = load_C_func_list(binding_dir, True) # suppress noise + if "no-mpiio" in G.opts: + func_list = [f for f in func_list if not f['name'].startswith('MPI_File_')] + else: + func_list.extend(get_mpiio_func_list()) + func_list.extend(get_type_create_f90_func_list()) + func_list.extend(get_f77_dummy_func_list()) + + # mpi_base.f90 + G.out = [] + dump_F_module_open("mpi_base") + G.out.append("INTERFACE") + for func in func_list: + check_func_directives(func) + if '_skip_fortran' in func: + continue + dump_f90_func(func) + G.out.append("") + G.out.append("END INTERFACE") + dump_F_module_close("mpi_base") + + f = "%s/mpi_base.f90" % f90_dir + dump_f90_file(f, G.out) + + # mpi_constants.f90 + G.out = [] + dump_F_module_open("mpi_constants") + dump_f90_constants() + dump_F_module_close("mpi_constants") + + f = "%s/mpi_constants.f90" % f90_dir + dump_f90_file(f, G.out) + + # mpi_sizeofs.f90 + G.out = [] + dump_F_module_open("mpi_sizeofs") + dump_f90_sizeofs() + dump_F_module_close("mpi_sizeofs") + + f = "%s/mpi_sizeofs.f90" % f90_dir + dump_f90_file(f, G.out) + +# --------------------------------------------------------- +if __name__ == "__main__": + main() diff --git a/maint/local_python/binding_f90.py b/maint/local_python/binding_f90.py new file mode 100644 index 00000000000..56b4b1eb960 --- /dev/null +++ b/maint/local_python/binding_f90.py @@ -0,0 +1,267 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +from local_python import MPI_API_Global as G +from local_python.binding_common import * +from local_python import RE + +import re + +def dump_f90_func(func): + f90_mapping = get_kind_map('F90', False) + + f_param_list = [] + decl_list = [] + + tkr_list = [] # variables that need IGNORE tkr (type-kind-rank) check + uses = {} + for p in func['parameters']: + if re.search(r'suppress=.*f90_parameter', p['t']): + continue + if re.search(r'large_only', p['t']): + continue + f_param_list.append(p['name']) + f_type = f90_mapping[p['kind']] + if re.match(r'', f_type, re.IGNORECASE): + # TODO: configure it + if False: + # use assumed type + f_type = 'TYPE(*), INTENT(IN)' + else: + f_type = 'REAL' + tkr_list.append(p['name']) + elif RE.match(r'.*(MPI_\w+_KIND)', f_type, re.IGNORECASE): + int_kind = RE.m.group(1) + if RE.match(r'MPI_Type_(lb|ub|extent|hvector|hindexed|struct)', func['name'], re.IGNORECASE): + f_type = 'INTEGER' + else: + uses[int_kind] = 1 + + if p['kind'] == 'STRING_ARRAY': + decl = "%s :: %s(*)" % (f_type, p['name']) + elif p['kind'] == 'STRING_2DARRAY': + if re.match(r'mpi_comm_spawn_multiple', func['name'], re.IGNORECASE): + decl = "%s :: %s(count, *)" % (f_type, p['name']) + else: + raise Exception("Unexpected") + elif p['length'] is not None: + if re.match(r'CHARACTER.*\*', f_type, re.IGNORECASE): + decl = "%s :: %s" % (f_type, p['name']) + elif isinstance(p['length'], list): + # assume [n, 3] as ranges in MPI_Group_range_excl + decl = "%s :: %s(%s, *)" % (f_type, p['name'], p['length'][1]) + elif p['length']: + decl = "%s :: %s(%s)" % (f_type, p['name'], p['length']) + else: + decl = "%s :: %s(*)" % (f_type, p['name']) + elif p['kind'] == 'STATUS': + uses['MPI_STATUS_SIZE'] = 1 + decl = "INTEGER :: %s(MPI_STATUS_SIZE)" % (p['name']) + else: + decl = "%s :: %s" % (f_type, p['name']) + decl_list.append(decl) + + def dump_uses(): + G.out.append("USE MPI_CONSTANTS, ONLY: %s" % ', '.join(uses.keys())) + + def dump_ignore_tkr(): + tkr_vars = ', '.join(tkr_list) + if G.opts['ignore-tkr'] == 'gcc': # e.g. gfort + # gfortran since 4.9 + G.out.append("!GCC$ ATTRIBUTES NO_ARG_CHECK :: " + tkr_vars) + elif G.opts['ignore-tkr'] == 'dec': # e.g. ifort + G.out.append("!DEC$ ATTRIBUTES NO_ARG_CHECK :: " + tkr_vars) + elif G.opts['ignore-tkr'] == 'pragma': # e.g. sunfort + G.out.append("!$PRAGMA IGNORE_TKR " + tkr_vars) + elif G.opts['ignore-tkr'] == 'dir': # e.g. flang + G.out.append("!DIR$ IGNORE_TKR " + tkr_vars) + elif G.opts['ignore-tkr'] == 'ibm': # e.g. IBM + G.out.append("!IBM* IGNORE_TKR " + tkr_vars) + elif G.opts['ignore-tkr'] == 'assumed': # Assumed type and rank + G.out.append("TYPE(*), DIMENSION(..) :: " + tkr_vars) + else: + raise Exception("Unrognized tkr options: %s" % G.opts['ignore-tkr']) + + if tkr_list and 'ignore-tkr' not in G.opts: + # skip routines with choice buffers unless we can ignore TKR check + return + + func_name = get_function_name(func) + G.out.append("") + if 'return' not in func: + if not len(f_param_list) or not RE.match(r'ierr(or)?', f_param_list[-1]): + f_param_list.append('ierr') + decl_list.append("INTEGER :: ierr") + dump_fortran_line("SUBROUTINE %s(%s)" % (func_name, ', '.join(f_param_list))) + else: + dump_fortran_line("FUNCTION %s(%s) result(res)" % (func_name, ', '.join(f_param_list))) + ret_type = f90_mapping[func['return']] + decl_list.append("%s :: res" % ret_type) + G.out.append("INDENT") + if uses: + dump_uses() + G.out.append("IMPLICIT NONE") + if tkr_list: + dump_ignore_tkr() + G.out.extend(decl_list) + G.out.append("DEDENT") + if 'return' not in func: + G.out.append("END SUBROUTINE %s" % func_name) + else: + G.out.append("END FUNCTION %s" % func_name) + +def dump_f90_constants(): + def get_op_procname(a, op): + if op == '.EQ.': + return a.lower() + 'eq' + elif op == '.NE.': + return a.lower() + 'neq' + else: + raise Exception("Unrecognized op: %s" % op) + + # ---------------------------------- + G.out.append("INCLUDE 'mpifnoext.h'") + + G.out.append("") + dump_F_type_open('MPI_Status') + for field in G.status_fields: + G.out.append("INTEGER :: %s" % field) + dump_F_type_close('MPI_Status') + + for a in G.handle_list: + G.out.append("") + dump_F_type_open("MPI_%s" % a) + G.out.append("INTEGER :: MPI_VAL") + dump_F_type_close("MPI_%s" % a) + + for op in ['.EQ.', '.NE.']: + G.out.append("") + G.out.append("INTERFACE OPERATOR(%s)" % op) + for a in G.handle_list: + G.out.append(" MODULE PROCEDURE %s" % get_op_procname(a, op)) + G.out.append("END INTERFACE") + + G.out.append("") + G.out.append("CONTAINS") + for op in ['.EQ.', '.NE.']: + for a in G.handle_list: + procname = get_op_procname(a, op) + G.out.append("") + G.out.append("LOGICAL FUNCTION %s(lhs, rhs)" % procname) + G.out.append(" TYPE(MPI_%s), INTENT(IN) :: lhs, rhs" % a) + G.out.append(" %s = lhs%%MPI_VAL %s rhs%%MPI_VAL" % (procname, op)) + G.out.append("END FUNCTION %s" % procname) + + +def dump_f90_sizeofs(): + # deprecated in MPI-4, replaced by Fortran intrinsic c_sizeof() and storage_size() + types = {} # list of types we support + types['CH1'] = "CHARACTER" + types['L4'] = "LOGICAL" + types['I1'] = "INTEGER*1" + types['I2'] = "INTEGER*2" + types['I4'] = "INTEGER*4" + types['I8'] = "INTEGER*8" + types['R4'] = "REAL*4" + types['R8'] = "REAL*8" + types['CX8'] = "COMPLEX*8" + types['CX16'] = "COMPLEX*16" + # we may need to configure grom G.opts if types such as INTEGER*4 is not available + if False: + k = "I%d" % G.opts['fint-size'] + types[k] = "INTEGER" + # assuming REAL is 4-byte and DOUBLE PRECISION is 8-byte + types['R4'] = "REAL" + types['R8'] = "DOUBLE PRECISION" + types['CX8'] = "COMPLEX" + types['CX16'] = "DOUBLE COMPLEX" + + G.out.append("PUBLIC :: MPI_SIZEOF") + G.out.append("INTERFACE MPI_SIZEOF") + for k in types.keys(): + G.out.append(" MODULE PROCEDURE MPI_SIZEOF_%s" % k) + G.out.append(" MODULE PROCEDURE MPI_SIZEOF_%sV" % k) + G.out.append("END INTERFACE") + G.out.append("") + G.out.append("CONTAINS") + for k, v in types.items(): + if RE.match(r'[A-Z]+(\d+)', k): + n = int(RE.m.group(1)) + # Scalar + G.out.append("") + G.out.append("SUBROUTINE MPI_SIZEOF_%s(X, SIZE, IERRROR)" %k) + G.out.append(" %s :: X" % v) + G.out.append(" INTEGER :: SIZE, IERRROR") + G.out.append(" SIZE = %d" % n) + G.out.append(" IERRROR = 0") + G.out.append("END SUBROUTINE MPI_SIZEOF_%s" % k) + # Array + G.out.append("") + G.out.append("SUBROUTINE MPI_SIZEOF_%sV(X, SIZE, IERRROR)" %k) + G.out.append(" %s :: X(*)" % v) + G.out.append(" INTEGER :: SIZE, IERRROR") + G.out.append(" SIZE = %d" % n) + G.out.append(" IERRROR = 0") + G.out.append("END SUBROUTINE MPI_SIZEOF_%sV" % k) + +#---------------------------------------- +def check_func_directives(func): + if 'dir' in func and func['dir'] == "mpit": + func['_skip_fortran'] = 1 + elif RE.match(r'mpix_grequest_', func['name'], re.IGNORECASE): + func['_skip_fortran'] = 1 + elif RE.match(r'mpi_attr_', func['name'], re.IGNORECASE): + func['_skip_fortran'] = 1 + elif RE.match(r'.*_function', func['name'], re.IGNORECASE): + func['_skip_fortran'] = 1 + elif RE.match(r'mpi_pcontrol', func['name'], re.IGNORECASE): + func['_skip_fortran'] = 1 + elif RE.match(r'mpi_\w+_(f|f08|c)2(f|f08|c)$', func['name'], re.IGNORECASE): + # implemented in mpi_f08_types.f90 + func['_skip_fortran'] = 1 + +#---------------------------------------- +def dump_F_module_open(name): + G.out.append("MODULE %s" % name) + G.out.append("INDENT") + G.out.append("IMPLICIT NONE") + +def dump_F_module_close(name): + G.out.append("DEDENT") + G.out.append("END MODULE %s" % name) + +def dump_F_type_open(name): + G.out.append("TYPE :: %s" % name) + G.out.append("INDENT") + G.out.append("SEQUENCE") + +def dump_F_type_close(name): + G.out.append("DEDENT") + G.out.append("END TYPE %s" % name) + +def dump_fortran_line(s): + tlist = split_line_with_break(s, '', 100) + n = len(tlist) + if n > 1: + for i in range(n-1): + tlist[i] = tlist[i] + ' &' + G.out.extend(tlist) + +def dump_f90_file(f, lines): + print(" --> [%s]" % f) + with open(f, "w") as Out: + for l in G.copyright_f90: + print(l, file=Out) + indent = 0 + for l in lines: + if RE.match(r'INDENT', l): + indent += 1 + elif RE.match(r'DEDENT', l): + indent -= 1 + else: + if indent > 0: + print(" " * indent, end='', file=Out) + print(l, file=Out) + From 1f4ae13e7eb762108ac91fc0fe979c5c7a0ced11 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 18 Nov 2021 19:17:28 -0600 Subject: [PATCH 404/607] binding/f90: add PMPI_Wtime and PMPI_Wtick The current buildiface have these two and we even have a test -- test/mpi/f90/timer/wtimef90.f90 to make sure of it. This is strange. If we want PMPI versions, we should do it for all functions, which isn't difficult anyway. --- maint/gen_binding_f90.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/maint/gen_binding_f90.py b/maint/gen_binding_f90.py index fe11937e7c2..5b05a14c521 100644 --- a/maint/gen_binding_f90.py +++ b/maint/gen_binding_f90.py @@ -32,6 +32,10 @@ def main(): if '_skip_fortran' in func: continue dump_f90_func(func) + # HACK: I don't understand why we add pmpi versions for only PMPI_W{time,tick} + if re.match(r'mpi_w(time|tick)', func['name'], re.IGNORECASE): + func['name'] = 'P' + func['name'] + dump_f90_func(func) G.out.append("") G.out.append("END INTERFACE") dump_F_module_close("mpi_base") From 9133e09ac63036e9faa84ef025c545b3e4bb8fab Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 18 Nov 2021 08:26:33 -0600 Subject: [PATCH 405/607] f90: remove src/binding/fortran/use_mpi/buildiface It is replaced by maint/gen_binding_f90.py --- src/binding/fortran/use_mpi/binding.sub | 158 --- src/binding/fortran/use_mpi/buildiface | 1271 ----------------------- 2 files changed, 1429 deletions(-) delete mode 100755 src/binding/fortran/use_mpi/binding.sub delete mode 100755 src/binding/fortran/use_mpi/buildiface diff --git a/src/binding/fortran/use_mpi/binding.sub b/src/binding/fortran/use_mpi/binding.sub deleted file mode 100755 index 51802b9ca1c..00000000000 --- a/src/binding/fortran/use_mpi/binding.sub +++ /dev/null @@ -1,158 +0,0 @@ -#! /usr/bin/env perl -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -# This file contains common routines for reading a file of function prototypes -# (such as mpi.h) and extracting the function prototypes. - -# -# ReadInterface( filename, routineprefix, routinepattern, routinehash ) -# Read file filename, look for routines that have a given prefix and name -# pattern, and insert that routine into routinehash with value the -# arguments of the routine. - -#$Finalized_args = "bool"; - -sub ReadInterface { - my $prototype_file = $_[0]; - my $routine_prefix = $_[1]; - my $routine_pattern = $_[2]; - my $routine_hash = $_[3]; - # $debug is a global variable - - open( FD, "<$prototype_file" ) || die "Cannot open $prototype_file\n"; - - # Skip to prototypes - while () { - if ( /\/\*\s*Begin Prototypes/ ) { last; } - } - - # Read each one - while () { - # Handle the special case of prototypes to ignore - if (/\/\*\s*Begin Skip Prototypes/) { - while () { - if (/\/\*\s*End Skip Prototypes/) { last; } - } - } - if (/\/\*\s*End Prototypes/) { last; } - # Remove any comments - $origline = $_; - while (/(.*)\/\*(.*?)\*\/(.*)/) { - my $removed = $2; - $_ = $1.$3; - if ($2 =~ /\/\*/) { - print STDERR "Error in processing comment within interface file $prototype_file in line $origline"; - } - } - - # Parse all routines returning an error code - print "\nParsing : $_" if $gDebug; - if (/^int\s+$routine_prefix($routine_pattern)\s*\((.*)/) { - $routine_name = $1; - $args = $2; - while (! ($args =~ /;/)) { - $args .= ; - } - $args =~ s/MPICH_ATTR[A-Z_]*\([^)]*\)//g; - $args =~ s/MPICH_API_PUBLIC//g; - $args =~ s/\)\s*;//g; - $args =~ s/[\r\n]*//g; - # remove qualifiers from args - $args =~ s/\s*const\s+//g; - - print "Found : $routine_name($args)\n" if $gDebug; - # Eventually, we'll create a new file here. - # For C++, we may create similar files by looking up - # the corresponding routines. - # Check for duplicates in the list of routines - if (defined($$routine_hash{$routine_name})) { - print STDERR "Duplicate prototypes for $routine_name\n"; - next; - } - # Separate argument types and names - my ($argtypes, $argnames) = &separate_args_and_append_ierror($args); - # # Handle special cases - # my $testname = $routine_name . "_args"; - # if (defined($$testname)) { - # print "replacing args for $routine_name\n" if $gDebug; - # $args = $$testname; - # } - $$routine_hash{$routine_name} = [$argtypes, $argnames]; - } - } -} - -# -# Look through $args, separate type and name of each argument. Then group argument -# types and names separately. In addition, append "int", "ierror" to existing -# argument types and names respectively. -# Input: an argument string -# Output: ($argtypes, $argnames), in which types (names) are delimited by comma. -sub separate_args_and_append_ierror { - my $argtypes = ""; - my $argnames = ""; - my $comma = ""; # no comma before the first arg - for my $parm (split(',', $_[0])) { - my $argtype = ""; - my $argname = ""; - # Remove any leading or trailing spaces - $parm =~ s/^\s*//; - $parm =~ s/\s*$//; - # Remove and remember qualifiers - $qualifier = ""; - if ($parm =~ /^const\s+(.*)/) { - $qualifier = "const "; - $parm = $1; - } - - if ($parm eq "void") { # e.g., MPI_Finalize(void) - last; - } - - # Question: What to do with the qualifier? - # Handle parameters with parameter names - # 1. "int foo" - # 2. "int *foo" - # 3. "int foo[]" - # 4. "int *foo[]" or "int **foo[]" - if ( ($parm =~ /^([A-Za-z0-9_]+)\s+([A-Za-z0-9_]+)$/) ) { - $argtype = $1; - $argname = $2; - } - elsif ( ($parm =~ /^([A-Za-z0-9_]+\s*\*)\s*([A-Za-z0-9_]+)$/) ) { - $argtype = $1; - $argname = $2; - } - elsif ( ($parm =~ /^([A-Za-z0-9_]+)\s*([A-Za-z0-9_]+)(\[.*\])\s*$/) ) { - my $basetype = $1; - my $arraytype = $3; - #if ($arraytype =~ /\[\s*\]/) { $arraytype = "*"; } - $argtype = $basetype . $arraytype; - $argname = $2; - } - elsif ( ($parm =~ /^([A-Za-z0-9_]+)\s(\*?\*?)\s*([A-Za-z0-9_]+)(\[.*\])\s*$/) ) { - my $basetype = $1; - my $arraytype = $2 . $4; - #if ($arraytype =~ /\[\s*\]/) { $arraytype = "*"; } - $argtype = $basetype . $arraytype; - $argname = $3; - } - - $argtypes .= "$comma$argtype"; - $argnames .= "$comma$argname"; - $comma = ","; - } - - # Append "int ierror" - $argtypes .= "${comma}int"; - $argnames .= "${comma}ierror"; - print "argtypes= $argtypes\n" if $gDebug; - print "argnames= $argnames\n" if $gDebug; - return ($argtypes, $argnames); -} - -# Since this is a required package, indicate that we are successful. -return 1; diff --git a/src/binding/fortran/use_mpi/buildiface b/src/binding/fortran/use_mpi/buildiface deleted file mode 100755 index 3bdff24cbe1..00000000000 --- a/src/binding/fortran/use_mpi/buildiface +++ /dev/null @@ -1,1271 +0,0 @@ -#! /usr/bin/env perl -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -# FIXME: -# TODO: -# For MPI-3 (See 17.1.3 for details), need to add (for mpi module; mpi_f08 -# module will require different system entirely): -# *ALL* functions declared -# This will require the use of non-standard, compiler-specific options, -# and may require overriding user choices about warning levels and options -# in order to handle the choice arguments -# Provide DERIVED TYPES for MPI_STATUS and all handles (as in the mpi_f08 -# module). For all handle types, provide overloads for .EQ., .NE., == -# and /= operators (Partially done) -# Check on MPI_F_SYNC_REG, mentioned on page 598. - -use warnings; - -# binding.sub provides the routines for reading the prototype file -# and extracting the function definitions. - -# Allow this program to be invoked from a different directory -$mydir = "."; -if (!-s "binding.sub") { - $mydir = $0; - $mydir =~ s/\/buildiface//; -} - -require "$mydir/binding.sub"; - -$gDebug = 0; - -$prototype_file = "../../../include/mpi_proto.h"; -$is_MPI = 1; -$buildMPIX = 0; -$routine_prefix = "MPI_"; -$routine_pattern = "[A-Z][a-z0-9_]*"; -$out_prefix = "MPI_"; -$outfile_prefix = "mpi"; -%CtoFName = (); -%mpi_routines = (); -%NeedConstants = (); # constants needed for declaration, hashed by routine -my $line_limit = 80; # Max line length - -# -# ToDo: Fortran 90 allows some additional checks not possible in Fortran 77. -# For example, the size of an array may be queried. This could be particularly -# useful for the ARGV argument in SPAWN, which in Fortran requires a blank -# line to terminate the ARGV. Even without that, the Fortran 90 wrappers -# could check for the required blank entry, and report an error if it was -# missing. -# - -# -# argtypec2f translates the C/C++ names to the Fortran 90 name. %name% will -# be replaced with the argument name in declarations. -# -# Some picky compilers want an interface description where Fortran 77 -# was happy with a simple EXTERNAL. To handle this, the EXTERNAL -# has a more elaborate form: -# INTERFACE %nl%SUBROUTINE %name%()%nl%%nl%END SUBROUTINE%nl%END INTERFACE -# where %nl% is newline/indent. -# -%argtypec2f = ( - 'int' => 'INTEGER', - 'int[]' => 'INTEGER %name%(*)', - 'int[][3]' => 'INTEGER %name%(3,*)', - 'int*' => 'INTEGER', # assume output scalar (see array - # replacement below) - 'bool' => 'LOGICAL', - 'bool[]' => 'LOGICAL %name%(*)', - 'MPI_Handler_function*' => -'INTERFACE %nl%SUBROUTINE %name%(vv0,vv1)%nl%INTEGER vv0,vv1%nl%END SUBROUTINE%nl%END INTERFACE', - 'MPI_Win_errhandler_function*' => -'INTERFACE %nl%SUBROUTINE %name%(vv0,vv1)%nl%INTEGER vv0,vv1%nl%END SUBROUTINE%nl%END INTERFACE', - 'MPI_Session_errhandler_function*' => -'INTERFACE %nl%SUBROUTINE %name%(vv0,vv1)%nl%INTEGER vv0,vv1%nl%END SUBROUTINE%nl%END INTERFACE', - 'MPI_Comm_errhandler_function*' => -'INTERFACE %nl%SUBROUTINE %name%(vv0,vv1)%nl%INTEGER vv0,vv1%nl%END SUBROUTINE%nl%END INTERFACE', - 'MPI_File_errhandler_function*' => -'INTERFACE %nl%SUBROUTINE %name%(vv0,vv1)%nl%INTEGER vv0,vv1%nl%END SUBROUTINE%nl%END INTERFACE', - - # These other functions have (really void*) arguments - # and so an interface spec is very hard to do in Fortran 90. - 'MPI_Comm_copy_attr_function*' => 'EXTERNAL', - 'MPI_Comm_delete_attr_function*' => 'EXTERNAL', - 'MPI_Type_copy_attr_function*' => 'EXTERNAL', - 'MPI_Type_delete_attr_function*' => 'EXTERNAL', - 'MPI_Win_copy_attr_function*' => 'EXTERNAL', - 'MPI_Win_delete_attr_function*' => 'EXTERNAL', - 'MPI_Copy_function*' => 'EXTERNAL', - 'MPI_Delete_function*' => 'EXTERNAL', - 'MPI_User_function*' => 'EXTERNAL', - 'MPI_Grequest_query_function*' => 'EXTERNAL', - 'MPI_Grequest_free_function*' => 'EXTERNAL', - 'MPI_Grequest_cancel_function*' => 'EXTERNAL', - 'MPI_Datarep_conversion_function*' => 'EXTERNAL', - 'MPI_Datarep_extent_function*' => 'EXTERNAL', - 'MPI_Request' => 'INTEGER', - 'MPI_Request*' => 'INTEGER', - 'MPI_Request[]' => 'INTEGER %name%(*)', - 'MPIO_Request' => 'INTEGER', - 'MPIO_Request*' => 'INTEGER', - 'MPI_Datatype' => 'INTEGER', - 'MPI_Datatype*' => 'INTEGER', - 'MPI_Datatype[]' => 'INTEGER %name%(*)', - 'MPI_Comm' => 'INTEGER', - 'MPI_Comm*' => 'INTEGER', # Never an array of comm - 'MPI_Group' => 'INTEGER', - 'MPI_Group*' => 'INTEGER', # Never an array of groups - 'MPI_Errhandler' => 'INTEGER', - 'MPI_Errhandler*' => 'INTEGER', # Never an array of errhandlers - 'MPI_Op' => 'INTEGER', - 'MPI_Op*' => 'INTEGER', # Never an array of ops - 'MPI_Message' => 'INTEGER', - 'MPI_Message*' => 'INTEGER', # Never an array of messages - 'MPI_Session' => 'INTEGER', - 'MPI_Session*' => 'INTEGER', # Never an array of sessions - 'MPI_Status*' => 'INTEGER %name%(MPI_STATUS_SIZE)', - 'MPI_Status[]' => 'INTEGER %name%(MPI_STATUS_SIZE,*)', - 'MPI_F08_status*' => 'TYPE(MPI_Status)', - 'MPI_Fint*' => 'INTEGER %name%(MPI_STATUS_SIZE)', - 'MPI_Aint' => 'INTEGER(KIND=MPI_ADDRESS_KIND)', - 'MPI_Aint*' => 'INTEGER(KIND=MPI_ADDRESS_KIND)', - 'MPI_Aint[]' => 'INTEGER(KIND=MPI_ADDRESS_KIND) %name%(*)', - 'MPI_Count' => 'INTEGER(KIND=MPI_COUNT_KIND)', - 'MPI_Count*' => 'INTEGER(KIND=MPI_COUNT_KIND)', - 'MPI_Offset' => 'INTEGER(KIND=MPI_OFFSET_KIND)', - 'MPI_Offset*' => 'INTEGER(KIND=MPI_OFFSET_KIND)', - 'MPI_Info' => 'INTEGER', - 'MPI_Info*' => 'INTEGER', # Never an array of info - 'MPI_Info[]' => 'INTEGER %name%(*)', - 'char*' => 'CHARACTER (LEN=*)', - 'char[]' => 'CHARACTER (LEN=*)', - 'char*[]' => 'CHARACTER (LEN=*) %name%(*)', - 'char**[]' => 'CHARACTER (LEN=*) %name%(count,*)', #special case - # from Comm_Spawn_multiple - 'MPI_Win' => 'INTEGER', - 'MPI_Win*' => 'INTEGER', # Never an array of win - 'MPI_File' => 'INTEGER', - 'MPI_File*' => 'INTEGER', # Never an array of files - 'MPI_Message' => 'INTEGER', - 'MPI_Message*' => 'INTEGER', # Never an array of messages -); - -# special_args provides for handling of arguments that require special -# features. The keys are of the form 'Routine-count', with count the -# position of the argument, starting from one. -%special_args = ( - 'Testany-2' => 'MPI_Request[]', - 'Testany-4' => 'bool', - 'Startall-2' => 'MPI_Request[]', - 'Testall-2' => 'MPI_Request[]', - 'Testall-3' => 'bool', - 'Testall-4' => 'MPI_Status[]', - 'Testsome-2' => 'MPI_Request[]', - 'Testsome-4' => 'int[]', - 'Testsome-5' => 'MPI_Status[]', - 'Test-2' => 'bool', - 'Test_cancelled-2' => 'bool', - 'Type_hindexed-2' => 'int[]', - 'Type_hindexed-3' => 'int[]', - 'Type_indexed-2' => 'int[]', - 'Type_indexed-3' => 'int[]', - 'Type_hvector-3' => 'int', - 'Type_struct-2' => 'int[]', - 'Type_struct-3' => 'int[]', - 'Type_struct-4' => 'MPI_Datatype[]', - 'Type_extent-2' => 'int', - 'Type_lb-2' => 'int', - 'Type_ub-2' => 'int', - 'Waitall-2' => 'MPI_Request[]', - 'Waitall-3' => 'MPI_Status[]', - 'Waitany-2' => 'MPI_Request[]', - 'Waitsome-2' => 'MPI_Request[]', - 'Waitsome-4' => 'int[]', - 'Waitsome-5' => 'MPI_Status[]', - 'Group_excl-3' => 'int[]', - 'Group_incl-3' => 'int[]', - 'Group_translate_ranks-3' => 'int[]', - 'Group_translate_ranks-5' => 'int[]', - 'Cart_coords-4' => 'int[]', - 'Cart_create-3' => 'int[]', - 'Cart_create-4' => 'bool[]', - 'Cart_get-3' => 'int[]', - 'Cart_get-5' => 'int[]', - 'Cart_get-4' => 'bool[]', - 'Cart_map-3' => 'int[]', - 'Cart_map-4' => 'bool[]', - 'Cart_rank-2' => 'int[]', - 'Cart_sub-2' => 'bool[]', - 'Dims_create-3' => 'int[]', - 'Graph_create-3' => 'int[]', - 'Graph_create-4' => 'int[]', - 'Graph_create-5' => 'bool', - 'Graph_get-4' => 'int[]', - 'Graph_get-5' => 'int[]', - 'Graph_map-3' => 'int[]', - 'Graph_map-4' => 'int[]', - 'Graph_neighbors-4' => 'int[]', - 'Dist_graph_create-8' => 'bool', - 'Dist_graph_create_adjacent-9' => 'bool', - 'Dist_graph_neighbors_count-4' => 'bool', - 'Allgatherv-5' => 'int[]', - 'Allgatherv-6' => 'int[]', - 'Alltoallv-2' => 'int[]', - 'Alltoallv-3' => 'int[]', - 'Alltoallv-6' => 'int[]', - 'Alltoallv-7' => 'int[]', - 'Alltoallw-2' => 'int[]', - 'Alltoallw-3' => 'int[]', - 'Alltoallw-6' => 'int[]', - 'Alltoallw-7' => 'int[]', - 'Gatherv-5' => 'int[]', - 'Gatherv-6' => 'int[]', - 'Iallgatherv-5' => 'int[]', - 'Iallgatherv-6' => 'int[]', - 'Ialltoallv-2' => 'int[]', - 'Ialltoallv-3' => 'int[]', - 'Ialltoallv-6' => 'int[]', - 'Ialltoallv-7' => 'int[]', - 'Ialltoallw-2' => 'int[]', - 'Ialltoallw-3' => 'int[]', - 'Ialltoallw-6' => 'int[]', - 'Ialltoallw-7' => 'int[]', - 'Igatherv-5' => 'int[]', - 'Igatherv-6' => 'int[]', - 'Ireduce_scatter-3' => 'int[]', - 'Iscatterv-2' => 'int[]', - 'Iscatterv-3' => 'int[]', - 'Reduce_scatter-3' => 'int[]', - 'Scatterv-2' => 'int[]', - 'Scatterv-3' => 'int[]', - 'Iprobe-4' => 'bool', - 'Improbe-4' => 'bool', - 'Op_create-2' => 'bool', - 'Attr_get-4' => 'bool', - 'Comm_get_attr-4' => 'bool', - 'Type_get_attr-4' => 'bool', - 'Win_get_attr-4' => 'bool', - 'Comm_test_inter-2' => 'bool', - 'Intercomm_merge-2' => 'bool', - 'Cart_create-5' => 'bool', - 'Initialized-1' => 'bool', - 'Finalized-1' => 'bool', - 'Group_range_excl-3' => 'int[][3]', - 'Group_range_incl-3' => 'int[][3]', - 'Info_get_valuelen-4' => 'bool', - 'Is_thread_main-1' => 'bool', - 'Type_create_subarray-2' => 'int[]', - 'Type_create_subarray-3' => 'int[]', - 'Type_create_subarray-4' => 'int[]', - 'Request_get_status-2' => 'bool', - 'Status_set_cancelled-2' => 'bool', - 'Info_get-5' => 'bool', - 'Info_get_string-5' => 'bool', - 'Type_create_indexed_block-3' => 'int[]', - 'Type_create_darray-4' => 'int[]', - 'Type_create_darray-5' => 'int[]', - 'Type_create_darray-6' => 'int[]', - 'Type_create_darray-7' => 'int[]', - 'Type_create_struct-2' => 'int[]', - 'Type_create_struct-3' => 'MPI_Aint[]', - 'Win_test-2' => 'bool', - 'Type_create_hindexed-2' => 'int[]', - 'Type_create_hindexed-3' => 'MPI_Aint[]', - 'Op_commutative-2' => 'bool', - 'File_set_atomicity-2' => 'bool', - 'File_get_atomicity-2' => 'bool', -); - -# Some routines must be skipped (custom code is provided for them) -%skip_routines = ( - 'Init' => 1, - 'Init_thread' => 1, - 'Status_c2f' => 1, - 'Status_f2c' => 1, - 'Status_f2f08' => 1, - 'Status_f082f' => 1, - 'Status_c2f08' => 1, - 'Status_f082c' => 1, - 'Pcontrol' => 1, - 'Info_create_env' => 1, -); - -# Some routines *may* be skipped if we don't want to handle the possibility -# of a scalar or vector argument -# Still to do: Add the others (datatype creation, translate ranks, etc.) -# For each of these, we need to know which arguments are the "scalar/vector" -# The value of the hash gives us the answer, indexed from 1 -# (these are not correct yet). -%scalarVectorRoutines = ( - 'Startall' => '2-1', - 'Testall' => '2-1:4-1', - 'Testany' => '2-1', - 'Testsome' => '2-1:4-1:5-1', - 'Waitall' => '2-1:3-1', - 'Waitany' => '2-1', - 'Waitsome' => '2-1:4-1:5-1', - 'Dims_create' => '3-2', - 'Cart_rank' => '2', - 'Cart_coords' => '4-3', - 'Cart_get' => '3-2:4-2:5-2', - 'Graph_neighbors' => '4-3', - 'Cart_sub' => '2', - 'Cart_map' => '3-2:4-2', - 'Cart_create' => '3-2:4-2', - 'Graph_create' => '3:4', - 'Dist_graph_create' => '6', - 'Dist_graph_create_adjacent' => '4:7', - 'Dist_graph_neighbors' => '4:7', - 'Group_translate_ranks' => '3-2:5-2', - -); - -# And we skip them by default -$buildScalarVector = 0; -$build_io = 1; - -# Process any options -foreach $_ (@ARGV) { - if (/--?prototype=(.*)/) { - $prototype_file = $1; - } elsif (/--?sv/) { - - # This obscure argument enables the creation of an interface that - # includes the routines that can accept a scalar or a vector - # (e.g., a single request or an array of requests) on a single - # type (e.g., an integer). By default, we leave these out. - $buildScalarVector = 1; - } elsif (/deffile=(.*)/) { - $definition_file = $1; - $is_MPI = 0; - } elsif (/--?noio/) { - $build_io = 0; - } elsif (/--?debug/) { - $gDebug = 1; - } else { - print STDERR "Unrecognized argument $_\n"; - exit 2; - } -} - -# -# Load any definition file -if ($definition_file) { - require $definition_file; -} -$ucoutfile_prefix = uc($outfile_prefix); - -# -# Read the interface file (e.g., mpi_proto.h) and file in the various -# data structures (they're in global variables) -&ReadInterface($prototype_file, $routine_prefix, $routine_pattern, - "mpi_routines"); -if (-s "../../mpi/romio/include/mpio.h.in" && $build_io) { - - # %skipBlocks = ( 'HAVE_MPI_DARRAY_SUBARRAY' => 1, - # 'HAVE_MPI_INFO' => 1, - # 'MPICH' => 1 ); - &ReadInterface("../../mpi/romio/include/mpio.h.in", - $routine_prefix, $routine_pattern, "mpi_routines"); - - # %skipBlocks = (); -} -if ($buildMPIX) { - &ReadInterface($prototype_file, "MPIX_", $routine_pattern, "mpi_routines"); -} - -# -# For some MPI routines, we need to distinguish between arguments that are -# input arrays versus ones that are output scalars. For those functions, -# convert input (or output) arrays to [] format. - -# ---------------------------------------------------------------------------- -# -# Generate the module for the routines -# First pass. Ignore the issue of choice routines -# Print header -open(MPIFD, ">${outfile_prefix}.f90.new") - || die "Could not open ${outfile_prefix}.f90.new\n"; - -# Was -# USE MPI_CONSTANTS, & -# & BASE_MPI_WTIME => MPI_WTIME, BASE_MPI_WTICK => MPI_WTICK -# but this caused problems with the pg compiler. Need to understand and fix -print MPIFD "! Copyright (C) by Argonne National Laboratory -! See COPYRIGHT in top-level directory - MODULE $ucoutfile_prefix -! This module was created by the script buildiface - USE ${ucoutfile_prefix}_CONSTANTS - USE ${ucoutfile_prefix}_SIZEOFS - USE ${ucoutfile_prefix}_BASE - END MODULE $ucoutfile_prefix\n"; - -close(MPIFD); -&ReplaceIfDifferent("${outfile_prefix}.f90", "${outfile_prefix}.f90.new"); - -# ---------------------------------------------------------------------------- -# This is the file for the routines that have no "choice" arguments. -# An example of a choice argument is a "void *buf" input argument to -# MPI_Send, which allows any buffer address, both numeric and character. -open(MPIBASEFD, ">${outfile_prefix}_base.f90.in.new") - || die "Could not open ${outfile_prefix}_base.f90.in.new\n"; -print MPIBASEFD "! Copyright (C) by Argonne National Laboratory -! See COPYRIGHT in top-level directory - MODULE ${ucoutfile_prefix}_BASE - IMPLICIT NONE -! This module was created by the script buildiface - INTERFACE\n"; - -foreach $routine (keys(%mpi_routines)) { - - # Permit each package to define a new name for the Fortran version of the - # routine - if (defined($CtoFName{$routine})) { - $routine = $CtoFName{$routine}; - } - $ucname = uc($routine); - my @argtypes = split(/,/, $mpi_routines{$routine}[0]); - my @argnames = split(/,/, $mpi_routines{$routine}[1]); - - print "Trying to bind $routine\n" if $gDebug; - - # Check for a routine to skip - if (defined($skip_routines{$routine})) { - print "Skipping $routine as required\n" if $gDebug; - next; - } - - if (defined($scalarVectorRoutines{$routine})) { - - # These require special processing in any case - next; - } - - # Check for a void * argument (usually choice) - # As noted above, we don't include the routines with choice arguments - # in the base module. - - if ($mpi_routines{$routine}[0] =~ /void/) { - $mpi_choice_routines{$routine} = $mpi_routines{$routine}[0]; - print "Skipping $routine because of void argument\n" if $gDebug; - next; - } - - print MPIBASEFD " SUBROUTINE $out_prefix$ucname"; - &PrintArgBrace(MPIBASEFD, - length(" SUBROUTINE $out_prefix$ucname"), - length(" SUBROUTINE "), - $line_limit, @argnames - ); - &PrintArgDecls($routine, 0, ""); - print MPIBASEFD " END SUBROUTINE $out_prefix$ucname\n\n"; -} - -# Add special routines (e.g., the ones with unusual arguments) - -# -# Some Fortran 90 compilers permit REAL*8; for some systems, this is -# preferable to DOUBLE PRECISION (in cases where the user is permitted -# to change the size of these basic types(!)). This script must produce -# a standard-conforming file. The top-level configure (in mpich/configure) -# will replace DOUBLE PRECISION with REAL*8 if the Fortran compiler -# supports REAL*8. -if ($is_MPI) { - print MPIBASEFD " - SUBROUTINE MPI_INIT(ierror) - INTEGER ierror - END SUBROUTINE MPI_INIT - - SUBROUTINE MPI_INIT_THREAD(v0,v1,ierror) - INTEGER v0, v1, ierror - END SUBROUTINE MPI_INIT_THREAD - - FUNCTION MPI_WTIME() - \@WTIME_DOUBLE_TYPE\@ MPI_WTIME - END FUNCTION MPI_WTIME -! - FUNCTION MPI_WTICK() - \@WTIME_DOUBLE_TYPE\@ MPI_WTICK - END FUNCTION MPI_WTICK - - FUNCTION MPI_AINT_ADD(base, disp) - USE MPI_CONSTANTS,ONLY: MPI_ADDRESS_KIND - INTEGER(KIND=MPI_ADDRESS_KIND) MPI_AINT_ADD - INTEGER(KIND=MPI_ADDRESS_KIND), INTENT(IN) :: base, disp - END FUNCTION MPI_AINT_ADD - - FUNCTION MPI_AINT_DIFF(addr1, addr2) - USE MPI_CONSTANTS,ONLY: MPI_ADDRESS_KIND - INTEGER(KIND=MPI_ADDRESS_KIND) MPI_AINT_DIFF - INTEGER(KIND=MPI_ADDRESS_KIND), INTENT(IN) :: addr1, addr2 - END FUNCTION MPI_AINT_DIFF - -! style:PMPIuse:PMPI_WTIME:3 sig:0 - FUNCTION PMPI_WTIME() - \@WTIME_DOUBLE_TYPE\@ PMPI_WTIME - END FUNCTION PMPI_WTIME -! -! style:PMPIuse:PMPI_WTICK:3 sig:0 - FUNCTION PMPI_WTICK() - \@WTIME_DOUBLE_TYPE\@ PMPI_WTICK - END FUNCTION PMPI_WTICK - - SUBROUTINE MPI_NULL_DELETE_FN(COMM, KEYVAL, ATTRIBUTE_VAL,& - EXTRA_STATE, IERROR) - USE MPI_CONSTANTS,ONLY: MPI_ADDRESS_KIND - INTEGER COMM, KEYVAL, IERROR - INTEGER(KIND=MPI_ADDRESS_KIND) ATTRIBUTE_VAL, EXTRA_STATE - END SUBROUTINE MPI_NULL_DELETE_FN - - SUBROUTINE MPI_DUP_FN(OLDCOMM, KEYVAL, EXTRA_STATE,& - ATTRIBUTE_VAL_IN, ATTRIBUTE_VAL_OUT, FLAG, IERROR) - USE MPI_CONSTANTS,ONLY: MPI_ADDRESS_KIND - INTEGER OLDCOMM, KEYVAL, IERROR - INTEGER(KIND=MPI_ADDRESS_KIND) EXTRA_STATE, ATTRIBUTE_VAL_IN, ATTRIBUTE_VAL_OUT - LOGICAL FLAG - END SUBROUTINE MPI_DUP_FN - - SUBROUTINE MPI_NULL_COPY_FN(OLDCOMM, KEYVAL, EXTRA_STATE,& - ATTRIBUTE_VAL_IN, ATTRIBUTE_VAL_OUT, FLAG, IERROR) - USE MPI_CONSTANTS,ONLY: MPI_ADDRESS_KIND - INTEGER OLDCOMM, KEYVAL, IERROR - INTEGER(KIND=MPI_ADDRESS_KIND) EXTRA_STATE, ATTRIBUTE_VAL_IN, ATTRIBUTE_VAL_OUT - LOGICAL FLAG - END SUBROUTINE MPI_NULL_COPY_FN - - SUBROUTINE MPI_COMM_NULL_DELETE_FN(COMM, COMM_KEYVAL, ATTRIBUTE_VAL,& - EXTRA_STATE, IERROR) - USE MPI_CONSTANTS,ONLY: MPI_ADDRESS_KIND - INTEGER COMM, COMM_KEYVAL, IERROR - INTEGER(KIND=MPI_ADDRESS_KIND) ATTRIBUTE_VAL, EXTRA_STATE - END SUBROUTINE MPI_COMM_NULL_DELETE_FN - - SUBROUTINE MPI_COMM_DUP_FN(OLDCOMM, COMM_KEYVAL, EXTRA_STATE,& - ATTRIBUTE_VAL_IN, ATTRIBUTE_VAL_OUT, FLAG, IERROR) - USE MPI_CONSTANTS,ONLY: MPI_ADDRESS_KIND - INTEGER OLDCOMM, COMM_KEYVAL, IERROR - INTEGER(KIND=MPI_ADDRESS_KIND) EXTRA_STATE, ATTRIBUTE_VAL_IN, ATTRIBUTE_VAL_OUT - LOGICAL FLAG - END SUBROUTINE MPI_COMM_DUP_FN - - SUBROUTINE MPI_COMM_NULL_COPY_FN(OLDCOMM, COMM_KEYVAL, EXTRA_STATE,& - ATTRIBUTE_VAL_IN, ATTRIBUTE_VAL_OUT, FLAG, IERROR) - USE MPI_CONSTANTS,ONLY: MPI_ADDRESS_KIND - INTEGER OLDCOMM, COMM_KEYVAL, IERROR - INTEGER(KIND=MPI_ADDRESS_KIND) EXTRA_STATE, ATTRIBUTE_VAL_IN, ATTRIBUTE_VAL_OUT - LOGICAL FLAG - END SUBROUTINE MPI_COMM_NULL_COPY_FN - - SUBROUTINE MPI_TYPE_NULL_DELETE_FN(DATATYPE, TYPE_KEYVAL, ATTRIBUTE_VAL,& - EXTRA_STATE, IERROR) - USE MPI_CONSTANTS,ONLY: MPI_ADDRESS_KIND - INTEGER DATATYPE, TYPE_KEYVAL, IERROR - INTEGER(KIND=MPI_ADDRESS_KIND) ATTRIBUTE_VAL, EXTRA_STATE - END SUBROUTINE MPI_TYPE_NULL_DELETE_FN - - SUBROUTINE MPI_TYPE_DUP_FN(OLDTYPE, TYPE_KEYVAL, EXTRA_STATE,& - ATTRIBUTE_VAL_IN, ATTRIBUTE_VAL_OUT, FLAG, IERROR) - USE MPI_CONSTANTS,ONLY: MPI_ADDRESS_KIND - INTEGER OLDTYPE, TYPE_KEYVAL, IERROR - INTEGER(KIND=MPI_ADDRESS_KIND) EXTRA_STATE, ATTRIBUTE_VAL_IN, ATTRIBUTE_VAL_OUT - LOGICAL FLAG - END SUBROUTINE MPI_TYPE_DUP_FN - - SUBROUTINE MPI_TYPE_NULL_COPY_FN(OLDTYPE, TYPE_KEYVAL, EXTRA_STATE,& - ATTRIBUTE_VAL_IN, ATTRIBUTE_VAL_OUT, FLAG, IERROR) - USE MPI_CONSTANTS,ONLY: MPI_ADDRESS_KIND - INTEGER OLDTYPE, TYPE_KEYVAL, IERROR - INTEGER(KIND=MPI_ADDRESS_KIND) EXTRA_STATE, ATTRIBUTE_VAL_IN, ATTRIBUTE_VAL_OUT - LOGICAL FLAG - END SUBROUTINE MPI_TYPE_NULL_COPY_FN - - SUBROUTINE MPI_WIN_NULL_DELETE_FN(WIN, WIN_KEYVAL, ATTRIBUTE_VAL,& - EXTRA_STATE, IERROR) - USE MPI_CONSTANTS,ONLY: MPI_ADDRESS_KIND - INTEGER WIN, WIN_KEYVAL, IERROR - INTEGER(KIND=MPI_ADDRESS_KIND) ATTRIBUTE_VAL, EXTRA_STATE - END SUBROUTINE MPI_WIN_NULL_DELETE_FN - - SUBROUTINE MPI_WIN_DUP_FN(OLDWIN, WIN_KEYVAL, EXTRA_STATE,& - ATTRIBUTE_VAL_IN, ATTRIBUTE_VAL_OUT, FLAG, IERROR) - USE MPI_CONSTANTS,ONLY: MPI_ADDRESS_KIND - INTEGER OLDWIN, WIN_KEYVAL, IERROR - INTEGER(KIND=MPI_ADDRESS_KIND) EXTRA_STATE, ATTRIBUTE_VAL_IN, ATTRIBUTE_VAL_OUT - LOGICAL FLAG - END SUBROUTINE MPI_WIN_DUP_FN - - SUBROUTINE MPI_WIN_NULL_COPY_FN(OLDWIN, WIN_KEYVAL, EXTRA_STATE,& - ATTRIBUTE_VAL_IN, ATTRIBUTE_VAL_OUT, FLAG, IERROR) - USE MPI_CONSTANTS,ONLY: MPI_ADDRESS_KIND - INTEGER OLDWIN, WIN_KEYVAL, IERROR - INTEGER(KIND=MPI_ADDRESS_KIND) EXTRA_STATE, ATTRIBUTE_VAL_IN, ATTRIBUTE_VAL_OUT - LOGICAL FLAG - END SUBROUTINE MPI_WIN_NULL_COPY_FN - - SUBROUTINE MPI_INFO_CREATE_ENV(info,ierror) - INTEGER info - INTEGER ierror - END SUBROUTINE MPI_INFO_CREATE_ENV -"; -} - -# Here's where we need to place the interface definitions for the functions -# that take vector or scalar arguments (startall, testall/any/some, -# waitall/any/some, group_translate_ranks, etc.) -# For each such routine, we need to generate two entries. Here's the -# example for STARTALL: -# subroutine MPI_STARTALL_S(c,r,ierr) -# integer c,r,ierr -# external MPI_STARTALL -# call MPI_STARTALL(c,r,ierr) -# end subroutine MPI_STARTALL_S -# subroutine MPI_STARTALL_V(c,r,ierr) -# integer c,r(*),ierr -# external MPI_STARTALL -# call MPI_STARTALL(c,r,ierr) -# end subroutine MPI_STARTALL_V - -print MPIBASEFD " END INTERFACE\n"; - -if ($buildScalarVector) { - - # Create the interface modules - foreach my $routine (keys(%scalarVectorRoutines)) { - $ucname = uc($routine); - print MPIBASEFD " INTERFACE ${out_prefix}$ucname\n"; - print MPIBASEFD - " MODULE PROCEDURE ${out_prefix}${ucname}_S\n"; - print MPIBASEFD - " MODULE PROCEDURE ${out_prefix}${ucname}_V\n"; - print MPIBASEFD " END INTERFACE ! ${out_prefix}$ucname\n\n"; - - } - print MPIBASEFD "\n CONTAINS\n"; - - # This is much like the base name (interface) block code - foreach my $routine (keys(%scalarVectorRoutines)) { - $ucname = uc($routine); - my @argtypes = split(/,/, $mpi_routines{$routine}[0]); - my @argnames = split(/,/, $mpi_routines{$routine}[1]); - $svArgs = $scalarVectorRoutines{$routine}; - - # The scalar version - print MPIBASEFD " SUBROUTINE ${out_prefix}${ucname}_S"; - &PrintArgBrace(MPIBASEFD, - length(" SUBROUTINE ${out_prefix}${ucname}_S"), - length(" SUBROUTINE "), - $line_limit, @argnames - ); - &PrintArgDecls($routine, 1, $svArgs); - - print MPIBASEFD " EXTERNAL ${out_prefix}${ucname}\n"; - print MPIBASEFD " call ${out_prefix}$ucname"; - &PrintArgBrace(MPIBASEFD, length(" call ${out_prefix}$ucname"), - length(" call "), $line_limit, @argnames); - print MPIBASEFD " END SUBROUTINE ${out_prefix}${ucname}_S\n\n"; - - # The vector version - print MPIBASEFD " SUBROUTINE ${out_prefix}${ucname}_V("; - &PrintArgBrace(MPIBASEFD, - length(" SUBROUTINE ${out_prefix}${ucname}_S"), - length(" SUBROUTINE "), - $line_limit, @argnames - ); - &PrintArgDecls($routine, 0, ""); - - print MPIBASEFD " EXTERNAL ${out_prefix}${ucname}\n"; - print MPIBASEFD " call ${out_prefix}$ucname"; - &PrintArgBrace(MPIBASEFD, length(" call ${out_prefix}$ucname"), - length(" call "), $line_limit, @argnames); - print MPIBASEFD " END SUBROUTINE ${out_prefix}${ucname}_V\n\n"; - } -} - -print MPIBASEFD " END MODULE ${ucoutfile_prefix}_BASE\n"; -close MPIBASEFD; -&ReplaceIfDifferent("${outfile_prefix}_base.f90.in", - "${outfile_prefix}_base.f90.in.new"); - -open(MPIFD, ">${outfile_prefix}_constants.f90.in.new") - || die "Cannot open ${outfile_prefix}_constants.f90.in.new\n"; -print MPIFD "! Copyright (C) by Argonne National Laboratory -! See COPYRIGHT in top-level directory - MODULE ${ucoutfile_prefix}_CONSTANTS - IMPLICIT NONE - INCLUDE 'mpifnoext.h'\n"; - -# MPI-3 Requires that even the MPI module (not just mpi_f08) include -# the MPI_Status type, as well as handle types -# WARNING: INTEGER is incorrect; it should be INTEGER(C_INT) if this -# is to be used directly by a C routine. That may also require using -# USE ISO_C_BINDING, ONLY :: C_INT -# Note that by using Fortran types with BIND(C), some compilers will -# general warnings about not being interoperable with C. -# See page 611, lines 3-13 in MPI-3. SEQUENCE is used for pre -# Fortran 2003 compilers. -# QUESTION: With BIND(C), all of these will generate warning statements -# because they don't use C integers, and they are not equivalent to the -# C types. Was that intended (even for Status?) -# Pick one of these two: -$BINDACCESS = ""; -$BINDDEF = "SEQUENCE"; - -# PUBLIC and PRIVATE were not present in the original F90; at least one -# compiler, the Absoft Fortran (from 2009) installed at ANL will not -# accept these qualifiers. Thus, we make these optional (but disabled -# by default). -# Use these to describe which fields are accessible to the user. -# Define these as empty to with early Fortran 90/95 compilers -#$PUBLICVAR = ", PUBLIC"; -#$PRIVATEVAR = ", PRIVATE"; -# Use the following for compilers that do not support pubilc and private -# qualifiers on declarations in derived types. -$PUBLICVAR = ""; -$PRIVATEVAR = ""; -# -#$BINDACCESS = ", BIND(C)"; -#$BINDDEF =""; -# Yet another problem. -# Because MPI_Count may be longer than a single (Fortran) INTEGER, -# alignment restrictions may introduce padding in the structure -# And one more problem: If a Fortran INTEGER is not the same as a C int, -# then these are also wrong (see the "fint" option in -# src/binding/fortran/mpif_h/buildiface -print MPIFD < 'Comm', - 'datatype' => 'Datatype', - 'group' => 'Group', - 'win' => 'Win', - 'file' => 'File', - 'op' => 'Op', - 'errhandler' => 'Errhandler', - 'request' => 'Request', - 'message' => 'Message', - 'info' => 'Info' -); - -foreach $handle (keys(%handles)) { - $mpitype = $handles{$handle}; - print MPIFD " TYPE$BINDACCESS :: MPI_$mpitype - $BINDDEF - INTEGER$PUBLICVAR :: MPI_VAL - END TYPE MPI_$mpitype\n"; -} - -print MPIFD " INTERFACE OPERATOR(.EQ.)\n"; -foreach $handle (keys(%handles)) { - print MPIFD " MODULE PROCEDURE ${handle}eq\n"; -} -print MPIFD " END INTERFACE\n"; - -# == and .EQ. appear to be synonyms, not separate names -#print MPIFD " INTERFACE OPERATOR(==)\n"; -#foreach $handle (keys(%handles)) { -# print MPIFD " MODULE PROCEDURE ${handle}eq\n"; -#} -#print MPIFD " END INTERFACE\n"; - -print MPIFD " INTERFACE OPERATOR(.NE.)\n"; -foreach $handle (keys(%handles)) { - print MPIFD " MODULE PROCEDURE ${handle}neq\n"; -} -print MPIFD " END INTERFACE\n"; - -# /= and .NE. appear to be synonyms, not separate names -# -#print MPIFD " INTERFACE OPERATOR(/=)\n"; -#foreach $handle (keys(%handles)) { -# print MPIFD " MODULE PROCEDURE ${handle}neq\n"; -#} -#print MPIFD " END INTERFACE\n"; - -print MPIFD " CONTAINS\n"; -foreach $handle (keys(%handles)) { - $mpitype = $handles{$handle}; - print MPIFD " LOGICAL FUNCTION ${handle}eq(lhs,rhs) - TYPE(MPI_$mpitype), INTENT(IN) :: lhs, rhs - ${handle}eq = lhs%MPI_VAL .EQ. rhs%MPI_VAL - END FUNCTION ${handle}eq - LOGICAL FUNCTION ${handle}neq(lhs,rhs) - TYPE(MPI_$mpitype), INTENT(IN) :: lhs, rhs - ${handle}neq = lhs%MPI_VAL .NE. rhs%MPI_VAL - END FUNCTION ${handle}neq\n"; -} - -print MPIFD " END MODULE ${ucoutfile_prefix}_CONSTANTS\n"; -close MPIFD; -&ReplaceIfDifferent( - "${outfile_prefix}_constants.f90.in", - "${outfile_prefix}_constants.f90.in.new" -); - -# -# Generate the choice argument routines -# FIXME: This file is not quite right. Also note that it is -# *input* for yet another step, one that generates particular values -# for the types of the choice arguments. We should consider using -# a different extension for this file, such as sed or in, so that -# it is clearly not a ready-to-use Fortran 90 input file. -# In particular, it needs to be set up so that -# -# -# -# -# -# can all be substituted as necessary. For example -# => 4 -# => real -# => (*) -# => real -# => (*) -# For scalar arguments, should be empty. -# Finally, the module name needs to be distinct for each choice of -# , , , and -open(MPIFD, ">${outfile_prefix}_t1.f90.new") - || die "Cannot open ${outfile_prefix}_t1.f90.new\n"; -print MPIFD "! Copyright (C) by Argonne National Laboratory -! See COPYRIGHT in top-level directory - MODULE ${ucoutfile_prefix}_t1_s - IMPLICIT NONE - PRIVATE\n"; - -# Generate the interface specs -foreach $routine (keys(%mpi_choice_routines)) { - $ucname = uc($routine); - - print MPIFD " PUBLIC :: ${out_prefix}$ucname\n"; - print MPIFD " INTERFACE ${out_prefix}$ucname\n"; - print MPIFD " MODULE PROCEDURE ${out_prefix}${ucname}_T\n"; - print MPIFD " END INTERFACE ${out_prefix}$ucname\n\n"; -} - -# MPI_Sizeof has its own module - -print MPIFD " CONTAINS\n\n"; - -# For each choice routine, add the modules -foreach $routine (keys(%mpi_choice_routines)) { - $ucname = uc($routine); - my @argtypes = split(/,/, $mpi_routines{$routine}[0]); - my @argnames = split(/,/, $mpi_routines{$routine}[1]); - - print MPIFD " SUBROUTINE ${out_prefix}${ucname}_T"; - &PrintArgBrace(MPIFD, - length(" SUBROUTINE ${out_prefix}${ucname}_T"), - length(" SUBROUTINE "), - $line_limit, @argnames - ); - - if (defined($NeedConstants{$routine})) { - print MPIFD " USE ${out_prefix}CONSTANTS,ONLY:"; - $sep = ""; - foreach $name (split(/\s+/, $NeedConstants{$routine})) { - print MPIFD "$sep$name"; - $sep = ", "; - } - print MPIFD "\n"; - } - - # print the arg decls ... - # convert %type% to the various types and %dims% to the dimensions, - # including scalar. - $nchoice = 0; - for ($i = 0 ; $i <= $#argtypes ; $i++) { - $argtypes[$i] =~ s/^const\s//; # Remove const if present - $argtype = $argtypes[$i]; - - # Check for special args - $loc = $i + 1; - if (defined($special_args{"$routine-$loc"})) { - $argtype = $special_args{"$routine-$loc"}; - } - - if ($argtype =~ /void/) { - - # An alternative to this is to have a separate file for - # routines with 2 choice arguments - if ($nchoice == 0) { - print MPIFD " $argnames[$i]\n"; - } else { - print MPIFD - " $argnames[$i]\n"; - } - $nchoice++; - } else { - - # Map the C type to the Fortran type - $cargtype = $argtype; - $cargtype =~ s/\s+//g; - $fargtype = $argtypec2f{$cargtype}; - if ($fargtype eq "") { - print STDERR - "$routine: No Fortran type for $cargtype ($argtype)\n"; - } - if ($fargtype =~ /%name%/) { - $fargtype =~ s/%name%/$argnames[$i]/; - - # In the name case, convert any %nl% to newlines and spaces - $fargtype =~ s/%nl%/\n /g; - print MPIFD " $fargtype\n"; - } else { - print MPIFD " $fargtype $argnames[$i]\n"; - } - } - } - - print MPIFD " EXTERNAL ${out_prefix}${ucname}\n"; - print MPIFD " CALL ${out_prefix}${ucname}"; - &PrintArgBrace(MPIFD, - length(" CALL ${out_prefix}${ucname}"), - length(" CALL "), - $line_limit, @argnames - ); - - print MPIFD " END SUBROUTINE ${out_prefix}${ucname}_T\n\n"; -} - -# The base sizeof's are handled separately now in their own file - -print MPIFD " END MODULE ${ucoutfile_prefix}_t1_s\n"; -close MPIFD; -&ReplaceIfDifferent("${outfile_prefix}_t1.f90", "${outfile_prefix}_t1.f90.new"); - -# -# Still to do -# make sure that we fit within the Fortran line length rules -# Look into alternatives for generating a zillion files -# Handle routines with more than one choice argument -# -# ------------------------------------------------------------------------ -# Procedures -# print_line( FD, line, count, continue, continuelen ) -# Print line to FD; if line size > count, output continue string and -# continue. Use print_endline to finish a line -sub print_line { - my $FD = $_[0]; - my $line = $_[1]; - my $count = $_[2]; - my $continue = $_[3]; - my $continue_len = $_[4]; - - $linelen = length($line); - - #print "linelen = $linelen, print_line_len = $print_line_len\n"; - if ($print_line_len + $linelen > $count) { - print $FD $continue; - $print_line_len = $continue_len; - } - print $FD $line; - $print_line_len += $linelen; -} - -sub print_endline { - my $FD = $_[0]; - print $FD "\n"; - $print_line_len = 0; -} - -# This routine adds to the Makefile.mk the instructions to create -# a module, handling the strange requirements of some Fortran 90 compilers. -# -# Pass any true value as the second argument to indicate that the source file -# lives in the srcdir rather than being generated in the builddir by -# config.status. -sub createModSteps { - my ($module, $deps, $srcFile, $use_srcdir) = @_; - - # Get a version of the source file with $(FCEXT) instead of .f90 - # as the extension - my $srcFileWithExt = $srcFile; - $srcFileWithExt =~ s/\.f90$/\.\$(FCEXT)/; - - # get the "libtool object" file name - my $loFile = $srcFile; - $loFile =~ s/\.f90$/\.lo/; - - # the no-extension name of the source file - my $noext = $srcFile; - $noext =~ s/\.f90$//; - - # filenames used by the make target - my $stamp = "src/binding/fortran/use_mpi/${noext}.\$(MOD)-stamp"; - my $lockfile = "src/binding/fortran/use_mpi/${noext}-lock"; - - # This code formerly supported the Intel Fortran Compiler's curious - # "-cl,blah.pcl" argument in a fragile and complicated way. Since this - # argument has been eliminated starting with Intel Fortran v7 (ca. 2002), - # I have dropped support for this behavior. A solution is theoretically - # possible, but a real PITA to get right for parallel-build safety and - # general cleanliness. [goodell@ 2011-06-06] - - # Attempt to deal with Fortran module files in a mostly sane way. Quick - # overview for the less Fortran literate: - # - # MPICH has four Fortran modules: mpi, mpi_constants, mpi_sizeofs, and - # mpi_base. Each module is produced as a side effect of compiling the - # corresponding .f90 file into a .lo. The .lo is produced by libtool and is - # actually just a text file pointing at the one or two object files that - # libtool actually creates (PIC/no-PIC). So we have to be careful when - # attempting to both support parallel make correctly and support a rebuild - # of only a missing .mod file. And we want to stay within the - # automake+libtool system to the greatest extent possible - # - # See "Handling Tools that Produce Many Outputs" from the automake-1.11.1 - # manual for an explanation of the make pattern used below. One odd thing - # is that our single invocation of FC_COMPILE_MODS will result in the - # libtool shell script actually compiling the source file twice and - # generating the .mod file twice. This appears to be harmless. - # - # A previous version of this code tried to use the "simple" recipe for - # parallel safety from the automake manual, but it is flawed: - # https://lists.gnu.org/archive/html/automake/2011-10/msg00004.html - - print MAKEFD </dev/null; then \\ -## This code is being executed by the first process. -\t rm -f ${stamp}; \\ -\t \$(MAKE) \$(AM_MAKEFLAGS) ${stamp}; \\ -\t rmdir ${lockfile}; \\ -\t else \\ -## This code is being executed by the follower processes. -## Wait until the first process is done. -\t while test -d ${lockfile}; do sleep 1; done; \\ -## Succeed if and only if the first process succeeded. -\t test -f ${stamp}; exit \$\$?; \\ -\t fi; \\ -\tfi - -CLEANFILES += ${stamp} ${module} src/binding/fortran/use_mpi/${loFile} src/binding/fortran/use_mpi/${noext}-tmp - - -EOT - -} - -# Print arguments in a pair of braces and end with a new line. -# $fd : File handle to print to. -# $curlen : Length of the current line. -# $indent : Indentation length of the following lines when they exist. -# $line_length : Maximal length of a line. -# @argnames : argument names to print out. -sub PrintArgBrace { - my ($fd, $curlen, $indent, $line_length, @argnames) = @_; - my $i = 0; - - print $fd "("; - $curlen++; - foreach my $arg (@argnames) { - if ($curlen + length($arg) + 2 > $line_length) - { # + 2 for the trailing ',&' - $curlen = $indent; - print $fd "&\n"; - print $fd " " x $indent; - print $fd "$arg"; - } else { - print $fd "$arg"; - } - - if ($i++ < $#argnames) { - print $fd ","; - } - - $curlen += length($arg) + 1; - } - - print $fd ")\n"; -} - -# Print the declarations for the given routine. -sub PrintArgDecls { - my ($routine, $svflag, $svArgs) = @_; - - my $ucname = uc($routine); - my @argtypes = split(/,/, $mpi_routines{$routine}[0]); - my @argnames = split(/,/, $mpi_routines{$routine}[1]); - - print "Printing argument delartion for $ucname\n" if $gDebug; - print "argtypes = $mpi_routines{$routine}[0]\n" if $gDebug; - print "argnames = $mpi_routines{$routine}[1]\n" if $gDebug; - - # preload the svargs if requested. This is used to decide whether - # an array arg is output as a scalar or a vector - my %svargs = (); - if ($svflag) { - for my $val (split(/:/, $svArgs)) { - my $loc = $val; - my $count = "-1"; - if ($loc =~ /(\d+)-(\d+)/) { - $loc = $1; - $count = $2; - } - $svargs{$loc} = $count; - } - } - - # Determine if we need any constants (e.g., MPI_STATUS_SIZE, - # MPI_OFFSET_KIND) - my %use_constants = (); - my $found_constants = 0; - for (my $i = 0 ; $i <= $#argtypes ; $i++) { - $argtypes[$i] =~ s/^const\s+//; # Remove const if present - my $argtype = $argtypes[$i]; - - # Check for special args - $loc = $i + 1; - if (defined($special_args{"$routine-$loc"})) { - $argtype = $special_args{"$routine-$loc"}; - } - - # Map the C type to the Fortran type - my $cargtype = $argtype; - $cargtype =~ s/\s+//g; - my $fargtype = $argtypec2f{$cargtype}; - - # Now, does this type contain an MPI constant? - if (!defined($fargtype)) { - print "$cargtype value has no matching fortran argtype\n"; - } - if ($fargtype =~ /(MPI_[A-Z_]*)/) { - $use_constants{$1} = 1; - $found_constants = 1; - } - } - if ($found_constants) { - print MPIBASEFD " USE MPI_CONSTANTS,ONLY:"; - $sep = ""; - foreach $name (keys(%use_constants)) { - print MPIBASEFD "$sep$name"; - $sep = ", "; - $NeedConstants{$routine} .= "$name "; - } - print MPIBASEFD "\n"; - } - - # Output argument types - for (my $i = 0 ; $i <= $#argtypes ; $i++) { - $argtype = $argtypes[$i]; - - # Check for special args - $loc = $i + 1; - if (defined($special_args{"$routine-$loc"})) { - $argtype = $special_args{"$routine-$loc"}; - } - - # Map the C type to the Fortran type - $cargtype = $argtype; - $cargtype =~ s/\s+//g; - $fargtype = $argtypec2f{$cargtype}; - if ($fargtype eq "") { - print STDERR "$routine: No Fortran type for $cargtype ($argtype)\n"; - } - - # Split out the base type from the name - if ($fargtype =~ /(\w+.*)\s+(%name\S.*)/) { - $varType = $1; - $varName = $2; - if ($varName =~ /%name%/) { - $varName =~ s/%name%/$argnames[$i]/; - } - $varName =~ s/%nl%/\n /g; - $varType =~ s/%nl%/\n /g; - - # Here's where we might change vector to scalar args - if ($svflag) { - if (defined($svargs{$loc})) { - - # The value is the count arg for the array; later, we - # can make use of that to improve the definitions - if ($varName =~ /,\*/) { - $varName =~ s/,\*//; - } elsif ($varName =~ /\(\*\)/) { - $varName =~ s/\(\*\)//; - } else { - print STDERR - "Failed to make arg $i in $routine a scalar\n"; - } - } - } - } else { - $varType = $fargtype; - $varName = $argnames[$i]; - } - - print MPIBASEFD " $varType $varName\n"; - } -} - -# -# Replace old file with new file only if new file is different -# Otherwise, remove new filename -sub ReplaceIfDifferent { - my ($oldfilename, $newfilename) = @_; - my $rc = 1; - if (-s $oldfilename) { - $rc = system "cmp -s $newfilename $oldfilename"; - $rc >>= 8; # Shift right to get exit status - } - if ($rc != 0) { - - # The files differ. Replace the old file - # with the new one - if (-s $oldfilename) { - print STDERR "Replacing $oldfilename\n"; - - # If debugging and there is a difference, show that difference - if ($gDebug) { system "diff $newfilename $oldfilename"; } - - unlink $oldfilename; - } else { - print STDERR "Creating $oldfilename\n"; - } - rename $newfilename, $oldfilename - || die "Could not replace $oldfilename"; - } else { - unlink $newfilename; - } -} From 94ccecd7bca339c7d1fa3ed11d5402b768f07438 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 18 Nov 2021 08:45:40 -0600 Subject: [PATCH 406/607] autogen: add running maint/gen_binding_f90.py We'll move into configure later to accept config options. We also remove the replacement of return types for MPI_Wtime/MPI_Wtick for now. They'll be taken care of once we move the codegen into configure. --- autogen.sh | 7 ++----- configure.ac | 1 - 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/autogen.sh b/autogen.sh index a6cdc78238a..239e2ca48c5 100755 --- a/autogen.sh +++ b/autogen.sh @@ -492,10 +492,7 @@ fn_f77() { fn_f90() { echo_n "Building Fortran 90 interface... " - # Remove any copy of mpi_base.f90 (this is used to handle the - # Double precision vs. Real*8 option - rm -f src/binding/fortran/use_mpi/mpi_base.f90.orig - ( cd src/binding/fortran/use_mpi && chmod a+x ./buildiface && ./buildiface ) + $PYTHON maint/gen_binding_f90.py echo "done" } @@ -503,7 +500,7 @@ fn_f08() { echo_n "Building Fortran 08 interface... " # Top-level files ( cd src/binding/fortran/use_mpi_f08 && chmod a+x ./buildiface && ./buildiface ) - # generate src/binding/fortran/use_mpi_f08/wrappers_c/... + # in configure: $PYTHON maint/gen_binding_f08.py [options] echo "done" } diff --git a/configure.ac b/configure.ac index 44cb77d6b09..f6e880b987b 100644 --- a/configure.ac +++ b/configure.ac @@ -4262,7 +4262,6 @@ AC_CONFIG_FILES([Makefile \ src/binding/fortran/mpif_h/setbotf.f \ src/binding/fortran/mpif_h/setbot.c \ src/binding/fortran/use_mpi/mpi_sizeofs.f90 \ - src/binding/fortran/use_mpi/mpi_base.f90 \ src/binding/fortran/use_mpi/mpi_constants.f90 \ src/binding/fortran/use_mpi_f08/mpi_f08_compile_constants.f90 \ src/binding/fortran/use_mpi_f08/mpi_c_interface_types.f90 \ From f4cc5d00ceda7fd417953d1992977f102ec5d21c Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 26 Nov 2021 22:26:35 -0600 Subject: [PATCH 407/607] configure: remove mpi_{sizeofs,constants}.f90.in We no longer generate .in files for configure to replace for these two files. We probably will later move the step of $PYTHON maint/gen_binding_f90.py inside configure to be able to reflect configure options. --- configure.ac | 2 -- 1 file changed, 2 deletions(-) diff --git a/configure.ac b/configure.ac index f6e880b987b..21d05387293 100644 --- a/configure.ac +++ b/configure.ac @@ -4261,8 +4261,6 @@ AC_CONFIG_FILES([Makefile \ src/binding/fortran/mpif_h/mpif.h \ src/binding/fortran/mpif_h/setbotf.f \ src/binding/fortran/mpif_h/setbot.c \ - src/binding/fortran/use_mpi/mpi_sizeofs.f90 \ - src/binding/fortran/use_mpi/mpi_constants.f90 \ src/binding/fortran/use_mpi_f08/mpi_f08_compile_constants.f90 \ src/binding/fortran/use_mpi_f08/mpi_c_interface_types.f90 \ src/packaging/pkgconfig/mpich.pc \ From 9ee4f392c749416e1795af0885ad58efa2d40b44 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 26 Nov 2021 23:36:17 -0600 Subject: [PATCH 408/607] f90: add mpi.f90 This file is simple enough that doesn't need be generated from script. --- .gitignore | 1 - src/binding/fortran/use_mpi/mpi.f90 | 8 ++++++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 src/binding/fortran/use_mpi/mpi.f90 diff --git a/.gitignore b/.gitignore index 4a58930697d..4734d27e7e0 100644 --- a/.gitignore +++ b/.gitignore @@ -417,7 +417,6 @@ Makefile.am-stamp /src/binding/fortran/use_mpi/mpi_base.f90.new /src/binding/fortran/use_mpi/mpif.h /src/binding/fortran/use_mpi/Makefile.sm -/src/binding/fortran/use_mpi/mpi.f90 /src/binding/fortran/use_mpi/mpi_t1.f90 /src/binding/fortran/use_mpi/mpimod.pcl /src/binding/fortran/use_mpi/mpi_sizeofs.f90 diff --git a/src/binding/fortran/use_mpi/mpi.f90 b/src/binding/fortran/use_mpi/mpi.f90 new file mode 100644 index 00000000000..29338d20001 --- /dev/null +++ b/src/binding/fortran/use_mpi/mpi.f90 @@ -0,0 +1,8 @@ +! Copyright (C) by Argonne National Laboratory +! See COPYRIGHT in top-level directory + +MODULE MPI + USE MPI_CONSTANTS + USE MPI_SIZEOFS + USE MPI_BASE +END MODULE MPI From d0485191eb877224b09e89aee363cec1b7c81ad3 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 27 Nov 2021 15:12:27 -0600 Subject: [PATCH 409/607] configure: check FC directives to ignore TKR check This is needed for Fortran interfaces for routines with choice buffers. --- confdb/aclocal_fc.m4 | 57 ++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 3 ++- 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/confdb/aclocal_fc.m4 b/confdb/aclocal_fc.m4 index 70d44052864..bc11e2c52ae 100644 --- a/confdb/aclocal_fc.m4 +++ b/confdb/aclocal_fc.m4 @@ -1210,3 +1210,60 @@ AC_DEFUN([PAC_FC_CHECK_REAL128],[ AC_MSG_RESULT([$pac_fc_has_real128]) AC_LANG_POP(Fortran) ]) + +dnl +dnl PAC_FC_CHECK_IGNORE_TKR check directives to ignore type-kind-rank checks +dnl set pac_fc_ignore_tkr to a type if supported, otherwise, no. +dnl +AC_DEFUN([PAC_FC_CHECK_IGNORE_TKR],[ + AC_LANG_PUSH(Fortran) + AC_MSG_CHECKING([directives for Fortran compiler to ignore TKR check]) + pac_fc_ignore_tkr=no + for a in gcc dec pragma dir ibm assumed; do + case $a in + gcc) + # gfortran since 4.9 + decl='!GCC$ ATTRIBUTES NO_ARG_CHECK :: buf' + ;; + dec) + # ifort + decl='!DEC$ ATTRIBUTES NO_ARG_CHECK :: buf' + ;; + pragma) + # sunfort + decl='!$PRAGMA IGNORE_TKR buf' + ;; + dir) + # flang + decl='!DIR$ IGNORE_TKR buf' + ;; + ibm) + # ibm + decl='!IBM* IGNORE_TKR buf' + ;; + assumed) + decl='TYPE(*), DIMENSION(..) :: buf' + ;; + esac + + AC_COMPILE_IFELSE([AC_LANG_SOURCE([ + program main + IMPLICIT NONE + INTERFACE + SUBROUTINE FUNC_A(buf) + REAL buf + $decl + END SUBROUTINE + END INTERFACE + + INTEGER A(10) + CALL FUNC_A(A) + end + ])],[pac_fc_ignore_tkr=$a],[]) + if test $pac_fc_ignore_tkr != no ; then + break + fi + done + AC_MSG_RESULT([$pac_fc_ignore_tkr]) + AC_LANG_POP(Fortran) +]) diff --git a/configure.ac b/configure.ac index 21d05387293..cc885c91a23 100644 --- a/configure.ac +++ b/configure.ac @@ -2240,7 +2240,8 @@ if test "$enable_fc" = "yes" ; then # Check whether additional libraries are needed when linking with C PAC_PROG_FC_AND_C_STDIO_LIBS AC_SUBST(FC_OTHER_LIBS) - # ------------------------------------------------ + + PAC_FC_CHECK_IGNORE_TKR fi if test "X$modincdir" = "X" ; then From da6771414521a3bb9a0dae523f33bf5d4fed2028 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 27 Nov 2021 15:36:57 -0600 Subject: [PATCH 410/607] configure: allow work-around when Python 3 is unavailable We believe it is uncommon to have a system without Python 3. But in case it is unavailable, one still can manually run e.g. `python3 maint/gen_binding_f08.py` separately to proceed, with the caveat that they need know the options if the default doesn't work. Also rename the variable "cmd" into "cmd_f08" to prevent collision with other parts of configure. --- confdb/aclocal_misc.m4 | 5 +++-- configure.ac | 28 +++++++++++++++++++--------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/confdb/aclocal_misc.m4 b/confdb/aclocal_misc.m4 index a4a6595b15b..401dcf4c32e 100644 --- a/confdb/aclocal_misc.m4 +++ b/confdb/aclocal_misc.m4 @@ -8,8 +8,9 @@ AC_DEFUN([PAC_CHECK_PYTHON],[ PYTHON=python elif test 3 = `python3 -c "$python_one_liner"`; then PYTHON=python3 - else - AC_MSG_ERROR([Python 3 is required but not found]) fi AC_MSG_RESULT($PYTHON) + if test -z "$PYTHON" ; then + AC_MSG_WARN([Python 3 not found! Bindings need to be generated before configure.]) + fi ]) diff --git a/configure.ac b/configure.ac index cc885c91a23..bd6e218e8d7 100644 --- a/configure.ac +++ b/configure.ac @@ -710,6 +710,9 @@ case "$enable_fortran" in ;; esac +# Python 3 is needed to generate Fortran bindings +PAC_CHECK_PYTHON + if test "$enable_fortran" != "no" ; then # suppress default "-g -O2" from AC_PROG_FC : ${FCFLAGS=""} @@ -4236,17 +4239,24 @@ AC_SUBST(pkgconfigdir) export pkgconfigdir if test "$f08_works" = "yes" ; then - PAC_CHECK_PYTHON PAC_FC_CHECK_REAL128 - cmd="$PYTHON $srcdir/maint/gen_binding_f08.py" - if test "$pac_fc_has_real128" = "no" ; then - cmd="$cmd -no-real128" - fi - if test "$enable_romio" = "no" ; then - cmd="$cmd -no-mpiio" + if test -z "$PYTHON" ; then + if test -f src/binding/fortran/use_mpi_f08/mpi_f08.f90 ; then + AC_MSG_NOTICE([Using pre-generated Fortran mpi_f08 binding source. To prevent issues, install Python 3 and rerun configure.]) + else + AC_MSG_ERROR([Python 3 is required to generate F08 bindings but not found!]) + fi + else + cmd_f08="$PYTHON $srcdir/maint/gen_binding_f08.py" + if test "$pac_fc_has_real128" = "no" ; then + cmd_f08="$cmd_f08 -no-real128" + fi + if test "$enable_romio" = "no" ; then + cmd_f08="$cmd_f08 -no-mpiio" + fi + cmd_f08="$cmd_f08 -fint-size=$pac_cv_f77_sizeof_integer -aint-size=$MPI_SIZEOF_AINT -count-size=$MPI_SIZEOF_COUNT -cint-size=$ac_cv_sizeof_int" + AC_CONFIG_COMMANDS([gen_binding_f08], [$cmd_gen_binding_f08], [cmd_gen_binding_f08="$cmd_f08"]) fi - cmd="$cmd -fint-size=$pac_cv_f77_sizeof_integer -aint-size=$MPI_SIZEOF_AINT -count-size=$MPI_SIZEOF_COUNT -cint-size=$ac_cv_sizeof_int" - AC_CONFIG_COMMANDS([gen_binding_f08], [$cmd_gen_binding_f08], [cmd_gen_binding_f08="$cmd"]) fi dnl This includes an experimental pkgconfig file for ch3 in the src/pkgconfig From 66f8df011b6a652493e7f837b10fdda7ae48e313 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 27 Nov 2021 15:52:37 -0600 Subject: [PATCH 411/607] configure: generate f90 bindings in configure This allows checking compiler features, for example, the directives to ignore TKR check. --- autogen.sh | 2 +- configure.ac | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/autogen.sh b/autogen.sh index 239e2ca48c5..e3fe410b9de 100755 --- a/autogen.sh +++ b/autogen.sh @@ -48,7 +48,7 @@ do_fortran=yes # if no, skips patching libtool for Fortran do_errmsgs=yes do_getcvars=yes do_f77=yes -do_f90=yes +do_f90=no # we generate f90 binding in configure do_f08=yes do_cxx=yes do_build_configure=yes diff --git a/configure.ac b/configure.ac index bd6e218e8d7..f4609c8e5bd 100644 --- a/configure.ac +++ b/configure.ac @@ -2245,6 +2245,20 @@ if test "$enable_fc" = "yes" ; then AC_SUBST(FC_OTHER_LIBS) PAC_FC_CHECK_IGNORE_TKR + + if test -z "$PYTHON" ; then + if test -f src/binding/fortran/use_mpi/mpi_base.f90 ; then + AC_MSG_NOTICE([Use pre-generated Fortran mpi binding. To prevent issues, install Python 3 and re-run configure.]) + else + AC_MSG_ERROR([Python 3 is required to generate F90 bindings but not found!]) + fi + else + cmd_f90="$PYTHON $srcdir/maint/gen_binding_f90.py" + if test "$pac_fc_ignore_tkr" != "no" ; then + cmd_f90="$cmd_f90 -ignore-tkr=$pac_fc_ignore_tkr" + fi + AC_CONFIG_COMMANDS([gen_binding_f90], [$cmd_gen_binding_f90], [cmd_gen_binding_f90="$cmd_f90"]) + fi fi if test "X$modincdir" = "X" ; then From df7bfae9cb7b8dde20ee65458e041037b8666ebd Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 28 Nov 2021 00:05:04 -0600 Subject: [PATCH 412/607] test: fix fortran tests of MPI_Alltoallv MPI_Alltoallv accepts scalar datatypes but these tests were passing in arrays. This is caught with gfortran-7, currently default on Jenkins Solaris node. On centos-7, gfortran 4.8 misses it. --- test/mpi/f77/coll/alltoallvf.f | 20 ++++++++++---------- test/mpi/f77/coll/split_typef.f | 12 ++++++------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/test/mpi/f77/coll/alltoallvf.f b/test/mpi/f77/coll/alltoallvf.f index 97c95ed12d3..3f5c000de5c 100644 --- a/test/mpi/f77/coll/alltoallvf.f +++ b/test/mpi/f77/coll/alltoallvf.f @@ -10,8 +10,8 @@ program main integer i, ans, size, rank, color, comm, newcomm integer maxSize, displ parameter (maxSize=128) - integer scounts(maxSize), sdispls(maxSize), stypes(maxSize) - integer rcounts(maxSize), rdispls(maxSize), rtypes(maxSize) + integer scounts(maxSize), sdispls(maxSize), stype + integer rcounts(maxSize), rdispls(maxSize), rtype integer sbuf(maxSize), rbuf(maxSize) errs = 0 @@ -39,15 +39,15 @@ program main do i=1, size scounts(i) = 1 sdispls(i) = (i-1) - stypes(i) = MPI_INTEGER sbuf(i) = rank * size + i rcounts(i) = 1 rdispls(i) = (i-1) - rtypes(i) = MPI_INTEGER rbuf(i) = -1 enddo - call mpi_alltoallv( sbuf, scounts, sdispls, stypes, - & rbuf, rcounts, rdispls, rtypes, comm, ierr ) + stype = MPI_INTEGER + rtype = MPI_INTEGER + call mpi_alltoallv( sbuf, scounts, sdispls, stype, + & rbuf, rcounts, rdispls, rtype, comm, ierr ) C C check rbuf(i) = data from the ith location of the ith send buf, or C rbuf(i) = (i-1) * size + i @@ -65,13 +65,13 @@ program main do i=1, size scounts(i) = 0 sdispls(i) = 0 - stypes(i) = MPI_INTEGER sbuf(i) = -1 rcounts(i) = 0 rdispls(i) = 0 - rtypes(i) = MPI_INTEGER rbuf(i) = -1 enddo + stype = MPI_INTEGER + rtype = MPI_INTEGER C C Note that the arrays are 1-origin @@ -99,8 +99,8 @@ program main displ = displ + 1 endif - call mpi_alltoallv( sbuf, scounts, sdispls, stypes, - & rbuf, rcounts, rdispls, rtypes, comm, ierr ) + call mpi_alltoallv( sbuf, scounts, sdispls, stype, + & rbuf, rcounts, rdispls, rtype, comm, ierr ) C C Check the neighbor values are correctly moved C diff --git a/test/mpi/f77/coll/split_typef.f b/test/mpi/f77/coll/split_typef.f index 1b4340a1458..cf985426c01 100644 --- a/test/mpi/f77/coll/split_typef.f +++ b/test/mpi/f77/coll/split_typef.f @@ -10,8 +10,8 @@ program main integer i, ans, size, rank, color, comm, newcomm integer maxSize, displ parameter (maxSize=128) - integer scounts(maxSize), sdispls(maxSize), stypes(maxSize) - integer rcounts(maxSize), rdispls(maxSize), rtypes(maxSize) + integer scounts(maxSize), sdispls(maxSize), stype + integer rcounts(maxSize), rdispls(maxSize), rtype integer sbuf(maxSize), rbuf(maxSize) errs = 0 @@ -29,15 +29,15 @@ program main do i=1, size scounts(i) = 1 sdispls(i) = (i-1) - stypes(i) = MPI_INTEGER sbuf(i) = rank * size + i rcounts(i) = 1 rdispls(i) = (i-1) - rtypes(i) = MPI_INTEGER rbuf(i) = -1 enddo - call mpi_alltoallv( sbuf, scounts, sdispls, stypes, - & rbuf, rcounts, rdispls, rtypes, newcomm, ierr ) + stype = MPI_INTEGER + rtype = MPI_INTEGER + call mpi_alltoallv( sbuf, scounts, sdispls, stype, + & rbuf, rcounts, rdispls, rtype, newcomm, ierr ) call mpi_comm_free( newcomm, ierr ) call mpi_comm_free( comm, ierr ) From c176806daabbf8a5dadd8b48c5c978928f280480 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 28 Nov 2021 00:20:07 -0600 Subject: [PATCH 413/607] test: fix fortran tests with MPI_IN_PLACE Even though we ignores send counts and displacements when MPI_IN_PLACE is used, fortran still checks the argument types. While we could add directives to disable the check for some compilers, it is not too much trouble for users to use dummy arrays, and I think it is useful not to disable this compiler checks. --- test/mpi/f77/coll/nonblocking_inpf.f | 8 ++++++-- test/mpi/f77/coll/vw_inplacef.f | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/test/mpi/f77/coll/nonblocking_inpf.f b/test/mpi/f77/coll/nonblocking_inpf.f index 8b76d6eba2f..406963a4dd6 100644 --- a/test/mpi/f77/coll/nonblocking_inpf.f +++ b/test/mpi/f77/coll/nonblocking_inpf.f @@ -12,6 +12,7 @@ program main integer MAX_SIZE parameter (MAX_SIZE=1024) integer rbuf(MAX_SIZE) + integer sdispls(1), scounts(1), stypes(1) integer rdispls(MAX_SIZE), rcounts(MAX_SIZE), rtypes(MAX_SIZE) integer comm, rank, size, req integer sumval, ierr, errs @@ -53,7 +54,10 @@ program main rbuf(rdispls(i)+j+1) = 100 * rank + 10 * (i-1) + j enddo enddo - call mpi_ialltoallv( MPI_IN_PLACE, 0, 0, MPI_DATATYPE_NULL, + sdispls(1) = 0 + scounts(1) = 0 + stypes(1) = MPI_DATATYPE_NULL + call mpi_ialltoallv( MPI_IN_PLACE, scounts, sdispls, stypes(1), . rbuf, rcounts, rdispls, MPI_INTEGER, . comm, req, ierr ) call mpi_wait( req, MPI_STATUS_IGNORE, ierr ) @@ -82,7 +86,7 @@ program main . + 10 * (i-1) + j enddo enddo - call mpi_ialltoallw( MPI_IN_PLACE, 0, 0, MPI_DATATYPE_NULL, + call mpi_ialltoallw( MPI_IN_PLACE, scounts, sdispls, stypes, . rbuf, rcounts, rdispls, rtypes, . comm, req, ierr ) call mpi_wait( req, MPI_STATUS_IGNORE, ierr ) diff --git a/test/mpi/f77/coll/vw_inplacef.f b/test/mpi/f77/coll/vw_inplacef.f index 8b96c7b08e5..be478ddfaae 100644 --- a/test/mpi/f77/coll/vw_inplacef.f +++ b/test/mpi/f77/coll/vw_inplacef.f @@ -12,6 +12,7 @@ program main integer MAX_SIZE parameter (MAX_SIZE=1024) integer rbuf(MAX_SIZE) + integer scounts(1), sdispls(1), stypes(1) integer rdispls(MAX_SIZE), rcounts(MAX_SIZE), rtypes(MAX_SIZE) integer ierr, errs integer comm, root @@ -48,6 +49,9 @@ program main endif enddo + scounts(1) = 0 + sdispls(1) = 0 + stypes(1) = MPI_DATATYPE_NULL do i=1,MAX_SIZE rbuf(i) = -1 enddo @@ -58,7 +62,7 @@ program main rbuf(rdispls(i)+j+1) = 100 * rank + 10 * (i-1) + j enddo enddo - call mpi_alltoallv( MPI_IN_PLACE, 0, 0, MPI_DATATYPE_NULL, + call mpi_alltoallv( MPI_IN_PLACE, scounts, sdispls, stypes(1), $ rbuf, rcounts, rdispls, MPI_INTEGER, $ comm, ierr ) do i=1,size @@ -87,7 +91,7 @@ program main $ + 10 * (i-1) + j enddo enddo - call mpi_alltoallw( MPI_IN_PLACE, 0, 0, MPI_DATATYPE_NULL, + call mpi_alltoallw( MPI_IN_PLACE, scounts, sdispls, stypes, $ rbuf, rcounts, rdispls, rtypes, $ comm, ierr ) do i=1,size From f1c54441dd2dc87846cf370e407fa8130b6691f3 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 2 Feb 2022 10:02:52 -0600 Subject: [PATCH 414/607] test: minor cleanup maint/f77tof90 script Fix an eyesore in regex, a bad indentation, and a typo. --- test/mpi/maint/f77tof90 | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/test/mpi/maint/f77tof90 b/test/mpi/maint/f77tof90 index 582eb2e787e..48a3c71f879 100755 --- a/test/mpi/maint/f77tof90 +++ b/test/mpi/maint/f77tof90 @@ -140,7 +140,9 @@ sub ConvertToF90 { # but in F77, it must come before the include mpif.h statement. # Rather than try and fix this, rely on the F77 versions to # catch undeclared variables - if (/[Ii][Mm][Pp][Ll][Ii][Cc][Ii][Tt]\s+[Nn][Oo][Nn][Ee]/) { next; } + if (/IMPLICIT\s+NONE/i) { + next; + } if (/^(\s*)include\s+[\'\"]mpif\.h/) { $_ = "$1use mpi"; } @@ -149,10 +151,10 @@ sub ConvertToF90 { if (/^CF90/) { s/^CF90/ /; } - # Remove lines used only for F77, such as external MPI function declarations - if (/!\s*F77ONLY\s*$/i) { - $_ = ""; - } + # Remove lines used only for F77, such as external MPI function declarations + if (/!\s*F77ONLY\s*$/i) { + $_ = ""; + } # Since we use interface statements for the error handlers, # remove their external declaration if (/^\s+external myerrhanfunc/) { From 302725bf9a5a1a78ffb23b5080d9ed8de07149d6 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 2 Feb 2022 10:18:19 -0600 Subject: [PATCH 415/607] test: use strict in Perl script maint/f77tof90 It prevents mistakes such as typos. --- test/mpi/maint/f77tof90 | 53 ++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/test/mpi/maint/f77tof90 b/test/mpi/maint/f77tof90 index 48a3c71f879..b6d0135f477 100755 --- a/test/mpi/maint/f77tof90 +++ b/test/mpi/maint/f77tof90 @@ -13,31 +13,31 @@ # We also allow the file name to be modified to help out Windows, since # programs in a project need to have distinct names # +use strict; use warnings; -$indir = $ARGV[0]; -$outdir = $ARGV[1]; -$makeTemplate = $ARGV[2]; -$makeAppend = $ARGV[3]; -$convertToFreeForm = 1; -$convertToNewComments = 1; +my ($indir, $outdir, $makeTemplate, $makeAppend) = @ARGV; +my $convertToFreeForm = 1; +my $convertToNewComments = 1; # Including a newline variable allows us to handle Unix and DOS source files -$newline = "\n"; - -%replaceInclude = ( 'iodisp' => 'integer (kind=MPI_OFFSET_KIND) disp', - 'ioaint' => 'integer (kind=MPI_ADDRESS_KIND) aint', - 'iooffset' => 'integer (kind=MPI_OFFSET_KIND) offset', - 'type1aint' => 'integer (kind=MPI_ADDRESS_KIND) aint', - 'typeaints' => 'integer (kind=MPI_ADDRESS_KIND) aint, aintv(max_asizev)', - 'attr1aints' => 'integer (kind=MPI_ADDRESS_KIND) extrastate, valin, valout, val', - 'attraints' => 'integer (kind=MPI_ADDRESS_KIND) extrastate, valin, valout, val', - 'addsize' => 'integer (kind=MPI_ADDRESS_KIND) asize', - 'add1size' => 'integer (kind=MPI_ADDRESS_KIND) asize', - ); - -%excludePrograms = (); -$debugReplace = 0; -$reportSkipped = 1; +my $newline = "\n"; + +my %replaceInclude = ( + 'iodisp' => 'integer (kind=MPI_OFFSET_KIND) disp', + 'ioaint' => 'integer (kind=MPI_ADDRESS_KIND) aint', + 'iooffset' => 'integer (kind=MPI_OFFSET_KIND) offset', + 'type1aint' => 'integer (kind=MPI_ADDRESS_KIND) aint', + 'typeaints' => 'integer (kind=MPI_ADDRESS_KIND) aint, aintv(max_asizev)', + 'attr1aints' => 'integer (kind=MPI_ADDRESS_KIND) extrastate, valin, valout, val', + 'attraints' => 'integer (kind=MPI_ADDRESS_KIND) extrastate, valin, valout, val', + 'addsize' => 'integer (kind=MPI_ADDRESS_KIND) asize', + 'add1size' => 'integer (kind=MPI_ADDRESS_KIND) asize', +); + +my %excludePrograms = (); +my $debugReplace = 0; +my $reportSkipped = 1; + # -------------------------------------------------------------------------- # Check the input arguments if ($indir eq "" || $outdir eq "") { @@ -58,11 +58,10 @@ if (! -d $outdir) { # -------------------------------------------------------------------------- opendir( DIR, "$indir" ); my @filelist = (); -while ($file = readdir(DIR)) { +while (my $file = readdir(DIR)) { # Extract the extension if ($file =~ /^(.*)\.([^\.]*)$/) { - $name = $1; - $ext = $2; + my ($name, $ext) = ($1, $2); # Special handling for C files, if any if ($ext eq "c") { my $name90 = $name; @@ -130,7 +129,7 @@ sub ConvertToF90 { open (OUTF, ">$outfile" ) || die "Could not open $outfile\n"; print OUTF "! This file created from $infile with f77tof90\n"; - my $lastLine = ""; + my $lastline = ""; my $firstline = 1; while () { if (/\r/) { $newline = "\r\n"; } @@ -188,7 +187,7 @@ sub ConvertToF90 { # convert to free-form input by holding one line back. if ($convertToFreeForm) { if (/^ \S(.*)/) { - $leftover = $1; + my $leftover = $1; # This line contains a continuation marker # Add a continuation marker to the previous line if # it doesn't already have one From 54d5e46e4b2d85c1915aef621aa91c2fd0a6277d Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 2 Feb 2022 10:09:55 -0600 Subject: [PATCH 416/607] test: fix f90 profile test To overwrite the existing routine from Fortran mpi module, we need rename the module routine in the "use mpi" line. --- test/mpi/maint/f77tof90 | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/mpi/maint/f77tof90 b/test/mpi/maint/f77tof90 index b6d0135f477..55faab27d04 100755 --- a/test/mpi/maint/f77tof90 +++ b/test/mpi/maint/f77tof90 @@ -131,10 +131,14 @@ sub ConvertToF90 { print OUTF "! This file created from $infile with f77tof90\n"; my $lastline = ""; my $firstline = 1; + my $scope = ""; # program or subroutine while () { if (/\r/) { $newline = "\r\n"; } # Remove any end-of-line characters s/[\r\n]*//g; + if (/^\s*(program|subroutine)\s*(\w+)/i) { + $scope = lc($1) . " " . lc($2); + } # The implicit none must not come before the use mpi statement, # but in F77, it must come before the include mpif.h statement. # Rather than try and fix this, rely on the F77 versions to @@ -143,7 +147,12 @@ sub ConvertToF90 { next; } if (/^(\s*)include\s+[\'\"]mpif\.h/) { - $_ = "$1use mpi"; + my $sp = $1; + if ($scope =~ /subroutine (mpi_\w+)/) { + $_ = $sp . "use mpi, skip_$1 => $1"; + } else { + $_ = $sp . "use mpi"; + } } # Allow the insertion of Fortran 90 only statements, such as # interface definitions From ea9dbe532012259b7656b577c15d553d7d6ac51e Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 3 Feb 2022 18:12:52 -0600 Subject: [PATCH 417/607] test/configure: check mpi module interface Check whether "use mpi" contains interface for choice-buffer routines, such as mpi_send, and patch f90/profile tests if necessary. --- test/mpi/configure.ac | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index 6f865bf4bfe..da46276037a 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -1259,6 +1259,25 @@ if test "$enable_fc" = yes ; then AC_LANG_POP([Fortran]) fi +if test "$f90dir" = "f90" ; then + AC_MSG_CHECKING([that mpi module contains choice buffer routines]) + AC_LANG_PUSH([Fortran]) + AC_COMPILE_IFELSE([ + AC_LANG_SOURCE([ + program main + use mpi, skip_mpi_send => mpi_send + end + ]) + ],[ + AC_MSG_RESULT(yes) + ],[ + AC_MSG_RESULT(no) + # patch f90/profile tests + find "$srcdir/f90/profile" -name "*.f90" -exec sed -i "s/use mpi, skip_.*/use mpi/" {} \; + ]) + AC_LANG_POP([Fortran]) +fi + f08dir="#" AC_SUBST(f08dir) if test "$enable_f08" = "yes" ; then From cb8b3586d5baf5446f3f0745f9283bd93d732811 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 5 Feb 2022 10:16:31 -0600 Subject: [PATCH 418/607] qmpi: do not add MPICH_API_PUBLIC in definition MPICH_API_PUBLIC is accidentally leaked into definitions, which isn't allowed. --- maint/local_python/binding_c.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/maint/local_python/binding_c.py b/maint/local_python/binding_c.py index 21f27105686..23ffa175804 100644 --- a/maint/local_python/binding_c.py +++ b/maint/local_python/binding_c.py @@ -159,7 +159,7 @@ def dump_mpix_symbols(): print("", file=Out) print("#endif /* MPIR_IMPL_H_INCLUDED */", file=Out) -def get_qmpi_decl_from_func_decl(func_decl): +def get_qmpi_decl_from_func_decl(func_decl, kind=""): if RE.match(r'(.*) (MPIX?_\w+)\((.*?)\)(.*)', func_decl): T, name, args, tail = RE.m.group(1,2,3,4) else: @@ -170,11 +170,12 @@ def get_qmpi_decl_from_func_decl(func_decl): else: t = "%s Q%s(QMPI_Context context, int tool_id, %s)" % (T, name, args) - while RE.search(r'MPICH_ATTR_POINTER_WITH_TYPE_TAG\((\d+),(\d+)\)(.*)', tail): - i1, i2, tail = RE.m.group(1, 2, 3) - t += " MPICH_ATTR_POINTER_WITH_TYPE_TAG(%d,%d)" % (int(i1) + 2, int(i2) + 2) + if kind == 'proto': + while RE.search(r'MPICH_ATTR_POINTER_WITH_TYPE_TAG\((\d+),(\d+)\)(.*)', tail): + i1, i2, tail = RE.m.group(1, 2, 3) + t += " MPICH_ATTR_POINTER_WITH_TYPE_TAG(%d,%d)" % (int(i1) + 2, int(i2) + 2) - t += " MPICH_API_PUBLIC" + t += " MPICH_API_PUBLIC" return t @@ -292,7 +293,7 @@ def dump_proto_line(l, Out): m = re.match(r'[a-zA-Z0-9_]* ([a-zA-Z0-9_]*)\(.*', func_decl); if need_skip_qmpi(m.group(1)): continue - func_decl = get_qmpi_decl_from_func_decl(func_decl) + func_decl = get_qmpi_decl_from_func_decl(func_decl, 'proto') dump_proto_line(func_decl, Out) print("", file=Out) From 5dfc8354fa3e45264ed631a68eacf0093c429e37 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 5 Feb 2022 08:40:30 -0600 Subject: [PATCH 419/607] doc: fix manpage generation The qmpi wrapper broke the in-source manpage flow. The same comment block now need move inside the qmpi wrapper for doctext to parse correctly. --- maint/local_python/binding_c.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/maint/local_python/binding_c.py b/maint/local_python/binding_c.py index 23ffa175804..54dd9cd7ea9 100644 --- a/maint/local_python/binding_c.py +++ b/maint/local_python/binding_c.py @@ -62,8 +62,7 @@ def dump_mpi_c(func, is_large=False): dump_function_internal(func, kind="normal") G.out.append("") - dump_manpage(func) - G.out.append("") + # NOTE: dump_manpage is now called inside dump_qmpi_wrappers # Create the MPI and QMPI wrapper functions that will call the above, "real" version of the # function in the MPII prefix @@ -769,6 +768,10 @@ def dump_qmpi_wrappers(func, is_large): dump_line_with_break(" return (*fn_ptr) (context, MPIR_QMPI_first_tool_ids[%s_T]%s);" % (func_name.upper(), parameters)); G.out.append("}") G.out.append("#else /* ENABLE_QMPI */") + + dump_manpage(func) + G.out.append("") + dump_line_with_break(func_decl) G.out.append("{") if func_name == "MPI_Pcontrol": From 2e4b922e79a85e20e76bdbd45f5ef8e9b2b2f99d Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 19 Jan 2022 19:12:19 -0600 Subject: [PATCH 420/607] coll: fix additional neighbor_alltoall algorithms The fix is for peioridic cartetian graph when dimension is 1 or 2. In both case we have two edges points to the same process and vice versa. If we send in the order of left and right, we need receive in the order of right and left since left and right are reversed between in and out. Previously we only fixed ineighbor_alltoall. This patch extends the same fix to ineighbor_alltoallv and ineighbor_alltoallw. I also updated the comment because the previous comments is still confusing to me. In particular, it fails to high light the key points -- First it only matters for the periodic cartesian dimension of 1 or 2. Second that results in multiple message with the same datatype and tag. Lastly, the matching need reverse because left and right is reversed between in and out. Personally, I think allowing graphs to have duplicated edges pointing to the same rank shouldn't be allowed. Because a general graph may not guarantee ordering the edges and thus there is no way of ensuring the correct matching order. In the general light, this fix is merely a hack. --- .../ineighbor_alltoall_allcomm_sched_linear.c | 18 +++++++++++++----- .../ineighbor_alltoall_tsp_linear.c | 8 +++----- .../ineighbor_alltoallv_allcomm_sched_linear.c | 5 ++++- .../ineighbor_alltoallv_tsp_linear.c | 5 ++++- .../ineighbor_alltoallw_allcomm_sched_linear.c | 5 ++++- .../ineighbor_alltoallw_tsp_linear.c | 5 ++++- 6 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/mpi/coll/ineighbor_alltoall/ineighbor_alltoall_allcomm_sched_linear.c b/src/mpi/coll/ineighbor_alltoall/ineighbor_alltoall_allcomm_sched_linear.c index 69f5912913e..c593a5fe200 100644 --- a/src/mpi/coll/ineighbor_alltoall/ineighbor_alltoall_allcomm_sched_linear.c +++ b/src/mpi/coll/ineighbor_alltoall/ineighbor_alltoall_allcomm_sched_linear.c @@ -42,11 +42,19 @@ int MPIR_Ineighbor_alltoall_allcomm_sched_linear(const void *sendbuf, MPI_Aint s MPIR_ERR_CHECK(mpi_errno); } - /* receive needs to happen in the opposite order of sends. This - * is to cover the case of Cartesian graphs where the same process - * might be both the left and right neighbor. In this case, we - * need to make sure the first message (which is from the right - * neighbor) is received in the last buffer. */ + /* Cartesian graph may result in multiple edges going to the same process when it is + * periodic and dim is 1 or 2, in which case, both left and right neighbor (in a circular sense) points to + * self or the other process. When that occurs, we are sending two messages to the + * same receiver and receiving two messages from the same sender. Both messages are using + * the same tag, thus we need reverse the order of recvs to ensure correct matching. + * In the example of 1-dim cartesian graph, if we send in the order of left and right, + * the target need receive in the order of right and left to receive the correct messages. + * + * Note: duplicate graph edges can only result from MPI_Cart_create when certain + * dimension is periodic and size is 1 or 2. And the resulting graph edges will be + * in fixed orders, which the code here takes advantage of. A general graph will not + * contain duplicated edges, and the order of send and recv should not matter. + */ for (l = indegree - 1; l >= 0; l--) { char *rb = ((char *) recvbuf) + l * recvcount * recvtype_extent; mpi_errno = MPIR_Sched_recv(rb, recvcount, recvtype, srcs[l], comm_ptr, s); diff --git a/src/mpi/coll/ineighbor_alltoall/ineighbor_alltoall_tsp_linear.c b/src/mpi/coll/ineighbor_alltoall/ineighbor_alltoall_tsp_linear.c index 93832a3d26f..51d7fa0f55d 100644 --- a/src/mpi/coll/ineighbor_alltoall/ineighbor_alltoall_tsp_linear.c +++ b/src/mpi/coll/ineighbor_alltoall/ineighbor_alltoall_tsp_linear.c @@ -52,11 +52,9 @@ int MPIR_TSP_Ineighbor_alltoall_sched_allcomm_linear(const void *sendbuf, MPI_Ai MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); } - /* receive needs to happen in the opposite order of sends. This - * is to cover the case of Cartesian graphs where the same process - * might be both the left and right neighbor. In this case, we - * need to make sure the first message (which is from the right - * neighbor) is received in the last buffer. */ + /* need reverse the order to ensure matching when the graph is from MPI_Cart_create and + * the n-th dimension is periodic and the size is 1 or 2. + * ref. ineighbor_alltoall_allcomm_sched_linear.c */ for (l = indegree - 1; l >= 0; l--) { char *rb = ((char *) recvbuf) + l * recvcount * recvtype_extent; mpi_errno = diff --git a/src/mpi/coll/ineighbor_alltoallv/ineighbor_alltoallv_allcomm_sched_linear.c b/src/mpi/coll/ineighbor_alltoallv/ineighbor_alltoallv_allcomm_sched_linear.c index 5145cd300d9..95713065499 100644 --- a/src/mpi/coll/ineighbor_alltoallv/ineighbor_alltoallv_allcomm_sched_linear.c +++ b/src/mpi/coll/ineighbor_alltoallv/ineighbor_alltoallv_allcomm_sched_linear.c @@ -43,7 +43,10 @@ int MPIR_Ineighbor_alltoallv_allcomm_sched_linear(const void *sendbuf, const MPI MPIR_ERR_CHECK(mpi_errno); } - for (l = 0; l < indegree; ++l) { + /* need reverse the order to ensure matching when the graph is from MPI_Cart_create and + * the n-th dimension is periodic and the size is 1 or 2. + * ref. ineighbor_alltoall_allcomm_sched_linear.c */ + for (l = indegree - 1; l >= 0; l--) { char *rb = ((char *) recvbuf) + rdispls[l] * recvtype_extent; mpi_errno = MPIR_Sched_recv(rb, recvcounts[l], recvtype, srcs[l], comm_ptr, s); MPIR_ERR_CHECK(mpi_errno); diff --git a/src/mpi/coll/ineighbor_alltoallv/ineighbor_alltoallv_tsp_linear.c b/src/mpi/coll/ineighbor_alltoallv/ineighbor_alltoallv_tsp_linear.c index 7ecbc1a5024..07303c1e0e7 100644 --- a/src/mpi/coll/ineighbor_alltoallv/ineighbor_alltoallv_tsp_linear.c +++ b/src/mpi/coll/ineighbor_alltoallv/ineighbor_alltoallv_tsp_linear.c @@ -55,7 +55,10 @@ int MPIR_TSP_Ineighbor_alltoallv_sched_allcomm_linear(const void *sendbuf, MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); } - for (l = 0; l < indegree; ++l) { + /* need reverse the order to ensure matching when the graph is from MPI_Cart_create and + * the n-th dimension is periodic and the size is 1 or 2. + * ref. ineighbor_alltoall_allcomm_sched_linear.c */ + for (l = indegree - 1; l >= 0; l--) { char *rb = ((char *) recvbuf) + rdispls[l] * recvtype_extent; mpi_errno = MPIR_TSP_sched_irecv(rb, recvcounts[l], recvtype, srcs[l], tag, comm_ptr, sched, 0, diff --git a/src/mpi/coll/ineighbor_alltoallw/ineighbor_alltoallw_allcomm_sched_linear.c b/src/mpi/coll/ineighbor_alltoallw/ineighbor_alltoallw_allcomm_sched_linear.c index 1e19c0e6edb..dd9f143bcf2 100644 --- a/src/mpi/coll/ineighbor_alltoallw/ineighbor_alltoallw_allcomm_sched_linear.c +++ b/src/mpi/coll/ineighbor_alltoallw/ineighbor_alltoallw_allcomm_sched_linear.c @@ -43,7 +43,10 @@ int MPIR_Ineighbor_alltoallw_allcomm_sched_linear(const void *sendbuf, const MPI MPIR_ERR_CHECK(mpi_errno); } - for (l = 0; l < indegree; ++l) { + /* need reverse the order to ensure matching when the graph is from MPI_Cart_create and + * the n-th dimension is periodic and the size is 1 or 2. + * ref. ineighbor_alltoall_allcomm_sched_linear.c */ + for (l = indegree - 1; l >= 0; l--) { char *rb; rb = ((char *) recvbuf) + rdispls[l]; diff --git a/src/mpi/coll/ineighbor_alltoallw/ineighbor_alltoallw_tsp_linear.c b/src/mpi/coll/ineighbor_alltoallw/ineighbor_alltoallw_tsp_linear.c index 3fa80cc2e5e..a03b962c332 100644 --- a/src/mpi/coll/ineighbor_alltoallw/ineighbor_alltoallw_tsp_linear.c +++ b/src/mpi/coll/ineighbor_alltoallw/ineighbor_alltoallw_tsp_linear.c @@ -53,7 +53,10 @@ int MPIR_TSP_Ineighbor_alltoallw_sched_allcomm_linear(const void *sendbuf, MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); } - for (l = 0; l < indegree; ++l) { + /* need reverse the order to ensure matching when the graph is from MPI_Cart_create and + * the n-th dimension is periodic and the size is 1 or 2. + * ref. ineighbor_alltoall_allcomm_sched_linear.c */ + for (l = indegree - 1; l >= 0; l--) { char *rb; rb = ((char *) recvbuf) + rdispls[l]; From 373b666b90d0c3b6a60ff631d7af83c3d1ef8f98 Mon Sep 17 00:00:00 2001 From: Gengbin Zheng Date: Thu, 27 Jan 2022 11:47:29 -0600 Subject: [PATCH 421/607] ch4/coll: Add CVAR to select composition for Barrier --- src/mpid/ch4/src/ch4_coll.h | 67 +++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/src/mpid/ch4/src/ch4_coll.h b/src/mpid/ch4/src/ch4_coll.h index 3c96bc84672..6f1f5d25d71 100644 --- a/src/mpid/ch4/src/ch4_coll.h +++ b/src/mpid/ch4/src/ch4_coll.h @@ -10,7 +10,28 @@ #include "ch4_proc.h" #include "ch4_coll_impl.h" -MPL_STATIC_INLINE_PREFIX int MPID_Barrier(MPIR_Comm * comm, MPIR_Errflag_t * errflag) +/* +=== BEGIN_MPI_T_CVAR_INFO_BLOCK === + +cvars: + - name : MPIR_CVAR_BARRIER_COMPOSITION + category : COLLECTIVE + type : int + default : 0 + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + Select composition (inter_node + intra_node) for Barrier + 0 Auto selection + 1 NM + SHM + 2 NM only + +=== END_MPI_T_CVAR_INFO_BLOCK === +*/ + +MPL_STATIC_INLINE_PREFIX int MPIDI_Barrier_allcomm_composition_json(MPIR_Comm * comm, + MPIR_Errflag_t * errflag) { int mpi_errno = MPI_SUCCESS; const MPIDI_Csel_container_s *cnt = NULL; @@ -20,8 +41,6 @@ MPL_STATIC_INLINE_PREFIX int MPID_Barrier(MPIR_Comm * comm, MPIR_Errflag_t * err .comm_ptr = comm, }; - MPIR_FUNC_ENTER; - cnt = MPIR_Csel_search(MPIDI_COMM(comm, csel_comm), coll_sig); if (cnt == NULL) { @@ -43,6 +62,48 @@ MPL_STATIC_INLINE_PREFIX int MPID_Barrier(MPIR_Comm * comm, MPIR_Errflag_t * err MPIR_ERR_CHECK(mpi_errno); + fn_exit: + return mpi_errno; + fn_fail: + goto fn_exit; +} + +MPL_STATIC_INLINE_PREFIX int MPID_Barrier(MPIR_Comm * comm, MPIR_Errflag_t * errflag) +{ + int mpi_errno = MPI_SUCCESS; + + MPIR_FUNC_ENTER; + + + switch (MPIR_CVAR_BARRIER_COMPOSITION) { + case 1: + MPII_COLLECTIVE_FALLBACK_CHECK(comm->rank, + (comm->comm_kind == MPIR_COMM_KIND__INTRACOMM) && + (comm->hierarchy_kind == + MPIR_COMM_HIERARCHY_KIND__PARENT), mpi_errno, + "Barrier composition alpha cannot be applied.\n"); + mpi_errno = MPIDI_Barrier_intra_composition_alpha(comm, errflag); + break; + case 2: + MPII_COLLECTIVE_FALLBACK_CHECK(comm->rank, + comm->comm_kind == MPIR_COMM_KIND__INTRACOMM, mpi_errno, + "Barrier composition beta cannot be applied.\n"); + mpi_errno = MPIDI_Barrier_intra_composition_beta(comm, errflag); + break; + default: + mpi_errno = MPIDI_Barrier_allcomm_composition_json(comm, errflag); + break; + } + + MPIR_ERR_CHECK(mpi_errno); + goto fn_exit; + + fallback: + if (comm->comm_kind == MPIR_COMM_KIND__INTERCOMM) + mpi_errno = MPIR_Barrier_impl(comm, errflag); + else + mpi_errno = MPIDI_Barrier_intra_composition_beta(comm, errflag); + fn_exit: MPIR_FUNC_EXIT; return mpi_errno; From 562dbfc7d89f1a5b84d9a4fdc0fcbc469b7beea9 Mon Sep 17 00:00:00 2001 From: Gengbin Zheng Date: Thu, 27 Jan 2022 13:42:54 -0600 Subject: [PATCH 422/607] ch4/coll: Add CVAR to select composition for Bcast --- src/mpid/ch4/src/ch4_coll.h | 77 +++++++++++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 4 deletions(-) diff --git a/src/mpid/ch4/src/ch4_coll.h b/src/mpid/ch4/src/ch4_coll.h index 6f1f5d25d71..409ae05e90c 100644 --- a/src/mpid/ch4/src/ch4_coll.h +++ b/src/mpid/ch4/src/ch4_coll.h @@ -27,6 +27,20 @@ 1 NM + SHM 2 NM only + - name : MPIR_CVAR_BCAST_COMPOSITION + category : COLLECTIVE + type : int + default : 0 + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + Select composition (inter_node + intra_node) for Bcast + 0 Auto selection + 1 NM + SHM with explicit send-recv between rank 0 and root + 2 NM + SHM without the explicit send-recv + 3 NM only + === END_MPI_T_CVAR_INFO_BLOCK === */ @@ -111,8 +125,10 @@ MPL_STATIC_INLINE_PREFIX int MPID_Barrier(MPIR_Comm * comm, MPIR_Errflag_t * err goto fn_exit; } -MPL_STATIC_INLINE_PREFIX int MPID_Bcast(void *buffer, MPI_Aint count, MPI_Datatype datatype, - int root, MPIR_Comm * comm, MPIR_Errflag_t * errflag) +MPL_STATIC_INLINE_PREFIX int MPIDI_Bcast_allcomm_composition_json(void *buffer, MPI_Aint count, + MPI_Datatype datatype, int root, + MPIR_Comm * comm, + MPIR_Errflag_t * errflag) { int mpi_errno = MPI_SUCCESS; MPIR_Csel_coll_sig_s coll_sig = { @@ -126,8 +142,6 @@ MPL_STATIC_INLINE_PREFIX int MPID_Bcast(void *buffer, MPI_Aint count, MPI_Dataty const MPIDI_Csel_container_s *cnt = NULL; - MPIR_FUNC_ENTER; - cnt = MPIR_Csel_search(MPIDI_COMM(comm, csel_comm), coll_sig); if (cnt == NULL) { @@ -155,6 +169,61 @@ MPL_STATIC_INLINE_PREFIX int MPID_Bcast(void *buffer, MPI_Aint count, MPI_Dataty MPIR_ERR_CHECK(mpi_errno); + fn_exit: + return mpi_errno; + fn_fail: + goto fn_exit; +} + +MPL_STATIC_INLINE_PREFIX int MPID_Bcast(void *buffer, MPI_Aint count, MPI_Datatype datatype, + int root, MPIR_Comm * comm, MPIR_Errflag_t * errflag) +{ + int mpi_errno = MPI_SUCCESS; + + MPIR_FUNC_ENTER; + + switch (MPIR_CVAR_BCAST_COMPOSITION) { + case 1: + MPII_COLLECTIVE_FALLBACK_CHECK(comm->rank, + (comm->comm_kind == MPIR_COMM_KIND__INTRACOMM) && + (comm->hierarchy_kind == + MPIR_COMM_HIERARCHY_KIND__PARENT), mpi_errno, + "Bcast composition alpha cannot be applied.\n"); + mpi_errno = + MPIDI_Bcast_intra_composition_alpha(buffer, count, datatype, root, comm, errflag); + break; + case 2: + MPII_COLLECTIVE_FALLBACK_CHECK(comm->rank, + (comm->comm_kind == MPIR_COMM_KIND__INTRACOMM) && + (comm->hierarchy_kind == + MPIR_COMM_HIERARCHY_KIND__PARENT), mpi_errno, + "Bcast composition beta cannot be applied.\n"); + mpi_errno = + MPIDI_Bcast_intra_composition_beta(buffer, count, datatype, root, comm, errflag); + break; + case 3: + MPII_COLLECTIVE_FALLBACK_CHECK(comm->rank, + comm->comm_kind == MPIR_COMM_KIND__INTRACOMM, mpi_errno, + "Bcast composition gamma cannot be applied.\n"); + mpi_errno = + MPIDI_Bcast_intra_composition_gamma(buffer, count, datatype, root, comm, errflag); + break; + default: + mpi_errno = + MPIDI_Bcast_allcomm_composition_json(buffer, count, datatype, root, comm, errflag); + break; + } + + MPIR_ERR_CHECK(mpi_errno); + goto fn_exit; + + fallback: + if (comm->comm_kind == MPIR_COMM_KIND__INTERCOMM) + mpi_errno = MPIR_Bcast_impl(buffer, count, datatype, root, comm, errflag); + else + mpi_errno = + MPIDI_Bcast_intra_composition_gamma(buffer, count, datatype, root, comm, errflag); + fn_exit: MPIR_FUNC_EXIT; return mpi_errno; From c63ba23ca2b41d07fd4fbb9029fc88177cf688f2 Mon Sep 17 00:00:00 2001 From: Gengbin Zheng Date: Thu, 27 Jan 2022 14:57:40 -0600 Subject: [PATCH 423/607] ch4/coll: Add CVAR to select composition for Allreduce --- src/mpid/ch4/src/ch4_coll.h | 91 +++++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 5 deletions(-) diff --git a/src/mpid/ch4/src/ch4_coll.h b/src/mpid/ch4/src/ch4_coll.h index 409ae05e90c..53d99c82f6f 100644 --- a/src/mpid/ch4/src/ch4_coll.h +++ b/src/mpid/ch4/src/ch4_coll.h @@ -41,6 +41,20 @@ 2 NM + SHM without the explicit send-recv 3 NM only + - name : MPIR_CVAR_ALLREDUCE_COMPOSITION + category : COLLECTIVE + type : int + default : 0 + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + Select composition (inter_node + intra_node) for Allreduce + 0 Auto selection + 1 NM + SHM with reduce + bcast + 2 NM only composition + 3 SHM only composition + === END_MPI_T_CVAR_INFO_BLOCK === */ @@ -231,9 +245,11 @@ MPL_STATIC_INLINE_PREFIX int MPID_Bcast(void *buffer, MPI_Aint count, MPI_Dataty goto fn_exit; } -MPL_STATIC_INLINE_PREFIX int MPID_Allreduce(const void *sendbuf, void *recvbuf, MPI_Aint count, - MPI_Datatype datatype, MPI_Op op, MPIR_Comm * comm, - MPIR_Errflag_t * errflag) +MPL_STATIC_INLINE_PREFIX int MPIDI_Allreduce_allcomm_composition_json(const void *sendbuf, + void *recvbuf, MPI_Aint count, + MPI_Datatype datatype, + MPI_Op op, MPIR_Comm * comm, + MPIR_Errflag_t * errflag) { int mpi_errno = MPI_SUCCESS; const MPIDI_Csel_container_s *cnt = NULL; @@ -249,8 +265,6 @@ MPL_STATIC_INLINE_PREFIX int MPID_Allreduce(const void *sendbuf, void *recvbuf, .u.allreduce.op = op, }; - MPIR_FUNC_ENTER; - cnt = MPIR_Csel_search(MPIDI_COMM(comm, csel_comm), coll_sig); if (cnt == NULL) { @@ -281,6 +295,72 @@ MPL_STATIC_INLINE_PREFIX int MPID_Allreduce(const void *sendbuf, void *recvbuf, MPIR_ERR_CHECK(mpi_errno); + fn_exit: + return mpi_errno; + fn_fail: + goto fn_exit; +} + +MPL_STATIC_INLINE_PREFIX int MPID_Allreduce(const void *sendbuf, void *recvbuf, MPI_Aint count, + MPI_Datatype datatype, MPI_Op op, MPIR_Comm * comm, + MPIR_Errflag_t * errflag) +{ + int mpi_errno = MPI_SUCCESS; + int is_commutative = -1; + + MPIR_FUNC_ENTER; + + is_commutative = MPIR_Op_is_commutative(op); + + switch (MPIR_CVAR_ALLREDUCE_COMPOSITION) { + case 1: + MPII_COLLECTIVE_FALLBACK_CHECK(comm->rank, + (comm->comm_kind == MPIR_COMM_KIND__INTRACOMM) && + (comm->hierarchy_kind == + MPIR_COMM_HIERARCHY_KIND__PARENT) && + is_commutative, mpi_errno, + "Allreduce composition alpha cannot be applied.\n"); + mpi_errno = + MPIDI_Allreduce_intra_composition_alpha(sendbuf, recvbuf, count, datatype, op, comm, + errflag); + break; + case 2: + MPII_COLLECTIVE_FALLBACK_CHECK(comm->rank, + comm->comm_kind == MPIR_COMM_KIND__INTRACOMM, mpi_errno, + "Allreduce composition beta cannot be applied.\n"); + mpi_errno = + MPIDI_Allreduce_intra_composition_beta(sendbuf, recvbuf, count, datatype, op, comm, + errflag); + break; + case 3: + MPII_COLLECTIVE_FALLBACK_CHECK(comm->rank, + (comm->comm_kind == MPIR_COMM_KIND__INTRACOMM) && + (comm->node_comm != NULL) && + (MPIR_Comm_size(comm) == + MPIR_Comm_size(comm->node_comm)), mpi_errno, + "Allreduce composition gamma cannot be applied.\n"); + mpi_errno = + MPIDI_Allreduce_intra_composition_gamma(sendbuf, recvbuf, count, datatype, op, comm, + errflag); + break; + default: + mpi_errno = + MPIDI_Allreduce_allcomm_composition_json(sendbuf, recvbuf, count, datatype, op, + comm, errflag); + break; + } + + MPIR_ERR_CHECK(mpi_errno); + goto fn_exit; + + fallback: + if (comm->comm_kind == MPIR_COMM_KIND__INTERCOMM) + mpi_errno = MPIR_Allreduce_impl(sendbuf, recvbuf, count, datatype, op, comm, errflag); + else + mpi_errno = + MPIDI_Allreduce_intra_composition_beta(sendbuf, recvbuf, count, datatype, op, comm, + errflag); + fn_exit: MPIR_FUNC_EXIT; return mpi_errno; @@ -288,6 +368,7 @@ MPL_STATIC_INLINE_PREFIX int MPID_Allreduce(const void *sendbuf, void *recvbuf, goto fn_exit; } + MPL_STATIC_INLINE_PREFIX int MPID_Allgather(const void *sendbuf, MPI_Aint sendcount, MPI_Datatype sendtype, void *recvbuf, MPI_Aint recvcount, MPI_Datatype recvtype, From f3eef9283648feb1977938395fc89da69b38bdf8 Mon Sep 17 00:00:00 2001 From: Gengbin Zheng Date: Wed, 2 Feb 2022 12:53:20 -0600 Subject: [PATCH 424/607] ch4/coll: Add CVAR to select composition for Allgather --- src/mpid/ch4/src/ch4_coll.h | 80 +++++++++++++++++++++++---- src/mpid/ch4/src/ch4_coll_impl.h | 16 +++--- src/mpid/ch4/src/ch4_csel_container.h | 1 + src/mpid/ch4/src/ch4_init.c | 3 + 4 files changed, 81 insertions(+), 19 deletions(-) diff --git a/src/mpid/ch4/src/ch4_coll.h b/src/mpid/ch4/src/ch4_coll.h index 53d99c82f6f..2d708b2e933 100644 --- a/src/mpid/ch4/src/ch4_coll.h +++ b/src/mpid/ch4/src/ch4_coll.h @@ -55,6 +55,19 @@ 2 NM only composition 3 SHM only composition + - name : MPIR_CVAR_ALLGATHER_COMPOSITION + category : COLLECTIVE + type : int + default : 0 + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + Select composition (inter_node + intra_node) for Allgather + 0 Auto selection + 1 Multi leaders based inter node + intra node composition + 2 NM only composition + === END_MPI_T_CVAR_INFO_BLOCK === */ @@ -369,10 +382,14 @@ MPL_STATIC_INLINE_PREFIX int MPID_Allreduce(const void *sendbuf, void *recvbuf, } -MPL_STATIC_INLINE_PREFIX int MPID_Allgather(const void *sendbuf, MPI_Aint sendcount, - MPI_Datatype sendtype, void *recvbuf, - MPI_Aint recvcount, MPI_Datatype recvtype, - MPIR_Comm * comm, MPIR_Errflag_t * errflag) +MPL_STATIC_INLINE_PREFIX int MPIDI_Allgather_allcomm_composition_json(const void *sendbuf, + MPI_Aint sendcount, + MPI_Datatype sendtype, + void *recvbuf, + MPI_Aint recvcount, + MPI_Datatype recvtype, + MPIR_Comm * comm, + MPIR_Errflag_t * errflag) { int mpi_errno = MPI_SUCCESS; const MPIDI_Csel_container_s *cnt = NULL; @@ -389,8 +406,6 @@ MPL_STATIC_INLINE_PREFIX int MPID_Allgather(const void *sendbuf, MPI_Aint sendco .u.allgather.recvtype = recvtype, }; - MPIR_FUNC_ENTER; - cnt = MPIR_Csel_search(MPIDI_COMM(comm, csel_comm), coll_sig); if (cnt == NULL) { @@ -402,11 +417,10 @@ MPL_STATIC_INLINE_PREFIX int MPID_Allgather(const void *sendbuf, MPI_Aint sendco } switch (cnt->id) { - case MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Allgather_intra_composition_alpha: + case MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Allgather_intra_composition_beta: mpi_errno = - MPIDI_Allgather_intra_composition_alpha(sendbuf, sendcount, sendtype, - recvbuf, recvcount, recvtype, - comm, errflag); + MPIDI_Allgather_intra_composition_beta(sendbuf, sendcount, sendtype, + recvbuf, recvcount, recvtype, comm, errflag); break; default: MPIR_Assert(0); @@ -415,7 +429,51 @@ MPL_STATIC_INLINE_PREFIX int MPID_Allgather(const void *sendbuf, MPI_Aint sendco MPIR_ERR_CHECK(mpi_errno); fn_exit: - MPIR_FUNC_EXIT; + return mpi_errno; + fn_fail: + goto fn_exit; +} + +MPL_STATIC_INLINE_PREFIX int MPID_Allgather(const void *sendbuf, MPI_Aint sendcount, + MPI_Datatype sendtype, void *recvbuf, + MPI_Aint recvcount, MPI_Datatype recvtype, + MPIR_Comm * comm, MPIR_Errflag_t * errflag) +{ + int mpi_errno = MPI_SUCCESS; + + MPIR_FUNC_ENTER; + + switch (MPIR_CVAR_ALLGATHER_COMPOSITION) { + case 2: + MPII_COLLECTIVE_FALLBACK_CHECK(comm->rank, + comm->comm_kind == MPIR_COMM_KIND__INTRACOMM, mpi_errno, + "Allgather composition beta cannot be applied.\n"); + mpi_errno = + MPIDI_Allgather_intra_composition_beta(sendbuf, sendcount, sendtype, recvbuf, + recvcount, recvtype, comm, errflag); + break; + default: + mpi_errno = MPIDI_Allgather_allcomm_composition_json(sendbuf, sendcount, sendtype, + recvbuf, recvcount, recvtype, comm, + errflag); + break; + } + + MPIR_ERR_CHECK(mpi_errno); + goto fn_exit; + + fallback: + if (comm->comm_kind == MPIR_COMM_KIND__INTERCOMM) + mpi_errno = + MPIR_Allgather_impl(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm, + errflag); + else + mpi_errno = + MPIDI_Allgather_intra_composition_beta(sendbuf, sendcount, sendtype, recvbuf, recvcount, + recvtype, comm, errflag); + + fn_exit: + MPIR_FUNC_ENTER; return mpi_errno; fn_fail: goto fn_exit; diff --git a/src/mpid/ch4/src/ch4_coll_impl.h b/src/mpid/ch4/src/ch4_coll_impl.h index a145d3bfbb2..cb734dea7c3 100644 --- a/src/mpid/ch4/src/ch4_coll_impl.h +++ b/src/mpid/ch4/src/ch4_coll_impl.h @@ -642,14 +642,14 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_Alltoallw_intra_composition_alpha(const void goto fn_exit; } -MPL_STATIC_INLINE_PREFIX int MPIDI_Allgather_intra_composition_alpha(const void *sendbuf, - MPI_Aint sendcount, - MPI_Datatype sendtype, - void *recvbuf, - MPI_Aint recvcount, - MPI_Datatype recvtype, - MPIR_Comm * comm_ptr, - MPIR_Errflag_t * errflag) +MPL_STATIC_INLINE_PREFIX int MPIDI_Allgather_intra_composition_beta(const void *sendbuf, + MPI_Aint sendcount, + MPI_Datatype sendtype, + void *recvbuf, + MPI_Aint recvcount, + MPI_Datatype recvtype, + MPIR_Comm * comm_ptr, + MPIR_Errflag_t * errflag) { int mpi_errno = MPI_SUCCESS; diff --git a/src/mpid/ch4/src/ch4_csel_container.h b/src/mpid/ch4/src/ch4_csel_container.h index 0d6dd7938f2..de888bc4877 100644 --- a/src/mpid/ch4/src/ch4_csel_container.h +++ b/src/mpid/ch4/src/ch4_csel_container.h @@ -23,6 +23,7 @@ typedef struct { MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Alltoallv_intra_composition_alpha, MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Alltoallw_intra_composition_alpha, MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Allgather_intra_composition_alpha, + MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Allgather_intra_composition_beta, MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Allgatherv_intra_composition_alpha, MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Gather_intra_composition_alpha, MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Gatherv_intra_composition_alpha, diff --git a/src/mpid/ch4/src/ch4_init.c b/src/mpid/ch4/src/ch4_init.c index cfafe7565bf..c1bc5417c24 100644 --- a/src/mpid/ch4/src/ch4_init.c +++ b/src/mpid/ch4/src/ch4_init.c @@ -151,6 +151,9 @@ static void *create_container(struct json_object *obj) else if (!strcmp(ckey, "composition=MPIDI_Allgather_intra_composition_alpha")) cnt->id = MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Allgather_intra_composition_alpha; + else if (!strcmp(ckey, "composition=MPIDI_Allgather_intra_composition_beta")) + cnt->id = + MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Allgather_intra_composition_beta; else if (!strcmp(ckey, "composition=MPIDI_Allgatherv_intra_composition_alpha")) cnt->id = MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Allgatherv_intra_composition_alpha; From 31aa52df66c83f7dcc96498a823190758b69540a Mon Sep 17 00:00:00 2001 From: Gengbin Zheng Date: Wed, 2 Feb 2022 15:07:39 -0600 Subject: [PATCH 425/607] ch4/coll: Add CVAR to select composition for Alltoall --- src/mpid/ch4/src/ch4_coll.h | 78 +++++++++++++++++++++++---- src/mpid/ch4/src/ch4_coll_impl.h | 16 +++--- src/mpid/ch4/src/ch4_csel_container.h | 1 + src/mpid/ch4/src/ch4_init.c | 2 + 4 files changed, 79 insertions(+), 18 deletions(-) diff --git a/src/mpid/ch4/src/ch4_coll.h b/src/mpid/ch4/src/ch4_coll.h index 2d708b2e933..704e695549e 100644 --- a/src/mpid/ch4/src/ch4_coll.h +++ b/src/mpid/ch4/src/ch4_coll.h @@ -68,6 +68,19 @@ 1 Multi leaders based inter node + intra node composition 2 NM only composition + - name : MPIR_CVAR_ALLTOALL_COMPOSITION + category : COLLECTIVE + type : int + default : 0 + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + Select composition (inter_node + intra_node) for Alltoall + 0 Auto selection + 1 Multi leaders based inter node + intra node composition + 2 NM only composition + === END_MPI_T_CVAR_INFO_BLOCK === */ @@ -743,10 +756,14 @@ MPL_STATIC_INLINE_PREFIX int MPID_Gatherv(const void *sendbuf, MPI_Aint sendcoun goto fn_exit; } -MPL_STATIC_INLINE_PREFIX int MPID_Alltoall(const void *sendbuf, MPI_Aint sendcount, - MPI_Datatype sendtype, void *recvbuf, MPI_Aint recvcount, - MPI_Datatype recvtype, MPIR_Comm * comm, - MPIR_Errflag_t * errflag) +MPL_STATIC_INLINE_PREFIX int MPIDI_Alltoall_allcomm_composition_json(const void *sendbuf, + MPI_Aint sendcount, + MPI_Datatype sendtype, + void *recvbuf, + MPI_Aint recvcount, + MPI_Datatype recvtype, + MPIR_Comm * comm, + MPIR_Errflag_t * errflag) { int mpi_errno = MPI_SUCCESS; const MPIDI_Csel_container_s *cnt = NULL; @@ -763,8 +780,6 @@ MPL_STATIC_INLINE_PREFIX int MPID_Alltoall(const void *sendbuf, MPI_Aint sendcou .u.alltoall.recvtype = recvtype, }; - MPIR_FUNC_ENTER; - cnt = MPIR_Csel_search(MPIDI_COMM(comm, csel_comm), coll_sig); if (cnt == NULL) { @@ -775,10 +790,10 @@ MPL_STATIC_INLINE_PREFIX int MPID_Alltoall(const void *sendbuf, MPI_Aint sendcou } switch (cnt->id) { - case MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Alltoall_intra_composition_alpha: + case MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Alltoall_intra_composition_beta: mpi_errno = - MPIDI_Alltoall_intra_composition_alpha(sendbuf, sendcount, sendtype, - recvbuf, recvcount, recvtype, comm, errflag); + MPIDI_Alltoall_intra_composition_beta(sendbuf, sendcount, sendtype, + recvbuf, recvcount, recvtype, comm, errflag); break; default: MPIR_Assert(0); @@ -787,7 +802,50 @@ MPL_STATIC_INLINE_PREFIX int MPID_Alltoall(const void *sendbuf, MPI_Aint sendcou MPIR_ERR_CHECK(mpi_errno); fn_exit: - MPIR_FUNC_EXIT; + return mpi_errno; + fn_fail: + goto fn_exit; +} + +MPL_STATIC_INLINE_PREFIX int MPID_Alltoall(const void *sendbuf, MPI_Aint sendcount, + MPI_Datatype sendtype, void *recvbuf, MPI_Aint recvcount, + MPI_Datatype recvtype, MPIR_Comm * comm, + MPIR_Errflag_t * errflag) +{ + int mpi_errno = MPI_SUCCESS; + + MPIR_FUNC_ENTER; + + switch (MPIR_CVAR_ALLTOALL_COMPOSITION) { + case 2: + MPII_COLLECTIVE_FALLBACK_CHECK(comm->rank, + comm->comm_kind == MPIR_COMM_KIND__INTRACOMM, mpi_errno, + "Alltoall composition beta cannot be applied.\n"); + mpi_errno = + MPIDI_Alltoall_intra_composition_beta(sendbuf, sendcount, sendtype, recvbuf, + recvcount, recvtype, comm, errflag); + break; + default: + mpi_errno = MPIDI_Alltoall_allcomm_composition_json(sendbuf, sendcount, sendtype, + recvbuf, recvcount, recvtype, comm, + errflag); + break; + } + + MPIR_ERR_CHECK(mpi_errno); + goto fn_exit; + + fallback: + if (comm->comm_kind == MPIR_COMM_KIND__INTERCOMM) + mpi_errno = + MPIR_Alltoall_impl(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm, + errflag); + else + mpi_errno = MPIDI_Alltoall_intra_composition_beta(sendbuf, sendcount, sendtype, recvbuf, + recvcount, recvtype, comm, errflag); + + fn_exit: + MPIR_FUNC_ENTER; return mpi_errno; fn_fail: goto fn_exit; diff --git a/src/mpid/ch4/src/ch4_coll_impl.h b/src/mpid/ch4/src/ch4_coll_impl.h index cb734dea7c3..58132b232d6 100644 --- a/src/mpid/ch4/src/ch4_coll_impl.h +++ b/src/mpid/ch4/src/ch4_coll_impl.h @@ -569,14 +569,14 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_Reduce_intra_composition_gamma(const void *se goto fn_exit; } -MPL_STATIC_INLINE_PREFIX int MPIDI_Alltoall_intra_composition_alpha(const void *sendbuf, - MPI_Aint sendcount, - MPI_Datatype sendtype, - void *recvbuf, - MPI_Aint recvcount, - MPI_Datatype recvtype, - MPIR_Comm * comm_ptr, - MPIR_Errflag_t * errflag) +MPL_STATIC_INLINE_PREFIX int MPIDI_Alltoall_intra_composition_beta(const void *sendbuf, + MPI_Aint sendcount, + MPI_Datatype sendtype, + void *recvbuf, + MPI_Aint recvcount, + MPI_Datatype recvtype, + MPIR_Comm * comm_ptr, + MPIR_Errflag_t * errflag) { int mpi_errno = MPI_SUCCESS; diff --git a/src/mpid/ch4/src/ch4_csel_container.h b/src/mpid/ch4/src/ch4_csel_container.h index de888bc4877..cd5144d3964 100644 --- a/src/mpid/ch4/src/ch4_csel_container.h +++ b/src/mpid/ch4/src/ch4_csel_container.h @@ -20,6 +20,7 @@ typedef struct { MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Allreduce_intra_composition_beta, MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Allreduce_intra_composition_gamma, MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Alltoall_intra_composition_alpha, + MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Alltoall_intra_composition_beta, MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Alltoallv_intra_composition_alpha, MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Alltoallw_intra_composition_alpha, MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Allgather_intra_composition_alpha, diff --git a/src/mpid/ch4/src/ch4_init.c b/src/mpid/ch4/src/ch4_init.c index c1bc5417c24..f3403b11338 100644 --- a/src/mpid/ch4/src/ch4_init.c +++ b/src/mpid/ch4/src/ch4_init.c @@ -142,6 +142,8 @@ static void *create_container(struct json_object *obj) else if (!strcmp(ckey, "composition=MPIDI_Alltoall_intra_composition_alpha")) cnt->id = MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Alltoall_intra_composition_alpha; + else if (!strcmp(ckey, "composition=MPIDI_Alltoall_intra_composition_beta")) + cnt->id = MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Alltoall_intra_composition_beta; else if (!strcmp(ckey, "composition=MPIDI_Alltoallv_intra_composition_alpha")) cnt->id = MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Alltoallv_intra_composition_alpha; From 8c26428ac3242e1e2d56279c577bbf3c278e5a3f Mon Sep 17 00:00:00 2001 From: Gengbin Zheng Date: Wed, 2 Feb 2022 18:20:00 -0600 Subject: [PATCH 426/607] ch4/coll: Add CVAR to select composition for Reduce --- src/mpid/ch4/src/ch4_coll.h | 85 ++++++++++++++++++++++++++++++++++--- 1 file changed, 80 insertions(+), 5 deletions(-) diff --git a/src/mpid/ch4/src/ch4_coll.h b/src/mpid/ch4/src/ch4_coll.h index 704e695549e..f456466f7f1 100644 --- a/src/mpid/ch4/src/ch4_coll.h +++ b/src/mpid/ch4/src/ch4_coll.h @@ -81,6 +81,20 @@ 1 Multi leaders based inter node + intra node composition 2 NM only composition + - name : MPIR_CVAR_REDUCE_COMPOSITION + category : COLLECTIVE + type : int + default : 0 + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + Select composition (inter_node + intra_node) for Reduce + 0 Auto selection + 1 NM + SHM with explicit send-recv between rank 0 and root + 2 NM + SHM without the explicit send-recv + 3 NM only + === END_MPI_T_CVAR_INFO_BLOCK === */ @@ -962,9 +976,11 @@ MPL_STATIC_INLINE_PREFIX int MPID_Alltoallw(const void *sendbuf, const MPI_Aint goto fn_exit; } -MPL_STATIC_INLINE_PREFIX int MPID_Reduce(const void *sendbuf, void *recvbuf, - MPI_Aint count, MPI_Datatype datatype, MPI_Op op, - int root, MPIR_Comm * comm, MPIR_Errflag_t * errflag) +MPL_STATIC_INLINE_PREFIX int MPIDI_Reduce_allcomm_composition_json(const void *sendbuf, + void *recvbuf, MPI_Aint count, + MPI_Datatype datatype, MPI_Op op, + int root, MPIR_Comm * comm, + MPIR_Errflag_t * errflag) { int mpi_errno = MPI_SUCCESS; const MPIDI_Csel_container_s *cnt = NULL; @@ -981,8 +997,6 @@ MPL_STATIC_INLINE_PREFIX int MPID_Reduce(const void *sendbuf, void *recvbuf, .u.reduce.root = root, }; - MPIR_FUNC_ENTER; - cnt = MPIR_Csel_search(MPIDI_COMM(comm, csel_comm), coll_sig); if (cnt == NULL) { @@ -1013,6 +1027,67 @@ MPL_STATIC_INLINE_PREFIX int MPID_Reduce(const void *sendbuf, void *recvbuf, MPIR_ERR_CHECK(mpi_errno); + fn_exit: + return mpi_errno; + fn_fail: + goto fn_exit; +} + +MPL_STATIC_INLINE_PREFIX int MPID_Reduce(const void *sendbuf, void *recvbuf, + MPI_Aint count, MPI_Datatype datatype, MPI_Op op, + int root, MPIR_Comm * comm, MPIR_Errflag_t * errflag) +{ + int mpi_errno = MPI_SUCCESS; + + MPIR_FUNC_ENTER; + + switch (MPIR_CVAR_REDUCE_COMPOSITION) { + case 1: + MPII_COLLECTIVE_FALLBACK_CHECK(comm->rank, comm->comm_kind == MPIR_COMM_KIND__INTRACOMM + && comm->hierarchy_kind == + MPIR_COMM_HIERARCHY_KIND__PARENT && + MPIR_Op_is_commutative(op), mpi_errno, + "Reduce composition alpha cannot be applied.\n"); + mpi_errno = + MPIDI_Reduce_intra_composition_alpha(sendbuf, recvbuf, count, datatype, op, root, + comm, errflag); + break; + case 2: + MPII_COLLECTIVE_FALLBACK_CHECK(comm->rank, comm->comm_kind == MPIR_COMM_KIND__INTRACOMM + && comm->hierarchy_kind == + MPIR_COMM_HIERARCHY_KIND__PARENT && + MPIR_Op_is_commutative(op), mpi_errno, + "Reduce composition beta cannot be applied.\n"); + mpi_errno = + MPIDI_Reduce_intra_composition_beta(sendbuf, recvbuf, count, datatype, op, root, + comm, errflag); + break; + case 3: + MPII_COLLECTIVE_FALLBACK_CHECK(comm->rank, + comm->comm_kind == MPIR_COMM_KIND__INTRACOMM, mpi_errno, + "Reduce composition gamma cannot be applied.\n"); + mpi_errno = + MPIDI_Reduce_intra_composition_gamma(sendbuf, recvbuf, count, datatype, op, root, + comm, errflag); + break; + default: + mpi_errno = + MPIDI_Reduce_allcomm_composition_json(sendbuf, recvbuf, count, datatype, op, + root, comm, errflag); + break; + } + + MPIR_ERR_CHECK(mpi_errno); + goto fn_exit; + + fallback: + if (comm->comm_kind == MPIR_COMM_KIND__INTERCOMM) + mpi_errno = MPIR_Reduce_impl(sendbuf, recvbuf, count, datatype, op, root, comm, errflag); + else + mpi_errno = + MPIDI_Reduce_intra_composition_gamma(sendbuf, recvbuf, count, datatype, op, root, comm, + errflag); + fn_exit: MPIR_FUNC_EXIT; return mpi_errno; From f0476629fb09a5bd274d707a40da99d55801eaf9 Mon Sep 17 00:00:00 2001 From: Gengbin Zheng Date: Thu, 3 Feb 2022 14:24:33 -0600 Subject: [PATCH 427/607] json: change Allgather/Alltoall composition to beta due to name change --- maint/tuning/coll/ch4/generic.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maint/tuning/coll/ch4/generic.json b/maint/tuning/coll/ch4/generic.json index 3e8c11de150..aa94ba85d5b 100644 --- a/maint/tuning/coll/ch4/generic.json +++ b/maint/tuning/coll/ch4/generic.json @@ -150,7 +150,7 @@ { "comm_type=intra": { - "composition=MPIDI_Alltoall_intra_composition_alpha":{} + "composition=MPIDI_Alltoall_intra_composition_beta":{} } }, "collective=alltoallv": @@ -171,7 +171,7 @@ { "comm_type=intra": { - "composition=MPIDI_Allgather_intra_composition_alpha":{} + "composition=MPIDI_Allgather_intra_composition_beta":{} } }, "collective=allgatherv": From 02cd7a14b2ac93686dd87d540ae1fcf637d64e42 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 31 Jan 2022 16:17:18 -0600 Subject: [PATCH 428/607] maint: fix extracterrmsgs We have been manually setting MPI error class index in src/mpi/errhan/baseerrnames.txt, and it has been out-of-sync with the values defined in mpi.h. This commit does following: * Remove the index from baseerrnames.txt and directly load the defined value from mpi.h instead. * Add UNKNOWN entry to map the missing entries in baseerrnames.txt. * When autogen.sh fails to extract error messages, do not generate dummy defmsg.h, fail instead. The dummy header will break the error class message translation anyway. --- autogen.sh | 21 +----- maint/extracterrmsgs | 114 ++++++++++++++++++----------- src/mpi/errhan/baseerrnames.txt | 126 ++++++++++++++++---------------- 3 files changed, 138 insertions(+), 123 deletions(-) diff --git a/autogen.sh b/autogen.sh index e3fe410b9de..55e05143f0d 100755 --- a/autogen.sh +++ b/autogen.sh @@ -401,25 +401,8 @@ fn_errmsgs() { mv .tmp src/mpi/errhan/defmsg.h fi if [ ! -s src/mpi/errhan/defmsg.h ] ; then - echo_n "Creating a dummy defmsg.h file... " - cat > src/mpi/errhan/defmsg.h < MPICH_ERROR_MSG__NONE -#define MPIR_MAX_ERROR_CLASS_INDEX 54 -static int class_to_index[] = { -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0 }; -#endif -EOF - echo "done" + error "Unable to extract error messages" + exit 1 fi } diff --git a/maint/extracterrmsgs b/maint/extracterrmsgs index 5dbc8e7ee4f..d4e842e3baa 100755 --- a/maint/extracterrmsgs +++ b/maint/extracterrmsgs @@ -45,8 +45,10 @@ foreach my $k ("envvarparse", "cvar_val"){ } # Check for special args -@files = (); -%skipFiles = (); +my $mpi_h = "src/include/mpi.h.in"; +my $baseerrnames_txt = "src/mpi/errhan/baseerrnames.txt"; +my @files = (); +my %skipFiles = (); my @errnameFiles = (); $outfile = ""; foreach $arg (@ARGV) { @@ -113,6 +115,30 @@ if ($build_test_pgm && -d "test/mpi/errhan") { print TESTFD "{\n int err;\n MPI_Init( 0, 0 );\n"; } +# Load mpi.h for error class constants +my %mpi_h_constants; +$mpi_h_constants{"MPI_SUCCESS"} = 0; +if (open In, $mpi_h) { + while () { + if (/^#define\s+((MPICH|MPI|MPI_T|MPIX)_ERR_\w+)\s+(.+)/) { + my ($key, $t) = ($1, $3); + if ($t=~/^(\d+)/) { + $mpi_h_constants{$key} = $1; + } elsif ($t=~/MPICH_ERR_FIRST_MPIX\s*\+\s*(\d+)/) { + $mpi_h_constants{$key} = $mpi_h_constants{MPICH_ERR_FIRST_MPIX} + $1; + } + } + } + close In; +} else { + die "Unable to read $mpi_h\n"; +} + +my $max_err_class = $mpi_h_constants{MPICH_ERR_LAST_MPIX}; +if (!$max_err_class) { + die "Failed to load MPICH_ERR_LAST_MPIX from $mpi_h\n"; +} + # Process the definitions foreach $file (@files) { print "$file\n" if $showfiles; @@ -127,6 +153,28 @@ foreach my $sourcefile (@errnameFiles) { &ReadErrnamesFile( $sourcefile ); } +# Load baseerrnames.txt +my @class_msgs; +if (open In, $baseerrnames_txt) { + while () { + if (/^(MPI\w+)\s+(\*\*\w+)/) { + my ($name, $shortmsg) = ($1, $2, $3); + my $id = $mpi_h_constants{$name}; + if (defined $id) { + $generic_msgs{$shortmsg}++; + $generic_loc{$shortmsg} = ":baseerrnames.txt"; + $class_msgs[$id] = $shortmsg; + } else { + die "error class $name not found in mpi.h\n"; + } + } + } + close In; +} else { + die "Unable to read $baseerrnames_txt\n"; +} + + # Create the output files from the input that we've read &CreateErrmsgsHeader( $OUTFD ); &CreateErrMsgMapping( $OUTFD ); @@ -193,46 +241,15 @@ typedef struct msgpair { sub CreateErrMsgMapping { my $OUTFD = $_[0]; - # Create a mapping of MPI error classes to the specific error - # message by index into generic_err_msgs. This reads the file - # baseerrnames, looks up the generic message, and maps the MPI error - # class to the corresponding index. - # We must do this here because we must ensure that all MPI error - # classes have been added to the generic messages - @class_msgs = (); - open (FD, "<$rootdir/src/mpi/errhan/baseerrnames.txt" ) || - die "Could not open $rootdir/src/mpi/errhan/baseerrnames.txt\n"; - while () { - s/#.*$//; - my ($mpiname,$num,$shortmsg) = split(/\s\s*/); - if (!defined($shortmsg)) { - # In case there is no short message entry (!) - $shortmsg = ""; - } - if ($shortmsg ne "") - { - if ($shortmsg =~ /\%/) - { - print STDERR "Warning: generic message $shortmsg in baseerrnames.txt contains format control\n"; - } - - $generic_msgs{$shortmsg}++; - $generic_loc{$shortmsg} = ":baseerrnames.txt"; - - $class_msgs[$num] = "$shortmsg"; - } - } - close (FD); - # For the case of classes only, output the strings for the class # messages print $OUTFD "#if MPICH_ERROR_MSG_LEVEL == MPICH_ERROR_MSG__CLASS\n"; print $OUTFD "#define MPIR_MAX_ERROR_CLASS_INDEX $#class_msgs+1\n"; print $OUTFD "static const char *classToMsg[] = {\n"; - for (my $i=0; $i<=$#class_msgs; $i++) { + for (my $i=0; $i<=$max_err_class; $i++) { my $shortname = $class_msgs[$i]; - my $msg = $longnames{$shortname}; - print $OUTFD "\"$msg\", /* $i $class_msgs[$i] */\n"; + my $msg = $longnames{$shortname}; + print $OUTFD "\"$msg\", /* $i $class_msgs[$i] */\n"; } print $OUTFD "0 }; \n"; print $OUTFD "#endif /* MSG_CLASS */\n"; @@ -246,8 +263,18 @@ sub CreateErrMsgMapping { print $OUTFD "/* The names are in sorted order, allowing the use of a simple\ linear search or bisection algorithm to find the message corresponding to\ a particular message */\n"; + my @sorted_generic_msgs = sort keys %generic_msgs; + + # add a dummy UNKNOWN entry in the front. + # NOTE: assume all other generic message are lowercase so "UNKNOWN" will + # be ordered first. This is critical because FindGenericMsgIndex assumes + # this ordering! + unshift @sorted_generic_msgs, "**UNKNOWN"; + $generic_loc{"**UNKNOWN"} = ":[NONE]"; + $longnames{"**UNKNOWN"} = "Unknown error class"; + my $num = 0; - foreach my $key (sort keys %generic_msgs) + foreach my $key (@sorted_generic_msgs) { $longvalue = "\"\0\""; if (!defined($longnames{$key})) @@ -333,12 +360,17 @@ sub CreateErrMsgMapping { print $OUTFD "#endif\n\n"; print $OUTFD "#if MPICH_ERROR_MSG_LEVEL > MPICH_ERROR_MSG__CLASS\n"; - $maxval = $#class_msgs + 1; + $maxval = $max_err_class + 1; print $OUTFD "#define MPIR_MAX_ERROR_CLASS_INDEX $maxval\n"; print $OUTFD "static int class_to_index[] = {\n"; - for (my $i=0; $i<=$#class_msgs; $i++) { - print $OUTFD "$short_to_num{$class_msgs[$i]}"; - print $OUTFD "," if ($i < $#class_msgs); + for (my $i=0; $i<=$max_err_class; $i++) { + my $idx = $short_to_num{$class_msgs[$i]}; + if (!$idx) { + # 0 is the "**UNKNOWN" entry + $idx = 0; + } + print $OUTFD "$idx"; + print $OUTFD "," if ($i < $max_err_class); print $OUTFD "\n" if !(($i + 1) % 10); } print $OUTFD "};\n"; diff --git a/src/mpi/errhan/baseerrnames.txt b/src/mpi/errhan/baseerrnames.txt index e2e3afe131e..9da37597f11 100644 --- a/src/mpi/errhan/baseerrnames.txt +++ b/src/mpi/errhan/baseerrnames.txt @@ -10,75 +10,75 @@ # mpi_err_xxx integer-value short-name # where "integer-value" is the same as in mpi.h (eventually, we should # generate this automatically). -MPI_SUCCESS 0 **success +MPI_SUCCESS **success # Communication argument parameters -MPI_ERR_BUFFER 1 **buffer -MPI_ERR_COUNT 2 **count -MPI_ERR_TYPE 3 **dtype -MPI_ERR_TAG 4 **tag -MPI_ERR_COMM 5 **comm -MPI_ERR_RANK 6 **rank -MPI_ERR_ROOT 7 **root -MPI_ERR_TRUNCATE 14 **truncate +MPI_ERR_BUFFER **buffer +MPI_ERR_COUNT **count +MPI_ERR_TYPE **dtype +MPI_ERR_TAG **tag +MPI_ERR_COMM **comm +MPI_ERR_RANK **rank +MPI_ERR_ROOT **root +MPI_ERR_TRUNCATE **truncate # MPI Objects (other than COMM) -MPI_ERR_GROUP 8 **group -MPI_ERR_OP 9 **op -MPI_ERR_REQUEST 19 **request +MPI_ERR_GROUP **group +MPI_ERR_OP **op +MPI_ERR_REQUEST **request # Special topology argument parameters -MPI_ERR_TOPOLOGY 10 **topology -MPI_ERR_DIMS 11 **dims +MPI_ERR_TOPOLOGY **topology +MPI_ERR_DIMS **dims # All other arguments. This is a class with many kinds -MPI_ERR_ARG 12 **arg +MPI_ERR_ARG **arg # Other errors that are not simply an invalid argument -MPI_ERR_OTHER 15 **other -MPI_ERR_UNKNOWN 13 **unknown -MPI_ERR_INTERN 16 **intern +MPI_ERR_OTHER **other +MPI_ERR_UNKNOWN **unknown +MPI_ERR_INTERN **intern # Multiple completion has two special error classes -MPI_ERR_IN_STATUS 17 **instatus -MPI_ERR_PENDING 18 **pending -MPIX_ERR_PROC_FAILED_PENDING 19 **failure_pending +MPI_ERR_IN_STATUS **instatus +MPI_ERR_PENDING **pending +MPIX_ERR_PROC_FAILED_PENDING **failure_pending # New MPI-2 Error classes -MPI_ERR_FILE 27 **file -MPI_ERR_ACCESS 20 **fileaccess -MPI_ERR_AMODE 21 **fileamode -MPI_ERR_BAD_FILE 22 **filename -MPI_ERR_FILE_EXISTS 25 **fileexist -MPI_ERR_FILE_IN_USE 26 **fileinuse -MPI_ERR_NO_SPACE 36 **filenospace -MPI_ERR_NO_SUCH_FILE 37 **filenoexist -MPI_ERR_IO 32 **io -MPI_ERR_READ_ONLY 40 **filerdonly -MPI_ERR_CONVERSION 23 **conversion -MPI_ERR_DUP_DATAREP 24 **datarepused -MPI_ERR_UNSUPPORTED_DATAREP 43 **datarepunsupported +MPI_ERR_FILE **file +MPI_ERR_ACCESS **fileaccess +MPI_ERR_AMODE **fileamode +MPI_ERR_BAD_FILE **filename +MPI_ERR_FILE_EXISTS **fileexist +MPI_ERR_FILE_IN_USE **fileinuse +MPI_ERR_NO_SPACE **filenospace +MPI_ERR_NO_SUCH_FILE **filenoexist +MPI_ERR_IO **io +MPI_ERR_READ_ONLY **filerdonly +MPI_ERR_CONVERSION **conversion +MPI_ERR_DUP_DATAREP **datarepused +MPI_ERR_UNSUPPORTED_DATAREP **datarepunsupported # MPI_ERR_INFO is NOT defined in the MPI-2 standard. I believe that # this is an oversight -MPI_ERR_INFO 28 **info -MPI_ERR_INFO_KEY 29 **infokey -MPI_ERR_INFO_VALUE 30 **infoval -MPI_ERR_INFO_NOKEY 31 **infonokey -MPI_ERR_NAME 33 **nameservice -MPI_ERR_NO_MEM 34 **allocmem -MPI_ERR_NOT_SAME 35 **notsame -MPI_ERR_PORT 38 **port -MPI_ERR_QUOTA 39 **filequota -MPI_ERR_SERVICE 41 **servicename -MPI_ERR_SPAWN 42 **spawn -MPI_ERR_UNSUPPORTED_OPERATION 44 **fileopunsupported -MPI_ERR_WIN 45 **win -MPI_ERR_BASE 46 **base -MPI_ERR_LOCKTYPE 47 **locktype -MPI_ERR_KEYVAL 48 **keyval -MPI_ERR_RMA_CONFLICT 49 **rmaconflict -MPI_ERR_RMA_SYNC 50 **rmasync -MPI_ERR_SIZE 51 **rmasize -MPI_ERR_DISP 52 **rmadisp -MPI_ERR_ASSERT 53 **assert -MPIX_ERR_PROC_FAILED 54 **proc_failed -MPI_ERR_RMA_RANGE 55 **rmarange -MPI_ERR_RMA_ATTACH 56 **rmaattach -MPI_ERR_RMA_SHARED 57 **rmashared -MPI_ERR_RMA_FLAVOR 58 **rmaflavor -MPIX_ERR_REVOKED 59 **revoked -MPIX_ERR_EAGAIN 60 **eagain -MPIX_ERR_NOREQ 61 **nomemreq +MPI_ERR_INFO **info +MPI_ERR_INFO_KEY **infokey +MPI_ERR_INFO_VALUE **infoval +MPI_ERR_INFO_NOKEY **infonokey +MPI_ERR_NAME **nameservice +MPI_ERR_NO_MEM **allocmem +MPI_ERR_NOT_SAME **notsame +MPI_ERR_PORT **port +MPI_ERR_QUOTA **filequota +MPI_ERR_SERVICE **servicename +MPI_ERR_SPAWN **spawn +MPI_ERR_UNSUPPORTED_OPERATION **fileopunsupported +MPI_ERR_WIN **win +MPI_ERR_BASE **base +MPI_ERR_LOCKTYPE **locktype +MPI_ERR_KEYVAL **keyval +MPI_ERR_RMA_CONFLICT **rmaconflict +MPI_ERR_RMA_SYNC **rmasync +MPI_ERR_SIZE **rmasize +MPI_ERR_DISP **rmadisp +MPI_ERR_ASSERT **assert +MPIX_ERR_PROC_FAILED **proc_failed +MPI_ERR_RMA_RANGE **rmarange +MPI_ERR_RMA_ATTACH **rmaattach +MPI_ERR_RMA_SHARED **rmashared +MPI_ERR_RMA_FLAVOR **rmaflavor +MPIX_ERR_REVOKED **revoked +MPIX_ERR_EAGAIN **eagain +MPIX_ERR_NOREQ **nomemreq From 91ee6883e2198abb3a401a2ff37c7848559264c4 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 31 Jan 2022 18:30:13 -0600 Subject: [PATCH 429/607] maint: indent the generated defmsg.h Add some indentation to the generated src/mpi/errhan/defmsg.h. --- maint/extracterrmsgs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/maint/extracterrmsgs b/maint/extracterrmsgs index d4e842e3baa..13272e5d7d9 100755 --- a/maint/extracterrmsgs +++ b/maint/extracterrmsgs @@ -249,9 +249,9 @@ sub CreateErrMsgMapping { for (my $i=0; $i<=$max_err_class; $i++) { my $shortname = $class_msgs[$i]; my $msg = $longnames{$shortname}; - print $OUTFD "\"$msg\", /* $i $class_msgs[$i] */\n"; + print $OUTFD " \"$msg\", /* $i $class_msgs[$i] */\n"; } - print $OUTFD "0 }; \n"; + print $OUTFD " NULL\n};\n"; print $OUTFD "#endif /* MSG_CLASS */\n"; # Now, output each short,long key @@ -314,7 +314,7 @@ sub CreateErrMsgMapping { my $sentinal2 = "0xcb0bfa11"; print $OUTFD "static const msgpair generic_err_msgs[] = {\n"; for (my $i = 0; $i < $num; $i ++) { - print $OUTFD "{ $sentinal1, short_gen$i, long_gen$i, $sentinal2 }"; + print $OUTFD " { $sentinal1, short_gen$i, long_gen$i, $sentinal2 }"; print $OUTFD "," if ($i < $num - 1); print $OUTFD "\n"; } @@ -352,7 +352,7 @@ sub CreateErrMsgMapping { print $OUTFD "\nstatic const int specific_msgs_len = $num;\n"; print $OUTFD "static const msgpair specific_err_msgs[] = {\n"; for (my $i = 0; $i < $num ; $i ++) { - print $OUTFD "{ $sentinal1, short_spc$i, long_spc$i, $sentinal2 }"; + print $OUTFD " { $sentinal1, short_spc$i, long_spc$i, $sentinal2 }"; print $OUTFD "," if ($i < $num - 1); print $OUTFD "\n"; } @@ -362,7 +362,7 @@ sub CreateErrMsgMapping { print $OUTFD "#if MPICH_ERROR_MSG_LEVEL > MPICH_ERROR_MSG__CLASS\n"; $maxval = $max_err_class + 1; print $OUTFD "#define MPIR_MAX_ERROR_CLASS_INDEX $maxval\n"; - print $OUTFD "static int class_to_index[] = {\n"; + print $OUTFD "static int class_to_index[] = {\n "; for (my $i=0; $i<=$max_err_class; $i++) { my $idx = $short_to_num{$class_msgs[$i]}; if (!$idx) { @@ -371,9 +371,9 @@ sub CreateErrMsgMapping { } print $OUTFD "$idx"; print $OUTFD "," if ($i < $max_err_class); - print $OUTFD "\n" if !(($i + 1) % 10); + print $OUTFD "\n " if !(($i + 1) % 10); } - print $OUTFD "};\n"; + print $OUTFD "\n};\n"; print $OUTFD "#endif\n"; } # From 4d1dca697c1c15da4ab7363ef1b40e25d103a4f6 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 31 Jan 2022 18:21:49 -0600 Subject: [PATCH 430/607] maint: optimize extracterrmsgs Re-initializing %KnownErrRoutines for every line of the source code is waste of time. Just load once can make the script run much faster -- from 3 seconds to a fraction of a second. --- maint/extracterrmsgs | 146 +++++++++++++++++++++++-------------------- 1 file changed, 79 insertions(+), 67 deletions(-) diff --git a/maint/extracterrmsgs b/maint/extracterrmsgs index 13272e5d7d9..b45c6d4c828 100755 --- a/maint/extracterrmsgs +++ b/maint/extracterrmsgs @@ -652,8 +652,14 @@ sub ReadErrnamesFile { # The last two are used to provide better error reporting. # $filename = ""; # Make global so that other routines can echo filename +%KnownErrRoutines; + sub ProcessFile { + if (!%KnownErrRoutines) { + load_KnownErrRoutines(); + } + # Leave filename global for AddTest $filename = $_[0]; my $linecount = 0; @@ -676,74 +682,13 @@ sub ProcessFile $_ = StripComments( FD, $_ ); # Skip the definition of the function if (/int\s+MPI[OUR]_Err_create_code/) { $remainder = ""; next; } - # Match the known routines and macros. - # Then check that the arguments match if there is a - # specific string (number of args matches the number present) - # MPIR_ERR_CHK(FATAL)?ANDJUMP[1-4]?(cond,code,class,gmsg[,smsg,args]) - # MPIR_ERR_SET(FATAL)?ANDJUMP[1-4]?(code,class,gmsg[,smsg,args]) - # MPIR_ERR_CHK(FATAL)?ANDSTMT[1-4]?(cond,code,class,stmt,gmsg[,smsg,args]) - # MPIR_ERR_SET(FATAL)?ANDSTMT[1-4]?(code,class,stmt,gmsg[,smsg,args]) - # Value is a tuple of: - # the count of args where the generic msg begins (starting from 0) - # location of __LINE__ (-1 for none) - # specific msg arg required (0 for no, > 0 for yes) - # is the generic message an indirect from errnames.txt (1=yes 0=no) - # location of the error class - %KnownErrRoutines = ( 'MPIR_Err_create_code' => '5:3:1:1:4', - 'MPIO_Err_create_code' => '5:3:1:0:-1', - 'MPIR_ERR_SET' => '2:-1:0:1:1', - 'MPIR_ERR_SETSIMPLE' => '2:-1:0:1:1', - 'MPIR_ERR_SET1' => '2:-1:1:1:1', - 'MPIR_ERR_SET2' => '2:-1:2:1:1', - 'MPIR_ERR_SETANDSTMT' => '3:-1:0:1:1', - 'MPIR_ERR_SETANDSTMT1' => '3:-1:1:1:1', - 'MPIR_ERR_SETANDSTMT2' => '3:-1:1:1:1', - 'MPIR_ERR_SETANDSTMT3' => '3:-1:1:1:1', - 'MPIR_ERR_SETANDSTMT4' => '3:-1:1:1:1', - 'MPIR_ERR_SETANDJUMP' => '2:-1:0:1:1', - 'MPIR_ERR_SETANDJUMP1' => '2:-1:1:1:1', - 'MPIR_ERR_SETANDJUMP2' => '2:-1:1:1:1', - 'MPIR_ERR_SETANDJUMP3' => '2:-1:1:1:1', - 'MPIR_ERR_SETANDJUMP4' => '2:-1:1:1:1', - 'MPIR_ERR_CHKANDSTMT' => '4:-1:0:1:2', - 'MPIR_ERR_CHKANDSTMT1' => '4:-1:1:1:2', - 'MPIR_ERR_CHKANDSTMT2' => '4:-1:1:1:2', - 'MPIR_ERR_CHKANDSTMT3' => '4:-1:1:1:2', - 'MPIR_ERR_CHKANDSTMT4' => '4:-1:1:1:2', - 'MPIR_ERR_CHKANDJUMP' => '3:-1:0:1:2', - 'MPIR_ERR_CHKANDJUMP1' => '3:-1:1:1:2', - 'MPIR_ERR_CHKANDJUMP2' => '3:-1:1:1:2', - 'MPIR_ERR_CHKANDJUMP3' => '3:-1:1:1:2', - 'MPIR_ERR_CHKANDJUMP4' => '3:-1:1:1:2', - 'MPIR_ERR_SETFATAL' => '2:-1:0:1:1', - 'MPIR_ERR_SETFATALSIMPLE' => '2:-1:0:1:1', - 'MPIR_ERR_SETFATAL1' => '2:-1:1:1:1', - 'MPIR_ERR_SETFATAL2' => '2:-1:2:1:1', - 'MPIR_ERR_SETFATALANDSTMT' => '3:-1:0:1:1', - 'MPIR_ERR_SETFATALANDSTMT1' => '3:-1:1:1:1', - 'MPIR_ERR_SETFATALANDSTMT2' => '3:-1:1:1:1', - 'MPIR_ERR_SETFATALANDSTMT3' => '3:-1:1:1:1', - 'MPIR_ERR_SETFATALANDSTMT4' => '3:-1:1:1:1', - 'MPIR_ERR_SETFATALANDJUMP' => '2:-1:0:1:1', - 'MPIR_ERR_SETFATALANDJUMP1' => '2:-1:1:1:1', - 'MPIR_ERR_SETFATALANDJUMP2' => '2:-1:1:1:1', - 'MPIR_ERR_SETFATALANDJUMP3' => '2:-1:1:1:1', - 'MPIR_ERR_SETFATALANDJUMP4' => '2:-1:1:1:1', - 'MPIR_ERR_CHKFATALANDSTMT' => '4:-1:0:1:2', - 'MPIR_ERR_CHKFATALANDSTMT1' => '4:-1:1:1:2', - 'MPIR_ERR_CHKFATALANDSTMT2' => '4:-1:1:1:2', - 'MPIR_ERR_CHKFATALANDSTMT3' => '4:-1:1:1:2', - 'MPIR_ERR_CHKFATALANDSTMT4' => '4:-1:1:1:2', - 'MPIR_ERR_CHKFATALANDJUMP' => '3:-1:0:1:2', - 'MPIR_ERR_CHKFATALANDJUMP1' => '3:-1:1:1:2', - 'MPIR_ERR_CHKFATALANDJUMP2' => '3:-1:1:1:2', - 'MPIR_ERR_CHKFATALANDJUMP3' => '3:-1:1:1:2', - 'MPIR_ERR_CHKFATALANDJUMP4' => '3:-1:1:1:2', - 'MPIR_ERRTEST_VALID_HANDLE' => '4:-1:0:1:3', - ); - while (/(MPI[OUR]_E[A-Za-z0-9_]+)\s*(\(.*)$/) { + while (/(MPI[OUR]_Err[A-Za-z0-9_]+)\s*(\(.*)$/i) { my $routineName = $1; my $arglist = $2; + if ($routineName =~ /MPIR_ERR_(CHECK|POP|ADD|GET_CLASS|COLL_CHECKANDCONT|is_fatal)/i) { + # skip known false positives + next; + } if (!defined($KnownErrRoutines{$routineName})) { print "Skipping $routineName\n" if $debug; last; @@ -943,7 +888,74 @@ sub ExpandDir { return @files; } - +sub load_KnownErrRoutines { + # Match the known routines and macros. + # Then check that the arguments match if there is a + # specific string (number of args matches the number present) + # MPIR_ERR_CHK(FATAL)?ANDJUMP[1-4]?(cond,code,class,gmsg[,smsg,args]) + # MPIR_ERR_SET(FATAL)?ANDJUMP[1-4]?(code,class,gmsg[,smsg,args]) + # MPIR_ERR_CHK(FATAL)?ANDSTMT[1-4]?(cond,code,class,stmt,gmsg[,smsg,args]) + # MPIR_ERR_SET(FATAL)?ANDSTMT[1-4]?(code,class,stmt,gmsg[,smsg,args]) + # Value is a tuple of: + # the count of args where the generic msg begins (starting from 0) + # location of __LINE__ (-1 for none) + # specific msg arg required (0 for no, > 0 for yes) + # is the generic message an indirect from errnames.txt (1=yes 0=no) + # location of the error class + %KnownErrRoutines = ( + 'MPIR_Err_create_code' => '5:3:1:1:4', + 'MPIO_Err_create_code' => '5:3:1:0:-1', + 'MPIR_ERR_SET' => '2:-1:0:1:1', + 'MPIR_ERR_SETSIMPLE' => '2:-1:0:1:1', + 'MPIR_ERR_SET1' => '2:-1:1:1:1', + 'MPIR_ERR_SET2' => '2:-1:2:1:1', + 'MPIR_ERR_SETANDSTMT' => '3:-1:0:1:1', + 'MPIR_ERR_SETANDSTMT1' => '3:-1:1:1:1', + 'MPIR_ERR_SETANDSTMT2' => '3:-1:1:1:1', + 'MPIR_ERR_SETANDSTMT3' => '3:-1:1:1:1', + 'MPIR_ERR_SETANDSTMT4' => '3:-1:1:1:1', + 'MPIR_ERR_SETANDJUMP' => '2:-1:0:1:1', + 'MPIR_ERR_SETANDJUMP1' => '2:-1:1:1:1', + 'MPIR_ERR_SETANDJUMP2' => '2:-1:1:1:1', + 'MPIR_ERR_SETANDJUMP3' => '2:-1:1:1:1', + 'MPIR_ERR_SETANDJUMP4' => '2:-1:1:1:1', + 'MPIR_ERR_CHKANDSTMT' => '4:-1:0:1:2', + 'MPIR_ERR_CHKANDSTMT1' => '4:-1:1:1:2', + 'MPIR_ERR_CHKANDSTMT2' => '4:-1:1:1:2', + 'MPIR_ERR_CHKANDSTMT3' => '4:-1:1:1:2', + 'MPIR_ERR_CHKANDSTMT4' => '4:-1:1:1:2', + 'MPIR_ERR_CHKANDJUMP' => '3:-1:0:1:2', + 'MPIR_ERR_CHKANDJUMP1' => '3:-1:1:1:2', + 'MPIR_ERR_CHKANDJUMP2' => '3:-1:1:1:2', + 'MPIR_ERR_CHKANDJUMP3' => '3:-1:1:1:2', + 'MPIR_ERR_CHKANDJUMP4' => '3:-1:1:1:2', + 'MPIR_ERR_SETFATAL' => '2:-1:0:1:1', + 'MPIR_ERR_SETFATALSIMPLE' => '2:-1:0:1:1', + 'MPIR_ERR_SETFATAL1' => '2:-1:1:1:1', + 'MPIR_ERR_SETFATAL2' => '2:-1:2:1:1', + 'MPIR_ERR_SETFATALANDSTMT' => '3:-1:0:1:1', + 'MPIR_ERR_SETFATALANDSTMT1' => '3:-1:1:1:1', + 'MPIR_ERR_SETFATALANDSTMT2' => '3:-1:1:1:1', + 'MPIR_ERR_SETFATALANDSTMT3' => '3:-1:1:1:1', + 'MPIR_ERR_SETFATALANDSTMT4' => '3:-1:1:1:1', + 'MPIR_ERR_SETFATALANDJUMP' => '2:-1:0:1:1', + 'MPIR_ERR_SETFATALANDJUMP1' => '2:-1:1:1:1', + 'MPIR_ERR_SETFATALANDJUMP2' => '2:-1:1:1:1', + 'MPIR_ERR_SETFATALANDJUMP3' => '2:-1:1:1:1', + 'MPIR_ERR_SETFATALANDJUMP4' => '2:-1:1:1:1', + 'MPIR_ERR_CHKFATALANDSTMT' => '4:-1:0:1:2', + 'MPIR_ERR_CHKFATALANDSTMT1' => '4:-1:1:1:2', + 'MPIR_ERR_CHKFATALANDSTMT2' => '4:-1:1:1:2', + 'MPIR_ERR_CHKFATALANDSTMT3' => '4:-1:1:1:2', + 'MPIR_ERR_CHKFATALANDSTMT4' => '4:-1:1:1:2', + 'MPIR_ERR_CHKFATALANDJUMP' => '3:-1:0:1:2', + 'MPIR_ERR_CHKFATALANDJUMP1' => '3:-1:1:1:2', + 'MPIR_ERR_CHKFATALANDJUMP2' => '3:-1:1:1:2', + 'MPIR_ERR_CHKFATALANDJUMP3' => '3:-1:1:1:2', + 'MPIR_ERR_CHKFATALANDJUMP4' => '3:-1:1:1:2', + 'MPIR_ERRTEST_VALID_HANDLE' => '4:-1:0:1:3', + ); +} # # Other todos: From 6429e794ba1dff5c2e3ef8afd769d462f368e608 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 1 Feb 2022 13:48:13 -0600 Subject: [PATCH 431/607] maint: use strict in maint/extracterrmsgs Use strict prevents misuse of global variables in Perl scripts. --- maint/extracterrmsgs | 107 +++++++++++++++++++++++-------------------- 1 file changed, 57 insertions(+), 50 deletions(-) diff --git a/maint/extracterrmsgs b/maint/extracterrmsgs index b45c6d4c828..bbf56bd2214 100755 --- a/maint/extracterrmsgs +++ b/maint/extracterrmsgs @@ -4,6 +4,8 @@ ## See COPYRIGHT in top-level directory ## +use strict; + # (Tested with -w; 10/5/04) # # Find the parse.sub routine. @@ -16,23 +18,22 @@ if ( ! -s "maint/parse.sub" ) { $maintdir = $program; $rootdir = $program; $rootdir =~ s/\/maint//g; - print "Rootdir = $rootdir\n" if $debug; } } require "$maintdir/parse.sub"; -$debug = 0; -$careful = 0; # Set careful to 1 to flag unused messages -$carefulFilename = ""; -$showfiles = 0; -$quiet = 0; -$build_test_pgm = 1; +my $debug = 0; +my $careful = 0; # Set careful to 1 to flag unused messages +my $carefulFilename = ""; +my $showfiles = 0; +my $quiet = 0; +my $build_test_pgm = 1; # FIXME: checkErrClass should be set to 1; currently set to zero # to permit autogen.sh to complete -$checkErrClass = 1; +my $checkErrClass = 1; # Strict is used to control checking of error message strings. -$gStrict = 0; +my $gStrict = 0; if (defined($ENV{"DEBUG_STRICT"})) { $gStrict = 1; } our (%generic_msgs, %generic_loc, %specific_msgs, %specific_loc); @@ -50,8 +51,8 @@ my $baseerrnames_txt = "src/mpi/errhan/baseerrnames.txt"; my @files = (); my %skipFiles = (); my @errnameFiles = (); -$outfile = ""; -foreach $arg (@ARGV) { +my $outfile = ""; +foreach my $arg (@ARGV) { if ($arg =~ /^--?showfiles/) { $showfiles = 1; } elsif( $arg =~ /^--?debug/) { $debug = 1; } elsif( $arg =~ /^--?quiet/) { $quiet = 1; } @@ -69,7 +70,7 @@ foreach $arg (@ARGV) { if (-d $arg) { # Add all .c files from directory $arg to the list of files # to process (this lets us shorten the arg list) - @files = (@files, &ExpandDir( $arg )); + ExpandDir(\@files, $arg); } else { # errname files are treated differently @@ -84,15 +85,17 @@ foreach $arg (@ARGV) { } # End of argument processing +print "Rootdir = $rootdir\n" if $debug; + # Setup the basic file for errnames - Now determined in ExpandDirs #@errnameFiles = ( "$rootdir/src/mpi/errhan/errnames.txt" ); +my $OUTFD; if ($outfile ne "") { - $OUTFD = "MyOutFile"; open( $OUTFD, ">$outfile" ) or die "Could not open $outfile\n"; } else { - $OUTFD = STDOUT; + $OUTFD = *STDOUT; } # Setup before processing the files if ($build_test_pgm && -d "test/mpi/errhan") { @@ -140,7 +143,8 @@ if (!$max_err_class) { } # Process the definitions -foreach $file (@files) { +my (%generic_msgs, %generic_loc, %specific_msgs, %specific_loc); +foreach my $file (@files) { print "$file\n" if $showfiles; &ProcessFile( $file ); } @@ -148,6 +152,8 @@ foreach $file (@files) { # # Create the hash %longnames that maps the short names to the long names, # $longnames{shortname} => longname, by reading the errnames.txt files +# +my (%longnames, %longnamesDefined); foreach my $sourcefile (@errnameFiles) { #print STDERR "processing $sourcefile for error names\n"; &ReadErrnamesFile( $sourcefile ); @@ -176,6 +182,7 @@ if (open In, $baseerrnames_txt) { # Create the output files from the input that we've read +my (%longnamesUsed, %short_to_num); &CreateErrmsgsHeader( $OUTFD ); &CreateErrMsgMapping( $OUTFD ); @@ -187,15 +194,14 @@ if ($build_test_pgm && -d "test/mpi/errhan") { # # Generate a list of unused keys if ($careful) { - my $OUTFD = STDERR; + my $OUTFD = *STDERR; if ($carefulFilename ne "") { - $OUTFD = "ERRFD"; open $OUTFD, ">$carefulFilename" or die "Cannot open $carefulFilename"; } - foreach $shortname (keys(%longnames)) { + foreach my $shortname (keys(%longnames)) { if (!defined($longnamesUsed{$shortname}) || $longnamesUsed{$shortname} < 1) { - $loc = $longnamesDefined{$shortname}; + my $loc = $longnamesDefined{$shortname}; print $OUTFD "Name $shortname is defined in $loc but never used\n"; } } @@ -211,7 +217,7 @@ if ($careful) { # text. # This is a temporary routine; the exact output form will be defined later sub CreateErrmsgsHeader { - $FD = $_[0]; + my $FD = $_[0]; print $FD "/*\ * Copyright (C) by Argonne National Laboratory\ * See COPYRIGHT in top-level directory\ @@ -276,15 +282,14 @@ sub CreateErrMsgMapping { my $num = 0; foreach my $key (@sorted_generic_msgs) { - $longvalue = "\"\0\""; + my $longvalue = "\"\0\""; if (!defined($longnames{$key})) { - $seenfile = $generic_loc{$key}; + my $seenfile = $generic_loc{$key}; if ($key =~ /^\*\*/) { # If the message begins with text, assume that it is a # literal message print STDERR "Shortname $key for generic messages has no expansion (first seen in file $seenfile)\n"; - print STDERR "(Add expansion to $sourcefile)\n"; } next; } @@ -324,9 +329,9 @@ sub CreateErrMsgMapping { $num = 0; # Now output the instance specific messages print $OUTFD "#if MPICH_ERROR_MSG_LEVEL > MPICH_ERROR_MSG__GENERIC\n"; - foreach $key (sort keys %specific_msgs) + foreach my $key (sort keys %specific_msgs) { - $longvalue = "\"\0\""; + my $longvalue = "\"\0\""; if (!defined($longnames{$key})) { @@ -360,7 +365,7 @@ sub CreateErrMsgMapping { print $OUTFD "#endif\n\n"; print $OUTFD "#if MPICH_ERROR_MSG_LEVEL > MPICH_ERROR_MSG__CLASS\n"; - $maxval = $max_err_class + 1; + my $maxval = $max_err_class + 1; print $OUTFD "#define MPIR_MAX_ERROR_CLASS_INDEX $maxval\n"; print $OUTFD "static int class_to_index[] = {\n "; for (my $i=0; $i<=$max_err_class; $i++) { @@ -380,9 +385,10 @@ sub CreateErrMsgMapping { # Add a call to test this message for the error message. # Handle both the generic and specific messages # +my (%test_generic_msg, %test_specific_msg); sub AddTestCall { - my $genericArgLoc = $_[0]; + my ($filename, $genericArgLoc, @msg_args) = @_; my $last_errcode = "MPI_SUCCESS"; # $_[0]; my $fatal_flag = "MPIR_ERR_RECOVERABLE"; # $_[1]; @@ -390,9 +396,11 @@ sub AddTestCall { my $linenum = "__LINE__"; # $_[3]; my $errclass = "MPI_ERR_OTHER"; # $_[4]; - my $generic_msg = $_[$genericArgLoc+1]; - my $specific_msg = $_[$genericArgLoc+2]; - if ($#_ < $genericArgLoc+2) { $specific_msg = "0"; } + my $generic_msg = $msg_args[$genericArgLoc]; + my $specific_msg = $msg_args[$genericArgLoc+1]; + if (!defined $specific_msg) { + $specific_msg = "0"; + } # Ensure that the last_errcode, class and fatal flag are specified. There are a few places where these are variables. if (!($last_errcode =~ /MPI_ERR_/) ) @@ -550,7 +558,7 @@ sub AddTestCall { print STDERR "Unrecognized format type $type for $fullformat in $filename\n"; } } - $actargs = $#_ - $genericArgLoc - 2; + my $actargs = $#msg_args - $genericArgLoc - 1; if ($actargs != $narg) { print STDERR "Error: Format $fullformat provides $narg arguments but call has $actargs in $filename\n"; @@ -651,8 +659,8 @@ sub ReadErrnamesFile { # and the same for hash specific_loc{msg}. # The last two are used to provide better error reporting. # -$filename = ""; # Make global so that other routines can echo filename -%KnownErrRoutines; +my %KnownErrRoutines; +my %bad_syntax_in_file; sub ProcessFile { @@ -660,18 +668,18 @@ sub ProcessFile load_KnownErrRoutines(); } - # Leave filename global for AddTest - $filename = $_[0]; + my $filename = $_[0]; my $linecount = 0; - open (FD, "<$filename" ) or die "Could not open $filename\n"; + my $remainder; + open (my $FD, "<$filename" ) or die "Could not open $filename\n"; - while () { + while (<$FD>) { $linecount++; # Skip code that is marked as ignore (e.g., for # macros that are used to simplify the use of MPIR_Err_create_code # (such macros must also be recognized and processed) if (/\/\*\s+--BEGIN ERROR MACROS--\s+\*\//) { - while () { + while (<$FD>) { $linecount++; if (/\/\*\s+--END ERROR MACROS--\s+\*\//) { last; } } @@ -679,7 +687,7 @@ sub ProcessFile next; } # Next, remove any comments - $_ = StripComments( FD, $_ ); + $_ = StripComments($FD, $_ ); # Skip the definition of the function if (/int\s+MPI[OUR]_Err_create_code/) { $remainder = ""; next; } while (/(MPI[OUR]_Err[A-Za-z0-9_]+)\s*(\(.*)$/i) { @@ -697,11 +705,12 @@ sub ProcessFile my ($genericArgLoc,$hasLine,$hasSpecific,$onlyIndirect,$errClassLoc) = split(/:/,$KnownErrRoutines{$routineName}); - ($leader, $remainder, @args ) = &GetSubArgs( FD, $arglist ); + my ($leader, @args); + ($leader, $remainder, @args ) = &GetSubArgs($FD, $arglist ); # Discard leader if ($debug) { print "Line begins with $leader\n"; # Use $leader to keep -w happy - foreach $arg (@args) { + foreach my $arg (@args) { print "|$arg|\n"; } } @@ -826,7 +835,7 @@ sub ProcessFile } if ($build_test_pgm) { - &AddTestCall( $genericArgLoc, @args ) + &AddTestCall($filename, $genericArgLoc, @args ) } if ($generic_msg =~ /^\"(.*)\"$/) { @@ -851,17 +860,16 @@ sub ProcessFile $_ = $remainder; } } - close FD; + close $FD; } # Get all of the .c files from the named directory, including any subdirs # Also, add any errnames.txt files to the errnamesFiles arrays sub ExpandDir { - my $dir = $_[0]; + my ($files, $dir) = @_; my @otherdirs = (); - my @files = (); opendir DIR, "$dir"; - while ($filename = readdir DIR) { + while (my $filename = readdir DIR) { if ($filename =~ /^\./) { next; } @@ -872,7 +880,7 @@ sub ExpandDir { # Test for both Unix- and Windows-style directory separators if (!defined($skipFiles{"$dir/$filename"}) && !defined($skipFiles{"$dir\\$filename"})) { - $files[$#files + 1] = "$dir/$filename"; + push @$files, "$dir/$filename"; } } elsif ($filename eq "errnames.txt") { @@ -882,10 +890,9 @@ sub ExpandDir { closedir DIR; # (almost) tail recurse on otherdirs (we've closed the directory handle, # so we don't need to worry about it anymore) - foreach $dir (@otherdirs) { - @files = (@files, &ExpandDir( $dir ) ); + foreach my $dir (@otherdirs) { + ExpandDir($files, $dir); } - return @files; } sub load_KnownErrRoutines { From fe6882d9abcca3ea482ea4d6101018f7b0562052 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 24 Jan 2022 19:23:56 -0600 Subject: [PATCH 432/607] config/fortran: add option to disable f08 Sometime user may want to disable f08 even when their compiler passes the PAC_FC_2008_SUPPORT test. Add explicit --disable-f08 option for that. --- configure.ac | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index f4609c8e5bd..c1042dbb929 100644 --- a/configure.ac +++ b/configure.ac @@ -446,6 +446,9 @@ AC_ARG_ENABLE(fortran, no|none - No Fortran support ],,[enable_fortran=all]) +AC_ARG_ENABLE(f08, + AS_HELP_STRING([--disable-f08], [Whether to disable "use mpi_f08" interface]),,[enable_f08=yes]) + AC_ARG_ENABLE(cxx, AS_HELP_STRING([--enable-cxx], [Enable C++ bindings]),,enable_cxx=yes) @@ -2085,19 +2088,15 @@ if test "$enable_fc" = "yes" ; then fi fi -f08_works=no -if test "$enable_fc" = "yes" ; then - PAC_FC_2008_SUPPORT([f08_works=yes],[f08_works=no]) +if test "$enable_f08" = "yes" ; then + PAC_FC_2008_SUPPORT([:],[enable_f08=no]) fi -AM_CONDITIONAL([BUILD_F08_BINDING], [test "$f08_works" = "yes"]) +AM_CONDITIONAL([BUILD_F08_BINDING], [test "$enable_f08" = "yes"]) -if test "$f08_works" = "yes" ; then - status_f08_works=1 +if test "$enable_f08" = "yes" ; then bindings="$bindings f08" -else - status_f08_works=0 + AC_DEFINE(HAVE_F08_BINDING, 1, [Define to 1 if we have Fortran 2008 binding]) fi -AC_DEFINE_UNQUOTED(HAVE_F08_BINDING, $status_f08_works, [Define to 1 to enable Fortran 2008 binding]) # Set defaults for these values so that the Makefile in src/bindings/f90 # is valid even if fc is not enabled (this is necessary for the @@ -4211,7 +4210,7 @@ if test "X$enable_shared" = "Xyes" ; then ) fi -if test "X$f08_works" = "Xyes"; then +if test "$enable_f08" = "yes"; then AS_CASE([$MPI_AINT], [short], [F08_C_AINT="c_short"], [int], [F08_C_AINT="c_int"], @@ -4252,7 +4251,8 @@ fi AC_SUBST(pkgconfigdir) export pkgconfigdir -if test "$f08_works" = "yes" ; then +if test "$enable_f08" = "yes" ; then + PAC_CHECK_PYTHON PAC_FC_CHECK_REAL128 if test -z "$PYTHON" ; then if test -f src/binding/fortran/use_mpi_f08/mpi_f08.f90 ; then From 4c8898a1f20f783c27cb9b4952e5bddc0231f596 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 24 Jan 2022 19:31:53 -0600 Subject: [PATCH 433/607] config: remove MPICH_ENABLE_FC and MPICH_ENABLE_CXX The test suite is now configured independently and no longer need these variables. --- configure.ac | 13 +------------ test/mpi/configure.ac | 4 ---- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/configure.ac b/configure.ac index c1042dbb929..728058d47f0 100644 --- a/configure.ac +++ b/configure.ac @@ -89,12 +89,10 @@ dnl 4. Determine MPI features dnl dnl dnl Special environment variables -dnl To let other scripts and in particular the configure in test/mpi +dnl To let other scripts, e.g. configure in hydra and romio, dnl know that they are being invoked from within the MPICH configure, dnl the following environment variables are set and exported: dnl FROM_MPICH -dnl MPICH_ENABLE_FC -dnl MPICH_ENABLE_CXX dnl dnl Note that no executable statements are allowed (and any are silently dnl dropped) before AC_INIT. @@ -4009,15 +4007,6 @@ AC_SUBST(MPI_MAX_ERROR_STRING) MPIU_DLL_SPEC_DEF="#define MPIU_DLL_SPEC" AC_SUBST(MPIU_DLL_SPEC_DEF) -dnl We can configure the test directory after the rest of the configure -dnl steps because it does not depend on them. -# set and export values that the test/mpi configure will reference to ensure -# that the correct decisions are made since this configure happens before the -# MPICH library is built. -MPICH_ENABLE_CXX=$enable_cxx -MPICH_ENABLE_FC=$enable_fc -export MPICH_ENABLE_CXX -export MPICH_ENABLE_FC AM_CONDITIONAL([BUILD_CXX_BINDING],[test "$enable_cxx" = "yes"]) AM_CONDITIONAL([BUILD_F77_BINDING],[test "$enable_f77" = "yes"]) dnl FIXME DJG this has been moved to the f90 bindings subconfigure.m4 for now diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index da46276037a..461be3cf9db 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -508,10 +508,6 @@ PAC_PROG_MAKE MPILIBLOC="" AC_SUBST(MPILIBLOC) -# more variables that must be marked precious for proper re-configure operation -AC_ARG_VAR([MPICH_ENABLE_FC],["yes" if the enclosing MPICH build supports modern Fortran]) -AC_ARG_VAR([MPICH_ENABLE_CXX],["yes" if the enclosing MPICH build supports C++]) - namepub_tests="#" if test "$enable_namepub" = "yes" ; then namepub_tests="" From c3e4686ab92b4f185c406661552911b4a6beaf52 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 24 Jan 2022 19:39:26 -0600 Subject: [PATCH 434/607] config/fortran: remove checking PAC_FC_AND_F77_COMPATIBLE Now we only use a single $FC compiler, there isn't a need to check compatibility between F77 and FC. --- configure.ac | 45 --------------------------------------------- 1 file changed, 45 deletions(-) diff --git a/configure.ac b/configure.ac index 728058d47f0..6c7af2d557d 100644 --- a/configure.ac +++ b/configure.ac @@ -1931,51 +1931,6 @@ information to configure with the FCFLAGS environment variable.]) fi -# FC requires F77 as well. If the user disabled f77, do not run the -# next test; instead, drop into the warning message -# Set a default value for fc works with f77. This value is -# set to no *only* if fc was selected but was not compatible with f77 -fc_with_f77=yes -if test "$enable_fc" = "yes" -a "$enable_f77" = yes ; then - enable_fc=no - if test "$FC" != "no" ; then - # If we allow multiple weak symbols, we should test a name - # that does not contain an underscore. The Fortran binding uses - # this rule for enabling multiple weak symbols: - # if defined(USE_WEAK_SYMBOLS) && !defined(USE_ONLY_MPI_NAMES) && - # defined(HAVE_MULTIPLE_PRAGMA_WEAK) && - # defined(F77_NAME_LOWER_2USCORE) - # - testRoutine="t1_2" - if test "$pac_cv_prog_c_multiple_weak_symbols" = "yes" -a \ - "$enable_weak_symbols" = "yes" -a \ - "$pac_cv_prog_f77_name_mangle" = "lower doubleunderscore" ; then - testRoutine="t12" - fi - PAC_FC_AND_F77_COMPATIBLE(fc_with_f77=yes,fc_with_f77=no,$testRoutine) - if test "$fc_with_f77" != yes ; then - enable_fc=no - AC_MSG_ERROR([The selected Fortran 90 compiler $FC does not work with the selected Fortran 77 compiler $F77. Use the environment variables FC and F77 respectively to select compatible Fortran compilers. The check here tests to see if a main program compiled with the Fortran 90 compiler can link with a subroutine compiled with the Fortran 77 compiler.]) - elif test "$fc_with_f77" = "yes" ; then - # If we got here, there is a Fortran 90 compiler that we can use - enable_fc=yes - fi - elif test "$pac_cv_prog_fc_works" = no; then - AC_MSG_WARN([Use --disable-fc to keep configure from searching for a Fortran 90 compiler]) - fi - - if test "$enable_fc" = "yes"; then - if test "$FC" = "no" -o "$FC" = ""; then - # No Fortran 90 compiler found; abort - AC_MSG_ERROR([No Fortran 90 compiler found. If you don't need - to build any Fortran 90 programs, you can disable Fortran 90 - support using --disable-fc. If you do want to build Fortran 90 - programs, you need to install a Fortran 90 compiler such as - gfortran or ifort before you can proceed.]) - fi - fi -fi - if test "$enable_fc" = "yes" -a "$enable_f77" != "yes" ; then # Fortran 90 support requires compatible Fortran 77 support AC_MSG_ERROR([ From ce6d5a6366b316109f744f5b2c5fa6bc30746870 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 24 Jan 2022 19:07:11 -0600 Subject: [PATCH 435/607] config/fortran: use enable_{f77,f90,f08} separately By default we will build all Fortran interfaces. However, sometime user may desire disable certain interface. Use separate options so user can easily do so. Currently the f90 interface depends on f77 interface. But it should be possible to only build f77, or only build f08, or build f77 + f08. Remove and replace the variable enable_fc from configure since it is ambiguous whether it refers to the FC compiler or the interface features. --- configure.ac | 83 +++++++-------------- src/binding/fortran/use_mpi/subconfigure.m4 | 2 +- 2 files changed, 28 insertions(+), 57 deletions(-) diff --git a/configure.ac b/configure.ac index 6c7af2d557d..31c3f89d9c2 100644 --- a/configure.ac +++ b/configure.ac @@ -436,13 +436,16 @@ AC_ARG_ENABLE(check-compiler-flags, options, xxxFLAGS, MPICH_xxxFLAGS. Default is on.]),, enable_check_compiler_flags=yes) -dnl We enable f77 and fc if we can find compilers for them. -dnl In addition, we check whether f77 and fc can work together. +dnl Whether to disable the Fortran bindings. By default, we'll probe and build all supported +dnl interfaces including mpif.h, use mpi, and use_mpi_f08. AC_ARG_ENABLE(fortran, -[ --enable-fortran=option - Control the level of Fortran support in the MPICH implementation. - yes|all - Enable all available Fortran implementations (F77, F90+) - no|none - No Fortran support -],,[enable_fortran=all]) + AS_HELP_STRING([--disable-fortran], [Whether to disable Fortran bindings]),,[enable_fortran=yes]) + +AC_ARG_ENABLE(f77, + AS_HELP_STRING([--disable-f77], [Whether to disable "include 'mpif.h'" interface]),,[enable_f77=yes]) + +AC_ARG_ENABLE(f90, + AS_HELP_STRING([--disable-f90], [Whether to disable "use mpi" interface]),,[enable_f90=yes]) AC_ARG_ENABLE(f08, AS_HELP_STRING([--disable-f08], [Whether to disable "use mpi_f08" interface]),,[enable_f08=yes]) @@ -690,26 +693,16 @@ dnl lead to weird AM_CONDITIONAL errors and potentially other problems. # # NOTE: we are skipping overriding CXX as some modules (e.g. ucx) may depend on CXX # -AS_IF([test "x$enable_f77" = "xno"],[F77=no]) -AS_IF([test "x$enable_fc" = "xno"],[FC=no]) # suppress default "-g -O2" from AC_PROG_CXX : ${CXXFLAGS=""} AC_PROG_CXX -enable_f77=no -enable_fc=no -case "$enable_fortran" in - yes|all) - enable_f77=yes - enable_fc=yes - ;; - no|none) - ;; - *) - AC_MSG_WARN([Unknown value $option for --enable-fortran]) - ;; -esac +if test "$enable_fortran" = "no" ; then + enable_f77=no + enable_f90=no + enable_f08=no +fi # Python 3 is needed to generate Fortran bindings PAC_CHECK_PYTHON @@ -719,24 +712,14 @@ if test "$enable_fortran" != "no" ; then : ${FCFLAGS=""} AC_PROG_FC - # HACK, use $FC as F77. We should remove all the F77 usages. - if test "$enable_fc" = "yes" ; then - F77=$FC - if test ! -z "$FCFLAGS" ; then - FFLAGS=$FCFLAGS - fi - fi + F77=$FC - # This needs to come after we've potentially set F77=$FC. Otherwise, we could - # override the user's Fortran compiler selection when only specifying FC at configure - # time, as is allowed. - # suppress default "-g -O2" from AC_PROG_F77 - : ${FFLAGS=""} + FFLAGS=$FCFLAGS AC_PROG_F77 fi -AM_CONDITIONAL([INSTALL_MPIF77],[test "$enable_fc" = "yes" -a "$F77" != "$FC" -a "$FFLAGS" != "$FCFLAGS"]) +AM_CONDITIONAL([INSTALL_MPIF77],[false]) # compute canonical system types AC_CANONICAL_BUILD @@ -1788,7 +1771,7 @@ AC_DEFINE_UNQUOTED(ENABLE_PVAR_MULTINIC,$status_multinic_pvars, # Handle default choices for the Fortran compilers # Note that these have already been set above -if test "$enable_fc" = "yes"; then +if test "$enable_f90" = "yes" -o "$enable_f08" = "yes"; then if test "$FC" = "" -o "$FC" = "no"; then # No Fortran compiler found; abort AC_MSG_ERROR([No Fortran compiler found. If you don't need to @@ -1931,7 +1914,7 @@ information to configure with the FCFLAGS environment variable.]) fi -if test "$enable_fc" = "yes" -a "$enable_f77" != "yes" ; then +if test "$enable_f90" = "yes" -a "$enable_f77" != "yes" ; then # Fortran 90 support requires compatible Fortran 77 support AC_MSG_ERROR([ Fortran 90 support requires compatible Fortran 77 support. @@ -1940,8 +1923,6 @@ do not use configure option --disable-fortran, and set the environment variable F77 to the name of the Fortran 90 compiler, or \$FC. If you do not want any Fortran support, use configure options --disable-fortran.]) - # We should probably do the compatibility test as well - enable_f77=yes fi # ---------------------------------------------------------------------------- @@ -2024,21 +2005,15 @@ fi fi], main_top_srcdir=$main_top_srcdir enable_f77=$enable_f77 -enable_fc=$enable_fc has_exclaim=$has_exclaim has_fort_real8=$pac_cv_fort_real8 includebuild_dir=$includebuild_dir libbuild_dir=$libbuild_dir bashWorks=$bashWorks) -if test "$enable_fc" = "yes" ; then - if test "$enable_f77" != "yes" ; then - AC_MSG_WARN([Fortran 90 requires Fortran 77]) - enable_fc=no - else - bindingsubsystems="$bindingsubsystems src/binding/fortran/use_mpi" - bindings="$bindings f90" - fi +if test "$enable_f90" = "yes" ; then + bindingsubsystems="$bindingsubsystems src/binding/fortran/use_mpi" + bindings="$bindings f90" fi if test "$enable_f08" = "yes" ; then @@ -2072,7 +2047,7 @@ MPI_F08_NAME=mpi_f08 MPI_C_INTERFACE_TYPES_NAME=mpi_c_interface_types MPI_C_INTERFACE_CDESC_NAME=mpi_c_interface_cdesc -if test "$enable_fc" = "yes" ; then +if test "$enable_f90" = "yes" -o "$enable_f08" = "yes"; then # determine shared library flags for FC fc_shlib_conf=src/env/fc_shlib.conf PAC_COMPILER_SHLIB_FLAGS([FC],[$fc_shlib_conf]) @@ -3090,8 +3065,7 @@ if test "$enable_f77" = yes ; then ]) AC_LANG_POP([Fortran]) WTIME_DOUBLE_TYPE="DOUBLE PRECISION" - # Save a copy of the original mpi_base.f90 file - if test "$enable_fc" = "yes" -a "$pac_cv_fort90_real8" = "yes" ; then + if test "$pac_cv_fort90_real8" = "yes" ; then WTIME_DOUBLE_TYPE="REAL*8" fi # WTIME_DOUBLE_TYPE is substituted into mpi_base.f90 @@ -3107,12 +3081,9 @@ if test "$enable_f77" = yes ; then # Note, however, that zero value are (in all practical case) invalid # for Fortran 90, and indicate a failure. Test and fail if Fortran 90 # enabled. - if test "$enable_fc" = "yes" ; then + if test "$enable_f90" = "yes" ; then if test "$ADDRESS_KIND" -le 0 -o "$OFFSET_KIND" -le 0 ; then AC_MSG_ERROR([Unable to determine Fortran 90 integer kinds for MPI types. If you do not need Fortran 90, add --disable-fc to the configure options.]) - # If the above is converted to a warning, you need to change - # enable_fc and remote f90 from the bindings - enable_fc=no fi fi AC_SUBST(ADDRESS_KIND) @@ -3416,7 +3387,7 @@ AC_SUBST(MPI_OFFSET_TYPEDEF) if test -z "$FORTRAN_MPI_OFFSET" ; then FORTRAN_MPI_OFFSET=INTEGER fi -if test "$enable_f77" = yes -a "$enable_fc" = yes ; then +if test "$enable_f77" = yes -a "$enable_f90" = yes ; then AC_LANG_PUSH([Fortran 77]) AC_MSG_CHECKING([whether the Fortran Offset type works with Fortran 77]) AC_COMPILE_IFELSE([ @@ -3965,7 +3936,7 @@ AC_SUBST(MPIU_DLL_SPEC_DEF) AM_CONDITIONAL([BUILD_CXX_BINDING],[test "$enable_cxx" = "yes"]) AM_CONDITIONAL([BUILD_F77_BINDING],[test "$enable_f77" = "yes"]) dnl FIXME DJG this has been moved to the f90 bindings subconfigure.m4 for now -dnl AM_CONDITIONAL([BUILD_FC_BINDING],[test "$enable_fc" = "yes"]) +dnl AM_CONDITIONAL([BUILD_FC_BINDING],[test "$enable_f90" = "yes"]) # MPI_SRCDIR gives the test/mpi configure the location of the source # files for an MPI implementation if test -n "$ac_abs_srcdir" ; then diff --git a/src/binding/fortran/use_mpi/subconfigure.m4 b/src/binding/fortran/use_mpi/subconfigure.m4 index 285b38b5dc2..cbfae2e4758 100644 --- a/src/binding/fortran/use_mpi/subconfigure.m4 +++ b/src/binding/fortran/use_mpi/subconfigure.m4 @@ -3,7 +3,7 @@ dnl This configure is used ONLY to determine the Fortran 90 features dnl that are needed to implement the create_type_xxx routines. AC_DEFUN([PAC_SUBCFG_PREREQ_]PAC_SUBCFG_AUTO_SUFFIX,[ -AM_CONDITIONAL([BUILD_FC_BINDING],[test "X$enable_fc" = "Xyes"]) +AM_CONDITIONAL([BUILD_FC_BINDING],[test "$enable_f90" = "yes"]) ]) AC_DEFUN([PAC_SUBCFG_BODY_]PAC_SUBCFG_AUTO_SUFFIX,[ From 016a6c0843782fb0926a69b79d8ab6af2b28ccbc Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 8 Feb 2022 14:12:29 -0600 Subject: [PATCH 436/607] hydra/config: Enable debugging with --enable-g=yes Adding --enable-g to the configure line was ignored. Make it is a synonym for --enable-g=all. --- src/pm/hydra/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pm/hydra/configure.ac b/src/pm/hydra/configure.ac index 679fc023403..5f8e6ca028f 100644 --- a/src/pm/hydra/configure.ac +++ b/src/pm/hydra/configure.ac @@ -520,7 +520,7 @@ for option in $enable_g ; do mem) AC_DEFINE(USE_MEMORY_TRACING,1,[Define if memory tracing is enabled]) ;; - all) + yes|all) PAC_APPEND_FLAG(-g, CFLAGS) AC_DEFINE(USE_MEMORY_TRACING,1,[Define if memory tracing is enabled]) AC_DEFINE(PMI_KEY_CHECK,1,[Define if we should check for PMI key collisions]) From 6766fd953a64ecdc799d105b0c6d8183b006b751 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 8 Feb 2022 15:13:00 -0600 Subject: [PATCH 437/607] hydra: Fix total core count calculation during launch Only consider the nodes used in a launch as part of the total core count. See pmodels/mpich#5835. --- src/pm/hydra/pm/pmiserv/pmiserv_utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pm/hydra/pm/pmiserv/pmiserv_utils.c b/src/pm/hydra/pm/pmiserv/pmiserv_utils.c index 2aabb432ffa..b8ea6564fbb 100644 --- a/src/pm/hydra/pm/pmiserv/pmiserv_utils.c +++ b/src/pm/hydra/pm/pmiserv/pmiserv_utils.c @@ -279,8 +279,8 @@ HYD_status HYD_pmcd_pmi_fill_in_exec_launch_info(struct HYD_pg *pg) } total_core_count = 0; - for (node = HYD_server_info.node_list; node; node = node->next) - total_core_count += node->core_count; + for (proxy = pg->proxy_list; proxy; proxy = proxy->next) + total_core_count += proxy->node->core_count; HYDU_MALLOC_OR_JUMP(filler_pmi_ids, int *, proxy_count * sizeof(int), status); HYDU_MALLOC_OR_JUMP(nonfiller_pmi_ids, int *, proxy_count * sizeof(int), status); From a0f1e29b8d0076370eb2ddf6e9ef07e05f53d041 Mon Sep 17 00:00:00 2001 From: Gengbin Zheng Date: Sat, 5 Feb 2022 02:02:45 -0600 Subject: [PATCH 438/607] mpi/coll: add TSP-based scatter/ring-based-allgather algo for Ibcast --- src/mpi/coll/coll_algorithms.txt | 7 +++-- src/mpi/coll/cvars.txt | 1 + src/mpi/coll/ibcast/Makefile.mk | 1 + .../ibcast/ibcast_tsp_scatterv_allgatherv.c | 21 ++++++++----- .../ibcast_tsp_scatterv_ring_allgatherv.c | 31 +++++++++++++++++++ src/mpi/coll/include/csel_container.h | 4 +++ test/mpi/maint/coll_cvars.txt | 2 ++ 7 files changed, 58 insertions(+), 9 deletions(-) create mode 100644 src/mpi/coll/ibcast/ibcast_tsp_scatterv_ring_allgatherv.c diff --git a/src/mpi/coll/coll_algorithms.txt b/src/mpi/coll/coll_algorithms.txt index edca0b068af..96a86da3fe0 100644 --- a/src/mpi/coll/coll_algorithms.txt +++ b/src/mpi/coll/coll_algorithms.txt @@ -81,8 +81,11 @@ ibcast-intra: cvar_params: TREE_TYPE, TREE_KVAL, TREE_PIPELINE_CHUNK_SIZE tsp_scatterv_recexch_allgatherv func_name: scatterv_allgatherv - extra_params: scatterv_k, allgatherv_k - cvar_params: SCATTERV_KVAL, ALLGATHERV_RECEXCH_KVAL + extra_params: allgatherv_algo=MPIR_CVAR_IALLGATHERV_INTRA_ALGORITHM_tsp_recexch_doubling, scatterv_k, allgatherv_k + cvar_params: -, SCATTERV_KVAL, ALLGATHERV_RECEXCH_KVAL + tsp_scatterv_ring_allgatherv + extra_params: scatterv_k + cvar_params: SCATTERV_KVAL tsp_ring func_name: tree extra_params: tree_type=MPIR_TREE_TYPE_KARY, k=1, chunk_size diff --git a/src/mpi/coll/cvars.txt b/src/mpi/coll/cvars.txt index 74cfac7b223..afb1b4d80ef 100644 --- a/src/mpi/coll/cvars.txt +++ b/src/mpi/coll/cvars.txt @@ -299,6 +299,7 @@ cvars: sched_scatter_ring_allgather - Force Scatter Ring Allgather algorithm tsp_tree - Force Generic Transport Tree algorithm tsp_scatterv_recexch_allgatherv - Force Generic Transport Scatterv followed by Recursive Exchange Allgatherv algorithm + tsp_scatterv_ring_allgatherv - Force Generic Transport Scatterv followed by Ring Allgatherv algorithm tsp_ring - Force Generic Transport Ring algorithm - name : MPIR_CVAR_IBCAST_SCATTERV_KVAL diff --git a/src/mpi/coll/ibcast/Makefile.mk b/src/mpi/coll/ibcast/Makefile.mk index eb4d2fa5aaa..909553902f4 100644 --- a/src/mpi/coll/ibcast/Makefile.mk +++ b/src/mpi/coll/ibcast/Makefile.mk @@ -14,6 +14,7 @@ mpi_core_sources += \ src/mpi/coll/ibcast/ibcast_intra_sched_smp.c \ src/mpi/coll/ibcast/ibcast_inter_sched_flat.c \ src/mpi/coll/ibcast/ibcast_tsp_scatterv_allgatherv.c \ + src/mpi/coll/ibcast/ibcast_tsp_scatterv_ring_allgatherv.c \ src/mpi/coll/ibcast/ibcast_tsp_tree.c \ src/mpi/coll/ibcast/ibcast_utils.c diff --git a/src/mpi/coll/ibcast/ibcast_tsp_scatterv_allgatherv.c b/src/mpi/coll/ibcast/ibcast_tsp_scatterv_allgatherv.c index edb72de0852..b7ea09db27e 100644 --- a/src/mpi/coll/ibcast/ibcast_tsp_scatterv_allgatherv.c +++ b/src/mpi/coll/ibcast/ibcast_tsp_scatterv_allgatherv.c @@ -9,8 +9,9 @@ /* Routine to schedule a scatter followed by recursive exchange based broadcast */ int MPIR_TSP_Ibcast_sched_intra_scatterv_allgatherv(void *buffer, MPI_Aint count, MPI_Datatype datatype, int root, - MPIR_Comm * comm, int scatterv_k, - int allgatherv_k, MPIR_TSP_sched_t sched) + MPIR_Comm * comm, int allgatherv_algo, + int scatterv_k, int allgatherv_k, + MPIR_TSP_sched_t sched) { int mpi_errno = MPI_SUCCESS; int mpi_errno_ret ATTRIBUTE((unused)) = MPI_SUCCESS; @@ -168,13 +169,19 @@ int MPIR_TSP_Ibcast_sched_intra_scatterv_allgatherv(void *buffer, MPI_Aint count mpi_errno = MPIR_TSP_sched_fence(sched); /* wait for scatter to complete */ MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); - /* Schedule Allgatherv */ - mpi_errno = - MPIR_TSP_Iallgatherv_sched_intra_recexch(MPI_IN_PLACE, cnts[rank], MPI_BYTE, tmp_buf, cnts, - displs, MPI_BYTE, comm, 0, allgatherv_k, sched); + if (allgatherv_algo == MPIR_CVAR_IALLGATHERV_INTRA_ALGORITHM_tsp_ring) + /* Schedule Allgatherv ring */ + mpi_errno = + MPIR_TSP_Iallgatherv_sched_intra_ring(MPI_IN_PLACE, cnts[rank], MPI_BYTE, tmp_buf, + cnts, displs, MPI_BYTE, comm, sched); + else + /* Schedule Allgatherv recexch */ + mpi_errno = + MPIR_TSP_Iallgatherv_sched_intra_recexch(MPI_IN_PLACE, cnts[rank], MPI_BYTE, tmp_buf, + cnts, displs, MPI_BYTE, comm, 0, allgatherv_k, + sched); MPIR_ERR_CHECK(mpi_errno); - if (!is_contig) { if (rank != root) { mpi_errno = MPIR_TSP_sched_sink(sched, &sink_id); /* wait for allgather to complete */ diff --git a/src/mpi/coll/ibcast/ibcast_tsp_scatterv_ring_allgatherv.c b/src/mpi/coll/ibcast/ibcast_tsp_scatterv_ring_allgatherv.c new file mode 100644 index 00000000000..25016705afa --- /dev/null +++ b/src/mpi/coll/ibcast/ibcast_tsp_scatterv_ring_allgatherv.c @@ -0,0 +1,31 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpiimpl.h" +#include "algo_common.h" + +/* Routine to schedule a scatter followed by ring based broadcast */ +int MPIR_TSP_Ibcast_sched_intra_scatterv_ring_allgatherv(void *buffer, MPI_Aint count, + MPI_Datatype datatype, int root, + MPIR_Comm * comm, int scatterv_k, + MPIR_TSP_sched_t sched) +{ + int mpi_errno = MPI_SUCCESS; + + MPIR_FUNC_ENTER; + + mpi_errno = MPIR_TSP_Ibcast_sched_intra_scatterv_allgatherv(buffer, count, datatype, root, + comm, + MPIR_CVAR_IALLGATHERV_INTRA_ALGORITHM_tsp_ring, + scatterv_k, 0, sched); + MPIR_ERR_CHECK(mpi_errno); + + fn_exit: + MPIR_FUNC_EXIT; + return mpi_errno; + fn_fail: + goto fn_exit; + +} diff --git a/src/mpi/coll/include/csel_container.h b/src/mpi/coll/include/csel_container.h index e6630a19175..5ae50ac8db3 100644 --- a/src/mpi/coll/include/csel_container.h +++ b/src/mpi/coll/include/csel_container.h @@ -115,6 +115,7 @@ typedef enum { MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ibarrier_inter_sched_bcast, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ibcast_intra_tsp_tree, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ibcast_intra_tsp_scatterv_recexch_allgatherv, + MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ibcast_intra_tsp_scatterv_ring_allgatherv, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ibcast_intra_tsp_ring, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ibcast_intra_sched_binomial, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ibcast_intra_sched_scatter_recursive_doubling_allgather, @@ -287,6 +288,9 @@ typedef struct { int scatterv_k; int allgatherv_k; } intra_tsp_scatterv_recexch_allgatherv; + struct { + int scatterv_k; + } intra_tsp_scatterv_ring_allgatherv; } ibcast; struct { struct { diff --git a/test/mpi/maint/coll_cvars.txt b/test/mpi/maint/coll_cvars.txt index e478b9dfe21..8f5e951cfea 100644 --- a/test/mpi/maint/coll_cvars.txt +++ b/test/mpi/maint/coll_cvars.txt @@ -350,6 +350,8 @@ algorithms: tsp_scatterv_recexch_allgatherv .MPIR_CVAR_IBCAST_SCATTERV_KVAL=3 .MPIR_CVAR_IBCAST_ALLGATHER_RECEXCH=3 + tsp_scatterv_ring_allgatherv + .MPIR_CVAR_IBCAST_SCATTERV_KVAL=3 tsp_ring .MPIR_CVAR_IBCAST_RING_CHUNK_SIZE=4096 exscan: From 7ee90b4201d2483a341e06edec33b929aeb5ef9a Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Mon, 10 Jan 2022 11:13:59 -0600 Subject: [PATCH 439/607] submodule: Update UCX to v1.12.0 --- modules/ucx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ucx b/modules/ucx index ef0e0fe320f..60c20b0639c 160000 --- a/modules/ucx +++ b/modules/ucx @@ -1 +1 @@ -Subproject commit ef0e0fe320fb67088b8d6ca67b584af5214b8a92 +Subproject commit 60c20b0639cf349250a8655837417ec9f89399e7 From 710c8080043f58cda5eba221cc0627d22195cde8 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 9 Feb 2022 09:40:40 -0600 Subject: [PATCH 440/607] hydra: remove leftover unused variable Left over from previous commits. --- src/pm/hydra/pm/pmiserv/pmiserv_utils.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pm/hydra/pm/pmiserv/pmiserv_utils.c b/src/pm/hydra/pm/pmiserv/pmiserv_utils.c index b8ea6564fbb..292a9755149 100644 --- a/src/pm/hydra/pm/pmiserv/pmiserv_utils.c +++ b/src/pm/hydra/pm/pmiserv/pmiserv_utils.c @@ -254,7 +254,6 @@ HYD_status HYD_pmcd_pmi_fill_in_exec_launch_info(struct HYD_pg *pg) struct HYD_env *env; struct HYD_proxy *proxy; struct HYD_exec *exec; - struct HYD_node *node; struct HYD_pmcd_pmi_pg_scratch *pg_scratch; char *mapping = NULL, *map; struct HYD_string_stash stash, exec_stash; From 778933a6ab43214471fb7729d4b592e38853dd49 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 9 Feb 2022 00:00:50 -0600 Subject: [PATCH 441/607] fortran: add mismatch flags to mpif77 wrapper Remove the AC_MSG_ERROR on needing the Fortran mismatch flag and add the flag to the mpif77 wrapper. This will not affect users of modern Fortran MPI applications who are likely to use `mpifort` or `mpif90` and uses the mpi module interface. Users who use `mpif77` is likely to use `mpif.h` interface and will require the ignore-mismatch compiler flags to compile their MPI applications. By adding the extra flags to mpif77 wrapper only, we hope to strike a balance of convenience and impact. --- configure.ac | 13 +++++-------- src/env/mpifort.bash.in | 5 +++++ src/env/mpifort.sh.in | 5 +++++ test/mpi/configure.ac | 20 -------------------- 4 files changed, 15 insertions(+), 28 deletions(-) diff --git a/configure.ac b/configure.ac index 31c3f89d9c2..0df2d15d249 100644 --- a/configure.ac +++ b/configure.ac @@ -1970,15 +1970,12 @@ if test "$enable_f77" = "yes" ; then # of different types (e.g., for MPI_Send) PAC_PROG_F77_MISMATCHED_ARGS(addarg,yes) if test "X$addarg" != "X" ; then - # We could add the names of all of the MPI routines that - # accept different types. Instead, we fail cleanly. - # Some Fortran compilers allow you to turn off checking for - # mismatched arguments for *all* routines. Adding an argument - # that turns off checking for *everything* is not something that - # configure should do - if the user wants this, they can follow - # the instructions in the following error message. - AC_MSG_ERROR([The Fortran compiler $FC does not accept programs that call the same routine with arguments of different types without the option $addarg. Rerun configure with FCFLAGS=$addarg]) + # Code using mpif.h interface will likely need this flag to compile. + # Code with `use mpi` or `use mpi_f08` do not need this flag. + # Add the flag to mpif77 wrappers. + WRAPPER_EXTRA_F77_FLAGS="$addarg" fi + AC_SUBST(WRAPPER_EXTRA_F77_FLAGS) bindings="$bindings f77" AC_DEFINE(HAVE_FORTRAN_BINDING,1,[Define if Fortran is supported]) diff --git a/src/env/mpifort.bash.in b/src/env/mpifort.bash.in index 1130c57986f..ba65b384991 100644 --- a/src/env/mpifort.bash.in +++ b/src/env/mpifort.bash.in @@ -343,6 +343,11 @@ if test "@INTERLIB_DEPS@" = "no" -o "${interlib_deps}" = "no" ; then final_libs="${final_libs} @LIBS@ @WRAPPER_LIBS@" fi +extra_f77_flags="@WRAPPER_EXTRA_F77_FLAGS@" +if test "mpif77" = ${0##*/} -a -n "$extra_f77_flags" ; then + final_fcflags="${final_fcflags} $extra_f77_flags" +fi + # A temporary statement to invoke the compiler # Place the -L before any args in case there are any mpi libraries in there. # Eventually, we'll want to move this after any non-MPI implementation diff --git a/src/env/mpifort.sh.in b/src/env/mpifort.sh.in index a1e7f4dd8e1..09be8de02f6 100644 --- a/src/env/mpifort.sh.in +++ b/src/env/mpifort.sh.in @@ -360,6 +360,11 @@ if test "@INTERLIB_DEPS@" = "no" -o "${interlib_deps}" = "no" ; then final_libs="${final_libs} @LIBS@ @WRAPPER_LIBS@" fi +extra_f77_flags="@WRAPPER_EXTRA_F77_FLAGS@" +if test "mpif77" = ${0##*/} -a -n "$extra_f77_flags" ; then + final_fcflags="${final_fcflags} $extra_f77_flags" +fi + # A temporary statement to invoke the compiler # Place the -L before any args in case there are any mpi libraries in there. # Eventually, we'll want to move this after any non-MPI implementation diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index 461be3cf9db..592fff2570b 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -1034,26 +1034,6 @@ EOF AC_LANG_FORTRAN77 PAC_PROG_F77_NAME_MANGLE - # Check that the Fortran compiler will allow us to pass arguments - # of different types (e.g., for MPI_Send) - # Any strict Fortran compiler will require that the arguments be - # the same type - currently, the NAG Fortran compiler (nagfor) is known - # to enforce this. - # We could set the FFLAGS/FCFLAGS values with the option that disables - # this check (if we found one), but because that may affect other tests, - # instead we tell the user and exit. - PAC_PROG_F77_MISMATCHED_ARGS(addarg,yes) - if test "X$addarg" != "X" ; then - # We could add the names of all of the MPI routines that - # accept different types. Instead, we fail cleanly. - # Some Fortran compilers allow you to turn off checking for - # mismatched arguments for *all* routines. Adding an argument - # that turns off checking for *everything* is not something that - # configure should do - if the user wants this, they can follow - # the instructions in the following error message. - AC_MSG_ERROR([The Fortran compiler $F77 does not accept programs that call the same routine with arguments of different types without the option $addarg. Rerun configure with FFLAGS=$addarg]) - fi - # Check whether we need -lU77 to get iargc and getarg, which # are used for a few of the tests in spawn (U77 was needed with # the native compilers on HPUX. See the aclocal_f77(old).m4 file, From cae3cc77b2a06175d76949f5a057abbecef93d9c Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 9 Feb 2022 11:37:47 -0600 Subject: [PATCH 442/607] test: supply empty mtest_mpix.h When testsuite autogen is run outside mpich, supply an empty mtest_mpix.h so the testing can proceed. The header files is for mpich specific extension and will fail with non-mpich implementation anyway. The empty stub will allow strict testing to proceed. The regular mpich testing is not affected since mpich's top level autogen will always supply this file. --- test/mpi/autogen.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/mpi/autogen.sh b/test/mpi/autogen.sh index 106c2a5dafd..e6e8d768e1b 100755 --- a/test/mpi/autogen.sh +++ b/test/mpi/autogen.sh @@ -25,6 +25,18 @@ check_copy version.m4 ../../maint/version.m4 check_copy confdb ../../confdb check_copy dtpools/confdb ../../confdb +# mtest_mpix.h is generated by mpich autogen, specifically, gen_binding_c.py. +# It provides macros that replace upcoming MPI functions with MPIX prefix. +# The tests using these new functions should not be included with +# --enable-strictmpi, an option should be given when testing general MPI +# implementations. +# +# Here we supply an empty stub when this is run outside mpich. +# +if test ! -e include/mtest_mpix.h ; then + touch include/mtest_mpix.h +fi + echo "Running autoreconf in dtpools" (cd dtpools && autoreconf -ivf) From c021aaeb32adccf0a5b907c5a120f46548a10332 Mon Sep 17 00:00:00 2001 From: Gengbin Zheng Date: Wed, 12 Jan 2022 22:46:07 -0600 Subject: [PATCH 443/607] coll: tsp_auto for iallreduce Routine to select only gentran-based algorithm for iallreduce. --- src/include/mpir_coll.h | 4 + src/mpi/coll/iallreduce/Makefile.mk | 3 +- src/mpi/coll/iallreduce/iallreduce_tsp_auto.c | 165 ++++++++++++++++++ 3 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 src/mpi/coll/iallreduce/iallreduce_tsp_auto.c diff --git a/src/include/mpir_coll.h b/src/include/mpir_coll.h index 1206874c923..b1dd8256d9d 100644 --- a/src/include/mpir_coll.h +++ b/src/include/mpir_coll.h @@ -53,4 +53,8 @@ int MPIC_Waitall(int numreq, MPIR_Request * requests[], MPI_Status statuses[], int MPIR_Reduce_local(const void *inbuf, void *inoutbuf, MPI_Aint count, MPI_Datatype datatype, MPI_Op op); +/* TSP auto */ +int MPIR_TSP_Iallreduce_sched_intra_tsp_auto(const void *sendbuf, void *recvbuf, MPI_Aint count, + MPI_Datatype datatype, MPI_Op op, + MPIR_Comm * comm, MPIR_TSP_sched_t sched); #endif /* MPIR_COLL_H_INCLUDED */ diff --git a/src/mpi/coll/iallreduce/Makefile.mk b/src/mpi/coll/iallreduce/Makefile.mk index 58bbdde07bc..18767375cd1 100644 --- a/src/mpi/coll/iallreduce/Makefile.mk +++ b/src/mpi/coll/iallreduce/Makefile.mk @@ -17,4 +17,5 @@ mpi_core_sources += \ src/mpi/coll/iallreduce/iallreduce_tsp_recexch.c \ src/mpi/coll/iallreduce/iallreduce_tsp_recexch_reduce_scatter_recexch_allgatherv.c \ src/mpi/coll/iallreduce/iallreduce_tsp_ring.c \ - src/mpi/coll/iallreduce/iallreduce_tsp_tree.c + src/mpi/coll/iallreduce/iallreduce_tsp_tree.c \ + src/mpi/coll/iallreduce/iallreduce_tsp_auto.c diff --git a/src/mpi/coll/iallreduce/iallreduce_tsp_auto.c b/src/mpi/coll/iallreduce/iallreduce_tsp_auto.c new file mode 100644 index 00000000000..be266211063 --- /dev/null +++ b/src/mpi/coll/iallreduce/iallreduce_tsp_auto.c @@ -0,0 +1,165 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpiimpl.h" +#include "algo_common.h" +#include "treealgo.h" + +/* Routine to schedule a pipelined tree based allreduce */ +int MPIR_TSP_Iallreduce_sched_intra_tsp_auto(const void *sendbuf, void *recvbuf, MPI_Aint count, + MPI_Datatype datatype, MPI_Op op, + MPIR_Comm * comm, MPIR_TSP_sched_t sched) +{ + int mpi_errno = MPI_SUCCESS; + int is_commutative = MPIR_Op_is_commutative(op); + int nranks = comm->local_size; + + MPIR_Assert(comm->comm_kind == MPIR_COMM_KIND__INTRACOMM); + + MPIR_Csel_coll_sig_s coll_sig = { + .coll_type = MPIR_CSEL_COLL_TYPE__IALLREDUCE, + .comm_ptr = comm, + + .u.iallreduce.sendbuf = sendbuf, + .u.iallreduce.recvbuf = recvbuf, + .u.iallreduce.count = count, + .u.iallreduce.datatype = datatype, + .u.iallreduce.op = op, + }; + + MPII_Csel_container_s *cnt; + + switch (MPIR_CVAR_IALLREDUCE_INTRA_ALGORITHM) { + case MPIR_CVAR_IALLREDUCE_INTRA_ALGORITHM_tsp_recexch_single_buffer: + mpi_errno = + MPIR_TSP_Iallreduce_sched_intra_recexch(sendbuf, recvbuf, count, + datatype, op, comm, + MPIR_IALLREDUCE_RECEXCH_TYPE_SINGLE_BUFFER, + MPIR_CVAR_IALLREDUCE_RECEXCH_KVAL, sched); + break; + + case MPIR_CVAR_IALLREDUCE_INTRA_ALGORITHM_tsp_recexch_multiple_buffer: + mpi_errno = + MPIR_TSP_Iallreduce_sched_intra_recexch(sendbuf, recvbuf, count, + datatype, op, comm, + MPIR_IALLREDUCE_RECEXCH_TYPE_MULTIPLE_BUFFER, + MPIR_CVAR_IALLREDUCE_RECEXCH_KVAL, sched); + break; + + case MPIR_CVAR_IALLREDUCE_INTRA_ALGORITHM_tsp_tree: + /*Only knomial_1 tree supports non-commutative operations */ + MPII_COLLECTIVE_FALLBACK_CHECK(comm->rank, is_commutative || + MPIR_Iallreduce_tree_type == + MPIR_TREE_TYPE_KNOMIAL_1, mpi_errno, + "Iallreduce gentran_tree cannot be applied.\n"); + mpi_errno = + MPIR_TSP_Iallreduce_sched_intra_tree(sendbuf, recvbuf, count, datatype, op, + comm, MPIR_Iallreduce_tree_type, + MPIR_CVAR_IALLREDUCE_TREE_KVAL, + MPIR_CVAR_IALLREDUCE_TREE_PIPELINE_CHUNK_SIZE, + MPIR_CVAR_IALLREDUCE_TREE_BUFFER_PER_CHILD, + sched); + break; + + case MPIR_CVAR_IALLREDUCE_INTRA_ALGORITHM_tsp_ring: + MPII_COLLECTIVE_FALLBACK_CHECK(comm->rank, is_commutative, mpi_errno, + "Iallreduce gentran_ring cannot be applied.\n"); + mpi_errno = + MPIR_TSP_Iallreduce_sched_intra_ring(sendbuf, recvbuf, count, datatype, + op, comm, sched); + break; + case MPIR_CVAR_IALLREDUCE_INTRA_ALGORITHM_tsp_recexch_reduce_scatter_recexch_allgatherv: + /* This algorithm will work for commutative + * operations and if the count is bigger than total + * number of ranks. If it not commutative or if the + * count < nranks, MPIR_Iallreduce_sched algorithm + * will be run */ + MPII_COLLECTIVE_FALLBACK_CHECK(comm->rank, is_commutative && + count >= nranks, mpi_errno, + "Iallreduce gentran_recexch_reduce_scatter_recexch_allgatherv cannot be applied.\n"); + mpi_errno = + MPIR_TSP_Iallreduce_sched_intra_recexch_reduce_scatter_recexch_allgatherv(sendbuf, + recvbuf, + count, + datatype, + op, + comm, + MPIR_CVAR_IALLREDUCE_RECEXCH_KVAL, + sched); + break; + default: + cnt = MPIR_Csel_search(comm->csel_comm, coll_sig); + MPIR_Assert(cnt); + + switch (cnt->id) { + case MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Iallreduce_intra_tsp_recexch_single_buffer: + mpi_errno = + MPIR_TSP_Iallreduce_sched_intra_recexch(sendbuf, recvbuf, count, + datatype, op, comm, + MPIR_IALLREDUCE_RECEXCH_TYPE_SINGLE_BUFFER, + cnt->u. + iallreduce.intra_tsp_recexch_single_buffer. + k, sched); + break; + + case MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Iallreduce_intra_tsp_recexch_multiple_buffer: + mpi_errno = + MPIR_TSP_Iallreduce_sched_intra_recexch(sendbuf, recvbuf, count, + datatype, op, comm, + MPIR_IALLREDUCE_RECEXCH_TYPE_MULTIPLE_BUFFER, + cnt->u. + iallreduce.intra_tsp_recexch_single_buffer. + k, sched); + break; + + case MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Iallreduce_intra_tsp_tree: + mpi_errno = + MPIR_TSP_Iallreduce_sched_intra_tree(sendbuf, recvbuf, count, datatype, op, + comm, + cnt->u.iallreduce. + intra_tsp_tree.tree_type, + cnt->u.iallreduce.intra_tsp_tree.k, + cnt->u.iallreduce. + intra_tsp_tree.chunk_size, + cnt->u.iallreduce. + intra_tsp_tree.buffer_per_child, + sched); + break; + + case MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Iallreduce_intra_tsp_ring: + mpi_errno = + MPIR_TSP_Iallreduce_sched_intra_ring(sendbuf, recvbuf, count, datatype, op, + comm, sched); + break; + + case MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Iallreduce_intra_tsp_recexch_reduce_scatter_recexch_allgatherv: + mpi_errno = + MPIR_TSP_Iallreduce_sched_intra_recexch_reduce_scatter_recexch_allgatherv + (sendbuf, recvbuf, count, datatype, op, comm, + cnt->u.iallreduce.intra_tsp_recexch_reduce_scatter_recexch_allgatherv.k, + sched); + break; + + default: + /* Replace this call with MPIR_Assert(0) when json files have gentran algos */ + goto fallback; + break; + } + } + + MPIR_ERR_CHECK(mpi_errno); + goto fn_exit; + + fallback: + mpi_errno = + MPIR_TSP_Iallreduce_sched_intra_recexch(sendbuf, recvbuf, count, + datatype, op, comm, + MPIR_IALLREDUCE_RECEXCH_TYPE_MULTIPLE_BUFFER, + MPIR_CVAR_IALLREDUCE_RECEXCH_KVAL, sched); + fn_exit: + return mpi_errno; + fn_fail: + goto fn_exit; +} From 95c84212eb54d9b3d26862098af6da62719233ae Mon Sep 17 00:00:00 2001 From: Gengbin Zheng Date: Wed, 12 Jan 2022 22:52:26 -0600 Subject: [PATCH 444/607] coll: tsp_auto for ibcast Routine to select only gentran-based algorithm for ibcast. --- src/include/mpir_coll.h | 2 + src/mpi/coll/ibcast/Makefile.mk | 1 + src/mpi/coll/ibcast/ibcast_tsp_auto.c | 159 ++++++++++++++++++++++++++ 3 files changed, 162 insertions(+) create mode 100644 src/mpi/coll/ibcast/ibcast_tsp_auto.c diff --git a/src/include/mpir_coll.h b/src/include/mpir_coll.h index b1dd8256d9d..61f7c105b51 100644 --- a/src/include/mpir_coll.h +++ b/src/include/mpir_coll.h @@ -57,4 +57,6 @@ int MPIR_Reduce_local(const void *inbuf, void *inoutbuf, MPI_Aint count, MPI_Dat int MPIR_TSP_Iallreduce_sched_intra_tsp_auto(const void *sendbuf, void *recvbuf, MPI_Aint count, MPI_Datatype datatype, MPI_Op op, MPIR_Comm * comm, MPIR_TSP_sched_t sched); +int MPIR_TSP_Ibcast_sched_intra_tsp_auto(void *buffer, int count, MPI_Datatype datatype, int root, + MPIR_Comm * comm_ptr, MPIR_TSP_sched_t sched); #endif /* MPIR_COLL_H_INCLUDED */ diff --git a/src/mpi/coll/ibcast/Makefile.mk b/src/mpi/coll/ibcast/Makefile.mk index 909553902f4..11c9cdf492d 100644 --- a/src/mpi/coll/ibcast/Makefile.mk +++ b/src/mpi/coll/ibcast/Makefile.mk @@ -16,6 +16,7 @@ mpi_core_sources += \ src/mpi/coll/ibcast/ibcast_tsp_scatterv_allgatherv.c \ src/mpi/coll/ibcast/ibcast_tsp_scatterv_ring_allgatherv.c \ src/mpi/coll/ibcast/ibcast_tsp_tree.c \ + src/mpi/coll/ibcast/ibcast_tsp_auto.c \ src/mpi/coll/ibcast/ibcast_utils.c noinst_HEADERS += \ diff --git a/src/mpi/coll/ibcast/ibcast_tsp_auto.c b/src/mpi/coll/ibcast/ibcast_tsp_auto.c new file mode 100644 index 00000000000..bcf9a319d6e --- /dev/null +++ b/src/mpi/coll/ibcast/ibcast_tsp_auto.c @@ -0,0 +1,159 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpiimpl.h" +#include "algo_common.h" +#include "treealgo.h" + +/* Provides a "flat" broadcast that doesn't know anything about + * hierarchy. It will choose between several different algorithms + * based on the given parameters. */ +/* Remove this function when gentran algos are in json file */ +static int MPIR_Ibcast_sched_intra_tsp_flat_auto(void *buffer, int count, MPI_Datatype datatype, + int root, MPIR_Comm * comm_ptr, + MPIR_TSP_sched_t sched) +{ + int mpi_errno = MPI_SUCCESS; + int comm_size; + MPI_Aint type_size, nbytes; + int tree_type = MPIR_TREE_TYPE_KNOMIAL_1; + int radix = 2, scatterv_k = 2, allgatherv_k = 2, block_size = 0; + + MPIR_Assert(comm_ptr->comm_kind == MPIR_COMM_KIND__INTRACOMM); + + comm_size = comm_ptr->local_size; + MPIR_Datatype_get_size_macro(datatype, type_size); + nbytes = type_size * count; + + /* simplistic implementation for now */ + if ((nbytes < MPIR_CVAR_BCAST_SHORT_MSG_SIZE) || (comm_size < MPIR_CVAR_BCAST_MIN_PROCS)) { + /* gentran tree with knomial tree type, radix 2 and pipeline block size 0 */ + mpi_errno = MPIR_TSP_Ibcast_sched_intra_tree(buffer, count, datatype, root, comm_ptr, + tree_type, radix, block_size, sched); + } else { + /* gentran scatterv recexch allgather with radix 2 */ + mpi_errno = + MPIR_TSP_Ibcast_sched_intra_scatterv_allgatherv(buffer, count, datatype, root, + comm_ptr, + MPIR_CVAR_IALLGATHERV_INTRA_ALGORITHM_tsp_recexch_doubling, + scatterv_k, allgatherv_k, sched); + } + if (mpi_errno) + MPIR_ERR_POP(mpi_errno); + + fn_exit: + return mpi_errno; + fn_fail: + goto fn_exit; +} + +/* sched version of CVAR and json based collective selection. Meant only for gentran scheduler */ +int MPIR_TSP_Ibcast_sched_intra_tsp_auto(void *buffer, int count, MPI_Datatype datatype, int root, + MPIR_Comm * comm_ptr, MPIR_TSP_sched_t sched) +{ + int mpi_errno = MPI_SUCCESS; + + MPIR_Csel_coll_sig_s coll_sig = { + .coll_type = MPIR_CSEL_COLL_TYPE__IBCAST, + .comm_ptr = comm_ptr, + + .u.ibcast.buffer = buffer, + .u.ibcast.count = count, + .u.ibcast.datatype = datatype, + .u.ibcast.root = root, + }; + MPII_Csel_container_s *cnt; + + MPIR_Assert(comm_ptr->comm_kind == MPIR_COMM_KIND__INTRACOMM); + + switch (MPIR_CVAR_IBCAST_INTRA_ALGORITHM) { + case MPIR_CVAR_IBCAST_INTRA_ALGORITHM_tsp_tree: + mpi_errno = + MPIR_TSP_Ibcast_sched_intra_tree(buffer, count, datatype, root, comm_ptr, + MPIR_Ibcast_tree_type, + MPIR_CVAR_IBCAST_TREE_KVAL, + MPIR_CVAR_IBCAST_TREE_PIPELINE_CHUNK_SIZE, sched); + break; + + case MPIR_CVAR_IBCAST_INTRA_ALGORITHM_tsp_scatterv_recexch_allgatherv: + mpi_errno = + MPIR_TSP_Ibcast_sched_intra_scatterv_allgatherv(buffer, count, datatype, + root, comm_ptr, + MPIR_CVAR_IALLGATHERV_INTRA_ALGORITHM_tsp_recexch_doubling, + MPIR_CVAR_IBCAST_SCATTERV_KVAL, + MPIR_CVAR_IBCAST_ALLGATHERV_RECEXCH_KVAL, + sched); + break; + + case MPIR_CVAR_IBCAST_INTRA_ALGORITHM_tsp_scatterv_ring_allgatherv: + mpi_errno = + MPIR_TSP_Ibcast_sched_intra_scatterv_ring_allgatherv(buffer, count, datatype, + root, comm_ptr, 1, sched); + break; + + case MPIR_CVAR_IBCAST_INTRA_ALGORITHM_tsp_ring: + mpi_errno = + MPIR_TSP_Ibcast_sched_intra_tree(buffer, count, datatype, root, comm_ptr, + MPIR_TREE_TYPE_KARY, 1, + MPIR_CVAR_IBCAST_RING_CHUNK_SIZE, sched); + break; + + default: + cnt = MPIR_Csel_search(comm_ptr->csel_comm, coll_sig); + MPIR_Assert(cnt); + + switch (cnt->id) { + case MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ibcast_intra_tsp_tree: + mpi_errno = + MPIR_TSP_Ibcast_sched_intra_tree(buffer, count, datatype, root, comm_ptr, + cnt->u.ibcast.intra_tsp_tree.tree_type, + cnt->u.ibcast.intra_tsp_tree.k, + cnt->u.ibcast.intra_tsp_tree.chunk_size, + sched); + break; + case MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ibcast_intra_tsp_scatterv_recexch_allgatherv: + mpi_errno = + MPIR_TSP_Ibcast_sched_intra_scatterv_allgatherv(buffer, count, datatype, + root, comm_ptr, + MPIR_CVAR_IALLGATHERV_INTRA_ALGORITHM_tsp_recexch_doubling, + cnt->u. + ibcast.intra_tsp_scatterv_recexch_allgatherv.scatterv_k, + cnt->u. + ibcast.intra_tsp_scatterv_recexch_allgatherv.allgatherv_k, + sched); + break; + + case MPIR_CVAR_IBCAST_INTRA_ALGORITHM_tsp_scatterv_ring_allgatherv: + mpi_errno = + MPIR_TSP_Ibcast_sched_intra_scatterv_ring_allgatherv(buffer, count, + datatype, root, + comm_ptr, 1, sched); + break; + + case MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ibcast_intra_tsp_ring: + mpi_errno = + MPIR_TSP_Ibcast_sched_intra_tree(buffer, count, datatype, root, comm_ptr, + MPIR_TREE_TYPE_KARY, 1, + cnt->u.ibcast.intra_tsp_tree.chunk_size, + sched); + break; + default: + /* Replace this call with MPIR_Assert(0) when json files have gentran algos */ + goto fallback; + break; + } + } + MPIR_ERR_CHECK(mpi_errno); + goto fn_exit; + + fallback: + mpi_errno = MPIR_Ibcast_sched_intra_tsp_flat_auto(buffer, count, datatype, root, + comm_ptr, sched); + + fn_exit: + return mpi_errno; + fn_fail: + goto fn_exit; +} From f24d22a4a3695d7d63ee8c4644ecc6c864784f59 Mon Sep 17 00:00:00 2001 From: Gengbin Zheng Date: Wed, 12 Jan 2022 22:54:37 -0600 Subject: [PATCH 445/607] coll: tsp_auto for ibarrier Routine to select only gentran-based algorithm for ibarrier. --- src/include/mpir_coll.h | 1 + src/mpi/coll/ibarrier/Makefile.mk | 3 +- src/mpi/coll/ibarrier/ibarrier_tsp_auto.c | 77 +++++++++++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 src/mpi/coll/ibarrier/ibarrier_tsp_auto.c diff --git a/src/include/mpir_coll.h b/src/include/mpir_coll.h index 61f7c105b51..9031cfc37f4 100644 --- a/src/include/mpir_coll.h +++ b/src/include/mpir_coll.h @@ -59,4 +59,5 @@ int MPIR_TSP_Iallreduce_sched_intra_tsp_auto(const void *sendbuf, void *recvbuf, MPIR_Comm * comm, MPIR_TSP_sched_t sched); int MPIR_TSP_Ibcast_sched_intra_tsp_auto(void *buffer, int count, MPI_Datatype datatype, int root, MPIR_Comm * comm_ptr, MPIR_TSP_sched_t sched); +int MPIR_TSP_Ibarrier_sched_intra_tsp_auto(MPIR_Comm * comm, MPIR_TSP_sched_t sched); #endif /* MPIR_COLL_H_INCLUDED */ diff --git a/src/mpi/coll/ibarrier/Makefile.mk b/src/mpi/coll/ibarrier/Makefile.mk index 93e9c5b5e97..a5d08f4ac34 100644 --- a/src/mpi/coll/ibarrier/Makefile.mk +++ b/src/mpi/coll/ibarrier/Makefile.mk @@ -11,4 +11,5 @@ mpi_core_sources += \ src/mpi/coll/ibarrier/ibarrier_intra_sched_recursive_doubling.c \ src/mpi/coll/ibarrier/ibarrier_inter_sched_bcast.c \ src/mpi/coll/ibarrier/ibarrier_intra_tsp_recexch.c \ - src/mpi/coll/ibarrier/ibarrier_intra_tsp_dissem.c + src/mpi/coll/ibarrier/ibarrier_intra_tsp_dissem.c \ + src/mpi/coll/ibarrier/ibarrier_tsp_auto.c diff --git a/src/mpi/coll/ibarrier/ibarrier_tsp_auto.c b/src/mpi/coll/ibarrier/ibarrier_tsp_auto.c new file mode 100644 index 00000000000..d98497b9ff0 --- /dev/null +++ b/src/mpi/coll/ibarrier/ibarrier_tsp_auto.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpiimpl.h" + +/* sched version of CVAR and json based collective selection. Meant only for gentran scheduler */ +int MPIR_TSP_Ibarrier_sched_intra_tsp_auto(MPIR_Comm * comm, MPIR_TSP_sched_t sched) +{ + int mpi_errno = MPI_SUCCESS; + + MPIR_Csel_coll_sig_s coll_sig = { + .coll_type = MPIR_CSEL_COLL_TYPE__IBARRIER, + .comm_ptr = comm, + }; + MPII_Csel_container_s *cnt; + void *recvbuf = NULL; + + MPIR_Assert(comm->comm_kind == MPIR_COMM_KIND__INTRACOMM); + + switch (MPIR_CVAR_IBARRIER_INTRA_ALGORITHM) { + case MPIR_CVAR_IBARRIER_INTRA_ALGORITHM_tsp_recexch: + mpi_errno = + MPIR_TSP_Iallreduce_sched_intra_recexch(MPI_IN_PLACE, recvbuf, 0, MPI_BYTE, MPI_SUM, + comm, + MPIR_IALLREDUCE_RECEXCH_TYPE_MULTIPLE_BUFFER, + MPIR_CVAR_IBARRIER_RECEXCH_KVAL, sched); + break; + + case MPIR_CVAR_IBARRIER_INTRA_ALGORITHM_tsp_k_dissemination: + mpi_errno = + MPIR_TSP_Ibarrier_sched_intra_k_dissemination(comm, MPIR_CVAR_IBARRIER_DISSEM_KVAL, + sched); + break; + + default: + cnt = MPIR_Csel_search(comm->csel_comm, coll_sig); + MPIR_Assert(cnt); + + switch (cnt->id) { + case MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ibarrier_intra_tsp_recexch: + mpi_errno = + MPIR_TSP_Iallreduce_sched_intra_recexch(MPI_IN_PLACE, recvbuf, 0, MPI_BYTE, + MPI_SUM, comm, + MPIR_IALLREDUCE_RECEXCH_TYPE_MULTIPLE_BUFFER, + cnt->u.ibarrier.intra_tsp_recexch.k, + sched); + break; + + case MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ibarrier_intra_tsp_k_dissemination: + mpi_errno = + MPIR_TSP_Ibarrier_sched_intra_k_dissemination(comm, + cnt->u. + ibarrier.intra_tsp_k_dissemination. + k, sched); + break; + + default: + /* Replace this call with MPIR_Assert(0) when json files have gentran algos */ + goto fallback; + break; + } + } + + MPIR_ERR_CHECK(mpi_errno); + goto fn_exit; + + fallback: + mpi_errno = MPIR_TSP_Iallreduce_sched_intra_recexch(MPI_IN_PLACE, NULL, 0, + MPI_BYTE, MPI_SUM, comm, 0, 2, sched); + + fn_exit: + return mpi_errno; + fn_fail: + goto fn_exit; +} From f7982c5adfa0f37df48f3eae2729cbc4f15a6271 Mon Sep 17 00:00:00 2001 From: Gengbin Zheng Date: Wed, 12 Jan 2022 23:00:43 -0600 Subject: [PATCH 446/607] coll: tsp_auto for ireduce Routine to select only gentran-based algorithm for ireduce. --- src/include/mpir_coll.h | 3 + src/mpi/coll/ireduce/Makefile.mk | 3 +- src/mpi/coll/ireduce/ireduce_tsp_auto.c | 131 ++++++++++++++++++++++++ 3 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 src/mpi/coll/ireduce/ireduce_tsp_auto.c diff --git a/src/include/mpir_coll.h b/src/include/mpir_coll.h index 9031cfc37f4..9674c234dd8 100644 --- a/src/include/mpir_coll.h +++ b/src/include/mpir_coll.h @@ -60,4 +60,7 @@ int MPIR_TSP_Iallreduce_sched_intra_tsp_auto(const void *sendbuf, void *recvbuf, int MPIR_TSP_Ibcast_sched_intra_tsp_auto(void *buffer, int count, MPI_Datatype datatype, int root, MPIR_Comm * comm_ptr, MPIR_TSP_sched_t sched); int MPIR_TSP_Ibarrier_sched_intra_tsp_auto(MPIR_Comm * comm, MPIR_TSP_sched_t sched); +int MPIR_TSP_Ireduce_sched_intra_tsp_auto(const void *sendbuf, void *recvbuf, int count, + MPI_Datatype datatype, MPI_Op op, int root, + MPIR_Comm * comm_ptr, MPIR_TSP_sched_t sched); #endif /* MPIR_COLL_H_INCLUDED */ diff --git a/src/mpi/coll/ireduce/Makefile.mk b/src/mpi/coll/ireduce/Makefile.mk index 591808c89b0..9e6fc9466b8 100644 --- a/src/mpi/coll/ireduce/Makefile.mk +++ b/src/mpi/coll/ireduce/Makefile.mk @@ -12,4 +12,5 @@ mpi_core_sources += \ src/mpi/coll/ireduce/ireduce_intra_sched_reduce_scatter_gather.c \ src/mpi/coll/ireduce/ireduce_intra_sched_smp.c \ src/mpi/coll/ireduce/ireduce_inter_sched_local_reduce_remote_send.c \ - src/mpi/coll/ireduce/ireduce_tsp_tree.c + src/mpi/coll/ireduce/ireduce_tsp_tree.c \ + src/mpi/coll/ireduce/ireduce_tsp_auto.c diff --git a/src/mpi/coll/ireduce/ireduce_tsp_auto.c b/src/mpi/coll/ireduce/ireduce_tsp_auto.c new file mode 100644 index 00000000000..f9f24a388ea --- /dev/null +++ b/src/mpi/coll/ireduce/ireduce_tsp_auto.c @@ -0,0 +1,131 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpiimpl.h" + +/* Provides a "flat" reduce that doesn't know anything about + * hierarchy. It will choose between several different algorithms + * based on the given parameters. */ +/* Remove this function when gentran algos are in json file */ +static int MPIR_Ireduce_sched_intra_tsp_flat_auto(const void *sendbuf, void *recvbuf, int count, + MPI_Datatype datatype, MPI_Op op, int root, + MPIR_Comm * comm_ptr, MPIR_TSP_sched_t sched) +{ + int mpi_errno = MPI_SUCCESS; + int tree_type = MPIR_TREE_TYPE_KNOMIAL_1; + int radix = 2, block_size = 0, buffer_per_child = 0; + + MPIR_Assert(comm_ptr->comm_kind == MPIR_COMM_KIND__INTRACOMM); + + /* Note: Use gentran_tree for short msg and gentran_reduce_scatter_gather for long msg + * when we have gentran_reduce_scatter_gather implemented. For now all msg size use + * gentran_tree algo */ + /* gentran tree with knomial tree type, radix 2 and pipeline block size 0 */ + mpi_errno = MPIR_TSP_Ireduce_sched_intra_tree(sendbuf, recvbuf, count, + datatype, op, root, comm_ptr, + tree_type, radix, block_size, + buffer_per_child, sched); + if (mpi_errno) + MPIR_ERR_POP(mpi_errno); + + fn_exit: + return mpi_errno; + fn_fail: + goto fn_exit; +} + +/* sched version of CVAR and json based collective selection. Meant only for gentran scheduler */ +int MPIR_TSP_Ireduce_sched_intra_tsp_auto(const void *sendbuf, void *recvbuf, int count, + MPI_Datatype datatype, MPI_Op op, int root, + MPIR_Comm * comm_ptr, MPIR_TSP_sched_t sched) +{ + int mpi_errno = MPI_SUCCESS; + + MPIR_Csel_coll_sig_s coll_sig = { + .coll_type = MPIR_CSEL_COLL_TYPE__IREDUCE, + .comm_ptr = comm_ptr, + + .u.ireduce.sendbuf = sendbuf, + .u.ireduce.recvbuf = recvbuf, + .u.ireduce.count = count, + .u.ireduce.datatype = datatype, + .u.ireduce.op = op, + .u.ireduce.root = root, + }; + MPII_Csel_container_s *cnt; + + MPIR_Assert(comm_ptr->comm_kind == MPIR_COMM_KIND__INTRACOMM); + + switch (MPIR_CVAR_IREDUCE_INTRA_ALGORITHM) { + case MPIR_CVAR_IREDUCE_INTRA_ALGORITHM_tsp_tree: + /*Only knomial_1 tree supports non-commutative operations */ + MPII_COLLECTIVE_FALLBACK_CHECK(comm_ptr->rank, MPIR_Op_is_commutative(op) || + MPIR_Ireduce_tree_type == MPIR_TREE_TYPE_KNOMIAL_1, + mpi_errno, "Ireduce gentran_tree cannot be applied.\n"); + mpi_errno = + MPIR_TSP_Ireduce_sched_intra_tree(sendbuf, recvbuf, count, datatype, op, root, + comm_ptr, MPIR_Ireduce_tree_type, + MPIR_CVAR_IREDUCE_TREE_KVAL, + MPIR_CVAR_IREDUCE_TREE_PIPELINE_CHUNK_SIZE, + MPIR_CVAR_IREDUCE_TREE_BUFFER_PER_CHILD, sched); + break; + + case MPIR_CVAR_IREDUCE_INTRA_ALGORITHM_tsp_ring: + mpi_errno = + MPIR_TSP_Ireduce_sched_intra_tree(sendbuf, recvbuf, count, datatype, op, root, + comm_ptr, MPIR_TREE_TYPE_KARY, 1, + MPIR_CVAR_IREDUCE_RING_CHUNK_SIZE, + MPIR_CVAR_IREDUCE_TREE_BUFFER_PER_CHILD, sched); + break; + + default: + cnt = MPIR_Csel_search(comm_ptr->csel_comm, coll_sig); + MPIR_Assert(cnt); + + switch (cnt->id) { + case MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ireduce_intra_tsp_tree: + mpi_errno = + MPIR_TSP_Ireduce_sched_intra_tree(sendbuf, recvbuf, count, datatype, op, + root, comm_ptr, + cnt->u.ireduce.intra_tsp_tree.tree_type, + cnt->u.ireduce.intra_tsp_tree.k, + cnt->u.ireduce.intra_tsp_tree.chunk_size, + cnt->u.ireduce. + intra_tsp_tree.buffer_per_child, sched); + break; + + case MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Ireduce_intra_tsp_ring: + mpi_errno = + MPIR_TSP_Ireduce_sched_intra_tree(sendbuf, recvbuf, count, datatype, op, + root, comm_ptr, MPIR_TREE_TYPE_KARY, 1, + cnt->u.ireduce.intra_tsp_ring.chunk_size, + cnt->u.ireduce. + intra_tsp_ring.buffer_per_child, sched); + break; + + default: + /* Replace this call with MPIR_Assert(0) when json files have gentran algos */ + mpi_errno = + MPIR_Ireduce_sched_intra_tsp_flat_auto(sendbuf, recvbuf, count, + datatype, op, root, comm_ptr, sched); + break; + } + } + MPIR_ERR_CHECK(mpi_errno); + goto fn_exit; + + fallback: + mpi_errno = + MPIR_TSP_Ireduce_sched_intra_tree(sendbuf, recvbuf, count, datatype, op, root, + comm_ptr, MPIR_TREE_TYPE_KARY, 1, + MPIR_CVAR_IREDUCE_RING_CHUNK_SIZE, + MPIR_CVAR_IREDUCE_TREE_BUFFER_PER_CHILD, sched); + + + fn_exit: + return mpi_errno; + fn_fail: + goto fn_exit; +} From 7602a36bc85cc35a15f160e223afad251d147ed0 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Mon, 10 Jan 2022 14:45:37 -0600 Subject: [PATCH 447/607] debugger: Use list macros for sendq add/remove --- src/mpi/debugger/dbginit.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/mpi/debugger/dbginit.c b/src/mpi/debugger/dbginit.c index 2bf5f601829..a944a4ecbfb 100644 --- a/src/mpi/debugger/dbginit.c +++ b/src/mpi/debugger/dbginit.c @@ -396,11 +396,7 @@ void MPII_Sendq_remember(MPIR_Request * req, int rank, int tag, int context_id) p->tag = tag; p->rank = rank; p->context_id = context_id; - p->next = MPIR_Sendq_head; - p->prev = NULL; - MPIR_Sendq_head = p; - if (p->next) - p->next->prev = p; + DL_PREPEND(MPIR_Sendq_head, p); if (MPIR_REQUEST_KIND__SEND == req->kind) req->u.send.dbg_next = p; else if (MPIR_REQUEST_KIND__PREQUEST_SEND == req->kind) @@ -428,13 +424,7 @@ void MPII_Sendq_forget(MPIR_Request * req) MPID_THREAD_CS_EXIT(POBJ, lock); return; } - prev = p->prev; - if (prev != NULL) - prev->next = p->next; - else - MPIR_Sendq_head = p->next; - if (p->next != NULL) - p->next->prev = prev; + DL_DELETE(MPIR_Sendq_head, p); /* Return this element to the pool */ p->next = pool; pool = p; From 44f0f7d8fb7a96c925977f62cbbebad1b4951554 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Mon, 10 Jan 2022 14:50:22 -0600 Subject: [PATCH 448/607] debugger: Rename debug queue entry pointer Send requests contain a pointer to a parallel entry in the send queue debugging list. It is misleading to call this entry "dbg_next" since it refers to the request itself. Note that if the send queue debugging code were to search for the request in the debug list, this field would not be necessary to have in the MPIR_Request. --- src/include/mpir_debugger.h | 2 +- src/include/mpir_request.h | 4 ++-- src/mpi/debugger/dbginit.c | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/include/mpir_debugger.h b/src/include/mpir_debugger.h index 869864ea56f..4240b2b6fad 100644 --- a/src/include/mpir_debugger.h +++ b/src/include/mpir_debugger.h @@ -24,7 +24,7 @@ void MPII_CommL_forget(MPIR_Comm *); #define MPII_SENDQ_FORGET(_a) MPII_Sendq_forget(_a) #define MPII_COMML_REMEMBER(_a) MPII_CommL_remember(_a) #define MPII_COMML_FORGET(_a) MPII_CommL_forget(_a) -#define MPII_REQUEST_CLEAR_DBG(_r) ((_r)->u.send.dbg_next = NULL) +#define MPII_REQUEST_CLEAR_DBG(_r) ((_r)->u.send.dbg = NULL) #else static inline void MPII_Wait_for_debugger(void) { diff --git a/src/include/mpir_request.h b/src/include/mpir_request.h index d3dc06edc58..3b5e9d10917 100644 --- a/src/include/mpir_request.h +++ b/src/include/mpir_request.h @@ -206,12 +206,12 @@ struct MPIR_Request { } nbc; /* kind : MPIR_REQUEST_KIND__COLL */ #if defined HAVE_DEBUGGER_SUPPORT struct { - struct MPIR_Sendq *dbg_next; + struct MPIR_Sendq *dbg; } send; /* kind : MPID_REQUEST_SEND */ #endif /* HAVE_DEBUGGER_SUPPORT */ struct { #if defined HAVE_DEBUGGER_SUPPORT - struct MPIR_Sendq *dbg_next; + struct MPIR_Sendq *dbg; #endif /* HAVE_DEBUGGER_SUPPORT */ /* Persistent requests have their own "real" requests */ struct MPIR_Request *real_request; diff --git a/src/mpi/debugger/dbginit.c b/src/mpi/debugger/dbginit.c index a944a4ecbfb..2172ff92f2d 100644 --- a/src/mpi/debugger/dbginit.c +++ b/src/mpi/debugger/dbginit.c @@ -386,9 +386,9 @@ void MPII_Sendq_remember(MPIR_Request * req, int rank, int tag, int context_id) if (!p) { /* Just ignore it */ if (MPIR_REQUEST_KIND__SEND == req->kind) - req->u.send.dbg_next = NULL; + req->u.send.dbg = NULL; else if (MPIR_REQUEST_KIND__PREQUEST_SEND == req->kind) - req->u.persist.dbg_next = NULL; + req->u.persist.dbg = NULL; goto fn_exit; } } @@ -398,9 +398,9 @@ void MPII_Sendq_remember(MPIR_Request * req, int rank, int tag, int context_id) p->context_id = context_id; DL_PREPEND(MPIR_Sendq_head, p); if (MPIR_REQUEST_KIND__SEND == req->kind) - req->u.send.dbg_next = p; + req->u.send.dbg = p; else if (MPIR_REQUEST_KIND__PREQUEST_SEND == req->kind) - req->u.persist.dbg_next = p; + req->u.persist.dbg = p; fn_exit: MPID_THREAD_CS_EXIT(VCI, lock); MPID_THREAD_CS_EXIT(POBJ, lock); @@ -415,9 +415,9 @@ void MPII_Sendq_forget(MPIR_Request * req) MPID_THREAD_CS_ENTER(VCI, lock); MPID_THREAD_CS_ENTER(POBJ, lock); if (MPIR_REQUEST_KIND__SEND == req->kind) - p = req->u.send.dbg_next; + p = req->u.send.dbg; else if (MPIR_REQUEST_KIND__PREQUEST_SEND == req->kind) - p = req->u.persist.dbg_next; + p = req->u.persist.dbg; if (!p) { /* Just ignore it */ MPID_THREAD_CS_EXIT(VCI, lock); From e73ab195d556b955a7abf4fe79feeb7cb0183480 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Mon, 10 Jan 2022 15:08:19 -0600 Subject: [PATCH 449/607] debugger: Fix sendq pointer init for persistent requests Persistent send requests were not initializing the debug queue entry, meaning a bad value could be stored. --- src/include/mpir_debugger.h | 10 +++++++++- src/include/mpir_request.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/include/mpir_debugger.h b/src/include/mpir_debugger.h index 4240b2b6fad..fcc91da1701 100644 --- a/src/include/mpir_debugger.h +++ b/src/include/mpir_debugger.h @@ -24,7 +24,15 @@ void MPII_CommL_forget(MPIR_Comm *); #define MPII_SENDQ_FORGET(_a) MPII_Sendq_forget(_a) #define MPII_COMML_REMEMBER(_a) MPII_CommL_remember(_a) #define MPII_COMML_FORGET(_a) MPII_CommL_forget(_a) -#define MPII_REQUEST_CLEAR_DBG(_r) ((_r)->u.send.dbg = NULL) +#define MPII_REQUEST_CLEAR_DBG(_r) \ + if ((_r)->kind == MPIR_REQUEST_KIND__SEND) { \ + ((_r)->u.send.dbg = NULL); \ + } else if ((_r)->kind == MPIR_REQUEST_KIND__PREQUEST_SEND) { \ + ((_r)->u.persist.dbg = NULL); \ + } else { \ + MPIR_Assert(0); \ + } + #else static inline void MPII_Wait_for_debugger(void) { diff --git a/src/include/mpir_request.h b/src/include/mpir_request.h index 3b5e9d10917..ca0b36e6ff9 100644 --- a/src/include/mpir_request.h +++ b/src/include/mpir_request.h @@ -422,6 +422,7 @@ static inline MPIR_Request *MPIR_Request_create_from_pool(MPIR_Request_kind_t ki switch (kind) { case MPIR_REQUEST_KIND__SEND: + case MPIR_REQUEST_KIND__PREQUEST_SEND: MPII_REQUEST_CLEAR_DBG(req); break; case MPIR_REQUEST_KIND__COLL: From af75e49d1879bc59c6e18721b79713ca60fc0fc9 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Mon, 10 Jan 2022 15:13:07 -0600 Subject: [PATCH 450/607] request: Update comments indicating request kind Update comments to reflect the current kind values for requests. --- src/include/mpir_request.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/include/mpir_request.h b/src/include/mpir_request.h index ca0b36e6ff9..9ab81ae731f 100644 --- a/src/include/mpir_request.h +++ b/src/include/mpir_request.h @@ -207,7 +207,7 @@ struct MPIR_Request { #if defined HAVE_DEBUGGER_SUPPORT struct { struct MPIR_Sendq *dbg; - } send; /* kind : MPID_REQUEST_SEND */ + } send; /* kind : MPIR_REQUEST_KIND__SEND */ #endif /* HAVE_DEBUGGER_SUPPORT */ struct { #if defined HAVE_DEBUGGER_SUPPORT @@ -216,7 +216,7 @@ struct MPIR_Request { /* Persistent requests have their own "real" requests */ struct MPIR_Request *real_request; MPIR_TSP_sched_t sched; - } persist; /* kind : MPID_PREQUEST_SEND or MPID_PREQUEST_RECV */ + } persist; /* kind : MPIR_REQUEST_KIND__PREQUEST_SEND or MPIR_REQUEST_KIND__PREQUEST_RECV */ struct { struct MPIR_Request *real_request; enum MPIR_sched_type sched_type; From e2e78aca9a7f5d42e688a35813eac4eda691b036 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Wed, 2 Feb 2022 10:33:58 -0600 Subject: [PATCH 451/607] debugger: Remove send request from debugq when freeing As long as a request exists, show it in the debug queue. Only when its freed should it be removed. --- src/include/mpir_request.h | 9 ++++----- src/mpi/request/mpir_request.c | 8 +------- src/mpi/request/request_impl.c | 2 -- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/include/mpir_request.h b/src/include/mpir_request.h index 9ab81ae731f..aff90929b2f 100644 --- a/src/include/mpir_request.h +++ b/src/include/mpir_request.h @@ -554,6 +554,10 @@ static inline void MPIR_Request_free_with_safety(MPIR_Request * req, int need_sa MPID_Request_destroy_hook(req); + if (req->kind == MPIR_REQUEST_KIND__SEND) { + MPII_SENDQ_FORGET(req); + } + if (need_safety) { MPID_THREAD_CS_ENTER(POBJ, MPIR_THREAD_POBJ_HANDLE_MUTEX); MPIR_Handle_obj_free_unsafe(&MPIR_Request_mem[pool], req, /* not info */ FALSE); @@ -609,11 +613,6 @@ MPL_STATIC_INLINE_PREFIX int MPIR_Request_completion_processing_fastpath(MPI_Req MPIR_Assert(request_ptr->kind == MPIR_REQUEST_KIND__SEND || request_ptr->kind == MPIR_REQUEST_KIND__RECV); - if (request_ptr->kind == MPIR_REQUEST_KIND__SEND) { - /* FIXME: are Ibsend requests added to the send queue? */ - MPII_SENDQ_FORGET(request_ptr); - } - /* the completion path for SEND and RECV is the same at this time, modulo * the SENDQ hook above */ mpi_errno = request_ptr->status.MPI_ERROR; diff --git a/src/mpi/request/mpir_request.c b/src/mpi/request/mpir_request.c index c6c3df52224..b80f73610cb 100644 --- a/src/mpi/request/mpir_request.c +++ b/src/mpi/request/mpir_request.c @@ -56,12 +56,7 @@ void MPII_init_request(void) MPIR_Status_set_procnull(&req->status); } -/* Complete a request, saving the status data if necessary. - If debugger information is being provided for pending (user-initiated) - send operations, the macros MPII_SENDQ_FORGET will be defined to - call the routine MPII_Sendq_forget; otherwise that macro will be a no-op. - The implementation of the MPIR_Sendq_xxx is in src/mpi/debugger/dbginit.c . -*/ +/* Complete a request, saving the status data if necessary. */ int MPIR_Request_completion_processing(MPIR_Request * request_ptr, MPI_Status * status) { int mpi_errno = MPI_SUCCESS; @@ -72,7 +67,6 @@ int MPIR_Request_completion_processing(MPIR_Request * request_ptr, MPI_Status * { MPIR_Status_set_cancel_bit(status, MPIR_STATUS_GET_CANCEL_BIT(request_ptr->status)); mpi_errno = request_ptr->status.MPI_ERROR; - MPII_SENDQ_FORGET(request_ptr); break; } case MPIR_REQUEST_KIND__COLL: diff --git a/src/mpi/request/request_impl.c b/src/mpi/request/request_impl.c index b2b52c02ac6..6e71f46f5db 100644 --- a/src/mpi/request/request_impl.c +++ b/src/mpi/request/request_impl.c @@ -149,8 +149,6 @@ int MPIR_Request_free_impl(MPIR_Request * request_ptr) MPID_Progress_poke(); switch (request_ptr->kind) { case MPIR_REQUEST_KIND__SEND: - MPII_SENDQ_FORGET(request_ptr); - break; case MPIR_REQUEST_KIND__RECV: break; case MPIR_REQUEST_KIND__PREQUEST_SEND: From 2ff3060b7f02e2a92ef7038d76f18b1d71566d0d Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Mon, 10 Jan 2022 15:32:09 -0600 Subject: [PATCH 452/607] debugger: Generalize request queue element Rename data structures and supporting functions so they can be extended and used for receive requests as well as send. --- src/include/mpir_debugger.h | 8 +++--- src/include/mpir_request.h | 4 +-- src/mpi/debugger/dbginit.c | 47 ++++++++++++++++--------------- src/mpi/debugger/dbgstub.c | 28 +++++++++--------- src/mpi/debugger/dll_mpich.c | 26 ++++++++--------- src/mpi/debugger/mpich_dll_defs.h | 12 ++++---- 6 files changed, 63 insertions(+), 62 deletions(-) diff --git a/src/include/mpir_debugger.h b/src/include/mpir_debugger.h index fcc91da1701..3f9c5d08c99 100644 --- a/src/include/mpir_debugger.h +++ b/src/include/mpir_debugger.h @@ -15,13 +15,13 @@ void MPII_Wait_for_debugger(void); void MPIR_Debugger_set_aborting(const char *); /* internal functions */ -void MPII_Sendq_remember(MPIR_Request *, int, int, int); -void MPII_Sendq_forget(MPIR_Request *); +void MPII_Debugq_remember(MPIR_Request *, int, int, int); +void MPII_Debugq_forget(MPIR_Request *); void MPII_CommL_remember(MPIR_Comm *); void MPII_CommL_forget(MPIR_Comm *); -#define MPII_SENDQ_REMEMBER(_a,_b,_c,_d) MPII_Sendq_remember(_a,_b,_c,_d) -#define MPII_SENDQ_FORGET(_a) MPII_Sendq_forget(_a) +#define MPII_SENDQ_REMEMBER(_a,_b,_c,_d) MPII_Debugq_remember(_a,_b,_c,_d) +#define MPII_SENDQ_FORGET(_a) MPII_Debugq_forget(_a) #define MPII_COMML_REMEMBER(_a) MPII_CommL_remember(_a) #define MPII_COMML_FORGET(_a) MPII_CommL_forget(_a) #define MPII_REQUEST_CLEAR_DBG(_r) \ diff --git a/src/include/mpir_request.h b/src/include/mpir_request.h index aff90929b2f..a09b2c772e7 100644 --- a/src/include/mpir_request.h +++ b/src/include/mpir_request.h @@ -206,12 +206,12 @@ struct MPIR_Request { } nbc; /* kind : MPIR_REQUEST_KIND__COLL */ #if defined HAVE_DEBUGGER_SUPPORT struct { - struct MPIR_Sendq *dbg; + struct MPIR_Debugq *dbg; } send; /* kind : MPIR_REQUEST_KIND__SEND */ #endif /* HAVE_DEBUGGER_SUPPORT */ struct { #if defined HAVE_DEBUGGER_SUPPORT - struct MPIR_Sendq *dbg; + struct MPIR_Debugq *dbg; #endif /* HAVE_DEBUGGER_SUPPORT */ /* Persistent requests have their own "real" requests */ struct MPIR_Request *real_request; diff --git a/src/mpi/debugger/dbginit.c b/src/mpi/debugger/dbginit.c index 2172ff92f2d..c9d9591440c 100644 --- a/src/mpi/debugger/dbginit.c +++ b/src/mpi/debugger/dbginit.c @@ -171,8 +171,8 @@ static int MPIR_FreeProctable(void *); */ /* Forward references */ -static void SendqInit(void); -static int SendqFreePool(void *); +static void DebugqInit(void); +static int DebugqFreePool(void *); static MPID_Thread_mutex_t lock; @@ -286,8 +286,8 @@ void MPII_Wait_for_debugger(void) /* After we exit the MPIR_Breakpoint routine, the debugger may have * set variables such as MPIR_being_debugged */ - /* Initialize the sendq support */ - SendqInit(); + /* Initialize the request queue support */ + DebugqInit(); if (getenv("MPIEXEC_DEBUG")) { while (!MPIR_debug_gate); @@ -351,25 +351,25 @@ void MPIR_Debugger_set_aborting(const char *msg) /* We need to save the tag and rank since this information may not be included in the request. Saving the context_id also simplifies matching these entries with a communicator */ -typedef struct MPIR_Sendq { - MPIR_Request *sreq; +typedef struct MPIR_Debugq { + MPIR_Request *req; int tag, rank, context_id; - struct MPIR_Sendq *next; - struct MPIR_Sendq *prev; -} MPIR_Sendq; + struct MPIR_Debugq *next; + struct MPIR_Debugq *prev; +} MPIR_Debugq; -MPIR_Sendq *MPIR_Sendq_head = 0; +MPIR_Debugq *MPIR_Sendq_head = 0; /* Keep a pool of previous sendq elements to speed allocation of queue elements */ -static MPIR_Sendq *pool = 0; +static MPIR_Debugq *pool = 0; /* This routine is used to establish a queue of send requests to allow the debugger easier access to the active requests. Some devices may be able to provide this information without requiring this separate queue. */ -void MPII_Sendq_remember(MPIR_Request * req, int rank, int tag, int context_id) +void MPII_Debugq_remember(MPIR_Request * req, int rank, int tag, int context_id) { #if defined HAVE_DEBUGGER_SUPPORT - MPIR_Sendq *p; + MPIR_Debugq *p; /* Builtin requests are always completed, simply return. */ if (HANDLE_IS_BUILTIN(req->handle)) { @@ -382,7 +382,7 @@ void MPII_Sendq_remember(MPIR_Request * req, int rank, int tag, int context_id) p = pool; pool = p->next; } else { - p = (MPIR_Sendq *) MPL_malloc(sizeof(MPIR_Sendq), MPL_MEM_DEBUG); + p = (MPIR_Debugq *) MPL_malloc(sizeof(MPIR_Debugq), MPL_MEM_DEBUG); if (!p) { /* Just ignore it */ if (MPIR_REQUEST_KIND__SEND == req->kind) @@ -392,11 +392,12 @@ void MPII_Sendq_remember(MPIR_Request * req, int rank, int tag, int context_id) goto fn_exit; } } - p->sreq = req; + p->req = req; p->tag = tag; p->rank = rank; p->context_id = context_id; DL_PREPEND(MPIR_Sendq_head, p); + if (MPIR_REQUEST_KIND__SEND == req->kind) req->u.send.dbg = p; else if (MPIR_REQUEST_KIND__PREQUEST_SEND == req->kind) @@ -407,10 +408,10 @@ void MPII_Sendq_remember(MPIR_Request * req, int rank, int tag, int context_id) #endif /* HAVE_DEBUGGER_SUPPORT */ } -void MPII_Sendq_forget(MPIR_Request * req) +void MPII_Debugq_forget(MPIR_Request * req) { #if defined HAVE_DEBUGGER_SUPPORT - MPIR_Sendq *p = NULL, *prev = NULL; + MPIR_Debugq *p = NULL, *prev = NULL; MPID_THREAD_CS_ENTER(VCI, lock); MPID_THREAD_CS_ENTER(POBJ, lock); @@ -433,9 +434,9 @@ void MPII_Sendq_forget(MPIR_Request * req) #endif /* HAVE_DEBUGGER_SUPPORT */ } -static int SendqFreePool(void *d) +static int DebugqFreePool(void *d) { - MPIR_Sendq *p; + MPIR_Debugq *p; /* Free the pool */ p = pool; @@ -454,14 +455,14 @@ static int SendqFreePool(void *d) return 0; } -static void SendqInit(void) +static void DebugqInit(void) { int i; - MPIR_Sendq *p; + MPIR_Debugq *p; /* Preallocated a few send requests */ for (i = 0; i < 10; i++) { - p = (MPIR_Sendq *) MPL_malloc(sizeof(MPIR_Sendq), MPL_MEM_DEBUG); + p = (MPIR_Debugq *) MPL_malloc(sizeof(MPIR_Debugq), MPL_MEM_DEBUG); if (!p) { /* Just ignore it */ break; @@ -471,7 +472,7 @@ static void SendqInit(void) } /* Make sure the pool is deleted */ - MPIR_Add_finalize(SendqFreePool, 0, 0); + MPIR_Add_finalize(DebugqFreePool, 0, 0); } /* Manage the known communicators */ diff --git a/src/mpi/debugger/dbgstub.c b/src/mpi/debugger/dbgstub.c index 66efc9da868..834a7f02971 100644 --- a/src/mpi/debugger/dbgstub.c +++ b/src/mpi/debugger/dbgstub.c @@ -15,12 +15,12 @@ extern MPIR_Request **const MPID_Recvq_posted_head_ptr, **const MPID_Recvq_unexp #include "mpi_interface.h" /* This is from dbginit.c; it is not exported to other files */ -typedef struct MPIR_Sendq { - MPIR_Request *sreq; +typedef struct MPIR_Debugq { + MPIR_Request *req; int tag, rank, context_id; - struct MPIR_Sendq *next; -} MPIR_Sendq; -extern MPIR_Sendq *MPIR_Sendq_head; + struct MPIR_Debugq *next; +} MPIR_Debugq; +extern MPIR_Debugq *MPIR_Sendq_head; /* This is from dbginit.c; it is not exported to other files */ typedef struct MPIR_Comm_list { int sequence_number; /* Used to detect changes in the list */ @@ -46,7 +46,7 @@ enum { TYPE_UNKNOWN = 0, TYPE_MPIDI_REQUEST = 3, TYPE_MPIDI_MESSAGE_MATCH = 4, TYPE_MPIR_REQUEST = 5, - TYPE_MPIR_SENDQ = 6, + TYPE_MPIR_DEBUGQ = 6, TYPE_MPIDI_MESSAGE_MATCH_PARTS = 7, TYPE_MPIDI_DEVREQ_T = 8, TYPE_MPIDIG_REQ_T = 9, @@ -60,7 +60,7 @@ enum { TYPE_UNKNOWN = 0, static int knownTypesArray[] = { TYPE_UNKNOWN, TYPE_MPIR_COMM, TYPE_MPIR_COMM_LIST, TYPE_MPIDI_REQUEST, TYPE_MPIDI_MESSAGE_MATCH, TYPE_MPIR_REQUEST, - TYPE_MPIR_SENDQ, + TYPE_MPIR_DEBUGQ, TYPE_MPIDI_MESSAGE_MATCH_PARTS, TYPE_MPIDI_DEVREQ_T, TYPE_MPIDIG_REQ_T, @@ -83,8 +83,8 @@ mqs_type *dbgrI_find_type(mqs_image * image, char *name, mqs_lang_code lang) curType = TYPE_MPIDI_MESSAGE_MATCH_PARTS; } else if (strcmp(name, "MPIR_Request") == 0) { curType = TYPE_MPIR_REQUEST; - } else if (strcmp(name, "MPIR_Sendq") == 0) { - curType = TYPE_MPIR_SENDQ; + } else if (strcmp(name, "MPIR_Debugq") == 0) { + curType = TYPE_MPIR_DEBUGQ; } else if (strcmp(name, "MPIDI_Devreq_t") == 0) { curType = TYPE_MPIDI_DEVREQ_T; } else if (strcmp(name, "MPIDIG_req_t") == 0) { @@ -240,9 +240,9 @@ int dbgrI_field_offset(mqs_type * type, char *name) } } break; - case TYPE_MPIR_SENDQ: + case TYPE_MPIR_DEBUGQ: { - struct MPIR_Sendq c; + struct MPIR_Debugq c; if (strcmp(name, "next") == 0) { off = ((char *) &c.next - (char *) &c); } else if (strcmp(name, "tag") == 0) { @@ -251,10 +251,10 @@ int dbgrI_field_offset(mqs_type * type, char *name) off = ((char *) &c.rank - (char *) &c); } else if (strcmp(name, "context_id") == 0) { off = ((char *) &c.context_id - (char *) &c); - } else if (strcmp(name, "sreq") == 0) { - off = ((char *) &c.sreq - (char *) &c); + } else if (strcmp(name, "req") == 0) { + off = ((char *) &c.req - (char *) &c); } else { - printf("Panic! Unrecognized Sendq field %s\n", name); + printf("Panic! Unrecognized request queue field %s\n", name); } } break; diff --git a/src/mpi/debugger/dll_mpich.c b/src/mpi/debugger/dll_mpich.c index 8851798e0bf..0331553d581 100644 --- a/src/mpi/debugger/dll_mpich.c +++ b/src/mpi/debugger/dll_mpich.c @@ -361,13 +361,13 @@ int mqs_image_has_queues(mqs_image * image, const char **message) /* Send queues use a separate system */ { - mqs_type *sreq_type = dbgr_find_type(image, (char *) "MPIR_Sendq", mqs_lang_c); + mqs_type *sreq_type = dbgr_find_type(image, (char *) "MPIR_Debugq", mqs_lang_c); if (sreq_type) { - i_info->sendq_next_offs = dbgr_field_offset(sreq_type, (char *) "next"); - i_info->sendq_tag_offs = dbgr_field_offset(sreq_type, (char *) "tag"); - i_info->sendq_rank_offs = dbgr_field_offset(sreq_type, (char *) "rank"); - i_info->sendq_context_id_offs = dbgr_field_offset(sreq_type, (char *) "context_id"); - i_info->sendq_req_offs = dbgr_field_offset(sreq_type, (char *) "sreq"); + i_info->debugq_next_offs = dbgr_field_offset(sreq_type, (char *) "next"); + i_info->debugq_tag_offs = dbgr_field_offset(sreq_type, (char *) "tag"); + i_info->debugq_rank_offs = dbgr_field_offset(sreq_type, (char *) "rank"); + i_info->debugq_context_id_offs = dbgr_field_offset(sreq_type, (char *) "context_id"); + i_info->debugq_req_offs = dbgr_field_offset(sreq_type, (char *) "req"); } } @@ -785,15 +785,15 @@ static int fetch_send(mqs_process * proc, mpich_process_info * p_info, mqs_pendi while (base != 0) { /* Check this entry to see if the context matches */ - int actual_context = fetch_int16(proc, base + i_info->sendq_context_id_offs, p_info); + int actual_context = fetch_int16(proc, base + i_info->debugq_context_id_offs, p_info); if (actual_context == wanted_context) { /* Fill in some of the fields */ - mqs_tword_t target = fetch_int(proc, base + i_info->sendq_rank_offs, p_info); - mqs_tword_t tag = fetch_int(proc, base + i_info->sendq_tag_offs, p_info); + mqs_tword_t target = fetch_int(proc, base + i_info->debugq_rank_offs, p_info); + mqs_tword_t tag = fetch_int(proc, base + i_info->debugq_tag_offs, p_info); mqs_tword_t length = 0; mqs_taddr_t data = 0; - mqs_taddr_t sreq = fetch_pointer(proc, base + i_info->sendq_req_offs, p_info); + mqs_taddr_t sreq = fetch_pointer(proc, base + i_info->debugq_req_offs, p_info); mqs_tword_t is_complete = fetch_int(proc, sreq + i_info->req_cc_offs, p_info); data = fetch_pointer(proc, sreq + i_info->req_user_buf_offs, p_info); length = fetch_int(proc, sreq + i_info->req_user_count_offs, p_info); @@ -802,7 +802,7 @@ static int fetch_send(mqs_process * proc, mpich_process_info * p_info, mqs_pendi #ifdef DEBUG_LIST_ITER initLogFile(); fprintf(debugfp, "sendq entry = %p, rank off = %d, tag off = %d, context = %d\n", - base, i_info->sendq_rank_offs, i_info->sendq_tag_offs, actual_context); + base, i_info->debugq_rank_offs, i_info->debugq_tag_offs, actual_context); #endif /* Ok, fill in the results */ @@ -817,11 +817,11 @@ static int fetch_send(mqs_process * proc, mpich_process_info * p_info, mqs_pendi /* Don't forget to step the queue ! */ - p_info->next_msg = base + i_info->sendq_next_offs; + p_info->next_msg = base + i_info->debugq_next_offs; return mqs_ok; } else { /* Try the next one */ - base = fetch_pointer(proc, base + i_info->sendq_next_offs, p_info); + base = fetch_pointer(proc, base + i_info->debugq_next_offs, p_info); } } #if 0 diff --git a/src/mpi/debugger/mpich_dll_defs.h b/src/mpi/debugger/mpich_dll_defs.h index 663839173df..5d05cd7b1f9 100644 --- a/src/mpi/debugger/mpich_dll_defs.h +++ b/src/mpi/debugger/mpich_dll_defs.h @@ -42,12 +42,12 @@ typedef struct { int req_datatype_offs; int req_next_offs; - /* Fields in MPIR_Sendq */ - int sendq_next_offs; - int sendq_tag_offs; - int sendq_rank_offs; - int sendq_context_id_offs; - int sendq_req_offs; + /* Fields in MPIR_Debugq */ + int debugq_next_offs; + int debugq_tag_offs; + int debugq_rank_offs; + int debugq_context_id_offs; + int debugq_req_offs; } mpich_image_info; /*********************************************************************** From 278b60c99b1c0863cb1b910194136ec10ad64dd8 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Fri, 14 Jan 2022 10:46:15 -0600 Subject: [PATCH 453/607] debugger: Add names to function arguments in header This makes it easier to use these functions by just scanning the header. --- src/include/mpir_debugger.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/include/mpir_debugger.h b/src/include/mpir_debugger.h index 3f9c5d08c99..0eab47e6ba8 100644 --- a/src/include/mpir_debugger.h +++ b/src/include/mpir_debugger.h @@ -13,12 +13,12 @@ #ifdef HAVE_DEBUGGER_SUPPORT void MPII_Wait_for_debugger(void); -void MPIR_Debugger_set_aborting(const char *); +void MPIR_Debugger_set_aborting(const char *msg); /* internal functions */ -void MPII_Debugq_remember(MPIR_Request *, int, int, int); -void MPII_Debugq_forget(MPIR_Request *); -void MPII_CommL_remember(MPIR_Comm *); -void MPII_CommL_forget(MPIR_Comm *); +void MPII_Debugq_remember(MPIR_Request * req, int rank, int tag, int context_id); +void MPII_Debugq_forget(MPIR_Request * req); +void MPII_CommL_remember(MPIR_Comm * comm); +void MPII_CommL_forget(MPIR_Comm * comm); #define MPII_SENDQ_REMEMBER(_a,_b,_c,_d) MPII_Debugq_remember(_a,_b,_c,_d) #define MPII_SENDQ_FORGET(_a) MPII_Debugq_forget(_a) From b7a4551ff8c538548029d0945f4506dfa60329f2 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Mon, 10 Jan 2022 16:11:52 -0600 Subject: [PATCH 454/607] debugger: Add support for standalone receive queue debugging Add the capability to remember/forget receive request entries in a standalone debug queue. This should allow us to simplify the associated code to expose receive queues to tools that currently rely on device-specific queues that may or may not exist depending on configuration. --- src/include/mpir_debugger.h | 29 ++++++++++++++++++--- src/include/mpir_request.h | 11 ++++++-- src/mpi/debugger/dbginit.c | 51 ++++++++++++++++--------------------- src/mpi/debugger/dbgstub.c | 7 ----- 4 files changed, 56 insertions(+), 42 deletions(-) diff --git a/src/include/mpir_debugger.h b/src/include/mpir_debugger.h index 0eab47e6ba8..09e892ef876 100644 --- a/src/include/mpir_debugger.h +++ b/src/include/mpir_debugger.h @@ -12,16 +12,31 @@ */ #ifdef HAVE_DEBUGGER_SUPPORT +typedef struct MPIR_Debugq { + MPIR_Request *req; + int tag, rank, context_id; + struct MPIR_Debugq *next; + struct MPIR_Debugq *prev; +} MPIR_Debugq; +extern MPIR_Debugq *MPIR_Sendq_head; +extern MPIR_Debugq *MPIR_Recvq_head; +extern MPIR_Debugq *MPIR_Unexpq_head; + void MPII_Wait_for_debugger(void); void MPIR_Debugger_set_aborting(const char *msg); /* internal functions */ -void MPII_Debugq_remember(MPIR_Request * req, int rank, int tag, int context_id); -void MPII_Debugq_forget(MPIR_Request * req); +void MPII_Debugq_remember(MPIR_Request * req, int rank, int tag, int context_id, + MPIR_Debugq ** queue); +void MPII_Debugq_forget(MPIR_Request * req, MPIR_Debugq ** queue); void MPII_CommL_remember(MPIR_Comm * comm); void MPII_CommL_forget(MPIR_Comm * comm); -#define MPII_SENDQ_REMEMBER(_a,_b,_c,_d) MPII_Debugq_remember(_a,_b,_c,_d) -#define MPII_SENDQ_FORGET(_a) MPII_Debugq_forget(_a) +#define MPII_SENDQ_REMEMBER(_a,_b,_c,_d) MPII_Debugq_remember(_a,_b,_c,_d,&MPIR_Sendq_head) +#define MPII_SENDQ_FORGET(_a) MPII_Debugq_forget(_a,&MPIR_Sendq_head) +#define MPII_RECVQ_REMEMBER(_a,_b,_c,_d) MPII_Debugq_remember(_a,_b,_c,_d,&MPIR_Recvq_head) +#define MPII_RECVQ_FORGET(_a) MPII_Debugq_forget(_a,&MPIR_Recvq_head) +#define MPII_UNEXPQ_REMEMBER(_a,_b,_c,_d) MPII_Debugq_remember(_a,_b,_c,_d,&MPIR_Unexpq_head) +#define MPII_UNEXPQ_FORGET(_a) MPII_Debugq_forget(_a,&MPIR_Unexpq_head) #define MPII_COMML_REMEMBER(_a) MPII_CommL_remember(_a) #define MPII_COMML_FORGET(_a) MPII_CommL_forget(_a) #define MPII_REQUEST_CLEAR_DBG(_r) \ @@ -29,6 +44,8 @@ void MPII_CommL_forget(MPIR_Comm * comm); ((_r)->u.send.dbg = NULL); \ } else if ((_r)->kind == MPIR_REQUEST_KIND__PREQUEST_SEND) { \ ((_r)->u.persist.dbg = NULL); \ + } else if ((_r)->kind == MPIR_REQUEST_KIND__RECV || (_r)->kind == MPIR_REQUEST_KIND__MPROBE) { \ + ((_r)->u.recv.dbg = NULL); \ } else { \ MPIR_Assert(0); \ } @@ -44,6 +61,10 @@ static inline void MPIR_Debugger_set_aborting(const char *dummy) #define MPII_SENDQ_REMEMBER(a,b,c,d) #define MPII_SENDQ_FORGET(a) +#define MPII_RECVQ_REMEMBER(a,b,c,d) +#define MPII_RECVQ_FORGET(a) +#define MPII_UNEXPQ_REMEMBER(a,b,c,d) +#define MPII_UNEXPQ_FORGET(a) #define MPII_COMML_REMEMBER(_a) #define MPII_COMML_FORGET(_a) #define MPII_REQUEST_CLEAR_DBG(_r) diff --git a/src/include/mpir_request.h b/src/include/mpir_request.h index a09b2c772e7..d29433d746e 100644 --- a/src/include/mpir_request.h +++ b/src/include/mpir_request.h @@ -208,6 +208,9 @@ struct MPIR_Request { struct { struct MPIR_Debugq *dbg; } send; /* kind : MPIR_REQUEST_KIND__SEND */ + struct { + struct MPIR_Debugq *dbg; + } recv; /* kind : MPIR_REQUEST_KIND__RECV */ #endif /* HAVE_DEBUGGER_SUPPORT */ struct { #if defined HAVE_DEBUGGER_SUPPORT @@ -423,6 +426,8 @@ static inline MPIR_Request *MPIR_Request_create_from_pool(MPIR_Request_kind_t ki switch (kind) { case MPIR_REQUEST_KIND__SEND: case MPIR_REQUEST_KIND__PREQUEST_SEND: + case MPIR_REQUEST_KIND__RECV: + case MPIR_REQUEST_KIND__MPROBE: MPII_REQUEST_CLEAR_DBG(req); break; case MPIR_REQUEST_KIND__COLL: @@ -552,12 +557,14 @@ static inline void MPIR_Request_free_with_safety(MPIR_Request * req, int need_sa MPL_free(req->u.ureq.greq_fns); } - MPID_Request_destroy_hook(req); - if (req->kind == MPIR_REQUEST_KIND__SEND) { MPII_SENDQ_FORGET(req); + } else if (req->kind == MPIR_REQUEST_KIND__RECV) { + MPII_RECVQ_FORGET(req); } + MPID_Request_destroy_hook(req); + if (need_safety) { MPID_THREAD_CS_ENTER(POBJ, MPIR_THREAD_POBJ_HANDLE_MUTEX); MPIR_Handle_obj_free_unsafe(&MPIR_Request_mem[pool], req, /* not info */ FALSE); diff --git a/src/mpi/debugger/dbginit.c b/src/mpi/debugger/dbginit.c index c9d9591440c..46024b95f9f 100644 --- a/src/mpi/debugger/dbginit.c +++ b/src/mpi/debugger/dbginit.c @@ -333,40 +333,25 @@ void MPIR_Debugger_set_aborting(const char *msg) /* ------------------------------------------------------------------------- */ /* - * Manage the send queue. + * Manage the request queues. * - * The send queue is needed only by the debugger. The communication - * device has a separate notion of send queue, which are the operations - * that it needs to complete, independent of whether the user has called - * MPI_Wait/Test/etc on the request. - * - * This implementation uses a simple linked list of user-visible requests - * (more specifically, requests created with MPI_Isend, MPI_Issend, or - * MPI_Irsend). + * This implementation uses a simple linked list of requests. * * FIXME: We should exploit this to allow Finalize to report on * send requests that were never completed. */ -/* We need to save the tag and rank since this information may not - be included in the request. Saving the context_id also simplifies - matching these entries with a communicator */ -typedef struct MPIR_Debugq { - MPIR_Request *req; - int tag, rank, context_id; - struct MPIR_Debugq *next; - struct MPIR_Debugq *prev; -} MPIR_Debugq; - MPIR_Debugq *MPIR_Sendq_head = 0; -/* Keep a pool of previous sendq elements to speed allocation of queue +MPIR_Debugq *MPIR_Recvq_head = 0; +MPIR_Debugq *MPIR_Unexpq_head = 0; +/* Keep a pool of previous debugq elements to speed allocation of queue elements */ static MPIR_Debugq *pool = 0; -/* This routine is used to establish a queue of send requests to allow the - debugger easier access to the active requests. Some devices may be able - to provide this information without requiring this separate queue. */ -void MPII_Debugq_remember(MPIR_Request * req, int rank, int tag, int context_id) +/* This routine is used to establish a queue of requests to allow the + debugger easier access to the active requests. */ +void MPII_Debugq_remember(MPIR_Request * req, int rank, int tag, int context_id, + MPIR_Debugq ** queue) { #if defined HAVE_DEBUGGER_SUPPORT MPIR_Debugq *p; @@ -389,6 +374,8 @@ void MPII_Debugq_remember(MPIR_Request * req, int rank, int tag, int context_id) req->u.send.dbg = NULL; else if (MPIR_REQUEST_KIND__PREQUEST_SEND == req->kind) req->u.persist.dbg = NULL; + else if (MPIR_REQUEST_KIND__RECV == req->kind) + req->u.recv.dbg = NULL; goto fn_exit; } } @@ -396,19 +383,23 @@ void MPII_Debugq_remember(MPIR_Request * req, int rank, int tag, int context_id) p->tag = tag; p->rank = rank; p->context_id = context_id; - DL_PREPEND(MPIR_Sendq_head, p); + DL_PREPEND(*queue, p); - if (MPIR_REQUEST_KIND__SEND == req->kind) + if (MPIR_REQUEST_KIND__SEND == req->kind) { req->u.send.dbg = p; - else if (MPIR_REQUEST_KIND__PREQUEST_SEND == req->kind) + } else if (MPIR_REQUEST_KIND__PREQUEST_SEND == req->kind) { req->u.persist.dbg = p; + } else if (MPIR_REQUEST_KIND__RECV == req->kind) { + req->u.recv.dbg = p; + } + fn_exit: MPID_THREAD_CS_EXIT(VCI, lock); MPID_THREAD_CS_EXIT(POBJ, lock); #endif /* HAVE_DEBUGGER_SUPPORT */ } -void MPII_Debugq_forget(MPIR_Request * req) +void MPII_Debugq_forget(MPIR_Request * req, MPIR_Debugq ** queue) { #if defined HAVE_DEBUGGER_SUPPORT MPIR_Debugq *p = NULL, *prev = NULL; @@ -419,13 +410,15 @@ void MPII_Debugq_forget(MPIR_Request * req) p = req->u.send.dbg; else if (MPIR_REQUEST_KIND__PREQUEST_SEND == req->kind) p = req->u.persist.dbg; + else if (MPIR_REQUEST_KIND__RECV == req->kind) + p = req->u.recv.dbg; if (!p) { /* Just ignore it */ MPID_THREAD_CS_EXIT(VCI, lock); MPID_THREAD_CS_EXIT(POBJ, lock); return; } - DL_DELETE(MPIR_Sendq_head, p); + DL_DELETE(*queue, p); /* Return this element to the pool */ p->next = pool; pool = p; diff --git a/src/mpi/debugger/dbgstub.c b/src/mpi/debugger/dbgstub.c index 834a7f02971..cbf4bbd053d 100644 --- a/src/mpi/debugger/dbgstub.c +++ b/src/mpi/debugger/dbgstub.c @@ -14,13 +14,6 @@ extern MPIR_Request **const MPID_Recvq_posted_head_ptr, **const MPID_Recvq_unexp #include "mpi_interface.h" -/* This is from dbginit.c; it is not exported to other files */ -typedef struct MPIR_Debugq { - MPIR_Request *req; - int tag, rank, context_id; - struct MPIR_Debugq *next; -} MPIR_Debugq; -extern MPIR_Debugq *MPIR_Sendq_head; /* This is from dbginit.c; it is not exported to other files */ typedef struct MPIR_Comm_list { int sequence_number; /* Used to detect changes in the list */ From 8e968fe73ee472fe6a982b81c10656842e0209b1 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Fri, 14 Jan 2022 14:38:43 -0600 Subject: [PATCH 455/607] ch3: Use recv queue debugging macros These macros will create entries in the standalone receive and unexpected queues, which we will eventually use to replace direct access to the device-level queues. --- src/mpid/ch3/src/ch3u_recvq.c | 6 ++++++ src/mpid/ch3/src/mpid_imrecv.c | 1 + src/mpid/ch3/src/mpid_irecv.c | 1 + src/mpid/ch3/src/mpid_recv.c | 1 + 4 files changed, 9 insertions(+) diff --git a/src/mpid/ch3/src/ch3u_recvq.c b/src/mpid/ch3/src/ch3u_recvq.c index 9a573fa7e08..cfe0f6b644b 100644 --- a/src/mpid/ch3/src/ch3u_recvq.c +++ b/src/mpid/ch3/src/ch3u_recvq.c @@ -337,6 +337,7 @@ MPIR_Request * MPIDI_CH3U_Recvq_FDU(MPI_Request sreq_id, } MPIR_T_PVAR_LEVEL_DEC(RECVQ, unexpected_recvq_length, 1); + MPII_UNEXPQ_FORGET(matching_cur_rreq); rreq = matching_cur_rreq; MPIR_T_PVAR_LEVEL_DEC(RECVQ, unexpected_recvq_buffer_size, rreq->dev.tmpbuf_sz); @@ -396,6 +397,7 @@ MPIR_Request * MPIDI_CH3U_Recvq_FDU_matchonly(int source, int tag, int context_i } MPIR_T_PVAR_LEVEL_DEC(RECVQ, unexpected_recvq_length, 1); MPIR_T_PVAR_LEVEL_DEC(RECVQ, unexpected_recvq_buffer_size, rreq->dev.tmpbuf_sz); + MPII_UNEXPQ_FORGET(rreq); rreq->comm = comm; MPIR_Comm_add_ref(comm); @@ -428,6 +430,7 @@ MPIR_Request * MPIDI_CH3U_Recvq_FDU_matchonly(int source, int tag, int context_i } MPIR_T_PVAR_LEVEL_DEC(RECVQ, unexpected_recvq_length, 1); MPIR_T_PVAR_LEVEL_DEC(RECVQ, unexpected_recvq_buffer_size, rreq->dev.tmpbuf_sz); + MPII_UNEXPQ_FORGET(rreq); rreq->comm = comm; MPIR_Comm_add_ref(comm); @@ -510,6 +513,7 @@ MPIR_Request * MPIDI_CH3U_Recvq_FDU_or_AEP(int source, int tag, recvq_unexpected_tail = prev_rreq; } MPIR_T_PVAR_LEVEL_DEC(RECVQ, unexpected_recvq_length, 1); + MPII_UNEXPQ_FORGET(rreq); if (MPIDI_Request_get_msg_type(rreq) == MPIDI_REQUEST_EAGER_MSG) MPIR_T_PVAR_LEVEL_DEC(RECVQ, unexpected_recvq_buffer_size, rreq->dev.tmpbuf_sz); @@ -546,6 +550,7 @@ MPIR_Request * MPIDI_CH3U_Recvq_FDU_or_AEP(int source, int tag, recvq_unexpected_tail = prev_rreq; } MPIR_T_PVAR_LEVEL_DEC(RECVQ, unexpected_recvq_length, 1); + MPII_UNEXPQ_FORGET(rreq); if (MPIDI_Request_get_msg_type(rreq) == MPIDI_REQUEST_EAGER_MSG) MPIR_T_PVAR_LEVEL_DEC(RECVQ, unexpected_recvq_buffer_size, rreq->dev.tmpbuf_sz); @@ -794,6 +799,7 @@ MPIR_Request * MPIDI_CH3U_Recvq_FDP_or_AEU(MPIDI_Message_match * match, found=FALSE;goto lock_exit ); MPIR_Assert(mpi_errno == 0); rreq->dev.recv_pending_count = 1; + MPII_UNEXPQ_REMEMBER(rreq, match->parts.rank, match->parts.tag, match->parts.context_id); /* Reset the error bits if we unset it earlier. */ if (error_bit_masked) MPIR_TAG_SET_ERROR_BIT(match->parts.tag); if (proc_failure_bit_masked) MPIR_TAG_SET_PROC_FAILURE_BIT(match->parts.tag); diff --git a/src/mpid/ch3/src/mpid_imrecv.c b/src/mpid/ch3/src/mpid_imrecv.c index 6cb79df4793..8eff3e16e27 100644 --- a/src/mpid/ch3/src/mpid_imrecv.c +++ b/src/mpid/ch3/src/mpid_imrecv.c @@ -28,6 +28,7 @@ int MPID_Imrecv(void *buf, int count, MPI_Datatype datatype, rreq->dev.user_buf = buf; rreq->dev.user_count = count; rreq->dev.datatype = datatype; + MPII_RECVQ_REMEMBER(rreq, rreq->status.MPI_SOURCE, rreq->status.MPI_TAG, rreq->comm->recvcontext_id); #ifdef ENABLE_COMM_OVERRIDES MPIDI_Comm_get_vc(comm, rreq->status.MPI_SOURCE, &vc); diff --git a/src/mpid/ch3/src/mpid_irecv.c b/src/mpid/ch3/src/mpid_irecv.c index bee65e2b101..29dfeee09bb 100644 --- a/src/mpid/ch3/src/mpid_irecv.c +++ b/src/mpid/ch3/src/mpid_irecv.c @@ -155,6 +155,7 @@ int MPID_Irecv(void * buf, MPI_Aint count, MPI_Datatype datatype, int rank, int *request = rreq; MPL_DBG_MSG_P(MPIDI_CH3_DBG_OTHER,VERBOSE,"request allocated, handle=0x%08x", rreq->handle); + MPII_RECVQ_REMEMBER(rreq, rank, tag, comm->recvcontext_id); MPIR_FUNC_EXIT; return mpi_errno; diff --git a/src/mpid/ch3/src/mpid_recv.c b/src/mpid/ch3/src/mpid_recv.c index 1d2f89602fc..1e14a4aaece 100644 --- a/src/mpid/ch3/src/mpid_recv.c +++ b/src/mpid/ch3/src/mpid_recv.c @@ -177,6 +177,7 @@ int MPID_Recv(void * buf, MPI_Aint count, MPI_Datatype datatype, int rank, int t { MPL_DBG_MSG_P(MPIDI_CH3_DBG_OTHER,VERBOSE, "request allocated, handle=0x%08x", rreq->handle); + MPII_RECVQ_REMEMBER(rreq, rank, tag, comm->recvcontext_id); } else { From 507619b67e22fcc94f1ec1fee874643f318ae756 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Fri, 14 Jan 2022 15:22:53 -0600 Subject: [PATCH 456/607] ch4: Call MPID_Imrecv from MPID_Mrecv These two functions are identical, so just maintain one implementation. --- src/mpid/ch4/src/ch4_recv.h | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/src/mpid/ch4/src/ch4_recv.h b/src/mpid/ch4/src/ch4_recv.h index e1cda600301..6fb3faa8d47 100644 --- a/src/mpid/ch4/src/ch4_recv.h +++ b/src/mpid/ch4/src/ch4_recv.h @@ -267,25 +267,7 @@ MPL_STATIC_INLINE_PREFIX int MPID_Mrecv(void *buf, MPI_Datatype datatype, MPIR_Request * message, MPI_Status * status, MPIR_Request ** rreq) { - int mpi_errno; - MPIR_FUNC_ENTER; - - MPIR_Assert(message->kind == MPIR_REQUEST_KIND__MPROBE); - message->kind = MPIR_REQUEST_KIND__RECV; - - if (message->comm && MPIDI_is_self_comm(message->comm)) { - mpi_errno = MPIDI_Self_imrecv(buf, count, datatype, message, rreq); - } else { - *rreq = message; - mpi_errno = MPIDI_imrecv(buf, count, datatype, message); - } - MPIR_ERR_CHECK(mpi_errno); - - fn_exit: - MPIR_FUNC_EXIT; - return mpi_errno; - fn_fail: - goto fn_exit; + return MPID_Imrecv(buf, count, datatype, message, rreq); } MPL_STATIC_INLINE_PREFIX int MPID_Imrecv(void *buf, MPI_Aint count, MPI_Datatype datatype, From 0298adc6e2ea00bd7e3b8753604e5f53ee515d14 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Fri, 14 Jan 2022 15:24:10 -0600 Subject: [PATCH 457/607] ch4: Use recv queue debugging macros These macros will create entries in the standalone receive and unexpected queues, which we will eventually use to replace direct access to the device-level queues. --- src/mpid/ch4/src/ch4_recv.h | 6 ++++++ src/mpid/ch4/src/mpidig_probe.h | 1 + src/mpid/ch4/src/mpidig_pt2pt_callbacks.c | 1 + src/mpid/ch4/src/mpidig_recv.h | 1 + 4 files changed, 9 insertions(+) diff --git a/src/mpid/ch4/src/ch4_recv.h b/src/mpid/ch4/src/ch4_recv.h index 6fb3faa8d47..3b1c4e3784f 100644 --- a/src/mpid/ch4/src/ch4_recv.h +++ b/src/mpid/ch4/src/ch4_recv.h @@ -287,6 +287,10 @@ MPL_STATIC_INLINE_PREFIX int MPID_Imrecv(void *buf, MPI_Aint count, MPI_Datatype mpi_errno = MPIDI_imrecv(buf, count, datatype, message); } MPIR_ERR_CHECK(mpi_errno); + + MPII_RECVQ_REMEMBER(message, message->status.MPI_SOURCE, message->status.MPI_TAG, + message->comm->recvcontext_id); + fn_exit: MPIR_FUNC_EXIT; return mpi_errno; @@ -314,6 +318,8 @@ MPL_STATIC_INLINE_PREFIX int MPID_Irecv(void *buf, } MPIR_ERR_CHECK(mpi_errno); + + MPII_RECVQ_REMEMBER(*request, rank, tag, comm->recvcontext_id); fn_exit: MPIR_FUNC_EXIT; return mpi_errno; diff --git a/src/mpid/ch4/src/mpidig_probe.h b/src/mpid/ch4/src/mpidig_probe.h index 7833e2d23fe..44085ccab50 100644 --- a/src/mpid/ch4/src/mpidig_probe.h +++ b/src/mpid/ch4/src/mpidig_probe.h @@ -57,6 +57,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_mpi_improbe(int source, int tag, MPIR_Comm * MPIDIG_PT2PT_UNEXP); if (unexp_req) { + MPII_UNEXPQ_FORGET(unexp_req); *flag = 1; *message = unexp_req; diff --git a/src/mpid/ch4/src/mpidig_pt2pt_callbacks.c b/src/mpid/ch4/src/mpidig_pt2pt_callbacks.c index 52a1329a4ad..7ecaeb32add 100644 --- a/src/mpid/ch4/src/mpidig_pt2pt_callbacks.c +++ b/src/mpid/ch4/src/mpidig_pt2pt_callbacks.c @@ -389,6 +389,7 @@ int MPIDIG_send_target_msg_cb(void *am_hdr, void *data, MPI_Aint in_data_sz, MPIDIG_enqueue_request(rreq, &MPIDI_global.per_vci[local_vci].unexp_list, MPIDIG_PT2PT_UNEXP); + MPII_UNEXPQ_REMEMBER(rreq, hdr->src_rank, hdr->tag, hdr->context_id); } else { /* matched path */ MPIDIG_REQUEST(rreq, req->remote_vci) = remote_vci; diff --git a/src/mpid/ch4/src/mpidig_recv.h b/src/mpid/ch4/src/mpidig_recv.h index 4b2a64d7d1b..12cfa29b2dd 100644 --- a/src/mpid/ch4/src/mpidig_recv.h +++ b/src/mpid/ch4/src/mpidig_recv.h @@ -204,6 +204,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDIG_do_irecv(void *buf, MPI_Aint count, MPI_Data MPIDIG_PT2PT_UNEXP); if (unexp_req) { + MPII_UNEXPQ_FORGET(unexp_req); unexp_req->comm = comm; MPIR_Comm_add_ref(comm); if (MPIDIG_REQUEST(unexp_req, req->status) & MPIDIG_REQ_BUSY) { From 1e8452d0ffde2463626afe50972be84a3769cfc7 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Fri, 14 Jan 2022 16:34:56 -0600 Subject: [PATCH 458/607] debugger: Extend MPIR_Debugq to include buffer and count --- src/binding/c/pt2pt_api.txt | 10 +++++----- src/include/mpir_debugger.h | 16 +++++++++------- src/mpi/debugger/dbginit.c | 6 ++++-- src/mpi/debugger/dbgstub.c | 4 ++++ src/mpi/debugger/mpich_dll_defs.h | 2 ++ src/mpid/ch3/src/mpid_imrecv.c | 2 +- src/mpid/ch3/src/mpid_irecv.c | 2 +- src/mpid/ch4/src/ch4_recv.h | 4 ++-- 8 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/binding/c/pt2pt_api.txt b/src/binding/c/pt2pt_api.txt index d14ff665005..3420cbe4647 100644 --- a/src/binding/c/pt2pt_api.txt +++ b/src/binding/c/pt2pt_api.txt @@ -50,7 +50,7 @@ MPI_Bsend_init: MPIR_CONTEXT_INTRA_PT2PT, &request_ptr); if (mpi_errno != MPI_SUCCESS) goto fn_fail; - MPII_SENDQ_REMEMBER(request_ptr, dest, tag, comm_ptr->context_id); + MPII_SENDQ_REMEMBER(request_ptr, dest, tag, comm_ptr->context_id, buf, count); /* return the handle of the request to the user */ MPIR_OBJ_PUBLISH_HANDLE(*request, request_ptr->handle); @@ -245,7 +245,7 @@ MPI_Irsend: MPIR_CONTEXT_INTRA_PT2PT, &request_ptr); if (mpi_errno != MPI_SUCCESS) goto fn_fail; - MPII_SENDQ_REMEMBER(request_ptr, dest, tag, comm_ptr->context_id); + MPII_SENDQ_REMEMBER(request_ptr, dest, tag, comm_ptr->context_id, buf, count); /* return the handle of the request to the user */ /* MPIU_OBJ_HANDLE_PUBLISH is unnecessary for irsend, lower-level access is @@ -265,7 +265,7 @@ MPI_Isend: if (mpi_errno != MPI_SUCCESS) goto fn_fail; - MPII_SENDQ_REMEMBER(request_ptr, dest, tag, comm_ptr->context_id); + MPII_SENDQ_REMEMBER(request_ptr, dest, tag, comm_ptr->context_id, buf, count); /* return the handle of the request to the user */ /* MPIU_OBJ_HANDLE_PUBLISH is unnecessary for isend, lower-level access is @@ -284,7 +284,7 @@ MPI_Issend: MPIR_CONTEXT_INTRA_PT2PT, &request_ptr); if (mpi_errno != MPI_SUCCESS) goto fn_fail; - MPII_SENDQ_REMEMBER(request_ptr, dest, tag, comm_ptr->context_id); + MPII_SENDQ_REMEMBER(request_ptr, dest, tag, comm_ptr->context_id, buf, count); /* return the handle of the request to the user */ /* MPIU_OBJ_HANDLE_PUBLISH is unnecessary for issend, lower-level access is @@ -477,7 +477,7 @@ MPI_Send_init: MPIR_CONTEXT_INTRA_PT2PT, &request_ptr); if (mpi_errno != MPI_SUCCESS) goto fn_fail; - MPII_SENDQ_REMEMBER(request_ptr, dest, tag, comm_ptr->context_id); + MPII_SENDQ_REMEMBER(request_ptr, dest, tag, comm_ptr->context_id, buf, count); /* return the handle of the request to the user */ MPIR_OBJ_PUBLISH_HANDLE(*request, request_ptr->handle); diff --git a/src/include/mpir_debugger.h b/src/include/mpir_debugger.h index 09e892ef876..383dd892fcc 100644 --- a/src/include/mpir_debugger.h +++ b/src/include/mpir_debugger.h @@ -15,6 +15,8 @@ typedef struct MPIR_Debugq { MPIR_Request *req; int tag, rank, context_id; + const void *buf; + MPI_Aint count; struct MPIR_Debugq *next; struct MPIR_Debugq *prev; } MPIR_Debugq; @@ -25,17 +27,17 @@ extern MPIR_Debugq *MPIR_Unexpq_head; void MPII_Wait_for_debugger(void); void MPIR_Debugger_set_aborting(const char *msg); /* internal functions */ -void MPII_Debugq_remember(MPIR_Request * req, int rank, int tag, int context_id, - MPIR_Debugq ** queue); +void MPII_Debugq_remember(MPIR_Request * req, int rank, int tag, int context_id, const void *buf, + MPI_Aint count, MPIR_Debugq ** queue); void MPII_Debugq_forget(MPIR_Request * req, MPIR_Debugq ** queue); void MPII_CommL_remember(MPIR_Comm * comm); void MPII_CommL_forget(MPIR_Comm * comm); -#define MPII_SENDQ_REMEMBER(_a,_b,_c,_d) MPII_Debugq_remember(_a,_b,_c,_d,&MPIR_Sendq_head) +#define MPII_SENDQ_REMEMBER(_a,_b,_c,_d,_e,_f) MPII_Debugq_remember(_a,_b,_c,_d,_e,_f,&MPIR_Sendq_head) #define MPII_SENDQ_FORGET(_a) MPII_Debugq_forget(_a,&MPIR_Sendq_head) -#define MPII_RECVQ_REMEMBER(_a,_b,_c,_d) MPII_Debugq_remember(_a,_b,_c,_d,&MPIR_Recvq_head) +#define MPII_RECVQ_REMEMBER(_a,_b,_c,_d,_e,_f) MPII_Debugq_remember(_a,_b,_c,_d,_e,_f,&MPIR_Recvq_head) #define MPII_RECVQ_FORGET(_a) MPII_Debugq_forget(_a,&MPIR_Recvq_head) -#define MPII_UNEXPQ_REMEMBER(_a,_b,_c,_d) MPII_Debugq_remember(_a,_b,_c,_d,&MPIR_Unexpq_head) +#define MPII_UNEXPQ_REMEMBER(_a,_b,_c,_d) MPII_Debugq_remember(_a,_b,_c,_d,NULL,0,&MPIR_Unexpq_head) #define MPII_UNEXPQ_FORGET(_a) MPII_Debugq_forget(_a,&MPIR_Unexpq_head) #define MPII_COMML_REMEMBER(_a) MPII_CommL_remember(_a) #define MPII_COMML_FORGET(_a) MPII_CommL_forget(_a) @@ -59,9 +61,9 @@ static inline void MPIR_Debugger_set_aborting(const char *dummy) { } -#define MPII_SENDQ_REMEMBER(a,b,c,d) +#define MPII_SENDQ_REMEMBER(a,b,c,d,e,f) #define MPII_SENDQ_FORGET(a) -#define MPII_RECVQ_REMEMBER(a,b,c,d) +#define MPII_RECVQ_REMEMBER(a,b,c,d,e,f) #define MPII_RECVQ_FORGET(a) #define MPII_UNEXPQ_REMEMBER(a,b,c,d) #define MPII_UNEXPQ_FORGET(a) diff --git a/src/mpi/debugger/dbginit.c b/src/mpi/debugger/dbginit.c index 46024b95f9f..94677e501b5 100644 --- a/src/mpi/debugger/dbginit.c +++ b/src/mpi/debugger/dbginit.c @@ -350,8 +350,8 @@ static MPIR_Debugq *pool = 0; /* This routine is used to establish a queue of requests to allow the debugger easier access to the active requests. */ -void MPII_Debugq_remember(MPIR_Request * req, int rank, int tag, int context_id, - MPIR_Debugq ** queue) +void MPII_Debugq_remember(MPIR_Request * req, int rank, int tag, int context_id, const void *buf, + MPI_Aint count, MPIR_Debugq ** queue) { #if defined HAVE_DEBUGGER_SUPPORT MPIR_Debugq *p; @@ -383,6 +383,8 @@ void MPII_Debugq_remember(MPIR_Request * req, int rank, int tag, int context_id, p->tag = tag; p->rank = rank; p->context_id = context_id; + p->buf = buf; + p->count = count; DL_PREPEND(*queue, p); if (MPIR_REQUEST_KIND__SEND == req->kind) { diff --git a/src/mpi/debugger/dbgstub.c b/src/mpi/debugger/dbgstub.c index cbf4bbd053d..ceaed5c77ce 100644 --- a/src/mpi/debugger/dbgstub.c +++ b/src/mpi/debugger/dbgstub.c @@ -244,6 +244,10 @@ int dbgrI_field_offset(mqs_type * type, char *name) off = ((char *) &c.rank - (char *) &c); } else if (strcmp(name, "context_id") == 0) { off = ((char *) &c.context_id - (char *) &c); + } else if (strcmp(name, "buf") == 0) { + off = ((char *) &c.buf - (char *) &c); + } else if (strcmp(name, "count") == 0) { + off = ((char *) &c.count - (char *) &c); } else if (strcmp(name, "req") == 0) { off = ((char *) &c.req - (char *) &c); } else { diff --git a/src/mpi/debugger/mpich_dll_defs.h b/src/mpi/debugger/mpich_dll_defs.h index 5d05cd7b1f9..857ed8bc45c 100644 --- a/src/mpi/debugger/mpich_dll_defs.h +++ b/src/mpi/debugger/mpich_dll_defs.h @@ -47,6 +47,8 @@ typedef struct { int debugq_tag_offs; int debugq_rank_offs; int debugq_context_id_offs; + int debugq_user_buf_offs; + int debugq_user_count_offs; int debugq_req_offs; } mpich_image_info; diff --git a/src/mpid/ch3/src/mpid_imrecv.c b/src/mpid/ch3/src/mpid_imrecv.c index 8eff3e16e27..42d43926506 100644 --- a/src/mpid/ch3/src/mpid_imrecv.c +++ b/src/mpid/ch3/src/mpid_imrecv.c @@ -28,7 +28,7 @@ int MPID_Imrecv(void *buf, int count, MPI_Datatype datatype, rreq->dev.user_buf = buf; rreq->dev.user_count = count; rreq->dev.datatype = datatype; - MPII_RECVQ_REMEMBER(rreq, rreq->status.MPI_SOURCE, rreq->status.MPI_TAG, rreq->comm->recvcontext_id); + MPII_RECVQ_REMEMBER(rreq, rreq->status.MPI_SOURCE, rreq->status.MPI_TAG, rreq->comm->recvcontext_id, buf, count); #ifdef ENABLE_COMM_OVERRIDES MPIDI_Comm_get_vc(comm, rreq->status.MPI_SOURCE, &vc); diff --git a/src/mpid/ch3/src/mpid_irecv.c b/src/mpid/ch3/src/mpid_irecv.c index 29dfeee09bb..54bb145bc48 100644 --- a/src/mpid/ch3/src/mpid_irecv.c +++ b/src/mpid/ch3/src/mpid_irecv.c @@ -155,7 +155,7 @@ int MPID_Irecv(void * buf, MPI_Aint count, MPI_Datatype datatype, int rank, int *request = rreq; MPL_DBG_MSG_P(MPIDI_CH3_DBG_OTHER,VERBOSE,"request allocated, handle=0x%08x", rreq->handle); - MPII_RECVQ_REMEMBER(rreq, rank, tag, comm->recvcontext_id); + MPII_RECVQ_REMEMBER(rreq, rank, tag, comm->recvcontext_id, buf, count); MPIR_FUNC_EXIT; return mpi_errno; diff --git a/src/mpid/ch4/src/ch4_recv.h b/src/mpid/ch4/src/ch4_recv.h index 3b1c4e3784f..d56fb290344 100644 --- a/src/mpid/ch4/src/ch4_recv.h +++ b/src/mpid/ch4/src/ch4_recv.h @@ -289,7 +289,7 @@ MPL_STATIC_INLINE_PREFIX int MPID_Imrecv(void *buf, MPI_Aint count, MPI_Datatype MPIR_ERR_CHECK(mpi_errno); MPII_RECVQ_REMEMBER(message, message->status.MPI_SOURCE, message->status.MPI_TAG, - message->comm->recvcontext_id); + message->comm->recvcontext_id, buf, count); fn_exit: MPIR_FUNC_EXIT; @@ -319,7 +319,7 @@ MPL_STATIC_INLINE_PREFIX int MPID_Irecv(void *buf, MPIR_ERR_CHECK(mpi_errno); - MPII_RECVQ_REMEMBER(*request, rank, tag, comm->recvcontext_id); + MPII_RECVQ_REMEMBER(*request, rank, tag, comm->recvcontext_id, buf, count); fn_exit: MPIR_FUNC_EXIT; return mpi_errno; From 4cbea993da19fc802749e24e3c7d95b495a724c6 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Fri, 28 Jan 2022 07:10:09 -0600 Subject: [PATCH 459/607] debugger: Move queue pointers out of request union The debug queue pointers are used for both send and receive request types, and may be extended to others in the future. Place them outside of the union in MPIR_Request to simplify access. Since these are compiled out in a default build, the space needed is not a major concern. Always initialize the queue pointers to NULL so that unexposed requests are ignored at free time. --- src/include/mpir_debugger.h | 12 +++--------- src/include/mpir_request.h | 24 +++++++---------------- src/mpi/debugger/dbginit.c | 38 +++++++++++++++++++------------------ 3 files changed, 30 insertions(+), 44 deletions(-) diff --git a/src/include/mpir_debugger.h b/src/include/mpir_debugger.h index 383dd892fcc..f3f514543c5 100644 --- a/src/include/mpir_debugger.h +++ b/src/include/mpir_debugger.h @@ -42,15 +42,9 @@ void MPII_CommL_forget(MPIR_Comm * comm); #define MPII_COMML_REMEMBER(_a) MPII_CommL_remember(_a) #define MPII_COMML_FORGET(_a) MPII_CommL_forget(_a) #define MPII_REQUEST_CLEAR_DBG(_r) \ - if ((_r)->kind == MPIR_REQUEST_KIND__SEND) { \ - ((_r)->u.send.dbg = NULL); \ - } else if ((_r)->kind == MPIR_REQUEST_KIND__PREQUEST_SEND) { \ - ((_r)->u.persist.dbg = NULL); \ - } else if ((_r)->kind == MPIR_REQUEST_KIND__RECV || (_r)->kind == MPIR_REQUEST_KIND__MPROBE) { \ - ((_r)->u.recv.dbg = NULL); \ - } else { \ - MPIR_Assert(0); \ - } + (_r)->send = NULL; \ + (_r)->recv = NULL; \ + (_r)->unexp = NULL; #else static inline void MPII_Wait_for_debugger(void) diff --git a/src/include/mpir_request.h b/src/include/mpir_request.h index d29433d746e..27d3074d15d 100644 --- a/src/include/mpir_request.h +++ b/src/include/mpir_request.h @@ -204,18 +204,7 @@ struct MPIR_Request { MPIR_Errflag_t errflag; MPII_Coll_req_t coll; } nbc; /* kind : MPIR_REQUEST_KIND__COLL */ -#if defined HAVE_DEBUGGER_SUPPORT - struct { - struct MPIR_Debugq *dbg; - } send; /* kind : MPIR_REQUEST_KIND__SEND */ struct { - struct MPIR_Debugq *dbg; - } recv; /* kind : MPIR_REQUEST_KIND__RECV */ -#endif /* HAVE_DEBUGGER_SUPPORT */ - struct { -#if defined HAVE_DEBUGGER_SUPPORT - struct MPIR_Debugq *dbg; -#endif /* HAVE_DEBUGGER_SUPPORT */ /* Persistent requests have their own "real" requests */ struct MPIR_Request *real_request; MPIR_TSP_sched_t sched; @@ -236,6 +225,12 @@ struct MPIR_Request { } rma; /* kind : MPIR_REQUEST_KIND__RMA */ } u; +#if defined HAVE_DEBUGGER_SUPPORT + struct MPIR_Debugq *send; + struct MPIR_Debugq *recv; + struct MPIR_Debugq *unexp; +#endif /* HAVE_DEBUGGER_SUPPORT */ + struct MPIR_Request *next, *prev; /* Other, device-specific information */ @@ -424,12 +419,6 @@ static inline MPIR_Request *MPIR_Request_create_from_pool(MPIR_Request_kind_t ki req->comm = NULL; switch (kind) { - case MPIR_REQUEST_KIND__SEND: - case MPIR_REQUEST_KIND__PREQUEST_SEND: - case MPIR_REQUEST_KIND__RECV: - case MPIR_REQUEST_KIND__MPROBE: - MPII_REQUEST_CLEAR_DBG(req); - break; case MPIR_REQUEST_KIND__COLL: req->u.nbc.errflag = MPIR_ERR_NONE; req->u.nbc.coll.host_sendbuf = NULL; @@ -443,6 +432,7 @@ static inline MPIR_Request *MPIR_Request_create_from_pool(MPIR_Request_kind_t ki default: break; } + MPII_REQUEST_CLEAR_DBG(req); MPID_Request_create_hook(req); diff --git a/src/mpi/debugger/dbginit.c b/src/mpi/debugger/dbginit.c index 94677e501b5..ae086ac7beb 100644 --- a/src/mpi/debugger/dbginit.c +++ b/src/mpi/debugger/dbginit.c @@ -370,12 +370,13 @@ void MPII_Debugq_remember(MPIR_Request * req, int rank, int tag, int context_id, p = (MPIR_Debugq *) MPL_malloc(sizeof(MPIR_Debugq), MPL_MEM_DEBUG); if (!p) { /* Just ignore it */ - if (MPIR_REQUEST_KIND__SEND == req->kind) - req->u.send.dbg = NULL; - else if (MPIR_REQUEST_KIND__PREQUEST_SEND == req->kind) - req->u.persist.dbg = NULL; - else if (MPIR_REQUEST_KIND__RECV == req->kind) - req->u.recv.dbg = NULL; + if (queue == &MPIR_Sendq_head) { + req->send = NULL; + } else if (queue == &MPIR_Recvq_head) { + req->recv = NULL; + } else { + req->unexp = NULL; + } goto fn_exit; } } @@ -387,12 +388,12 @@ void MPII_Debugq_remember(MPIR_Request * req, int rank, int tag, int context_id, p->count = count; DL_PREPEND(*queue, p); - if (MPIR_REQUEST_KIND__SEND == req->kind) { - req->u.send.dbg = p; - } else if (MPIR_REQUEST_KIND__PREQUEST_SEND == req->kind) { - req->u.persist.dbg = p; - } else if (MPIR_REQUEST_KIND__RECV == req->kind) { - req->u.recv.dbg = p; + if (queue == &MPIR_Sendq_head) { + req->send = p; + } else if (queue == &MPIR_Recvq_head) { + req->recv = p; + } else { + req->unexp = p; } fn_exit: @@ -408,12 +409,13 @@ void MPII_Debugq_forget(MPIR_Request * req, MPIR_Debugq ** queue) MPID_THREAD_CS_ENTER(VCI, lock); MPID_THREAD_CS_ENTER(POBJ, lock); - if (MPIR_REQUEST_KIND__SEND == req->kind) - p = req->u.send.dbg; - else if (MPIR_REQUEST_KIND__PREQUEST_SEND == req->kind) - p = req->u.persist.dbg; - else if (MPIR_REQUEST_KIND__RECV == req->kind) - p = req->u.recv.dbg; + if (queue == &MPIR_Sendq_head) { + p = req->send; + } else if (queue == &MPIR_Recvq_head) { + p = req->recv; + } else { + p = req->unexp; + } if (!p) { /* Just ignore it */ MPID_THREAD_CS_EXIT(VCI, lock); From 5c32213235e90a04976344ea491da443f73f5d1c Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Thu, 20 Jan 2022 14:23:57 -0600 Subject: [PATCH 460/607] ch4: Support unexpected message debugging in self transport --- src/mpid/ch4/src/ch4_self.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mpid/ch4/src/ch4_self.c b/src/mpid/ch4/src/ch4_self.c index 1986deafb34..0769b76331b 100644 --- a/src/mpid/ch4/src/ch4_self.c +++ b/src/mpid/ch4/src/ch4_self.c @@ -135,6 +135,7 @@ int MPIDI_Self_isend(const void *buf, MPI_Aint count, MPI_Datatype datatype, int } else { sreq = MPIR_Request_create(MPIR_REQUEST_KIND__SEND); ENQUEUE_SELF_SEND(sreq, buf, count, datatype, tag, comm->context_id); + MPII_UNEXPQ_REMEMBER(sreq, rank, tag, comm->context_id); sreq->comm = comm; MPIR_Comm_add_ref(comm); MPIR_Datatype_add_ref_if_not_builtin(datatype); @@ -166,6 +167,7 @@ int MPIDI_Self_irecv(void *buf, MPI_Aint count, MPI_Datatype datatype, int rank, /* comm will be released by MPIR_Request_free(sreq) */ MPIR_Datatype_release_if_not_builtin(sreq->dev.ch4.self.datatype); MPIR_cc_set(&rreq->cc, 0); + MPII_UNEXPQ_FORGET(sreq); } else { ENQUEUE_SELF_RECV(rreq, buf, count, datatype, tag, comm->context_id); rreq->comm = comm; @@ -229,6 +231,7 @@ int MPIDI_Self_improbe(int rank, int tag, MPIR_Comm * comm, int context_offset, *message = MPIR_Request_create(MPIR_REQUEST_KIND__MPROBE); (*message)->dev.ch4.self.match_req = sreq; (*message)->comm = sreq->comm; /* set so we can check it in MPI_{M,Im}recv */ + MPII_UNEXPQ_FORGET(sreq); } else { *flag = FALSE; } From 6a78c71ea3c378635739d1a0ea654513f114ee01 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Mon, 17 Jan 2022 12:48:28 -0600 Subject: [PATCH 461/607] debugger: Use standalone receive queues Convert message queue debugging to use the standalone receive debug queues rather than accessing device information directly. --- src/mpi/debugger/dbgstub.c | 127 +++--------------------------- src/mpi/debugger/dll_mpich.c | 125 +++++++---------------------- src/mpi/debugger/mpich_dll_defs.h | 7 -- 3 files changed, 36 insertions(+), 223 deletions(-) diff --git a/src/mpi/debugger/dbgstub.c b/src/mpi/debugger/dbgstub.c index ceaed5c77ce..869a63caa51 100644 --- a/src/mpi/debugger/dbgstub.c +++ b/src/mpi/debugger/dbgstub.c @@ -7,11 +7,6 @@ #include "mpiimpl.h" -/* These are pointers to the static variables in ch3u_recvq.c or ch4r_recvq.c - that contains the *addresses* of the posted and unexpected queue head - pointers */ -extern MPIR_Request **const MPID_Recvq_posted_head_ptr, **const MPID_Recvq_unexpected_head_ptr; - #include "mpi_interface.h" /* This is from dbginit.c; it is not exported to other files */ @@ -36,14 +31,9 @@ extern MPIR_Comm_list MPIR_All_communicators; enum { TYPE_UNKNOWN = 0, TYPE_MPIR_COMM = 1, TYPE_MPIR_COMM_LIST = 2, - TYPE_MPIDI_REQUEST = 3, - TYPE_MPIDI_MESSAGE_MATCH = 4, - TYPE_MPIR_REQUEST = 5, - TYPE_MPIR_DEBUGQ = 6, - TYPE_MPIDI_MESSAGE_MATCH_PARTS = 7, - TYPE_MPIDI_DEVREQ_T = 8, - TYPE_MPIDIG_REQ_T = 9, - TYPE_MPIDIG_COMM_T = 10, + TYPE_MPIR_REQUEST = 3, + TYPE_MPIR_DEBUGQ = 4, + TYPE_MPIDIG_COMM_T = 5, } KnownTypes; /* The dll_mpich.c has a few places where it doesn't always use the most @@ -51,12 +41,9 @@ enum { TYPE_UNKNOWN = 0, have an example of each type, and return that value. */ static int knownTypesArray[] = { TYPE_UNKNOWN, TYPE_MPIR_COMM, - TYPE_MPIR_COMM_LIST, TYPE_MPIDI_REQUEST, - TYPE_MPIDI_MESSAGE_MATCH, TYPE_MPIR_REQUEST, + TYPE_MPIR_COMM_LIST, + TYPE_MPIR_REQUEST, TYPE_MPIR_DEBUGQ, - TYPE_MPIDI_MESSAGE_MATCH_PARTS, - TYPE_MPIDI_DEVREQ_T, - TYPE_MPIDIG_REQ_T, TYPE_MPIDIG_COMM_T, }; @@ -68,20 +55,10 @@ mqs_type *dbgrI_find_type(mqs_image * image, char *name, mqs_lang_code lang) curType = TYPE_MPIR_COMM; } else if (strcmp(name, "MPIR_Comm_list") == 0) { curType = TYPE_MPIR_COMM_LIST; - } else if (strcmp(name, "MPIDI_Request") == 0) { - curType = TYPE_MPIDI_REQUEST; - } else if (strcmp(name, "MPIDI_Message_match") == 0) { - curType = TYPE_MPIDI_MESSAGE_MATCH; - } else if (strcmp(name, "MPIDI_Message_match_parts_t") == 0) { - curType = TYPE_MPIDI_MESSAGE_MATCH_PARTS; } else if (strcmp(name, "MPIR_Request") == 0) { curType = TYPE_MPIR_REQUEST; } else if (strcmp(name, "MPIR_Debugq") == 0) { curType = TYPE_MPIR_DEBUGQ; - } else if (strcmp(name, "MPIDI_Devreq_t") == 0) { - curType = TYPE_MPIDI_DEVREQ_T; - } else if (strcmp(name, "MPIDIG_req_t") == 0) { - curType = TYPE_MPIDIG_REQ_T; } else if (strcmp(name, "MPIDIG_comm_t") == 0) { curType = TYPE_MPIDIG_COMM_T; } else { @@ -133,90 +110,6 @@ int dbgrI_field_offset(mqs_type * type, char *name) } } break; -#ifndef HAVE_CH4_DEBUGGER_SUPPORT - case TYPE_MPIDI_REQUEST: - { - struct MPIDI_Request c; - if (strcmp(name, "match") == 0) { - off = ((char *) &c.match - (char *) &c); - } else if (strcmp(name, "user_buf") == 0) { - off = ((char *) &c.user_buf - (char *) &c); - } else if (strcmp(name, "user_count") == 0) { - off = ((char *) &c.user_count - (char *) &c); - } else if (strcmp(name, "datatype") == 0) { - off = ((char *) &c.datatype - (char *) &c); - } else { - printf("Panic! Unrecognized mpidi request field %s\n", name); - } - } - break; - case TYPE_MPIDI_MESSAGE_MATCH: - { - if (strcmp(name, "parts") == 0) { - off = 0; - } else { - printf("Panic: Unrecognized mpidi_match fields %s\n", name); - } - } - break; - case TYPE_MPIDI_MESSAGE_MATCH_PARTS: - { - MPIDI_Message_match c; - if (strcmp(name, "tag") == 0) { - off = ((char *) &c.parts.tag - (char *) &c); - } else if (strcmp(name, "rank") == 0) { - off = ((char *) &c.parts.rank - (char *) &c); - } else if (strcmp(name, "context_id") == 0) { - off = ((char *) &c.parts.context_id - (char *) &c); - } else { - printf("Panic! Unrecognized message match parts field %s\n", name); - } - } - break; -#else - case TYPE_MPIDI_DEVREQ_T: - { - MPIDI_Devreq_t c; - if (strcmp(name, "am") == 0) { - off = ((char *) &c.ch4.am - (char *) &c); - } else { - printf("Panic! Unrecognized MPIDI_Devreq_t field %s\n", name); - } - } - break; - case TYPE_MPIDIG_REQ_T: - { - MPIDIG_req_t c; - if (strcmp(name, "buffer") == 0) { - off = ((char *) &c.buffer - (char *) &c); - } else if (strcmp(name, "count") == 0) { - off = ((char *) &c.count - (char *) &c); - } else if (strcmp(name, "rank") == 0) { - off = ((char *) &c.u.recv.source - (char *) &c); - } else if (strcmp(name, "tag") == 0) { - off = ((char *) &c.u.recv.tag - (char *) &c); - } else if (strcmp(name, "context_id") == 0) { - off = ((char *) &c.u.recv.context_id - (char *) &c); - } else if (strcmp(name, "datatype") == 0) { - off = ((char *) &c.datatype - (char *) &c); - } else { - printf("Panic! Unrecognized MPIDIG_req_t field %s\n", name); - } - } - break; - case TYPE_MPIDIG_COMM_T: - { - MPIDIG_comm_t c; - if (strcmp(name, "posted_head_ptr") == 0) { - off = ((char *) &c.posted_head_ptr - (char *) &c); - } else if (strcmp(name, "unexp_head_ptr") == 0) { - off = ((char *) &c.unexp_head_ptr - (char *) &c); - } else { - printf("Panic! Unrecognized MPIDIG_comm_t field %s\n", name); - } - } - break; -#endif case TYPE_MPIR_REQUEST: { MPIR_Request c; @@ -277,13 +170,11 @@ int dbgrI_find_symbol(mqs_image * image, char *name, mqs_taddr_t * loc) printf("all communicators head as pointer %p\n", &MPIR_All_communicators); printf("head is %p\n", MPIR_All_communicators.head); return mqs_ok; - } else if (strcmp(name, "MPID_Recvq_posted_head_ptr") == 0) { - *loc = (mqs_taddr_t) & MPID_Recvq_posted_head_ptr; - printf("Address of ptr to posted head ptr = %p\n", &MPID_Recvq_posted_head_ptr); - printf("Address of posted head ptr = %p\n", MPID_Recvq_posted_head_ptr); + } else if (strcmp(name, "MPIR_Recvq_head") == 0) { + *loc = (mqs_taddr_t) & MPIR_Recvq_head; return mqs_ok; - } else if (strcmp(name, "MPID_Recvq_unexpected_head_ptr") == 0) { - *loc = (mqs_taddr_t) & MPID_Recvq_unexpected_head_ptr; + } else if (strcmp(name, "MPIR_Unexpq_head") == 0) { + *loc = (mqs_taddr_t) & MPIR_Unexpq_head; return mqs_ok; } else if (strcmp(name, "MPIR_Sendq_head") == 0) { *loc = (mqs_taddr_t) & MPIR_Sendq_head; diff --git a/src/mpi/debugger/dll_mpich.c b/src/mpi/debugger/dll_mpich.c index 0331553d581..f759944d238 100644 --- a/src/mpi/debugger/dll_mpich.c +++ b/src/mpi/debugger/dll_mpich.c @@ -287,87 +287,17 @@ int mqs_image_has_queues(mqs_image * image, const char **message) } } - /* Now the receive queues. The receive queues contain MPIR_Request - * objects, and the various fields are within types in that object. - * To simplify the eventual access, we compute all offsets relative to the - * request. This means diving into the types that make of the - * request definition */ + /* Request queues */ { - mqs_type *req_type = dbgr_find_type(image, (char *) "MPIR_Request", mqs_lang_c); + mqs_type *req_type = dbgr_find_type(image, (char *) "MPIR_Debugq", mqs_lang_c); if (req_type) { - int dev_offs; - dev_offs = dbgr_field_offset(req_type, (char *) "dev"); - i_info->req_status_offs = dbgr_field_offset(req_type, (char *) "status"); - i_info->req_cc_offs = dbgr_field_offset(req_type, (char *) "cc"); - i_info->req_next_offs = dbgr_field_offset(req_type, (char *) "next"); - if (dev_offs >= 0) { - i_info->req_dev_offs = dev_offs; -#ifdef HAVE_CH4_DEBUGGER_SUPPORT - /* Only support CH4 active message */ - /* buffer, count, rank, tag, context_id and datatype are stored in AM request */ - mqs_type *dreq_type = dbgr_find_type(image, (char *) "MPIDI_Devreq_t", mqs_lang_c); - - int am_offs = dev_offs + dbgr_field_offset(dreq_type, (char *) "am"); - mqs_type *am_req_type = dbgr_find_type(image, (char *) "MPIDIG_req_t", mqs_lang_c); - i_info->req_user_buf_offs = - am_offs + dbgr_field_offset(am_req_type, (char *) "buffer"); - i_info->req_user_count_offs = - am_offs + dbgr_field_offset(am_req_type, (char *) "count"); - i_info->req_rank_offs = am_offs + dbgr_field_offset(am_req_type, (char *) "rank"); - i_info->req_tag_offs = am_offs + dbgr_field_offset(am_req_type, (char *) "tag"); - i_info->req_context_id_offs = - am_offs + dbgr_field_offset(am_req_type, (char *) "context_id"); - i_info->req_datatype_offs = - am_offs + dbgr_field_offset(am_req_type, (char *) "datatype"); -#else - /* CH3 specific request definition */ - mqs_type *dreq_type = dbgr_find_type(image, (char *) "MPIDI_Request", - mqs_lang_c); - if (dreq_type) { - int loff, match_offs; - loff = dbgr_field_offset(dreq_type, (char *) "user_buf"); - i_info->req_user_buf_offs = dev_offs + loff; - loff = dbgr_field_offset(dreq_type, (char *) "user_count"); - i_info->req_user_count_offs = dev_offs + loff; - loff = dbgr_field_offset(dreq_type, (char *) "datatype"); - i_info->req_datatype_offs = dev_offs + loff; - match_offs = dbgr_field_offset(dreq_type, (char *) "match"); - if (match_offs >= 0) { - mqs_type *match_type = - dbgr_find_type(image, (char *) "MPIDI_Message_match", mqs_lang_c); - if (match_type) { - int parts_offs = dbgr_field_offset(match_type, (char *) "parts"); - if (parts_offs >= 0) { - mqs_type *parts_type = - dbgr_find_type(image, (char *) "MPIDI_Message_match_parts_t", - mqs_lang_c); - if (parts_type) { - int moff; - moff = dbgr_field_offset(parts_type, (char *) "tag"); - i_info->req_tag_offs = dev_offs + match_offs + moff; - moff = dbgr_field_offset(parts_type, (char *) "rank"); - i_info->req_rank_offs = dev_offs + match_offs + moff; - moff = dbgr_field_offset(parts_type, (char *) "context_id"); - i_info->req_context_id_offs = dev_offs + match_offs + moff; - } - } - } - } - } -#endif - } - } - } - - /* Send queues use a separate system */ - { - mqs_type *sreq_type = dbgr_find_type(image, (char *) "MPIR_Debugq", mqs_lang_c); - if (sreq_type) { - i_info->debugq_next_offs = dbgr_field_offset(sreq_type, (char *) "next"); - i_info->debugq_tag_offs = dbgr_field_offset(sreq_type, (char *) "tag"); - i_info->debugq_rank_offs = dbgr_field_offset(sreq_type, (char *) "rank"); - i_info->debugq_context_id_offs = dbgr_field_offset(sreq_type, (char *) "context_id"); - i_info->debugq_req_offs = dbgr_field_offset(sreq_type, (char *) "req"); + i_info->debugq_next_offs = dbgr_field_offset(req_type, (char *) "next"); + i_info->debugq_tag_offs = dbgr_field_offset(req_type, (char *) "tag"); + i_info->debugq_rank_offs = dbgr_field_offset(req_type, (char *) "rank"); + i_info->debugq_context_id_offs = dbgr_field_offset(req_type, (char *) "context_id"); + i_info->debugq_user_buf_offs = dbgr_field_offset(req_type, (char *) "buf"); + i_info->debugq_user_count_offs = dbgr_field_offset(req_type, (char *) "count"); + i_info->debugq_req_offs = dbgr_field_offset(req_type, (char *) "req"); } } @@ -416,7 +346,6 @@ int mqs_process_has_queues(mqs_process * proc, char **msg) mpich_process_info *p_info = (mpich_process_info *) dbgr_get_process_info(proc); mqs_image *image = dbgr_get_image(proc); mpich_image_info *i_info = (mpich_image_info *) dbgr_get_image_info(image); - mqs_taddr_t head_ptr; /* Don't bother with a pop up here, it's unlikely to be helpful */ *msg = 0; @@ -427,13 +356,11 @@ int mqs_process_has_queues(mqs_process * proc, char **msg) return err_all_communicators; /* Check for the receive and send queues */ - if (dbgr_find_symbol(image, (char *) "MPID_Recvq_posted_head_ptr", &head_ptr) != mqs_ok) + if (dbgr_find_symbol(image, (char *) "MPIR_Recvq_head", &p_info->posted_base) != mqs_ok) return err_posted; - p_info->posted_base = fetch_pointer(proc, head_ptr, p_info); - if (dbgr_find_symbol(image, (char *) "MPID_Recvq_unexpected_head_ptr", &head_ptr) != mqs_ok) + if (dbgr_find_symbol(image, (char *) "MPIR_Unexpq_head", &p_info->unexpected_base) != mqs_ok) return err_unexpected; - p_info->unexpected_base = fetch_pointer(proc, head_ptr, p_info); /* Send queues are optional */ if (dbgr_find_symbol(image, (char *) "MPIR_Sendq_head", &p_info->sendq_base) == mqs_ok) { @@ -462,9 +389,9 @@ const char *mqs_dll_error_string(int errcode) return "Could not read a communicator's group from the process (probably a store corruption)"; case err_unexpected: - return "Failed to find symbol MPID_Recvq_unexpected_head_ptr"; + return "Failed to find symbol MPIR_Unexpq_head"; case err_posted: - return "Failed to find symbol MPID_Recvq_posted_head_ptr"; + return "Failed to find symbol MPIR_Recvq_head"; } return "Unknown error code"; } @@ -636,7 +563,7 @@ static int fetch_receive(mqs_process * proc, mpich_process_info * p_info, #endif while (base != 0) { /* Check this entry to see if the context matches */ - int16_t actual_context = fetch_int16(proc, base + i_info->req_context_id_offs, p_info); + int16_t actual_context = fetch_int16(proc, base + i_info->debugq_context_id_offs, p_info); #ifdef DEBUG_LIST_ITER initLogFile(); @@ -644,11 +571,13 @@ static int fetch_receive(mqs_process * proc, mpich_process_info * p_info, #endif if (actual_context == wanted_context) { /* Found a request for this communicator */ - int tag = fetch_int(proc, base + i_info->req_tag_offs, p_info); - int rank = fetch_int16(proc, base + i_info->req_rank_offs, p_info); - int is_complete = fetch_int(proc, base + i_info->req_cc_offs, p_info); - mqs_tword_t user_buffer = fetch_pointer(proc, base + i_info->req_user_buf_offs, p_info); - int user_count = fetch_int(proc, base + i_info->req_user_count_offs, p_info); + int tag = fetch_int(proc, base + i_info->debugq_tag_offs, p_info); + int rank = fetch_int16(proc, base + i_info->debugq_rank_offs, p_info); + mqs_taddr_t rreq = fetch_pointer(proc, base + i_info->debugq_req_offs, p_info); + mqs_tword_t is_complete = fetch_int(proc, rreq + i_info->req_cc_offs, p_info); + mqs_tword_t user_buffer = + fetch_pointer(proc, base + i_info->debugq_user_buf_offs, p_info); + int user_count = fetch_int(proc, base + i_info->debugq_user_count_offs, p_info); /* Return -1 for ANY_TAG or ANY_SOURCE */ res->desired_tag = (tag >= 0) ? tag : -1; @@ -671,11 +600,11 @@ static int fetch_receive(mqs_process * proc, mpich_process_info * p_info, res->status = (is_complete != 0) ? mqs_st_pending : mqs_st_complete; /* Don't forget to step the queue ! */ - p_info->next_msg = base + i_info->req_next_offs; + p_info->next_msg = base + i_info->debugq_next_offs; return mqs_ok; } else { /* Try the next one */ - base = fetch_pointer(proc, base + i_info->req_next_offs, p_info); + base = fetch_pointer(proc, base + i_info->debugq_next_offs, p_info); } } #if 0 @@ -744,10 +673,10 @@ static int fetch_receive(mqs_process * proc, mpich_process_info * p_info, } /* Don't forget to step the queue ! */ - p_info->next_msg = base + i_info->next_offs; + p_info->next_msg = base + i_info->debugq_next_offs; return mqs_ok; } else { /* Try the next one */ - base = fetch_pointer(proc, base + i_info->next_offs, p_info); + base = fetch_pointer(proc, base + i_info->debugq_next_offs, p_info); } } #endif @@ -795,8 +724,8 @@ static int fetch_send(mqs_process * proc, mpich_process_info * p_info, mqs_pendi mqs_taddr_t data = 0; mqs_taddr_t sreq = fetch_pointer(proc, base + i_info->debugq_req_offs, p_info); mqs_tword_t is_complete = fetch_int(proc, sreq + i_info->req_cc_offs, p_info); - data = fetch_pointer(proc, sreq + i_info->req_user_buf_offs, p_info); - length = fetch_int(proc, sreq + i_info->req_user_count_offs, p_info); + data = fetch_pointer(proc, base + i_info->debugq_user_buf_offs, p_info); + length = fetch_int(proc, base + i_info->debugq_user_count_offs, p_info); /* mqs_tword_t complete=0; */ #ifdef DEBUG_LIST_ITER diff --git a/src/mpi/debugger/mpich_dll_defs.h b/src/mpi/debugger/mpich_dll_defs.h index 857ed8bc45c..d3b11d6684d 100644 --- a/src/mpi/debugger/mpich_dll_defs.h +++ b/src/mpi/debugger/mpich_dll_defs.h @@ -33,14 +33,7 @@ typedef struct { /* Fields in MPIR_Request (including structures within the request) */ int req_status_offs; int req_cc_offs; - int req_dev_offs; - int req_tag_offs; - int req_rank_offs; - int req_context_id_offs; - int req_user_buf_offs; - int req_user_count_offs; int req_datatype_offs; - int req_next_offs; /* Fields in MPIR_Debugq */ int debugq_next_offs; From b229641ec76b562e6ecd7ad3559fcac9da969071 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Fri, 28 Jan 2022 13:05:10 -0600 Subject: [PATCH 462/607] debugger: Amend tvtest.c to return non-zero value on failure tvtest.c is a basic test of the debug queue interfaces. Have it return a non-zero return code on failure in order to integrate it into our automated testing. --- src/mpi/debugger/tvtest.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mpi/debugger/tvtest.c b/src/mpi/debugger/tvtest.c index db21ddaf32c..0ea715851ce 100644 --- a/src/mpi/debugger/tvtest.c +++ b/src/mpi/debugger/tvtest.c @@ -241,17 +241,20 @@ int showQueues(int nComm, int expected) mqs_next_communicator(&process); } + int ret = 0; if (nFound < expected) { fprintf(stderr, "Error: expected to find %d queue entries but only saw %d\n", expected, nFound); + ret = 1; } if (nCommFound < nComm) { fprintf(stderr, "Error: expected to find %d comms but only saw %d\n", nComm, nCommFound); + ret = 1; } fflush(stdout); fflush(stderr); - return 0; + return ret; } From c1d7dbea7bf1fb8630bc9160114c341777f389d7 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Fri, 11 Feb 2022 16:09:21 -0600 Subject: [PATCH 463/607] ch3: Fix MPII_RECVQ_REMEMBER usage Add missing buffer and count arguments. --- src/mpid/ch3/src/mpid_recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mpid/ch3/src/mpid_recv.c b/src/mpid/ch3/src/mpid_recv.c index 1e14a4aaece..df5186ce8cd 100644 --- a/src/mpid/ch3/src/mpid_recv.c +++ b/src/mpid/ch3/src/mpid_recv.c @@ -177,7 +177,7 @@ int MPID_Recv(void * buf, MPI_Aint count, MPI_Datatype datatype, int rank, int t { MPL_DBG_MSG_P(MPIDI_CH3_DBG_OTHER,VERBOSE, "request allocated, handle=0x%08x", rreq->handle); - MPII_RECVQ_REMEMBER(rreq, rank, tag, comm->recvcontext_id); + MPII_RECVQ_REMEMBER(rreq, rank, tag, comm->recvcontext_id, buf, count); } else { From 207bca7b08715aea92d645c8778b96a590882af8 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 8 Feb 2022 17:52:28 -0600 Subject: [PATCH 464/607] test: permanently xfail collective length checks Since we have no plan of supporting collective length checks in general, hard code the xfail in the testlist. This avoids making general users alarmed that not tests are passing. We can easily revert this commit once our plan changes. --- test/mpi/errors/coll/testlist | 26 +++++++++++++------------- test/mpi/maint/jenkins/xfail.conf | 15 --------------- 2 files changed, 13 insertions(+), 28 deletions(-) diff --git a/test/mpi/errors/coll/testlist b/test/mpi/errors/coll/testlist index f147a400fc5..92cc692075a 100644 --- a/test/mpi/errors/coll/testlist +++ b/test/mpi/errors/coll/testlist @@ -7,17 +7,17 @@ nb_rerr 2 reduce_local 1 bcastlength 4 ibcastlength 4 -reducelength 4 -ireducelength 4 -allreducelength 4 -iallreducelength 4 -reduceop 4 -ireduceop 4 -gatherlength 4 -igatherlength 4 -scatterlength 4 -iscatterlength 4 -allgatherlength 4 -iallgatherlength 4 -alltoalllength 4 +reducelength 4 xfail=ticket3655 +ireducelength 4 xfail=ticket3655 +allreducelength 4 xfail=ticket3655 +iallreducelength 4 xfail=ticket3655 +reduceop 4 xfail=ticket3655 +ireduceop 4 xfail=ticket3655 +gatherlength 4 xfail=ticket3655 +igatherlength 4 xfail=ticket3655 +scatterlength 4 xfail=ticket3655 +iscatterlength 4 xfail=ticket3655 +allgatherlength 4 xfail=ticket3655 +iallgatherlength 4 xfail=ticket3655 +alltoalllength 4 xfail=ticket3655 diff --git a/test/mpi/maint/jenkins/xfail.conf b/test/mpi/maint/jenkins/xfail.conf index ac33f85c122..41e982b6577 100644 --- a/test/mpi/maint/jenkins/xfail.conf +++ b/test/mpi/maint/jenkins/xfail.conf @@ -58,21 +58,6 @@ * * asan ch4:ucx * /^.*262144\|65530\|16000000.*/ xfail=ticket0 rma/testlist.dtp # Bug - Github Issue https://github.com/pmodels/mpich/issues/3618 * * * ch4:ucx * /^darray_pack/ xfail=ticket0 datatype/testlist -# Collectivess other than bcast don't currently detect mismatched datatype lengths -* * * * * /^reducelength/ xfail=ticket3655 errors/coll/testlist -* * * * * /^ireducelength/ xfail=ticket3655 errors/coll/testlist -* * * * * /^allreducelength/ xfail=ticket3655 errors/coll/testlist -* * * * * /^iallreducelength/ xfail=ticket3655 errors/coll/testlist -* * * * * /^reduceop/ xfail=ticket3655 errors/coll/testlist -* * * * * /^ireduceop/ xfail=ticket3655 errors/coll/testlist -* * * * * /^gatherlength/ xfail=ticket3655 errors/coll/testlist -* * * * * /^igatherlength/ xfail=ticket3655 errors/coll/testlist -* * * * * /^allgatherlength/ xfail=ticket3655 errors/coll/testlist -* * * * * /^iallgatherlength/ xfail=ticket3655 errors/coll/testlist -* * * * * /^alltoalllength/ xfail=ticket3655 errors/coll/testlist -* * * * * /^ialltoalllength/ xfail=ticket3655 errors/coll/testlist -* * * * * /^scatterlength/ xfail=ticket3655 errors/coll/testlist -* * * * * /^iscatterlength/ xfail=ticket3655 errors/coll/testlist # some of the bcastlength test that is still failing * * * ch3:ofi * /^ibcastlength/ xfail=issue3775 errors/coll/testlist * * * ch3:ofi * /^bcastlength/ xfail=issue4373 errors/coll/testlist From c4e999add5017f57f0bf20010dfc31e952174ccb Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Fri, 4 Feb 2022 09:59:36 -0600 Subject: [PATCH 465/607] config.rpath: Add support for Intel OneAPI compilers Add in checks for icx and ifx compilers, which are replacing icc and ifort. --- confdb/config.rpath | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/confdb/config.rpath b/confdb/config.rpath index 1effeeecc2a..9a8d62e98be 100755 --- a/confdb/config.rpath +++ b/confdb/config.rpath @@ -76,7 +76,7 @@ else ecc*) wl='-Wl,' ;; - icc* | ifort*) + icc* | icx* | ifort* | ifx*) wl='-Wl,' ;; lf95*) @@ -233,7 +233,7 @@ if test "$with_gnu_ld" = yes; then enable_dtags_flag="${wl}--enable-new-dtags" disable_dtags_flag="${wl}--disable-new-dtags" else - case $cc_basename in ifort*) + case $cc_basename in ifort* | ifx*) enable_dtags_flag="${wl}--enable-new-dtags" disable_dtags_flag="${wl}--disable-new-dtags" ;; @@ -380,7 +380,7 @@ else ;; darwin* | rhapsody*) hardcode_direct=no - if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then + if { case $cc_basename in ifort* | ifx*) true;; *) test "$GCC" = yes;; esac; }; then : else ld_shlibs=no From b61e7d4fafa251565a6761ff45f8d398585c3fb9 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Mon, 14 Feb 2022 13:01:52 -0600 Subject: [PATCH 466/607] config/fortran: Determine FCEXT earlier Once we know if we are building either the mpi or mpi_f08 module, determine FCEXT so it can be used properly in configure tests. --- configure.ac | 9 +++++---- src/binding/fortran/use_mpi/subconfigure.m4 | 5 ----- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index 0df2d15d249..7c84f9a081e 100644 --- a/configure.ac +++ b/configure.ac @@ -1780,6 +1780,11 @@ if test "$enable_f90" = "yes" -o "$enable_f08" = "yes"; then programs, you need to install a Fortran compiler such as gfortran or ifort before you can proceed.]) fi + + # Determine the extension for Fortran 90 files (it isn't always .f90) + PAC_FC_EXT + FCEXT=$ac_fc_srcext + AC_SUBST(FCEXT) fi if test "$enable_f77" = yes ; then @@ -2068,10 +2073,6 @@ if test "$enable_f90" = "yes" -o "$enable_f08" = "yes"; then fi fi - # Determine the extension for Fortran 90 files (it isn't always .f90) - FCEXT=$ac_fc_srcext - AC_SUBST(FCEXT) - if test "$FC" = "no" ; then if test "$fc_rejected" = "yes" ; then AC_MSG_ERROR([Could not find a usable Fortran 90 compiler. The compiler $oldFC may be incompatible with the Fortran 77 compiler $F77; check the output of configure and consult the installation manuals]) diff --git a/src/binding/fortran/use_mpi/subconfigure.m4 b/src/binding/fortran/use_mpi/subconfigure.m4 index cbfae2e4758..64b4fd133cb 100644 --- a/src/binding/fortran/use_mpi/subconfigure.m4 +++ b/src/binding/fortran/use_mpi/subconfigure.m4 @@ -17,11 +17,6 @@ AC_MSG_NOTICE([RUNNING CONFIGURE FOR F90 CODE]) AC_PROG_LN_S -# Determine the extension for Fortran 90 files (it isn't always .f90) -PAC_FC_EXT -FCEXT=$ac_fc_srcext -AC_SUBST(FCEXT) - # Determine the precision and range of the standard Fortran types. This # isn't quite enough for a full implementation of the Type_create_f90_xxx # routines, but will handle most programs. We can extend this by trying to From 9690834fd131a3578a1b699e693ae13146b1de53 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Wed, 16 Feb 2022 08:16:17 -0600 Subject: [PATCH 467/607] test/f08: Remove use of block feature F08 blocks allow for declarations inside them, but these tests did not utilize the feature. Some compilers, e.g. ifx, do not support block yet. Remove usage since the test output does not change either way. --- test/mpi/f08/subarray/test10.f90 | 46 +++++++++++++--------------- test/mpi/f08/subarray/test11.f90 | 50 +++++++++++++------------------ test/mpi/f08/subarray/test12.f90 | 48 +++++++++++++----------------- test/mpi/f08/subarray/test14.f90 | 51 ++++++++++++++------------------ test/mpi/f08/subarray/test15.f90 | 51 ++++++++++++++------------------ 5 files changed, 105 insertions(+), 141 deletions(-) diff --git a/test/mpi/f08/subarray/test10.f90 b/test/mpi/f08/subarray/test10.f90 index be58752c1d0..cceb2491434 100644 --- a/test/mpi/f08/subarray/test10.f90 +++ b/test/mpi/f08/subarray/test10.f90 @@ -34,35 +34,29 @@ program main print *, "rank 0 sends ", sint endif - block - - call mpi_isend(sint, 1, MPI_INTEGER, 1, 567, MPI_COMM_WORLD, request, ierr); - if (ierr .ne. MPI_SUCCESS) then - print *,"PE ",rank,": ",name,": mpi_isend exited in error (",ierr,")" - errs = errs + 1 - endif + call mpi_isend(sint, 1, MPI_INTEGER, 1, 567, MPI_COMM_WORLD, request, ierr); + if (ierr .ne. MPI_SUCCESS) then + print *,"PE ",rank,": ",name,": mpi_isend exited in error (",ierr,")" + errs = errs + 1 + endif - call mpi_wait(request, status, ierr) - if (ierr .ne. MPI_SUCCESS) then - print *,"PE ",rank,": ",name,": mpi_wait exited in error (",ierr,")" - errs = errs + 1 - endif - end block + call mpi_wait(request, status, ierr) + if (ierr .ne. MPI_SUCCESS) then + print *,"PE ",rank,": ",name,": mpi_wait exited in error (",ierr,")" + errs = errs + 1 + endif else - block - - call mpi_irecv(sint, 1, MPI_INTEGER, 0, 567, MPI_COMM_WORLD, request, ierr); - if (ierr .ne. MPI_SUCCESS) then - print *,"PE ",rank,": ",name,"mpi_irecv exited in error (",ierr,")" - errs = errs + 1 - endif + call mpi_irecv(sint, 1, MPI_INTEGER, 0, 567, MPI_COMM_WORLD, request, ierr); + if (ierr .ne. MPI_SUCCESS) then + print *,"PE ",rank,": ",name,"mpi_irecv exited in error (",ierr,")" + errs = errs + 1 + endif - call mpi_wait(request, status, ierr) - if (ierr .ne. MPI_SUCCESS) then - print *,"PE ",rank,": ",name,": mpi_wait exited in error (",ierr,")" - errs = errs + 1 - endif - end block + call mpi_wait(request, status, ierr) + if (ierr .ne. MPI_SUCCESS) then + print *,"PE ",rank,": ",name,": mpi_wait exited in error (",ierr,")" + errs = errs + 1 + endif if (verbose) print *, "rank 1 receives ",sint if (sint .eq. 789) then diff --git a/test/mpi/f08/subarray/test11.f90 b/test/mpi/f08/subarray/test11.f90 index 6345117b942..777aeedddc3 100644 --- a/test/mpi/f08/subarray/test11.f90 +++ b/test/mpi/f08/subarray/test11.f90 @@ -32,39 +32,31 @@ program main iar(i)=i end do - block - - call mpi_isend(iar, 10, MPI_INTEGER, 1, 567, MPI_COMM_WORLD, request, ierr); - if (ierr .ne. MPI_SUCCESS) then - if (verbose) print *,"PE ",rank,": ",name,": mpi_isend exited in error (",ierr,")" - errs = errs + 1 - endif - - call mpi_wait(request, status, ierr) - if (ierr .ne. MPI_SUCCESS) then - if (verbose) print *,"PE ",rank,": ",name,": mpi_wait exited in error (",ierr,")" - errs = errs + 1 - endif + call mpi_isend(iar, 10, MPI_INTEGER, 1, 567, MPI_COMM_WORLD, request, ierr); + if (ierr .ne. MPI_SUCCESS) then + if (verbose) print *,"PE ",rank,": ",name,": mpi_isend exited in error (",ierr,")" + errs = errs + 1 + endif - end block + call mpi_wait(request, status, ierr) + if (ierr .ne. MPI_SUCCESS) then + if (verbose) print *,"PE ",rank,": ",name,": mpi_wait exited in error (",ierr,")" + errs = errs + 1 + endif else if (rank .eq. 1) then - block - - call mpi_irecv(iar, 10, MPI_INTEGER, 0, 567, MPI_COMM_WORLD, request, ierr); - if (ierr .ne. MPI_SUCCESS) then - if (verbose) print *,"PE ",rank,": ",name,"mpi_irecv exited in error (",ierr,")" - errs = errs + 1 - endif - - call mpi_wait(request, status, ierr) - if (ierr .ne. MPI_SUCCESS) then - if (verbose) print *,"PE ",rank,": ",name,": mpi_wait exited in error (",ierr,")" - errs = errs + 1 - endif - - end block + call mpi_irecv(iar, 10, MPI_INTEGER, 0, 567, MPI_COMM_WORLD, request, ierr); + if (ierr .ne. MPI_SUCCESS) then + if (verbose) print *,"PE ",rank,": ",name,"mpi_irecv exited in error (",ierr,")" + errs = errs + 1 + endif + + call mpi_wait(request, status, ierr) + if (ierr .ne. MPI_SUCCESS) then + if (verbose) print *,"PE ",rank,": ",name,": mpi_wait exited in error (",ierr,")" + errs = errs + 1 + endif do i=1,10 if (iar(i) .ne. i) then diff --git a/test/mpi/f08/subarray/test12.f90 b/test/mpi/f08/subarray/test12.f90 index 02352f56494..0125642ecdb 100644 --- a/test/mpi/f08/subarray/test12.f90 +++ b/test/mpi/f08/subarray/test12.f90 @@ -33,21 +33,17 @@ program main iar(i)=i end do - block - - call mpi_isend(iar(2:7), 6, MPI_INTEGER, 1, 678, MPI_COMM_WORLD, request, ierr); - if (ierr .ne. MPI_SUCCESS) then - if (verbose) print *,"PE ",rank,": ",name,": mpi_isend exited in error (",ierr,")" - errs = errs + 1 - endif - - call mpi_wait(request, status, ierr) - if (ierr .ne. MPI_SUCCESS) then - if (verbose) print *,"PE ",rank,": ",name,": mpi_wait exited in error (",ierr,")" - errs = errs + 1 - endif + call mpi_isend(iar(2:7), 6, MPI_INTEGER, 1, 678, MPI_COMM_WORLD, request, ierr); + if (ierr .ne. MPI_SUCCESS) then + if (verbose) print *,"PE ",rank,": ",name,": mpi_isend exited in error (",ierr,")" + errs = errs + 1 + endif - end block + call mpi_wait(request, status, ierr) + if (ierr .ne. MPI_SUCCESS) then + if (verbose) print *,"PE ",rank,": ",name,": mpi_wait exited in error (",ierr,")" + errs = errs + 1 + endif else if (rank .eq. 1) then do i=1,10 @@ -58,21 +54,17 @@ program main iar_check(i)=i end do - block - - call mpi_irecv(iar(2:7), 6, MPI_INTEGER, 0, 678, MPI_COMM_WORLD, request, ierr); - if (ierr .ne. MPI_SUCCESS) then - if (verbose) print *,"PE ",rank,": ",name,"mpi_irecv exited in error (",ierr,")" - errs = errs + 1 - endif - - call mpi_wait(request, status, ierr) - if (ierr .ne. MPI_SUCCESS) then - if (verbose) print *,"PE ",rank,": ",name,": mpi_wait exited in error (",ierr,")" - errs = errs + 1 - endif + call mpi_irecv(iar(2:7), 6, MPI_INTEGER, 0, 678, MPI_COMM_WORLD, request, ierr); + if (ierr .ne. MPI_SUCCESS) then + if (verbose) print *,"PE ",rank,": ",name,"mpi_irecv exited in error (",ierr,")" + errs = errs + 1 + endif - end block + call mpi_wait(request, status, ierr) + if (ierr .ne. MPI_SUCCESS) then + if (verbose) print *,"PE ",rank,": ",name,": mpi_wait exited in error (",ierr,")" + errs = errs + 1 + endif do i=1,10 if (iar(i) .ne. iar_check(i)) then diff --git a/test/mpi/f08/subarray/test14.f90 b/test/mpi/f08/subarray/test14.f90 index f102755bb71..09ec854b08a 100644 --- a/test/mpi/f08/subarray/test14.f90 +++ b/test/mpi/f08/subarray/test14.f90 @@ -57,38 +57,31 @@ program main if (rank .eq. 0) then - block - - call mpi_isend(iar_2d(:,2:6:2), 27, MPI_INTEGER, 1, 123, MPI_COMM_WORLD, request, ierr); - if (ierr .ne. MPI_SUCCESS) then - if (verbose) print *,"PE ",rank,": ",name,": mpi_isend exited in error (",ierr,")" - errs = errs + 1 - endif - - call mpi_wait(request, status, ierr) - if (ierr .ne. MPI_SUCCESS) then - if (verbose) print *,"PE ",rank,": ",name,": mpi_wait exited in error (",ierr,")" - errs = errs + 1 - endif - - end block + call mpi_isend(iar_2d(:,2:6:2), 27, MPI_INTEGER, 1, 123, MPI_COMM_WORLD, request, ierr); + if (ierr .ne. MPI_SUCCESS) then + if (verbose) print *,"PE ",rank,": ",name,": mpi_isend exited in error (",ierr,")" + errs = errs + 1 + endif + + call mpi_wait(request, status, ierr) + if (ierr .ne. MPI_SUCCESS) then + if (verbose) print *,"PE ",rank,": ",name,": mpi_wait exited in error (",ierr,")" + errs = errs + 1 + endif else if (rank .eq. 1) then - block - - call mpi_irecv(iar_2d(:,2:6:2), 27, MPI_INTEGER, 0, 123, MPI_COMM_WORLD, request, ierr); - if (ierr .ne. MPI_SUCCESS) then - if (verbose) print *,"PE ",rank,": ",name,"mpi_irecv exited in error (",ierr,")" - errs = errs + 1 - endif - - call mpi_wait(request, status, ierr) - if (ierr .ne. MPI_SUCCESS) then - if (verbose) print *,"PE ",rank,": ",name,": mpi_wait exited in error (",ierr,")" - errs = errs + 1 - endif - end block + call mpi_irecv(iar_2d(:,2:6:2), 27, MPI_INTEGER, 0, 123, MPI_COMM_WORLD, request, ierr); + if (ierr .ne. MPI_SUCCESS) then + if (verbose) print *,"PE ",rank,": ",name,"mpi_irecv exited in error (",ierr,")" + errs = errs + 1 + endif + + call mpi_wait(request, status, ierr) + if (ierr .ne. MPI_SUCCESS) then + if (verbose) print *,"PE ",rank,": ",name,": mpi_wait exited in error (",ierr,")" + errs = errs + 1 + endif do i=1,9 do j=1,9 diff --git a/test/mpi/f08/subarray/test15.f90 b/test/mpi/f08/subarray/test15.f90 index b056b4365b0..9f0e338cab6 100644 --- a/test/mpi/f08/subarray/test15.f90 +++ b/test/mpi/f08/subarray/test15.f90 @@ -56,36 +56,29 @@ program main endif if (rank .eq. 0) then - block - call mpi_isend(iar_2d(1:7:3,2:6:2), 9, MPI_INTEGER, 1, 123, MPI_COMM_WORLD, request, ierr); - if (ierr .ne. MPI_SUCCESS) then - if (verbose) print *,"PE ",rank,": ",name,": mpi_isend exited in error (",ierr,")" - errs = errs + 1 - endif - - call mpi_wait(request, status, ierr) - if (ierr .ne. MPI_SUCCESS) then - if (verbose) print *,"PE ",rank,": ",name,": mpi_wait exited in error (",ierr,")" - errs = errs + 1 - endif - - end block + call mpi_isend(iar_2d(1:7:3,2:6:2), 9, MPI_INTEGER, 1, 123, MPI_COMM_WORLD, request, ierr); + if (ierr .ne. MPI_SUCCESS) then + if (verbose) print *,"PE ",rank,": ",name,": mpi_isend exited in error (",ierr,")" + errs = errs + 1 + endif + + call mpi_wait(request, status, ierr) + if (ierr .ne. MPI_SUCCESS) then + if (verbose) print *,"PE ",rank,": ",name,": mpi_wait exited in error (",ierr,")" + errs = errs + 1 + endif else if (rank .eq. 1) then - block - - call mpi_irecv(iar_2d(1:7:3,2:6:2), 9, MPI_INTEGER, 0, 123, MPI_COMM_WORLD, request, ierr); - if (ierr .ne. MPI_SUCCESS) then - if (verbose) print *,"PE ",rank,": ",name,"mpi_irecv exited in error (",ierr,")" - errs = errs + 1 - endif - - call mpi_wait(request, status, ierr) - if (ierr .ne. MPI_SUCCESS) then - if (verbose) print *,"PE ",rank,": ",name,": mpi_wait exited in error (",ierr,")" - errs = errs + 1 - endif - - end block + call mpi_irecv(iar_2d(1:7:3,2:6:2), 9, MPI_INTEGER, 0, 123, MPI_COMM_WORLD, request, ierr); + if (ierr .ne. MPI_SUCCESS) then + if (verbose) print *,"PE ",rank,": ",name,"mpi_irecv exited in error (",ierr,")" + errs = errs + 1 + endif + + call mpi_wait(request, status, ierr) + if (ierr .ne. MPI_SUCCESS) then + if (verbose) print *,"PE ",rank,": ",name,": mpi_wait exited in error (",ierr,")" + errs = errs + 1 + endif do i=2,6,2 do j=1,7,3 From 76363030a0c46543e172b8775d3e9c86effb2ac0 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 15 Feb 2022 11:14:00 -0600 Subject: [PATCH 468/607] test: Fix error output setting The dereference operator has lower precedence than postfix increment. Add parens or else the address will be incremented and not the value. Squashes a -Wunused-value warning. --- test/mpi/f77/datatype/bottomc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/mpi/f77/datatype/bottomc.c b/test/mpi/f77/datatype/bottomc.c index 647d876d880..2434862feed 100644 --- a/test/mpi/f77/datatype/bottomc.c +++ b/test/mpi/f77/datatype/bottomc.c @@ -65,10 +65,10 @@ void c_routine_(MPI_Fint * ftype, int *errs) MPI_Recv(buf, 6, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); if (buf[0] != 5) - *errs++; + (*errs)++; for (i = 1; i < 6; i++) if (buf[i] != i) - *errs++; + (*errs)++; } MPI_Type_free(&newtype); From e393a936913fea5075d3be63232b71b4f9e7fcb7 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 6 Feb 2022 23:57:01 -0600 Subject: [PATCH 469/607] maint: generate mansrc for MPI functions separately Since we are generating both the C binding source and the man pages, there is little benefit mixing them. Generate the man source separately for cleaner control. --- maint/gen_binding_c.py | 18 ++++-- maint/local_python/binding_c.py | 102 ++++++++++++++++++++------------ 2 files changed, 79 insertions(+), 41 deletions(-) diff --git a/maint/gen_binding_c.py b/maint/gen_binding_c.py index 9721528c154..8cfbfce4f3a 100644 --- a/maint/gen_binding_c.py +++ b/maint/gen_binding_c.py @@ -33,8 +33,11 @@ def main(): mapping = G.MAPS['SMALL_C_KIND_MAP'] G.mpi_declares.append(get_declare_function(func, False, "proto")) + G.check_write_path(c_dir + '/mansrc/') + # -- Generating code -- G.out = [] + G.doc3_src_txt = [] # internal function to dump G.out into filepath def dump_out(file_path): G.check_write_path(file_path) @@ -46,15 +49,23 @@ def dump_out(file_path): # ---- for func in func_list: G.err_codes = {} + manpage_out = [] # dumps the code to G.out array # Note: set func['_has_poly'] = False to skip embiggenning func['_has_poly'] = function_has_POLY_parameters(func) + dump_mpi_c(func, False) + dump_manpage(func, manpage_out) if func['_has_poly']: - dump_mpi_c(func, False) dump_mpi_c(func, True) - else: - dump_mpi_c(func, False) + dump_manpage(func, manpage_out) + + if 'output-mansrc' in G.opts: + f = get_mansrc_file_path(func, c_dir + '/mansrc') + with open(f, "w") as Out: + for l in manpage_out: + print(l.rstrip(), file=Out) + G.doc3_src_txt.append(f) if 'single-source' not in G.opts: # dump individual functions in separate source files @@ -64,7 +75,6 @@ def dump_out(file_path): dump_out(c_dir + "/c_binding.c") # -- Dump other files -- - G.check_write_path(c_dir) G.check_write_path("src/include") G.check_write_path("src/mpi_t") G.check_write_path("src/include/mpi_proto.h") diff --git a/maint/local_python/binding_c.py b/maint/local_python/binding_c.py index 54dd9cd7ea9..572c0d71f68 100644 --- a/maint/local_python/binding_c.py +++ b/maint/local_python/binding_c.py @@ -84,6 +84,22 @@ def get_func_file_path(func, root_dir): return file_path +def get_mansrc_file_path(func, root_dir): + file_path = None + dir_path = root_dir + if 'file' in func: + file_path = dir_path + '/' + func['file'] + ".txt" + elif RE.match(r'MPI_T_(\w+)', func['name'], re.IGNORECASE): + name = RE.m.group(1) + file_path = dir_path + '/' + name.lower() + ".txt" + elif RE.match(r'MPIX?_(\w+)', func['name'], re.IGNORECASE): + name = RE.m.group(1) + file_path = dir_path + '/' + name.lower() + ".txt" + else: + raise Exception("Error in function name pattern: %s\n" % func['name']) + + return file_path + def dump_c_file(f, lines): print(" --> [%s]" % f) with open(f, "w") as Out: @@ -94,14 +110,7 @@ def dump_c_file(f, lines): # stripping the newline for consistency l = l.rstrip() # handle special directives etc. - if RE.match(r'\[ERR CODES\]', l): - # man page error codes - print(".N Errors", file=Out) - print(".N MPI_SUCCESS\n", file=Out) - for err in sorted (G.err_codes.keys()): - print(".N %s" % (err), file=Out) - print(".N MPI_ERR_OTHER\n", file=Out) - elif RE.match(r'(INDENT|DEDENT)', l): + if RE.match(r'(INDENT|DEDENT)', l): # indentations a = RE.m.group(1) if a == "INDENT": @@ -137,6 +146,15 @@ def dump_Makefile_mk(f): else: print(" %s" % f, file=Out) + n = len(G.doc3_src_txt) + if n > 0: + print("doc3_src_txt += \\", file=Out) + for i, f in enumerate(G.doc3_src_txt): + if i < n - 1: + print(" %s \\" % f, file=Out) + else: + print(" %s" % f, file=Out) + def dump_mpir_impl_h(f): def dump_mpix_symbols(): # define MPI symbols from future API to MPIX @@ -769,7 +787,6 @@ def dump_qmpi_wrappers(func, is_large): G.out.append("}") G.out.append("#else /* ENABLE_QMPI */") - dump_manpage(func) G.out.append("") dump_line_with_break(func_decl) @@ -806,10 +823,10 @@ def dump_profiling(func): G.out.append("#endif /* MPICH_MPI_FROM_PMPI */") G.out.append("") -def dump_manpage(func): - G.out.append("/*@") - G.out.append(" %s - %s" % (get_function_name(func, func['_is_large']), func['desc'])) - G.out.append("") +def dump_manpage(func, out): + out.append("/*@") + out.append(" %s - %s" % (get_function_name(func, func['_is_large']), func['desc'])) + out.append("") lis_map = G.MAPS['LIS_KIND_MAP'] for p in func['c_parameters']: lis_type = lis_map[p['kind']] @@ -828,28 +845,28 @@ def dump_manpage(func): inout_list.append(p) else: input_list.append(p) - dump_manpage_list(input_list, "Input Parameters") - dump_manpage_list(inout_list, "Input/Output Parameters") - dump_manpage_list(output_list, "Output Parameters") + dump_manpage_list(input_list, "Input Parameters", out) + dump_manpage_list(inout_list, "Input/Output Parameters", out) + dump_manpage_list(output_list, "Output Parameters", out) # Add the custom notes (specified in e.g. pt2pt_api.txt) as is. if 'notes' in func: for l in func['notes']: - G.out.append(l) - G.out.append("") + out.append(l) + out.append("") if 'replace' in func: if RE.match(r'\s*(deprecated|removed)', func['replace'], re.IGNORECASE): - G.out.append(".N %s" % RE.m.group(1).capitalize()) + out.append(".N %s" % RE.m.group(1).capitalize()) else: print("Missing reasons in %s .replace" % func['name'], file=sys.stderr) if RE.search(r'with\s+(\w+)', func['replace']): - G.out.append(" The replacement for this routine is '%s'." % RE.m.group(1)) - G.out.append("") + out.append(" The replacement for this routine is '%s'." % RE.m.group(1)) + out.append("") for note in func['_docnotes']: - G.out.append(".N %s" % note) + out.append(".N %s" % note) if note == "Fortran": has = {} for p in func['c_parameters']: @@ -859,30 +876,41 @@ def dump_manpage(func): else: has['FortranStatus'] = 1 for k in has: - G.out.append(".N %s" % k) - G.out.append("") + out.append(".N %s" % k) + out.append("") if 'notes2' in func: for l in func['notes2']: - G.out.append(l) - G.out.append("") + out.append(l) + out.append("") if '_skip_err_codes' not in func: - G.out.append("[ERR CODES]") - G.out.append("") + out.append(".N Errors") + out.append(".N MPI_SUCCESS") + for err in sorted (G.err_codes.keys()): + out.append(".N %s" % (err)) + out.append(".N MPI_ERR_OTHER") + out.append("") if 'seealso' in func: - G.out.append(".seealso: %s" % func['seealso']) - G.out.append("@*/") - G.out.append("") - -def dump_manpage_list(list, header): + out.append(".seealso: %s" % func['seealso']) + out.append("@*/") + out.append("") + + # Follow the comment with actual function prototype + func_decl = get_declare_function(func, func['_is_large']) + tlist = split_line_with_break(func_decl, '', 100) + out.extend(tlist) + out.append("{}") + out.append("") + +def dump_manpage_list(list, header, out): count = len(list) if count == 0: return - G.out.append("%s:" % header) + out.append("%s:" % header) if count == 1: p = list[0] - G.out.append(". %s - %s" % (p['name'], p['desc'])) + out.append(". %s - %s" % (p['name'], p['desc'])) else: for i, p in enumerate(list): lead = "." @@ -890,8 +918,8 @@ def dump_manpage_list(list, header): lead = "+" elif i == count - 1: lead = "-" - G.out.append("%s %s - %s" % (lead, p['name'], p['desc'])) - G.out.append("") + out.append("%s %s - %s" % (lead, p['name'], p['desc'])) + out.append("") def get_function_internal_prototype(func_decl): func_decl = re.sub(r'MPI(X?)_([a-zA-Z0-9_]*\()', r'internal\1_\2', func_decl, 1) From 73d6a89e744d4f611476e45e951ef09d69f1c3a2 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 7 Feb 2022 00:11:40 -0600 Subject: [PATCH 470/607] autogen: use --with-doc to generate man sources Typically we only need generate man sources when preparing release tarball. --- autogen.sh | 12 ++++++++---- maint/release.pl | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/autogen.sh b/autogen.sh index 55e05143f0d..e1e515f52cf 100755 --- a/autogen.sh +++ b/autogen.sh @@ -65,6 +65,7 @@ do_test=yes do_hydra=yes do_hydra2=yes do_romio=yes +do_doc=no do_quick=no # Check -quick option. When enabled, skip as much as we can. @@ -510,11 +511,14 @@ fn_gen_coll() { fn_gen_binding_c() { set_PYTHON echo_n "generating MPI C functions..." - if test "$do_quick" = "no" ; then - $PYTHON maint/gen_binding_c.py - else - $PYTHON maint/gen_binding_c.py -single-source + _opt= + if test "$do_quick" = "yes"; then + _opt="$_opt -single-source" + fi + if test "$do_doc" = "yes"; then + _opt="$_opt -output-mansrc" fi + $PYTHON maint/gen_binding_c.py $_opt echo "done" } diff --git a/maint/release.pl b/maint/release.pl index 9fda053c45b..d735bedec9f 100755 --- a/maint/release.pl +++ b/maint/release.pl @@ -218,7 +218,7 @@ sub run_cmd print("===> Creating configure in the main codebase... "); chdir($expdir); { - my $cmd = "./autogen.sh"; + my $cmd = "./autogen.sh --with-doc"; $cmd .= " --with-autoconf=$with_autoconf" if $with_autoconf; $cmd .= " --with-automake=$with_automake" if $with_automake; run_cmd($cmd); From 5b482d800e6a4a3c6d2106478d7686b463994d7f Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 7 Feb 2022 14:06:41 -0600 Subject: [PATCH 471/607] maint: do not duplicate lis info in manpage output When the parameter description already contains lis info, do not double append them. --- maint/local_python/binding_c.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/maint/local_python/binding_c.py b/maint/local_python/binding_c.py index 572c0d71f68..6e6941cbb95 100644 --- a/maint/local_python/binding_c.py +++ b/maint/local_python/binding_c.py @@ -835,7 +835,8 @@ def dump_manpage(func, out): p['desc'] = G.default_descriptions[p['kind']] else: p['desc'] = p['name'] - p['desc'] += " (%s)" % (lis_type) + if not re.search(r'\)$', p['desc']): + p['desc'] += " (%s)" % (lis_type) input_list, output_list, inout_list = [], [], [] for p in func['c_parameters']: From 257d4fa8a6fc80c87eb1dbd4a7c4c49031d8f040 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 7 Feb 2022 16:33:12 -0600 Subject: [PATCH 472/607] maint: combine manpages of large count functions The large count function man page is nearly identical to its normal version. Rather than produce two separate man pages, it is probably more useful for user to see a combined man page. This commit embed verbose synopsis into the generated man source rather than relying on doctext to pick synopsis from the code. --- maint/gen_binding_c.py | 4 ++-- maint/local_python/binding_c.py | 29 +++++++++++++++++++---------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/maint/gen_binding_c.py b/maint/gen_binding_c.py index 8cfbfce4f3a..a70f14db14b 100644 --- a/maint/gen_binding_c.py +++ b/maint/gen_binding_c.py @@ -55,10 +55,10 @@ def dump_out(file_path): # Note: set func['_has_poly'] = False to skip embiggenning func['_has_poly'] = function_has_POLY_parameters(func) dump_mpi_c(func, False) - dump_manpage(func, manpage_out) if func['_has_poly']: dump_mpi_c(func, True) - dump_manpage(func, manpage_out) + + dump_manpage(func, manpage_out) if 'output-mansrc' in G.opts: f = get_mansrc_file_path(func, c_dir + '/mansrc') diff --git a/maint/local_python/binding_c.py b/maint/local_python/binding_c.py index 6e6941cbb95..b03ff43bec2 100644 --- a/maint/local_python/binding_c.py +++ b/maint/local_python/binding_c.py @@ -824,9 +824,25 @@ def dump_profiling(func): G.out.append("") def dump_manpage(func, out): - out.append("/*@") - out.append(" %s - %s" % (get_function_name(func, func['_is_large']), func['desc'])) + out.append("/*D") + out.append(" %s - %s" % (get_function_name(func, False), func['desc'])) out.append("") + + # Synopsis + out.append("Synopsis:") + func_decl = get_declare_function(func, False) + tlist = split_line_with_break(func_decl, '', 80) + out.append(".vb") + out.extend(tlist) + out.append(".ve") + if func['_has_poly']: + func_decl = get_declare_function(func, True) + tlist = split_line_with_break(func_decl, '', 80) + out.append(".vb") + out.extend(tlist) + out.append(".ve") + out.append("") + lis_map = G.MAPS['LIS_KIND_MAP'] for p in func['c_parameters']: lis_type = lis_map[p['kind']] @@ -894,14 +910,7 @@ def dump_manpage(func, out): out.append("") if 'seealso' in func: out.append(".seealso: %s" % func['seealso']) - out.append("@*/") - out.append("") - - # Follow the comment with actual function prototype - func_decl = get_declare_function(func, func['_is_large']) - tlist = split_line_with_break(func_decl, '', 100) - out.extend(tlist) - out.append("{}") + out.append("D*/") out.append("") def dump_manpage_list(list, header, out): From 1e8bebfc9f83abf4f1798ed3d95c4bca1f3e3b3c Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 8 Feb 2022 12:57:43 -0600 Subject: [PATCH 473/607] doc: we no longer generate man pages from source Now that we generate man sources directly in maint/gen_binding_c.py, we no longer need process C sources for producing man pages. --- Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index d2dea25cd7e..f86e5531630 100644 --- a/Makefile.am +++ b/Makefile.am @@ -474,7 +474,7 @@ mandoc: test -d $(mandoc_path1) || $(MKDIR_P) $(mandoc_path1) test -d $(mandoc_path3) || $(MKDIR_P) $(mandoc_path3) $(MAKE) $(AM_MAKEFLAGS) mandoc-local -mandoc-local: $(mpi_sources:.c=.man-phony) $(doc1_src_txt:.txt=.man1-phony) \ +mandoc-local: $(doc1_src_txt:.txt=.man1-phony) \ $(doc3_src_txt:.txt=.man3-phony) for subdir in $(MANDOC_SUBDIRS) - ; do \ if test "x$$subdir" = "x-" ; then break ; fi ; \ @@ -504,7 +504,7 @@ htmldoc: rm -f $(htmldoc_path3)/mpi.cit $(MAKE) $(AM_MAKEFLAGS) htmldoc-local -htmldoc-local: $(mpi_sources:.c=.html-phony) $(doc1_src_txt:.txt=.html1-phony) \ +htmldoc-local: $(doc1_src_txt:.txt=.html1-phony) \ $(doc3_src_txt:.txt=.html3-phony) for subdir in $(HTMLDOC_SUBDIRS) - ; do \ if test "x$$subdir" = "x-" ; then break ; fi ; \ From 57cdac5dd9c41f243cc2349d77513048f0f633b4 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 8 Feb 2022 13:48:42 -0600 Subject: [PATCH 474/607] maint/release.pl: remove extra newline from output There is a leftover extra newline in the output. --- maint/release.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maint/release.pl b/maint/release.pl index d735bedec9f..99d76a955e1 100755 --- a/maint/release.pl +++ b/maint/release.pl @@ -286,7 +286,7 @@ sub run_cmd run_cmd("cp -a ${expdir}/src/pm/hydra hydra-${version}"); run_cmd("tar -czvf hydra-${version}.tar.gz hydra-${version}"); run_cmd("cp -a hydra-${version}.tar.gz ${root}/"); -print("done\n\n"); +print("done\n"); # Create the testsuite tarball print("===> Creating the final mpich-testsuite tarball... "); From 82fde2bad37363733905face3ae5db6a5ff219e8 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 8 Feb 2022 15:04:01 -0600 Subject: [PATCH 475/607] maint/release.pl: remove check for txt2man We do not use txt2man. --- maint/release.pl | 1 - 1 file changed, 1 deletion(-) diff --git a/maint/release.pl b/maint/release.pl index 99d76a955e1..4de19bd70a6 100755 --- a/maint/release.pl +++ b/maint/release.pl @@ -144,7 +144,6 @@ sub run_cmd } check_package("doctext"); -check_package("txt2man"); check_package("git"); check_package("latex"); check_package("autoconf"); From 488d92918badc7159e12a511d3d870e2bea4c91b Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 8 Feb 2022 17:21:48 -0600 Subject: [PATCH 476/607] maint/release.pl: make missing doctext a warning Sometime users just want the convenience of tarball but don't care about the documentation. --- maint/release.pl | 67 ++++++++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/maint/release.pl b/maint/release.pl index 4de19bd70a6..c50e3e29597 100755 --- a/maint/release.pl +++ b/maint/release.pl @@ -47,23 +47,24 @@ sub check_package # the user specified a dir where autoconf can be found if (not -x "$with_autoconf/$pack") { print "not found\n"; - exit; + return 0; } } if ($with_automake and ($pack eq "automake")) { # the user specified a dir where automake can be found if (not -x "$with_automake/$pack") { print "not found\n"; - exit; + return 0; } } else { if (`which $pack` eq "") { print "not found\n"; - exit; + return 0; } } print "done\n"; + return 1; } sub check_autotools_version @@ -143,11 +144,19 @@ sub run_cmd usage(); } -check_package("doctext"); -check_package("git"); -check_package("latex"); -check_package("autoconf"); -check_package("automake"); +my $has_doctext = check_package("doctext"); +my $has_git = check_package("git"); +my $has_latex = check_package("latex"); +my $has_autoconf = check_package("autoconf"); +my $has_automake = check_package("automake"); +if (!$has_git || !$has_autoconf || !$has_automake) { + die "\tFATAL: git, autoconf, and automake are required.\n"; +} +if (!$has_doctext || !$has_latex) { + print("\tWARNING: doctext or latex not found. Man pages and documentations\n"); + print("\t will be skipped in the release package.\n\n"); + print("\tdoctext is available on http://wgropp.cs.illinois.edu/projects/software/sowing/\n"); +} print("\n"); ## NOTE: Different autotools versions may result in accidental ABI chanages. @@ -252,26 +261,28 @@ sub run_cmd print("done\n"); # Get docs -print("===> Creating secondary codebase for the docs... "); -run_cmd("mkdir ${expdir}-build"); -chdir("${expdir}-build"); -run_cmd("${expdir}/configure --with-device=ch4:stubnm --disable-fortran --disable-cxx"); -run_cmd("(make mandoc && make htmldoc && make latexdoc)"); -print("done\n"); - -print("===> Copying docs over... "); -run_cmd("cp -a man ${expdir}"); -run_cmd("cp -a www ${expdir}"); -run_cmd("cp -a doc/userguide/user.pdf ${expdir}/doc/userguide"); -run_cmd("cp -a doc/installguide/install.pdf ${expdir}/doc/installguide"); -print("done\n"); - -print("===> Creating ROMIO docs... "); -chdir("${expdir}/src/mpi"); -chdir("romio/doc"); -run_cmd("make"); -run_cmd("rm -f users-guide.blg users-guide.toc users-guide.aux users-guide.bbl users-guide.log users-guide.dvi"); -print("done\n"); +if ($has_doctext and $has_latex) { + print("===> Creating secondary codebase for the docs... "); + run_cmd("mkdir ${expdir}-build"); + chdir("${expdir}-build"); + run_cmd("${expdir}/configure --with-device=ch4:stubnm --disable-fortran --disable-cxx"); + run_cmd("(make mandoc && make htmldoc && make latexdoc)"); + print("done\n"); + + print("===> Copying docs over... "); + run_cmd("cp -a man ${expdir}"); + run_cmd("cp -a www ${expdir}"); + run_cmd("cp -a doc/userguide/user.pdf ${expdir}/doc/userguide"); + run_cmd("cp -a doc/installguide/install.pdf ${expdir}/doc/installguide"); + print("done\n"); + + print("===> Creating ROMIO docs... "); + chdir("${expdir}/src/mpi"); + chdir("romio/doc"); + run_cmd("make"); + run_cmd("rm -f users-guide.blg users-guide.toc users-guide.aux users-guide.bbl users-guide.log users-guide.dvi"); + print("done\n"); +} # Create the main tarball print("===> Creating the final mpich tarball... "); From 1b7293f2567e1b92ea9a49b02561ed8b4a7c0e7d Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 8 Feb 2022 15:15:00 -0600 Subject: [PATCH 477/607] hydra: fix htmldoc make target Need add hydra to the HTMLDOC_SUBDIRS variable. The htmldoc target had a typo resulted in html pages not built. --- src/pm/Makefile.mk | 1 + src/pm/hydra/Makefile.am | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pm/Makefile.mk b/src/pm/Makefile.mk index 35c2e11d372..2fa308c756f 100644 --- a/src/pm/Makefile.mk +++ b/src/pm/Makefile.mk @@ -27,6 +27,7 @@ if BUILD_PM_HYDRA SUBDIRS += src/pm/hydra DIST_SUBDIRS += src/pm/hydra MANDOC_SUBDIRS += src/pm/hydra +HTMLDOC_SUBDIRS += src/pm/hydra endif BUILD_PM_HYDRA # has its own full automake setup, not Makefile.mk diff --git a/src/pm/hydra/Makefile.am b/src/pm/hydra/Makefile.am index ac107f49408..701704becf1 100644 --- a/src/pm/hydra/Makefile.am +++ b/src/pm/hydra/Makefile.am @@ -102,7 +102,7 @@ htmldoc: test -d $(top_builddir)/www/www1 || $(MKDIR_P) $(top_builddir)/www/www1 test -d $(top_builddir)/www/www3 || $(MKDIR_P) $(top_builddir)/www/www3 $(MAKE) $(AM_MAKEFLAGS) htmldoc-local -htmldoc-local: $(doc1_src_txt:.txt=.man1-phony) +htmldoc-local: $(doc1_src_txt:.txt=.html1-phony) # created by confdb/aclocal_cache.m4 DISTCLEANFILES += config.system From 930585cff6ae82bd2c874a36e0c567a863679cf6 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 8 Feb 2022 16:37:47 -0600 Subject: [PATCH 478/607] hydra: fix hydra_nameserver.txt The special directives such as .vb and .ve need start at the beginning of the lines. --- .../hydra/tools/nameserver/hydra_nameserver.txt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/pm/hydra/tools/nameserver/hydra_nameserver.txt b/src/pm/hydra/tools/nameserver/hydra_nameserver.txt index 022a881447b..99e90acd81c 100644 --- a/src/pm/hydra/tools/nameserver/hydra_nameserver.txt +++ b/src/pm/hydra/tools/nameserver/hydra_nameserver.txt @@ -1,13 +1,15 @@ -/*D hydra_nameserver - program to support MPI's name publishing features with hydra +/*D +hydra_nameserver - program to support MPI's name publishing features with hydra Description: - Hydra is the default name service for MPI's name publishing features + Hydra is the default name service for MPI\'s name publishing features (MPI_PUBLISH_NAME/MPI_LOOKUP_NAME). For programs launched by separate hydra instances, a separate nameserver mechanism need be launched in order for the name publishing to work across multiple process managers. - This can be achieved with hydra_nameserver. For example: - .vb - shell@myhost1$ hydra_nameserver & - shell@myhost1$ mpiexec -hosts myhost1,myhost2 -n 4 -nameserver myhost1 ./a.out - .ve + + This can be achieved with hydra_nameserver. For example\: +.vb + shell@myhost1$ hydra_nameserver & + shell@myhost1$ mpiexec -hosts myhost1,myhost2 -n 4 -nameserver myhost1 ./a.out +.ve D*/ From 6199df8d3cfaf1db69fc369082f4d8aad75a8397 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 8 Feb 2022 09:48:34 -0600 Subject: [PATCH 479/607] maint: move createhtmlindex out of autoconf maint/createhtmlindex does not contain any autoconf variables and can be used directly. --- maint/configure.ac | 4 ++-- maint/{createhtmlindex.in => createhtmlindex} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename maint/{createhtmlindex.in => createhtmlindex} (100%) mode change 100644 => 100755 diff --git a/maint/configure.ac b/maint/configure.ac index 0b618ed8a3d..68fc53476f5 100644 --- a/maint/configure.ac +++ b/maint/configure.ac @@ -31,7 +31,7 @@ if test "$xargs_out" != "0" ; then fi AC_SUBST(XARGS_NODATA_OPT) -AC_CONFIG_COMMANDS([chmod], [chmod a+x checkbuilds getcoverage clmake extractstrings extractcvars extractfixme createcoverage gcovmerge createhtmlindex getfuncstack]) +AC_CONFIG_COMMANDS([chmod], [chmod a+x checkbuilds getcoverage clmake extractstrings extractcvars extractfixme createcoverage gcovmerge getfuncstack]) # We have to redefine the variables that autoconf always substitutes and that # are used in simplemake CFLAGS='@CFLAGS@' @@ -42,4 +42,4 @@ CXXFLAGS='@CXXFLAGS@' # autoconf replacement. # Note that top_srcdir and srcdir are special cases (they must not # be changed in configure.ac because configure uses them to find other files) -AC_OUTPUT(checkbuilds getcoverage clmake extractstrings extractcvars extractfixme createcoverage gcovmerge createhtmlindex cvardirs getfuncstack) +AC_OUTPUT(checkbuilds getcoverage clmake extractstrings extractcvars extractfixme createcoverage gcovmerge cvardirs getfuncstack) diff --git a/maint/createhtmlindex.in b/maint/createhtmlindex old mode 100644 new mode 100755 similarity index 100% rename from maint/createhtmlindex.in rename to maint/createhtmlindex From a8bcedada49c95a96e0c62bad7a9f78e0e2922ae Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 8 Feb 2022 09:54:17 -0600 Subject: [PATCH 480/607] maint: cleanup maint/createhtmlindex Use strict. Remove clutter. --- maint/createhtmlindex | 82 +++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 42 deletions(-) diff --git a/maint/createhtmlindex b/maint/createhtmlindex index 1cc7f79cc03..fe9fad7a471 100755 --- a/maint/createhtmlindex +++ b/maint/createhtmlindex @@ -4,44 +4,38 @@ ## See COPYRIGHT in top-level directory ## +use strict; + # Create an index of web pages for MPICH # # Default values # Root for the pages -$WWWRoot=`pwd`; +my $WWWRoot=`pwd`; chop $WWWRoot; # Base address (installation address) -# $URLBase = "http://"; +my $URLBase; # End of line character (\r\n is DOS-friendly) -$eol = "\r\n"; +my $eol = "\r\n"; # Number of columns in table of names -$TableCols = 3; +my $TableCols = 3; # # Process arguments for any changes -foreach $_ (@ARGV) { - if (/-?(-[^=]*)=(.*)/) { - $argname = $1; - $argval = $2; - } - else { - $argname = $1; - $argval = ""; +foreach $a (@ARGV) { + if ($a =~ /-?-wwwroot=(.*)/) { + $WWWRoot = $1; } - if ($argname =~ /-wwwroot/) { - $WWWRoot = $argval; + elsif ($a =~ /-?-urlbase=(.*)/) { + $URLBase = $1; } - elsif ($argname =~ /-urlbase/) { - $URLBase = $argval; - } - elsif ($argname eq "-help") { - print STDOUT "createhtmlindex [ -wwwroot=directory ] [ -urlbase=base ]\n"; - print STDOUT "Build the www index pages for MPICH."; - print STDOUT "This must be run in the root of an MPICH tree; it may\n -be run in a VPATH directory after configuring.\n"; + elsif ($a =~ /-?help/) { + print STDOUT "createhtmlindex [ -wwwroot=directory ] [ -urlbase=base ]\n\n"; + print STDOUT "Build the www index pages for MPICH.\n"; + print STDOUT "This must be run in the root of an MPICH tree; it may\n"; + print STDOUT "be run in a VPATH directory after configuring.\n"; exit 1; } else { - print STDERR "Unknown argument $_\n"; + print STDERR "Unknown argument $a\n"; exit 1; } } @@ -104,8 +98,10 @@ close( OUTFD ); # --------------------------------------------------------------------------- sub AddHeader { my $title = $_[0]; + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(); + my $today = sprintf("%d/%d/%d", $mon + 1, $mday, $year + 1900); print OUTFD "$eol$eol$title$eol"; - print OUTFD "$eol"; + print OUTFD "$eol"; print OUTFD "$eol$eol"; print OUTFD "

$title

$eol"; } @@ -119,18 +115,17 @@ sub AddTrailer { # on the page, rather than just a page which is what a file link would # accomplish sub createRedirects { - $rootdir = $_[0]; - $mapfile = $_[1]; + my ($rootdir, $mapfile) = @_; open( MAPFD, "<$rootdir/$mapfile" ) || die "Cannot open map file $mapfile\n"; while () { - @fields = split(/\+/); - $name = $fields[1]; - $url = $fields[8]; + my @fields = split(/\+/); + my $name = $fields[1]; + my $url = $fields[8]; if ($url =~ /(.*)\/([^\/]*)\.([HTMLhtml]*)#(.*)/) { - $rooturl = $1; - $basefile = $2; - $ext = $3; - $anchor = $4; + my $rooturl = $1; + my $basefile = $2; + my $ext = $3; + my $anchor = $4; if ($basefile ne $anchor) { open(RFD, ">$rootdir/$anchor.htm") || die "Cannot open redirect file $anchor.htm\n"; print RFD "\n"; @@ -151,22 +146,23 @@ sub createRedirects { # @HTMLFiles # 2. Use the routine MakeHTMLTable to create a table with a given # number of columns, adding the links within the columns -@HTMLFiles = (); # Look in $1/$2 for files, but make links relative to $2 sub AddDirectoryContents { my $rootdir = $_[0]; my $dirname = $_[1]; # 1 Read the files - @HTMLFiles = (); + my @HTMLFiles = (); opendir DIR, "$rootdir/$dirname"; + + my $prefixname; if ($dirname eq ".") { $prefixname = ""; } else { $prefixname = "$dirname/"; } - while ($filename = readdir DIR) { + while (my $filename = readdir DIR) { if ($filename =~ /index\.html?/) { next; } if ($filename =~ /.*\.html?$/) { $HTMLFiles[$#HTMLFiles+1] = "$prefixname$filename"; @@ -177,23 +173,25 @@ sub AddDirectoryContents { @HTMLFiles = sort( @HTMLFiles ); # Format the table - &MakeHTMLTable; + &MakeHTMLTable(\@HTMLFiles); } # MakeHTMLTable takes an array of items and turns them into a table with # $TableCols columns. # sub MakeHTMLTable { - my $nvals = $#HTMLFiles; + my ($HTMLFiles) = @_; + my $nvals = @$HTMLFiles; my $nrows = int ( ($nvals + $TableCols - 1) / $TableCols ); print OUTFD "$eol"; - for ($j=0; $j<$nrows; $j++) { + for (my $j=0; $j<$nrows; $j++) { print OUTFD ""; - for ($e=0; $e<$TableCols; $e++) { - $filename = $HTMLFiles[$j + $e * $nrows]; - $linkname = $filename; + for (my $e=0; $e<$TableCols; $e++) { + my $filename = $HTMLFiles->[$j + $e * $nrows]; + my $linkname = $filename; $linkname =~ s/\.html?//; $linkname =~ s/.*\///; + my $line; if ($filename ne "") { $line = "$linkname"; } From 9d1cf747812ea7c708b031027385c10dbcf9d20a Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 8 Feb 2022 10:56:41 -0600 Subject: [PATCH 481/607] maint: remove unused code from maint/createhtmlindex URLBase is not used. We only create pages using relative links. The redirect pages are not indexed and thus not used. It is redundant since the index page can directly link to the in-page anchors. Thus, it is removed. It is now one less dependency -- mpi.cit. --- maint/createhtmlindex | 55 +------------------------------------------ 1 file changed, 1 insertion(+), 54 deletions(-) diff --git a/maint/createhtmlindex b/maint/createhtmlindex index fe9fad7a471..b766a5b5610 100755 --- a/maint/createhtmlindex +++ b/maint/createhtmlindex @@ -12,8 +12,6 @@ use strict; # Root for the pages my $WWWRoot=`pwd`; chop $WWWRoot; -# Base address (installation address) -my $URLBase; # End of line character (\r\n is DOS-friendly) my $eol = "\r\n"; # Number of columns in table of names @@ -24,11 +22,8 @@ foreach $a (@ARGV) { if ($a =~ /-?-wwwroot=(.*)/) { $WWWRoot = $1; } - elsif ($a =~ /-?-urlbase=(.*)/) { - $URLBase = $1; - } elsif ($a =~ /-?help/) { - print STDOUT "createhtmlindex [ -wwwroot=directory ] [ -urlbase=base ]\n\n"; + print STDOUT "createhtmlindex [ -wwwroot=directory ]\n\n"; print STDOUT "Build the www index pages for MPICH.\n"; print STDOUT "This must be run in the root of an MPICH tree; it may\n"; print STDOUT "be run in a VPATH directory after configuring.\n"; @@ -50,17 +45,8 @@ print OUTFD "

MPI Commands

$eol"; &AddDirectoryContents( "www", "www1" ); print OUTFD "

MPI Routines and Constants

$eol"; -if (-f "www/www3/mpi.cit") { - &createRedirects("www/www3", "mpi.cit"); -} -else { - print STDERR "Could not find mapping file\n"; -} &AddDirectoryContents( "www", "www3" ); -#print OUTFD "

MPE Routines

$eol"; -#&AddDirectoryContents( "www", "www4" ); - &AddTrailer( ); close( OUTFD ); @@ -82,15 +68,6 @@ open( OUTFD, ">$WWWRoot/www/www3/index.htm" ) || &AddTrailer( ); close( OUTFD ); -# open( OUTFD, ">$WWWRoot/www/www4/index.htm" ) || -# die "Cannot open $WWWRoot/www/www4/index.htm\n"; - -# &AddHeader( "Web pages for MPE Routines" ); -# &AddDirectoryContents( "www/www4", "." ); -# &AddTrailer( ); -# close( OUTFD ); - - 0; # --------------------------------------------------------------------------- # Support routines. @@ -110,36 +87,6 @@ sub AddTrailer { print OUTFD "$eol$eol"; } -# For the items (mostly MPI constants) that are within a single web page, -# create a redirect page for them. This allows us to point to a location -# on the page, rather than just a page which is what a file link would -# accomplish -sub createRedirects { - my ($rootdir, $mapfile) = @_; - open( MAPFD, "<$rootdir/$mapfile" ) || die "Cannot open map file $mapfile\n"; - while () { - my @fields = split(/\+/); - my $name = $fields[1]; - my $url = $fields[8]; - if ($url =~ /(.*)\/([^\/]*)\.([HTMLhtml]*)#(.*)/) { - my $rooturl = $1; - my $basefile = $2; - my $ext = $3; - my $anchor = $4; - if ($basefile ne $anchor) { - open(RFD, ">$rootdir/$anchor.htm") || die "Cannot open redirect file $anchor.htm\n"; - print RFD "\n"; - close RFD; - } - } - else { - print STDERR "Could not decode $url\n"; - } - - } - close MAPFD; -} - # Take all .htm and .html files and add them to the OUTFD file. # This works in two steps: # 1. Read and sort the contents of the directory into the array From 79deec0b3cc439d1fb84a6702c9aa04a4dab7c89 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 8 Feb 2022 13:45:55 -0600 Subject: [PATCH 482/607] maint: create better index for MPI constants Create index for constants by directly parse Constants.html and link to its anchors. --- maint/createhtmlindex | 82 ++++++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 33 deletions(-) diff --git a/maint/createhtmlindex b/maint/createhtmlindex index b766a5b5610..84956a414f3 100755 --- a/maint/createhtmlindex +++ b/maint/createhtmlindex @@ -35,23 +35,26 @@ foreach $a (@ARGV) { } } -# Create the main index +# ---- Create the main index ---- open( OUTFD, ">$WWWRoot/www/index.html" ) || die "Cannot open $WWWRoot/www/index.html\n"; -&AddHeader( "Web pages for MPI" ); +&AddHeader( "Man pages for MPI" ); print OUTFD "

MPI Commands

$eol"; &AddDirectoryContents( "www", "www1" ); -print OUTFD "

MPI Routines and Constants

$eol"; +print OUTFD "

MPI Routines

$eol"; &AddDirectoryContents( "www", "www3" ); +print OUTFD "

MPI Constants

$eol"; +&AddDirectoryConstants( "www", "www3/Constants.html" ); + &AddTrailer( ); close( OUTFD ); -# Create the sectional indices +# ---- Create the www1 index ---- open( OUTFD, ">$WWWRoot/www/www1/index.htm" ) || die "Cannot open $WWWRoot/www/www1/index.htm\n"; @@ -60,11 +63,18 @@ open( OUTFD, ">$WWWRoot/www/www1/index.htm" ) || &AddTrailer( ); close( OUTFD ); +# ---- Create the www3 index ---- open( OUTFD, ">$WWWRoot/www/www3/index.htm" ) || die "Cannot open $WWWRoot/www/www3/index.htm\n"; -&AddHeader( "Web pages for MPI Routines and Constants" ); +&AddHeader( "Man pages for MPI Routines and Constants" ); +&AddDirectoryContents( "www/www3", "." ); +print OUTFD "

MPI Routines

$eol"; &AddDirectoryContents( "www/www3", "." ); + +print OUTFD "

MPI Constants

$eol"; +&AddDirectoryConstants( "www/www3", "Constants.html" ); + &AddTrailer( ); close( OUTFD ); @@ -87,64 +97,70 @@ sub AddTrailer { print OUTFD "$eol$eol"; } +# Create a table of indexes for MPI Constants. Each link points to an +# anchor within Constants.html. We assume each anchor is in a expected +# format. +# +sub AddDirectoryConstants { + my ($rootdir, $file) = @_; + my %links; + open In, "$rootdir/$file" or die "Can't open $rootdir/$file\n"; + while () { + if (/<\/a>/) { + $links{$1} = "$file#$1"; + } + } + MakeHTMLTable(\%links); +} + # Take all .htm and .html files and add them to the OUTFD file. # This works in two steps: -# 1. Read and sort the contents of the directory into the array -# @HTMLFiles +# 1. Read the contents of the directory into the %links # 2. Use the routine MakeHTMLTable to create a table with a given # number of columns, adding the links within the columns # Look in $1/$2 for files, but make links relative to $2 +# sub AddDirectoryContents { - my $rootdir = $_[0]; - my $dirname = $_[1]; + my ($rootdir, $dirname) = @_; - # 1 Read the files - my @HTMLFiles = (); + my %links; opendir DIR, "$rootdir/$dirname"; my $prefixname; - if ($dirname eq ".") { - $prefixname = ""; - } - else { + if ($dirname ne ".") { $prefixname = "$dirname/"; } while (my $filename = readdir DIR) { - if ($filename =~ /index\.html?/) { next; } - if ($filename =~ /.*\.html?$/) { - $HTMLFiles[$#HTMLFiles+1] = "$prefixname$filename"; + if ($filename =~ /(index|Constants)\.html?/) { + next; + } elsif ($filename =~ /(\w+)\.html?$/) { + $links{$1} = "$prefixname$filename"; } } closedir DIR; - @HTMLFiles = sort( @HTMLFiles ); - - # Format the table - &MakeHTMLTable(\@HTMLFiles); + MakeHTMLTable(\%links); } -# MakeHTMLTable takes an array of items and turns them into a table with + +# MakeHTMLTable takes an hash of items and turns them into a table with # $TableCols columns. # sub MakeHTMLTable { - my ($HTMLFiles) = @_; - my $nvals = @$HTMLFiles; + my ($links) = @_; + my @keys = sort keys %$links; + my $nvals = @keys; my $nrows = int ( ($nvals + $TableCols - 1) / $TableCols ); print OUTFD "
$eol"; for (my $j=0; $j<$nrows; $j++) { print OUTFD ""; for (my $e=0; $e<$TableCols; $e++) { - my $filename = $HTMLFiles->[$j + $e * $nrows]; - my $linkname = $filename; - $linkname =~ s/\.html?//; - $linkname =~ s/.*\///; + my $linkname = $keys[$j + $e * $nrows]; + my $filename = $links->{$linkname}; my $line; - if ($filename ne "") { + if ($filename) { $line = "$linkname"; } - else { - $line = ""; - } print OUTFD "$eol"; } print OUTFD "$eol"; From 489437a2b31c6891d46597e1d4ad3fb06f316c2b Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 8 Feb 2022 19:33:30 -0600 Subject: [PATCH 483/607] maint: add alias_mancnst There used to be a mancnst script that creates alias man pages for individual constants. This commit adds the script to provide the same functionality. --- Makefile.am | 3 +-- maint/alias_mancnst | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100755 maint/alias_mancnst diff --git a/Makefile.am b/Makefile.am index f86e5531630..261a2e83a8c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -492,8 +492,7 @@ mandoc-local: $(doc1_src_txt:.txt=.man1-phony) \ fi \ fi \ done -# FIXME: the 'mancnst' script need to be committed for this to work -# (cd $(abs_top_builddir) && $(abs_top_srcdir)/doc/mansrc/mancnst) + $(srcdir)/maint/alias_mancnst # use htmldoc-local target to force directory creation before running DOCTEXT # Note that the mpi.cit is appended to by each update, so it must be removed diff --git a/maint/alias_mancnst b/maint/alias_mancnst new file mode 100755 index 00000000000..629cdfb5bdb --- /dev/null +++ b/maint/alias_mancnst @@ -0,0 +1,27 @@ +#! /usr/bin/env perl +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +# This script renames man/man3/Constants.3 into man/man3/mpiconsts.3 +# to avoid collision with other packages. Then it creates alias man +# pages for individual constants. + +use strict; + +if (!-e "man/man3/Constants.3") { + die "man/man3/Constants.3 not found.\n"; +} + +rename "man/man3/Constants.3", "man/man3/mpiconsts.3"; + +open In, "man/man3/mpiconsts.3" or die "Can't open man/man3/mpiconsts.3\n"; +while () { + if (/^\.B\s+(MPIX?_\w+)/) { + open Out, "> man/man3/$1.3" or die "Can't create man/man3/$1.3\n"; + print Out ".so man3/mpiconsts.3\n"; + close Out; + } +} +close In; From 49777ae40be2b6b6ee23c3f3cee1d353c7bf24c0 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 26 Jan 2022 09:32:43 -0600 Subject: [PATCH 484/607] ch3/nemesis: fix usage in MPIR_Typerep_to_iov The old code didn't set max_iov_len properly on calling MPIR_Typerep_to_iov. This bug is revealed when we test ch3 with yaksa. It is curious why dataloop didn't fail. TODO: investigate dataloop. --- src/mpid/ch3/channels/nemesis/netmod/tcp/tcp_send.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mpid/ch3/channels/nemesis/netmod/tcp/tcp_send.c b/src/mpid/ch3/channels/nemesis/netmod/tcp/tcp_send.c index ab6d881361a..64f303b0fac 100644 --- a/src/mpid/ch3/channels/nemesis/netmod/tcp/tcp_send.c +++ b/src/mpid/ch3/channels/nemesis/netmod/tcp/tcp_send.c @@ -700,6 +700,8 @@ int MPID_nem_tcp_SendNoncontig(MPIDI_VC_t * vc, MPIR_Request * sreq, void *heade iov_offset = iov_n; + /* Set iov_n to remaining capacity. It will be set to actual num of iovs loaded on output. */ + iov_n = MPL_IOV_LIMIT - iov_offset; mpi_errno = MPIDI_CH3U_Request_load_send_iov(sreq, &iov[iov_offset], &iov_n); MPIR_ERR_CHKANDJUMP(mpi_errno, mpi_errno, MPI_ERR_OTHER, "**ch3|loadsendiov"); From ab7f7048d653ac7c162323e9dc9a59fa535e52ad Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 2 Feb 2022 22:09:18 -0600 Subject: [PATCH 485/607] ch3: avoid manually pack data When the old code manually unpack data using IOVs, it may end up stop at inside of a pairtype. Because a pairtype is considered a basic type, the datatype engine, specifically, yaksa, may not able to continue pack from the middle of it. Always use MPIR_Typerep_pack avoids such inconsistency. --- src/mpid/ch3/src/ch3u_request.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/mpid/ch3/src/ch3u_request.c b/src/mpid/ch3/src/ch3u_request.c index 4a4f67148ca..d18cadaac54 100644 --- a/src/mpid/ch3/src/ch3u_request.c +++ b/src/mpid/ch3/src/ch3u_request.c @@ -120,7 +120,6 @@ int MPIDI_CH3U_Request_load_send_iov(MPIR_Request * const sreq, else { intptr_t data_sz; - int i, iov_data_copied; MPL_DBG_MSG(MPIDI_CH3_DBG_CHANNEL,VERBOSE,"low density. using SRBuf."); @@ -141,29 +140,21 @@ int MPIDI_CH3U_Request_load_send_iov(MPIR_Request * const sreq, /* --END ERROR HANDLING-- */ } - iov_data_copied = 0; - for (i = 0; i < *iov_n; i++) { - MPIR_Memcpy((char*) sreq->dev.tmpbuf + iov_data_copied, - iov[i].iov_base, iov[i].iov_len); - iov_data_copied += iov[i].iov_len; - } - sreq->dev.msg_offset = last; - MPI_Aint max_pack_bytes; MPI_Aint actual_pack_bytes; - if (data_sz > sreq->dev.tmpbuf_sz - iov_data_copied) - max_pack_bytes = sreq->dev.tmpbuf_sz - iov_data_copied; + if (data_sz > sreq->dev.tmpbuf_sz) + max_pack_bytes = sreq->dev.tmpbuf_sz; else - max_pack_bytes = sreq->dev.msgsize - sreq->dev.msg_offset; + max_pack_bytes = data_sz; MPIR_Typerep_pack(sreq->dev.user_buf, sreq->dev.user_count, sreq->dev.datatype, - sreq->dev.msg_offset, (char*) sreq->dev.tmpbuf + iov_data_copied, + sreq->dev.msg_offset, (char*) sreq->dev.tmpbuf, max_pack_bytes, &actual_pack_bytes, MPIR_TYPEREP_FLAG_NONE); last = sreq->dev.msg_offset + actual_pack_bytes; iov[0].iov_base = (void *)sreq->dev.tmpbuf; - iov[0].iov_len = actual_pack_bytes + iov_data_copied; + iov[0].iov_len = actual_pack_bytes; *iov_n = 1; if (last == sreq->dev.msgsize) { From b1f5b44e78b74502626b045cd833843354e20876 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 3 Feb 2022 17:26:52 -0600 Subject: [PATCH 486/607] ch3: always pack low-density data MPIR_Typerep_pack may leave off at non-iov boundary, which prevent continuing loading iov. This is not an issue with dataloop but yaksa does not allow it. Typically, if a datatype overall is high-density, it won't benefit much from packing sporadic low-density area since there won't be significant amount of low-density area. On the other hand, if overall it is low-density, it is rare to have local high-density area. Thus, simply use overall density should be sufficient for performance. Doing so avoids mixing packing with using iovs. --- src/mpid/ch3/src/ch3u_request.c | 72 ++++++++++++++++----------------- 1 file changed, 35 insertions(+), 37 deletions(-) diff --git a/src/mpid/ch3/src/ch3u_request.c b/src/mpid/ch3/src/ch3u_request.c index d18cadaac54..1742a525096 100644 --- a/src/mpid/ch3/src/ch3u_request.c +++ b/src/mpid/ch3/src/ch3u_request.c @@ -80,46 +80,44 @@ void MPID_Request_create_hook(MPIR_Request *req) int MPIDI_CH3U_Request_load_send_iov(MPIR_Request * const sreq, struct iovec * const iov, int * const iov_n) { - MPI_Aint last; int mpi_errno = MPI_SUCCESS; MPIR_FUNC_ENTER; - last = sreq->dev.msgsize; - MPL_DBG_MSG_FMT(MPIDI_CH3_DBG_CHANNEL,VERBOSE,(MPL_DBG_FDEST, - "pre-pv: first=%" PRIdPTR ", last=%" PRIdPTR ", iov_n=%d", - sreq->dev.msg_offset, last, *iov_n)); - MPIR_Assert(sreq->dev.msg_offset < last); - MPIR_Assert(last > 0); - MPIR_Assert(*iov_n > 0 && *iov_n <= MPL_IOV_LIMIT); - - int max_iov_len = *iov_n; - MPI_Aint actual_iov_bytes, actual_iov_len; - MPIR_Typerep_to_iov(sreq->dev.user_buf, sreq->dev.user_count, sreq->dev.datatype, - sreq->dev.msg_offset, iov, (MPI_Aint) max_iov_len, - sreq->dev.msgsize - sreq->dev.msg_offset, &actual_iov_len, &actual_iov_bytes); - *iov_n = (int) actual_iov_len; - last = sreq->dev.msg_offset + actual_iov_bytes; - - MPL_DBG_MSG_FMT(MPIDI_CH3_DBG_CHANNEL,VERBOSE,(MPL_DBG_FDEST, - "post-pv: first=%" PRIdPTR ", last=%" PRIdPTR ", iov_n=%d", - sreq->dev.msg_offset, last, *iov_n)); - MPIR_Assert(*iov_n > 0 && *iov_n <= MPL_IOV_LIMIT); - - if (last == sreq->dev.msgsize) - { - MPL_DBG_MSG(MPIDI_CH3_DBG_CHANNEL,VERBOSE,"remaining data loaded into IOV"); - sreq->dev.OnDataAvail = sreq->dev.OnFinal; - } - else if ((last - sreq->dev.msg_offset) / *iov_n >= MPIDI_IOV_DENSITY_MIN) - { - MPL_DBG_MSG(MPIDI_CH3_DBG_CHANNEL,VERBOSE,"more data loaded into IOV"); - sreq->dev.msg_offset = last; - sreq->dev.OnDataAvail = MPIDI_CH3_ReqHandler_SendReloadIOV; - } - else - { - intptr_t data_sz; + MPI_Aint density; + MPIR_Datatype_get_density(sreq->dev.datatype, density); + if (density >= MPIDI_IOV_DENSITY_MIN) { + MPI_Aint last = sreq->dev.msgsize; + MPL_DBG_MSG_FMT(MPIDI_CH3_DBG_CHANNEL,VERBOSE,(MPL_DBG_FDEST, + "pre-pv: first=%" PRIdPTR ", last=%" PRIdPTR ", iov_n=%d", + sreq->dev.msg_offset, last, *iov_n)); + MPIR_Assert(sreq->dev.msg_offset < last); + MPIR_Assert(last > 0); + MPIR_Assert(*iov_n > 0 && *iov_n <= MPL_IOV_LIMIT); + + int max_iov_len = *iov_n; + MPI_Aint actual_iov_bytes, actual_iov_len; + MPIR_Typerep_to_iov(sreq->dev.user_buf, sreq->dev.user_count, sreq->dev.datatype, + sreq->dev.msg_offset, iov, (MPI_Aint) max_iov_len, + sreq->dev.msgsize - sreq->dev.msg_offset, &actual_iov_len, &actual_iov_bytes); + *iov_n = (int) actual_iov_len; + last = sreq->dev.msg_offset + actual_iov_bytes; + + MPL_DBG_MSG_FMT(MPIDI_CH3_DBG_CHANNEL,VERBOSE,(MPL_DBG_FDEST, + "post-pv: first=%" PRIdPTR ", last=%" PRIdPTR ", iov_n=%d", + sreq->dev.msg_offset, last, *iov_n)); + MPIR_Assert(*iov_n > 0 && *iov_n <= MPL_IOV_LIMIT); + + if (last == sreq->dev.msgsize) { + MPL_DBG_MSG(MPIDI_CH3_DBG_CHANNEL,VERBOSE,"remaining data loaded into IOV"); + sreq->dev.OnDataAvail = sreq->dev.OnFinal; + } else { + MPL_DBG_MSG(MPIDI_CH3_DBG_CHANNEL,VERBOSE,"more data loaded into IOV"); + sreq->dev.msg_offset = last; + sreq->dev.OnDataAvail = MPIDI_CH3_ReqHandler_SendReloadIOV; + } + } else { + MPI_Aint data_sz; MPL_DBG_MSG(MPIDI_CH3_DBG_CHANNEL,VERBOSE,"low density. using SRBuf."); @@ -151,7 +149,7 @@ int MPIDI_CH3U_Request_load_send_iov(MPIR_Request * const sreq, MPIR_Typerep_pack(sreq->dev.user_buf, sreq->dev.user_count, sreq->dev.datatype, sreq->dev.msg_offset, (char*) sreq->dev.tmpbuf, max_pack_bytes, &actual_pack_bytes, MPIR_TYPEREP_FLAG_NONE); - last = sreq->dev.msg_offset + actual_pack_bytes; + MPI_Aint last = sreq->dev.msg_offset + actual_pack_bytes; iov[0].iov_base = (void *)sreq->dev.tmpbuf; iov[0].iov_len = actual_pack_bytes; From ad468c3a8d45ecd2701410720b4c7bdd06c3d6fa Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Wed, 16 Feb 2022 14:58:17 -0600 Subject: [PATCH 487/607] mtest: Encapsulate GPU dependencies All GPU code used by the testsuite is currently part of mtest_common.c, which is the basis of libmtest.la. Instead of adding GPU dependencies ad-hoc in various Makefiles, make them part of the convenience library. Libtool should take care of everything from there. --- test/mpi/Makefile_common.mtest | 6 ++---- test/mpi/Makefile_cxx.mtest | 5 ++--- test/mpi/Makefile_f08.mtest | 2 +- test/mpi/Makefile_f77.mtest | 2 +- test/mpi/Makefile_f90.mtest | 2 +- test/mpi/f77/ext/Makefile.am | 2 +- test/mpi/f77/io/Makefile.am | 2 +- test/mpi/util/Makefile.am | 8 +++++++- 8 files changed, 16 insertions(+), 13 deletions(-) diff --git a/test/mpi/Makefile_common.mtest b/test/mpi/Makefile_common.mtest index 2b6427247c0..f48afa7c164 100644 --- a/test/mpi/Makefile_common.mtest +++ b/test/mpi/Makefile_common.mtest @@ -12,13 +12,11 @@ ## Makefile.am # AM_CPPFLAGS are used for C++ code as well -AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include @cuda_CPPFLAGS@ @ze_CPPFLAGS@ @hip_CPPFLAGS@ -AM_LDFLAGS = @cuda_LDFLAGS@ @ze_LDFLAGS@ @hip_LDFLAGS@ -LDADD = @cuda_LIBS@ @ze_LIBS@ @hip_LIBS@ +AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include # Add libdtpools support AM_CPPFLAGS += -I$(top_srcdir)/dtpools/include -LDADD += $(top_builddir)/dtpools/src/libdtpools.la +LDADD = $(top_builddir)/dtpools/src/libdtpools.la $(top_builddir)/dtpools/src/libdtpools.la: (cd $(top_builddir)/dtpools && $(MAKE)) diff --git a/test/mpi/Makefile_cxx.mtest b/test/mpi/Makefile_cxx.mtest index daa8677371c..213ca08ed4b 100644 --- a/test/mpi/Makefile_cxx.mtest +++ b/test/mpi/Makefile_cxx.mtest @@ -9,9 +9,8 @@ ## ## see Makefile_common.mtest for a description why this file exists, but for C++ -AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include @cuda_CPPFLAGS@ @ze_CPPFLAGS@ @hip_CPPFLAGS@ -AM_LDFLAGS = @cuda_LDFLAGS@ @ze_LDFLAGS@ @hip_LDFLAGS@ -LDADD = $(top_builddir)/util/libmtest_cxx.la @cuda_LIBS@ @ze_LIBS@ @hip_LIBS@ +AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include +LDADD = $(top_builddir)/util/libmtest_cxx.la # Add libdtpools support AM_CPPFLAGS += -I$(top_srcdir)/dtpools/include diff --git a/test/mpi/Makefile_f08.mtest b/test/mpi/Makefile_f08.mtest index 724c9110771..1d9cffdfb39 100644 --- a/test/mpi/Makefile_f08.mtest +++ b/test/mpi/Makefile_f08.mtest @@ -5,7 +5,7 @@ # these CPPFLAGS are only used when building C/C++ source files, not for actual # F08 code itself -AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include @cuda_CPPFLAGS@ @ze_CPPFLAGS@ @hip_CPPFLAGS@ +AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include LDADD = $(top_builddir)/util/libmtest_f08.la mtest_c_objects = $(top_builddir)/util/libmtest_single.la diff --git a/test/mpi/Makefile_f77.mtest b/test/mpi/Makefile_f77.mtest index f46eca2ac9d..0282b49742b 100644 --- a/test/mpi/Makefile_f77.mtest +++ b/test/mpi/Makefile_f77.mtest @@ -11,7 +11,7 @@ # these CPPFLAGS are only used when building C/C++ source files, not for actual # F77 code itself -AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include @cuda_CPPFLAGS@ @ze_CPPFLAGS@ @hip_CPPFLAGS@ +AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include # This is right for many platforms, but not all. The right fix involves a # configure test, but this version is no worse than the simplemake version was. diff --git a/test/mpi/Makefile_f90.mtest b/test/mpi/Makefile_f90.mtest index 2a938aae6e2..ff7b1d76f63 100644 --- a/test/mpi/Makefile_f90.mtest +++ b/test/mpi/Makefile_f90.mtest @@ -5,7 +5,7 @@ # these CPPFLAGS are only used when building C/C++ source files, not for actual # F90 code itself -AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include @cuda_CPPFLAGS@ @ze_CPPFLAGS@ @hip_CPPFLAGS@ +AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include LDADD = $(top_builddir)/util/libmtest_f90.la mtest_c_objects = $(top_builddir)/util/libmtest_single.la diff --git a/test/mpi/f77/ext/Makefile.am b/test/mpi/f77/ext/Makefile.am index 1c733ec86c9..b08a63c3290 100644 --- a/test/mpi/f77/ext/Makefile.am +++ b/test/mpi/f77/ext/Makefile.am @@ -17,7 +17,7 @@ c2f2cf_SOURCES = c2f2c.c c2f2cf.f ctypesinf_SOURCES = ctypesinf.f ctypesfromc.c # C programs get a different mtest utility object -c2fmult_LDADD = $(mtest_c_objects) @cuda_LIBS@ @ze_LIBS@ @hip_LIBS@ @cuda_LDFLAGS@ @ze_LDFLAGS@ @hip_LDFLAGS@ +c2fmult_LDADD = $(mtest_c_objects) c2fmult_SOURCES = c2fmult.c ## add1size.h will be distributed because it's listed in AC_CONFIG_FILES/AC_OUTPUT diff --git a/test/mpi/f77/io/Makefile.am b/test/mpi/f77/io/Makefile.am index 86b90de5dad..59039f8fbc2 100644 --- a/test/mpi/f77/io/Makefile.am +++ b/test/mpi/f77/io/Makefile.am @@ -57,7 +57,7 @@ nodist_writeshf_SOURCES = writeshf.f c2fmultio_SOURCES = c2fmultio.c # this is a C only program, so we must include mtest_c_objects -c2fmultio_LDADD = $(mtest_c_objects) @cuda_LIBS@ @ze_LIBS@ @hip_LIBS@ @cuda_LDFLAGS@ @ze_LDFLAGS@ @hip_LDFLAGS@ +c2fmultio_LDADD = $(mtest_c_objects) c2f2ciof_SOURCES = c2f2cio.c c2f2ciof.f diff --git a/test/mpi/util/Makefile.am b/test/mpi/util/Makefile.am index 47e5b056983..8f33dcc2630 100644 --- a/test/mpi/util/Makefile.am +++ b/test/mpi/util/Makefile.am @@ -3,10 +3,16 @@ ## See COPYRIGHT in top-level directory ## -AM_CPPFLAGS = -I$(srcdir)/../include -I../include -I$(srcdir)/../dtpools/include @cuda_CPPFLAGS@ @ze_CPPFLAGS@ @hip_CPPFLAGS@ +AM_CPPFLAGS = -I$(srcdir)/../include -I../include -I$(srcdir)/../dtpools/include noinst_LTLIBRARIES = libmtest.la libmtest_la_SOURCES = mtest.c mtest_common.c +# All GPU code is currently in mtest_common.c, so all flags and +# libraries can go here. Any program that links with libmtest.la will +# get the right dependencies via libtool. +libmtest_la_LIBADD = @cuda_LIBS@ @ze_LIBS@ @hip_LIBS@ +libmtest_la_LDFLAGS = @cuda_LDFLAGS@ @ze_LDFLAGS@ @hip_LDFLAGS@ +libmtest_la_CPPFLAGS = $(AM_CPPFLAGS) @cuda_CPPFLAGS@ @ze_CPPFLAGS@ @hip_CPPFLAGS@ noinst_LTLIBRARIES += libdtypes.la libdtypes_la_SOURCES = dtypes.c From 5d03a658e74d4a13828fb0d134dbee4ef26656b6 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 15 Feb 2022 13:18:18 -0600 Subject: [PATCH 488/607] pmi2/simple: Fix PMI2_Nameserv_lookup Use the correct key (PORT_KEY) to search the lookup response message. --- src/pmi/pmi2/simple/simple2pmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pmi/pmi2/simple/simple2pmi.c b/src/pmi/pmi2/simple/simple2pmi.c index 0adf286c023..00249bc7bdf 100644 --- a/src/pmi/pmi2/simple/simple2pmi.c +++ b/src/pmi/pmi2/simple/simple2pmi.c @@ -1034,7 +1034,7 @@ int PMI2_Nameserv_lookup(const char service_name[], const PMI2U_Info * info_ptr, PMI2U_ERR_CHKANDJUMP1(rc, pmi2_errno, PMI2_ERR_OTHER, "**pmi2_nameservlookup", "**pmi2_nameservlookup %s", errmsg ? errmsg : "unknown"); - found = getval(cmd.pairs, cmd.nPairs, VALUE_KEY, &found_port, &plen); + found = getval(cmd.pairs, cmd.nPairs, PORT_KEY, &found_port, &plen); PMI2U_ERR_CHKANDJUMP1(!found, pmi2_errno, PMI2_ERR_OTHER, "**pmi2_nameservlookup", "**pmi2_nameservlookup %s", "not found"); MPL_strncpy(port, found_port, portLen); From 34a64de1b18208f6faa86ab52b7bd7be23c47093 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 15 Feb 2022 14:04:17 -0600 Subject: [PATCH 489/607] pm/hydra: Fix appnum retrieval in pmi2 server appnum was always hardcoded to 0 in the PMI2_Init response. Get the information out of the executable list and return it like in pmi1. --- src/pm/hydra/pm/pmiserv/pmip_pmi_v2.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/pm/hydra/pm/pmiserv/pmip_pmi_v2.c b/src/pm/hydra/pm/pmiserv/pmip_pmi_v2.c index 22d6047f262..92d2e14b3ba 100644 --- a/src/pm/hydra/pm/pmiserv/pmip_pmi_v2.c +++ b/src/pm/hydra/pm/pmiserv/pmip_pmi_v2.c @@ -172,8 +172,18 @@ static HYD_status fn_fullinit(int fd, char *args[]) break; } } + int idx = i; HYDU_ASSERT(i < HYD_pmcd_pmip.local.proxy_process_count, status); + /* find executable information */ + i = 0; + struct HYD_exec *exec; + for (exec = HYD_pmcd_pmip.exec_list; exec; exec = exec->next) { + i += exec->proc_count; + if (idx < i) + break; + } + HYD_STRING_STASH_INIT(stash); HYD_STRING_STASH(stash, MPL_strdup("cmd=fullinit-response;pmi-version=2;pmi-subversion=0;rank="), @@ -183,7 +193,8 @@ static HYD_status fn_fullinit(int fd, char *args[]) HYD_STRING_STASH(stash, MPL_strdup(";size="), status); HYD_STRING_STASH(stash, HYDU_int_to_str(HYD_pmcd_pmip.system_global.global_process_count), status); - HYD_STRING_STASH(stash, MPL_strdup(";appnum=0"), status); + HYD_STRING_STASH(stash, MPL_strdup(";appnum="), status); + HYD_STRING_STASH(stash, HYDU_int_to_str(exec->appnum), status); if (HYD_pmcd_pmip.local.spawner_kvsname) { HYD_STRING_STASH(stash, MPL_strdup(";spawner-jobid="), status); HYD_STRING_STASH(stash, MPL_strdup(HYD_pmcd_pmip.local.spawner_kvsname), status); From 140ea750e67bfd9d5859ede90c317cebc526082a Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 15 Feb 2022 17:57:43 -0600 Subject: [PATCH 490/607] ch3/sock: Remove unused header include This causes a compile error if not using pmi1. --- src/mpid/ch3/channels/sock/src/ch3_progress.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mpid/ch3/channels/sock/src/ch3_progress.c b/src/mpid/ch3/channels/sock/src/ch3_progress.c index 52e03b30cdd..c7f4a182251 100644 --- a/src/mpid/ch3/channels/sock/src/ch3_progress.c +++ b/src/mpid/ch3/channels/sock/src/ch3_progress.c @@ -4,7 +4,6 @@ */ #include "mpidi_ch3_impl.h" -#include "pmi.h" #include "mpidu_sock.h" #include "utlist.h" From 9312248ab3070a9008a2226494da4de90a2a24e2 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 15 Feb 2022 17:58:36 -0600 Subject: [PATCH 491/607] ch3: Define max jobid length in a single place This value is used in a couple different places in the device. Define it once in a header instead of in multiple files. Fixes a compile error with ch3:sock + pmi2. --- src/mpid/ch3/include/mpidimpl.h | 1 + src/mpid/ch3/src/mpid_init.c | 2 -- src/mpid/ch3/src/mpidi_pg.c | 6 ++---- src/mpid/ch3/util/sock/ch3u_connect_sock.c | 2 +- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/mpid/ch3/include/mpidimpl.h b/src/mpid/ch3/include/mpidimpl.h index 1ca5e7dd2b9..753a2cf9d7e 100644 --- a/src/mpid/ch3/include/mpidimpl.h +++ b/src/mpid/ch3/include/mpidimpl.h @@ -1006,6 +1006,7 @@ int MPIDI_CH3I_Port_destroy(int port_name_tag); --------------------------*/ #define MPIDI_MAX_KVS_VALUE_LEN 4096 +#define MPIDI_MAX_JOBID_LEN 1024 /* ------------------------------------------------------------------------- */ /* mpirma.h (in src/mpi/rma?) */ diff --git a/src/mpid/ch3/src/mpid_init.c b/src/mpid/ch3/src/mpid_init.c index ffbe4839f8a..5d6b780a5de 100644 --- a/src/mpid/ch3/src/mpid_init.c +++ b/src/mpid/ch3/src/mpid_init.c @@ -5,8 +5,6 @@ #include "mpidimpl.h" -#define MAX_JOBID_LEN 1024 - #if defined(HAVE_LIMITS_H) #include #endif diff --git a/src/mpid/ch3/src/mpidi_pg.c b/src/mpid/ch3/src/mpidi_pg.c index 72289c7c372..19870fd6bdc 100644 --- a/src/mpid/ch3/src/mpidi_pg.c +++ b/src/mpid/ch3/src/mpidi_pg.c @@ -10,8 +10,6 @@ #include "pmi.h" #endif -#define MAX_JOBID_LEN 1024 - /* === BEGIN_MPI_T_CVAR_INFO_BLOCK === @@ -739,12 +737,12 @@ int MPIDI_PG_InitConnKVS( MPIDI_PG_t *pg ) #ifdef USE_PMI2_API int mpi_errno = MPI_SUCCESS; - pg->connData = (char *)MPL_malloc(MAX_JOBID_LEN, MPL_MEM_STRINGS); + pg->connData = (char *)MPL_malloc(MPIDI_MAX_JOBID_LEN, MPL_MEM_STRINGS); if (pg->connData == NULL) { MPIR_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**nomem"); } - mpi_errno = PMI2_Job_GetId(pg->connData, MAX_JOBID_LEN); + mpi_errno = PMI2_Job_GetId(pg->connData, MPIDI_MAX_JOBID_LEN); MPIR_ERR_CHECK(mpi_errno); #else int pmi_errno, kvs_name_sz; diff --git a/src/mpid/ch3/util/sock/ch3u_connect_sock.c b/src/mpid/ch3/util/sock/ch3u_connect_sock.c index 0cd2f7c9258..ebff3cabd45 100644 --- a/src/mpid/ch3/util/sock/ch3u_connect_sock.c +++ b/src/mpid/ch3/util/sock/ch3u_connect_sock.c @@ -163,7 +163,7 @@ int MPIDI_CH3I_Connection_alloc(MPIDI_CH3I_Connection_t ** connp) we might prefer for connections to simply point at the single process group to which the remote process belong */ #ifdef USE_PMI2_API - id_sz = MPID_MAX_JOBID_LEN; + id_sz = MPIDI_MAX_JOBID_LEN; #else pmi_errno = PMI_KVS_Get_name_length_max(&id_sz); MPIR_ERR_CHKANDJUMP1(pmi_errno, mpi_errno,MPI_ERR_OTHER, From 71ccd5f808ed26d40a38179bf49deeed0cfa902d Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Wed, 16 Feb 2022 10:31:37 -0600 Subject: [PATCH 492/607] mpir: Add pmi2 support in MPIR_pmi_spawn_multiple --- src/util/mpir_pmi.c | 51 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/src/util/mpir_pmi.c b/src/util/mpir_pmi.c index 58632c12510..629af28ee61 100644 --- a/src/util/mpir_pmi.c +++ b/src/util/mpir_pmi.c @@ -886,8 +886,55 @@ int MPIR_pmi_spawn_multiple(int count, char *commands[], char **argvs[], MPIR_ERR_CHKANDJUMP1(pmi_errno != PMI_SUCCESS, mpi_errno, MPI_ERR_OTHER, "**pmi_spawn_multiple", "**pmi_spawn_multiple %d", pmi_errno); #elif defined(USE_PMI2_API) - /* not supported yet */ - MPIR_Assert(0); + struct MPIR_Info preput; + struct MPIR_Info *preput_p[1] = { &preput }; + int *argcs = MPL_malloc(count * sizeof(int), MPL_MEM_DYNAMIC); + int *info_keyval_sizes = MPL_malloc(count * sizeof(int), MPL_MEM_DYNAMIC); + MPIR_Assert(argcs); + MPIR_Assert(info_keyval_sizes); + + /* compute argcs array */ + for (int i = 0; i < count; ++i) { + argcs[i] = 0; + if (argvs != NULL && argvs[i] != NULL) { + while (argvs[i][argcs[i]]) { + ++argcs[i]; + } + } + } + + /* FIXME cheating on constness */ + preput.key = (char *) preput_keyvals->key; + preput.value = preput_keyvals->val; + preput.next = NULL; + + /* determine info sizes */ + if (!info_ptrs) { + for (int i = 0; i < count; i++) { + info_keyval_sizes[i] = 0; + } + } else { + for (int i = 0; i < count; i++) { + if (info_ptrs[i] != NULL) { + MPIR_Info_get_nkeys_impl(info_ptrs[i], &info_keyval_sizes[i]); + info_ptrs[i] = info_ptrs[i]->next; /* skip empty MPIR_Info struct */ + } else { + info_keyval_sizes[i] = 0; + } + } + } + + pmi_errno = PMI2_Job_Spawn(count, (const char **) commands, + argcs, (const char ***) argvs, + maxprocs, + info_keyval_sizes, (const MPIR_Info **) info_ptrs, + 1, (const struct MPIR_Info **) preput_p, NULL, 0, pmi_errcodes); + MPL_free(argcs); + MPL_free(info_keyval_sizes); + if (pmi_errno != PMI2_SUCCESS) { + MPIR_ERR_SETANDJUMP1(mpi_errno, MPI_ERR_OTHER, + "**pmi_spawn_multiple", "**pmi_spawn_multiple %d", pmi_errno); + } #elif defined(USE_PMIX_API) /* not supported yet */ MPIR_Assert(0); From 4c2c23d1bc4f7a3c10b75416a16ef427c4b17b28 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 15 Feb 2022 13:19:08 -0600 Subject: [PATCH 493/607] ch3: Use MPIR_pmi_spawn_multiple Eliminate duplicate code already present in the MPIR layer. --- src/mpid/ch3/src/ch3u_comm_spawn_multiple.c | 174 +------------------- 1 file changed, 7 insertions(+), 167 deletions(-) diff --git a/src/mpid/ch3/src/ch3u_comm_spawn_multiple.c b/src/mpid/ch3/src/ch3u_comm_spawn_multiple.c index d421730844d..4592a8e3de1 100644 --- a/src/mpid/ch3/src/ch3u_comm_spawn_multiple.c +++ b/src/mpid/ch3/src/ch3u_comm_spawn_multiple.c @@ -25,66 +25,6 @@ children */ #define PARENT_PORT_KVSKEY "PARENT_ROOT_PORT_NAME" -/* FIXME: We can avoid these two routines if we define PMI as using - MPI info values */ -/* Turn a SINGLE MPI_Info into an array of PMI_keyvals (return the pointer - to the array of PMI keyvals) */ -static int mpi_to_pmi_keyvals( MPIR_Info *info_ptr, PMI_keyval_t **kv_ptr, - int *nkeys_ptr ) -{ - char key[MPI_MAX_INFO_KEY]; - PMI_keyval_t *kv = 0; - int i, nkeys = 0, vallen, flag, mpi_errno=MPI_SUCCESS; - - if (!info_ptr || info_ptr->handle == MPI_INFO_NULL) { - goto fn_exit; - } - - MPIR_Info_get_nkeys_impl( info_ptr, &nkeys ); - if (nkeys == 0) { - goto fn_exit; - } - kv = (PMI_keyval_t *)MPL_malloc( nkeys * sizeof(PMI_keyval_t), MPL_MEM_DYNAMIC ); - if (!kv) { MPIR_ERR_POP(mpi_errno); } - - for (i=0; i, value: <%s>\n", kv[i].key, kv[i].val)); - } - - fn_fail: - fn_exit: - *kv_ptr = kv; - *nkeys_ptr = nkeys; - return mpi_errno; -} -/* Free the entire array of PMI keyvals */ -static void free_pmi_keyvals(PMI_keyval_t **kv, int size, int *counts) -{ - int i,j; - - for (i=0; irank == root) { /* create an array for the pmi error codes */ total_num_processes = 0; @@ -126,105 +64,12 @@ int MPIDI_Comm_spawn_multiple(int count, char **commands, /* --END ERROR HANDLING-- */ /* Spawn the processes */ -#ifdef USE_PMI2_API - MPIR_Assert(count > 0); - { - int *argcs = MPL_malloc(count*sizeof(int), MPL_MEM_DYNAMIC); - struct MPIR_Info preput; - struct MPIR_Info *preput_p[1] = { &preput }; - - MPIR_Assert(argcs); - /* - info_keyval_sizes = MPL_malloc(count * sizeof(int), MPL_MEM_DYNAMIC); - */ - - /* FIXME cheating on constness */ - preput.key = (char *)PARENT_PORT_KVSKEY; - preput.value = port_name; - preput.next = NULL; - - /* compute argcs array */ - for (i = 0; i < count; ++i) { - argcs[i] = 0; - if (argvs != NULL && argvs[i] != NULL) { - while (argvs[i][argcs[i]]) { - ++argcs[i]; - } - } - - /* a fib for now */ - /* - info_keyval_sizes[i] = 0; - */ - } - /* XXX DJG don't need this, PMI API is thread-safe? */ - /*MPID_THREAD_CS_ENTER(POBJ, MPIR_THREAD_POBJ_PMI_MUTEX);*/ - /* release the global CS for spawn PMI calls */ - MPID_THREAD_CS_EXIT(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); - pmi_errno = PMI2_Job_Spawn(count, (const char **)commands, - argcs, (const char ***)argvs, - maxprocs, - info_keyval_sizes, (const MPIR_Info **)info_ptrs, - 1, (const struct MPIR_Info **)preput_p, - NULL, 0, - /*jobId, jobIdSize,*/ /* XXX DJG job stuff? */ - pmi_errcodes); - MPID_THREAD_CS_ENTER(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); - /*MPID_THREAD_CS_EXIT(POBJ, MPIR_THREAD_POBJ_PMI_MUTEX);*/ - MPL_free(argcs); - if (pmi_errno != PMI2_SUCCESS) { - MPIR_ERR_SETANDJUMP1(mpi_errno, MPI_ERR_OTHER, - "**pmi_spawn_multiple", "**pmi_spawn_multiple %d", pmi_errno); - } - } -#else - /* FIXME: This is *really* awkward. We should either - Fix on MPI-style info data structures for PMI (avoid unnecessary - duplication) or add an MPIU_Info_getall(...) that creates - the necessary arrays of key/value pairs */ - - /* convert the infos into PMI keyvals */ - info_keyval_sizes = (int *) MPL_malloc(count * sizeof(int), MPL_MEM_DYNAMIC); - info_keyval_vectors = - (PMI_keyval_t**) MPL_malloc(count * sizeof(PMI_keyval_t*), MPL_MEM_DYNAMIC); - if (!info_keyval_sizes || !info_keyval_vectors) { - MPIR_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem"); - } + MPIR_PMI_KEYVAL_t preput; + preput.key = PARENT_PORT_KVSKEY; + preput.val = port_name; - if (!info_ptrs) { - for (i=0; i Date: Tue, 15 Feb 2022 11:39:02 -0600 Subject: [PATCH 494/607] debugger: Remove unused prev variable to fix compiler warning --- src/mpi/debugger/dbginit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mpi/debugger/dbginit.c b/src/mpi/debugger/dbginit.c index ae086ac7beb..cf3791be25b 100644 --- a/src/mpi/debugger/dbginit.c +++ b/src/mpi/debugger/dbginit.c @@ -405,7 +405,7 @@ void MPII_Debugq_remember(MPIR_Request * req, int rank, int tag, int context_id, void MPII_Debugq_forget(MPIR_Request * req, MPIR_Debugq ** queue) { #if defined HAVE_DEBUGGER_SUPPORT - MPIR_Debugq *p = NULL, *prev = NULL; + MPIR_Debugq *p = NULL; MPID_THREAD_CS_ENTER(VCI, lock); MPID_THREAD_CS_ENTER(POBJ, lock); From 9c827702f0dfca598f5d8b2458e428f622ba3157 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Thu, 17 Feb 2022 17:34:47 -0600 Subject: [PATCH 495/607] part: Add missing const to MPI_Psend_init buffer This was fixed as errata in MPI-4.0, so it was missed during our import of the MPI standard API definitions. Add const to MPI_Psend_init and all internal functions where the buffer is passed in. --- src/binding/mpi_standard_api.txt | 2 +- src/mpid/ch3/include/mpidpre.h | 2 +- src/mpid/ch3/src/mpid_part.c | 2 +- src/mpid/ch4/ch4_api.txt | 4 ++-- src/mpid/ch4/include/mpidch4.h | 2 +- src/mpid/ch4/netmod/ofi/ofi_part.c | 2 +- src/mpid/ch4/netmod/ucx/ucx_part.c | 2 +- src/mpid/ch4/shm/posix/posix_part.c | 2 +- src/mpid/ch4/shm/src/shm_part.c | 2 +- src/mpid/ch4/src/ch4_part.c | 2 +- src/mpid/ch4/src/mpidig_part.c | 4 ++-- src/mpid/ch4/src/mpidig_part.h | 2 +- 12 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/binding/mpi_standard_api.txt b/src/binding/mpi_standard_api.txt index 2aaab196b44..01d5a419332 100644 --- a/src/binding/mpi_standard_api.txt +++ b/src/binding/mpi_standard_api.txt @@ -1654,7 +1654,7 @@ MPI_Probe: comm: COMMUNICATOR status: STATUS, direction=out MPI_Psend_init: - buf: BUFFER, direction=IN, [initial address of send buffer (choice)] + buf: BUFFER, constant=True, direction=IN, [initial address of send buffer (choice)] partitions: PARTITION, direction=IN, [number of partitions] count: XFER_NUM_ELEM_NNI, direction=IN, [number of elements send per partition] datatype: DATATYPE, direction=IN, [type of each element] diff --git a/src/mpid/ch3/include/mpidpre.h b/src/mpid/ch3/include/mpidpre.h index b7a81c7bc91..c2e21435593 100644 --- a/src/mpid/ch3/include/mpidpre.h +++ b/src/mpid/ch3/include/mpidpre.h @@ -726,7 +726,7 @@ int MPID_Mrecv(void *buf, int count, MPI_Datatype datatype, int MPID_Cancel_send(MPIR_Request *); int MPID_Cancel_recv(MPIR_Request *); -int MPID_Psend_init(void *buf, int partitions, MPI_Count count, MPI_Datatype datatype, +int MPID_Psend_init(const void *buf, int partitions, MPI_Count count, MPI_Datatype datatype, int dest, int tag, MPIR_Comm *comm, MPIR_Info *info, MPIR_Request **request ); int MPID_Precv_init(void *buf, int partitions, MPI_Count count, MPI_Datatype datatype, diff --git a/src/mpid/ch3/src/mpid_part.c b/src/mpid/ch3/src/mpid_part.c index 11b860fffdc..5484af49f66 100644 --- a/src/mpid/ch3/src/mpid_part.c +++ b/src/mpid/ch3/src/mpid_part.c @@ -5,7 +5,7 @@ #include "mpidimpl.h" -int MPID_Psend_init(void *buf, int partitions, MPI_Count count, MPI_Datatype datatype, +int MPID_Psend_init(const void *buf, int partitions, MPI_Count count, MPI_Datatype datatype, int dest, int tag, MPIR_Comm *comm, MPIR_Info *info, MPIR_Request **request ) { diff --git a/src/mpid/ch4/ch4_api.txt b/src/mpid/ch4/ch4_api.txt index 4dc2959babd..672091d42d8 100644 --- a/src/mpid/ch4/ch4_api.txt +++ b/src/mpid/ch4/ch4_api.txt @@ -126,8 +126,8 @@ Native API: NM*: rreq SHM*: rreq mpi_psend_init : int - NM: buf-2, partitions, count, datatype, rank, tag, comm, info, av, req_p - SHM: buf-2, partitions, count, datatype, rank, tag, comm, info, av, req_p + NM: buf, partitions, count, datatype, rank, tag, comm, info, av, req_p + SHM: buf, partitions, count, datatype, rank, tag, comm, info, av, req_p mpi_precv_init : int NM: buf-2, partitions, count, datatype, rank, tag, comm, info, av, req_p SHM: buf-2, partitions, count, datatype, rank, tag, comm, info, av, req_p diff --git a/src/mpid/ch4/include/mpidch4.h b/src/mpid/ch4/include/mpidch4.h index 49301fda3ac..59983db2cf0 100644 --- a/src/mpid/ch4/include/mpidch4.h +++ b/src/mpid/ch4/include/mpidch4.h @@ -93,7 +93,7 @@ MPL_STATIC_INLINE_PREFIX int MPID_Rsend_init(const void *, MPI_Aint, MPI_Datatyp MPIR_Request **) MPL_STATIC_INLINE_SUFFIX; MPL_STATIC_INLINE_PREFIX int MPID_Startall(int, MPIR_Request *[]) MPL_STATIC_INLINE_SUFFIX; -int MPID_Psend_init(void *, int, MPI_Aint, MPI_Datatype, int, int, MPIR_Comm *, +int MPID_Psend_init(const void *, int, MPI_Aint, MPI_Datatype, int, int, MPIR_Comm *, MPIR_Info *, MPIR_Request **); int MPID_Precv_init(void *, int, MPI_Aint, MPI_Datatype, int, int, MPIR_Comm *, MPIR_Info *, MPIR_Request **); diff --git a/src/mpid/ch4/netmod/ofi/ofi_part.c b/src/mpid/ch4/netmod/ofi/ofi_part.c index d3ebdad1ef3..1f99334413c 100644 --- a/src/mpid/ch4/netmod/ofi/ofi_part.c +++ b/src/mpid/ch4/netmod/ofi/ofi_part.c @@ -7,7 +7,7 @@ #include "ofi_impl.h" #include "ofi_noinline.h" -int MPIDI_OFI_mpi_psend_init(void *buf, int partitions, MPI_Aint count, +int MPIDI_OFI_mpi_psend_init(const void *buf, int partitions, MPI_Aint count, MPI_Datatype datatype, int dest, int tag, MPIR_Comm * comm, MPIR_Info * info, MPIDI_av_entry_t * av, MPIR_Request ** request) diff --git a/src/mpid/ch4/netmod/ucx/ucx_part.c b/src/mpid/ch4/netmod/ucx/ucx_part.c index 1a18b4669ca..fd9e3d3347f 100644 --- a/src/mpid/ch4/netmod/ucx/ucx_part.c +++ b/src/mpid/ch4/netmod/ucx/ucx_part.c @@ -6,7 +6,7 @@ #include "mpidimpl.h" #include "ucx_impl.h" -int MPIDI_UCX_mpi_psend_init(void *buf, int partitions, MPI_Aint count, +int MPIDI_UCX_mpi_psend_init(const void *buf, int partitions, MPI_Aint count, MPI_Datatype datatype, int dest, int tag, MPIR_Comm * comm, MPIR_Info * info, MPIDI_av_entry_t * av, MPIR_Request ** request) diff --git a/src/mpid/ch4/shm/posix/posix_part.c b/src/mpid/ch4/shm/posix/posix_part.c index 7a9d38d8eac..0c6964925bc 100644 --- a/src/mpid/ch4/shm/posix/posix_part.c +++ b/src/mpid/ch4/shm/posix/posix_part.c @@ -6,7 +6,7 @@ #include "mpidimpl.h" #include "posix_noinline.h" -int MPIDI_POSIX_mpi_psend_init(void *buf, int partitions, MPI_Aint count, +int MPIDI_POSIX_mpi_psend_init(const void *buf, int partitions, MPI_Aint count, MPI_Datatype datatype, int dest, int tag, MPIR_Comm * comm, MPIR_Info * info, MPIDI_av_entry_t * av, MPIR_Request ** request) diff --git a/src/mpid/ch4/shm/src/shm_part.c b/src/mpid/ch4/shm/src/shm_part.c index 72c5ed67ba6..cebd788a496 100644 --- a/src/mpid/ch4/shm/src/shm_part.c +++ b/src/mpid/ch4/shm/src/shm_part.c @@ -7,7 +7,7 @@ #include "shm_noinline.h" #include "../posix/posix_noinline.h" -int MPIDI_SHM_mpi_psend_init(void *buf, int partitions, MPI_Aint count, +int MPIDI_SHM_mpi_psend_init(const void *buf, int partitions, MPI_Aint count, MPI_Datatype datatype, int dest, int tag, MPIR_Comm * comm, MPIR_Info * info, MPIDI_av_entry_t * av, MPIR_Request ** request) diff --git a/src/mpid/ch4/src/ch4_part.c b/src/mpid/ch4/src/ch4_part.c index 5bda70e4219..bf1d9fab3c1 100644 --- a/src/mpid/ch4/src/ch4_part.c +++ b/src/mpid/ch4/src/ch4_part.c @@ -5,7 +5,7 @@ #include "mpidimpl.h" -int MPID_Psend_init(void *buf, int partitions, MPI_Aint count, +int MPID_Psend_init(const void *buf, int partitions, MPI_Aint count, MPI_Datatype datatype, int dest, int tag, MPIR_Comm * comm, MPIR_Info * info, MPIR_Request ** request) { diff --git a/src/mpid/ch4/src/mpidig_part.c b/src/mpid/ch4/src/mpidig_part.c index 4b22cd33641..f25b0c6dbc7 100644 --- a/src/mpid/ch4/src/mpidig_part.c +++ b/src/mpid/ch4/src/mpidig_part.c @@ -92,7 +92,7 @@ void MPIDIG_precv_matched(MPIR_Request * part_req) } } -int MPIDIG_mpi_psend_init(void *buf, int partitions, MPI_Aint count, +int MPIDIG_mpi_psend_init(const void *buf, int partitions, MPI_Aint count, MPI_Datatype datatype, int dest, int tag, MPIR_Comm * comm, MPIR_Info * info, MPIR_Request ** request) { @@ -102,7 +102,7 @@ int MPIDIG_mpi_psend_init(void *buf, int partitions, MPI_Aint count, MPID_THREAD_CS_ENTER(VCI, MPIDI_VCI(0).lock); /* Create and initialize device-layer partitioned request */ - mpi_errno = part_req_create(buf, partitions, count, datatype, dest, tag, comm, + mpi_errno = part_req_create((void *) buf, partitions, count, datatype, dest, tag, comm, MPIR_REQUEST_KIND__PART_SEND, request); MPIR_ERR_CHECK(mpi_errno); diff --git a/src/mpid/ch4/src/mpidig_part.h b/src/mpid/ch4/src/mpidig_part.h index 356ae446225..2fc38f6b226 100644 --- a/src/mpid/ch4/src/mpidig_part.h +++ b/src/mpid/ch4/src/mpidig_part.h @@ -10,7 +10,7 @@ #include "mpidig_part_utils.h" void MPIDIG_precv_matched(MPIR_Request * part_req); -int MPIDIG_mpi_psend_init(void *buf, int partitions, MPI_Aint count, +int MPIDIG_mpi_psend_init(const void *buf, int partitions, MPI_Aint count, MPI_Datatype datatype, int dest, int tag, MPIR_Comm * comm, MPIR_Info * info, MPIR_Request ** request); int MPIDIG_mpi_precv_init(void *buf, int partitions, int count, From bf2ee7e6e8592b006bf91adebdd4ec51aade4100 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 15 Feb 2022 13:12:32 -0600 Subject: [PATCH 496/607] hydra: reorganize mansrc files Rather than scatter the manual pages, put them in the mansrc directory. Move mpiexec man page into hydra folder because we need ensure the documentation is in sync with the code. We omit hydra2 here since it is deprecated. --- src/env/Makefile.mk | 3 +-- src/pm/hydra/Makefile.am | 6 +++++- .../hydra/{tools/nameserver => mansrc}/hydra_nameserver.txt | 0 .../{tools/bootstrap/persist => mansrc}/hydra_persist.txt | 0 src/pm/hydra/{pm/pmiserv => mansrc}/hydra_pmi_proxy.txt | 0 src/{env => pm/hydra/mansrc}/mpiexec.txt | 0 src/pm/hydra/pm/pmiserv/Makefile.mk | 2 -- src/pm/hydra/tools/bootstrap/persist/Makefile.mk | 2 -- src/pm/hydra/tools/nameserver/Makefile.mk | 2 -- 9 files changed, 6 insertions(+), 9 deletions(-) rename src/pm/hydra/{tools/nameserver => mansrc}/hydra_nameserver.txt (100%) rename src/pm/hydra/{tools/bootstrap/persist => mansrc}/hydra_persist.txt (100%) rename src/pm/hydra/{pm/pmiserv => mansrc}/hydra_pmi_proxy.txt (100%) rename src/{env => pm/hydra/mansrc}/mpiexec.txt (100%) diff --git a/src/env/Makefile.mk b/src/env/Makefile.mk index ca27daafecb..b448fbf883a 100644 --- a/src/env/Makefile.mk +++ b/src/env/Makefile.mk @@ -58,7 +58,6 @@ DISTCLEANFILES += $(top_builddir)/src/env/cc_shlib.conf \ wrapper_doc_src = src/env/mpicc.txt \ src/env/mpicxx.txt \ - src/env/mpifort.txt \ - src/env/mpiexec.txt + src/env/mpifort.txt doc1_src_txt += $(wrapper_doc_src) EXTRA_DIST += $(wrapper_doc_src) diff --git a/src/pm/hydra/Makefile.am b/src/pm/hydra/Makefile.am index 701704becf1..15bb81f3bd7 100644 --- a/src/pm/hydra/Makefile.am +++ b/src/pm/hydra/Makefile.am @@ -14,7 +14,11 @@ noinst_HEADERS = DISTCLEANFILES = EXTRA_DIST = SUFFIXES = -doc1_src_txt = +doc1_src_txt = \ + mansrc/mpiexec.txt \ + mansrc/hydra_pmi_proxy.txt \ + mansrc/hydra_nameserver.txt \ + mansrc/hydra_persist.txt ACLOCAL_AMFLAGS = -I confdb AM_CPPFLAGS = -I$(top_srcdir)/include $(external_includes) diff --git a/src/pm/hydra/tools/nameserver/hydra_nameserver.txt b/src/pm/hydra/mansrc/hydra_nameserver.txt similarity index 100% rename from src/pm/hydra/tools/nameserver/hydra_nameserver.txt rename to src/pm/hydra/mansrc/hydra_nameserver.txt diff --git a/src/pm/hydra/tools/bootstrap/persist/hydra_persist.txt b/src/pm/hydra/mansrc/hydra_persist.txt similarity index 100% rename from src/pm/hydra/tools/bootstrap/persist/hydra_persist.txt rename to src/pm/hydra/mansrc/hydra_persist.txt diff --git a/src/pm/hydra/pm/pmiserv/hydra_pmi_proxy.txt b/src/pm/hydra/mansrc/hydra_pmi_proxy.txt similarity index 100% rename from src/pm/hydra/pm/pmiserv/hydra_pmi_proxy.txt rename to src/pm/hydra/mansrc/hydra_pmi_proxy.txt diff --git a/src/env/mpiexec.txt b/src/pm/hydra/mansrc/mpiexec.txt similarity index 100% rename from src/env/mpiexec.txt rename to src/pm/hydra/mansrc/mpiexec.txt diff --git a/src/pm/hydra/pm/pmiserv/Makefile.mk b/src/pm/hydra/pm/pmiserv/Makefile.mk index 303a75e1c7e..10b0dc64048 100644 --- a/src/pm/hydra/pm/pmiserv/Makefile.mk +++ b/src/pm/hydra/pm/pmiserv/Makefile.mk @@ -36,5 +36,3 @@ libpm_la_SOURCES += pm/pmiserv/pmiserv_pmi.c \ pm/pmiserv/pmiserv_utils.c \ pm/pmiserv/common.c \ pm/pmiserv/pmi_v2_common.c - -doc1_src_txt += pm/pmiserv/hydra_pmi_proxy.txt diff --git a/src/pm/hydra/tools/bootstrap/persist/Makefile.mk b/src/pm/hydra/tools/bootstrap/persist/Makefile.mk index f77dd153fc6..ab8502bdbe5 100644 --- a/src/pm/hydra/tools/bootstrap/persist/Makefile.mk +++ b/src/pm/hydra/tools/bootstrap/persist/Makefile.mk @@ -19,5 +19,3 @@ noinst_HEADERS += \ libhydra_la_SOURCES += tools/bootstrap/persist/persist_init.c \ tools/bootstrap/persist/persist_launch.c \ tools/bootstrap/persist/persist_wait.c - -doc1_src_txt += tools/bootstrap/persist/hydra_persist.txt diff --git a/src/pm/hydra/tools/nameserver/Makefile.mk b/src/pm/hydra/tools/nameserver/Makefile.mk index 025750fc608..97be8b10269 100644 --- a/src/pm/hydra/tools/nameserver/Makefile.mk +++ b/src/pm/hydra/tools/nameserver/Makefile.mk @@ -10,5 +10,3 @@ hydra_nameserver_CFLAGS = $(AM_CFLAGS) hydra_nameserver_LDFLAGS = $(external_ldflags) hydra_nameserver_LDADD = -lhydra $(external_libs) hydra_nameserver_DEPENDENCIES = libhydra.la - -doc1_src_txt += tools/nameserver/hydra_nameserver.txt From 5d4c2b76fc12fda0e2f09cc35b0d74ce656a1e86 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 6 Feb 2022 15:22:50 -0600 Subject: [PATCH 497/607] hydra: move main hydra source into mpiexec folder Rather than searching for the main hydra code, move the main code into mpiexec folder and flatten its directory layout. There was a --with-hydr-ui configure option that were designed to build different versions of mpiexec. This design seems never panned out. Remove the option for now. --- .gitignore | 1 - src/pm/hydra/Makefile.am | 2 +- src/pm/hydra/configure.ac | 11 ----------- src/pm/hydra/{ui/mpich => mpiexec}/Makefile.mk | 11 ++++++----- src/pm/hydra/{ui/mpich => mpiexec}/mpiexec.c | 0 src/pm/hydra/{ui/mpich => mpiexec}/mpiexec.h | 0 src/pm/hydra/{ui/include => mpiexec}/ui.h | 0 src/pm/hydra/{ui/utils => mpiexec}/uiu.c | 0 src/pm/hydra/{ui/utils => mpiexec}/uiu.h | 0 src/pm/hydra/{ui/mpich => mpiexec}/utils.c | 0 src/pm/hydra/ui/Makefile.mk | 14 -------------- src/pm/hydra/ui/utils/Makefile.mk | 8 -------- 12 files changed, 7 insertions(+), 40 deletions(-) rename src/pm/hydra/{ui/mpich => mpiexec}/Makefile.mk (58%) rename src/pm/hydra/{ui/mpich => mpiexec}/mpiexec.c (100%) rename src/pm/hydra/{ui/mpich => mpiexec}/mpiexec.h (100%) rename src/pm/hydra/{ui/include => mpiexec}/ui.h (100%) rename src/pm/hydra/{ui/utils => mpiexec}/uiu.c (100%) rename src/pm/hydra/{ui/utils => mpiexec}/uiu.h (100%) rename src/pm/hydra/{ui/mpich => mpiexec}/utils.c (100%) delete mode 100644 src/pm/hydra/ui/Makefile.mk delete mode 100644 src/pm/hydra/ui/utils/Makefile.mk diff --git a/.gitignore b/.gitignore index 4734d27e7e0..2ab80263d3b 100644 --- a/.gitignore +++ b/.gitignore @@ -96,7 +96,6 @@ localdefs mpe_*.conf mpich*pgrs.html mpid_config.h.in -mpiexec old old*_pngs stamp-h1 diff --git a/src/pm/hydra/Makefile.am b/src/pm/hydra/Makefile.am index 15bb81f3bd7..28cf6372c55 100644 --- a/src/pm/hydra/Makefile.am +++ b/src/pm/hydra/Makefile.am @@ -35,7 +35,7 @@ libhydra_la_SOURCES = include utils/Makefile.mk include tools/Makefile.mk include pm/Makefile.mk -include ui/Makefile.mk +include mpiexec/Makefile.mk # External subdirs should be built first, as we might depend on them SUBDIRS = ${external_subdirs} . diff --git a/src/pm/hydra/configure.ac b/src/pm/hydra/configure.ac index 5f8e6ca028f..0dd41dacb55 100644 --- a/src/pm/hydra/configure.ac +++ b/src/pm/hydra/configure.ac @@ -355,17 +355,6 @@ AC_SUBST(hydra_pm) AM_CONDITIONAL([hydra_pm_pmiserv], [test $hydra_pm = "pmiserv"]) -######################################################################### -# Check what UI we should use -######################################################################### -AC_ARG_WITH(hydra-ui, [ --with-hydra-ui=name - User Interface (mpich)], - [ hydra_ui=$withval ], - [ hydra_ui=mpich ]) -AC_MSG_CHECKING(user interface) -AC_MSG_RESULT($hydra_ui) -AC_SUBST(hydra_ui) -AM_CONDITIONAL([hydra_ui_mpich], [test $hydra_ui = "mpich"]) - ######################################################################### # Processor Topology ######################################################################### diff --git a/src/pm/hydra/ui/mpich/Makefile.mk b/src/pm/hydra/mpiexec/Makefile.mk similarity index 58% rename from src/pm/hydra/ui/mpich/Makefile.mk rename to src/pm/hydra/mpiexec/Makefile.mk index 9890e19ba7c..b3ddb3702ad 100644 --- a/src/pm/hydra/ui/mpich/Makefile.mk +++ b/src/pm/hydra/mpiexec/Makefile.mk @@ -3,13 +3,14 @@ ## See COPYRIGHT in top-level directory ## -AM_CPPFLAGS += -I$(top_srcdir)/ui/utils -DHYDRA_CONF_FILE=\"@sysconfdir@/mpiexec.hydra.conf\" - -noinst_HEADERS += ui/mpich/mpiexec.h - bin_PROGRAMS += mpiexec.hydra -mpiexec_hydra_SOURCES = ui/mpich/mpiexec.c ui/mpich/utils.c +mpiexec_hydra_SOURCES = \ + mpiexec/mpiexec.c \ + mpiexec/utils.c \ + mpiexec/uiu.c + +mpiexec_hydra_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/mpiexec -DHYDRA_CONF_FILE=\"@sysconfdir@/mpiexec.hydra.conf\" mpiexec_hydra_LDFLAGS = $(external_ldflags) -L$(top_builddir) mpiexec_hydra_LDADD = -lpm -lhydra $(external_libs) mpiexec_hydra_DEPENDENCIES = libpm.la libhydra.la diff --git a/src/pm/hydra/ui/mpich/mpiexec.c b/src/pm/hydra/mpiexec/mpiexec.c similarity index 100% rename from src/pm/hydra/ui/mpich/mpiexec.c rename to src/pm/hydra/mpiexec/mpiexec.c diff --git a/src/pm/hydra/ui/mpich/mpiexec.h b/src/pm/hydra/mpiexec/mpiexec.h similarity index 100% rename from src/pm/hydra/ui/mpich/mpiexec.h rename to src/pm/hydra/mpiexec/mpiexec.h diff --git a/src/pm/hydra/ui/include/ui.h b/src/pm/hydra/mpiexec/ui.h similarity index 100% rename from src/pm/hydra/ui/include/ui.h rename to src/pm/hydra/mpiexec/ui.h diff --git a/src/pm/hydra/ui/utils/uiu.c b/src/pm/hydra/mpiexec/uiu.c similarity index 100% rename from src/pm/hydra/ui/utils/uiu.c rename to src/pm/hydra/mpiexec/uiu.c diff --git a/src/pm/hydra/ui/utils/uiu.h b/src/pm/hydra/mpiexec/uiu.h similarity index 100% rename from src/pm/hydra/ui/utils/uiu.h rename to src/pm/hydra/mpiexec/uiu.h diff --git a/src/pm/hydra/ui/mpich/utils.c b/src/pm/hydra/mpiexec/utils.c similarity index 100% rename from src/pm/hydra/ui/mpich/utils.c rename to src/pm/hydra/mpiexec/utils.c diff --git a/src/pm/hydra/ui/Makefile.mk b/src/pm/hydra/ui/Makefile.mk deleted file mode 100644 index 12fe62900de..00000000000 --- a/src/pm/hydra/ui/Makefile.mk +++ /dev/null @@ -1,14 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -AM_CPPFLAGS += -I$(top_srcdir)/ui/include - -noinst_HEADERS += ui/include/ui.h - -include ui/utils/Makefile.mk - -if hydra_ui_mpich -include ui/mpich/Makefile.mk -endif diff --git a/src/pm/hydra/ui/utils/Makefile.mk b/src/pm/hydra/ui/utils/Makefile.mk deleted file mode 100644 index 33e2ca1d2cc..00000000000 --- a/src/pm/hydra/ui/utils/Makefile.mk +++ /dev/null @@ -1,8 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -libhydra_la_SOURCES += ui/utils/uiu.c - -noinst_HEADERS += ui/utils/uiu.h From 263e26cef4b5aedca87ab3e9f08dd80a8d21c092 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 6 Feb 2022 17:00:41 -0600 Subject: [PATCH 498/607] hydra: rename pm/pmiserv/common.h to pmiserv_common.h There are multiple common.h. Rename it to be more specific. Also remove noinst_HEADERS from src/pm/hydra/pm/pmiserv/Makefile.mk since we no longer maintain dist target and it is now irrelevant. --- src/pm/hydra/pm/pmiserv/Makefile.mk | 9 --------- src/pm/hydra/pm/pmiserv/common.c | 2 +- src/pm/hydra/pm/pmiserv/pmip.h | 2 +- src/pm/hydra/pm/pmiserv/pmip_pmi.h | 2 +- src/pm/hydra/pm/pmiserv/pmiserv.h | 2 +- src/pm/hydra/pm/pmiserv/{common.h => pmiserv_common.h} | 0 src/pm/hydra/pm/pmiserv/pmiserv_pmi.h | 2 +- 7 files changed, 5 insertions(+), 14 deletions(-) rename src/pm/hydra/pm/pmiserv/{common.h => pmiserv_common.h} (100%) diff --git a/src/pm/hydra/pm/pmiserv/Makefile.mk b/src/pm/hydra/pm/pmiserv/Makefile.mk index 10b0dc64048..e6658eded58 100644 --- a/src/pm/hydra/pm/pmiserv/Makefile.mk +++ b/src/pm/hydra/pm/pmiserv/Makefile.mk @@ -5,15 +5,6 @@ AM_CPPFLAGS += -I$(top_srcdir)/pm/utils -noinst_HEADERS += \ - pm/pmiserv/common.h \ - pm/pmiserv/pmi_v2_common.h \ - pm/pmiserv/pmip.h \ - pm/pmiserv/pmip_pmi.h \ - pm/pmiserv/pmiserv.h \ - pm/pmiserv/pmiserv_pmi.h \ - pm/pmiserv/pmiserv_utils.h - bin_PROGRAMS += hydra_pmi_proxy hydra_pmi_proxy_SOURCES = pm/pmiserv/pmip.c \ diff --git a/src/pm/hydra/pm/pmiserv/common.c b/src/pm/hydra/pm/pmiserv/common.c index 2816fcb81be..04a596c8ce1 100644 --- a/src/pm/hydra/pm/pmiserv/common.c +++ b/src/pm/hydra/pm/pmiserv/common.c @@ -4,7 +4,7 @@ */ #include "hydra.h" -#include "common.h" +#include "pmiserv_common.h" #include "topo.h" void HYD_pmcd_init_header(struct HYD_pmcd_hdr *hdr) diff --git a/src/pm/hydra/pm/pmiserv/pmip.h b/src/pm/hydra/pm/pmiserv/pmip.h index 87576701f81..db30e49e756 100644 --- a/src/pm/hydra/pm/pmiserv/pmip.h +++ b/src/pm/hydra/pm/pmiserv/pmip.h @@ -7,7 +7,7 @@ #define PMIP_H_INCLUDED #include "hydra.h" -#include "common.h" +#include "pmiserv_common.h" struct HYD_pmcd_pmip_map { int left; diff --git a/src/pm/hydra/pm/pmiserv/pmip_pmi.h b/src/pm/hydra/pm/pmiserv/pmip_pmi.h index 14afdf1089e..26375c69f95 100644 --- a/src/pm/hydra/pm/pmiserv/pmip_pmi.h +++ b/src/pm/hydra/pm/pmiserv/pmip_pmi.h @@ -7,7 +7,7 @@ #define PMIP_PMI_H_INCLUDED #include "hydra.h" -#include "common.h" +#include "pmiserv_common.h" /* PMI-1 specific definitions */ extern struct HYD_pmcd_pmip_pmi_handle *HYD_pmcd_pmip_pmi_v1; diff --git a/src/pm/hydra/pm/pmiserv/pmiserv.h b/src/pm/hydra/pm/pmiserv/pmiserv.h index 957eea7fc0e..22622940d1e 100644 --- a/src/pm/hydra/pm/pmiserv/pmiserv.h +++ b/src/pm/hydra/pm/pmiserv/pmiserv.h @@ -6,7 +6,7 @@ #ifndef PMISERV_H_INCLUDED #define PMISERV_H_INCLUDED -#include "common.h" +#include "pmiserv_common.h" HYD_status HYD_pmcd_pmiserv_proxy_init_cb(int fd, HYD_event_t events, void *userp); HYD_status HYD_pmcd_pmiserv_control_listen_cb(int fd, HYD_event_t events, void *userp); diff --git a/src/pm/hydra/pm/pmiserv/common.h b/src/pm/hydra/pm/pmiserv/pmiserv_common.h similarity index 100% rename from src/pm/hydra/pm/pmiserv/common.h rename to src/pm/hydra/pm/pmiserv/pmiserv_common.h diff --git a/src/pm/hydra/pm/pmiserv/pmiserv_pmi.h b/src/pm/hydra/pm/pmiserv/pmiserv_pmi.h index 2ae7f113e48..fdf9c2fa767 100644 --- a/src/pm/hydra/pm/pmiserv/pmiserv_pmi.h +++ b/src/pm/hydra/pm/pmiserv/pmiserv_pmi.h @@ -8,7 +8,7 @@ #include "hydra.h" #include "demux.h" -#include "common.h" +#include "pmiserv_common.h" /* PMI-1 specific definitions */ extern struct HYD_pmcd_pmi_handle *HYD_pmcd_pmi_v1; From 93f8e3deecc6aa9c25615c6449243afc9a431811 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 6 Feb 2022 15:49:33 -0600 Subject: [PATCH 499/607] hydra: move hydra_pmi_proxy source into proxy folder hydra_pmi_proxy is a separate executable. Move it into its own top-level directory rather than hiding inside a library folder. --- src/pm/hydra/Makefile.am | 1 + src/pm/hydra/pm/pmiserv/Makefile.mk | 16 +-------------- src/pm/hydra/proxy/Makefile.mk | 20 +++++++++++++++++++ src/pm/hydra/{pm/pmiserv => proxy}/pmip.c | 0 src/pm/hydra/{pm/pmiserv => proxy}/pmip.h | 0 src/pm/hydra/{pm/pmiserv => proxy}/pmip_cb.c | 0 src/pm/hydra/{pm/pmiserv => proxy}/pmip_pmi.h | 0 .../hydra/{pm/pmiserv => proxy}/pmip_pmi_v1.c | 0 .../hydra/{pm/pmiserv => proxy}/pmip_pmi_v2.c | 0 .../hydra/{pm/pmiserv => proxy}/pmip_utils.c | 0 10 files changed, 22 insertions(+), 15 deletions(-) create mode 100644 src/pm/hydra/proxy/Makefile.mk rename src/pm/hydra/{pm/pmiserv => proxy}/pmip.c (100%) rename src/pm/hydra/{pm/pmiserv => proxy}/pmip.h (100%) rename src/pm/hydra/{pm/pmiserv => proxy}/pmip_cb.c (100%) rename src/pm/hydra/{pm/pmiserv => proxy}/pmip_pmi.h (100%) rename src/pm/hydra/{pm/pmiserv => proxy}/pmip_pmi_v1.c (100%) rename src/pm/hydra/{pm/pmiserv => proxy}/pmip_pmi_v2.c (100%) rename src/pm/hydra/{pm/pmiserv => proxy}/pmip_utils.c (100%) diff --git a/src/pm/hydra/Makefile.am b/src/pm/hydra/Makefile.am index 28cf6372c55..3e45525737e 100644 --- a/src/pm/hydra/Makefile.am +++ b/src/pm/hydra/Makefile.am @@ -36,6 +36,7 @@ include utils/Makefile.mk include tools/Makefile.mk include pm/Makefile.mk include mpiexec/Makefile.mk +include proxy/Makefile.mk # External subdirs should be built first, as we might depend on them SUBDIRS = ${external_subdirs} . diff --git a/src/pm/hydra/pm/pmiserv/Makefile.mk b/src/pm/hydra/pm/pmiserv/Makefile.mk index e6658eded58..eac95dbd43a 100644 --- a/src/pm/hydra/pm/pmiserv/Makefile.mk +++ b/src/pm/hydra/pm/pmiserv/Makefile.mk @@ -3,21 +3,7 @@ ## See COPYRIGHT in top-level directory ## -AM_CPPFLAGS += -I$(top_srcdir)/pm/utils - -bin_PROGRAMS += hydra_pmi_proxy - -hydra_pmi_proxy_SOURCES = pm/pmiserv/pmip.c \ - pm/pmiserv/pmip_cb.c \ - pm/pmiserv/pmip_utils.c \ - pm/pmiserv/pmip_pmi_v1.c \ - pm/pmiserv/pmip_pmi_v2.c \ - pm/pmiserv/common.c \ - pm/pmiserv/pmi_v2_common.c -hydra_pmi_proxy_CFLAGS = $(AM_CFLAGS) -hydra_pmi_proxy_LDFLAGS = $(external_ldflags) -L$(top_builddir) -hydra_pmi_proxy_LDADD = -lhydra $(external_libs) -hydra_pmi_proxy_DEPENDENCIES = libhydra.la +AM_CPPFLAGS += -I$(top_srcdir)/pm/utils -I$(top_srcdir)/pm/pmiserv libpm_la_SOURCES += pm/pmiserv/pmiserv_pmi.c \ pm/pmiserv/pmiserv_pmi_v1.c \ diff --git a/src/pm/hydra/proxy/Makefile.mk b/src/pm/hydra/proxy/Makefile.mk new file mode 100644 index 00000000000..d71c224666e --- /dev/null +++ b/src/pm/hydra/proxy/Makefile.mk @@ -0,0 +1,20 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +bin_PROGRAMS += hydra_pmi_proxy + +hydra_pmi_proxy_SOURCES = \ + proxy/pmip.c \ + proxy/pmip_cb.c \ + proxy/pmip_utils.c \ + proxy/pmip_pmi_v1.c \ + proxy/pmip_pmi_v2.c \ + pm/pmiserv/common.c \ + pm/pmiserv/pmi_v2_common.c + +hydra_pmi_proxy_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/proxy +hydra_pmi_proxy_LDFLAGS = $(external_ldflags) -L$(top_builddir) +hydra_pmi_proxy_LDADD = -lhydra $(external_libs) +hydra_pmi_proxy_DEPENDENCIES = libhydra.la diff --git a/src/pm/hydra/pm/pmiserv/pmip.c b/src/pm/hydra/proxy/pmip.c similarity index 100% rename from src/pm/hydra/pm/pmiserv/pmip.c rename to src/pm/hydra/proxy/pmip.c diff --git a/src/pm/hydra/pm/pmiserv/pmip.h b/src/pm/hydra/proxy/pmip.h similarity index 100% rename from src/pm/hydra/pm/pmiserv/pmip.h rename to src/pm/hydra/proxy/pmip.h diff --git a/src/pm/hydra/pm/pmiserv/pmip_cb.c b/src/pm/hydra/proxy/pmip_cb.c similarity index 100% rename from src/pm/hydra/pm/pmiserv/pmip_cb.c rename to src/pm/hydra/proxy/pmip_cb.c diff --git a/src/pm/hydra/pm/pmiserv/pmip_pmi.h b/src/pm/hydra/proxy/pmip_pmi.h similarity index 100% rename from src/pm/hydra/pm/pmiserv/pmip_pmi.h rename to src/pm/hydra/proxy/pmip_pmi.h diff --git a/src/pm/hydra/pm/pmiserv/pmip_pmi_v1.c b/src/pm/hydra/proxy/pmip_pmi_v1.c similarity index 100% rename from src/pm/hydra/pm/pmiserv/pmip_pmi_v1.c rename to src/pm/hydra/proxy/pmip_pmi_v1.c diff --git a/src/pm/hydra/pm/pmiserv/pmip_pmi_v2.c b/src/pm/hydra/proxy/pmip_pmi_v2.c similarity index 100% rename from src/pm/hydra/pm/pmiserv/pmip_pmi_v2.c rename to src/pm/hydra/proxy/pmip_pmi_v2.c diff --git a/src/pm/hydra/pm/pmiserv/pmip_utils.c b/src/pm/hydra/proxy/pmip_utils.c similarity index 100% rename from src/pm/hydra/pm/pmiserv/pmip_utils.c rename to src/pm/hydra/proxy/pmip_utils.c From 58281d05f3ecdcdc59124ff757f80b1693d21509 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 6 Feb 2022 17:13:01 -0600 Subject: [PATCH 500/607] hydra: move nameserver source to nameserver folder hydra_nameserver is a separate executable. Move it into its separate folder. --- src/pm/hydra/Makefile.am | 1 + src/pm/hydra/{tools => }/nameserver/Makefile.mk | 2 +- src/pm/hydra/{tools => }/nameserver/hydra_nameserver.c | 0 src/pm/hydra/tools/Makefile.mk | 1 - 4 files changed, 2 insertions(+), 2 deletions(-) rename src/pm/hydra/{tools => }/nameserver/Makefile.mk (83%) rename src/pm/hydra/{tools => }/nameserver/hydra_nameserver.c (100%) diff --git a/src/pm/hydra/Makefile.am b/src/pm/hydra/Makefile.am index 3e45525737e..9fba4142255 100644 --- a/src/pm/hydra/Makefile.am +++ b/src/pm/hydra/Makefile.am @@ -37,6 +37,7 @@ include tools/Makefile.mk include pm/Makefile.mk include mpiexec/Makefile.mk include proxy/Makefile.mk +include nameserver/Makefile.mk # External subdirs should be built first, as we might depend on them SUBDIRS = ${external_subdirs} . diff --git a/src/pm/hydra/tools/nameserver/Makefile.mk b/src/pm/hydra/nameserver/Makefile.mk similarity index 83% rename from src/pm/hydra/tools/nameserver/Makefile.mk rename to src/pm/hydra/nameserver/Makefile.mk index 97be8b10269..4b5586ae579 100644 --- a/src/pm/hydra/tools/nameserver/Makefile.mk +++ b/src/pm/hydra/nameserver/Makefile.mk @@ -5,7 +5,7 @@ bin_PROGRAMS += hydra_nameserver -hydra_nameserver_SOURCES = tools/nameserver/hydra_nameserver.c +hydra_nameserver_SOURCES = nameserver/hydra_nameserver.c hydra_nameserver_CFLAGS = $(AM_CFLAGS) hydra_nameserver_LDFLAGS = $(external_ldflags) hydra_nameserver_LDADD = -lhydra $(external_libs) diff --git a/src/pm/hydra/tools/nameserver/hydra_nameserver.c b/src/pm/hydra/nameserver/hydra_nameserver.c similarity index 100% rename from src/pm/hydra/tools/nameserver/hydra_nameserver.c rename to src/pm/hydra/nameserver/hydra_nameserver.c diff --git a/src/pm/hydra/tools/Makefile.mk b/src/pm/hydra/tools/Makefile.mk index 62a4d6c7e7a..b22e89d0fb3 100644 --- a/src/pm/hydra/tools/Makefile.mk +++ b/src/pm/hydra/tools/Makefile.mk @@ -9,4 +9,3 @@ include tools/topo/Makefile.mk include tools/bootstrap/Makefile.mk include tools/demux/Makefile.mk include tools/debugger/Makefile.mk -include tools/nameserver/Makefile.mk From 133983037c9d98628376c03110e5c47f46b8c2a2 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 6 Feb 2022 17:30:04 -0600 Subject: [PATCH 501/607] hydra: move persist_server.c to its own folder persist_server is an individual executable. Move it to its own folder. --- src/pm/hydra/Makefile.am | 3 +++ src/pm/hydra/persist_server/Makefile.mk | 12 ++++++++++++ .../persist => persist_server}/persist_server.c | 0 src/pm/hydra/tools/bootstrap/persist/Makefile.mk | 13 +------------ 4 files changed, 16 insertions(+), 12 deletions(-) create mode 100644 src/pm/hydra/persist_server/Makefile.mk rename src/pm/hydra/{tools/bootstrap/persist => persist_server}/persist_server.c (100%) diff --git a/src/pm/hydra/Makefile.am b/src/pm/hydra/Makefile.am index 9fba4142255..a6af88e8514 100644 --- a/src/pm/hydra/Makefile.am +++ b/src/pm/hydra/Makefile.am @@ -38,6 +38,9 @@ include pm/Makefile.mk include mpiexec/Makefile.mk include proxy/Makefile.mk include nameserver/Makefile.mk +if hydra_bss_persist +include persist_server/Makefile.mk +endif # External subdirs should be built first, as we might depend on them SUBDIRS = ${external_subdirs} . diff --git a/src/pm/hydra/persist_server/Makefile.mk b/src/pm/hydra/persist_server/Makefile.mk new file mode 100644 index 00000000000..15bf29a56e9 --- /dev/null +++ b/src/pm/hydra/persist_server/Makefile.mk @@ -0,0 +1,12 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +bin_PROGRAMS += hydra_persist + +hydra_persist_SOURCES = persist_server/persist_server.c +hydra_persist_CFLAGS = $(AM_CFLAGS) +hydra_persist_LDFLAGS = $(external_ldflags) -L$(top_builddir) +hydra_persist_LDADD = -lhydra $(external_libs) +hydra_persist_DEPENDENCIES = libhydra.la diff --git a/src/pm/hydra/tools/bootstrap/persist/persist_server.c b/src/pm/hydra/persist_server/persist_server.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/persist/persist_server.c rename to src/pm/hydra/persist_server/persist_server.c diff --git a/src/pm/hydra/tools/bootstrap/persist/Makefile.mk b/src/pm/hydra/tools/bootstrap/persist/Makefile.mk index ab8502bdbe5..e16bfb0a659 100644 --- a/src/pm/hydra/tools/bootstrap/persist/Makefile.mk +++ b/src/pm/hydra/tools/bootstrap/persist/Makefile.mk @@ -3,18 +3,7 @@ ## See COPYRIGHT in top-level directory ## -bin_PROGRAMS += hydra_persist - -hydra_persist_SOURCES = tools/bootstrap/persist/persist_server.c -hydra_persist_CFLAGS = $(AM_CFLAGS) -hydra_persist_LDFLAGS = $(external_ldflags) -L$(top_builddir) -hydra_persist_LDADD = -lhydra $(external_libs) -hydra_persist_DEPENDENCIES = libhydra.la - -noinst_HEADERS += \ - tools/bootstrap/persist/persist.h \ - tools/bootstrap/persist/persist_client.h \ - tools/bootstrap/persist/persist_server.h +AM_CPPFLAGS += -I$(top_srcdir)/tools/bootstrap/persist libhydra_la_SOURCES += tools/bootstrap/persist/persist_init.c \ tools/bootstrap/persist/persist_launch.c \ From 6605fa2e0cf8665d00c7f7c65dad5b3cbeafe963 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 6 Feb 2022 18:22:10 -0600 Subject: [PATCH 502/607] hydra: move libhydra source into lib folder This fits libhydra.la as a top-level target. --- src/pm/hydra/Makefile.am | 3 +- src/pm/hydra/configure.ac | 2 +- src/pm/hydra/lib/Makefile.mk | 8 +++ src/pm/hydra/lib/tools/Makefile.mk | 11 ++++ src/pm/hydra/lib/tools/bootstrap/Makefile.mk | 19 ++++++ .../lib/tools/bootstrap/external/Makefile.mk | 61 +++++++++++++++++++ .../tools/bootstrap/external/cobalt.h | 0 .../tools/bootstrap/external/cobalt_init.c | 0 .../external/cobalt_query_native_int.c | 0 .../external/cobalt_query_node_list.c | 0 .../tools/bootstrap/external/common.h | 0 .../bootstrap/external/external_common.c | 0 .../external/external_common_launch.c | 0 .../tools/bootstrap/external/external_init.c | 0 .../tools/bootstrap/external/fork_init.c | 0 .../{ => lib}/tools/bootstrap/external/ll.h | 0 .../tools/bootstrap/external/ll_env.c | 0 .../tools/bootstrap/external/ll_init.c | 0 .../tools/bootstrap/external/ll_launch.c | 0 .../bootstrap/external/ll_query_native_int.c | 0 .../bootstrap/external/ll_query_node_list.c | 0 .../bootstrap/external/ll_query_proxy_id.c | 0 .../{ => lib}/tools/bootstrap/external/lsf.h | 0 .../tools/bootstrap/external/lsf_env.c | 0 .../tools/bootstrap/external/lsf_init.c | 0 .../bootstrap/external/lsf_query_native_int.c | 0 .../bootstrap/external/lsf_query_node_list.c | 0 .../tools/bootstrap/external/manual_init.c | 0 .../{ => lib}/tools/bootstrap/external/pbs.h | 0 .../tools/bootstrap/external/pbs_env.c | 0 .../tools/bootstrap/external/pbs_finalize.c | 0 .../tools/bootstrap/external/pbs_init.c | 0 .../tools/bootstrap/external/pbs_launch.c | 0 .../bootstrap/external/pbs_query_native_int.c | 0 .../bootstrap/external/pbs_query_node_list.c | 0 .../tools/bootstrap/external/pbs_wait.c | 0 .../{ => lib}/tools/bootstrap/external/rsh.h | 0 .../tools/bootstrap/external/rsh_env.c | 0 .../tools/bootstrap/external/rsh_init.c | 0 .../{ => lib}/tools/bootstrap/external/sge.h | 0 .../tools/bootstrap/external/sge_env.c | 0 .../tools/bootstrap/external/sge_init.c | 0 .../bootstrap/external/sge_query_native_int.c | 0 .../bootstrap/external/sge_query_node_list.c | 0 .../tools/bootstrap/external/slurm.h | 0 .../tools/bootstrap/external/slurm_env.c | 0 .../tools/bootstrap/external/slurm_init.c | 0 .../tools/bootstrap/external/slurm_launch.c | 0 .../external/slurm_query_native_int.c | 0 .../external/slurm_query_node_list.c | 0 .../bootstrap/external/slurm_query_proxy_id.c | 0 .../{ => lib}/tools/bootstrap/external/ssh.c | 0 .../{ => lib}/tools/bootstrap/external/ssh.h | 0 .../tools/bootstrap/external/ssh_env.c | 0 .../tools/bootstrap/external/ssh_finalize.c | 0 .../tools/bootstrap/external/ssh_init.c | 0 .../tools/bootstrap/external/user_init.c | 0 .../{ => lib}/tools/bootstrap/include/bsci.h | 0 .../lib/tools/bootstrap/persist/Makefile.mk | 10 +++ .../tools/bootstrap/persist/persist.h | 0 .../tools/bootstrap/persist/persist_client.h | 0 .../tools/bootstrap/persist/persist_init.c | 0 .../tools/bootstrap/persist/persist_launch.c | 0 .../tools/bootstrap/persist/persist_server.h | 0 .../tools/bootstrap/persist/persist_wait.c | 0 .../hydra/lib/tools/bootstrap/src/Makefile.mk | 13 ++++ .../{ => lib}/tools/bootstrap/src/bsci_env.c | 0 .../tools/bootstrap/src/bsci_finalize.c | 0 .../tools/bootstrap/src/bsci_init.c.in | 0 .../tools/bootstrap/src/bsci_launch.c | 0 .../bootstrap/src/bsci_query_native_int.c | 0 .../bootstrap/src/bsci_query_node_list.c | 0 .../tools/bootstrap/src/bsci_query_proxy_id.c | 0 .../{ => lib}/tools/bootstrap/src/bsci_wait.c | 0 .../lib/tools/bootstrap/utils/Makefile.mk | 12 ++++ .../{ => lib}/tools/bootstrap/utils/bscu.h | 0 .../{ => lib}/tools/bootstrap/utils/bscu_cb.c | 0 .../tools/bootstrap/utils/bscu_wait.c | 0 src/pm/hydra/lib/tools/debugger/Makefile.mk | 8 +++ .../hydra/{ => lib}/tools/debugger/debugger.c | 0 .../hydra/{ => lib}/tools/debugger/debugger.h | 0 src/pm/hydra/lib/tools/demux/Makefile.mk | 18 ++++++ src/pm/hydra/{ => lib}/tools/demux/demux.c | 0 src/pm/hydra/{ => lib}/tools/demux/demux.h | 0 .../{ => lib}/tools/demux/demux_internal.h | 0 .../hydra/{ => lib}/tools/demux/demux_poll.c | 0 .../{ => lib}/tools/demux/demux_select.c | 0 src/pm/hydra/lib/tools/topo/Makefile.mk | 14 +++++ src/pm/hydra/lib/tools/topo/hwloc/Makefile.mk | 8 +++ .../{ => lib}/tools/topo/hwloc/topo_hwloc.c | 0 .../{ => lib}/tools/topo/hwloc/topo_hwloc.h | 0 src/pm/hydra/{ => lib}/tools/topo/topo.c | 0 src/pm/hydra/{ => lib}/tools/topo/topo.h | 0 src/pm/hydra/lib/utils/Makefile.mk | 14 +++++ src/pm/hydra/lib/utils/alloc/Makefile.mk | 6 ++ src/pm/hydra/{ => lib}/utils/alloc/alloc.c | 0 .../alloc => lib/utils/args}/Makefile.mk | 2 +- src/pm/hydra/{ => lib}/utils/args/args.c | 0 .../{utils/args => lib/utils/dbg}/Makefile.mk | 2 +- src/pm/hydra/{ => lib}/utils/dbg/dbg.c | 0 .../{utils/dbg => lib/utils/env}/Makefile.mk | 2 +- src/pm/hydra/{ => lib}/utils/env/env.c | 0 src/pm/hydra/lib/utils/launch/Makefile.mk | 6 ++ src/pm/hydra/{ => lib}/utils/launch/launch.c | 0 src/pm/hydra/lib/utils/others/Makefile.mk | 6 ++ src/pm/hydra/{ => lib}/utils/others/others.c | 0 src/pm/hydra/lib/utils/signals/Makefile.mk | 6 ++ .../hydra/{ => lib}/utils/signals/signals.c | 0 .../{utils/env => lib/utils/sock}/Makefile.mk | 2 +- src/pm/hydra/{ => lib}/utils/sock/sock.c | 0 src/pm/hydra/lib/utils/string/Makefile.mk | 6 ++ src/pm/hydra/{ => lib}/utils/string/string.c | 0 src/pm/hydra/tools/Makefile.mk | 11 ---- src/pm/hydra/tools/bootstrap/Makefile.mk | 19 ------ .../tools/bootstrap/external/Makefile.mk | 61 ------------------- .../hydra/tools/bootstrap/persist/Makefile.mk | 10 --- src/pm/hydra/tools/bootstrap/src/Makefile.mk | 13 ---- .../hydra/tools/bootstrap/utils/Makefile.mk | 12 ---- src/pm/hydra/tools/debugger/Makefile.mk | 10 --- src/pm/hydra/tools/demux/Makefile.mk | 18 ------ src/pm/hydra/tools/topo/Makefile.mk | 14 ----- src/pm/hydra/tools/topo/hwloc/Makefile.mk | 8 --- src/pm/hydra/utils/Makefile.mk | 14 ----- src/pm/hydra/utils/launch/Makefile.mk | 6 -- src/pm/hydra/utils/others/Makefile.mk | 6 -- src/pm/hydra/utils/signals/Makefile.mk | 6 -- src/pm/hydra/utils/sock/Makefile.mk | 6 -- src/pm/hydra/utils/string/Makefile.mk | 6 -- 128 files changed, 232 insertions(+), 227 deletions(-) create mode 100644 src/pm/hydra/lib/Makefile.mk create mode 100644 src/pm/hydra/lib/tools/Makefile.mk create mode 100644 src/pm/hydra/lib/tools/bootstrap/Makefile.mk create mode 100644 src/pm/hydra/lib/tools/bootstrap/external/Makefile.mk rename src/pm/hydra/{ => lib}/tools/bootstrap/external/cobalt.h (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/cobalt_init.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/cobalt_query_native_int.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/cobalt_query_node_list.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/common.h (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/external_common.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/external_common_launch.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/external_init.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/fork_init.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/ll.h (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/ll_env.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/ll_init.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/ll_launch.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/ll_query_native_int.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/ll_query_node_list.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/ll_query_proxy_id.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/lsf.h (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/lsf_env.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/lsf_init.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/lsf_query_native_int.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/lsf_query_node_list.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/manual_init.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/pbs.h (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/pbs_env.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/pbs_finalize.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/pbs_init.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/pbs_launch.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/pbs_query_native_int.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/pbs_query_node_list.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/pbs_wait.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/rsh.h (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/rsh_env.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/rsh_init.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/sge.h (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/sge_env.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/sge_init.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/sge_query_native_int.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/sge_query_node_list.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/slurm.h (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/slurm_env.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/slurm_init.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/slurm_launch.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/slurm_query_native_int.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/slurm_query_node_list.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/slurm_query_proxy_id.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/ssh.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/ssh.h (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/ssh_env.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/ssh_finalize.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/ssh_init.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/external/user_init.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/include/bsci.h (100%) create mode 100644 src/pm/hydra/lib/tools/bootstrap/persist/Makefile.mk rename src/pm/hydra/{ => lib}/tools/bootstrap/persist/persist.h (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/persist/persist_client.h (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/persist/persist_init.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/persist/persist_launch.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/persist/persist_server.h (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/persist/persist_wait.c (100%) create mode 100644 src/pm/hydra/lib/tools/bootstrap/src/Makefile.mk rename src/pm/hydra/{ => lib}/tools/bootstrap/src/bsci_env.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/src/bsci_finalize.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/src/bsci_init.c.in (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/src/bsci_launch.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/src/bsci_query_native_int.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/src/bsci_query_node_list.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/src/bsci_query_proxy_id.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/src/bsci_wait.c (100%) create mode 100644 src/pm/hydra/lib/tools/bootstrap/utils/Makefile.mk rename src/pm/hydra/{ => lib}/tools/bootstrap/utils/bscu.h (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/utils/bscu_cb.c (100%) rename src/pm/hydra/{ => lib}/tools/bootstrap/utils/bscu_wait.c (100%) create mode 100644 src/pm/hydra/lib/tools/debugger/Makefile.mk rename src/pm/hydra/{ => lib}/tools/debugger/debugger.c (100%) rename src/pm/hydra/{ => lib}/tools/debugger/debugger.h (100%) create mode 100644 src/pm/hydra/lib/tools/demux/Makefile.mk rename src/pm/hydra/{ => lib}/tools/demux/demux.c (100%) rename src/pm/hydra/{ => lib}/tools/demux/demux.h (100%) rename src/pm/hydra/{ => lib}/tools/demux/demux_internal.h (100%) rename src/pm/hydra/{ => lib}/tools/demux/demux_poll.c (100%) rename src/pm/hydra/{ => lib}/tools/demux/demux_select.c (100%) create mode 100644 src/pm/hydra/lib/tools/topo/Makefile.mk create mode 100644 src/pm/hydra/lib/tools/topo/hwloc/Makefile.mk rename src/pm/hydra/{ => lib}/tools/topo/hwloc/topo_hwloc.c (100%) rename src/pm/hydra/{ => lib}/tools/topo/hwloc/topo_hwloc.h (100%) rename src/pm/hydra/{ => lib}/tools/topo/topo.c (100%) rename src/pm/hydra/{ => lib}/tools/topo/topo.h (100%) create mode 100644 src/pm/hydra/lib/utils/Makefile.mk create mode 100644 src/pm/hydra/lib/utils/alloc/Makefile.mk rename src/pm/hydra/{ => lib}/utils/alloc/alloc.c (100%) rename src/pm/hydra/{utils/alloc => lib/utils/args}/Makefile.mk (68%) rename src/pm/hydra/{ => lib}/utils/args/args.c (100%) rename src/pm/hydra/{utils/args => lib/utils/dbg}/Makefile.mk (69%) rename src/pm/hydra/{ => lib}/utils/dbg/dbg.c (100%) rename src/pm/hydra/{utils/dbg => lib/utils/env}/Makefile.mk (69%) rename src/pm/hydra/{ => lib}/utils/env/env.c (100%) create mode 100644 src/pm/hydra/lib/utils/launch/Makefile.mk rename src/pm/hydra/{ => lib}/utils/launch/launch.c (100%) create mode 100644 src/pm/hydra/lib/utils/others/Makefile.mk rename src/pm/hydra/{ => lib}/utils/others/others.c (100%) create mode 100644 src/pm/hydra/lib/utils/signals/Makefile.mk rename src/pm/hydra/{ => lib}/utils/signals/signals.c (100%) rename src/pm/hydra/{utils/env => lib/utils/sock}/Makefile.mk (68%) rename src/pm/hydra/{ => lib}/utils/sock/sock.c (100%) create mode 100644 src/pm/hydra/lib/utils/string/Makefile.mk rename src/pm/hydra/{ => lib}/utils/string/string.c (100%) delete mode 100644 src/pm/hydra/tools/Makefile.mk delete mode 100644 src/pm/hydra/tools/bootstrap/Makefile.mk delete mode 100644 src/pm/hydra/tools/bootstrap/external/Makefile.mk delete mode 100644 src/pm/hydra/tools/bootstrap/persist/Makefile.mk delete mode 100644 src/pm/hydra/tools/bootstrap/src/Makefile.mk delete mode 100644 src/pm/hydra/tools/bootstrap/utils/Makefile.mk delete mode 100644 src/pm/hydra/tools/debugger/Makefile.mk delete mode 100644 src/pm/hydra/tools/demux/Makefile.mk delete mode 100644 src/pm/hydra/tools/topo/Makefile.mk delete mode 100644 src/pm/hydra/tools/topo/hwloc/Makefile.mk delete mode 100644 src/pm/hydra/utils/Makefile.mk delete mode 100644 src/pm/hydra/utils/launch/Makefile.mk delete mode 100644 src/pm/hydra/utils/others/Makefile.mk delete mode 100644 src/pm/hydra/utils/signals/Makefile.mk delete mode 100644 src/pm/hydra/utils/sock/Makefile.mk delete mode 100644 src/pm/hydra/utils/string/Makefile.mk diff --git a/src/pm/hydra/Makefile.am b/src/pm/hydra/Makefile.am index a6af88e8514..0719650ae29 100644 --- a/src/pm/hydra/Makefile.am +++ b/src/pm/hydra/Makefile.am @@ -32,8 +32,7 @@ noinst_LTLIBRARIES = libhydra.la libhydra_la_SOURCES = # The below directories contribute to libhydra -include utils/Makefile.mk -include tools/Makefile.mk +include lib/Makefile.mk include pm/Makefile.mk include mpiexec/Makefile.mk include proxy/Makefile.mk diff --git a/src/pm/hydra/configure.ac b/src/pm/hydra/configure.ac index 0dd41dacb55..eb4366a3e44 100644 --- a/src/pm/hydra/configure.ac +++ b/src/pm/hydra/configure.ac @@ -620,7 +620,7 @@ fi # Final output AC_CONFIG_FILES([Makefile - tools/bootstrap/src/bsci_init.c + lib/tools/bootstrap/src/bsci_init.c hydra-doxygen.cfg ]) AC_OUTPUT diff --git a/src/pm/hydra/lib/Makefile.mk b/src/pm/hydra/lib/Makefile.mk new file mode 100644 index 00000000000..a256b443fc1 --- /dev/null +++ b/src/pm/hydra/lib/Makefile.mk @@ -0,0 +1,8 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +include lib/utils/Makefile.mk +include lib/tools/Makefile.mk + diff --git a/src/pm/hydra/lib/tools/Makefile.mk b/src/pm/hydra/lib/tools/Makefile.mk new file mode 100644 index 00000000000..2b16a818454 --- /dev/null +++ b/src/pm/hydra/lib/tools/Makefile.mk @@ -0,0 +1,11 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +tools_libs = + +include lib/tools/topo/Makefile.mk +include lib/tools/bootstrap/Makefile.mk +include lib/tools/demux/Makefile.mk +include lib/tools/debugger/Makefile.mk diff --git a/src/pm/hydra/lib/tools/bootstrap/Makefile.mk b/src/pm/hydra/lib/tools/bootstrap/Makefile.mk new file mode 100644 index 00000000000..d90cf631c6e --- /dev/null +++ b/src/pm/hydra/lib/tools/bootstrap/Makefile.mk @@ -0,0 +1,19 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +AM_CPPFLAGS += -I$(top_srcdir)/lib/tools/bootstrap/include + +noinst_HEADERS += lib/tools/bootstrap/include/bsci.h + +include lib/tools/bootstrap/src/Makefile.mk +include lib/tools/bootstrap/utils/Makefile.mk + +if hydra_bss_external +include lib/tools/bootstrap/external/Makefile.mk +endif + +if hydra_bss_persist +include lib/tools/bootstrap/persist/Makefile.mk +endif diff --git a/src/pm/hydra/lib/tools/bootstrap/external/Makefile.mk b/src/pm/hydra/lib/tools/bootstrap/external/Makefile.mk new file mode 100644 index 00000000000..3910bf23cfa --- /dev/null +++ b/src/pm/hydra/lib/tools/bootstrap/external/Makefile.mk @@ -0,0 +1,61 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +noinst_HEADERS += \ + lib/tools/bootstrap/external/common.h \ + lib/tools/bootstrap/external/ll.h \ + lib/tools/bootstrap/external/lsf.h \ + lib/tools/bootstrap/external/pbs.h \ + lib/tools/bootstrap/external/rsh.h \ + lib/tools/bootstrap/external/sge.h \ + lib/tools/bootstrap/external/slurm.h \ + lib/tools/bootstrap/external/cobalt.h \ + lib/tools/bootstrap/external/ssh.h + +libhydra_la_SOURCES += lib/tools/bootstrap/external/external_common.c \ + lib/tools/bootstrap/external/external_common_launch.c \ + lib/tools/bootstrap/external/fork_init.c \ + lib/tools/bootstrap/external/user_init.c \ + lib/tools/bootstrap/external/manual_init.c \ + lib/tools/bootstrap/external/rsh_init.c \ + lib/tools/bootstrap/external/rsh_env.c \ + lib/tools/bootstrap/external/ssh_init.c \ + lib/tools/bootstrap/external/ssh.c \ + lib/tools/bootstrap/external/ssh_env.c \ + lib/tools/bootstrap/external/ssh_finalize.c \ + lib/tools/bootstrap/external/slurm_init.c \ + lib/tools/bootstrap/external/slurm_launch.c \ + lib/tools/bootstrap/external/slurm_env.c \ + lib/tools/bootstrap/external/slurm_query_native_int.c \ + lib/tools/bootstrap/external/slurm_query_node_list.c \ + lib/tools/bootstrap/external/slurm_query_proxy_id.c \ + lib/tools/bootstrap/external/ll_init.c \ + lib/tools/bootstrap/external/ll_launch.c \ + lib/tools/bootstrap/external/ll_query_native_int.c \ + lib/tools/bootstrap/external/ll_query_node_list.c \ + lib/tools/bootstrap/external/ll_query_proxy_id.c \ + lib/tools/bootstrap/external/ll_env.c \ + lib/tools/bootstrap/external/lsf_init.c \ + lib/tools/bootstrap/external/lsf_query_native_int.c \ + lib/tools/bootstrap/external/lsf_query_node_list.c \ + lib/tools/bootstrap/external/lsf_env.c \ + lib/tools/bootstrap/external/sge_init.c \ + lib/tools/bootstrap/external/sge_query_native_int.c \ + lib/tools/bootstrap/external/sge_query_node_list.c \ + lib/tools/bootstrap/external/sge_env.c \ + lib/tools/bootstrap/external/pbs_init.c \ + lib/tools/bootstrap/external/pbs_query_native_int.c \ + lib/tools/bootstrap/external/pbs_query_node_list.c \ + lib/tools/bootstrap/external/cobalt_init.c \ + lib/tools/bootstrap/external/cobalt_query_native_int.c \ + lib/tools/bootstrap/external/cobalt_query_node_list.c + +if hydra_pbs_launcher +libhydra_la_SOURCES += \ + lib/tools/bootstrap/external/pbs_finalize.c \ + lib/tools/bootstrap/external/pbs_launch.c \ + lib/tools/bootstrap/external/pbs_wait.c \ + lib/tools/bootstrap/external/pbs_env.c +endif diff --git a/src/pm/hydra/tools/bootstrap/external/cobalt.h b/src/pm/hydra/lib/tools/bootstrap/external/cobalt.h similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/cobalt.h rename to src/pm/hydra/lib/tools/bootstrap/external/cobalt.h diff --git a/src/pm/hydra/tools/bootstrap/external/cobalt_init.c b/src/pm/hydra/lib/tools/bootstrap/external/cobalt_init.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/cobalt_init.c rename to src/pm/hydra/lib/tools/bootstrap/external/cobalt_init.c diff --git a/src/pm/hydra/tools/bootstrap/external/cobalt_query_native_int.c b/src/pm/hydra/lib/tools/bootstrap/external/cobalt_query_native_int.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/cobalt_query_native_int.c rename to src/pm/hydra/lib/tools/bootstrap/external/cobalt_query_native_int.c diff --git a/src/pm/hydra/tools/bootstrap/external/cobalt_query_node_list.c b/src/pm/hydra/lib/tools/bootstrap/external/cobalt_query_node_list.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/cobalt_query_node_list.c rename to src/pm/hydra/lib/tools/bootstrap/external/cobalt_query_node_list.c diff --git a/src/pm/hydra/tools/bootstrap/external/common.h b/src/pm/hydra/lib/tools/bootstrap/external/common.h similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/common.h rename to src/pm/hydra/lib/tools/bootstrap/external/common.h diff --git a/src/pm/hydra/tools/bootstrap/external/external_common.c b/src/pm/hydra/lib/tools/bootstrap/external/external_common.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/external_common.c rename to src/pm/hydra/lib/tools/bootstrap/external/external_common.c diff --git a/src/pm/hydra/tools/bootstrap/external/external_common_launch.c b/src/pm/hydra/lib/tools/bootstrap/external/external_common_launch.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/external_common_launch.c rename to src/pm/hydra/lib/tools/bootstrap/external/external_common_launch.c diff --git a/src/pm/hydra/tools/bootstrap/external/external_init.c b/src/pm/hydra/lib/tools/bootstrap/external/external_init.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/external_init.c rename to src/pm/hydra/lib/tools/bootstrap/external/external_init.c diff --git a/src/pm/hydra/tools/bootstrap/external/fork_init.c b/src/pm/hydra/lib/tools/bootstrap/external/fork_init.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/fork_init.c rename to src/pm/hydra/lib/tools/bootstrap/external/fork_init.c diff --git a/src/pm/hydra/tools/bootstrap/external/ll.h b/src/pm/hydra/lib/tools/bootstrap/external/ll.h similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/ll.h rename to src/pm/hydra/lib/tools/bootstrap/external/ll.h diff --git a/src/pm/hydra/tools/bootstrap/external/ll_env.c b/src/pm/hydra/lib/tools/bootstrap/external/ll_env.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/ll_env.c rename to src/pm/hydra/lib/tools/bootstrap/external/ll_env.c diff --git a/src/pm/hydra/tools/bootstrap/external/ll_init.c b/src/pm/hydra/lib/tools/bootstrap/external/ll_init.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/ll_init.c rename to src/pm/hydra/lib/tools/bootstrap/external/ll_init.c diff --git a/src/pm/hydra/tools/bootstrap/external/ll_launch.c b/src/pm/hydra/lib/tools/bootstrap/external/ll_launch.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/ll_launch.c rename to src/pm/hydra/lib/tools/bootstrap/external/ll_launch.c diff --git a/src/pm/hydra/tools/bootstrap/external/ll_query_native_int.c b/src/pm/hydra/lib/tools/bootstrap/external/ll_query_native_int.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/ll_query_native_int.c rename to src/pm/hydra/lib/tools/bootstrap/external/ll_query_native_int.c diff --git a/src/pm/hydra/tools/bootstrap/external/ll_query_node_list.c b/src/pm/hydra/lib/tools/bootstrap/external/ll_query_node_list.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/ll_query_node_list.c rename to src/pm/hydra/lib/tools/bootstrap/external/ll_query_node_list.c diff --git a/src/pm/hydra/tools/bootstrap/external/ll_query_proxy_id.c b/src/pm/hydra/lib/tools/bootstrap/external/ll_query_proxy_id.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/ll_query_proxy_id.c rename to src/pm/hydra/lib/tools/bootstrap/external/ll_query_proxy_id.c diff --git a/src/pm/hydra/tools/bootstrap/external/lsf.h b/src/pm/hydra/lib/tools/bootstrap/external/lsf.h similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/lsf.h rename to src/pm/hydra/lib/tools/bootstrap/external/lsf.h diff --git a/src/pm/hydra/tools/bootstrap/external/lsf_env.c b/src/pm/hydra/lib/tools/bootstrap/external/lsf_env.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/lsf_env.c rename to src/pm/hydra/lib/tools/bootstrap/external/lsf_env.c diff --git a/src/pm/hydra/tools/bootstrap/external/lsf_init.c b/src/pm/hydra/lib/tools/bootstrap/external/lsf_init.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/lsf_init.c rename to src/pm/hydra/lib/tools/bootstrap/external/lsf_init.c diff --git a/src/pm/hydra/tools/bootstrap/external/lsf_query_native_int.c b/src/pm/hydra/lib/tools/bootstrap/external/lsf_query_native_int.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/lsf_query_native_int.c rename to src/pm/hydra/lib/tools/bootstrap/external/lsf_query_native_int.c diff --git a/src/pm/hydra/tools/bootstrap/external/lsf_query_node_list.c b/src/pm/hydra/lib/tools/bootstrap/external/lsf_query_node_list.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/lsf_query_node_list.c rename to src/pm/hydra/lib/tools/bootstrap/external/lsf_query_node_list.c diff --git a/src/pm/hydra/tools/bootstrap/external/manual_init.c b/src/pm/hydra/lib/tools/bootstrap/external/manual_init.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/manual_init.c rename to src/pm/hydra/lib/tools/bootstrap/external/manual_init.c diff --git a/src/pm/hydra/tools/bootstrap/external/pbs.h b/src/pm/hydra/lib/tools/bootstrap/external/pbs.h similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/pbs.h rename to src/pm/hydra/lib/tools/bootstrap/external/pbs.h diff --git a/src/pm/hydra/tools/bootstrap/external/pbs_env.c b/src/pm/hydra/lib/tools/bootstrap/external/pbs_env.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/pbs_env.c rename to src/pm/hydra/lib/tools/bootstrap/external/pbs_env.c diff --git a/src/pm/hydra/tools/bootstrap/external/pbs_finalize.c b/src/pm/hydra/lib/tools/bootstrap/external/pbs_finalize.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/pbs_finalize.c rename to src/pm/hydra/lib/tools/bootstrap/external/pbs_finalize.c diff --git a/src/pm/hydra/tools/bootstrap/external/pbs_init.c b/src/pm/hydra/lib/tools/bootstrap/external/pbs_init.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/pbs_init.c rename to src/pm/hydra/lib/tools/bootstrap/external/pbs_init.c diff --git a/src/pm/hydra/tools/bootstrap/external/pbs_launch.c b/src/pm/hydra/lib/tools/bootstrap/external/pbs_launch.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/pbs_launch.c rename to src/pm/hydra/lib/tools/bootstrap/external/pbs_launch.c diff --git a/src/pm/hydra/tools/bootstrap/external/pbs_query_native_int.c b/src/pm/hydra/lib/tools/bootstrap/external/pbs_query_native_int.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/pbs_query_native_int.c rename to src/pm/hydra/lib/tools/bootstrap/external/pbs_query_native_int.c diff --git a/src/pm/hydra/tools/bootstrap/external/pbs_query_node_list.c b/src/pm/hydra/lib/tools/bootstrap/external/pbs_query_node_list.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/pbs_query_node_list.c rename to src/pm/hydra/lib/tools/bootstrap/external/pbs_query_node_list.c diff --git a/src/pm/hydra/tools/bootstrap/external/pbs_wait.c b/src/pm/hydra/lib/tools/bootstrap/external/pbs_wait.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/pbs_wait.c rename to src/pm/hydra/lib/tools/bootstrap/external/pbs_wait.c diff --git a/src/pm/hydra/tools/bootstrap/external/rsh.h b/src/pm/hydra/lib/tools/bootstrap/external/rsh.h similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/rsh.h rename to src/pm/hydra/lib/tools/bootstrap/external/rsh.h diff --git a/src/pm/hydra/tools/bootstrap/external/rsh_env.c b/src/pm/hydra/lib/tools/bootstrap/external/rsh_env.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/rsh_env.c rename to src/pm/hydra/lib/tools/bootstrap/external/rsh_env.c diff --git a/src/pm/hydra/tools/bootstrap/external/rsh_init.c b/src/pm/hydra/lib/tools/bootstrap/external/rsh_init.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/rsh_init.c rename to src/pm/hydra/lib/tools/bootstrap/external/rsh_init.c diff --git a/src/pm/hydra/tools/bootstrap/external/sge.h b/src/pm/hydra/lib/tools/bootstrap/external/sge.h similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/sge.h rename to src/pm/hydra/lib/tools/bootstrap/external/sge.h diff --git a/src/pm/hydra/tools/bootstrap/external/sge_env.c b/src/pm/hydra/lib/tools/bootstrap/external/sge_env.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/sge_env.c rename to src/pm/hydra/lib/tools/bootstrap/external/sge_env.c diff --git a/src/pm/hydra/tools/bootstrap/external/sge_init.c b/src/pm/hydra/lib/tools/bootstrap/external/sge_init.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/sge_init.c rename to src/pm/hydra/lib/tools/bootstrap/external/sge_init.c diff --git a/src/pm/hydra/tools/bootstrap/external/sge_query_native_int.c b/src/pm/hydra/lib/tools/bootstrap/external/sge_query_native_int.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/sge_query_native_int.c rename to src/pm/hydra/lib/tools/bootstrap/external/sge_query_native_int.c diff --git a/src/pm/hydra/tools/bootstrap/external/sge_query_node_list.c b/src/pm/hydra/lib/tools/bootstrap/external/sge_query_node_list.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/sge_query_node_list.c rename to src/pm/hydra/lib/tools/bootstrap/external/sge_query_node_list.c diff --git a/src/pm/hydra/tools/bootstrap/external/slurm.h b/src/pm/hydra/lib/tools/bootstrap/external/slurm.h similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/slurm.h rename to src/pm/hydra/lib/tools/bootstrap/external/slurm.h diff --git a/src/pm/hydra/tools/bootstrap/external/slurm_env.c b/src/pm/hydra/lib/tools/bootstrap/external/slurm_env.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/slurm_env.c rename to src/pm/hydra/lib/tools/bootstrap/external/slurm_env.c diff --git a/src/pm/hydra/tools/bootstrap/external/slurm_init.c b/src/pm/hydra/lib/tools/bootstrap/external/slurm_init.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/slurm_init.c rename to src/pm/hydra/lib/tools/bootstrap/external/slurm_init.c diff --git a/src/pm/hydra/tools/bootstrap/external/slurm_launch.c b/src/pm/hydra/lib/tools/bootstrap/external/slurm_launch.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/slurm_launch.c rename to src/pm/hydra/lib/tools/bootstrap/external/slurm_launch.c diff --git a/src/pm/hydra/tools/bootstrap/external/slurm_query_native_int.c b/src/pm/hydra/lib/tools/bootstrap/external/slurm_query_native_int.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/slurm_query_native_int.c rename to src/pm/hydra/lib/tools/bootstrap/external/slurm_query_native_int.c diff --git a/src/pm/hydra/tools/bootstrap/external/slurm_query_node_list.c b/src/pm/hydra/lib/tools/bootstrap/external/slurm_query_node_list.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/slurm_query_node_list.c rename to src/pm/hydra/lib/tools/bootstrap/external/slurm_query_node_list.c diff --git a/src/pm/hydra/tools/bootstrap/external/slurm_query_proxy_id.c b/src/pm/hydra/lib/tools/bootstrap/external/slurm_query_proxy_id.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/slurm_query_proxy_id.c rename to src/pm/hydra/lib/tools/bootstrap/external/slurm_query_proxy_id.c diff --git a/src/pm/hydra/tools/bootstrap/external/ssh.c b/src/pm/hydra/lib/tools/bootstrap/external/ssh.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/ssh.c rename to src/pm/hydra/lib/tools/bootstrap/external/ssh.c diff --git a/src/pm/hydra/tools/bootstrap/external/ssh.h b/src/pm/hydra/lib/tools/bootstrap/external/ssh.h similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/ssh.h rename to src/pm/hydra/lib/tools/bootstrap/external/ssh.h diff --git a/src/pm/hydra/tools/bootstrap/external/ssh_env.c b/src/pm/hydra/lib/tools/bootstrap/external/ssh_env.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/ssh_env.c rename to src/pm/hydra/lib/tools/bootstrap/external/ssh_env.c diff --git a/src/pm/hydra/tools/bootstrap/external/ssh_finalize.c b/src/pm/hydra/lib/tools/bootstrap/external/ssh_finalize.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/ssh_finalize.c rename to src/pm/hydra/lib/tools/bootstrap/external/ssh_finalize.c diff --git a/src/pm/hydra/tools/bootstrap/external/ssh_init.c b/src/pm/hydra/lib/tools/bootstrap/external/ssh_init.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/ssh_init.c rename to src/pm/hydra/lib/tools/bootstrap/external/ssh_init.c diff --git a/src/pm/hydra/tools/bootstrap/external/user_init.c b/src/pm/hydra/lib/tools/bootstrap/external/user_init.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/external/user_init.c rename to src/pm/hydra/lib/tools/bootstrap/external/user_init.c diff --git a/src/pm/hydra/tools/bootstrap/include/bsci.h b/src/pm/hydra/lib/tools/bootstrap/include/bsci.h similarity index 100% rename from src/pm/hydra/tools/bootstrap/include/bsci.h rename to src/pm/hydra/lib/tools/bootstrap/include/bsci.h diff --git a/src/pm/hydra/lib/tools/bootstrap/persist/Makefile.mk b/src/pm/hydra/lib/tools/bootstrap/persist/Makefile.mk new file mode 100644 index 00000000000..d59a0e98bc4 --- /dev/null +++ b/src/pm/hydra/lib/tools/bootstrap/persist/Makefile.mk @@ -0,0 +1,10 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +AM_CPPFLAGS += -I$(top_srcdir)/lib/tools/bootstrap/persist + +libhydra_la_SOURCES += lib/tools/bootstrap/persist/persist_init.c \ + lib/tools/bootstrap/persist/persist_launch.c \ + lib/tools/bootstrap/persist/persist_wait.c diff --git a/src/pm/hydra/tools/bootstrap/persist/persist.h b/src/pm/hydra/lib/tools/bootstrap/persist/persist.h similarity index 100% rename from src/pm/hydra/tools/bootstrap/persist/persist.h rename to src/pm/hydra/lib/tools/bootstrap/persist/persist.h diff --git a/src/pm/hydra/tools/bootstrap/persist/persist_client.h b/src/pm/hydra/lib/tools/bootstrap/persist/persist_client.h similarity index 100% rename from src/pm/hydra/tools/bootstrap/persist/persist_client.h rename to src/pm/hydra/lib/tools/bootstrap/persist/persist_client.h diff --git a/src/pm/hydra/tools/bootstrap/persist/persist_init.c b/src/pm/hydra/lib/tools/bootstrap/persist/persist_init.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/persist/persist_init.c rename to src/pm/hydra/lib/tools/bootstrap/persist/persist_init.c diff --git a/src/pm/hydra/tools/bootstrap/persist/persist_launch.c b/src/pm/hydra/lib/tools/bootstrap/persist/persist_launch.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/persist/persist_launch.c rename to src/pm/hydra/lib/tools/bootstrap/persist/persist_launch.c diff --git a/src/pm/hydra/tools/bootstrap/persist/persist_server.h b/src/pm/hydra/lib/tools/bootstrap/persist/persist_server.h similarity index 100% rename from src/pm/hydra/tools/bootstrap/persist/persist_server.h rename to src/pm/hydra/lib/tools/bootstrap/persist/persist_server.h diff --git a/src/pm/hydra/tools/bootstrap/persist/persist_wait.c b/src/pm/hydra/lib/tools/bootstrap/persist/persist_wait.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/persist/persist_wait.c rename to src/pm/hydra/lib/tools/bootstrap/persist/persist_wait.c diff --git a/src/pm/hydra/lib/tools/bootstrap/src/Makefile.mk b/src/pm/hydra/lib/tools/bootstrap/src/Makefile.mk new file mode 100644 index 00000000000..0bc36591cfd --- /dev/null +++ b/src/pm/hydra/lib/tools/bootstrap/src/Makefile.mk @@ -0,0 +1,13 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +libhydra_la_SOURCES += lib/tools/bootstrap/src/bsci_init.c \ + lib/tools/bootstrap/src/bsci_finalize.c \ + lib/tools/bootstrap/src/bsci_launch.c \ + lib/tools/bootstrap/src/bsci_query_node_list.c \ + lib/tools/bootstrap/src/bsci_query_proxy_id.c \ + lib/tools/bootstrap/src/bsci_query_native_int.c \ + lib/tools/bootstrap/src/bsci_wait.c \ + lib/tools/bootstrap/src/bsci_env.c diff --git a/src/pm/hydra/tools/bootstrap/src/bsci_env.c b/src/pm/hydra/lib/tools/bootstrap/src/bsci_env.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/src/bsci_env.c rename to src/pm/hydra/lib/tools/bootstrap/src/bsci_env.c diff --git a/src/pm/hydra/tools/bootstrap/src/bsci_finalize.c b/src/pm/hydra/lib/tools/bootstrap/src/bsci_finalize.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/src/bsci_finalize.c rename to src/pm/hydra/lib/tools/bootstrap/src/bsci_finalize.c diff --git a/src/pm/hydra/tools/bootstrap/src/bsci_init.c.in b/src/pm/hydra/lib/tools/bootstrap/src/bsci_init.c.in similarity index 100% rename from src/pm/hydra/tools/bootstrap/src/bsci_init.c.in rename to src/pm/hydra/lib/tools/bootstrap/src/bsci_init.c.in diff --git a/src/pm/hydra/tools/bootstrap/src/bsci_launch.c b/src/pm/hydra/lib/tools/bootstrap/src/bsci_launch.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/src/bsci_launch.c rename to src/pm/hydra/lib/tools/bootstrap/src/bsci_launch.c diff --git a/src/pm/hydra/tools/bootstrap/src/bsci_query_native_int.c b/src/pm/hydra/lib/tools/bootstrap/src/bsci_query_native_int.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/src/bsci_query_native_int.c rename to src/pm/hydra/lib/tools/bootstrap/src/bsci_query_native_int.c diff --git a/src/pm/hydra/tools/bootstrap/src/bsci_query_node_list.c b/src/pm/hydra/lib/tools/bootstrap/src/bsci_query_node_list.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/src/bsci_query_node_list.c rename to src/pm/hydra/lib/tools/bootstrap/src/bsci_query_node_list.c diff --git a/src/pm/hydra/tools/bootstrap/src/bsci_query_proxy_id.c b/src/pm/hydra/lib/tools/bootstrap/src/bsci_query_proxy_id.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/src/bsci_query_proxy_id.c rename to src/pm/hydra/lib/tools/bootstrap/src/bsci_query_proxy_id.c diff --git a/src/pm/hydra/tools/bootstrap/src/bsci_wait.c b/src/pm/hydra/lib/tools/bootstrap/src/bsci_wait.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/src/bsci_wait.c rename to src/pm/hydra/lib/tools/bootstrap/src/bsci_wait.c diff --git a/src/pm/hydra/lib/tools/bootstrap/utils/Makefile.mk b/src/pm/hydra/lib/tools/bootstrap/utils/Makefile.mk new file mode 100644 index 00000000000..a2914c46f99 --- /dev/null +++ b/src/pm/hydra/lib/tools/bootstrap/utils/Makefile.mk @@ -0,0 +1,12 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +AM_CPPFLAGS += -I$(top_srcdir)/lib/tools/bootstrap/utils + +noinst_HEADERS += lib/tools/bootstrap/utils/bscu.h + +libhydra_la_SOURCES += \ + lib/tools/bootstrap/utils/bscu_wait.c \ + lib/tools/bootstrap/utils/bscu_cb.c diff --git a/src/pm/hydra/tools/bootstrap/utils/bscu.h b/src/pm/hydra/lib/tools/bootstrap/utils/bscu.h similarity index 100% rename from src/pm/hydra/tools/bootstrap/utils/bscu.h rename to src/pm/hydra/lib/tools/bootstrap/utils/bscu.h diff --git a/src/pm/hydra/tools/bootstrap/utils/bscu_cb.c b/src/pm/hydra/lib/tools/bootstrap/utils/bscu_cb.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/utils/bscu_cb.c rename to src/pm/hydra/lib/tools/bootstrap/utils/bscu_cb.c diff --git a/src/pm/hydra/tools/bootstrap/utils/bscu_wait.c b/src/pm/hydra/lib/tools/bootstrap/utils/bscu_wait.c similarity index 100% rename from src/pm/hydra/tools/bootstrap/utils/bscu_wait.c rename to src/pm/hydra/lib/tools/bootstrap/utils/bscu_wait.c diff --git a/src/pm/hydra/lib/tools/debugger/Makefile.mk b/src/pm/hydra/lib/tools/debugger/Makefile.mk new file mode 100644 index 00000000000..2077d3608d7 --- /dev/null +++ b/src/pm/hydra/lib/tools/debugger/Makefile.mk @@ -0,0 +1,8 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +AM_CPPFLAGS += -I$(top_srcdir)/lib/tools/debugger + +libhydra_la_SOURCES += lib/tools/debugger/debugger.c diff --git a/src/pm/hydra/tools/debugger/debugger.c b/src/pm/hydra/lib/tools/debugger/debugger.c similarity index 100% rename from src/pm/hydra/tools/debugger/debugger.c rename to src/pm/hydra/lib/tools/debugger/debugger.c diff --git a/src/pm/hydra/tools/debugger/debugger.h b/src/pm/hydra/lib/tools/debugger/debugger.h similarity index 100% rename from src/pm/hydra/tools/debugger/debugger.h rename to src/pm/hydra/lib/tools/debugger/debugger.h diff --git a/src/pm/hydra/lib/tools/demux/Makefile.mk b/src/pm/hydra/lib/tools/demux/Makefile.mk new file mode 100644 index 00000000000..623dffb0a67 --- /dev/null +++ b/src/pm/hydra/lib/tools/demux/Makefile.mk @@ -0,0 +1,18 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +AM_CPPFLAGS += -I$(top_srcdir)/lib/tools/demux + +noinst_HEADERS += lib/tools/demux/demux.h lib/tools/demux/demux_internal.h + +libhydra_la_SOURCES += lib/tools/demux/demux.c + +if hydra_have_poll +libhydra_la_SOURCES += lib/tools/demux/demux_poll.c +endif + +if hydra_have_select +libhydra_la_SOURCES += lib/tools/demux/demux_select.c +endif diff --git a/src/pm/hydra/tools/demux/demux.c b/src/pm/hydra/lib/tools/demux/demux.c similarity index 100% rename from src/pm/hydra/tools/demux/demux.c rename to src/pm/hydra/lib/tools/demux/demux.c diff --git a/src/pm/hydra/tools/demux/demux.h b/src/pm/hydra/lib/tools/demux/demux.h similarity index 100% rename from src/pm/hydra/tools/demux/demux.h rename to src/pm/hydra/lib/tools/demux/demux.h diff --git a/src/pm/hydra/tools/demux/demux_internal.h b/src/pm/hydra/lib/tools/demux/demux_internal.h similarity index 100% rename from src/pm/hydra/tools/demux/demux_internal.h rename to src/pm/hydra/lib/tools/demux/demux_internal.h diff --git a/src/pm/hydra/tools/demux/demux_poll.c b/src/pm/hydra/lib/tools/demux/demux_poll.c similarity index 100% rename from src/pm/hydra/tools/demux/demux_poll.c rename to src/pm/hydra/lib/tools/demux/demux_poll.c diff --git a/src/pm/hydra/tools/demux/demux_select.c b/src/pm/hydra/lib/tools/demux/demux_select.c similarity index 100% rename from src/pm/hydra/tools/demux/demux_select.c rename to src/pm/hydra/lib/tools/demux/demux_select.c diff --git a/src/pm/hydra/lib/tools/topo/Makefile.mk b/src/pm/hydra/lib/tools/topo/Makefile.mk new file mode 100644 index 00000000000..f652b247d2f --- /dev/null +++ b/src/pm/hydra/lib/tools/topo/Makefile.mk @@ -0,0 +1,14 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +AM_CPPFLAGS += -I$(top_srcdir)/lib/tools/topo + +noinst_HEADERS += lib/tools/topo/topo.h + +libhydra_la_SOURCES += lib/tools/topo/topo.c + +if HYDRA_HAVE_HWLOC +include lib/tools/topo/hwloc/Makefile.mk +endif diff --git a/src/pm/hydra/lib/tools/topo/hwloc/Makefile.mk b/src/pm/hydra/lib/tools/topo/hwloc/Makefile.mk new file mode 100644 index 00000000000..9b865f90ed0 --- /dev/null +++ b/src/pm/hydra/lib/tools/topo/hwloc/Makefile.mk @@ -0,0 +1,8 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +libhydra_la_SOURCES += lib/tools/topo/hwloc/topo_hwloc.c + +noinst_HEADERS += lib/tools/topo/hwloc/topo_hwloc.h diff --git a/src/pm/hydra/tools/topo/hwloc/topo_hwloc.c b/src/pm/hydra/lib/tools/topo/hwloc/topo_hwloc.c similarity index 100% rename from src/pm/hydra/tools/topo/hwloc/topo_hwloc.c rename to src/pm/hydra/lib/tools/topo/hwloc/topo_hwloc.c diff --git a/src/pm/hydra/tools/topo/hwloc/topo_hwloc.h b/src/pm/hydra/lib/tools/topo/hwloc/topo_hwloc.h similarity index 100% rename from src/pm/hydra/tools/topo/hwloc/topo_hwloc.h rename to src/pm/hydra/lib/tools/topo/hwloc/topo_hwloc.h diff --git a/src/pm/hydra/tools/topo/topo.c b/src/pm/hydra/lib/tools/topo/topo.c similarity index 100% rename from src/pm/hydra/tools/topo/topo.c rename to src/pm/hydra/lib/tools/topo/topo.c diff --git a/src/pm/hydra/tools/topo/topo.h b/src/pm/hydra/lib/tools/topo/topo.h similarity index 100% rename from src/pm/hydra/tools/topo/topo.h rename to src/pm/hydra/lib/tools/topo/topo.h diff --git a/src/pm/hydra/lib/utils/Makefile.mk b/src/pm/hydra/lib/utils/Makefile.mk new file mode 100644 index 00000000000..88da3ee8f0a --- /dev/null +++ b/src/pm/hydra/lib/utils/Makefile.mk @@ -0,0 +1,14 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +include lib/utils/alloc/Makefile.mk +include lib/utils/args/Makefile.mk +include lib/utils/dbg/Makefile.mk +include lib/utils/env/Makefile.mk +include lib/utils/launch/Makefile.mk +include lib/utils/others/Makefile.mk +include lib/utils/signals/Makefile.mk +include lib/utils/sock/Makefile.mk +include lib/utils/string/Makefile.mk diff --git a/src/pm/hydra/lib/utils/alloc/Makefile.mk b/src/pm/hydra/lib/utils/alloc/Makefile.mk new file mode 100644 index 00000000000..939e35eb9e6 --- /dev/null +++ b/src/pm/hydra/lib/utils/alloc/Makefile.mk @@ -0,0 +1,6 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +libhydra_la_SOURCES += lib/utils/alloc/alloc.c diff --git a/src/pm/hydra/utils/alloc/alloc.c b/src/pm/hydra/lib/utils/alloc/alloc.c similarity index 100% rename from src/pm/hydra/utils/alloc/alloc.c rename to src/pm/hydra/lib/utils/alloc/alloc.c diff --git a/src/pm/hydra/utils/alloc/Makefile.mk b/src/pm/hydra/lib/utils/args/Makefile.mk similarity index 68% rename from src/pm/hydra/utils/alloc/Makefile.mk rename to src/pm/hydra/lib/utils/args/Makefile.mk index dc95ea0c946..351e59ab4a9 100644 --- a/src/pm/hydra/utils/alloc/Makefile.mk +++ b/src/pm/hydra/lib/utils/args/Makefile.mk @@ -3,4 +3,4 @@ ## See COPYRIGHT in top-level directory ## -libhydra_la_SOURCES += utils/alloc/alloc.c +libhydra_la_SOURCES += lib/utils/args/args.c diff --git a/src/pm/hydra/utils/args/args.c b/src/pm/hydra/lib/utils/args/args.c similarity index 100% rename from src/pm/hydra/utils/args/args.c rename to src/pm/hydra/lib/utils/args/args.c diff --git a/src/pm/hydra/utils/args/Makefile.mk b/src/pm/hydra/lib/utils/dbg/Makefile.mk similarity index 69% rename from src/pm/hydra/utils/args/Makefile.mk rename to src/pm/hydra/lib/utils/dbg/Makefile.mk index 32c160d260b..9e57b7a5d61 100644 --- a/src/pm/hydra/utils/args/Makefile.mk +++ b/src/pm/hydra/lib/utils/dbg/Makefile.mk @@ -3,4 +3,4 @@ ## See COPYRIGHT in top-level directory ## -libhydra_la_SOURCES += utils/args/args.c +libhydra_la_SOURCES += lib/utils/dbg/dbg.c diff --git a/src/pm/hydra/utils/dbg/dbg.c b/src/pm/hydra/lib/utils/dbg/dbg.c similarity index 100% rename from src/pm/hydra/utils/dbg/dbg.c rename to src/pm/hydra/lib/utils/dbg/dbg.c diff --git a/src/pm/hydra/utils/dbg/Makefile.mk b/src/pm/hydra/lib/utils/env/Makefile.mk similarity index 69% rename from src/pm/hydra/utils/dbg/Makefile.mk rename to src/pm/hydra/lib/utils/env/Makefile.mk index 13f9e931f07..38e76b00178 100644 --- a/src/pm/hydra/utils/dbg/Makefile.mk +++ b/src/pm/hydra/lib/utils/env/Makefile.mk @@ -3,4 +3,4 @@ ## See COPYRIGHT in top-level directory ## -libhydra_la_SOURCES += utils/dbg/dbg.c +libhydra_la_SOURCES += lib/utils/env/env.c diff --git a/src/pm/hydra/utils/env/env.c b/src/pm/hydra/lib/utils/env/env.c similarity index 100% rename from src/pm/hydra/utils/env/env.c rename to src/pm/hydra/lib/utils/env/env.c diff --git a/src/pm/hydra/lib/utils/launch/Makefile.mk b/src/pm/hydra/lib/utils/launch/Makefile.mk new file mode 100644 index 00000000000..8334b788cfc --- /dev/null +++ b/src/pm/hydra/lib/utils/launch/Makefile.mk @@ -0,0 +1,6 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +libhydra_la_SOURCES += lib/utils/launch/launch.c diff --git a/src/pm/hydra/utils/launch/launch.c b/src/pm/hydra/lib/utils/launch/launch.c similarity index 100% rename from src/pm/hydra/utils/launch/launch.c rename to src/pm/hydra/lib/utils/launch/launch.c diff --git a/src/pm/hydra/lib/utils/others/Makefile.mk b/src/pm/hydra/lib/utils/others/Makefile.mk new file mode 100644 index 00000000000..52e0c320e6b --- /dev/null +++ b/src/pm/hydra/lib/utils/others/Makefile.mk @@ -0,0 +1,6 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +libhydra_la_SOURCES += lib/utils/others/others.c diff --git a/src/pm/hydra/utils/others/others.c b/src/pm/hydra/lib/utils/others/others.c similarity index 100% rename from src/pm/hydra/utils/others/others.c rename to src/pm/hydra/lib/utils/others/others.c diff --git a/src/pm/hydra/lib/utils/signals/Makefile.mk b/src/pm/hydra/lib/utils/signals/Makefile.mk new file mode 100644 index 00000000000..b9fd3d3bc7d --- /dev/null +++ b/src/pm/hydra/lib/utils/signals/Makefile.mk @@ -0,0 +1,6 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +libhydra_la_SOURCES += lib/utils/signals/signals.c diff --git a/src/pm/hydra/utils/signals/signals.c b/src/pm/hydra/lib/utils/signals/signals.c similarity index 100% rename from src/pm/hydra/utils/signals/signals.c rename to src/pm/hydra/lib/utils/signals/signals.c diff --git a/src/pm/hydra/utils/env/Makefile.mk b/src/pm/hydra/lib/utils/sock/Makefile.mk similarity index 68% rename from src/pm/hydra/utils/env/Makefile.mk rename to src/pm/hydra/lib/utils/sock/Makefile.mk index 43577f63e7d..37ec5cb005b 100644 --- a/src/pm/hydra/utils/env/Makefile.mk +++ b/src/pm/hydra/lib/utils/sock/Makefile.mk @@ -3,4 +3,4 @@ ## See COPYRIGHT in top-level directory ## -libhydra_la_SOURCES += utils/env/env.c +libhydra_la_SOURCES += lib/utils/sock/sock.c diff --git a/src/pm/hydra/utils/sock/sock.c b/src/pm/hydra/lib/utils/sock/sock.c similarity index 100% rename from src/pm/hydra/utils/sock/sock.c rename to src/pm/hydra/lib/utils/sock/sock.c diff --git a/src/pm/hydra/lib/utils/string/Makefile.mk b/src/pm/hydra/lib/utils/string/Makefile.mk new file mode 100644 index 00000000000..78500445f9d --- /dev/null +++ b/src/pm/hydra/lib/utils/string/Makefile.mk @@ -0,0 +1,6 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +libhydra_la_SOURCES += lib/utils/string/string.c diff --git a/src/pm/hydra/utils/string/string.c b/src/pm/hydra/lib/utils/string/string.c similarity index 100% rename from src/pm/hydra/utils/string/string.c rename to src/pm/hydra/lib/utils/string/string.c diff --git a/src/pm/hydra/tools/Makefile.mk b/src/pm/hydra/tools/Makefile.mk deleted file mode 100644 index b22e89d0fb3..00000000000 --- a/src/pm/hydra/tools/Makefile.mk +++ /dev/null @@ -1,11 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -tools_libs = - -include tools/topo/Makefile.mk -include tools/bootstrap/Makefile.mk -include tools/demux/Makefile.mk -include tools/debugger/Makefile.mk diff --git a/src/pm/hydra/tools/bootstrap/Makefile.mk b/src/pm/hydra/tools/bootstrap/Makefile.mk deleted file mode 100644 index cc0dd5faee8..00000000000 --- a/src/pm/hydra/tools/bootstrap/Makefile.mk +++ /dev/null @@ -1,19 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -AM_CPPFLAGS += -I$(top_srcdir)/tools/bootstrap/include - -noinst_HEADERS += tools/bootstrap/include/bsci.h - -include tools/bootstrap/src/Makefile.mk -include tools/bootstrap/utils/Makefile.mk - -if hydra_bss_external -include tools/bootstrap/external/Makefile.mk -endif - -if hydra_bss_persist -include tools/bootstrap/persist/Makefile.mk -endif diff --git a/src/pm/hydra/tools/bootstrap/external/Makefile.mk b/src/pm/hydra/tools/bootstrap/external/Makefile.mk deleted file mode 100644 index 35a5ecbcfb3..00000000000 --- a/src/pm/hydra/tools/bootstrap/external/Makefile.mk +++ /dev/null @@ -1,61 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -noinst_HEADERS += \ - tools/bootstrap/external/common.h \ - tools/bootstrap/external/ll.h \ - tools/bootstrap/external/lsf.h \ - tools/bootstrap/external/pbs.h \ - tools/bootstrap/external/rsh.h \ - tools/bootstrap/external/sge.h \ - tools/bootstrap/external/slurm.h \ - tools/bootstrap/external/cobalt.h \ - tools/bootstrap/external/ssh.h - -libhydra_la_SOURCES += tools/bootstrap/external/external_common.c \ - tools/bootstrap/external/external_common_launch.c \ - tools/bootstrap/external/fork_init.c \ - tools/bootstrap/external/user_init.c \ - tools/bootstrap/external/manual_init.c \ - tools/bootstrap/external/rsh_init.c \ - tools/bootstrap/external/rsh_env.c \ - tools/bootstrap/external/ssh_init.c \ - tools/bootstrap/external/ssh.c \ - tools/bootstrap/external/ssh_env.c \ - tools/bootstrap/external/ssh_finalize.c \ - tools/bootstrap/external/slurm_init.c \ - tools/bootstrap/external/slurm_launch.c \ - tools/bootstrap/external/slurm_env.c \ - tools/bootstrap/external/slurm_query_native_int.c \ - tools/bootstrap/external/slurm_query_node_list.c \ - tools/bootstrap/external/slurm_query_proxy_id.c \ - tools/bootstrap/external/ll_init.c \ - tools/bootstrap/external/ll_launch.c \ - tools/bootstrap/external/ll_query_native_int.c \ - tools/bootstrap/external/ll_query_node_list.c \ - tools/bootstrap/external/ll_query_proxy_id.c \ - tools/bootstrap/external/ll_env.c \ - tools/bootstrap/external/lsf_init.c \ - tools/bootstrap/external/lsf_query_native_int.c \ - tools/bootstrap/external/lsf_query_node_list.c \ - tools/bootstrap/external/lsf_env.c \ - tools/bootstrap/external/sge_init.c \ - tools/bootstrap/external/sge_query_native_int.c \ - tools/bootstrap/external/sge_query_node_list.c \ - tools/bootstrap/external/sge_env.c \ - tools/bootstrap/external/pbs_init.c \ - tools/bootstrap/external/pbs_query_native_int.c \ - tools/bootstrap/external/pbs_query_node_list.c \ - tools/bootstrap/external/cobalt_init.c \ - tools/bootstrap/external/cobalt_query_native_int.c \ - tools/bootstrap/external/cobalt_query_node_list.c - -if hydra_pbs_launcher -libhydra_la_SOURCES += \ - tools/bootstrap/external/pbs_finalize.c \ - tools/bootstrap/external/pbs_launch.c \ - tools/bootstrap/external/pbs_wait.c \ - tools/bootstrap/external/pbs_env.c -endif diff --git a/src/pm/hydra/tools/bootstrap/persist/Makefile.mk b/src/pm/hydra/tools/bootstrap/persist/Makefile.mk deleted file mode 100644 index e16bfb0a659..00000000000 --- a/src/pm/hydra/tools/bootstrap/persist/Makefile.mk +++ /dev/null @@ -1,10 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -AM_CPPFLAGS += -I$(top_srcdir)/tools/bootstrap/persist - -libhydra_la_SOURCES += tools/bootstrap/persist/persist_init.c \ - tools/bootstrap/persist/persist_launch.c \ - tools/bootstrap/persist/persist_wait.c diff --git a/src/pm/hydra/tools/bootstrap/src/Makefile.mk b/src/pm/hydra/tools/bootstrap/src/Makefile.mk deleted file mode 100644 index 003569e3cdb..00000000000 --- a/src/pm/hydra/tools/bootstrap/src/Makefile.mk +++ /dev/null @@ -1,13 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -libhydra_la_SOURCES += tools/bootstrap/src/bsci_init.c \ - tools/bootstrap/src/bsci_finalize.c \ - tools/bootstrap/src/bsci_launch.c \ - tools/bootstrap/src/bsci_query_node_list.c \ - tools/bootstrap/src/bsci_query_proxy_id.c \ - tools/bootstrap/src/bsci_query_native_int.c \ - tools/bootstrap/src/bsci_wait.c \ - tools/bootstrap/src/bsci_env.c diff --git a/src/pm/hydra/tools/bootstrap/utils/Makefile.mk b/src/pm/hydra/tools/bootstrap/utils/Makefile.mk deleted file mode 100644 index 40678b1afd6..00000000000 --- a/src/pm/hydra/tools/bootstrap/utils/Makefile.mk +++ /dev/null @@ -1,12 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -AM_CPPFLAGS += -I$(top_srcdir)/tools/bootstrap/utils - -noinst_HEADERS += tools/bootstrap/utils/bscu.h - -libhydra_la_SOURCES += \ - tools/bootstrap/utils/bscu_wait.c \ - tools/bootstrap/utils/bscu_cb.c diff --git a/src/pm/hydra/tools/debugger/Makefile.mk b/src/pm/hydra/tools/debugger/Makefile.mk deleted file mode 100644 index 2b0cd429e9c..00000000000 --- a/src/pm/hydra/tools/debugger/Makefile.mk +++ /dev/null @@ -1,10 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -AM_CPPFLAGS += -I$(top_srcdir)/tools/debugger - -noinst_HEADERS += tools/debugger/debugger.h - -libhydra_la_SOURCES += tools/debugger/debugger.c diff --git a/src/pm/hydra/tools/demux/Makefile.mk b/src/pm/hydra/tools/demux/Makefile.mk deleted file mode 100644 index da9c256f652..00000000000 --- a/src/pm/hydra/tools/demux/Makefile.mk +++ /dev/null @@ -1,18 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -AM_CPPFLAGS += -I$(top_srcdir)/tools/demux - -noinst_HEADERS += tools/demux/demux.h tools/demux/demux_internal.h - -libhydra_la_SOURCES += tools/demux/demux.c - -if hydra_have_poll -libhydra_la_SOURCES += tools/demux/demux_poll.c -endif - -if hydra_have_select -libhydra_la_SOURCES += tools/demux/demux_select.c -endif diff --git a/src/pm/hydra/tools/topo/Makefile.mk b/src/pm/hydra/tools/topo/Makefile.mk deleted file mode 100644 index 49348010406..00000000000 --- a/src/pm/hydra/tools/topo/Makefile.mk +++ /dev/null @@ -1,14 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -AM_CPPFLAGS += -I$(top_srcdir)/tools/topo - -noinst_HEADERS += tools/topo/topo.h - -libhydra_la_SOURCES += tools/topo/topo.c - -if HYDRA_HAVE_HWLOC -include tools/topo/hwloc/Makefile.mk -endif diff --git a/src/pm/hydra/tools/topo/hwloc/Makefile.mk b/src/pm/hydra/tools/topo/hwloc/Makefile.mk deleted file mode 100644 index 1325d414946..00000000000 --- a/src/pm/hydra/tools/topo/hwloc/Makefile.mk +++ /dev/null @@ -1,8 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -libhydra_la_SOURCES += tools/topo/hwloc/topo_hwloc.c - -noinst_HEADERS += tools/topo/hwloc/topo_hwloc.h diff --git a/src/pm/hydra/utils/Makefile.mk b/src/pm/hydra/utils/Makefile.mk deleted file mode 100644 index 08dbd3d0b32..00000000000 --- a/src/pm/hydra/utils/Makefile.mk +++ /dev/null @@ -1,14 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -include utils/alloc/Makefile.mk -include utils/args/Makefile.mk -include utils/dbg/Makefile.mk -include utils/env/Makefile.mk -include utils/launch/Makefile.mk -include utils/others/Makefile.mk -include utils/signals/Makefile.mk -include utils/sock/Makefile.mk -include utils/string/Makefile.mk diff --git a/src/pm/hydra/utils/launch/Makefile.mk b/src/pm/hydra/utils/launch/Makefile.mk deleted file mode 100644 index e8187b451c4..00000000000 --- a/src/pm/hydra/utils/launch/Makefile.mk +++ /dev/null @@ -1,6 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -libhydra_la_SOURCES += utils/launch/launch.c diff --git a/src/pm/hydra/utils/others/Makefile.mk b/src/pm/hydra/utils/others/Makefile.mk deleted file mode 100644 index 632b7a0358b..00000000000 --- a/src/pm/hydra/utils/others/Makefile.mk +++ /dev/null @@ -1,6 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -libhydra_la_SOURCES += utils/others/others.c diff --git a/src/pm/hydra/utils/signals/Makefile.mk b/src/pm/hydra/utils/signals/Makefile.mk deleted file mode 100644 index 26971ba56ac..00000000000 --- a/src/pm/hydra/utils/signals/Makefile.mk +++ /dev/null @@ -1,6 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -libhydra_la_SOURCES += utils/signals/signals.c diff --git a/src/pm/hydra/utils/sock/Makefile.mk b/src/pm/hydra/utils/sock/Makefile.mk deleted file mode 100644 index c1882dbf9f7..00000000000 --- a/src/pm/hydra/utils/sock/Makefile.mk +++ /dev/null @@ -1,6 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -libhydra_la_SOURCES += utils/sock/sock.c diff --git a/src/pm/hydra/utils/string/Makefile.mk b/src/pm/hydra/utils/string/Makefile.mk deleted file mode 100644 index d2331aa5367..00000000000 --- a/src/pm/hydra/utils/string/Makefile.mk +++ /dev/null @@ -1,6 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -libhydra_la_SOURCES += utils/string/string.c From 7f8328a03c24d3f22125490d3c954b3b2a8cf279 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 6 Feb 2022 18:36:26 -0600 Subject: [PATCH 503/607] hydra: move pm files into mpiexec and lib Most code in libpm.la are specific for mpiexec, and two common files are shared by mpiexec and hydra_pmi_proxy. Move the mpiexec specific files into mpiexec folder and move the common files into lib folder. --- src/pm/hydra/Makefile.am | 1 - src/pm/hydra/lib/Makefile.mk | 6 ++++++ src/pm/hydra/{pm/pmiserv => lib}/pmi_v2_common.c | 1 - src/pm/hydra/{pm/pmiserv => lib}/pmi_v2_common.h | 0 .../{pm/pmiserv/common.c => lib/pmiserv_common.c} | 0 src/pm/hydra/{pm/pmiserv => lib}/pmiserv_common.h | 0 src/pm/hydra/mpiexec/Makefile.mk | 12 +++++++++--- src/pm/hydra/{pm/include => mpiexec}/pmci.h | 0 src/pm/hydra/{pm/pmiserv => mpiexec}/pmiserv.h | 0 src/pm/hydra/{pm/pmiserv => mpiexec}/pmiserv_cb.c | 0 .../hydra/{pm/pmiserv => mpiexec}/pmiserv_pmci.c | 0 .../hydra/{pm/pmiserv => mpiexec}/pmiserv_pmi.c | 0 .../hydra/{pm/pmiserv => mpiexec}/pmiserv_pmi.h | 0 .../{pm/pmiserv => mpiexec}/pmiserv_pmi_v1.c | 0 .../{pm/pmiserv => mpiexec}/pmiserv_pmi_v2.c | 0 .../hydra/{pm/pmiserv => mpiexec}/pmiserv_utils.c | 0 .../hydra/{pm/pmiserv => mpiexec}/pmiserv_utils.h | 0 src/pm/hydra/pm/Makefile.mk | 15 --------------- src/pm/hydra/pm/pmiserv/Makefile.mk | 15 --------------- src/pm/hydra/proxy/Makefile.mk | 4 +--- 20 files changed, 16 insertions(+), 38 deletions(-) rename src/pm/hydra/{pm/pmiserv => lib}/pmi_v2_common.c (97%) rename src/pm/hydra/{pm/pmiserv => lib}/pmi_v2_common.h (100%) rename src/pm/hydra/{pm/pmiserv/common.c => lib/pmiserv_common.c} (100%) rename src/pm/hydra/{pm/pmiserv => lib}/pmiserv_common.h (100%) rename src/pm/hydra/{pm/include => mpiexec}/pmci.h (100%) rename src/pm/hydra/{pm/pmiserv => mpiexec}/pmiserv.h (100%) rename src/pm/hydra/{pm/pmiserv => mpiexec}/pmiserv_cb.c (100%) rename src/pm/hydra/{pm/pmiserv => mpiexec}/pmiserv_pmci.c (100%) rename src/pm/hydra/{pm/pmiserv => mpiexec}/pmiserv_pmi.c (100%) rename src/pm/hydra/{pm/pmiserv => mpiexec}/pmiserv_pmi.h (100%) rename src/pm/hydra/{pm/pmiserv => mpiexec}/pmiserv_pmi_v1.c (100%) rename src/pm/hydra/{pm/pmiserv => mpiexec}/pmiserv_pmi_v2.c (100%) rename src/pm/hydra/{pm/pmiserv => mpiexec}/pmiserv_utils.c (100%) rename src/pm/hydra/{pm/pmiserv => mpiexec}/pmiserv_utils.h (100%) delete mode 100644 src/pm/hydra/pm/Makefile.mk delete mode 100644 src/pm/hydra/pm/pmiserv/Makefile.mk diff --git a/src/pm/hydra/Makefile.am b/src/pm/hydra/Makefile.am index 0719650ae29..bf79dff2736 100644 --- a/src/pm/hydra/Makefile.am +++ b/src/pm/hydra/Makefile.am @@ -33,7 +33,6 @@ libhydra_la_SOURCES = # The below directories contribute to libhydra include lib/Makefile.mk -include pm/Makefile.mk include mpiexec/Makefile.mk include proxy/Makefile.mk include nameserver/Makefile.mk diff --git a/src/pm/hydra/lib/Makefile.mk b/src/pm/hydra/lib/Makefile.mk index a256b443fc1..c4686ee5e49 100644 --- a/src/pm/hydra/lib/Makefile.mk +++ b/src/pm/hydra/lib/Makefile.mk @@ -3,6 +3,12 @@ ## See COPYRIGHT in top-level directory ## +AM_CPPFLAGS += -I$(top_srcdir)/lib + +libhydra_la_SOURCES += \ + lib/pmiserv_common.c \ + lib/pmi_v2_common.c + include lib/utils/Makefile.mk include lib/tools/Makefile.mk diff --git a/src/pm/hydra/pm/pmiserv/pmi_v2_common.c b/src/pm/hydra/lib/pmi_v2_common.c similarity index 97% rename from src/pm/hydra/pm/pmiserv/pmi_v2_common.c rename to src/pm/hydra/lib/pmi_v2_common.c index c0012f49798..ff2613af8b1 100644 --- a/src/pm/hydra/pm/pmiserv/pmi_v2_common.c +++ b/src/pm/hydra/lib/pmi_v2_common.c @@ -5,7 +5,6 @@ #include "hydra.h" #include "bsci.h" -#include "pmiserv_pmi.h" #include "pmi_v2_common.h" HYD_status HYD_pmcd_pmi_v2_queue_req(int fd, int pid, int pgid, char *args[], char *key, diff --git a/src/pm/hydra/pm/pmiserv/pmi_v2_common.h b/src/pm/hydra/lib/pmi_v2_common.h similarity index 100% rename from src/pm/hydra/pm/pmiserv/pmi_v2_common.h rename to src/pm/hydra/lib/pmi_v2_common.h diff --git a/src/pm/hydra/pm/pmiserv/common.c b/src/pm/hydra/lib/pmiserv_common.c similarity index 100% rename from src/pm/hydra/pm/pmiserv/common.c rename to src/pm/hydra/lib/pmiserv_common.c diff --git a/src/pm/hydra/pm/pmiserv/pmiserv_common.h b/src/pm/hydra/lib/pmiserv_common.h similarity index 100% rename from src/pm/hydra/pm/pmiserv/pmiserv_common.h rename to src/pm/hydra/lib/pmiserv_common.h diff --git a/src/pm/hydra/mpiexec/Makefile.mk b/src/pm/hydra/mpiexec/Makefile.mk index b3ddb3702ad..899b65bd234 100644 --- a/src/pm/hydra/mpiexec/Makefile.mk +++ b/src/pm/hydra/mpiexec/Makefile.mk @@ -8,9 +8,15 @@ bin_PROGRAMS += mpiexec.hydra mpiexec_hydra_SOURCES = \ mpiexec/mpiexec.c \ mpiexec/utils.c \ - mpiexec/uiu.c + mpiexec/uiu.c \ + mpiexec/pmiserv_cb.c \ + mpiexec/pmiserv_pmi.c \ + mpiexec/pmiserv_pmi_v1.c \ + mpiexec/pmiserv_pmi_v2.c \ + mpiexec/pmiserv_pmci.c \ + mpiexec/pmiserv_utils.c mpiexec_hydra_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/mpiexec -DHYDRA_CONF_FILE=\"@sysconfdir@/mpiexec.hydra.conf\" mpiexec_hydra_LDFLAGS = $(external_ldflags) -L$(top_builddir) -mpiexec_hydra_LDADD = -lpm -lhydra $(external_libs) -mpiexec_hydra_DEPENDENCIES = libpm.la libhydra.la +mpiexec_hydra_LDADD = -lhydra $(external_libs) +mpiexec_hydra_DEPENDENCIES = libhydra.la diff --git a/src/pm/hydra/pm/include/pmci.h b/src/pm/hydra/mpiexec/pmci.h similarity index 100% rename from src/pm/hydra/pm/include/pmci.h rename to src/pm/hydra/mpiexec/pmci.h diff --git a/src/pm/hydra/pm/pmiserv/pmiserv.h b/src/pm/hydra/mpiexec/pmiserv.h similarity index 100% rename from src/pm/hydra/pm/pmiserv/pmiserv.h rename to src/pm/hydra/mpiexec/pmiserv.h diff --git a/src/pm/hydra/pm/pmiserv/pmiserv_cb.c b/src/pm/hydra/mpiexec/pmiserv_cb.c similarity index 100% rename from src/pm/hydra/pm/pmiserv/pmiserv_cb.c rename to src/pm/hydra/mpiexec/pmiserv_cb.c diff --git a/src/pm/hydra/pm/pmiserv/pmiserv_pmci.c b/src/pm/hydra/mpiexec/pmiserv_pmci.c similarity index 100% rename from src/pm/hydra/pm/pmiserv/pmiserv_pmci.c rename to src/pm/hydra/mpiexec/pmiserv_pmci.c diff --git a/src/pm/hydra/pm/pmiserv/pmiserv_pmi.c b/src/pm/hydra/mpiexec/pmiserv_pmi.c similarity index 100% rename from src/pm/hydra/pm/pmiserv/pmiserv_pmi.c rename to src/pm/hydra/mpiexec/pmiserv_pmi.c diff --git a/src/pm/hydra/pm/pmiserv/pmiserv_pmi.h b/src/pm/hydra/mpiexec/pmiserv_pmi.h similarity index 100% rename from src/pm/hydra/pm/pmiserv/pmiserv_pmi.h rename to src/pm/hydra/mpiexec/pmiserv_pmi.h diff --git a/src/pm/hydra/pm/pmiserv/pmiserv_pmi_v1.c b/src/pm/hydra/mpiexec/pmiserv_pmi_v1.c similarity index 100% rename from src/pm/hydra/pm/pmiserv/pmiserv_pmi_v1.c rename to src/pm/hydra/mpiexec/pmiserv_pmi_v1.c diff --git a/src/pm/hydra/pm/pmiserv/pmiserv_pmi_v2.c b/src/pm/hydra/mpiexec/pmiserv_pmi_v2.c similarity index 100% rename from src/pm/hydra/pm/pmiserv/pmiserv_pmi_v2.c rename to src/pm/hydra/mpiexec/pmiserv_pmi_v2.c diff --git a/src/pm/hydra/pm/pmiserv/pmiserv_utils.c b/src/pm/hydra/mpiexec/pmiserv_utils.c similarity index 100% rename from src/pm/hydra/pm/pmiserv/pmiserv_utils.c rename to src/pm/hydra/mpiexec/pmiserv_utils.c diff --git a/src/pm/hydra/pm/pmiserv/pmiserv_utils.h b/src/pm/hydra/mpiexec/pmiserv_utils.h similarity index 100% rename from src/pm/hydra/pm/pmiserv/pmiserv_utils.h rename to src/pm/hydra/mpiexec/pmiserv_utils.h diff --git a/src/pm/hydra/pm/Makefile.mk b/src/pm/hydra/pm/Makefile.mk deleted file mode 100644 index 4a9a21665e9..00000000000 --- a/src/pm/hydra/pm/Makefile.mk +++ /dev/null @@ -1,15 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -AM_CPPFLAGS += -I$(top_srcdir)/pm/include - -noinst_HEADERS += pm/include/pmci.h - -noinst_LTLIBRARIES += libpm.la -libpm_la_SOURCES = - -if hydra_pm_pmiserv -include pm/pmiserv/Makefile.mk -endif diff --git a/src/pm/hydra/pm/pmiserv/Makefile.mk b/src/pm/hydra/pm/pmiserv/Makefile.mk deleted file mode 100644 index eac95dbd43a..00000000000 --- a/src/pm/hydra/pm/pmiserv/Makefile.mk +++ /dev/null @@ -1,15 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -AM_CPPFLAGS += -I$(top_srcdir)/pm/utils -I$(top_srcdir)/pm/pmiserv - -libpm_la_SOURCES += pm/pmiserv/pmiserv_pmi.c \ - pm/pmiserv/pmiserv_pmi_v1.c \ - pm/pmiserv/pmiserv_pmi_v2.c \ - pm/pmiserv/pmiserv_pmci.c \ - pm/pmiserv/pmiserv_cb.c \ - pm/pmiserv/pmiserv_utils.c \ - pm/pmiserv/common.c \ - pm/pmiserv/pmi_v2_common.c diff --git a/src/pm/hydra/proxy/Makefile.mk b/src/pm/hydra/proxy/Makefile.mk index d71c224666e..53a154c1bbf 100644 --- a/src/pm/hydra/proxy/Makefile.mk +++ b/src/pm/hydra/proxy/Makefile.mk @@ -10,9 +10,7 @@ hydra_pmi_proxy_SOURCES = \ proxy/pmip_cb.c \ proxy/pmip_utils.c \ proxy/pmip_pmi_v1.c \ - proxy/pmip_pmi_v2.c \ - pm/pmiserv/common.c \ - pm/pmiserv/pmi_v2_common.c + proxy/pmip_pmi_v2.c hydra_pmi_proxy_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/proxy hydra_pmi_proxy_LDFLAGS = $(external_ldflags) -L$(top_builddir) From c82693bcd46918049932e1ccb2ab687403fcc82f Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 6 Feb 2022 18:48:25 -0600 Subject: [PATCH 504/607] hydra: flatten lib/utils It is not necessary to put individual utility source files into separate directories. --- src/pm/hydra/lib/utils/Makefile.mk | 19 ++++++++++--------- src/pm/hydra/lib/utils/{alloc => }/alloc.c | 0 src/pm/hydra/lib/utils/alloc/Makefile.mk | 6 ------ src/pm/hydra/lib/utils/{args => }/args.c | 0 src/pm/hydra/lib/utils/args/Makefile.mk | 6 ------ src/pm/hydra/lib/utils/{dbg => }/dbg.c | 0 src/pm/hydra/lib/utils/dbg/Makefile.mk | 6 ------ src/pm/hydra/lib/utils/{env => }/env.c | 0 src/pm/hydra/lib/utils/env/Makefile.mk | 6 ------ src/pm/hydra/lib/utils/{launch => }/launch.c | 0 src/pm/hydra/lib/utils/launch/Makefile.mk | 6 ------ src/pm/hydra/lib/utils/{others => }/others.c | 0 src/pm/hydra/lib/utils/others/Makefile.mk | 6 ------ .../hydra/lib/utils/{signals => }/signals.c | 0 src/pm/hydra/lib/utils/signals/Makefile.mk | 6 ------ src/pm/hydra/lib/utils/{sock => }/sock.c | 0 src/pm/hydra/lib/utils/sock/Makefile.mk | 6 ------ src/pm/hydra/lib/utils/{string => }/string.c | 0 src/pm/hydra/lib/utils/string/Makefile.mk | 6 ------ 19 files changed, 10 insertions(+), 63 deletions(-) rename src/pm/hydra/lib/utils/{alloc => }/alloc.c (100%) delete mode 100644 src/pm/hydra/lib/utils/alloc/Makefile.mk rename src/pm/hydra/lib/utils/{args => }/args.c (100%) delete mode 100644 src/pm/hydra/lib/utils/args/Makefile.mk rename src/pm/hydra/lib/utils/{dbg => }/dbg.c (100%) delete mode 100644 src/pm/hydra/lib/utils/dbg/Makefile.mk rename src/pm/hydra/lib/utils/{env => }/env.c (100%) delete mode 100644 src/pm/hydra/lib/utils/env/Makefile.mk rename src/pm/hydra/lib/utils/{launch => }/launch.c (100%) delete mode 100644 src/pm/hydra/lib/utils/launch/Makefile.mk rename src/pm/hydra/lib/utils/{others => }/others.c (100%) delete mode 100644 src/pm/hydra/lib/utils/others/Makefile.mk rename src/pm/hydra/lib/utils/{signals => }/signals.c (100%) delete mode 100644 src/pm/hydra/lib/utils/signals/Makefile.mk rename src/pm/hydra/lib/utils/{sock => }/sock.c (100%) delete mode 100644 src/pm/hydra/lib/utils/sock/Makefile.mk rename src/pm/hydra/lib/utils/{string => }/string.c (100%) delete mode 100644 src/pm/hydra/lib/utils/string/Makefile.mk diff --git a/src/pm/hydra/lib/utils/Makefile.mk b/src/pm/hydra/lib/utils/Makefile.mk index 88da3ee8f0a..504b259aade 100644 --- a/src/pm/hydra/lib/utils/Makefile.mk +++ b/src/pm/hydra/lib/utils/Makefile.mk @@ -3,12 +3,13 @@ ## See COPYRIGHT in top-level directory ## -include lib/utils/alloc/Makefile.mk -include lib/utils/args/Makefile.mk -include lib/utils/dbg/Makefile.mk -include lib/utils/env/Makefile.mk -include lib/utils/launch/Makefile.mk -include lib/utils/others/Makefile.mk -include lib/utils/signals/Makefile.mk -include lib/utils/sock/Makefile.mk -include lib/utils/string/Makefile.mk +libhydra_la_SOURCES += \ + lib/utils/alloc.c \ + lib/utils/args.c \ + lib/utils/dbg.c \ + lib/utils/env.c \ + lib/utils/launch.c \ + lib/utils/others.c \ + lib/utils/signals.c \ + lib/utils/sock.c \ + lib/utils/string.c diff --git a/src/pm/hydra/lib/utils/alloc/alloc.c b/src/pm/hydra/lib/utils/alloc.c similarity index 100% rename from src/pm/hydra/lib/utils/alloc/alloc.c rename to src/pm/hydra/lib/utils/alloc.c diff --git a/src/pm/hydra/lib/utils/alloc/Makefile.mk b/src/pm/hydra/lib/utils/alloc/Makefile.mk deleted file mode 100644 index 939e35eb9e6..00000000000 --- a/src/pm/hydra/lib/utils/alloc/Makefile.mk +++ /dev/null @@ -1,6 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -libhydra_la_SOURCES += lib/utils/alloc/alloc.c diff --git a/src/pm/hydra/lib/utils/args/args.c b/src/pm/hydra/lib/utils/args.c similarity index 100% rename from src/pm/hydra/lib/utils/args/args.c rename to src/pm/hydra/lib/utils/args.c diff --git a/src/pm/hydra/lib/utils/args/Makefile.mk b/src/pm/hydra/lib/utils/args/Makefile.mk deleted file mode 100644 index 351e59ab4a9..00000000000 --- a/src/pm/hydra/lib/utils/args/Makefile.mk +++ /dev/null @@ -1,6 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -libhydra_la_SOURCES += lib/utils/args/args.c diff --git a/src/pm/hydra/lib/utils/dbg/dbg.c b/src/pm/hydra/lib/utils/dbg.c similarity index 100% rename from src/pm/hydra/lib/utils/dbg/dbg.c rename to src/pm/hydra/lib/utils/dbg.c diff --git a/src/pm/hydra/lib/utils/dbg/Makefile.mk b/src/pm/hydra/lib/utils/dbg/Makefile.mk deleted file mode 100644 index 9e57b7a5d61..00000000000 --- a/src/pm/hydra/lib/utils/dbg/Makefile.mk +++ /dev/null @@ -1,6 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -libhydra_la_SOURCES += lib/utils/dbg/dbg.c diff --git a/src/pm/hydra/lib/utils/env/env.c b/src/pm/hydra/lib/utils/env.c similarity index 100% rename from src/pm/hydra/lib/utils/env/env.c rename to src/pm/hydra/lib/utils/env.c diff --git a/src/pm/hydra/lib/utils/env/Makefile.mk b/src/pm/hydra/lib/utils/env/Makefile.mk deleted file mode 100644 index 38e76b00178..00000000000 --- a/src/pm/hydra/lib/utils/env/Makefile.mk +++ /dev/null @@ -1,6 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -libhydra_la_SOURCES += lib/utils/env/env.c diff --git a/src/pm/hydra/lib/utils/launch/launch.c b/src/pm/hydra/lib/utils/launch.c similarity index 100% rename from src/pm/hydra/lib/utils/launch/launch.c rename to src/pm/hydra/lib/utils/launch.c diff --git a/src/pm/hydra/lib/utils/launch/Makefile.mk b/src/pm/hydra/lib/utils/launch/Makefile.mk deleted file mode 100644 index 8334b788cfc..00000000000 --- a/src/pm/hydra/lib/utils/launch/Makefile.mk +++ /dev/null @@ -1,6 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -libhydra_la_SOURCES += lib/utils/launch/launch.c diff --git a/src/pm/hydra/lib/utils/others/others.c b/src/pm/hydra/lib/utils/others.c similarity index 100% rename from src/pm/hydra/lib/utils/others/others.c rename to src/pm/hydra/lib/utils/others.c diff --git a/src/pm/hydra/lib/utils/others/Makefile.mk b/src/pm/hydra/lib/utils/others/Makefile.mk deleted file mode 100644 index 52e0c320e6b..00000000000 --- a/src/pm/hydra/lib/utils/others/Makefile.mk +++ /dev/null @@ -1,6 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -libhydra_la_SOURCES += lib/utils/others/others.c diff --git a/src/pm/hydra/lib/utils/signals/signals.c b/src/pm/hydra/lib/utils/signals.c similarity index 100% rename from src/pm/hydra/lib/utils/signals/signals.c rename to src/pm/hydra/lib/utils/signals.c diff --git a/src/pm/hydra/lib/utils/signals/Makefile.mk b/src/pm/hydra/lib/utils/signals/Makefile.mk deleted file mode 100644 index b9fd3d3bc7d..00000000000 --- a/src/pm/hydra/lib/utils/signals/Makefile.mk +++ /dev/null @@ -1,6 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -libhydra_la_SOURCES += lib/utils/signals/signals.c diff --git a/src/pm/hydra/lib/utils/sock/sock.c b/src/pm/hydra/lib/utils/sock.c similarity index 100% rename from src/pm/hydra/lib/utils/sock/sock.c rename to src/pm/hydra/lib/utils/sock.c diff --git a/src/pm/hydra/lib/utils/sock/Makefile.mk b/src/pm/hydra/lib/utils/sock/Makefile.mk deleted file mode 100644 index 37ec5cb005b..00000000000 --- a/src/pm/hydra/lib/utils/sock/Makefile.mk +++ /dev/null @@ -1,6 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -libhydra_la_SOURCES += lib/utils/sock/sock.c diff --git a/src/pm/hydra/lib/utils/string/string.c b/src/pm/hydra/lib/utils/string.c similarity index 100% rename from src/pm/hydra/lib/utils/string/string.c rename to src/pm/hydra/lib/utils/string.c diff --git a/src/pm/hydra/lib/utils/string/Makefile.mk b/src/pm/hydra/lib/utils/string/Makefile.mk deleted file mode 100644 index 78500445f9d..00000000000 --- a/src/pm/hydra/lib/utils/string/Makefile.mk +++ /dev/null @@ -1,6 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -libhydra_la_SOURCES += lib/utils/string/string.c From 21da60787e827c4d8ff59af7fd0f0e0a7df4acab Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Wed, 26 Jan 2022 15:22:49 -0600 Subject: [PATCH 505/607] test/mpi: Add back collalgo testing switch Collective algorithm testing requires Python 3 at configure time. Give users who do not have Python 3 an option to disable those tests, and skip the testlist generation. --- test/mpi/configure.ac | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index 592fff2570b..3c2cbe2e0df 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -238,6 +238,11 @@ AC_ARG_ENABLE(xfail, [Run tests marked for expected failure])],, [enable_xfail=no]) +AC_ARG_ENABLE(collalgo-tests, + [AS_HELP_STRING([--enable-collalgo-tests], + [Run extended collective algorithm tests])],, + [enable_collalgo_tests=yes]) + AC_ARG_ENABLE(gpu-tests-only, [AS_HELP_STRING([--enable-gpu-tests-only], [Run only GPU tests])],, @@ -253,12 +258,14 @@ AC_ARG_WITH(dtpools-datatypes, # parse args for typegen.sh script dtp_args="--with-dtpools-datatypes=${with_dtpools_datatypes}" - -PAC_CHECK_PYTHON AC_CONFIG_COMMANDS([gentests],[$srcdir/maint/gentests_dtp.sh $dtp_args],[dtp_args="$dtp_args"]) -#Test collectives algorithms with CVARs -cmd="$PYTHON $srcdir/maint/gen_coll_cvar.py" -AC_CONFIG_COMMANDS([collcvartests],[$cmd_gen_coll],[cmd_gen_coll="$cmd"]) + +if test $enable_collalgo_tests = "yes" ; then + PAC_CHECK_PYTHON + #Test collectives algorithms with CVARs + cmd="$PYTHON $srcdir/maint/gen_coll_cvar.py" + AC_CONFIG_COMMANDS([collcvartests],[$cmd_gen_coll],[cmd_gen_coll="$cmd"]) +fi AC_ARG_WITH(mpi, [AC_HELP_STRING([--with-mpi=dir], From 6422c3e580b9adf8fc8bc82fe48fb359d70953b8 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Thu, 27 Jan 2022 13:23:27 -0600 Subject: [PATCH 506/607] test/mpi: Move testlist settings to configure Setup testlist and testdirs for "make testing" at configure time, rather than spread the logic to Makefiles with AM_CONDITIONAL. --- test/mpi/Makefile_common.mtest | 12 ++---------- test/mpi/configure.ac | 27 +++++++++++++++------------ 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/test/mpi/Makefile_common.mtest b/test/mpi/Makefile_common.mtest index f48afa7c164..753291544d5 100644 --- a/test/mpi/Makefile_common.mtest +++ b/test/mpi/Makefile_common.mtest @@ -21,16 +21,8 @@ LDADD = $(top_builddir)/dtpools/src/libdtpools.la $(top_builddir)/dtpools/src/libdtpools.la: (cd $(top_builddir)/dtpools && $(MAKE)) -if HAVE_GPU -if GPU_ONLY -TESTDIRS ?= coll,pt2pt,rma -TESTLIST ?= testlist.gpu -else -TESTLIST ?= testlist,testlist.dtp,testlist.cvar,testlist.gpu -endif -else -TESTLIST ?= testlist,testlist.dtp,testlist.cvar -endif +TESTDIRS ?= @TESTDIRS@ +TESTLIST ?= @TESTLIST@ SUMMARY_BASENAME ?= summary testing: diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index 3c2cbe2e0df..1436e496d8c 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -133,14 +133,6 @@ AC_ARG_ENABLE([dtpools], [AS_HELP_STRING([--disable-dtpools],[Disable dtpools tests])],, [enable_dtpools=yes]) -if test "x${enable_dtpools}" = "xyes"; then - DTP_SWITCH="ON" -else - DTP_SWITCH="OFF" -fi - -AC_SUBST(DTP_SWITCH) - # runtests options RUNTESTS_OPTS= AC_SUBST(RUNTESTS_OPTS) @@ -746,13 +738,24 @@ PAC_POP_FLAG([CPPFLAGS]) PAC_POP_FLAG([LDFLAGS]) PAC_POP_FLAG([LIBS]) -AM_CONDITIONAL([HAVE_GPU], [test $have_gpu = "yes"]) -# GPU only tests +# setup which tests "make testing" will run +TESTLIST=testlist,testlist.cvar +TESTDIRS= +if test $have_gpu = "yes" ; then + TESTLIST="${TESTLIST},testlist.gpu" +fi +if test $enable_dtpools = "yes" ; then + TESTLIST="${TESTLIST},testlist.dtp" +fi +# handle --enable-gpu-tests-only if test $have_gpu = "no" -a $enable_gpu_tests_only = "yes" ; then AC_MSG_ERROR([GPU only test configuration requires GPU library (CUDA or LevelZero)]) +elif test $enable_gpu_tests_only = "yes" ; then + TESTDIRS=coll,pt2pt,rma + TESTLIST=testlist.gpu fi -AM_CONDITIONAL([GPU_ONLY], [test $enable_gpu_tests_only = "yes"]) -# End of GPU libs Check +AC_SUBST([TESTDIRS]) +AC_SUBST([TESTLIST]) # for tests that require large mem largetest="#" From 4734cf53b76fe7b34502b2d00cb5b0f42ff3acd6 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Thu, 27 Jan 2022 13:30:36 -0600 Subject: [PATCH 507/607] test/mpi: Move collalgo test generation to autogen These testlist have no dependency on configure, so just generate them always and remove the Python 3 requirement from configure entirely. --- test/mpi/autogen.sh | 29 +++++++++++++++++++++++++++++ test/mpi/configure.ac | 12 ++++-------- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/test/mpi/autogen.sh b/test/mpi/autogen.sh index e6e8d768e1b..b6fcbab6467 100755 --- a/test/mpi/autogen.sh +++ b/test/mpi/autogen.sh @@ -4,6 +4,35 @@ ## See COPYRIGHT in top-level directory ## +echo_n() { + # "echo -n" isn't portable, must portably implement with printf + printf "%s" "$*" +} + +PYTHON= +check_python3() { + echo_n "Checking for Python 3... " + PYTHON= + if test 3 = `python -c 'import sys; print(sys.version_info[0])'`; then + PYTHON=python + fi + + if test -z "$PYTHON" -a 3 = `python3 -c 'import sys; print(sys.version_info[0])'`; then + PYTHON=python3 + fi + + if test -z "$PYTHON" ; then + echo "not found" + exit 1 + else + echo "$PYTHON" + fi +} + +check_python3 +echo "Generating collective cvar tests" +$PYTHON maint/gen_coll_cvar.py + check_copy() { name=$1 orig=$2 diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index 1436e496d8c..b0673eaa5de 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -252,13 +252,6 @@ AC_ARG_WITH(dtpools-datatypes, dtp_args="--with-dtpools-datatypes=${with_dtpools_datatypes}" AC_CONFIG_COMMANDS([gentests],[$srcdir/maint/gentests_dtp.sh $dtp_args],[dtp_args="$dtp_args"]) -if test $enable_collalgo_tests = "yes" ; then - PAC_CHECK_PYTHON - #Test collectives algorithms with CVARs - cmd="$PYTHON $srcdir/maint/gen_coll_cvar.py" - AC_CONFIG_COMMANDS([collcvartests],[$cmd_gen_coll],[cmd_gen_coll="$cmd"]) -fi - AC_ARG_WITH(mpi, [AC_HELP_STRING([--with-mpi=dir], [Use the selected MPI; compilation scripts for mpicc, @@ -739,7 +732,7 @@ PAC_POP_FLAG([LDFLAGS]) PAC_POP_FLAG([LIBS]) # setup which tests "make testing" will run -TESTLIST=testlist,testlist.cvar +TESTLIST=testlist TESTDIRS= if test $have_gpu = "yes" ; then TESTLIST="${TESTLIST},testlist.gpu" @@ -747,6 +740,9 @@ fi if test $enable_dtpools = "yes" ; then TESTLIST="${TESTLIST},testlist.dtp" fi +if test $enable_collalgo_tests = "yes" ; then + TESTLIST="${TESTLIST},testlist.cvar" +fi # handle --enable-gpu-tests-only if test $have_gpu = "no" -a $enable_gpu_tests_only = "yes" ; then AC_MSG_ERROR([GPU only test configuration requires GPU library (CUDA or LevelZero)]) From a993f6ad5a76161e6b6cb02d0a91f33e85a54264 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 1 Feb 2022 11:17:08 -0600 Subject: [PATCH 508/607] test/mpi: Rename collalgo testlist file --- test/mpi/.gitignore | 1 + test/mpi/configure.ac | 2 +- test/mpi/maint/gen_coll_cvar.py | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/test/mpi/.gitignore b/test/mpi/.gitignore index 4a8e1f9d290..c191a2a7b31 100644 --- a/test/mpi/.gitignore +++ b/test/mpi/.gitignore @@ -178,6 +178,7 @@ /coll/scattern /coll/scatterv /coll/testlist +/coll/testlist.collalgo /coll/testlist.dtp /coll/uop_equal /coll/uoplong diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index b0673eaa5de..15fd13d6f4d 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -741,7 +741,7 @@ if test $enable_dtpools = "yes" ; then TESTLIST="${TESTLIST},testlist.dtp" fi if test $enable_collalgo_tests = "yes" ; then - TESTLIST="${TESTLIST},testlist.cvar" + TESTLIST="${TESTLIST},testlist.collalgo" fi # handle --enable-gpu-tests-only if test $have_gpu = "no" -a $enable_gpu_tests_only = "yes" ; then diff --git a/test/mpi/maint/gen_coll_cvar.py b/test/mpi/maint/gen_coll_cvar.py index 07e6c960e7f..0e541a18d58 100644 --- a/test/mpi/maint/gen_coll_cvar.py +++ b/test/mpi/maint/gen_coll_cvar.py @@ -20,7 +20,7 @@ def search(pat, str, flags=0): def main(): (tests, algos, algo_params) = load_config("coll_cvars.txt") - testlist_cvar = "coll/testlist.cvar" + testlist_cvar = "coll/testlist.collalgo" print(" --> [%s]" % testlist_cvar) with open(testlist_cvar, "w") as Out: for (key, testlist) in tests.items(): From c1c99b1d3f2f168a12fb9f71ebbf121b3c29bc53 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 15 Feb 2022 13:28:21 -0600 Subject: [PATCH 509/607] hydra: update mpiexec manpage Remove a few environment variables that hydra does not support. Update the text to reflect that this only describes a general set of the interface. TODO: document all options and variables that hydra supports. --- src/pm/hydra/mansrc/mpiexec.txt | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/pm/hydra/mansrc/mpiexec.txt b/src/pm/hydra/mansrc/mpiexec.txt index 8d616fe0c6b..32e66541d9b 100644 --- a/src/pm/hydra/mansrc/mpiexec.txt +++ b/src/pm/hydra/mansrc/mpiexec.txt @@ -48,6 +48,14 @@ The MPI standard specifies the following arguments and their meanings\: MPICH-Specific Arguments: + MPICH implements a few process managers. Here we list a general set of + arguments that many of the implementations support. More detailed options + that are supported by a particular implementation, e.g. hydra, are + available via\: +.vb + mpiexec -h +.ve + Many of the implementations of process managers in MPICH support the following arguments to 'mpiexec'\: @@ -92,17 +100,6 @@ The MPI standard specifies the following arguments and their meanings\: 10000 and 10100, use '10000:10100'. . MPICH_PORT_RANGE - Has the same meaning as 'MPIEXEC_PORT_RANGE' and is used if 'MPIEXEC_PORT_RANGE' is not set. -. MPIEXEC_PREFIX_DEFAULT - If this environment variable is set, output - to standard output is prefixed by the rank in 'MPI_COMM_WORLD' of the - process and output to standard error is prefixed by the rank and the - text '(err)'; both are followed by an angle bracket ('>'). If - this variable is not set, there is no prefix. -. MPIEXEC_PREFIX_STDOUT - Set the prefix used for lines sent to standard - output. A '%d' is replaced with the rank in 'MPI_COMM_WORLD'; a '%w' is - replaced with an indication of which 'MPI_COMM_WORLD' in MPI jobs that - involve multiple 'MPI_COMM_WORLD's (e.g., ones that use 'MPI_Comm_spawn' or - 'MPI_Comm_connect'). -- MPIEXEC_PREFIX_STDERR - Like 'MPIEXEC_PREFIX_STDOUT', but for standard error. Return Status: 'mpiexec' returns the maximum of the exit status values of all of the From dfb6d8eb9aebc33ffba315925f0a09f1d49bb07f Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 18 Feb 2022 15:32:17 -0600 Subject: [PATCH 510/607] binding/c: check when alltoallw count is 0 When the counts array in MPI_Alltoallw contains 0, we need skip the corresponding datatype check. --- maint/local_python/binding_c.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/maint/local_python/binding_c.py b/maint/local_python/binding_c.py index b03ff43bec2..3fc338c4d09 100644 --- a/maint/local_python/binding_c.py +++ b/maint/local_python/binding_c.py @@ -2079,7 +2079,9 @@ def dump_validate_userbuffer_neighbor_vw(func, kind, buf, ct, dt, disp): ct += '[i]' if RE.search(r'-w$', kind): dt += '[i]' + dump_if_open("%s > 0" % ct) dump_validate_datatype(func, dt) + dump_if_close() G.out.append("MPIR_ERRTEST_COUNT(%s, mpi_errno);" % ct) G.out.append("if (%s[i] == 0) {" % disp) G.out.append(" MPIR_ERRTEST_USERBUFFER(%s, %s, %s, mpi_errno);" % (buf, ct, dt)) @@ -2198,7 +2200,9 @@ def dump_validate_userbuffer_coll(func, kind, buf, ct, dt, disp): ct += '[i]' if RE.search(r'-w$', kind): dt += '[i]' + dump_if_open("%s > 0" % ct) dump_validate_datatype(func, dt) + dump_if_close() # -- test wrong MPI_IN_PLACE SEND = "SEND" From bc7f81a0de671172388f59270192d80535143b4b Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 19 Jan 2022 17:36:31 -0600 Subject: [PATCH 511/607] op: replace predefined datatype on input We are supposed to support operations on some predefined datatype, such as those from MPI_Type_create_f90_xxx. However, those types are in fact derived types wraps around a basic type. Check and replace the input datatype with the basic type if that is the case so the reduction can work. Since the datatype in these case are all input only parameters, there shouldn't be any side effects replacing them. --- maint/local_python/binding_c.py | 8 ++++++++ src/include/mpir_op.h | 4 ++++ src/mpi/coll/op/oputil.c | 22 ++++++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/maint/local_python/binding_c.py b/maint/local_python/binding_c.py index 3fc338c4d09..26884858f50 100644 --- a/maint/local_python/binding_c.py +++ b/maint/local_python/binding_c.py @@ -2287,6 +2287,14 @@ def dump_validate_op(op, dt, is_coll): if dt: G.out.append("} else {") G.out.append(" mpi_errno = (*MPIR_OP_HDL_TO_DTYPE_FN(%s)) (%s);" % (op, dt)) + # check predefined datatype and replace with basic_type if necessary + G.out.append(" if (mpi_errno != MPI_SUCCESS) {") + G.out.append(" MPI_Datatype alt_dt = MPIR_Op_get_alt_datatype(%s, %s);" % (op, dt)) + G.out.append(" if (alt_dt != MPI_DATATYPE_NULL) {") + G.out.append(" %s = alt_dt;" % dt) + G.out.append(" mpi_errno = MPI_SUCCESS;") + G.out.append(" }") + G.out.append(" }") G.out.append("}") dump_error_check("") diff --git a/src/include/mpir_op.h b/src/include/mpir_op.h index 4d82dcc9df9..4aa2c051999 100644 --- a/src/include/mpir_op.h +++ b/src/include/mpir_op.h @@ -220,4 +220,8 @@ extern MPIR_Op_check_dtype_fn *MPIR_Op_check_dtype_table[]; int MPIR_Op_is_commutative(MPI_Op); +/* for some predefined datatypes, e.g. from MPI_Type_create_f90_xxx, we need + * use its basic type for operations */ +MPI_Datatype MPIR_Op_get_alt_datatype(MPI_Op op, MPI_Datatype datatype); + #endif /* MPIR_OP_H_INCLUDED */ diff --git a/src/mpi/coll/op/oputil.c b/src/mpi/coll/op/oputil.c index aedbd439fe7..8b21bbd1635 100644 --- a/src/mpi/coll/op/oputil.c +++ b/src/mpi/coll/op/oputil.c @@ -86,3 +86,25 @@ const char *MPIR_Op_builtin_get_shortname(MPI_Op op) } return ""; } + +/* for some predefined datatypes, e.g. from MPI_Type_create_f90_xxx, we need + * use its basic type for operations */ +MPI_Datatype MPIR_Op_get_alt_datatype(MPI_Op op, MPI_Datatype datatype) +{ + MPI_Datatype alt_dt = MPI_DATATYPE_NULL; + if (!HANDLE_IS_BUILTIN(datatype)) { + MPIR_Datatype *dt_ptr; + MPIR_Datatype_get_ptr(datatype, dt_ptr); + + if (dt_ptr && dt_ptr->contents) { + int combiner = dt_ptr->contents->combiner; + if (combiner == MPI_COMBINER_F90_REAL || + combiner == MPI_COMBINER_F90_COMPLEX || combiner == MPI_COMBINER_F90_INTEGER) { + if (MPI_SUCCESS == (*MPIR_OP_HDL_TO_DTYPE_FN(op)) (dt_ptr->basic_type)) { + alt_dt = dt_ptr->basic_type; + } + } + } + } + return alt_dt; +} From 66830ab84e5e6c83d3265c776540b1b46fcfcc96 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 22 Feb 2022 16:19:33 -0600 Subject: [PATCH 512/607] ch4: Workaround Intel compiler TLS bug on macOS Same problem as previously fixed in [2925988a]. global_vci_poll_count was not being allocated as TLS by the Intel compiler on macOS. Add a dummy function to touch it and force the correct allocation. --- src/mpid/ch4/src/ch4_globals.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/mpid/ch4/src/ch4_globals.c b/src/mpid/ch4/src/ch4_globals.c index 22c94bb64c0..3da236a9c59 100644 --- a/src/mpid/ch4/src/ch4_globals.c +++ b/src/mpid/ch4/src/ch4_globals.c @@ -36,6 +36,17 @@ MPL_COMPILER_TLS int global_vci_poll_count; int global_vci_poll_count = 0; #endif +/* ** HACK ** + * Hack to workaround an Intel compiler bug on macOS. Touching + * global_vci_poll_count in this file forces the compiler to allocate + * it as TLS. See https://github.com/pmodels/mpich/issues/3437. + */ +int _dummy_touch_tls(void); +int _dummy_touch_tls(void) +{ + return global_vci_poll_count; +} + /* PVAR */ unsigned PVAR_LEVEL_posted_recvq_length ATTRIBUTE((unused)); unsigned PVAR_LEVEL_unexpected_recvq_length ATTRIBUTE((unused)); From 099bb980364bb28bf227da09fbfc9805b68d6c36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= Date: Sun, 23 Jan 2022 01:49:08 +0000 Subject: [PATCH 513/607] mpl: Use CPU affinity functions with standard names The functions with leading underscores are internally used in some systems, but the user-facing ones are without underscores: https://linux.die.net/man/3/cpu_set. The underscore-prefixed names are not available on Musl systems, leading to a linking error: ``` [01:19:03] libtool: link: cc -fvisibility=hidden -DNDEBUG -DNVALGRIND -O3 -o src/env/.libs/mpichversion src/env/mpichversion.o lib/.libs/libmpi.so -lpthread -lm -Wl,-rpath -Wl,/workspace/destdir/lib [01:19:03] /opt/x86_64-linux-musl/bin/../lib/gcc/x86_64-linux-musl/8.1.0/../../../../x86_64-linux-musl/bin/ld: lib/.libs/libmpi.so: undefined reference to `__CPU_ISSET_S' [01:19:03] /opt/x86_64-linux-musl/bin/../lib/gcc/x86_64-linux-musl/8.1.0/../../../../x86_64-linux-musl/bin/ld: lib/.libs/libmpi.so: undefined reference to `__CPU_SET_S' [01:19:03] /opt/x86_64-linux-musl/bin/../lib/gcc/x86_64-linux-musl/8.1.0/../../../../x86_64-linux-musl/bin/ld: lib/.libs/libmpi.so: undefined reference to `__CPU_ZERO_S' [01:19:03] /opt/x86_64-linux-musl/bin/../lib/gcc/x86_64-linux-musl/8.1.0/../../../../x86_64-linux-musl/bin/ld: lib/.libs/libmpi.so: undefined reference to collect2: error: ld returned 1 exit status [01:19:03] `__CPU_ISSET_S' [01:19:03] /opt/x86_64-linux-musl/bin/../lib/gcc/x86_64-linux-musl/8.1.0/../../../../x86_64-linux-musl/bin/ld: lib/.libs/libmpi.so: undefined reference to `__CPU_SET_S' [01:19:03] /opt/x86_64-linux-musl/bin/../lib/gcc/x86_64-linux-musl/8.1.0/../../../../x86_64-linux-musl/bin/ld: lib/.libs/libmpi.so: undefined reference to `__CPU_ZERO_S' [01:19:03] collect2: error: ld returned 1 exit status [01:19:03] make[2]: *** [Makefile:14129: src/env/mpichversion] Error 1 [01:19:03] make[2]: *** Waiting for unfinished jobs.... [01:19:03] make[2]: *** [Makefile:14135: src/env/mpivars] Error 1 ``` --- src/mpl/src/thread/mpl_thread_posix.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mpl/src/thread/mpl_thread_posix.c b/src/mpl/src/thread/mpl_thread_posix.c index 44ec06aeca5..09f9b524ddf 100644 --- a/src/mpl/src/thread/mpl_thread_posix.c +++ b/src/mpl/src/thread/mpl_thread_posix.c @@ -90,10 +90,10 @@ void MPL_thread_set_affinity(MPL_thread_id_t thread, int *affinity_arr, int affi int err = MPL_SUCCESS; int proc_idx, set_size = 0; cpu_set_t cpuset; - __CPU_ZERO_S(sizeof(cpu_set_t), &cpuset); + CPU_ZERO_S(sizeof(cpu_set_t), &cpuset); for (proc_idx = 0; proc_idx < affinity_size; proc_idx++) - __CPU_SET_S(affinity_arr[proc_idx], sizeof(cpu_set_t), &cpuset); + CPU_SET_S(affinity_arr[proc_idx], sizeof(cpu_set_t), &cpuset); if (pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset) != 0) { err = MPL_ERR_THREAD; @@ -106,7 +106,7 @@ void MPL_thread_set_affinity(MPL_thread_id_t thread, int *affinity_arr, int affi } for (proc_idx = 0; proc_idx < affinity_size; proc_idx++) { - if (__CPU_ISSET_S(affinity_arr[proc_idx], sizeof(cpu_set_t), &cpuset)) + if (CPU_ISSET_S(affinity_arr[proc_idx], sizeof(cpu_set_t), &cpuset)) set_size++; } if (set_size != affinity_size) { From 7de1f9677b7848131c8494c1c63b9dc14f194173 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Mon, 31 Jan 2022 11:53:06 -0600 Subject: [PATCH 514/607] pm/hydra: Support newer Slurm environment variables SLURM_NNODES and SLURM_NODELIST are deprecated. Add support for using SLURM_JOB_NUM_NODES and SLURM_JOB_NODELIST, but retain the old ones for compatibility. --- .../lib/tools/bootstrap/external/slurm_query_native_int.c | 5 +++-- .../lib/tools/bootstrap/external/slurm_query_node_list.c | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/pm/hydra/lib/tools/bootstrap/external/slurm_query_native_int.c b/src/pm/hydra/lib/tools/bootstrap/external/slurm_query_native_int.c index 89730068d6f..fb458813e7e 100644 --- a/src/pm/hydra/lib/tools/bootstrap/external/slurm_query_native_int.c +++ b/src/pm/hydra/lib/tools/bootstrap/external/slurm_query_native_int.c @@ -15,9 +15,10 @@ HYD_status HYDT_bscd_slurm_query_native_int(int *ret) *ret = 1; - if (!HYDTI_bscd_env_is_avail("SLURM_NODELIST")) + if (!HYDTI_bscd_env_is_avail("SLURM_JOB_NODELIST") && + !HYDTI_bscd_env_is_avail("SLURM_NODELIST")) *ret = 0; - if (!HYDTI_bscd_env_is_avail("SLURM_NNODES")) + if (!HYDTI_bscd_env_is_avail("SLURM_JOB_NUM_NODES") && !HYDTI_bscd_env_is_avail("SLURM_NNODES")) *ret = 0; if (!HYDTI_bscd_env_is_avail("SLURM_TASKS_PER_NODE")) *ret = 0; diff --git a/src/pm/hydra/lib/tools/bootstrap/external/slurm_query_node_list.c b/src/pm/hydra/lib/tools/bootstrap/external/slurm_query_node_list.c index 869d38b7add..49c2a2af20c 100644 --- a/src/pm/hydra/lib/tools/bootstrap/external/slurm_query_node_list.c +++ b/src/pm/hydra/lib/tools/bootstrap/external/slurm_query_node_list.c @@ -466,12 +466,14 @@ HYD_status HYDT_bscd_slurm_query_node_list(struct HYD_node **node_list) HYDU_FUNC_ENTER(); - if (MPL_env2str("SLURM_NODELIST", (const char **) &list) == 0) { + if (MPL_env2str("SLURM_JOB_NODELIST", (const char **) &list) == 0 || + MPL_env2str("SLURM_NODELIST", (const char **) &list) == 0) { *node_list = NULL; goto fn_exit; } - if (MPL_env2str("SLURM_NNODES", (const char **) &dummy) == 0) { + if (MPL_env2str("SLURM_JOB_NUM_NODES", (const char **) &dummy) == 0 || + MPL_env2str("SLURM_NNODES", (const char **) &dummy) == 0) { *node_list = NULL; goto fn_exit; } From 95ba4ddc7efc7ddc7f25ed41480ee35248184680 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Mon, 31 Jan 2022 12:21:58 -0600 Subject: [PATCH 515/607] pm/hydra: Simplify Slurm environment inheritance Rather than try to keep a list of environment variables in sync with what Slurm uses, just match on prefixes SLURM_, SLURMD_, and SBATCH_. That covers everything that is documented at https://slurm.schedmd.com/sbatch.html. --- .../lib/tools/bootstrap/external/slurm_env.c | 29 +++++-------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/src/pm/hydra/lib/tools/bootstrap/external/slurm_env.c b/src/pm/hydra/lib/tools/bootstrap/external/slurm_env.c index 3d5e9a95b0b..05380b004f9 100644 --- a/src/pm/hydra/lib/tools/bootstrap/external/slurm_env.c +++ b/src/pm/hydra/lib/tools/bootstrap/external/slurm_env.c @@ -9,30 +9,15 @@ HYD_status HYDT_bscd_slurm_query_env_inherit(const char *env_name, int *ret) { - const char *env_list[] = { "SLURM_ACCOUNT", "SLURM_CPU_BIND", - "SLURM_CPUS_PER_TASK", "SLURM_CONN_TYPE", - "SLURM_CORE_FORMAT", "SLURM_DEBUG", "SLURMD_DEBUG", - "SLURM_DISABLE_STATUS", "SLURM_DISTRIBUTION", - "SLURM_GEOMETRY", "SLURM_LABELIO", "SLURM_MEM_BIND", - "SLURM_NETWORK", "SLURM_NNODES", "SLURM_NO_ROTATE", - "SLURM_NPROCS", "SLURM_OVERCOMMIT", "SLURM_PARTITION", - "SLURM_REMOTE_CWD", "SLURM_SRUN_COMM_IFHN", - "SLURM_STDERRMODE", "SLURM_STDINMODE", - "SLURM_STDOUTMODE", "SLURM_TASK_EPILOG", - "SLURM_TASK_PROLOG", "SLURM_TIMELIMIT", "SLURM_WAIT", - "SLURM_CPU_BIND_VERBOSE", "SLURM_CPU_BIND_TYPE", - "SLURM_CPU_BIND_LIST", "SLURM_CPUS_ON_NODE", - "SLURM_JOBID", "SLURM_LAUNCH_NODE_IPADDR", - "SLURM_LOCALID", "SLURM_MEM_BIND_VERBOSE", - "SLURM_MEM_BIND_TYPE", "SLURM_MEM_BIND_LIST", - "SLURM_NODEID", "SLURM_NODELIST", "SLURM_PROCID", - "SLURM_TASKS_PER_NODE", "MAX_TASKS_PER_NODE", - "SLURM_HOSTFILE", NULL - }; - HYDU_FUNC_ENTER(); - *ret = !HYDTI_bscd_in_env_list(env_name, env_list); + /* check if envvar starts with SBATCH_, SLURMD_, or SLURM_ */ + if (strncmp(env_name, "SBATCH_", 7) == 0 || strncmp(env_name, "SLURMD_", 7) == 0 || + strncmp(env_name, "SLURM_", 6) == 0) { + *ret = 1; + } else { + *ret = 0; + } HYDU_FUNC_EXIT(); From 7a531ba1345eca947c55e6c110f3c1b095e32618 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Wed, 16 Feb 2022 11:30:53 -0600 Subject: [PATCH 516/607] Makefile: Add option to configure the testsuite Sometimes it is desirable to setup the testsuite for use, but not actually execute any tests. --- Makefile.am | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile.am b/Makefile.am index 261a2e83a8c..71df5f21fb8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -191,6 +191,9 @@ EXTRA_DIST += README.vin testing: ( cd test && $(MAKE) $(AM_MAKEFLAGS) testing ) +testconfig: + ( cd test && $(MAKE) $(AM_MAKEFLAGS) mpi/Makefile ) + test-clean: ( cd test && $(MAKE) $(AM_MAKEFLAGS) clean ) CLEAN_LOCAL_TARGETS += test-clean From 9342636e58975b359bcad3f712b1f225435cd3b9 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Wed, 16 Feb 2022 11:32:31 -0600 Subject: [PATCH 517/607] Makefile: Do not add test files to clean target The testsuite is built separately, so attempts to clean it along with the main MPICH build may result in error. Leave the target, but do not include it in `make clean` from the top-level directory. --- Makefile.am | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 71df5f21fb8..7ae7d44195c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -196,7 +196,6 @@ testconfig: test-clean: ( cd test && $(MAKE) $(AM_MAKEFLAGS) clean ) -CLEAN_LOCAL_TARGETS += test-clean ## FIXME: this should live in src/env/Makefile.mk. Moving it there ## will not cause a problem, but it will break the build if another From 690953d5fb55b098ae093753a109a190ea06dd3c Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 18 Feb 2022 14:27:34 -0600 Subject: [PATCH 518/607] Revert "configure: reset flags before configure hydra etc" This reverts commit 6cff62e0ab3bcc8eca8432c0c78c098accd83ba9. We need inherit at the CFLAGS to enable strict warnings check with hydra and romio. --- configure.ac | 3 --- 1 file changed, 3 deletions(-) diff --git a/configure.ac b/configure.ac index 7c84f9a081e..ab82b8f67fb 100644 --- a/configure.ac +++ b/configure.ac @@ -3848,12 +3848,9 @@ m4_map([PAC_SUBCFG_CONFIGURE_SUBSYS], [PAC_SUBCFG_MODULE_LIST]) # now configure any actual recursively configures subsystems, such as ROMIO and # hydra, or older components that haven't been updated to a subconfigure.m4 yet -PAC_PUSH_ALL_FLAGS() -PAC_RESET_ALL_FLAGS() for subsys in $devsubsystems $subsystems ; do PAC_CONFIG_SUBDIR([$subsys],[],[AC_MSG_ERROR([$subsys configure failed])]) done -PAC_POP_ALL_FLAGS() if test "$DEBUG_SUBDIR_CACHE" = yes -a "$enable_echo" != yes ; then set +x fi From 8b023dd3ae7020d0fee75cb74c067a992ad75861 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 18 Feb 2022 14:47:58 -0600 Subject: [PATCH 519/607] config: pass --with-hwloc=embedded to subsys configure When user has an outdated hwloc installed, the configure will switch to use the embedded hwloc. This may end up hydra check with embedded hwloc -- due to inheriting CPPFLAGS from mpich -- and link with external outdated hwloc. Pass --with-hwloc=embedded option down will prevent such inconsistency. --- confdb/aclocal_modules.m4 | 2 ++ configure.ac | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/confdb/aclocal_modules.m4 b/confdb/aclocal_modules.m4 index 2f879aeb5a6..629f47ee2b3 100644 --- a/confdb/aclocal_modules.m4 +++ b/confdb/aclocal_modules.m4 @@ -79,6 +79,8 @@ AC_DEFUN([PAC_CONFIG_HWLOC],[ if test "$pac_have_hwloc" = "no" -a "$with_hwloc" != "no"; then with_hwloc=embedded pac_have_hwloc=yes + # make sure subsystems such as hydra will use embedded hwloc consistently + subsys_config_args="$subsys_config_args --with-hwloc=embedded" fi if test "$with_hwloc" = "embedded" ; then diff --git a/configure.ac b/configure.ac index ab82b8f67fb..4ffd91efa4d 100644 --- a/configure.ac +++ b/configure.ac @@ -3849,7 +3849,7 @@ m4_map([PAC_SUBCFG_CONFIGURE_SUBSYS], [PAC_SUBCFG_MODULE_LIST]) # now configure any actual recursively configures subsystems, such as ROMIO and # hydra, or older components that haven't been updated to a subconfigure.m4 yet for subsys in $devsubsystems $subsystems ; do - PAC_CONFIG_SUBDIR([$subsys],[],[AC_MSG_ERROR([$subsys configure failed])]) + PAC_CONFIG_SUBDIR_ARGS([$subsys],[$subsys_config_args],[],[AC_MSG_ERROR([$subsys configure failed])]) done if test "$DEBUG_SUBDIR_CACHE" = yes -a "$enable_echo" != yes ; then set +x From 27403bf59ed7bf84d90b7a9454dbba59dc651f65 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 23 Feb 2022 15:17:04 -0600 Subject: [PATCH 520/607] config: remove PAC_CC_STRICT from hydra Hydra is going to inherit the CFLAGS from mpich configure. Meanwhile, having the extra interaction between MPICH and hydra is easy to bring forth complications. Thus we remove PAC_CC_STRICT from hydra to keep it simple. --- confdb/aclocal_cc.m4 | 8 +------- src/pm/hydra/configure.ac | 2 -- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/confdb/aclocal_cc.m4 b/confdb/aclocal_cc.m4 index 762ad36f003..3f522e07348 100644 --- a/confdb/aclocal_cc.m4 +++ b/confdb/aclocal_cc.m4 @@ -471,12 +471,7 @@ dnl had trouble with gcc 2.95.3 accepting -std=c89 but then trying to dnl compile program with a invalid set of options dnl (-D __STRICT_ANSI__-trigraphs) AC_DEFUN([PAC_CC_STRICT],[ -PAC_CC_VENDOR() -export enable_strict_done -if test "$enable_strict_done" != "yes" ; then - # make sure we don't add the below flags multiple times - enable_strict_done=yes - + PAC_CC_VENDOR() # Some comments on strict warning options. # These were added to improve portability # -Wstack-usage=262144 -- 32 bit FreeBSD did not like the mprobe test @@ -682,7 +677,6 @@ if test "$enable_strict_done" != "yes" ; then PAC_POP_FLAG([CFLAGS]) done pac_cc_strict_flags=$accepted_flags -fi ]) dnl/*D diff --git a/src/pm/hydra/configure.ac b/src/pm/hydra/configure.ac index eb4366a3e44..51ed50f9320 100644 --- a/src/pm/hydra/configure.ac +++ b/src/pm/hydra/configure.ac @@ -46,8 +46,6 @@ AC_SUBST(WRAPPER_LIBS) # let confdb macro know that we are using WRAPPER FLAGS m4_define([use_wrapper_flags], [1]) -PAC_ARG_STRICT - # Look for perl. The absolute path of perl is required in hydra-doxygen.cfg. AC_PATH_PROG(PERL,perl) From 19ef1a33caa989176a9a7eeb1b8cbc425dd8eb7a Mon Sep 17 00:00:00 2001 From: Gengbin Zheng Date: Mon, 14 Feb 2022 11:48:19 -0600 Subject: [PATCH 521/607] coll: add high radix diessemination algorithm for Barrier --- src/mpi/coll/barrier/Makefile.mk | 1 + .../barrier/barrier_intra_k_dissemination.c | 104 ++++++++++++++++++ src/mpi/coll/coll_algorithms.txt | 3 + src/mpi/coll/cvars.txt | 11 ++ src/mpi/coll/include/csel_container.h | 6 + src/mpi/coll/src/csel_container.c | 15 ++- test/mpi/maint/coll_cvars.txt | 2 + 7 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 src/mpi/coll/barrier/barrier_intra_k_dissemination.c diff --git a/src/mpi/coll/barrier/Makefile.mk b/src/mpi/coll/barrier/Makefile.mk index eb2fc8de296..fcdc2407e6f 100644 --- a/src/mpi/coll/barrier/Makefile.mk +++ b/src/mpi/coll/barrier/Makefile.mk @@ -10,5 +10,6 @@ mpi_core_sources += \ src/mpi/coll/barrier/barrier_allcomm_nb.c \ src/mpi/coll/barrier/barrier_intra_dissemination.c \ + src/mpi/coll/barrier/barrier_intra_k_dissemination.c \ src/mpi/coll/barrier/barrier_intra_smp.c \ src/mpi/coll/barrier/barrier_inter_bcast.c diff --git a/src/mpi/coll/barrier/barrier_intra_k_dissemination.c b/src/mpi/coll/barrier/barrier_intra_k_dissemination.c new file mode 100644 index 00000000000..f811d19412f --- /dev/null +++ b/src/mpi/coll/barrier/barrier_intra_k_dissemination.c @@ -0,0 +1,104 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpiimpl.h" + + +/* Algorithm: high radix dissemination + * Similar to dissemination algorithm, but generalized with high radix k + */ +int MPIR_Barrier_intra_k_dissemination(MPIR_Comm * comm, int k, MPIR_Errflag_t * errflag) +{ + int mpi_errno = MPI_SUCCESS, mpi_errno_ret = MPI_SUCCESS; + int i, j, nranks, rank; + int p_of_k; /* minimum power of k that is greater than or equal to number of ranks */ + int shift, to, from; + int nphases = 0; + MPIR_Request *sreqs[MAX_RADIX], *rreqs[MAX_RADIX * 2]; + MPIR_Request **send_reqs = NULL, **recv_reqs = NULL; + + nranks = MPIR_Comm_size(comm); + rank = MPIR_Comm_rank(comm); + + if (nranks == 1) + goto fn_exit; + + if (nranks < k) + k = nranks; + + /* If k value is greater than the maximum radix defined by MAX_RADIX macro, + * we allocate memory for requests here. Otherwise we use the requests defined + * in the communicator for allreduce/barrier recexch */ + if (k > MAX_RADIX) { + recv_reqs = + (MPIR_Request **) MPL_malloc((k - 1) * 2 * sizeof(MPIR_Request *), MPL_MEM_BUFFER); + MPIR_ERR_CHKANDJUMP(!recv_reqs, mpi_errno, MPI_ERR_OTHER, "**nomem"); + send_reqs = (MPIR_Request **) MPL_malloc((k - 1) * sizeof(MPIR_Request *), MPL_MEM_BUFFER); + MPIR_ERR_CHKANDJUMP(!send_reqs, mpi_errno, MPI_ERR_OTHER, "**nomem"); + } else { + send_reqs = sreqs; + recv_reqs = rreqs; + } + + p_of_k = 1; + while (p_of_k < nranks) { + p_of_k *= k; + nphases++; + } + + shift = 1; + for (i = 0; i < nphases; i++) { + for (j = 1; j < k; j++) { + to = (rank + j * shift) % nranks; + from = (nranks + (rank - j * shift)) % nranks; + while (from < 0) + from += nranks; + MPIR_Assert(from >= 0 && from < nranks); + MPIR_Assert(to >= 0 && to < nranks); + + /* recv from (k-1) nbrs */ + mpi_errno = + MPIC_Irecv(NULL, 0, MPI_BYTE, from, MPIR_BARRIER_TAG, comm, + &recv_reqs[(j - 1) + ((k - 1) * (i & 1))]); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); + /* wait on recvs from prev phase */ + if (i > 0 && j == 1) { + mpi_errno = + MPIC_Waitall(k - 1, &recv_reqs[((k - 1) * ((i - 1) & 1))], MPI_STATUSES_IGNORE, + errflag); + if (mpi_errno && mpi_errno != MPI_ERR_IN_STATUS) + MPIR_ERR_POP(mpi_errno); + } + + mpi_errno = + MPIC_Isend(NULL, 0, MPI_BYTE, to, MPIR_BARRIER_TAG, comm, &send_reqs[j - 1], + errflag); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); + } + mpi_errno = MPIC_Waitall(k - 1, send_reqs, MPI_STATUSES_IGNORE, errflag); + if (mpi_errno && mpi_errno != MPI_ERR_IN_STATUS) + MPIR_ERR_POP(mpi_errno); + shift *= k; + } + + mpi_errno = + MPIC_Waitall(k - 1, recv_reqs + ((k - 1) * ((nphases - 1) & 1)), MPI_STATUSES_IGNORE, + errflag); + if (mpi_errno && mpi_errno != MPI_ERR_IN_STATUS) + MPIR_ERR_POP(mpi_errno); + + fn_exit: + if (k > MAX_RADIX) { + MPL_free(recv_reqs); + MPL_free(send_reqs); + } + if (mpi_errno_ret) + mpi_errno = mpi_errno_ret; + else if (*errflag != MPIR_ERR_NONE) + MPIR_ERR_SET(mpi_errno, *errflag, "**coll_fail"); + return mpi_errno; + fn_fail: + goto fn_exit; +} diff --git a/src/mpi/coll/coll_algorithms.txt b/src/mpi/coll/coll_algorithms.txt index 96a86da3fe0..c3b61fcbb6e 100644 --- a/src/mpi/coll/coll_algorithms.txt +++ b/src/mpi/coll/coll_algorithms.txt @@ -42,6 +42,9 @@ barrier-intra: dissemination + k_dissemination + extra_params: k + cvar_params: DISSEM_KVAL smp restrictions: parent-comm barrier-inter: diff --git a/src/mpi/coll/cvars.txt b/src/mpi/coll/cvars.txt index afb1b4d80ef..921d217204e 100644 --- a/src/mpi/coll/cvars.txt +++ b/src/mpi/coll/cvars.txt @@ -20,6 +20,7 @@ cvars: nb - Force nonblocking algorithm smp - Force smp algorithm dissemination - Force dissemination algorithm + k_dissemination - Force high radix dissemination algorithm - name : MPIR_CVAR_BARRIER_INTER_ALGORITHM category : COLLECTIVE @@ -34,6 +35,16 @@ cvars: bcast - Force bcast algorithm nb - Force nonblocking algorithm + - name : MPIR_CVAR_BARRIER_DISSEM_KVAL + category : COLLECTIVE + type : int + default : 2 + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + k value for dissemination exchange based barrier algorithm + - name : MPIR_CVAR_IBARRIER_RECEXCH_KVAL category : COLLECTIVE type : int diff --git a/src/mpi/coll/include/csel_container.h b/src/mpi/coll/include/csel_container.h index 5ae50ac8db3..a23128838be 100644 --- a/src/mpi/coll/include/csel_container.h +++ b/src/mpi/coll/include/csel_container.h @@ -45,6 +45,7 @@ typedef enum { MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Alltoallw_inter_pairwise_exchange, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Alltoallw_allcomm_nb, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Barrier_intra_dissemination, + MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Barrier_intra_k_dissemination, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Barrier_intra_smp, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Barrier_inter_bcast, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Barrier_allcomm_nb, @@ -267,6 +268,11 @@ typedef struct { int bblock; } intra_tsp_blocked; } ialltoallw; + struct { + struct { + int k; + } intra_k_dissemination; + } barrier; struct { struct { int k; diff --git a/src/mpi/coll/src/csel_container.c b/src/mpi/coll/src/csel_container.c index 3131b4ff1cb..0cbd685c9e3 100644 --- a/src/mpi/coll/src/csel_container.c +++ b/src/mpi/coll/src/csel_container.c @@ -238,6 +238,17 @@ static void parse_container_params(struct json_object *obj, MPII_Csel_container_ } break; + case MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Barrier_intra_k_dissemination: + { + json_object_object_foreach(obj, key, val) { + ckey = MPL_strdup_no_spaces(key); + if (!strncmp(ckey, "k=", strlen("k="))) + cnt->u.barrier.intra_k_dissemination.k = atoi(ckey + strlen("k=")); + MPL_free(ckey); + } + } + break; + default: /* Algorithm does not have parameters */ break; @@ -324,8 +335,8 @@ void *MPII_Create_container(struct json_object *obj) cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Alltoallw_inter_pairwise_exchange; else if (!strcmp(ckey, "algorithm=MPIR_Alltoallw_allcomm_nb")) cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Alltoallw_allcomm_nb; - else if (!strcmp(ckey, "algorithm=MPIR_Barrier_intra_dissemination")) - cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Barrier_intra_dissemination; + else if (!strcmp(ckey, "algorithm=MPIR_Barrier_intra_k_dissemination")) + cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Barrier_intra_k_dissemination; else if (!strcmp(ckey, "algorithm=MPIR_Barrier_intra_smp")) cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Barrier_intra_smp; else if (!strcmp(ckey, "algorithm=MPIR_Barrier_inter_bcast")) diff --git a/test/mpi/maint/coll_cvars.txt b/test/mpi/maint/coll_cvars.txt index 8f5e951cfea..a0758d2ff37 100644 --- a/test/mpi/maint/coll_cvars.txt +++ b/test/mpi/maint/coll_cvars.txt @@ -309,6 +309,8 @@ algorithms: sched_bcast intra-blocking: dissemination + k_dissemination + .MPIR_CVAR_BARRIER_DISSEM_KVAL=2,3,4,8 intra-nonblocking: sched_recursive_doubling tsp_recexch From f4d7afbc335cb6652f2e93aaefd12a5fe78daea8 Mon Sep 17 00:00:00 2001 From: Gengbin Zheng Date: Tue, 15 Feb 2022 12:04:15 -0600 Subject: [PATCH 522/607] coll: add high radix recursive exchange algorithm for Barrier --- src/mpi/coll/barrier/Makefile.mk | 1 + src/mpi/coll/barrier/barrier_intra_recexch.c | 25 ++++++++++++++++++++ src/mpi/coll/coll_algorithms.txt | 3 +++ src/mpi/coll/cvars.txt | 22 +++++++++++++++++ src/mpi/coll/include/csel_container.h | 5 ++++ src/mpi/coll/src/csel_container.c | 13 ++++++++++ test/mpi/maint/coll_cvars.txt | 3 +++ 7 files changed, 72 insertions(+) create mode 100644 src/mpi/coll/barrier/barrier_intra_recexch.c diff --git a/src/mpi/coll/barrier/Makefile.mk b/src/mpi/coll/barrier/Makefile.mk index fcdc2407e6f..b1842fb340f 100644 --- a/src/mpi/coll/barrier/Makefile.mk +++ b/src/mpi/coll/barrier/Makefile.mk @@ -11,5 +11,6 @@ mpi_core_sources += \ src/mpi/coll/barrier/barrier_allcomm_nb.c \ src/mpi/coll/barrier/barrier_intra_dissemination.c \ src/mpi/coll/barrier/barrier_intra_k_dissemination.c \ + src/mpi/coll/barrier/barrier_intra_recexch.c \ src/mpi/coll/barrier/barrier_intra_smp.c \ src/mpi/coll/barrier/barrier_inter_bcast.c diff --git a/src/mpi/coll/barrier/barrier_intra_recexch.c b/src/mpi/coll/barrier/barrier_intra_recexch.c new file mode 100644 index 00000000000..47a04b57a2e --- /dev/null +++ b/src/mpi/coll/barrier/barrier_intra_recexch.c @@ -0,0 +1,25 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpiimpl.h" + + +/* Algorithm: call Allreduce's recursive exchange algorithm + */ +int MPIR_Barrier_intra_recexch(MPIR_Comm * comm, int k, int single_phase_recv, + MPIR_Errflag_t * errflag) +{ + int mpi_errno = MPI_SUCCESS; + + mpi_errno = MPIR_Allreduce_intra_recexch(MPI_IN_PLACE, NULL, 0, + MPI_BYTE, MPI_SUM, comm, + k, single_phase_recv, errflag); + MPIR_ERR_CHECK(mpi_errno); + + fn_exit: + return mpi_errno; + fn_fail: + goto fn_exit; +} diff --git a/src/mpi/coll/coll_algorithms.txt b/src/mpi/coll/coll_algorithms.txt index c3b61fcbb6e..95b4507390a 100644 --- a/src/mpi/coll/coll_algorithms.txt +++ b/src/mpi/coll/coll_algorithms.txt @@ -45,6 +45,9 @@ barrier-intra: k_dissemination extra_params: k cvar_params: DISSEM_KVAL + recexch + extra_params: k, single_phase_recv + cvar_params: RECEXCH_KVAL, RECEXCH_SINGLE_PHASE_RECV smp restrictions: parent-comm barrier-inter: diff --git a/src/mpi/coll/cvars.txt b/src/mpi/coll/cvars.txt index 921d217204e..bf8e04a94c8 100644 --- a/src/mpi/coll/cvars.txt +++ b/src/mpi/coll/cvars.txt @@ -21,6 +21,7 @@ cvars: smp - Force smp algorithm dissemination - Force dissemination algorithm k_dissemination - Force high radix dissemination algorithm + recexch - Force recursive exchange algorithm - name : MPIR_CVAR_BARRIER_INTER_ALGORITHM category : COLLECTIVE @@ -45,6 +46,27 @@ cvars: description : >- k value for dissemination exchange based barrier algorithm + - name : MPIR_CVAR_BARRIER_RECEXCH_KVAL + category : COLLECTIVE + type : int + default : 2 + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + k value for recursive exchange based allreduce based barrier + + - name : MPIR_CVAR_BARRIER_RECEXCH_SINGLE_PHASE_RECV + category : COLLECTIVE + type : boolean + default : false + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + This CVAR controls whether the recv is posted for one phase or two phases + in recexch algos. By default, we post the recvs for 2 phases. + - name : MPIR_CVAR_IBARRIER_RECEXCH_KVAL category : COLLECTIVE type : int diff --git a/src/mpi/coll/include/csel_container.h b/src/mpi/coll/include/csel_container.h index a23128838be..5b3a62ab4a3 100644 --- a/src/mpi/coll/include/csel_container.h +++ b/src/mpi/coll/include/csel_container.h @@ -46,6 +46,7 @@ typedef enum { MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Alltoallw_allcomm_nb, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Barrier_intra_dissemination, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Barrier_intra_k_dissemination, + MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Barrier_intra_recexch, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Barrier_intra_smp, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Barrier_inter_bcast, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Barrier_allcomm_nb, @@ -272,6 +273,10 @@ typedef struct { struct { int k; } intra_k_dissemination; + struct { + int k; + bool single_phase_recv; + } intra_recexch; } barrier; struct { struct { diff --git a/src/mpi/coll/src/csel_container.c b/src/mpi/coll/src/csel_container.c index 0cbd685c9e3..d88fd61122c 100644 --- a/src/mpi/coll/src/csel_container.c +++ b/src/mpi/coll/src/csel_container.c @@ -249,6 +249,17 @@ static void parse_container_params(struct json_object *obj, MPII_Csel_container_ } break; + case MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Barrier_intra_recexch: + { + json_object_object_foreach(obj, key, val) { + ckey = MPL_strdup_no_spaces(key); + if (!strncmp(ckey, "k=", strlen("k="))) + cnt->u.barrier.intra_recexch.k = atoi(ckey + strlen("k=")); + MPL_free(ckey); + } + } + break; + default: /* Algorithm does not have parameters */ break; @@ -337,6 +348,8 @@ void *MPII_Create_container(struct json_object *obj) cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Alltoallw_allcomm_nb; else if (!strcmp(ckey, "algorithm=MPIR_Barrier_intra_k_dissemination")) cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Barrier_intra_k_dissemination; + else if (!strcmp(ckey, "algorithm=MPIR_Barrier_intra_recexch")) + cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Barrier_intra_recexch; else if (!strcmp(ckey, "algorithm=MPIR_Barrier_intra_smp")) cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Barrier_intra_smp; else if (!strcmp(ckey, "algorithm=MPIR_Barrier_inter_bcast")) diff --git a/test/mpi/maint/coll_cvars.txt b/test/mpi/maint/coll_cvars.txt index a0758d2ff37..9432b104bd2 100644 --- a/test/mpi/maint/coll_cvars.txt +++ b/test/mpi/maint/coll_cvars.txt @@ -311,6 +311,9 @@ algorithms: dissemination k_dissemination .MPIR_CVAR_BARRIER_DISSEM_KVAL=2,3,4,8 + recexch + .MPIR_CVAR_BARRIER_RECEXCH_KVAL=2,3,4,8 + .MPIR_CVAR_BARRIER_RECEXCH_SINGLE_PHASE_RECV=0,1 intra-nonblocking: sched_recursive_doubling tsp_recexch From 7e03fe85444993a4182c08640d73d2a6d2d528cc Mon Sep 17 00:00:00 2001 From: Gengbin Zheng Date: Wed, 23 Feb 2022 22:27:08 -0600 Subject: [PATCH 523/607] coll: merge barrier dissemination to the high radix dissemination Make the optimized version of dissemination algorithm to be a special case of the high radix dissemination algorithm. --- maint/tuning/coll/mpir/generic.json | 4 +- src/include/mpir_coll.h | 2 + src/mpi/coll/barrier/Makefile.mk | 1 - .../barrier/barrier_intra_dissemination.c | 50 ------------------- .../barrier/barrier_intra_k_dissemination.c | 40 +++++++++++++++ src/mpi/coll/coll_algorithms.txt | 1 - src/mpi/coll/cvars.txt | 1 - src/mpi/coll/include/csel_container.h | 1 - test/mpi/maint/coll_cvars.txt | 1 - 9 files changed, 45 insertions(+), 56 deletions(-) delete mode 100644 src/mpi/coll/barrier/barrier_intra_dissemination.c diff --git a/maint/tuning/coll/mpir/generic.json b/maint/tuning/coll/mpir/generic.json index aab28224ba2..02b1bf36155 100644 --- a/maint/tuning/coll/mpir/generic.json +++ b/maint/tuning/coll/mpir/generic.json @@ -421,7 +421,9 @@ }, "comm_hierarchy=any": { - "algorithm=MPIR_Barrier_intra_dissemination":{} + "algorithm=MPIR_Barrier_intra_k_dissemination":{ + "k=2": {} + } } }, "comm_type=inter": diff --git a/src/include/mpir_coll.h b/src/include/mpir_coll.h index 9674c234dd8..49cb1cf3868 100644 --- a/src/include/mpir_coll.h +++ b/src/include/mpir_coll.h @@ -53,6 +53,8 @@ int MPIC_Waitall(int numreq, MPIR_Request * requests[], MPI_Status statuses[], int MPIR_Reduce_local(const void *inbuf, void *inoutbuf, MPI_Aint count, MPI_Datatype datatype, MPI_Op op); +int MPIR_Barrier_intra_dissemination(MPIR_Comm * comm_ptr, MPIR_Errflag_t * errflag); + /* TSP auto */ int MPIR_TSP_Iallreduce_sched_intra_tsp_auto(const void *sendbuf, void *recvbuf, MPI_Aint count, MPI_Datatype datatype, MPI_Op op, diff --git a/src/mpi/coll/barrier/Makefile.mk b/src/mpi/coll/barrier/Makefile.mk index b1842fb340f..082d1f0fac4 100644 --- a/src/mpi/coll/barrier/Makefile.mk +++ b/src/mpi/coll/barrier/Makefile.mk @@ -9,7 +9,6 @@ mpi_core_sources += \ src/mpi/coll/barrier/barrier_allcomm_nb.c \ - src/mpi/coll/barrier/barrier_intra_dissemination.c \ src/mpi/coll/barrier/barrier_intra_k_dissemination.c \ src/mpi/coll/barrier/barrier_intra_recexch.c \ src/mpi/coll/barrier/barrier_intra_smp.c \ diff --git a/src/mpi/coll/barrier/barrier_intra_dissemination.c b/src/mpi/coll/barrier/barrier_intra_dissemination.c deleted file mode 100644 index 8bfb4086693..00000000000 --- a/src/mpi/coll/barrier/barrier_intra_dissemination.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) by Argonne National Laboratory - * See COPYRIGHT in top-level directory - */ - -#include "mpiimpl.h" - -/* Algorithm: MPI_Barrier - * - * We use the dissemination algorithm described in: - * Debra Hensgen, Raphael Finkel, and Udi Manbet, "Two Algorithms for - * Barrier Synchronization," International Journal of Parallel - * Programming, 17(1):1-17, 1988. - * - * It uses ceiling(lgp) steps. In step k, 0 <= k <= (ceiling(lgp)-1), - * process i sends to process (i + 2^k) % p and receives from process - * (i - 2^k + p) % p. - */ -int MPIR_Barrier_intra_dissemination(MPIR_Comm * comm_ptr, MPIR_Errflag_t * errflag) -{ - int size, rank, src, dst, mask, mpi_errno = MPI_SUCCESS; - int mpi_errno_ret = MPI_SUCCESS; - - size = comm_ptr->local_size; - rank = comm_ptr->rank; - - mask = 0x1; - while (mask < size) { - dst = (rank + mask) % size; - src = (rank - mask + size) % size; - mpi_errno = MPIC_Sendrecv(NULL, 0, MPI_BYTE, dst, - MPIR_BARRIER_TAG, NULL, 0, MPI_BYTE, - src, MPIR_BARRIER_TAG, comm_ptr, MPI_STATUS_IGNORE, errflag); - if (mpi_errno) { - /* for communication errors, just record the error but continue */ - *errflag = - MPIX_ERR_PROC_FAILED == - MPIR_ERR_GET_CLASS(mpi_errno) ? MPIR_ERR_PROC_FAILED : MPIR_ERR_OTHER; - MPIR_ERR_SET(mpi_errno, *errflag, "**fail"); - MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); - } - mask <<= 1; - } - - if (mpi_errno_ret) - mpi_errno = mpi_errno_ret; - else if (*errflag != MPIR_ERR_NONE) - MPIR_ERR_SET(mpi_errno, *errflag, "**coll_fail"); - return mpi_errno; -} diff --git a/src/mpi/coll/barrier/barrier_intra_k_dissemination.c b/src/mpi/coll/barrier/barrier_intra_k_dissemination.c index f811d19412f..08860420029 100644 --- a/src/mpi/coll/barrier/barrier_intra_k_dissemination.c +++ b/src/mpi/coll/barrier/barrier_intra_k_dissemination.c @@ -5,6 +5,42 @@ #include "mpiimpl.h" +/* Algorithm: MPI_Barrier + * + * We use the dissemination algorithm described in: + * Debra Hensgen, Raphael Finkel, and Udi Manbet, "Two Algorithms for + * Barrier Synchronization," International Journal of Parallel + * Programming, 17(1):1-17, 1988. + * + * It uses ceiling(lgp) steps. In step k, 0 <= k <= (ceiling(lgp)-1), + * process i sends to process (i + 2^k) % p and receives from process + * (i - 2^k + p) % p. + */ +int MPIR_Barrier_intra_dissemination(MPIR_Comm * comm_ptr, MPIR_Errflag_t * errflag) +{ + int size, rank, src, dst, mask, mpi_errno = MPI_SUCCESS; + int mpi_errno_ret = MPI_SUCCESS; + + size = comm_ptr->local_size; + rank = comm_ptr->rank; + + mask = 0x1; + while (mask < size) { + dst = (rank + mask) % size; + src = (rank - mask + size) % size; + mpi_errno = MPIC_Sendrecv(NULL, 0, MPI_BYTE, dst, + MPIR_BARRIER_TAG, NULL, 0, MPI_BYTE, + src, MPIR_BARRIER_TAG, comm_ptr, MPI_STATUS_IGNORE, errflag); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); + mask <<= 1; + } + + if (mpi_errno_ret) + mpi_errno = mpi_errno_ret; + else if (*errflag != MPIR_ERR_NONE) + MPIR_ERR_SET(mpi_errno, *errflag, "**coll_fail"); + return mpi_errno; +} /* Algorithm: high radix dissemination * Similar to dissemination algorithm, but generalized with high radix k @@ -28,6 +64,10 @@ int MPIR_Barrier_intra_k_dissemination(MPIR_Comm * comm, int k, MPIR_Errflag_t * if (nranks < k) k = nranks; + if (k == 2) { + return MPIR_Barrier_intra_dissemination(comm, errflag); + } + /* If k value is greater than the maximum radix defined by MAX_RADIX macro, * we allocate memory for requests here. Otherwise we use the requests defined * in the communicator for allreduce/barrier recexch */ diff --git a/src/mpi/coll/coll_algorithms.txt b/src/mpi/coll/coll_algorithms.txt index 95b4507390a..d96fd7f76d3 100644 --- a/src/mpi/coll/coll_algorithms.txt +++ b/src/mpi/coll/coll_algorithms.txt @@ -41,7 +41,6 @@ # Some algorithm use another algorithm or use a different function name. barrier-intra: - dissemination k_dissemination extra_params: k cvar_params: DISSEM_KVAL diff --git a/src/mpi/coll/cvars.txt b/src/mpi/coll/cvars.txt index bf8e04a94c8..ecbb7ad4de1 100644 --- a/src/mpi/coll/cvars.txt +++ b/src/mpi/coll/cvars.txt @@ -19,7 +19,6 @@ cvars: auto - Internal algorithm selection (can be overridden with MPIR_CVAR_COLL_SELECTION_TUNING_JSON_FILE) nb - Force nonblocking algorithm smp - Force smp algorithm - dissemination - Force dissemination algorithm k_dissemination - Force high radix dissemination algorithm recexch - Force recursive exchange algorithm diff --git a/src/mpi/coll/include/csel_container.h b/src/mpi/coll/include/csel_container.h index 5b3a62ab4a3..73c4caf2f24 100644 --- a/src/mpi/coll/include/csel_container.h +++ b/src/mpi/coll/include/csel_container.h @@ -44,7 +44,6 @@ typedef enum { MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Alltoallw_intra_scattered, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Alltoallw_inter_pairwise_exchange, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Alltoallw_allcomm_nb, - MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Barrier_intra_dissemination, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Barrier_intra_k_dissemination, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Barrier_intra_recexch, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Barrier_intra_smp, diff --git a/test/mpi/maint/coll_cvars.txt b/test/mpi/maint/coll_cvars.txt index 9432b104bd2..0343be5aab5 100644 --- a/test/mpi/maint/coll_cvars.txt +++ b/test/mpi/maint/coll_cvars.txt @@ -308,7 +308,6 @@ algorithms: inter-nonblocking: sched_bcast intra-blocking: - dissemination k_dissemination .MPIR_CVAR_BARRIER_DISSEM_KVAL=2,3,4,8 recexch From 84f14ebe778f86f16aff6e29f602048f572c7015 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 28 Feb 2022 10:46:10 -0600 Subject: [PATCH 524/607] test: add generation of composition cvar tests Add special syntax "composition:x" to generate tests with setting CVAR to e.g. MPIR_CVAR_BCAST_COMPOSITION=x. --- test/mpi/maint/gen_coll_cvar.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/mpi/maint/gen_coll_cvar.py b/test/mpi/maint/gen_coll_cvar.py index 0e541a18d58..5b7cb474723 100644 --- a/test/mpi/maint/gen_coll_cvar.py +++ b/test/mpi/maint/gen_coll_cvar.py @@ -51,6 +51,8 @@ def dump_tests(Out, key, testlist, algos, algo_params, special=None): segs.append("env=MPIR_CVAR_%s_%s_ALGORITHM=nb" % (NAME, INTRA)) segs.append("env=MPIR_CVAR_I%s_DEVICE_COLLECTIVE=0" % NAME) segs.append("env=MPIR_CVAR_I%s_%s_ALGORITHM=%s" % (NAME, INTRA, algo)) + elif RE.match(r'composition:(\w+)', algo): + segs.append("env=MPIR_CVAR_%s_COMPOSITION=%s" % (NAME, RE.m.group(1))) elif RE.match(r'(\w+):(\w+)', algo): DEVICE = RE.m.group(1).upper() segs.append("env=MPIR_CVAR_%s_%s_%s_ALGORITHM=%s" % (NAME, DEVICE, INTRA, RE.m.group(2))) From 6c6412363f8829a939990628da57a9d7bc3ecc4a Mon Sep 17 00:00:00 2001 From: Taru Doodi Date: Mon, 28 Feb 2022 22:52:52 -0600 Subject: [PATCH 525/607] test: Add blocking composition CVARs for testing --- test/mpi/maint/coll_cvars.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/mpi/maint/coll_cvars.txt b/test/mpi/maint/coll_cvars.txt index 0343be5aab5..a371dd8b43b 100644 --- a/test/mpi/maint/coll_cvars.txt +++ b/test/mpi/maint/coll_cvars.txt @@ -179,6 +179,8 @@ algorithms: inter-nonblocking: sched_local_gather_remote_bcast intra-blocking: + composition:1 + composition:2 brucks k_brucks .MPIR_CVAR_ALLGATHER_BRUCKS_KVAL=2,3,4 @@ -221,6 +223,9 @@ algorithms: inter-nonblocking: sched_remote_reduce_local_bcast intra-blocking: + composition:1 + composition:2 + composition:3 smp recursive_doubling reduce_scatter_allgather @@ -255,6 +260,8 @@ algorithms: inter-nonblocking: sched_pairwise_exchange intra-blocking: + composition:1 + composition:2 brucks k_brucks .MPIR_CVAR_ALLTOALL_BRUCKS_KVAL=2,3,4 @@ -308,6 +315,8 @@ algorithms: inter-nonblocking: sched_bcast intra-blocking: + composition:1 + composition:2 k_dissemination .MPIR_CVAR_BARRIER_DISSEM_KVAL=2,3,4,8 recexch @@ -325,6 +334,9 @@ algorithms: inter-nonblocking: sched_flat intra-blocking: + composition:1 + composition:2 + composition:3 binomial smp scatter_recursive_doubling_allgather @@ -427,6 +439,9 @@ algorithms: inter-nonblocking: sched_local_reduce_remote_send intra-blocking: + composition:1 + composition:2 + composition:3 binomial smp reduce_scatter_gather From 42d9a8994a8c53fc8ba5bd409c6aef2bb479680e Mon Sep 17 00:00:00 2001 From: "Islam, Nusrat" Date: Fri, 27 Aug 2021 16:22:13 -0500 Subject: [PATCH 526/607] coll: change MPIR_TSP_sched_cb's prototype This commit changes the function signature of MPIR_TSP_sched_cb() to return mpi_errno instead of the vertex ID. --- src/mpi/coll/ibcast/ibcast_tsp_tree.c | 3 ++- src/mpi/coll/transports/gentran/tsp_gentran.c | 12 ++++++------ src/mpi/coll/transports/tsp_impl.h | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/mpi/coll/ibcast/ibcast_tsp_tree.c b/src/mpi/coll/ibcast/ibcast_tsp_tree.c index aad6b236a64..4bfbbc63f01 100644 --- a/src/mpi/coll/ibcast/ibcast_tsp_tree.c +++ b/src/mpi/coll/ibcast/ibcast_tsp_tree.c @@ -74,7 +74,8 @@ int MPIR_TSP_Ibcast_sched_intra_tree(void *buffer, MPI_Aint count, MPI_Datatype datatype, my_tree.parent, tag, comm, &ibcast_state->status, sched, 0, NULL, &recv_id); MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); - MPIR_TSP_sched_cb(&MPII_Ibcast_sched_test_length, ibcast_state, sched, 1, &recv_id); + MPIR_TSP_sched_cb(&MPII_Ibcast_sched_test_length, ibcast_state, sched, 1, &recv_id, + &vtx_id); #else mpi_errno = MPIR_TSP_sched_irecv((char *) buffer + offset * extent, msgsize, datatype, diff --git a/src/mpi/coll/transports/gentran/tsp_gentran.c b/src/mpi/coll/transports/gentran/tsp_gentran.c index 5d0e6f8faca..3b686d97969 100644 --- a/src/mpi/coll/transports/gentran/tsp_gentran.c +++ b/src/mpi/coll/transports/gentran/tsp_gentran.c @@ -430,24 +430,24 @@ int MPIR_TSP_sched_localcopy(const void *sendbuf, MPI_Aint sendcount, MPI_Dataty /* Transport function that adds a callback type vertex in the graph */ int MPIR_TSP_sched_cb(MPIR_TSP_cb_t cb_p, void *cb_data, MPIR_TSP_sched_t sched, - int n_in_vtcs, int *in_vtcs) + int n_in_vtcs, int *in_vtcs, int *vtx_id) { vtx_t *vtxp; - int vtx_id; + int mpi_errno = MPI_SUCCESS; /* assign a new vertex */ - vtx_id = MPII_Genutil_vtx_create(sched, &vtxp); + *vtx_id = MPII_Genutil_vtx_create(sched, &vtxp); vtxp->vtx_kind = MPII_GENUTIL_VTX_KIND__CB; - MPII_Genutil_vtx_add_dependencies(sched, vtx_id, n_in_vtcs, in_vtcs); + MPII_Genutil_vtx_add_dependencies(sched, *vtx_id, n_in_vtcs, in_vtcs); /* record the arguments */ vtxp->u.cb.cb_p = cb_p; vtxp->u.cb.cb_data = cb_data; - MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, (MPL_DBG_FDEST, "Gentran: schedule [%d] cb", vtx_id)); + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, (MPL_DBG_FDEST, "Gentran: schedule [%d] cb", *vtx_id)); - return vtx_id; + return mpi_errno; } /* Transport function that adds a no op vertex in the graph that has diff --git a/src/mpi/coll/transports/tsp_impl.h b/src/mpi/coll/transports/tsp_impl.h index 468b8a38754..4204637376e 100644 --- a/src/mpi/coll/transports/tsp_impl.h +++ b/src/mpi/coll/transports/tsp_impl.h @@ -102,7 +102,7 @@ int MPIR_TSP_sched_localcopy(const void *sendbuf, MPI_Aint sendcount, MPI_Dataty /* Transport function that adds a callback type vertex in the graph */ int MPIR_TSP_sched_cb(MPIR_TSP_cb_t cb_p, void *cb_data, MPIR_TSP_sched_t sched, - int n_in_vtcs, int *in_vtcs); + int n_in_vtcs, int *in_vtcs, int *vtx_id); /* Transport function to schedule a vertex that completes when all the incoming vertices have * completed */ From efb4262283155d6cee9e1f1e7a01ad56f0f17e92 Mon Sep 17 00:00:00 2001 From: "Islam, Nusrat" Date: Wed, 3 Nov 2021 14:42:21 -0500 Subject: [PATCH 527/607] posix: change the interval of release-gather wait --- src/mpid/ch4/shm/posix/posix_coll.h | 11 +++++++++++ .../ch4/shm/posix/release_gather/release_gather.h | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/mpid/ch4/shm/posix/posix_coll.h b/src/mpid/ch4/shm/posix/posix_coll.h index 032d4c349a5..18c197918aa 100644 --- a/src/mpid/ch4/shm/posix/posix_coll.h +++ b/src/mpid/ch4/shm/posix/posix_coll.h @@ -69,6 +69,17 @@ release_gather - Force shm optimized algo using release, gather primitives auto - Internal algorithm selection (can be overridden with MPIR_CVAR_CH4_POSIX_COLL_SELECTION_TUNING_JSON_FILE) + - name : MPIR_CVAR_POSIX_POLL_FREQUENCY + category : COLLECTIVE + type : int + default : 1000 + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + This cvar sets the number of loops before the yield function is called. A + value of 0 disables yielding. + === END_MPI_T_CVAR_INFO_BLOCK === */ diff --git a/src/mpid/ch4/shm/posix/release_gather/release_gather.h b/src/mpid/ch4/shm/posix/release_gather/release_gather.h index 861e0922b54..63c2a51a47e 100644 --- a/src/mpid/ch4/shm/posix/release_gather/release_gather.h +++ b/src/mpid/ch4/shm/posix/release_gather/release_gather.h @@ -20,7 +20,7 @@ extern MPIDI_POSIX_release_gather_tree_type_t MPIDI_POSIX_Bcast_tree_type, do { \ int spin_count = 0; \ while (MPL_atomic_acquire_load_uint64(ptr) < (value)) { \ - if (++spin_count >= 10000) { \ + if (++spin_count >= MPIR_CVAR_POSIX_POLL_FREQUENCY) { \ /* Call progress only after waiting for a while */ \ MPID_Progress_test(NULL); \ spin_count = 0; \ From d2300c0a5172f3f4ecda174ef869acc731ce384e Mon Sep 17 00:00:00 2001 From: "Islam, Nusrat" Date: Thu, 20 Jan 2022 16:02:23 -0600 Subject: [PATCH 528/607] ch4/shm: add a new tree type for shm This commit adds support for knomial-1 tree generation for posix collectives. --- src/mpi/errhan/errnames.txt | 1 + .../shm/posix/release_gather/release_gather.c | 37 +- src/mpid/ch4/shm/src/topotree.c | 447 ++++++++++++------ src/mpid/ch4/shm/src/topotree.h | 29 +- 4 files changed, 354 insertions(+), 160 deletions(-) diff --git a/src/mpi/errhan/errnames.txt b/src/mpi/errhan/errnames.txt index 4944c9b0458..b285f8658b2 100644 --- a/src/mpi/errhan/errnames.txt +++ b/src/mpi/errhan/errnames.txt @@ -228,6 +228,7 @@ MPI_TYPECLASS_INTEGER, or MPI_TYPECLASS_COMPLEX **invalidcollid: Invalid collective ID used. **sockaddrfailed: MPL_get_sockaddr failed +**nosupport: Algorithm selected is not supported. Please choose another algorithm **nomembind: hwloc_set_area_membind() is not available **invalidmembind: Invalid bind object identifier. **invalidmembind %d: cannot bind memory to object (%d). \ diff --git a/src/mpid/ch4/shm/posix/release_gather/release_gather.c b/src/mpid/ch4/shm/posix/release_gather/release_gather.c index d05c648975a..c9c321bab35 100644 --- a/src/mpid/ch4/shm/posix/release_gather/release_gather.c +++ b/src/mpid/ch4/shm/posix/release_gather/release_gather.c @@ -79,6 +79,7 @@ kary - kary tree type knomial_1 - knomial_1 tree type (ranks are added in order from the left side) knomial_2 - knomial_2 tree type (ranks are added in order from the right side) + knomial_2 is only supported with non topology aware trees. - name : MPIR_CVAR_REDUCE_INTRANODE_TREE_KVAL category : COLLECTIVE @@ -102,6 +103,7 @@ kary - kary tree type knomial_1 - knomial_1 tree type (ranks are added in order from the left side) knomial_2 - knomial_2 tree type (ranks are added in order from the right side) + knomial_2 is only supported with non topology aware trees. - name : MPIR_CVAR_ENABLE_INTRANODE_TOPOLOGY_AWARE_TREES category : COLLECTIVE @@ -125,8 +127,8 @@ order, first child to be added is the last one to be processed in traversal) The tree radix and tree type of package_leaders and per_package tree is MPIR_CVAR_BCAST{REDUCE}_INTRANODE_TREE_KVAL and MPIR_CVAR_BCAST{REDUCE}_INTRANODE_TREE_TYPE - respectively for bast and reduce. But of as now topology aware trees are only kary. knomial - is to be implemented. + respectively for bast and reduce. But of as now topology aware trees are only kary and knomial_1. + knomial_2 is not implemented. === END_MPI_T_CVAR_INFO_BLOCK === */ @@ -154,6 +156,7 @@ static int get_tree_type(const char *tree_type_name) /* Initialize the release_gather struct to NULL */ int MPIDI_POSIX_mpi_release_gather_comm_init_null(MPIR_Comm * comm_ptr) { + MPIR_FUNC_ENTER; RELEASE_GATHER_FIELD(comm_ptr, num_collective_calls) = 0; @@ -263,10 +266,19 @@ int MPIDI_POSIX_mpi_release_gather_comm_init(MPIR_Comm * comm_ptr, if ((tmp_shm_counter + memory_to_be_allocated) > (MPIR_CVAR_COLL_SHM_LIMIT_PER_NODE * 1024)) { /* cannot create more shm, fallback to MPIR level algorithms, and broadcast the decision to other ranks */ + if (MPIR_CVAR_COLLECTIVE_FALLBACK == MPIR_CVAR_COLLECTIVE_FALLBACK_print) { + fprintf(stderr, + "Intra-node collectives about to allocate more shared memory than \ + the specified limit through MPIR_CVAR_COLL_SHM_LIMIT_PER_NODE. Fallback \ + to other algorithms.\n"); + } + fallback = 1; MPIR_Bcast_impl(&fallback, 1, MPI_INT, 0, comm_ptr, &errflag); MPIR_ERR_SETANDJUMP(mpi_errno_ret, MPI_ERR_NO_MEM, "**nomem"); } else { + /* More shm can be created, update the shared counter */ + MPL_atomic_fetch_add_uint64(MPIDI_POSIX_shm_limit_counter, memory_to_be_allocated); fallback = 0; mpi_errno = MPIR_Bcast_impl(&fallback, 1, MPI_INT, 0, comm_ptr, &errflag); MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); @@ -296,9 +308,11 @@ int MPIDI_POSIX_mpi_release_gather_comm_init(MPIR_Comm * comm_ptr, mpi_errno = MPIDI_SHM_topology_tree_init(comm_ptr, 0, RELEASE_GATHER_FIELD(comm_ptr, bcast_tree_kval), + RELEASE_GATHER_FIELD(comm_ptr, bcast_tree_type), &release_gather_info_ptr->bcast_tree, &topotree_fail[0], RELEASE_GATHER_FIELD(comm_ptr, reduce_tree_kval), + RELEASE_GATHER_FIELD(comm_ptr, reduce_tree_type), &release_gather_info_ptr->reduce_tree, &topotree_fail[1], &errflag); MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); @@ -309,14 +323,7 @@ int MPIDI_POSIX_mpi_release_gather_comm_init(MPIR_Comm * comm_ptr, } mpi_errno = MPIR_Allreduce_impl(MPI_IN_PLACE, topotree_fail, 2, MPI_INT, MPI_MAX, comm_ptr, &errflag); - if (mpi_errno) { - /* for communication errors, just record the error but continue */ - errflag = - MPIX_ERR_PROC_FAILED == - MPIR_ERR_GET_CLASS(mpi_errno) ? MPIR_ERR_PROC_FAILED : MPIR_ERR_OTHER; - MPIR_ERR_SET(mpi_errno, errflag, "**fail"); - MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); - } + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); } else { topotree_fail[0] = -1; topotree_fail[1] = -1; @@ -343,6 +350,7 @@ int MPIDI_POSIX_mpi_release_gather_comm_init(MPIR_Comm * comm_ptr, RELEASE_GATHER_FIELD(comm_ptr, reduce_tree_kval), 0, &release_gather_info_ptr->reduce_tree); MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); + } release_gather_info_ptr->gather_state = release_gather_info_ptr->release_state = @@ -353,16 +361,14 @@ int MPIDI_POSIX_mpi_release_gather_comm_init(MPIR_Comm * comm_ptr, release_gather_info_ptr->reduce_buf_addr = NULL; release_gather_info_ptr->child_reduce_buf_addr = NULL; - RELEASE_GATHER_FIELD(comm_ptr, flags_shm_size) = flags_shm_size; - /* update the shared counter */ - if (rank == 0) - MPL_atomic_fetch_add_uint64(MPIDI_POSIX_shm_limit_counter, flags_shm_size); mpi_errno = MPIDU_shm_alloc(comm_ptr, flags_shm_size, (void **) &(release_gather_info_ptr->flags_addr), &mapfail_flag); - if (mapfail_flag) { + if (mpi_errno || mapfail_flag) { + /* for communication errors, just record the error but continue */ MPIR_ERR_ADD(mpi_errno_ret, MPIR_ERR_OTHER); } + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno_ret, errflag); MPIR_ERR_CHECK(mpi_errno_ret); @@ -412,6 +418,7 @@ int MPIDI_POSIX_mpi_release_gather_comm_init(MPIR_Comm * comm_ptr, (void **) &(RELEASE_GATHER_FIELD(comm_ptr, reduce_buf_addr)), &mapfail_flag); if (mapfail_flag) { + /* for communication errors, just record the error but continue */ MPIR_ERR_ADD(mpi_errno_ret, MPIR_ERR_OTHER); } MPIR_ERR_COLL_CHECKANDCONT(mpi_errno_ret, errflag); diff --git a/src/mpid/ch4/shm/src/topotree.c b/src/mpid/ch4/shm/src/topotree.c index faec5f4a97a..e2ede277940 100644 --- a/src/mpid/ch4/shm/src/topotree.c +++ b/src/mpid/ch4/shm/src/topotree.c @@ -11,74 +11,132 @@ #include -#define MAX_TOPO_DEPTH 7 - -static int create_template_tree(MPIDI_SHM_topotree_t * template_tree, int k_val, - bool right_skewed, int max_ranks, MPIR_Errflag_t * eflag); - -static void copy_tree(int *shared_region, int num_ranks, int rank, - MPIR_Treealgo_tree_t * my_tree, int *topotree_fail); - -static int topotree_get_package_level(int *num_packages, int num_ranks, int *bind_map); - -static void gen_package_tree(int num_packages, int k_val, MPIDI_SHM_topotree_t * package_tree, - int *package_leaders); - -static void gen_tree_sharedmemory(int *shared_region, MPIDI_SHM_topotree_t * tree, - MPIDI_SHM_topotree_t * package_tree, int *package_leaders, - int num_packages, int num_ranks, int k_val, - bool package_leaders_first); - -static int gen_tree(int k_val, int *shared_region, int num_packages, - int **ranks_per_package, int max_ranks_per_package, int *package_ctr, - int package_level, int num_ranks, bool package_leaders_first, - bool right_skewed, MPIR_Errflag_t * eflag); - -/* This function allocates and generates a template_tree based on k_val and right_skewed for - * max_ranks. +/* This function allocates and generates a template_tree based on k_val, tree_type, and + * skewness for max_ranks. * */ -static int create_template_tree(MPIDI_SHM_topotree_t * template_tree, int k_val, - bool right_skewed, int max_ranks, MPIR_Errflag_t * errflag) +int MPIDI_SHM_create_template_tree(MPIDI_SHM_topotree_t * template_tree, int k_val, int tree_type, + bool right_skewed, int max_ranks, MPIR_Errflag_t * errflag) { int mpi_errno = MPI_SUCCESS, mpi_errno_ret ATTRIBUTE((unused)) = MPI_SUCCESS; - int child_id, child_idx; + int i, j, child_id, child_idx; mpi_errno = MPIDI_SHM_topotree_allocate(template_tree, max_ranks, k_val); MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); - for (int i = 0; i < max_ranks; ++i) { - MPIDI_SHM_TOPOTREE_PARENT(template_tree, i) = ceilf(i / (float) (k_val)) - 1; - MPIDI_SHM_TOPOTREE_NUM_CHILD(template_tree, i) = 0; - if (!right_skewed) { - for (int j = 0; j < k_val; ++j) { - child_id = i * k_val + 1 + j; - if (child_id < max_ranks) { - child_idx = MPIDI_SHM_TOPOTREE_NUM_CHILD(template_tree, i)++; - MPIDI_SHM_TOPOTREE_CHILD(template_tree, i, child_idx) = child_id; + if (tree_type == MPIDI_POSIX_RELEASE_GATHER_TREE_TYPE_KARY) { + /* Notice that skewness matters only for kary trees */ + for (i = 0; i < max_ranks; ++i) { + MPIDI_SHM_TOPOTREE_PARENT(template_tree, i) = ceilf(i / (float) (k_val)) - 1; + MPIDI_SHM_TOPOTREE_NUM_CHILD(template_tree, i) = 0; + if (!right_skewed) { + for (j = 0; j < k_val; ++j) { + child_id = i * k_val + 1 + j; + if (child_id < max_ranks) { + child_idx = MPIDI_SHM_TOPOTREE_NUM_CHILD(template_tree, i)++; + MPIDI_SHM_TOPOTREE_CHILD(template_tree, i, child_idx) = child_id; + } + } + } else if (right_skewed) { + for (j = k_val - 1; j >= 0; --j) { + child_id = i * k_val + 1 + j; + if (child_id < max_ranks) { + child_idx = MPIDI_SHM_TOPOTREE_NUM_CHILD(template_tree, i)++; + MPIDI_SHM_TOPOTREE_CHILD(template_tree, i, child_idx) = child_id; + } } } - } else if (right_skewed) { - for (int j = k_val - 1; j >= 0; --j) { - child_id = i * k_val + 1 + j; - if (child_id < max_ranks) { - child_idx = MPIDI_SHM_TOPOTREE_NUM_CHILD(template_tree, i)++; - MPIDI_SHM_TOPOTREE_CHILD(template_tree, i, child_idx) = child_id; + } + } else { + /* Handle knomial_2 tree case, as it is not implemented */ + if (tree_type == MPIDI_POSIX_RELEASE_GATHER_TREE_TYPE_KNOMIAL_2) { + if (MPIR_CVAR_COLLECTIVE_FALLBACK == MPIR_CVAR_COLLECTIVE_FALLBACK_error) { + /* No fallback */ + MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**nosupport"); + } else if (MPIR_CVAR_COLLECTIVE_FALLBACK == MPIR_CVAR_COLLECTIVE_FALLBACK_print) { + /* Fallback with print */ + fprintf(stderr, "Intra-node topology aware trees does not have support for \ + knomial_2 trees. Falling back to knomial_1 trees.\n"); + } + } + /* Generate knomial_1 tree */ + int crank, rank, tmp; + int maxtime = 0; + const int root = 0; + for (tmp = max_ranks - 1; tmp; tmp /= k_val) + maxtime++; + for (rank = 0; rank < max_ranks; ++rank) { + int lrank = (rank + (max_ranks - root)) % max_ranks; + int time = 0; + int parent = -1; /* root has no parent */ + int current_rank = 0; /* start at root of the tree */ + int running_rank = current_rank + 1; + + for (time = 0;; time++) { + /* desired rank found */ + if (lrank == current_rank) + break; + /* check if rank lies in this range */ + for (j = 1; j < k_val; j++) { + if (lrank >= running_rank && + lrank < running_rank + pow(k_val, maxtime - time - 1)) { + /* move to the corresponding subtree */ + parent = current_rank; + current_rank = running_rank; + running_rank = current_rank + 1; + break; + } + running_rank += pow(k_val, maxtime - time - 1); + } + } + parent = parent == -1 ? -1 : (parent + root) % max_ranks; + /* set the children */ + crank = lrank + 1; /* crank stands for child rank */ + for (i = time; i < maxtime; i++) { + for (j = 1; j < k_val; j++) { + if (crank < max_ranks) { + child_idx = MPIDI_SHM_TOPOTREE_NUM_CHILD(template_tree, rank)++; + child_id = (crank + root) % max_ranks; + MPIDI_SHM_TOPOTREE_CHILD(template_tree, rank, child_idx) = child_id; + MPIDI_SHM_TOPOTREE_PARENT(template_tree, child_id) = rank; + if (MPIDI_SHM_TOPOTREE_DEBUG) + fprintf(stderr, "Rank=%d, AddChild=%d, Index=%d\n", rank, + (crank + root) % max_ranks, child_idx); + } + crank += pow(k_val, maxtime - i - 1); } } } } + /* Mark the parent of root (rank 0) as -1 */ MPIDI_SHM_TOPOTREE_PARENT(template_tree, 0) = -1; + if (MPIDI_SHM_TOPOTREE_DEBUG) { + fprintf(stderr, "TemplateTree, %d\n", max_ranks); + MPIDI_SHM_print_topotree("TemplateTree", template_tree); + for (i = 0; i < max_ranks; ++i) { + fprintf(stderr, "TemplateR, %d, P=%d, C=%d, [", i, + MPIDI_SHM_TOPOTREE_PARENT(template_tree, i), + MPIDI_SHM_TOPOTREE_NUM_CHILD(template_tree, i)); + for (j = 0; j < MPIDI_SHM_TOPOTREE_NUM_CHILD(template_tree, i); ++j) { + fprintf(stderr, "%d, ", MPIDI_SHM_TOPOTREE_CHILD(template_tree, i, j)); + } + fprintf(stderr, "]\n"); + } + } /* template tree is ready here */ + + fn_exit: return mpi_errno; + fn_fail: + goto fn_exit; } /* This function copies the tree present in shared_region into the my_tree data structure for rank. * Doesn't perform any direct allocation, but utarray_new is called to allocate space for children * in my_tree. * */ -static void copy_tree(int *shared_region, int num_ranks, int rank, - MPIR_Treealgo_tree_t * my_tree, int *topotree_fail) +void MPIDI_SHM_copy_tree(int *shared_region, int num_ranks, int rank, + MPIR_Treealgo_tree_t * my_tree, int *topotree_fail) { int *parent_ptr = shared_region; int *child_ctr = &shared_region[num_ranks]; @@ -93,56 +151,74 @@ static void copy_tree(int *shared_region, int num_ranks, int rank, my_tree->rank = rank; my_tree->nranks = num_ranks; utarray_new(my_tree->children, &ut_int_icd, MPL_MEM_COLL); + MPIR_Assert(my_tree->children); utarray_reserve(my_tree->children, num_children, MPL_MEM_COLL); + char str[1024], tmp[128]; + sprintf(str, "----**Rank %d, Parent, %d, Child(%d)[", rank, parent, num_children); for (int c = 0; c < num_children; ++c) { utarray_push_back(my_tree->children, &my_children[c], MPL_MEM_COLL); if (my_children[c] == 0) { *topotree_fail = 1; } + sprintf(tmp, "%d, ", my_children[c]); + strcat(str, tmp); my_tree->num_children++; } + if (MPIDI_SHM_TOPOTREE_DEBUG) + fprintf(stderr, "%s]\n", str); } /* This function returns the topology level where we will break the tree into a package_leaders * and a per_package tree. If needed MPIDI_SHM_TOPOTREE_CUTOFF can be modified to the level where this cutoff - * should happen. Note, this function also output num_packages at the package_level + * should happen. Note, this function also fills out max_entries_per_level, which is needed in other * functions. * */ -int topotree_get_package_level(int *num_packages, int num_ranks, int *bind_map) +int MPIDI_SHM_topotree_get_package_level(int topo_depth, int *max_entries_per_level, int num_ranks, + int **bind_map) { - int package_level; - int max_entries_per_level[MAX_TOPO_DEPTH]; - - for (int lvl = 0; lvl < MAX_TOPO_DEPTH; ++lvl) { - int max = -1; - for (int i = 0; i < num_ranks; ++i) { - max = MPL_MAX(max, bind_map[i * MAX_TOPO_DEPTH + lvl] + 1); + int lvl, i, socket_level; + + for (lvl = 0; lvl < topo_depth; ++lvl) { + max_entries_per_level[lvl] = -1; + for (i = 0; i < num_ranks; ++i) { + max_entries_per_level[lvl] = + (max_entries_per_level[lvl] > + bind_map[i][lvl] + 1) ? max_entries_per_level[lvl] : bind_map[i][lvl] + 1; } - max_entries_per_level[lvl] = max; } - /* set package_level to first level that is more than one entries, or leave at level 0 */ - package_level = 0; - for (int i = 0; i < MAX_TOPO_DEPTH; i++) { - if (max_entries_per_level[i] > 1) { - package_level = i; - break; + /* STEP 3.3. Determine the package level based on first level (top-down) with #nodes >1 */ + socket_level = topo_depth; + { + for (i = topo_depth - 1; i >= 0; --i) { + if (max_entries_per_level[i] > 1) { + socket_level = i; + break; + } } + } - if (MPIDI_SHM_TOPOTREE_CUTOFF >= 0) { - package_level = MPIDI_SHM_TOPOTREE_CUTOFF; - } - *num_packages = max_entries_per_level[package_level]; - return package_level; + /* indicates the package level in topology */ + if (MPIDI_SHM_TOPOTREE_DEBUG) + fprintf(stderr, "Max entries per level :: %d\n", max_entries_per_level[socket_level]); + + return (MPIDI_SHM_TOPOTREE_CUTOFF == -1) ? socket_level : MPIDI_SHM_TOPOTREE_CUTOFF; } /* This function generates a package level tree using the package leaders and k_val. * */ -void gen_package_tree(int num_packages, int k_val, MPIDI_SHM_topotree_t * package_tree, - int *package_leaders) +void MPIDI_SHM_gen_package_tree(int num_packages, int k_val, bool right_skewed, + MPIDI_SHM_topotree_t * package_tree, int *package_leaders) { - int parent_idx, child_id, idx; + int i, j, parent_idx, child_id, idx; + if (MPIDI_SHM_TOPOTREE_DEBUG) { + fprintf(stderr, "Package_leaders:["); + for (i = 0; i < num_packages; ++i) { + fprintf(stderr, "%d, ", package_leaders[i]); + } + fprintf(stderr, "]\n"); + } /* Generate a package (top-level) tree */ - for (int i = 0; i < num_packages; ++i) { + for (i = 0; i < num_packages; ++i) { if (i == 0) { MPIDI_SHM_TOPOTREE_PARENT(package_tree, i) = -1; } else { @@ -150,32 +226,46 @@ void gen_package_tree(int num_packages, int k_val, MPIDI_SHM_topotree_t * packag MPIDI_SHM_TOPOTREE_PARENT(package_tree, i) = package_leaders[parent_idx]; } MPIDI_SHM_TOPOTREE_NUM_CHILD(package_tree, i) = 0; - for (int j = 0; j < k_val; ++j) { - child_id = i * k_val + 1 + j; - if (child_id < num_packages && package_leaders[child_id] != -1) { - idx = MPIDI_SHM_TOPOTREE_NUM_CHILD(package_tree, i)++; - MPIDI_SHM_TOPOTREE_CHILD(package_tree, i, idx) = package_leaders[child_id]; + if (!right_skewed) { + for (j = 0; j < k_val; ++j) { + child_id = i * k_val + 1 + j; + if (child_id < num_packages && package_leaders[child_id] != -1) { + idx = MPIDI_SHM_TOPOTREE_NUM_CHILD(package_tree, i)++; + MPIDI_SHM_TOPOTREE_CHILD(package_tree, i, idx) = package_leaders[child_id]; + } + } + } else { + for (j = k_val - 1; j >= 0; --j) { + child_id = i * k_val + 1 + j; + if (child_id < num_packages && package_leaders[child_id] != -1) { + idx = MPIDI_SHM_TOPOTREE_NUM_CHILD(package_tree, i)++; + MPIDI_SHM_TOPOTREE_CHILD(package_tree, i, idx) = package_leaders[child_id]; + } } } } + if (MPIDI_SHM_TOPOTREE_DEBUG) { + fprintf(stderr, "PackageTree for %d packages\n", num_packages); + MPIDI_SHM_print_topotree("Package", package_tree); + } } /* This function assembles the package leaders tree and per package tree into a single tree in * shared memory. * */ -static void gen_tree_sharedmemory(int *shared_region, MPIDI_SHM_topotree_t * tree, - MPIDI_SHM_topotree_t * package_tree, int *package_leaders, - int num_packages, int num_ranks, int k_val, - bool package_leaders_first) +void MPIDI_SHM_gen_tree_sharedmemory(int *shared_region, MPIDI_SHM_topotree_t * tree, + MPIDI_SHM_topotree_t * package_tree, int *package_leaders, + int num_packages, int num_ranks, int k_val, + bool package_leaders_first) { - int is_package_leader; + int i, pm, j, is_package_leader; int *parent_ptr = shared_region; int *child_ctr = &shared_region[num_ranks]; int *children = &shared_region[num_ranks + num_ranks + 1]; memset(shared_region, 0, sizeof(int) * (3 * num_ranks) + 1); child_ctr[0] = 0; - for (int i = 0; i < num_ranks; ++i) { + for (i = 0; i < num_ranks; ++i) { parent_ptr[i] = i == 0 ? -1 : MPIDI_SHM_TOPOTREE_PARENT(tree, i); child_ctr[i + 1] = child_ctr[i]; /* Package last as 0 means package leaders are added first before adding the per-package @@ -183,14 +273,13 @@ static void gen_tree_sharedmemory(int *shared_region, MPIDI_SHM_topotree_t * tre if (package_leaders_first) { /* Add children for package leaders */ is_package_leader = -1; - for (int pm = 0; pm < num_packages; ++pm) { + for (pm = 0; pm < num_packages; ++pm) { if (i == package_leaders[pm]) { is_package_leader = pm; } } if (is_package_leader != -1) { - for (int j = 0; j < MPIDI_SHM_TOPOTREE_NUM_CHILD(package_tree, is_package_leader); - ++j) { + for (j = 0; j < MPIDI_SHM_TOPOTREE_NUM_CHILD(package_tree, is_package_leader); ++j) { children[child_ctr[i + 1]] = MPIDI_SHM_TOPOTREE_CHILD(package_tree, is_package_leader, j); child_ctr[i + 1]++; @@ -199,7 +288,7 @@ static void gen_tree_sharedmemory(int *shared_region, MPIDI_SHM_topotree_t * tre } } - for (int j = 0; j < MPIDI_SHM_TOPOTREE_NUM_CHILD(tree, i); ++j) { + for (j = 0; j < MPIDI_SHM_TOPOTREE_NUM_CHILD(tree, i); ++j) { children[child_ctr[i + 1]] = MPIDI_SHM_TOPOTREE_CHILD(tree, i, j); child_ctr[i + 1]++; } @@ -209,14 +298,13 @@ static void gen_tree_sharedmemory(int *shared_region, MPIDI_SHM_topotree_t * tre if (!package_leaders_first) { /* Add children for package leaders */ is_package_leader = -1; - for (int pm = 0; pm < num_packages; ++pm) { + for (pm = 0; pm < num_packages; ++pm) { if (i == package_leaders[pm]) { is_package_leader = pm; } } if (is_package_leader != -1) { - for (int j = 0; j < MPIDI_SHM_TOPOTREE_NUM_CHILD(package_tree, is_package_leader); - ++j) { + for (j = 0; j < MPIDI_SHM_TOPOTREE_NUM_CHILD(package_tree, is_package_leader); ++j) { children[child_ctr[i + 1]] = MPIDI_SHM_TOPOTREE_CHILD(package_tree, is_package_leader, j); child_ctr[i + 1]++; @@ -225,26 +313,38 @@ static void gen_tree_sharedmemory(int *shared_region, MPIDI_SHM_topotree_t * tre } } } + + if (MPIDI_SHM_TOPOTREE_DEBUG) { + for (i = 0; i < num_ranks; ++i) { + fprintf(stderr, "SRank, %d, Parent, %d, Children(%d)[", i, parent_ptr[i], + child_ctr[i + 1] - child_ctr[i]); + for (j = child_ctr[i]; j < child_ctr[i + 1]; ++j) { + fprintf(stderr, "%d, ", children[j]); + } + fprintf(stderr, "]\n"); + } + } } /* This is the main function which generates a tree in shared memory. The tree is parameterized * over the different data-structures: * k_val : the tree K-value * shared_region : the shared memory region where the tree will be generated - * num_packages : the maximum number of packages at package_level + * max_entries_per_level : the maximum number of ranks per level * ranks_per_package : the different ranks at each level * max_ranks_per_package : the maximum ranks in any package * package_ctr : number of ranks in each package * package_level : the topology level where we cutoff the tree * num_ranks : the number of ranks * */ -static int gen_tree(int k_val, int *shared_region, int num_packages, - int **ranks_per_package, int max_ranks_per_package, int *package_ctr, - int package_level, int num_ranks, bool package_leaders_first, - bool right_skewed, MPIR_Errflag_t * errflag) +int MPIDI_SHM_gen_tree(int k_val, int *shared_region, int *max_entries_per_level, + int **ranks_per_package, int max_ranks_per_package, int *package_ctr, + int package_level, int num_ranks, bool package_leaders_first, + bool right_skewed, int tree_type, MPIR_Errflag_t * errflag) { int mpi_errno = MPI_SUCCESS, mpi_errno_ret ATTRIBUTE((unused)) = MPI_SUCCESS; - int rank, idx; + int i, j, p, r, rank, idx; + int num_packages = max_entries_per_level[package_level]; int package_count = 0; MPIDI_SHM_topotree_t package_tree, tree, template_tree; const int package_tree_sz = num_packages > num_ranks ? num_packages : num_ranks; @@ -260,9 +360,10 @@ static int gen_tree(int k_val, int *shared_region, int num_packages, MPIR_CHKPMEM_CALLOC(package_leaders, int *, num_packages * sizeof(int), mpi_errno, "intra_node_package_leaders", MPL_MEM_OTHER); + MPIR_ERR_CHKANDJUMP(!package_leaders, mpi_errno, MPI_ERR_OTHER, "**nomem"); /* We pick package leaders as the first rank in each package */ - for (int p = 0; p < num_packages; ++p) { + for (p = 0; p < max_entries_per_level[package_level]; ++p) { package_leaders[p] = -1; if (package_ctr[p] > 0) { package_leaders[package_count++] = ranks_per_package[p][0]; @@ -271,23 +372,39 @@ static int gen_tree(int k_val, int *shared_region, int num_packages, num_packages = package_count; /* STEP 4. Now use the template tree to generate the top level tree */ - gen_package_tree(num_packages, k_val, &package_tree, package_leaders); + MPIDI_SHM_gen_package_tree(num_packages, k_val, right_skewed, &package_tree, package_leaders); /* STEP 5. Create a template tree for the ranks */ - mpi_errno = create_template_tree(&template_tree, k_val, right_skewed, - max_ranks_per_package, errflag); + mpi_errno = + MPIDI_SHM_create_template_tree(&template_tree, k_val, tree_type, right_skewed, + max_ranks_per_package, errflag); MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); + if (MPIDI_SHM_TOPOTREE_DEBUG) { + for (i = 0; i < max_entries_per_level[package_level]; ++i) { + fprintf(stderr, "pre-Rank %d, parent %d, children=%d [", i, + MPIDI_SHM_TOPOTREE_PARENT(&tree, i), MPIDI_SHM_TOPOTREE_NUM_CHILD(&tree, i)); + for (j = 0; j < MPIDI_SHM_TOPOTREE_NUM_CHILD(&tree, i); ++j) { + fprintf(stderr, "%d, ", MPIDI_SHM_TOPOTREE_CHILD(&tree, i, j)); + } + fprintf(stderr, "]\n"); + } + } + /* use the template tree to generate the tree for each rank */ - for (int p = 0; p < num_packages; ++p) { - for (int r = 0; r < package_ctr[p]; ++r) { + for (p = 0; p < max_entries_per_level[package_level]; ++p) { + for (r = 0; r < package_ctr[p]; ++r) { rank = ranks_per_package[p][r]; + if (MPIDI_SHM_TOPOTREE_DEBUG) + fprintf(stderr, "Rank=%d, p=%d, r=%d, opt1=%d, opt2=%d\n", rank, p, r, + MPIDI_SHM_TOPOTREE_PARENT(&template_tree, r), + ranks_per_package[p][MPIDI_SHM_TOPOTREE_PARENT(&template_tree, r)]); if (MPIDI_SHM_TOPOTREE_PARENT(&template_tree, r) == -1) { MPIDI_SHM_TOPOTREE_PARENT(&tree, rank) = -1; } else { MPIDI_SHM_TOPOTREE_PARENT(&tree, rank) = ranks_per_package[p][MPIDI_SHM_TOPOTREE_PARENT(&template_tree, r)]; } - for (int j = 0; j < MPIDI_SHM_TOPOTREE_NUM_CHILD(&template_tree, r); ++j) { + for (j = 0; j < MPIDI_SHM_TOPOTREE_NUM_CHILD(&template_tree, r); ++j) { idx = MPIDI_SHM_TOPOTREE_NUM_CHILD(&tree, rank); if (MPIDI_SHM_TOPOTREE_CHILD(&template_tree, r, j) < package_ctr[p]) { MPIDI_SHM_TOPOTREE_NUM_CHILD(&tree, rank)++; @@ -297,9 +414,21 @@ static int gen_tree(int k_val, int *shared_region, int num_packages, } } } + if (MPIDI_SHM_TOPOTREE_DEBUG) { + char str[1024], tmp[128]; + for (i = 0; i < num_ranks; ++i) { + sprintf(str, "*BaseTreeRank %d, parent %d, children=%d [", i, + MPIDI_SHM_TOPOTREE_PARENT(&tree, i), MPIDI_SHM_TOPOTREE_NUM_CHILD(&tree, i)); + for (j = 0; j < MPIDI_SHM_TOPOTREE_NUM_CHILD(&tree, i); ++j) { + sprintf(tmp, "%d, ", MPIDI_SHM_TOPOTREE_CHILD(&tree, i, j)); + strcat(str, tmp); + } + fprintf(stderr, "%s]\n", str); + } + } /* Assemble the per package tree package leaders tree and copy it to shared memory region */ - gen_tree_sharedmemory(shared_region, &tree, &package_tree, package_leaders, - num_packages, num_ranks, k_val, package_leaders_first); + MPIDI_SHM_gen_tree_sharedmemory(shared_region, &tree, &package_tree, package_leaders, + num_packages, num_ranks, k_val, package_leaders_first); MPL_free(tree.base); MPL_free(package_tree.base); MPL_free(template_tree.base); @@ -316,18 +445,22 @@ static int gen_tree(int k_val, int *shared_region, int num_packages, * information, builds a package-level tree (for package leaders), and a per-package tree. * These are combined in shared memory for other ranks to read out from. * */ -int MPIDI_SHM_topology_tree_init(MPIR_Comm * comm_ptr, int root, int bcast_k, +int MPIDI_SHM_topology_tree_init(MPIR_Comm * comm_ptr, int root, int bcast_k, int bcast_tree_type, MPIR_Treealgo_tree_t * bcast_tree, int *bcast_topotree_fail, - int reduce_k, MPIR_Treealgo_tree_t * reduce_tree, - int *reduce_topotree_fail, MPIR_Errflag_t * errflag) + int reduce_k, int reduce_tree_type, + MPIR_Treealgo_tree_t * reduce_tree, int *reduce_topotree_fail, + MPIR_Errflag_t * errflag) { int *shared_region; int num_ranks, rank; - int mpi_errno = MPI_SUCCESS, mpi_errno_ret = MPI_SUCCESS; + int mpi_errno = MPI_SUCCESS, mpi_errno_ret ATTRIBUTE((unused)) = MPI_SUCCESS; size_t shm_size; + int **bind_map = NULL; + int *max_entries_per_level = NULL; int **ranks_per_package = NULL; int *package_ctr = NULL; - int package_level = 0, max_ranks_per_package = 0; + size_t topo_depth = 0; + int package_level = 0, i, max_ranks_per_package = 0; bool mapfail_flag = false; MPIR_FUNC_ENTER; @@ -335,56 +468,70 @@ int MPIDI_SHM_topology_tree_init(MPIR_Comm * comm_ptr, int root, int bcast_k, num_ranks = MPIR_Comm_size(comm_ptr); rank = MPIR_Comm_rank(comm_ptr); - /* FIXME: explain the magic number 5? */ - shm_size = sizeof(int) * MAX_TOPO_DEPTH * num_ranks + sizeof(int) * 5 * num_ranks; + /* Calculate the size of shared memory that would be needed */ + MPIR_hwtopo_gid_t gid = MPIR_hwtopo_get_leaf(); + topo_depth = MPIR_hwtopo_get_depth(gid) + 1; + shm_size = sizeof(int) * topo_depth * num_ranks + sizeof(int) * 5 * num_ranks; /* STEP 1. Create shared memory region for exchanging topology information (root only) */ mpi_errno = MPIDU_shm_alloc(comm_ptr, shm_size, (void **) &shared_region, &mapfail_flag); - if (mapfail_flag) { - MPIR_ERR_ADD(mpi_errno_ret, MPI_ERR_OTHER); + if (mpi_errno || mapfail_flag) { + /* for communication errors, just record the error but continue */ + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); } - MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); /* STEP 2. Every process fills affinity information in shared_region */ - MPIR_hwtopo_gid_t gid = MPIR_hwtopo_get_leaf(); - int topo_depth = MPIR_hwtopo_get_depth(gid) + 1; - for (int depth = 0; depth < MAX_TOPO_DEPTH; depth++) { - if (depth < topo_depth) { - gid = MPIR_hwtopo_get_ancestor(gid, depth); - shared_region[rank * MAX_TOPO_DEPTH + depth] = MPIR_hwtopo_get_lid(gid); - } else { - shared_region[rank * MAX_TOPO_DEPTH + depth] = 0; - } + int (*shared_region_ptr)[topo_depth] = (int (*)[topo_depth]) shared_region; + int depth = 0; + while (depth < topo_depth) { + shared_region_ptr[rank][depth++] = MPIR_hwtopo_get_lid(gid); + gid = MPIR_hwtopo_get_ancestor(gid, topo_depth - depth - 1); } mpi_errno = MPIR_Barrier_impl(comm_ptr, errflag); MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); + /* STEP 3. Root has all the bind_map information, now build tree */ - int num_packages = 0; /* init to avoid -Wmaybe-uninitialized */ if (rank == root) { - int *bind_map = shared_region; + bind_map = (int **) MPL_malloc(num_ranks * sizeof(int *), MPL_MEM_OTHER); + MPIR_ERR_CHKANDJUMP(!bind_map, mpi_errno, MPI_ERR_OTHER, "**nomem"); + for (i = 0; i < num_ranks; ++i) { + bind_map[i] = (int *) MPL_calloc(topo_depth, sizeof(int), MPL_MEM_OTHER); + MPIR_ERR_CHKANDJUMP(!bind_map[i], mpi_errno, MPI_ERR_OTHER, "**nomem"); + MPIR_Memcpy(bind_map[i], shared_region_ptr[i], topo_depth * sizeof(int)); + } /* Done building the topology information */ /* STEP 3.1. Count the maximum entries at each level - used for breaking the tree into * intra/inter socket */ - package_level = topotree_get_package_level(&num_packages, num_ranks, bind_map); + max_entries_per_level = (int *) MPL_calloc(topo_depth, sizeof(size_t), MPL_MEM_OTHER); + MPIR_ERR_CHKANDJUMP(!max_entries_per_level, mpi_errno, MPI_ERR_OTHER, "**nomem"); + package_level = + MPIDI_SHM_topotree_get_package_level(topo_depth, max_entries_per_level, num_ranks, + bind_map); + if (MPIDI_SHM_TOPOTREE_DEBUG) + fprintf(stderr, "Breaking topology at :: %d (default= %d)\n", package_level, + MPIDI_SHM_TOPOTREE_CUTOFF); /* STEP 3.2. allocate space for the entries that go in each package based on topology info */ - ranks_per_package = (int **) MPL_malloc(num_packages * sizeof(int *), MPL_MEM_OTHER); + ranks_per_package = + (int + **) MPL_malloc(max_entries_per_level[package_level] * sizeof(int *), MPL_MEM_OTHER); MPIR_ERR_CHKANDJUMP(!ranks_per_package, mpi_errno, MPI_ERR_OTHER, "**nomem"); - package_ctr = (int *) MPL_calloc(num_packages, sizeof(int), MPL_MEM_OTHER); + package_ctr = + (int *) MPL_calloc(max_entries_per_level[package_level], sizeof(int), MPL_MEM_OTHER); MPIR_ERR_CHKANDJUMP(!package_ctr, mpi_errno, MPI_ERR_OTHER, "**nomem"); - for (int i = 0; i < num_packages; ++i) { + for (i = 0; i < max_entries_per_level[package_level]; ++i) { package_ctr[i] = 0; ranks_per_package[i] = (int *) MPL_calloc(num_ranks, sizeof(int), MPL_MEM_OTHER); MPIR_ERR_CHKANDJUMP(!ranks_per_package[i], mpi_errno, MPI_ERR_OTHER, "**nomem"); } /* sort the ranks into packages based on the binding information */ - for (int i = 0; i < num_ranks; ++i) { - int package = bind_map[i * MAX_TOPO_DEPTH + package_level]; + for (i = 0; i < num_ranks; ++i) { + int package = bind_map[i][package_level]; ranks_per_package[package][package_ctr[package]++] = i; } max_ranks_per_package = 0; - for (int i = 0; i < num_packages; ++i) { + for (i = 0; i < max_entries_per_level[package_level]; ++i) { max_ranks_per_package = MPL_MAX(max_ranks_per_package, package_ctr[i]); } /* At this point we have done the common work in extracting topology information @@ -392,17 +539,19 @@ int MPIDI_SHM_topology_tree_init(MPIR_Comm * comm_ptr, int root, int bcast_k, /* For Bcast, package leaders are added before the package local ranks, and the per_package * tree is left_skewed */ - mpi_errno = gen_tree(bcast_k, shared_region, num_packages, - ranks_per_package, max_ranks_per_package, package_ctr, - package_level, num_ranks, 1 /*package_leaders_first */ , - 0 /*left_skewed */ , errflag); + mpi_errno = MPIDI_SHM_gen_tree(bcast_k, shared_region, max_entries_per_level, + ranks_per_package, max_ranks_per_package, package_ctr, + package_level, num_ranks, 1 /*package_leaders_first */ , + 0 /*left_skewed */ , bcast_tree_type, errflag); MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); } mpi_errno = MPIR_Barrier_impl(comm_ptr, errflag); MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); /* Every rank copies their tree out from shared memory */ - copy_tree(shared_region, num_ranks, rank, bcast_tree, bcast_topotree_fail); + MPIDI_SHM_copy_tree(shared_region, num_ranks, rank, bcast_tree, bcast_topotree_fail); + if (MPIDI_SHM_TOPOTREE_DEBUG) + MPIDI_SHM_print_topotree_file("BCAST", comm_ptr->context_id, rank, bcast_tree); /* Wait until shared memory is available */ mpi_errno = MPIR_Barrier_impl(comm_ptr, errflag); @@ -412,32 +561,46 @@ int MPIDI_SHM_topology_tree_init(MPIR_Comm * comm_ptr, int root, int bcast_k, * tree is right_skewed (children are added in the reverse order */ if (rank == root) { memset(shared_region, 0, shm_size); - mpi_errno = gen_tree(reduce_k, shared_region, num_packages, - ranks_per_package, max_ranks_per_package, package_ctr, - package_level, num_ranks, 0 /*package_leaders_last */ , - 1 /*right_skewed */ , errflag); + mpi_errno = MPIDI_SHM_gen_tree(reduce_k, shared_region, max_entries_per_level, + ranks_per_package, max_ranks_per_package, package_ctr, + package_level, num_ranks, 0 /*package_leaders_last */ , + 1 /*right_skewed */ , reduce_tree_type, errflag); MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); } mpi_errno = MPIR_Barrier_impl(comm_ptr, errflag); MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); + /* each rank copy the reduce tree out */ - copy_tree(shared_region, num_ranks, rank, reduce_tree, reduce_topotree_fail); + MPIDI_SHM_copy_tree(shared_region, num_ranks, rank, reduce_tree, reduce_topotree_fail); + if (MPIDI_SHM_TOPOTREE_DEBUG) + MPIDI_SHM_print_topotree_file("REDUCE", comm_ptr->context_id, rank, reduce_tree); /* Wait for all ranks to copy out the tree */ mpi_errno = MPIR_Barrier_impl(comm_ptr, errflag); MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, *errflag); /* Cleanup */ if (rank == root) { - for (int i = 0; i < num_packages; ++i) { + for (i = 0; i < max_entries_per_level[package_level]; ++i) { MPL_free(ranks_per_package[i]); } MPL_free(ranks_per_package); MPL_free(package_ctr); + if (MPIDI_SHM_TOPOTREE_DEBUG) + for (i = 0; i < topo_depth; ++i) { + fprintf(stderr, "Level :: %d, Max :: %d\n", i, max_entries_per_level[i]); + } + for (i = 0; i < num_ranks; ++i) { + MPL_free(bind_map[i]); + } + MPL_free(max_entries_per_level); + MPL_free(bind_map); } MPIDU_shm_free(shared_region); fn_exit: + if (rank == root && MPIDI_SHM_TOPOTREE_DEBUG) + fprintf(stderr, "Done creating tree for %d\n", num_ranks); MPIR_FUNC_EXIT; return mpi_errno; fn_fail: diff --git a/src/mpid/ch4/shm/src/topotree.h b/src/mpid/ch4/shm/src/topotree.h index 889de1cd3a9..6ec31cce4be 100644 --- a/src/mpid/ch4/shm/src/topotree.h +++ b/src/mpid/ch4/shm/src/topotree.h @@ -8,9 +8,32 @@ #include "topotree_types.h" -int MPIDI_SHM_topology_tree_init(MPIR_Comm * comm_ptr, int root, int bcast_k, +int MPIDI_SHM_create_template_tree(MPIDI_SHM_topotree_t * template_tree, int k_val, int tree_type, + bool right_skewed, int max_ranks, MPIR_Errflag_t * eflag); + +void MPIDI_SHM_copy_tree(int *shared_region, int num_ranks, int rank, + MPIR_Treealgo_tree_t * my_tree, int *topotree_fail); + +int MPIDI_SHM_topotree_get_package_level(int topo_depth, int *max_entries_per_level, int num_ranks, + int **bind_map); + +void MPIDI_SHM_gen_package_tree(int num_packages, int k_val, bool right_skewed, + MPIDI_SHM_topotree_t * package_tree, int *package_leaders); + +void MPIDI_SHM_gen_tree_sharedmemory(int *shared_region, MPIDI_SHM_topotree_t * tree, + MPIDI_SHM_topotree_t * package_tree, int *package_leaders, + int num_packages, int num_ranks, int k_val, + bool package_leaders_first); + +int MPIDI_SHM_gen_tree(int k_val, int *shared_region, int *max_entries_per_level, + int **ranks_per_package, int max_ranks_per_package, int *package_ctr, + int package_level, int num_ranks, bool package_leaders_first, + bool right_skewed, int tree_type, MPIR_Errflag_t * eflag); + +int MPIDI_SHM_topology_tree_init(MPIR_Comm * comm_ptr, int root, int bcast_k, int bcast_tree_type, MPIR_Treealgo_tree_t * bcast_tree, int *bcast_topotree_fail, - int reduce_k, MPIR_Treealgo_tree_t * reduce_tree, - int *reduce_topotree_fail, MPIR_Errflag_t * eflag); + int reduce_k, int reduce_tree_type, + MPIR_Treealgo_tree_t * reduce_tree, int *reduce_topotree_fail, + MPIR_Errflag_t * eflag); #endif /* TOPOTREE_H_INCLUDED */ From 5849ce735056e756c0dc4f997c86ac14a76d79a6 Mon Sep 17 00:00:00 2001 From: "Islam, Nusrat" Date: Tue, 25 Jan 2022 11:47:01 -0600 Subject: [PATCH 529/607] posix: add release-gather based non-blocking collective framework Implement non-blocking version of release_gather framework to implement shm_ibcast and shm_ireduce using gentran scheduler. A schedule is created in the form of a forest, where each tree represents a chunk of a large message. Each chunk is given a unique sequence number so that all ranks know which cell of shm buffer to use for copying the data in/out. Also, have a set of release, gather flags per rank per cell of shm_buffer. --- src/mpid/ch4/shm/posix/posix_comm.c | 6 + src/mpid/ch4/shm/posix/posix_pre.h | 4 +- .../ch4/shm/posix/release_gather/Makefile.mk | 7 +- .../release_gather/nb_bcast_release_gather.h | 507 +++++++++++++++++ .../release_gather/nb_reduce_release_gather.h | 511 ++++++++++++++++++ .../posix/release_gather/nb_release_gather.c | 348 ++++++++++++ .../shm/posix/release_gather/release_gather.c | 3 + .../shm/posix/release_gather/release_gather.h | 3 + .../release_gather/release_gather_types.h | 23 + 9 files changed, 1409 insertions(+), 3 deletions(-) create mode 100644 src/mpid/ch4/shm/posix/release_gather/nb_bcast_release_gather.h create mode 100644 src/mpid/ch4/shm/posix/release_gather/nb_reduce_release_gather.h create mode 100644 src/mpid/ch4/shm/posix/release_gather/nb_release_gather.c diff --git a/src/mpid/ch4/shm/posix/posix_comm.c b/src/mpid/ch4/shm/posix/posix_comm.c index 7bd2c973cec..e4084dda234 100644 --- a/src/mpid/ch4/shm/posix/posix_comm.c +++ b/src/mpid/ch4/shm/posix/posix_comm.c @@ -6,6 +6,8 @@ #include "mpidimpl.h" #include "posix_noinline.h" #include "release_gather.h" +#include "nb_bcast_release_gather.h" +#include "nb_reduce_release_gather.h" int MPIDI_POSIX_mpi_comm_commit_pre_hook(MPIR_Comm * comm) { @@ -18,6 +20,9 @@ int MPIDI_POSIX_mpi_comm_commit_pre_hook(MPIR_Comm * comm) MPIR_ERR_CHECK(mpi_errno); } + MPIDI_POSIX_COMM(comm, nb_bcast_seq_no) = 0; + MPIDI_POSIX_COMM(comm, nb_reduce_seq_no) = 0; + fn_exit: MPIR_FUNC_EXIT; return mpi_errno; @@ -60,6 +65,7 @@ int MPIDI_POSIX_mpi_comm_free_hook(MPIR_Comm * comm) /* Release_gather primitives based collective algorithm works for Intra-comms only */ if (comm->comm_kind == MPIR_COMM_KIND__INTRACOMM) { mpi_errno = MPIDI_POSIX_mpi_release_gather_comm_free(comm); + mpi_errno = MPIDI_POSIX_nb_release_gather_comm_free(comm); MPIR_ERR_CHECK(mpi_errno); } diff --git a/src/mpid/ch4/shm/posix/posix_pre.h b/src/mpid/ch4/shm/posix/posix_pre.h index 7d49229a33b..142b50a8f3f 100644 --- a/src/mpid/ch4/shm/posix/posix_pre.h +++ b/src/mpid/ch4/shm/posix/posix_pre.h @@ -36,8 +36,10 @@ extern char MPIDI_POSIX_coll_generic_json[]; /* These structs are populated with dummy variables because empty structs are not supported in all * compilers: https://stackoverflow.com/a/755339/491687 */ typedef struct { - MPIDI_POSIX_release_gather_comm_t release_gather; void *csel_comm; + MPIDI_POSIX_release_gather_comm_t release_gather, nb_release_gather; + int nb_bcast_seq_no; /* Seq number of the release-gather based nonblocking bcast call */ + int nb_reduce_seq_no; /* Seq number of the release-gather based nonblocking reduce call */ } MPIDI_POSIX_comm_t; typedef struct { diff --git a/src/mpid/ch4/shm/posix/release_gather/Makefile.mk b/src/mpid/ch4/shm/posix/release_gather/Makefile.mk index 911ce204e16..729b000969c 100644 --- a/src/mpid/ch4/shm/posix/release_gather/Makefile.mk +++ b/src/mpid/ch4/shm/posix/release_gather/Makefile.mk @@ -6,6 +6,9 @@ AM_CPPFLAGS += -I$(top_srcdir)/src/mpid/ch4/shm/posix/release_gather noinst_HEADERS += src/mpid/ch4/shm/posix/release_gather/release_gather_types.h \ - src/mpid/ch4/shm/posix/release_gather/release_gather.h + src/mpid/ch4/shm/posix/release_gather/release_gather.h \ + src/mpid/ch4/shm/posix/release_gather/nb_bcast_release_gather.h \ + src/mpid/ch4/shm/posix/release_gather/nb_reduce_release_gather.h -mpi_core_sources += src/mpid/ch4/shm/posix/release_gather/release_gather.c +mpi_core_sources += src/mpid/ch4/shm/posix/release_gather/release_gather.c \ + src/mpid/ch4/shm/posix/release_gather/nb_release_gather.c diff --git a/src/mpid/ch4/shm/posix/release_gather/nb_bcast_release_gather.h b/src/mpid/ch4/shm/posix/release_gather/nb_bcast_release_gather.h new file mode 100644 index 00000000000..acd7c4aa8d2 --- /dev/null +++ b/src/mpid/ch4/shm/posix/release_gather/nb_bcast_release_gather.h @@ -0,0 +1,507 @@ +/* + * Copyright (C) by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + * + */ + +#ifndef NB_BCAST_RELEASE_GATHER_H_INCLUDED +#define NB_BCAST_RELEASE_GATHER_H_INCLUDED + +#include "gentran_types.h" + +/* Flags Layout - For segment 0, gather flag for each rank, followed by release flag for each rank. + * Repeat same for segment 1 and so on. + */ +#define MPIDI_POSIX_RELEASE_GATHER_NB_IBCAST_GATHER_FLAG_ADDR(rank, segment, num_ranks) \ + (((MPL_atomic_uint64_t *)nb_release_gather_info_ptr->ibcast_flags_addr) + \ + (((segment * num_ranks * MPIDI_POSIX_RELEASE_GATHER_FLAG_SPACE_PER_RANK) + \ + (rank * MPIDI_POSIX_RELEASE_GATHER_FLAG_SPACE_PER_RANK + \ + MPIDI_POSIX_RELEASE_GATHER_GATHER_FLAG_OFFSET))/(MPIDI_POSIX_RELEASE_GATHER_FLAG_SIZE))) + +#define MPIDI_POSIX_RELEASE_GATHER_NB_IBCAST_RELEASE_FLAG_ADDR(rank, segment, num_ranks) \ + (((MPL_atomic_uint64_t *)nb_release_gather_info_ptr->ibcast_flags_addr) + \ + (((segment * num_ranks * MPIDI_POSIX_RELEASE_GATHER_FLAG_SPACE_PER_RANK) + \ + (rank * MPIDI_POSIX_RELEASE_GATHER_FLAG_SPACE_PER_RANK + \ + MPIDI_POSIX_RELEASE_GATHER_RELEASE_FLAG_OFFSET))/(MPIDI_POSIX_RELEASE_GATHER_FLAG_SIZE))) + +#define MPIDI_POSIX_RELEASE_GATHER_NB_IBCAST_DATA_ADDR(buf)\ + (char *) nb_release_gather_info_ptr->bcast_buf_addr + \ + (buf * MPIDI_POSIX_RELEASE_GATHER_BCAST_CELLSIZE) + +int MPIDI_POSIX_nb_release_gather_comm_init(MPIR_Comm * comm_ptr, + const MPIDI_POSIX_release_gather_opcode_t operation); +int MPIDI_POSIX_nb_release_gather_comm_free(MPIR_Comm * comm_ptr); + +/* The following functions with suffix issue, completion or cb are used as function pointers in the + * generic vertex types or callback type vertices created later */ +MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_NB_RG_empty_issue(void *v, int *done) +{ + *done = 0; + return MPI_SUCCESS; +} + +MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_NB_RG_root_datacopy_issue(void *v, int *done) +{ + MPII_Genutil_vtx_t *vtxp = (MPII_Genutil_vtx_t *) v; + MPIDI_POSIX_per_call_ibcast_info_t *per_call_data = + (MPIDI_POSIX_per_call_ibcast_info_t *) vtxp->u.generic.data; + int root = per_call_data->root; + MPIR_Comm *comm_ptr = per_call_data->comm_ptr; + + int rank = MPIR_Comm_rank(comm_ptr); + + if (root != 0) { + if (rank == root || rank == 0) { + /* Root has to be send data to rank 0 when the shm_buffer is available */ + *done = 0; + return MPI_SUCCESS; + } + } else if (rank == 0) { + /* Rank 0 has to copy data to shm_buffer when it is available */ + *done = 0; + return MPI_SUCCESS; + } + /* Rest of the ranks can proceed to next vertex */ + *done = 1; + return MPI_SUCCESS; +} + +MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_NB_RG_root_datacopy_completion(void *v, int *done) +{ + MPII_Genutil_vtx_t *vtxp = (MPII_Genutil_vtx_t *) v; + MPIDI_POSIX_per_call_ibcast_info_t *per_call_data = + (MPIDI_POSIX_per_call_ibcast_info_t *) vtxp->u.generic.data; + int root = per_call_data->root; + int num_cells = MPIR_CVAR_BCAST_INTRANODE_NUM_CELLS; + MPIDI_POSIX_release_gather_comm_t *nb_release_gather_info_ptr; + int segment = per_call_data->seq_no % num_cells; + MPIR_Comm *comm_ptr = per_call_data->comm_ptr; + nb_release_gather_info_ptr = &MPIDI_POSIX_COMM(comm_ptr, nb_release_gather); + int rank = MPIR_Comm_rank(comm_ptr); + int num_ranks = MPIR_Comm_size(comm_ptr); + MPIR_Errflag_t errflag = MPIR_ERR_NONE; + int last_seq_no = nb_release_gather_info_ptr->ibcast_last_seq_no_completed[segment]; + + MPL_atomic_uint64_t *my_release_flag_addr = + MPIDI_POSIX_RELEASE_GATHER_NB_IBCAST_RELEASE_FLAG_ADDR(rank, segment, num_ranks); + MPL_atomic_uint64_t *my_gather_flag_addr = + MPIDI_POSIX_RELEASE_GATHER_NB_IBCAST_GATHER_FLAG_ADDR(rank, segment, num_ranks); + MPL_atomic_uint64_t *rank_0_gather_flag_addr = + MPIDI_POSIX_RELEASE_GATHER_NB_IBCAST_GATHER_FLAG_ADDR(0, segment, num_ranks); + + if (MPL_atomic_acquire_load_uint64(rank_0_gather_flag_addr) == -1) { + /* Buffer can be overwritten */ + if (root != 0) { + /* Root sends data to rank 0 */ + if (rank == root) { + MPIC_Isend(per_call_data->local_buf, per_call_data->count, per_call_data->datatype, + 0, per_call_data->tag, comm_ptr, &(per_call_data->sreq), &errflag); + *done = 1; + } else if (rank == 0) { + MPIC_Irecv(MPIDI_POSIX_RELEASE_GATHER_NB_IBCAST_DATA_ADDR(segment), + per_call_data->count, per_call_data->datatype, per_call_data->root, + per_call_data->tag, comm_ptr, &(per_call_data->rreq)); + *done = 1; + } + } else { + /* Rank 0 makes sure that the seq_nos that executes on a cell are in order. It will + * hold the buffer for seq_no 8 only when seq_no 4 is completed (Assuming num_cells + * is 4). */ + if (rank == 0 && + (last_seq_no == per_call_data->seq_no - num_cells || last_seq_no < num_cells)) { + /* Mark the buffer as occupied */ + MPL_atomic_release_store_uint64(my_gather_flag_addr, -2); + MPIR_Localcopy(per_call_data->local_buf, per_call_data->count, + per_call_data->datatype, + MPIDI_POSIX_RELEASE_GATHER_NB_IBCAST_DATA_ADDR(segment), + per_call_data->count, per_call_data->datatype); + MPL_atomic_release_store_uint64(my_release_flag_addr, per_call_data->seq_no); + *done = 1; + } else { + *done = 0; + } + } + } else { + /* Buffer was not ready */ + *done = 0; + } + + return MPI_SUCCESS; +} + +MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_NB_RG_finish_send_recv_issue(void *v, int *done) +{ + MPII_Genutil_vtx_t *vtxp = (MPII_Genutil_vtx_t *) v; + MPIDI_POSIX_per_call_ibcast_info_t *per_call_data = + (MPIDI_POSIX_per_call_ibcast_info_t *) vtxp->u.generic.data; + int root = per_call_data->root; + MPIR_Comm *comm_ptr = per_call_data->comm_ptr; + int rank = MPIR_Comm_rank(comm_ptr); + + if ((root != 0) && (rank == root || rank == 0)) { + /* Root and rank 0 will have to wait on completion of send, recv respectively in case of + * non-zero root*/ + *done = 0; + return MPI_SUCCESS; + } + *done = 1; + return MPI_SUCCESS; +} + +MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_NB_RG_finish_send_recv_completion(void *v, int *done) +{ + MPII_Genutil_vtx_t *vtxp = (MPII_Genutil_vtx_t *) v; + MPIDI_POSIX_per_call_ibcast_info_t *per_call_data = + (MPIDI_POSIX_per_call_ibcast_info_t *) vtxp->u.generic.data; + int root = per_call_data->root; + MPIDI_POSIX_release_gather_comm_t *nb_release_gather_info_ptr; + int segment = per_call_data->seq_no % MPIR_CVAR_BCAST_INTRANODE_NUM_CELLS; + MPIR_Comm *comm_ptr = per_call_data->comm_ptr; + nb_release_gather_info_ptr = &MPIDI_POSIX_COMM(comm_ptr, nb_release_gather); + int rank = MPIR_Comm_rank(comm_ptr); + int num_ranks = MPIR_Comm_size(comm_ptr); + MPL_atomic_uint64_t *my_release_flag_addr = + MPIDI_POSIX_RELEASE_GATHER_NB_IBCAST_RELEASE_FLAG_ADDR(rank, segment, num_ranks); + MPL_atomic_uint64_t *my_gather_flag_addr = + MPIDI_POSIX_RELEASE_GATHER_NB_IBCAST_GATHER_FLAG_ADDR(rank, segment, num_ranks); + + if (root != 0) { + if (rank == root) { + if (MPIR_Request_is_complete(per_call_data->sreq)) { + MPIR_Request_free(per_call_data->sreq); + per_call_data->sreq = NULL; + *done = 1; + return MPI_SUCCESS; + } else { + /* Send is not complete */ + *done = 0; + return MPI_SUCCESS; + } + } else if (rank == 0) { + if (MPIR_Request_is_complete(per_call_data->rreq)) { + /* Mark the buffer as occupied */ + MPL_atomic_release_store_uint64(my_gather_flag_addr, -2); + MPIR_Request_free(per_call_data->rreq); + per_call_data->rreq = NULL; + /* Rank 0 updates its flag when it arrives and data is ready in shm buffer (if bcast) */ + /* zm_memord_release makes sure that the write of data does not get reordered after this + * store */ + MPL_atomic_release_store_uint64(my_release_flag_addr, per_call_data->seq_no); + *done = 1; + return MPI_SUCCESS; + } else { + /* Recv is not complete */ + *done = 0; + return MPI_SUCCESS; + } + } + } + *done = 1; + return MPI_SUCCESS; + +} + +MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_NB_RG_update_release_flag_completion(void *v, int *done) +{ + int mpi_errno = MPI_SUCCESS; + MPII_Genutil_vtx_t *vtxp = (MPII_Genutil_vtx_t *) v; + MPIDI_POSIX_per_call_ibcast_info_t *per_call_data = vtxp->u.generic.data; + MPIR_Comm *comm_ptr = per_call_data->comm_ptr; + int rank = MPIR_Comm_rank(comm_ptr); + int num_ranks = MPIR_Comm_size(comm_ptr); + MPL_atomic_uint64_t *parent_release_flag_addr, *my_release_flag_addr; + + MPIDI_POSIX_release_gather_comm_t *nb_release_gather_info_ptr; + nb_release_gather_info_ptr = &MPIDI_POSIX_COMM(comm_ptr, nb_release_gather); + int segment = per_call_data->seq_no % MPIR_CVAR_BCAST_INTRANODE_NUM_CELLS; + + my_release_flag_addr = + MPIDI_POSIX_RELEASE_GATHER_NB_IBCAST_RELEASE_FLAG_ADDR(rank, segment, num_ranks); + + if (rank != 0) { + parent_release_flag_addr = + MPIDI_POSIX_RELEASE_GATHER_NB_IBCAST_RELEASE_FLAG_ADDR + (nb_release_gather_info_ptr->bcast_tree.parent, segment, num_ranks); + } + + if (rank != 0) { + if (MPL_atomic_acquire_load_uint64(parent_release_flag_addr) == per_call_data->seq_no) { + /* Update my release_flag if the parent has arrived */ + MPL_atomic_release_store_uint64(my_release_flag_addr, per_call_data->seq_no); + } else { + *done = 0; + return MPI_SUCCESS; + } + } + + *done = 1; + return mpi_errno; +} + + +MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_NB_RG_non_root_datacopy_cb(MPIR_Comm * comm, int tag, + void *data) +{ + MPIDI_POSIX_per_call_ibcast_info_t *per_call_data = data; + MPIR_Comm *comm_ptr = per_call_data->comm_ptr; + int rank = MPIR_Comm_rank(comm_ptr); + int num_ranks = MPIR_Comm_size(comm_ptr); + MPIDI_POSIX_release_gather_comm_t *nb_release_gather_info_ptr; + int segment = per_call_data->seq_no % MPIR_CVAR_BCAST_INTRANODE_NUM_CELLS; + nb_release_gather_info_ptr = &MPIDI_POSIX_COMM(comm_ptr, nb_release_gather); + int num_children = nb_release_gather_info_ptr->bcast_tree.num_children; + MPL_atomic_uint64_t *my_gather_flag_addr; + + my_gather_flag_addr = + MPIDI_POSIX_RELEASE_GATHER_NB_IBCAST_GATHER_FLAG_ADDR(rank, segment, num_ranks); + + if (rank != per_call_data->root) { + MPIR_Localcopy(MPIDI_POSIX_RELEASE_GATHER_NB_IBCAST_DATA_ADDR(segment), + per_call_data->count, per_call_data->datatype, per_call_data->local_buf, + per_call_data->count, per_call_data->datatype); + } + if (num_children == 0) { + /* Leaf ranks update their gather flags */ + MPL_atomic_release_store_uint64(my_gather_flag_addr, per_call_data->seq_no); + } + + return MPI_SUCCESS; +} + +MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_NB_RG_gather_completion(void *v, int *done) +{ + MPII_Genutil_vtx_t *vtxp = (MPII_Genutil_vtx_t *) v; + MPIDI_POSIX_per_call_ibcast_info_t *per_call_data = vtxp->u.generic.data; + MPIR_Comm *comm_ptr = per_call_data->comm_ptr; + int num_ranks = MPIR_Comm_size(comm_ptr); + UT_array *children; + int i; + MPIDI_POSIX_release_gather_comm_t *nb_release_gather_info_ptr; + nb_release_gather_info_ptr = &MPIDI_POSIX_COMM(comm_ptr, nb_release_gather); + children = nb_release_gather_info_ptr->bcast_tree.children; + int num_children = nb_release_gather_info_ptr->bcast_tree.num_children; + int segment = per_call_data->seq_no % MPIR_CVAR_BCAST_INTRANODE_NUM_CELLS; + MPL_atomic_uint64_t *child_gather_flag_addr; + + /* Gather phase begins */ + for (i = 0; i < num_children; i++) { + child_gather_flag_addr = + MPIDI_POSIX_RELEASE_GATHER_NB_IBCAST_GATHER_FLAG_ADDR(*utarray_eltptr(children, i), + segment, num_ranks); + if (MPL_atomic_acquire_load_uint64(child_gather_flag_addr) != per_call_data->seq_no) { + *done = 0; + return MPI_SUCCESS; + } + } + + *done = 1; + return MPI_SUCCESS; +} + +MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_NB_RG_update_gather_flag_cb(MPIR_Comm * comm, int tag, + void *data) +{ + MPIDI_POSIX_per_call_ibcast_info_t *per_call_data = data; + MPIR_Comm *comm_ptr = per_call_data->comm_ptr; + int rank = MPIR_Comm_rank(comm_ptr); + int num_ranks = MPIR_Comm_size(comm_ptr); + MPIDI_POSIX_release_gather_comm_t *nb_release_gather_info_ptr; + int segment = per_call_data->seq_no % MPIR_CVAR_BCAST_INTRANODE_NUM_CELLS; + nb_release_gather_info_ptr = &MPIDI_POSIX_COMM(comm_ptr, nb_release_gather); + MPL_atomic_uint64_t *my_gather_flag_addr; + + my_gather_flag_addr = + MPIDI_POSIX_RELEASE_GATHER_NB_IBCAST_GATHER_FLAG_ADDR(rank, segment, num_ranks); + /* Update my gather flag. Reaching here means all my children have arrived */ + MPL_atomic_release_store_uint64(my_gather_flag_addr, per_call_data->seq_no); + + if (rank == 0 && MPL_atomic_acquire_load_uint64(my_gather_flag_addr) == per_call_data->seq_no) { + /* If I am rank 0 and all the ranks have arrived, set my_gather_flag to -1 */ + MPL_atomic_release_store_uint64(my_gather_flag_addr, -1); + nb_release_gather_info_ptr->ibcast_last_seq_no_completed[segment] = per_call_data->seq_no; + } + return MPI_SUCCESS; +} + +/* Add vertices to the schedule to perform a release followed by gather. Both the steps are broken + * into a total of 6 vertices. It involves the following steps: + * + * 1. Rank 0 copies the data into a cell of shm_buffer and updates its release flag. + * 2. Rest of the ranks are waiting on this flag. + * 3. Then non-zero ranks copy data out of shm_buffer and update its gather_flag, depending on if + * the children have arrived. This way rank 0 knows when the buffer can be overwritten for the next + * release step */ +MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_nb_release_gather_ibcast_impl(void *local_buf, + MPI_Aint count, + MPI_Datatype datatype, + const int root, + MPIR_Comm * comm_ptr, + MPIR_TSP_sched_t sched) +{ + MPIR_FUNC_ENTER; + + int mpi_errno = MPI_SUCCESS, mpi_errno_ret = MPI_SUCCESS; + int tag, my_rank; + int first_vtx_id = -1, second_vtx_id, third_vtx_id, fourth_vtx_id, fifth_vtx_id, *sixth_vtx_id; + int prev_vtx_id, pack_vtx_id = -1; + int root_datacopy_type_id, update_release_flag_type_id, gather_type_id, + finish_send_recv_type_id; + MPIDI_POSIX_per_call_ibcast_info_t *data; + int i; + MPI_Aint num_chunks, chunk_count_floor, chunk_count_ceil; + int offset = 0, is_contig, ori_count = count, vtx_id; + MPI_Aint type_size, nbytes, true_lb, true_extent; + void *ori_local_buf = local_buf; + MPI_Datatype ori_datatype = datatype; + + MPIR_CHKLMEM_DECL(1); + /* Register the vertices */ + root_datacopy_type_id = + MPIR_TSP_sched_new_type(sched, MPIDI_POSIX_NB_RG_root_datacopy_issue, + MPIDI_POSIX_NB_RG_root_datacopy_completion, NULL); + finish_send_recv_type_id = + MPIR_TSP_sched_new_type(sched, MPIDI_POSIX_NB_RG_finish_send_recv_issue, + MPIDI_POSIX_NB_RG_finish_send_recv_completion, NULL); + update_release_flag_type_id = + MPIR_TSP_sched_new_type(sched, MPIDI_POSIX_NB_RG_empty_issue, + MPIDI_POSIX_NB_RG_update_release_flag_completion, NULL); + gather_type_id = + MPIR_TSP_sched_new_type(sched, MPIDI_POSIX_NB_RG_empty_issue, + MPIDI_POSIX_NB_RG_gather_completion, NULL); + + my_rank = MPIR_Comm_rank(comm_ptr); + MPIR_Datatype_is_contig(datatype, &is_contig); + + if (is_contig) { + MPIR_Datatype_get_size_macro(datatype, type_size); + } else { + MPIR_Pack_size_impl(1, datatype, comm_ptr, &type_size); + } + + nbytes = type_size * count; + + if (is_contig) { + /* contiguous. No need to pack */ + MPIR_Type_get_true_extent_impl(datatype, &true_lb, &true_extent); + local_buf = (char *) ori_local_buf + true_lb; + } else { + local_buf = MPIR_TSP_sched_malloc(count, sched); + if (my_rank == root) { + /* Root packs the data before sending, for non contiguous datatypes */ + mpi_errno_ret = + MPIR_TSP_sched_localcopy(ori_local_buf, ori_count, ori_datatype, local_buf, nbytes, + MPI_BYTE, sched, 0, NULL, &pack_vtx_id); + if (mpi_errno_ret) + MPIR_ERR_ADD(mpi_errno, mpi_errno_ret); + } + } + + /* Calculate chunking information for pipelining */ + /* Chunking information is calculated in terms of bytes (not type_size), so we may copy only + * half a datatype in one chunk, but that is fine */ + MPIR_Algo_calculate_pipeline_chunk_info(MPIDI_POSIX_RELEASE_GATHER_BCAST_CELLSIZE, 1, + nbytes, &num_chunks, &chunk_count_floor, + &chunk_count_ceil); + MPIR_CHKLMEM_MALLOC(sixth_vtx_id, int *, num_chunks * sizeof(int), mpi_errno, "sixth_vtx_ids", + MPL_MEM_COLL); + + /* Do pipelined release-gather */ + /* A schedule gets created in the form of a forest, where each tree has 6 vertices (to perform + * release_gather) and number of trees is same as number of chunks the message is divided + * into. Then, there is a dependence from first vertex of previous chunk to first vertex of next + * chunk. */ + + for (i = 0; i < num_chunks; i++) { + int chunk_count = (i == 0) ? chunk_count_floor : chunk_count_ceil; + int n_incoming = 0; + if (i == 0 && !is_contig) { + /* Create dependence from the pack vertex to the first vertex of the first chunk */ + n_incoming = 1; + prev_vtx_id = pack_vtx_id; + } + + data = (MPIDI_POSIX_per_call_ibcast_info_t *) + MPIR_TSP_sched_malloc(sizeof(MPIDI_POSIX_per_call_ibcast_info_t), sched); + MPIR_ERR_CHKANDJUMP(!data, mpi_errno, MPI_ERR_OTHER, "**nomem"); + + mpi_errno = MPIR_Sched_next_tag(comm_ptr, &tag); + if (mpi_errno) + MPIR_ERR_POP(mpi_errno); + + /* Every iteration gets a unique sequence number. This is needed to determine which cell in + * shm_buffer should be used for which iteration */ + MPIDI_POSIX_COMM(comm_ptr, nb_bcast_seq_no)++; + + /* Fill in the per_call data structure */ + data->seq_no = MPIDI_POSIX_COMM(comm_ptr, nb_bcast_seq_no); + data->local_buf = (char *) local_buf + offset; + data->count = chunk_count; + data->datatype = MPI_BYTE; + data->root = root; + data->comm_ptr = comm_ptr; + data->tag = tag; + data->sreq = NULL; + data->rreq = NULL; + + /* First vertex of next chunk depends on first vertex of previous chunk */ + if (i > 0) { + n_incoming = 1; + prev_vtx_id = first_vtx_id; + } + mpi_errno_ret = + MPIR_TSP_sched_generic(root_datacopy_type_id, data, sched, n_incoming, &prev_vtx_id, + &first_vtx_id); + if (mpi_errno_ret) + MPIR_ERR_ADD(mpi_errno, mpi_errno_ret); + + mpi_errno_ret = + MPIR_TSP_sched_generic(finish_send_recv_type_id, data, sched, 1, &first_vtx_id, + &second_vtx_id); + if (mpi_errno_ret) + MPIR_ERR_ADD(mpi_errno, mpi_errno_ret); + + mpi_errno_ret = + MPIR_TSP_sched_generic(update_release_flag_type_id, data, sched, 1, &second_vtx_id, + &third_vtx_id); + if (mpi_errno_ret) + MPIR_ERR_ADD(mpi_errno, mpi_errno_ret); + + mpi_errno_ret = + MPIR_TSP_sched_cb(&MPIDI_POSIX_NB_RG_non_root_datacopy_cb, data, sched, 1, + &third_vtx_id, &fourth_vtx_id); + if (mpi_errno_ret) + MPIR_ERR_ADD(mpi_errno, mpi_errno_ret); + mpi_errno_ret = + MPIR_TSP_sched_generic(gather_type_id, data, sched, 1, &fourth_vtx_id, &fifth_vtx_id); + if (mpi_errno_ret) + MPIR_ERR_ADD(mpi_errno, mpi_errno_ret); + + mpi_errno = + MPIR_TSP_sched_cb(&MPIDI_POSIX_NB_RG_update_gather_flag_cb, data, sched, 1, + &fifth_vtx_id, &sixth_vtx_id[i]); + if (mpi_errno_ret) + MPIR_ERR_ADD(mpi_errno, mpi_errno_ret); + offset += chunk_count; + } + + if (!is_contig) { + if (my_rank != root) { + /* Non-root unpack the data if expecting non-contiguous datatypes */ + /* Dependency is created from the last vertices of each chunk to the unpack vertex */ + mpi_errno = + MPIR_TSP_sched_localcopy(local_buf, nbytes, MPI_BYTE, ori_local_buf, ori_count, + ori_datatype, sched, num_chunks, sixth_vtx_id, &vtx_id); + if (mpi_errno) + MPIR_ERR_POP(mpi_errno); + } + } + + fn_exit: + MPIR_CHKLMEM_FREEALL(); + MPIR_FUNC_EXIT; + return mpi_errno; + fn_fail: + goto fn_exit; +} + +#endif diff --git a/src/mpid/ch4/shm/posix/release_gather/nb_reduce_release_gather.h b/src/mpid/ch4/shm/posix/release_gather/nb_reduce_release_gather.h new file mode 100644 index 00000000000..66605c9292f --- /dev/null +++ b/src/mpid/ch4/shm/posix/release_gather/nb_reduce_release_gather.h @@ -0,0 +1,511 @@ +/* + * Copyright (C) by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + * + */ + +#ifndef NB_REDUCE_RELEASE_GATHER_H_INCLUDED +#define NB_REDUCE_RELEASE_GATHER_H_INCLUDED + +#include "gentran_types.h" + +#define MPIDI_POSIX_RELEASE_GATHER_NB_IREDUCE_GATHER_FLAG_ADDR(rank, segment, num_ranks) \ + (((MPL_atomic_uint64_t *)nb_release_gather_info_ptr->ireduce_flags_addr) + \ + (((segment * num_ranks * MPIDI_POSIX_RELEASE_GATHER_FLAG_SPACE_PER_RANK) + \ + (rank * MPIDI_POSIX_RELEASE_GATHER_FLAG_SPACE_PER_RANK + \ + MPIDI_POSIX_RELEASE_GATHER_GATHER_FLAG_OFFSET))/(MPIDI_POSIX_RELEASE_GATHER_FLAG_SIZE))) + +#define MPIDI_POSIX_RELEASE_GATHER_NB_IREDUCE_RELEASE_FLAG_ADDR(rank, segment, num_ranks) \ + (((MPL_atomic_uint64_t *)nb_release_gather_info_ptr->ireduce_flags_addr) + \ + (((segment * num_ranks * MPIDI_POSIX_RELEASE_GATHER_FLAG_SPACE_PER_RANK) + \ + (rank * MPIDI_POSIX_RELEASE_GATHER_FLAG_SPACE_PER_RANK + \ + MPIDI_POSIX_RELEASE_GATHER_RELEASE_FLAG_OFFSET))/(MPIDI_POSIX_RELEASE_GATHER_FLAG_SIZE))) + +#define MPIDI_POSIX_RELEASE_GATHER_NB_REDUCE_DATA_ADDR(rank, buf) \ + (((char *) nb_release_gather_info_ptr->reduce_buf_addr) + \ + (rank * MPIR_CVAR_REDUCE_INTRANODE_BUFFER_TOTAL_SIZE) + \ + (buf * MPIDI_POSIX_RELEASE_GATHER_REDUCE_CELLSIZE)) + +/* The following functions with suffix issue, completion, or cb are used as function pointers in the + * generic vertex types or callback type vertices created later */ + +MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_NB_RG_rank0_hold_buf_issue(void *v, int *done) +{ + MPII_Genutil_vtx_t *vtxp = (MPII_Genutil_vtx_t *) v; + /* Step 1 issue */ + MPIDI_POSIX_per_call_ireduce_info_t *per_call_data = + (MPIDI_POSIX_per_call_ireduce_info_t *) vtxp->u.generic.data; + MPIR_Comm *comm_ptr = per_call_data->comm_ptr; + int rank = MPIR_Comm_rank(comm_ptr); + + if (rank != 0) + *done = 1; + else + *done = 0; + + return MPI_SUCCESS; +} + +MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_NB_RG_rank0_hold_buf_completion(void *v, int *done) +{ + MPII_Genutil_vtx_t *vtxp = (MPII_Genutil_vtx_t *) v; + /* Step 1 completion */ + MPIDI_POSIX_per_call_ireduce_info_t *per_call_data = + (MPIDI_POSIX_per_call_ireduce_info_t *) vtxp->u.generic.data; + MPIDI_POSIX_release_gather_comm_t *nb_release_gather_info_ptr; + int num_cells = MPIR_CVAR_REDUCE_INTRANODE_NUM_CELLS; + int segment = per_call_data->seq_no % num_cells; + MPIR_Comm *comm_ptr = per_call_data->comm_ptr; + nb_release_gather_info_ptr = &MPIDI_POSIX_COMM(comm_ptr, nb_release_gather); + int rank = MPIR_Comm_rank(comm_ptr); + int num_ranks = MPIR_Comm_size(comm_ptr); + int last_seq_no = nb_release_gather_info_ptr->ireduce_last_seq_no_completed[segment]; + + MPL_atomic_uint64_t *my_release_flag_addr = + MPIDI_POSIX_RELEASE_GATHER_NB_IREDUCE_RELEASE_FLAG_ADDR(rank, segment, num_ranks); + MPL_atomic_uint64_t *my_gather_flag_addr = + MPIDI_POSIX_RELEASE_GATHER_NB_IREDUCE_GATHER_FLAG_ADDR(rank, segment, num_ranks); + + /* Rank 0 keeps checking if the a particular cell is available */ + if (rank == 0 && (MPL_atomic_acquire_load_uint64(my_gather_flag_addr) == -1) && + (last_seq_no == per_call_data->seq_no - num_cells || last_seq_no < num_cells)) { + /* Buffer can be overwritten */ + if (rank == 0) { + /* Mark the buffer as occupied */ + MPL_atomic_release_store_uint64(my_gather_flag_addr, -2); + /* Update the release_flag, so that the children ranks can move on */ + MPL_atomic_release_store_uint64(my_release_flag_addr, per_call_data->seq_no); + *done = 1; + } + } else { + /* Buffer was not ready */ + *done = 0; + } + + return MPI_SUCCESS; +} + +MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_NB_RG_update_release_flags_completion(void *v, int *done) +{ + MPII_Genutil_vtx_t *vtxp = (MPII_Genutil_vtx_t *) v; + /* Step 2 completion */ + MPIDI_POSIX_per_call_ireduce_info_t *per_call_data = vtxp->u.generic.data; + MPIR_Comm *comm_ptr = per_call_data->comm_ptr; + int rank = MPIR_Comm_rank(comm_ptr); + int num_ranks = MPIR_Comm_size(comm_ptr); + MPL_atomic_uint64_t *parent_release_flag_addr, *my_release_flag_addr; + + MPIDI_POSIX_release_gather_comm_t *nb_release_gather_info_ptr; + nb_release_gather_info_ptr = &MPIDI_POSIX_COMM(comm_ptr, nb_release_gather); + int segment = per_call_data->seq_no % MPIR_CVAR_REDUCE_INTRANODE_NUM_CELLS; + + my_release_flag_addr = + MPIDI_POSIX_RELEASE_GATHER_NB_IREDUCE_RELEASE_FLAG_ADDR(rank, segment, num_ranks); + + /* Everyone except rank 0 waits for its parent to arrive */ + if (rank != 0) { + parent_release_flag_addr = + MPIDI_POSIX_RELEASE_GATHER_NB_IREDUCE_RELEASE_FLAG_ADDR + (nb_release_gather_info_ptr->reduce_tree.parent, segment, num_ranks); + + if (MPL_atomic_acquire_load_uint64(parent_release_flag_addr) == per_call_data->seq_no) { + /* Update my release_flag if the parent has arrived */ + MPL_atomic_release_store_uint64(my_release_flag_addr, per_call_data->seq_no); + } else { + *done = 0; + return MPI_SUCCESS; + } + } + + *done = 1; + + return MPI_SUCCESS; +} + +MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_NB_RG_all_datacopy_cb(MPIR_Comm * comm, int tag, + void *data) +{ + /* Step 3 callback */ + MPIDI_POSIX_per_call_ireduce_info_t *per_call_data = data; + MPIR_Comm *comm_ptr = per_call_data->comm_ptr; + int rank = MPIR_Comm_rank(comm_ptr); + int root = per_call_data->root; + MPIDI_POSIX_release_gather_comm_t *nb_release_gather_info_ptr; + int segment = per_call_data->seq_no % MPIR_CVAR_REDUCE_INTRANODE_NUM_CELLS; + nb_release_gather_info_ptr = &MPIDI_POSIX_COMM(comm_ptr, nb_release_gather); + + /* If root is rank 0, final data is reduced into the recv_buf directly. It is to avoid extra + * data copy between shm_buf and recv_buf */ + if (per_call_data->send_buf != per_call_data->recv_buf && rank == 0 && root == 0) { + /* If MPI_IN_PLACE is not used and root is rank 0, copy data from send_buf to recv_buf */ + MPIR_Localcopy(per_call_data->send_buf, per_call_data->count, per_call_data->datatype, + per_call_data->recv_buf, per_call_data->count, per_call_data->datatype); + } else { + /* ranks copy data from sendbuf to shmbuf */ + MPIR_Localcopy(per_call_data->send_buf, per_call_data->count, per_call_data->datatype, + MPIDI_POSIX_RELEASE_GATHER_NB_REDUCE_DATA_ADDR(rank, segment), + per_call_data->count, per_call_data->datatype); + } + + return MPI_SUCCESS; +} + +MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_NB_RG_gather_step_completion(void *v, int *done) +{ + MPII_Genutil_vtx_t *vtxp = (MPII_Genutil_vtx_t *) v; + /* Step 4 completion */ + MPIDI_POSIX_per_call_ireduce_info_t *per_call_data = vtxp->u.generic.data; + MPIR_Comm *comm_ptr = per_call_data->comm_ptr; + int num_ranks = MPIR_Comm_size(comm_ptr); + UT_array *children; + int i; + MPIDI_POSIX_release_gather_comm_t *nb_release_gather_info_ptr; + nb_release_gather_info_ptr = &MPIDI_POSIX_COMM(comm_ptr, nb_release_gather); + children = nb_release_gather_info_ptr->reduce_tree.children; + int num_children = nb_release_gather_info_ptr->reduce_tree.num_children; + int segment = per_call_data->seq_no % MPIR_CVAR_REDUCE_INTRANODE_NUM_CELLS; + MPL_atomic_uint64_t *child_gather_flag_addr; + + /* Gather phase begins */ + /* Wait for all my children to arrive */ + for (i = 0; i < num_children; i++) { + child_gather_flag_addr = + MPIDI_POSIX_RELEASE_GATHER_NB_IREDUCE_GATHER_FLAG_ADDR(*utarray_eltptr(children, i), + segment, num_ranks); + if (MPL_atomic_acquire_load_uint64(child_gather_flag_addr) != per_call_data->seq_no) { + /* Set *done to 0 even if a single child has not arrived */ + *done = 0; + return MPI_SUCCESS; + } + } + + *done = 1; + + return MPI_SUCCESS; +} + +MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_NB_RG_reduce_data_cb(MPIR_Comm * comm, int tag, void *data) +{ + /* Step 5 callback */ + MPIDI_POSIX_per_call_ireduce_info_t *per_call_data = data; + MPIR_Comm *comm_ptr = per_call_data->comm_ptr; + int num_ranks = MPIR_Comm_size(comm_ptr); + int rank = MPIR_Comm_rank(comm_ptr); + int i; + int root = per_call_data->root; + MPIDI_POSIX_release_gather_comm_t *nb_release_gather_info_ptr; + nb_release_gather_info_ptr = &MPIDI_POSIX_COMM(comm_ptr, nb_release_gather); + int num_children = nb_release_gather_info_ptr->reduce_tree.num_children; + int segment = per_call_data->seq_no % MPIR_CVAR_REDUCE_INTRANODE_NUM_CELLS; + MPL_atomic_uint64_t *my_gather_flag_addr = + MPIDI_POSIX_RELEASE_GATHER_NB_IREDUCE_GATHER_FLAG_ADDR(rank, segment, num_ranks); + void *child_data_addr; + + /* All my children have arrived (step 4 completion guarantees that). Reduce the data */ + for (i = 0; i < num_children; i++) { + child_data_addr = + (char *) nb_release_gather_info_ptr->child_reduce_buf_addr[i] + + segment * MPIDI_POSIX_RELEASE_GATHER_REDUCE_CELLSIZE; + if (root == 0 && rank == 0) { + /* If rank 0 is root, reduce directly in recv_buf */ + MPIR_Reduce_local((void *) child_data_addr, per_call_data->recv_buf, + per_call_data->count, per_call_data->datatype, per_call_data->op); + + } else { + /* Reduce in a specific cell in shm_buf */ + MPIR_Reduce_local((void *) child_data_addr, + (void *) MPIDI_POSIX_RELEASE_GATHER_NB_REDUCE_DATA_ADDR(rank, + segment), + per_call_data->count, per_call_data->datatype, per_call_data->op); + } + } + + if (rank == 0 && root == 0) { + /* Mark the buffer as available, if root was rank 0 */ + MPL_atomic_release_store_uint64(my_gather_flag_addr, -1); + } else { + /* Update my gather flag to seq_no (so that my parent can be unblocked) */ + MPL_atomic_release_store_uint64(my_gather_flag_addr, per_call_data->seq_no); + } + + return MPI_SUCCESS; +} + +MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_NB_RG_reduce_start_sendrecv_completion(void *v, int *done) +{ + MPII_Genutil_vtx_t *vtxp = (MPII_Genutil_vtx_t *) v; + /* Step 6 completion */ + MPIDI_POSIX_per_call_ireduce_info_t *per_call_data = + (MPIDI_POSIX_per_call_ireduce_info_t *) vtxp->u.generic.data; + int root = per_call_data->root; + int segment = per_call_data->seq_no % MPIR_CVAR_REDUCE_INTRANODE_NUM_CELLS; + MPIR_Comm *comm_ptr = per_call_data->comm_ptr; + MPIDI_POSIX_release_gather_comm_t *nb_release_gather_info_ptr; + nb_release_gather_info_ptr = &MPIDI_POSIX_COMM(comm_ptr, nb_release_gather); + int rank = MPIR_Comm_rank(comm_ptr); + MPIR_Errflag_t errflag = MPIR_ERR_NONE; + + /* If root is not rank 0, rank 0 sends data to root */ + if (root != 0) { + if (rank == root) { + MPIC_Irecv(per_call_data->recv_buf, per_call_data->count, per_call_data->datatype, + 0, per_call_data->tag, comm_ptr, &(per_call_data->rreq)); + } else if (rank == 0) { + MPIC_Isend(MPIDI_POSIX_RELEASE_GATHER_NB_REDUCE_DATA_ADDR(rank, segment), + per_call_data->count, per_call_data->datatype, per_call_data->root, + per_call_data->tag, comm_ptr, &(per_call_data->sreq), &errflag); + } + } + + *done = 1; + return MPI_SUCCESS; +} + +MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_NB_RG_finish_sendrecv_issue(void *v, int *done) +{ + MPII_Genutil_vtx_t *vtxp = (MPII_Genutil_vtx_t *) v; + /* Step 6,7 issue */ + MPIDI_POSIX_per_call_ireduce_info_t *per_call_data = + (MPIDI_POSIX_per_call_ireduce_info_t *) vtxp->u.generic.data; + int root = per_call_data->root; + MPIR_Comm *comm_ptr = per_call_data->comm_ptr; + int rank = MPIR_Comm_rank(comm_ptr); + + if ((root != 0) && (rank == root || rank == 0)) { + /* Root and rank 0 will have to wait on completion of recv, send respectively in case of + * non-zero root */ + *done = 0; + return MPI_SUCCESS; + } + + *done = 1; + + return MPI_SUCCESS; +} + +MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_NB_RG_reduce_finish_sendrecv_completion(void *v, int *done) +{ + MPII_Genutil_vtx_t *vtxp = (MPII_Genutil_vtx_t *) v; + /* Step 7 completion */ + MPIDI_POSIX_per_call_ireduce_info_t *per_call_data = + (MPIDI_POSIX_per_call_ireduce_info_t *) vtxp->u.generic.data; + int root = per_call_data->root; + int segment = per_call_data->seq_no % MPIR_CVAR_REDUCE_INTRANODE_NUM_CELLS; + MPIR_Comm *comm_ptr = per_call_data->comm_ptr; + MPIDI_POSIX_release_gather_comm_t *nb_release_gather_info_ptr; + nb_release_gather_info_ptr = &MPIDI_POSIX_COMM(comm_ptr, nb_release_gather); + int rank = MPIR_Comm_rank(comm_ptr); + int num_ranks = MPIR_Comm_size(comm_ptr); + MPL_atomic_uint64_t *my_gather_flag_addr = + MPIDI_POSIX_RELEASE_GATHER_NB_IREDUCE_GATHER_FLAG_ADDR(rank, segment, num_ranks); + + if (root != 0) { + if (rank == root) { + if (MPIR_Request_is_complete(per_call_data->rreq)) { + MPIR_Request_free(per_call_data->rreq); + per_call_data->rreq = NULL; + *done = 1; + } else { + /* Recv is not complete */ + *done = 0; + } + } else if (rank == 0) { + if (MPIR_Request_is_complete(per_call_data->sreq)) { + MPIR_Request_free(per_call_data->sreq); + per_call_data->sreq = NULL; + /* Mark the buffer as available for next use */ + MPL_atomic_release_store_uint64(my_gather_flag_addr, -1); + /* Update the last seq no completed */ + nb_release_gather_info_ptr->ireduce_last_seq_no_completed[segment] = + per_call_data->seq_no; + *done = 1; + } else { + /* Send is not complete */ + *done = 0; + } + } + } + + return MPI_SUCCESS; +} + +MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_NB_RG_ref_count_decrement_free(void *v) +{ + MPII_Genutil_vtx_t *vtxp = (MPII_Genutil_vtx_t *) v; + /* Step 7 free */ + MPIDI_POSIX_per_call_ireduce_info_t *per_call_data = + (MPIDI_POSIX_per_call_ireduce_info_t *) vtxp->u.generic.data; + MPIR_Op_release_if_not_builtin(per_call_data->op); + MPIR_Datatype_release_if_not_builtin(per_call_data->datatype); + + return MPI_SUCCESS; +} + +/* Creates the generic type vertices as well as dependencies to implement release step followed + * by gather step to implement Ireduce */ +MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_nb_release_gather_ireduce_impl(void *send_buf, + void *recv_buf, + MPI_Aint count, + MPI_Datatype datatype, + MPI_Op op, const int root, + MPIR_Comm * comm_ptr, + MPIR_TSP_sched_t sched) +{ + MPIR_FUNC_ENTER; + + int mpi_errno = MPI_SUCCESS, mpi_errno_ret = MPI_SUCCESS; + int tag; + int first_vtx_id = -1, second_vtx_id, third_vtx_id, fourth_vtx_id, fifth_vtx_id, sixth_vtx_id, + seventh_vtx_id, prev_vtx_id; + int reserve_buf_type_id, propagate_release_flag_type_id, gather_type_id, start_sendrecv_type_id, + finish_sendrecv_type_id; + MPIDI_POSIX_per_call_ireduce_info_t *data; + int i; + MPI_Aint num_chunks, chunk_count_floor, chunk_count_ceil; + MPI_Aint true_extent, type_size, lb, extent; + int offset = 0, is_contig; + + /* Register the vertices */ + reserve_buf_type_id = MPIR_TSP_sched_new_type(sched, MPIDI_POSIX_NB_RG_rank0_hold_buf_issue, + MPIDI_POSIX_NB_RG_rank0_hold_buf_completion, + NULL); + propagate_release_flag_type_id = + MPIR_TSP_sched_new_type(sched, MPIDI_POSIX_NB_RG_empty_issue, + MPIDI_POSIX_NB_RG_update_release_flags_completion, NULL); + gather_type_id = + MPIR_TSP_sched_new_type(sched, MPIDI_POSIX_NB_RG_empty_issue, + MPIDI_POSIX_NB_RG_gather_step_completion, NULL); + start_sendrecv_type_id = + MPIR_TSP_sched_new_type(sched, MPIDI_POSIX_NB_RG_finish_sendrecv_issue, + MPIDI_POSIX_NB_RG_reduce_start_sendrecv_completion, NULL); + finish_sendrecv_type_id = + MPIR_TSP_sched_new_type(sched, MPIDI_POSIX_NB_RG_finish_sendrecv_issue, + MPIDI_POSIX_NB_RG_reduce_finish_sendrecv_completion, + MPIDI_POSIX_NB_RG_ref_count_decrement_free); + + MPIR_Type_get_extent_impl(datatype, &lb, &extent); + MPIR_Type_get_true_extent_impl(datatype, &lb, &true_extent); + extent = MPL_MAX(extent, true_extent); + + MPIR_Datatype_is_contig(datatype, &is_contig); + + if (is_contig) { + MPIR_Datatype_get_size_macro(datatype, type_size); + } else { + MPIR_Pack_size_impl(1, datatype, comm_ptr, &type_size); + } + + if (send_buf == MPI_IN_PLACE) { + send_buf = recv_buf; + } + /* Calculate chunking information, using extent handles contiguous and non-contiguous datatypes + * both */ + MPIR_Algo_calculate_pipeline_chunk_info(MPIDI_POSIX_RELEASE_GATHER_REDUCE_CELLSIZE, + extent, count, &num_chunks, + &chunk_count_floor, &chunk_count_ceil); + + /* Print chunking information */ + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, (MPL_DBG_FDEST, + "Ireduce shmgr pipeline info: segsize=%d count=%ld " + "num_chunks=%ld chunk_count_floor=%ld chunk_size_ceil=%ld" + "\n", MPIDI_POSIX_RELEASE_GATHER_REDUCE_CELLSIZE, + count, num_chunks, chunk_count_floor, + chunk_count_ceil)); + + /* Do pipelined release-gather */ + /* A schedule gets created in the form of a forest, where each tree has 7 vertices (to perform + * release_gather) and number of trees is same as number of chunks the message is divided + * into. Then, there is a dependence from first vertex of previous chunk to first vertex of next + * chunk. */ + for (i = 0; i < num_chunks; i++) { + int chunk_count = (i == 0) ? chunk_count_floor : chunk_count_ceil; + int n_incoming = 0; + data = (MPIDI_POSIX_per_call_ireduce_info_t *) + MPIR_TSP_sched_malloc(sizeof(MPIDI_POSIX_per_call_ireduce_info_t), sched); + MPIR_ERR_CHKANDJUMP(!data, mpi_errno, MPI_ERR_OTHER, "**nomem"); + + data->seq_no = MPIDI_POSIX_COMM(comm_ptr, nb_reduce_seq_no); + + mpi_errno = MPIR_Sched_next_tag(comm_ptr, &tag); + if (mpi_errno) + MPIR_ERR_POP(mpi_errno); + + MPIR_Datatype_add_ref_if_not_builtin(datatype); + MPIR_Op_add_ref_if_not_builtin(op); + + /* Every iteration gets a unique sequence number. This is needed to determine which cell in + * shm_buffer should be used for which iteration */ + MPIDI_POSIX_COMM(comm_ptr, nb_reduce_seq_no)++; + + /* Fill in the per_call data structure */ + data->seq_no = MPIDI_POSIX_COMM(comm_ptr, nb_reduce_seq_no); + data->send_buf = (char *) send_buf + offset * extent; + data->recv_buf = (char *) recv_buf + offset * extent; + data->count = chunk_count; + data->datatype = datatype; + data->root = root; + data->op = op; + data->comm_ptr = comm_ptr; + data->tag = tag; + data->sreq = NULL; + data->rreq = NULL; + + /* First vertex of next chunk depends on first vertex of previous chunk */ + if (i > 0) { + n_incoming = 1; + prev_vtx_id = first_vtx_id; + } + mpi_errno_ret = + MPIR_TSP_sched_generic(reserve_buf_type_id, data, sched, n_incoming, &prev_vtx_id, + &first_vtx_id); + if (mpi_errno_ret) + MPIR_ERR_ADD(mpi_errno, mpi_errno_ret); + + mpi_errno_ret = + MPIR_TSP_sched_generic(propagate_release_flag_type_id, data, sched, 1, &first_vtx_id, + &second_vtx_id); + if (mpi_errno_ret) + MPIR_ERR_ADD(mpi_errno, mpi_errno_ret); + + mpi_errno_ret = + MPIR_TSP_sched_cb(&MPIDI_POSIX_NB_RG_all_datacopy_cb, data, sched, 1, &second_vtx_id, + &third_vtx_id); + + if (mpi_errno_ret) + MPIR_ERR_ADD(mpi_errno, mpi_errno_ret); + + mpi_errno_ret = + MPIR_TSP_sched_generic(gather_type_id, data, sched, 1, &third_vtx_id, &fourth_vtx_id); + if (mpi_errno_ret) + MPIR_ERR_ADD(mpi_errno, mpi_errno_ret); + + mpi_errno_ret = + MPIR_TSP_sched_cb(&MPIDI_POSIX_NB_RG_reduce_data_cb, data, sched, 1, &fourth_vtx_id, + &fifth_vtx_id); + + if (mpi_errno_ret) + MPIR_ERR_ADD(mpi_errno, mpi_errno_ret); + + mpi_errno_ret = + MPIR_TSP_sched_generic(start_sendrecv_type_id, data, sched, 1, &fifth_vtx_id, + &sixth_vtx_id); + if (mpi_errno_ret) + MPIR_ERR_ADD(mpi_errno, mpi_errno_ret); + + mpi_errno_ret = + MPIR_TSP_sched_generic(finish_sendrecv_type_id, data, sched, 1, &sixth_vtx_id, + &seventh_vtx_id); + if (mpi_errno_ret) + MPIR_ERR_ADD(mpi_errno, mpi_errno_ret); + + offset += chunk_count; + } + + fn_exit: + MPIR_FUNC_EXIT; + return mpi_errno; + fn_fail: + goto fn_exit; +} + +#endif diff --git a/src/mpid/ch4/shm/posix/release_gather/nb_release_gather.c b/src/mpid/ch4/shm/posix/release_gather/nb_release_gather.c new file mode 100644 index 00000000000..d555d84cd26 --- /dev/null +++ b/src/mpid/ch4/shm/posix/release_gather/nb_release_gather.c @@ -0,0 +1,348 @@ +/* + * Copyright (C) by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + * + */ + +#include "mpiimpl.h" +#include "release_gather.h" +#include "nb_bcast_release_gather.h" +#include "nb_reduce_release_gather.h" +#ifdef HAVE_HWLOC +#include "topotree.h" +#include "topotree_util.h" +#include "mpir_hwtopo.h" +#endif + + +/* Initialize the data structures and allocate the shared memory (flags, bcast buffer) */ +int MPIDI_POSIX_nb_release_gather_comm_init(MPIR_Comm * comm_ptr, + const MPIDI_POSIX_release_gather_opcode_t operation) +{ + MPIR_FUNC_ENTER; + + int mpi_errno = MPI_SUCCESS; + int mpi_errno_ret = MPI_SUCCESS; + int rank, num_ranks; + bool initialize_tree = false, initialize_ibcast_buf = false, initialize_ireduce_buf = false; + int ibcast_flags_num_pages, ireduce_flags_num_pages, fallback = 0; + size_t ibcast_flags_shm_size = 0, ireduce_flags_shm_size = 0; + const long pg_sz = sysconf(_SC_PAGESIZE); + MPIR_Errflag_t errflag = MPIR_ERR_NONE; + bool mapfail_flag = false; + int topotree_fail[2] = { -1, -1 }; /* -1 means topo trees not created due to reasons like not + * specifying binding, no hwloc etc. 0 means topo trees were + * created successfully. 1 means topo trees were created + * but there was a failure, so the tree needs to be freed + * before creating the non-topo tree */ + + rank = MPIR_Comm_rank(comm_ptr); + num_ranks = MPIR_Comm_size(comm_ptr); + + int i; + MPIDI_POSIX_release_gather_comm_t *nb_release_gather_info_ptr = NULL; + + if (NB_RELEASE_GATHER_FIELD(comm_ptr, is_initialized) == 0) { + /* release_gather based nb collectives have not been used before on this comm */ + initialize_tree = true; + if (operation == MPIDI_POSIX_RELEASE_GATHER_OPCODE_BCAST) { + initialize_ibcast_buf = true; + } else if (operation == MPIDI_POSIX_RELEASE_GATHER_OPCODE_REDUCE) { + initialize_ireduce_buf = true; + } + } else { + /* at least one release_gather based nb collective was used on this comm */ + if (operation == MPIDI_POSIX_RELEASE_GATHER_OPCODE_BCAST && + NB_RELEASE_GATHER_FIELD(comm_ptr, bcast_buf_addr) == NULL) { + initialize_ibcast_buf = true; + } else if (operation == MPIDI_POSIX_RELEASE_GATHER_OPCODE_REDUCE && + NB_RELEASE_GATHER_FIELD(comm_ptr, reduce_buf_addr) == NULL) { + initialize_ireduce_buf = true; + } + } + + if (initialize_ibcast_buf || initialize_ireduce_buf) { + /* Calculate the amount of shm to be created */ + size_t tmp_shm_counter; + size_t memory_to_be_allocated = 0; + + /* Layout of the shm region for flags: for each cell, a gather flag for each rank, followed + * by a release flag for each rank */ + /* Calculate the amount of memory that would be allocated for flags */ + if (initialize_ibcast_buf) { + ibcast_flags_shm_size = MPIDI_POSIX_RELEASE_GATHER_FLAG_SPACE_PER_RANK * num_ranks * + MPIR_CVAR_BCAST_INTRANODE_NUM_CELLS; + /* Reset flags_shm_size so that the data buffers are aligned to the system pages */ + ibcast_flags_num_pages = ibcast_flags_shm_size / (int) (pg_sz); + if (ibcast_flags_shm_size % pg_sz != 0) { + ibcast_flags_num_pages++; + } + ibcast_flags_shm_size = ibcast_flags_num_pages * pg_sz; + } else if (initialize_ireduce_buf) { + ireduce_flags_shm_size = MPIDI_POSIX_RELEASE_GATHER_FLAG_SPACE_PER_RANK * num_ranks * + MPIR_CVAR_REDUCE_INTRANODE_NUM_CELLS; + /* Reset flags_shm_size so that the data buffers are aligned to the system pages */ + ireduce_flags_num_pages = ireduce_flags_shm_size / (int) (pg_sz); + if (ireduce_flags_shm_size % pg_sz != 0) { + ireduce_flags_num_pages++; + } + ireduce_flags_shm_size = ireduce_flags_num_pages * pg_sz; + } + + /* Update the amount of memory to be allocated */ + memory_to_be_allocated += ibcast_flags_shm_size + ireduce_flags_shm_size; + + if (initialize_ibcast_buf) { + memory_to_be_allocated += MPIR_CVAR_BCAST_INTRANODE_BUFFER_TOTAL_SIZE; + } + if (initialize_ireduce_buf) { + memory_to_be_allocated += (num_ranks * MPIR_CVAR_REDUCE_INTRANODE_BUFFER_TOTAL_SIZE); + } + + if (rank == 0) { + /* rank 0 decides if more memory can be created and broadcasts the decision to other + * ranks */ + tmp_shm_counter = MPL_atomic_acquire_load_uint64(MPIDI_POSIX_shm_limit_counter); + + /* Check if it is allowed to create more shm on this node */ + if ((tmp_shm_counter + memory_to_be_allocated) > + (MPIR_CVAR_COLL_SHM_LIMIT_PER_NODE * 1024)) { + /* cannot create more shm, fallback to MPIR level algorithms, and broadcast the + * decision to other ranks */ + if (MPIR_CVAR_COLLECTIVE_FALLBACK == MPIR_CVAR_COLLECTIVE_FALLBACK_print) { + fprintf(stderr, + "Intra-node collectives about to allocate more shared memory than \ + the specified limit through MPIR_CVAR_COLL_SHM_LIMIT_PER_NODE. Fallback \ + to other algorithms.\n"); + } + fallback = 1; + MPIR_Bcast_impl(&fallback, 1, MPI_INT, 0, comm_ptr, &errflag); + MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_NO_MEM, "**nomem"); + } else { + /* More shm can be created, update the shared counter */ + MPL_atomic_fetch_add_uint64(MPIDI_POSIX_shm_limit_counter, memory_to_be_allocated); + fallback = 0; + mpi_errno = MPIR_Bcast_impl(&fallback, 1, MPI_INT, 0, comm_ptr, &errflag); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); + } + } else { + mpi_errno = MPIR_Bcast_impl(&fallback, 1, MPI_INT, 0, comm_ptr, &errflag); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); + if (fallback) { + MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_NO_MEM, "**nomem"); + } + } + } + + if (initialize_tree) { + /* Initialize the release_gather struct (tree, buffers) and attach to the communicator */ + NB_RELEASE_GATHER_FIELD(comm_ptr, is_initialized) = 1; + nb_release_gather_info_ptr = &MPIDI_POSIX_COMM(comm_ptr, nb_release_gather); + +#ifdef HAVE_HWLOC + /* Create bcast_tree and reduce_tree with root of the tree as 0 */ + if (MPIR_CVAR_ENABLE_INTRANODE_TOPOLOGY_AWARE_TREES && + getenv("HYDRA_USER_PROVIDED_BINDING")) { + /* Topology aware trees are created only when the user has specified process binding */ + if (MPIR_hwtopo_is_initialized()) { + + mpi_errno = + MPIDI_SHM_topology_tree_init(comm_ptr, 0, + MPIR_CVAR_BCAST_INTRANODE_TREE_KVAL, + MPIDI_POSIX_Bcast_tree_type, + &nb_release_gather_info_ptr->bcast_tree, + &topotree_fail[0], + MPIR_CVAR_REDUCE_INTRANODE_TREE_KVAL, + MPIDI_POSIX_Reduce_tree_type, + &nb_release_gather_info_ptr->reduce_tree, + &topotree_fail[1], &errflag); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); + } else { + /* Finalize was already called and MPIR_Process.hwloc_topology has been destroyed */ + topotree_fail[0] = -1; + topotree_fail[1] = -1; + } + mpi_errno = MPIR_Allreduce_impl(MPI_IN_PLACE, topotree_fail, 2, MPI_INT, + MPI_MAX, comm_ptr, &errflag); + } else { + topotree_fail[0] = -1; + topotree_fail[1] = -1; + } +#endif + /* Non-topology aware trees */ + if (topotree_fail[0] != 0) { + if (topotree_fail[0] == 1) + MPIR_Treealgo_tree_free(&nb_release_gather_info_ptr->bcast_tree); + mpi_errno = + MPIR_Treealgo_tree_create(rank, num_ranks, MPIDI_POSIX_Bcast_tree_type, + MPIR_CVAR_BCAST_INTRANODE_TREE_KVAL, 0, + &nb_release_gather_info_ptr->bcast_tree); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); + } + + if (topotree_fail[1] != 0) { + if (topotree_fail[1] == 1) + MPIR_Treealgo_tree_free(&nb_release_gather_info_ptr->reduce_tree); + mpi_errno = + MPIR_Treealgo_tree_create(rank, num_ranks, MPIDI_POSIX_Reduce_tree_type, + MPIR_CVAR_REDUCE_INTRANODE_TREE_KVAL, 0, + &nb_release_gather_info_ptr->reduce_tree); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); + } + nb_release_gather_info_ptr->bcast_buf_addr = NULL; + nb_release_gather_info_ptr->reduce_buf_addr = NULL; + } + + + if (initialize_ibcast_buf) { + /* Allocate and initialize the flags and buffer for non-blocking bcast */ + nb_release_gather_info_ptr = &MPIDI_POSIX_COMM(comm_ptr, nb_release_gather); + /* Array to keep track of last seq_no completed on each shm cell */ + nb_release_gather_info_ptr->ibcast_last_seq_no_completed = + MPL_malloc(MPIR_CVAR_BCAST_INTRANODE_NUM_CELLS * sizeof(int), MPL_MEM_COLL); + MPIR_ERR_CHKANDJUMP(!nb_release_gather_info_ptr->ibcast_last_seq_no_completed, mpi_errno, + MPI_ERR_OTHER, "**nomem"); + + mpi_errno = MPIDU_shm_alloc(comm_ptr, ibcast_flags_shm_size, + (void **) &(nb_release_gather_info_ptr->ibcast_flags_addr), + &mapfail_flag); + if (mpi_errno || mapfail_flag) { + /* for communication errors, just record the error but continue */ + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); + } + /* Calculate gather and release flag address and initialize to the gather and release states */ + for (i = 0; i < MPIR_CVAR_BCAST_INTRANODE_NUM_CELLS; i++) { + MPL_atomic_release_store_uint64(MPIDI_POSIX_RELEASE_GATHER_NB_IBCAST_GATHER_FLAG_ADDR + (rank, i, num_ranks), -1); + MPL_atomic_release_store_uint64(MPIDI_POSIX_RELEASE_GATHER_NB_IBCAST_RELEASE_FLAG_ADDR + (rank, i, num_ranks), -1); + nb_release_gather_info_ptr->ibcast_last_seq_no_completed[i] = -1; + } + /* Allocate the shared memory for ibcast buffer */ + mpi_errno = MPIDU_shm_alloc(comm_ptr, MPIR_CVAR_BCAST_INTRANODE_BUFFER_TOTAL_SIZE, + (void **) &(NB_RELEASE_GATHER_FIELD(comm_ptr, bcast_buf_addr)), + &mapfail_flag); + if (mpi_errno || mapfail_flag) { + /* for communication errors, just record the error but continue */ + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); + } + } + + if (initialize_ireduce_buf) { + /* Allocate and initialize the flags and buffer for non-blocking reduce */ + nb_release_gather_info_ptr = &MPIDI_POSIX_COMM(comm_ptr, nb_release_gather); + /* Array to keep track of last seq_no completed on each shm cell */ + nb_release_gather_info_ptr->ireduce_last_seq_no_completed = + MPL_malloc(MPIR_CVAR_REDUCE_INTRANODE_NUM_CELLS * sizeof(int), MPL_MEM_COLL); + MPIR_ERR_CHKANDJUMP(!nb_release_gather_info_ptr->ireduce_last_seq_no_completed, mpi_errno, + MPI_ERR_OTHER, "**nomem"); + + NB_RELEASE_GATHER_FIELD(comm_ptr, child_reduce_buf_addr) = + MPL_malloc(num_ranks * sizeof(void *), MPL_MEM_COLL); + + mpi_errno = MPIDU_shm_alloc(comm_ptr, ireduce_flags_shm_size, + (void **) &(nb_release_gather_info_ptr->ireduce_flags_addr), + &mapfail_flag); + if (mpi_errno || mapfail_flag) { + /* for communication errors, just record the error but continue */ + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); + } + for (i = 0; i < MPIR_CVAR_REDUCE_INTRANODE_NUM_CELLS; i++) { + MPL_atomic_release_store_uint64(MPIDI_POSIX_RELEASE_GATHER_NB_IREDUCE_GATHER_FLAG_ADDR + (rank, i, num_ranks), -1); + MPL_atomic_release_store_uint64(MPIDI_POSIX_RELEASE_GATHER_NB_IREDUCE_RELEASE_FLAG_ADDR + (rank, i, num_ranks), -1); + nb_release_gather_info_ptr->ireduce_last_seq_no_completed[i] = -1; + } + /* Allocate the shared memory for ireduce buffer */ + mpi_errno = MPIDU_shm_alloc(comm_ptr, + num_ranks * MPIR_CVAR_REDUCE_INTRANODE_BUFFER_TOTAL_SIZE, + (void **) &(NB_RELEASE_GATHER_FIELD(comm_ptr, reduce_buf_addr)), + &mapfail_flag); + if (mpi_errno || mapfail_flag) { + /* for communication errors, just record the error but continue */ + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); + } + + /* Store address of each of the children's reduce buffer */ + for (i = 0; i < NB_RELEASE_GATHER_FIELD(comm_ptr, reduce_tree.num_children); i++) { + MPIR_ERR_CHKANDJUMP(!utarray_eltptr + (NB_RELEASE_GATHER_FIELD(comm_ptr, reduce_tree.children), i), + mpi_errno, MPI_ERR_OTHER, "**nomem"); + NB_RELEASE_GATHER_FIELD(comm_ptr, child_reduce_buf_addr[i]) = + (char *) NB_RELEASE_GATHER_FIELD(comm_ptr, + reduce_buf_addr) + + ((*utarray_eltptr(NB_RELEASE_GATHER_FIELD(comm_ptr, reduce_tree.children), i)) + * MPIR_CVAR_REDUCE_INTRANODE_BUFFER_TOTAL_SIZE); + } + } + + if (initialize_ibcast_buf || initialize_ireduce_buf) { + /* Make sure all the flags are set before ranks start reading each other's flags from shm */ + mpi_errno = MPIR_Barrier_impl(comm_ptr, &errflag); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); + } + + fn_exit: + MPIR_FUNC_EXIT; + /* --BEGIN ERROR HANDLING-- */ + if (mpi_errno_ret) + mpi_errno = mpi_errno_ret; + else if (errflag != MPIR_ERR_NONE) + MPIR_ERR_SET(mpi_errno, errflag, "**coll_fail"); + /* --END ERROR HANDLING-- */ + return mpi_errno; + fn_fail: + goto fn_exit; +} + +/* Cleanup the release_gather data structures and free the allocated memory */ +int MPIDI_POSIX_nb_release_gather_comm_free(MPIR_Comm * comm_ptr) +{ + MPIR_FUNC_ENTER; + + int mpi_errno = MPI_SUCCESS; + int mpi_errno_ret = MPI_SUCCESS; + MPIR_Errflag_t errflag = MPIR_ERR_NONE; + + /* Clean up is not required for NULL struct */ + if (NB_RELEASE_GATHER_FIELD(comm_ptr, is_initialized) == 0) { + goto fn_exit; + } + + if (NB_RELEASE_GATHER_FIELD(comm_ptr, bcast_buf_addr) != NULL) { + /* destroy and detach the flags and buffer for Ibcast */ + mpi_errno = MPIDU_shm_free(NB_RELEASE_GATHER_FIELD(comm_ptr, ibcast_flags_addr)); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); + + /* destroy and detach shared memory used for bcast buffer */ + mpi_errno = MPIDU_shm_free(NB_RELEASE_GATHER_FIELD(comm_ptr, bcast_buf_addr)); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); + MPL_free(NB_RELEASE_GATHER_FIELD(comm_ptr, ibcast_last_seq_no_completed)); + } + + if (NB_RELEASE_GATHER_FIELD(comm_ptr, reduce_buf_addr) != NULL) { + /* destroy and detach the flags and buffer for Ireduce */ + mpi_errno = MPIDU_shm_free(NB_RELEASE_GATHER_FIELD(comm_ptr, ireduce_flags_addr)); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); + + mpi_errno = MPIDU_shm_free(NB_RELEASE_GATHER_FIELD(comm_ptr, reduce_buf_addr)); + MPIR_ERR_COLL_CHECKANDCONT(mpi_errno, errflag); + + MPL_free(NB_RELEASE_GATHER_FIELD(comm_ptr, child_reduce_buf_addr)); + MPL_free(NB_RELEASE_GATHER_FIELD(comm_ptr, ireduce_last_seq_no_completed)); + } + + MPIR_Treealgo_tree_free(&(NB_RELEASE_GATHER_FIELD(comm_ptr, bcast_tree))); + MPIR_Treealgo_tree_free(&(NB_RELEASE_GATHER_FIELD(comm_ptr, reduce_tree))); + + fn_exit: + MPIR_FUNC_EXIT; + /* --BEGIN ERROR HANDLING-- */ + if (mpi_errno_ret) + mpi_errno = mpi_errno_ret; + else if (errflag != MPIR_ERR_NONE) + MPIR_ERR_SET(mpi_errno, errflag, "**coll_fail"); + /* --END ERROR HANDLING-- */ + return mpi_errno; +} diff --git a/src/mpid/ch4/shm/posix/release_gather/release_gather.c b/src/mpid/ch4/shm/posix/release_gather/release_gather.c index c9c321bab35..b6460c7725e 100644 --- a/src/mpid/ch4/shm/posix/release_gather/release_gather.c +++ b/src/mpid/ch4/shm/posix/release_gather/release_gather.c @@ -162,6 +162,9 @@ int MPIDI_POSIX_mpi_release_gather_comm_init_null(MPIR_Comm * comm_ptr) RELEASE_GATHER_FIELD(comm_ptr, num_collective_calls) = 0; RELEASE_GATHER_FIELD(comm_ptr, is_initialized) = 0; + NB_RELEASE_GATHER_FIELD(comm_ptr, num_collective_calls) = 0; + NB_RELEASE_GATHER_FIELD(comm_ptr, is_initialized) = 0; + MPIR_FUNC_EXIT; return MPI_SUCCESS; } diff --git a/src/mpid/ch4/shm/posix/release_gather/release_gather.h b/src/mpid/ch4/shm/posix/release_gather/release_gather.h index 63c2a51a47e..4d2ef82930a 100644 --- a/src/mpid/ch4/shm/posix/release_gather/release_gather.h +++ b/src/mpid/ch4/shm/posix/release_gather/release_gather.h @@ -14,6 +14,9 @@ extern MPIDI_POSIX_release_gather_tree_type_t MPIDI_POSIX_Bcast_tree_type, #define RELEASE_GATHER_FIELD(comm, field) \ MPIDI_POSIX_COMM(comm, release_gather).field +#define NB_RELEASE_GATHER_FIELD(comm, field) \ + MPIDI_POSIX_COMM(comm, nb_release_gather).field + /* Blocking wait implementation */ /* "acquire" makes sure no writes/reads are reordered before this load */ #define MPIDI_POSIX_RELEASE_GATHER_WAIT_WHILE_LESS_THAN(ptr, value) \ diff --git a/src/mpid/ch4/shm/posix/release_gather/release_gather_types.h b/src/mpid/ch4/shm/posix/release_gather/release_gather_types.h index 94b2de42993..d7ef9a19ab2 100644 --- a/src/mpid/ch4/shm/posix/release_gather/release_gather_types.h +++ b/src/mpid/ch4/shm/posix/release_gather/release_gather_types.h @@ -33,6 +33,7 @@ typedef struct MPIDI_POSIX_release_gather_comm_t { uint64_t gather_state, release_state; void *flags_addr, *bcast_buf_addr, *reduce_buf_addr; + void *ibcast_flags_addr, *ireduce_flags_addr; void **child_reduce_buf_addr; MPL_atomic_uint64_t *release_flag_addr, *gather_flag_addr; @@ -42,6 +43,28 @@ typedef struct MPIDI_POSIX_release_gather_comm_t { int reduce_tree_type, reduce_tree_kval; int reduce_num_cells; + int *ibcast_last_seq_no_completed, *ireduce_last_seq_no_completed; } MPIDI_POSIX_release_gather_comm_t; +typedef struct MPIDI_POSIX_per_call_ibcast_info_t { + int seq_no; + uint64_t *parent_gather_flag_addr, *my_gather_flag_addr, *my_release_flag_addr; + void *local_buf; + int count, root, tag; + MPI_Datatype datatype; + MPIR_Comm *comm_ptr; + MPIR_Request *sreq, *rreq; +} MPIDI_POSIX_per_call_ibcast_info_t; + +typedef struct MPIDI_POSIX_per_call_ireduce_info_t { + int seq_no; + uint64_t *parent_gather_flag_addr, *my_gather_flag_addr, *my_release_flag_addr; + void *send_buf, *recv_buf; + int count, root, tag; + MPI_Op op; + MPI_Datatype datatype; + MPIR_Comm *comm_ptr; + MPIR_Request *sreq, *rreq; +} MPIDI_POSIX_per_call_ireduce_info_t; + #endif /* RELEASE_GATHER_TYPES_H_INCLUDED */ From a7b20b54d83a4559c9a5553fe6ca783e31c56794 Mon Sep 17 00:00:00 2001 From: "Islam, Nusrat" Date: Tue, 25 Jan 2022 13:51:17 -0600 Subject: [PATCH 530/607] posix: add release-gather based ibcast and ireduce --- src/mpid/ch4/shm/posix/posix_coll.h | 26 ++++ .../shm/posix/posix_coll_nb_release_gather.h | 122 ++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 src/mpid/ch4/shm/posix/posix_coll_nb_release_gather.h diff --git a/src/mpid/ch4/shm/posix/posix_coll.h b/src/mpid/ch4/shm/posix/posix_coll.h index 18c197918aa..e19db8b2f75 100644 --- a/src/mpid/ch4/shm/posix/posix_coll.h +++ b/src/mpid/ch4/shm/posix/posix_coll.h @@ -29,6 +29,19 @@ release_gather - Force shm optimized algo using release, gather primitives auto - Internal algorithm selection (can be overridden with MPIR_CVAR_CH4_POSIX_COLL_SELECTION_TUNING_JSON_FILE) + - name : MPIR_CVAR_IBCAST_POSIX_INTRA_ALGORITHM + category : COLLECTIVE + type : enum + default : auto + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : |- + Variable to select algorithm for intra-node bcast + mpir - Fallback to MPIR collectives + release_gather - Force shm optimized algo using release, gather primitives + auto - Internal algorithm selection (can be overridden with MPIR_CVAR_CH4_POSIX_COLL_SELECTION_TUNING_JSON_FILE) + - name : MPIR_CVAR_REDUCE_POSIX_INTRA_ALGORITHM category : COLLECTIVE type : enum @@ -42,6 +55,19 @@ release_gather - Force shm optimized algo using release, gather primitives auto - Internal algorithm selection (can be overridden with MPIR_CVAR_CH4_POSIX_COLL_SELECTION_TUNING_JSON_FILE) + - name : MPIR_CVAR_IREDUCE_POSIX_INTRA_ALGORITHM + category : COLLECTIVE + type : enum + default : auto + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : |- + Variable to select algorithm for intra-node reduce + mpir - Fallback to MPIR collectives + release_gather - Force shm optimized algo using release, gather primitives + auto - Internal algorithm selection (can be overridden with MPIR_CVAR_CH4_POSIX_COLL_SELECTION_TUNING_JSON_FILE) + - name : MPIR_CVAR_ALLREDUCE_POSIX_INTRA_ALGORITHM category : COLLECTIVE type : enum diff --git a/src/mpid/ch4/shm/posix/posix_coll_nb_release_gather.h b/src/mpid/ch4/shm/posix/posix_coll_nb_release_gather.h new file mode 100644 index 00000000000..287abe42562 --- /dev/null +++ b/src/mpid/ch4/shm/posix/posix_coll_nb_release_gather.h @@ -0,0 +1,122 @@ +/* + * + * Copyright (C) by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ + +#ifndef POSIX_COLL_NB_RELEASE_GATHER_H_INCLUDED +#define POSIX_COLL_NB_RELEASE_GATHER_H_INCLUDED + +#include "mpiimpl.h" +#include "algo_common.h" +#include "nb_release_gather.h" + +/* Intra-node Ibcast is implemented as a release step followed by gather step in release_gather + * framework. The actual data movement happens in release step. Gather step makes sure that + * the shared bcast buffer can be reused for next bcast call. Release gather framework has + * multitple cells in bcast buffer, so that the copying in next cell can be overlapped with + * copying out of previous cells (pipelining). + */ +MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_ibcast_release_gather(void *buffer, int count, + MPI_Datatype datatype, int root, + MPIR_Comm * comm_ptr, + MPIR_TSP_sched_t sched) +{ + MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_POSIX_MPI_IBCAST_RELEASE_GATHER); + MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_POSIX_MPI_IBCAST_RELEASE_GATHER); + + int mpi_errno = MPI_SUCCESS; + + MPIDI_POSIX_COMM(comm_ptr, nb_release_gather).num_collective_calls++; + if (MPIDI_POSIX_COMM(comm_ptr, nb_release_gather).num_collective_calls < + MPIR_CVAR_POSIX_NUM_NB_COLLS_THRESHOLD) { + /* Fallback to pt2pt algorithms if the total number of release_gather collective calls is + * less than the specified threshold */ + goto fallback; + } + + /* Lazy initialization of release_gather specific struct */ + mpi_errno = + MPIDI_POSIX_nb_release_gather_comm_init(comm_ptr, MPIDI_POSIX_RELEASE_GATHER_OPCODE_BCAST); + MPII_COLLECTIVE_FALLBACK_CHECK(MPIR_Comm_rank(comm_ptr), !mpi_errno, mpi_errno, + "release_gather ibcast cannot create more shared memory. Falling back to pt2pt algorithms.\n"); + + mpi_errno = + MPIDI_POSIX_nb_release_gather_ibcast_impl(buffer, count, datatype, root, comm_ptr, sched); + + fn_exit: + MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPIDI_POSIX_MPI_IBCAST_RELEASE_GATHER); + return mpi_errno; + + fn_fail: + goto fn_exit; + + fallback: + /* Fall back to other algo as release_gather based bcast cannot be used */ + mpi_errno = + MPIR_TSP_Ibcast_sched_intra_tsp_auto(buffer, count, datatype, root, comm_ptr, sched); + goto fn_exit; +} + +/* Intra-node Ireduce is implemented as a release step followed by gather step in release_gather + * framework. The actual data movement happens in gather step. Release step makes sure that + * the shared reduce buffer can be reused for next reduce call. Release gather framework has + * multiple cells in reduce buffer, so that the copying in next cell can be overlapped with + * reduction and copying out of previous cells (pipelining). + */ +MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_ireduce_release_gather(const void *sendbuf, + void *recvbuf, int count, + MPI_Datatype datatype, + MPI_Op op, int root, + MPIR_Comm * comm_ptr, + MPIR_TSP_sched_t sched) +{ + MPIR_FUNC_ENTER; + int mpi_errno = MPI_SUCCESS; + int mpi_errno_ret = MPI_SUCCESS; + + if (MPIR_Comm_size(comm_ptr) == 1) { + if (sendbuf != MPI_IN_PLACE) { + /* Simply copy the data from sendbuf to recvbuf if there is only 1 rank and MPI_IN_PLACE + * is not used */ + mpi_errno_ret = MPIR_Localcopy(sendbuf, count, datatype, recvbuf, count, datatype); + if (mpi_errno_ret) { + MPIR_ERR_ADD(mpi_errno, mpi_errno_ret); + } + } + goto fn_exit; + } + MPIDI_POSIX_COMM(comm_ptr, nb_release_gather).num_collective_calls++; + if (MPIDI_POSIX_COMM(comm_ptr, nb_release_gather).num_collective_calls < + MPIR_CVAR_POSIX_NUM_NB_COLLS_THRESHOLD) { + /* Fallback to pt2pt algorithms if the total number of release_gather collective calls is + * less than the specified threshold */ + goto fallback; + } + + /* Lazy initialization of release_gather specific struct */ + mpi_errno = + MPIDI_POSIX_nb_release_gather_comm_init(comm_ptr, MPIDI_POSIX_RELEASE_GATHER_OPCODE_REDUCE); + MPII_COLLECTIVE_FALLBACK_CHECK(MPIR_Comm_rank(comm_ptr), !mpi_errno, mpi_errno, + "release_gather ibcast cannot create more shared memory. Falling back to pt2pt algorithms.\n"); + + mpi_errno = + MPIDI_POSIX_nb_release_gather_ireduce_impl((void *) sendbuf, recvbuf, count, datatype, op, + root, comm_ptr, sched); + + fn_exit: + MPIR_FUNC_EXIT; + return mpi_errno; + + fn_fail: + goto fn_exit; + + fallback: + /* Fall back to other algo as release_gather algo cannot be used */ + mpi_errno = + MPIR_TSP_Ireduce_sched_intra_tsp_auto(sendbuf, recvbuf, count, datatype, op, root, + comm_ptr, sched); + goto fn_exit; +} + +#endif /* POSIX_COLL_NB_RELEASE_GATHER_H_INCLUDED */ From d88b9117b7c82e05e4414880565b50f5fca9f58f Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 15 Mar 2022 16:28:01 -0500 Subject: [PATCH 531/607] test: xfail allocmemf90 test for solstudio Solstudio's fortran compiler forbid passing cray pointer as integer in MPI_Alloc_mem. Since cray pointer is non-standard feature, it is not a priority to work around. Xfail for now. --- test/mpi/maint/jenkins/xfail.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/mpi/maint/jenkins/xfail.conf b/test/mpi/maint/jenkins/xfail.conf index 41e982b6577..566ff1a0351 100644 --- a/test/mpi/maint/jenkins/xfail.conf +++ b/test/mpi/maint/jenkins/xfail.conf @@ -83,6 +83,9 @@ # timeout due to lack of passive progress * * vci ch4:ofi * /^rma_contig.*iter=10000/ xfail=issue5565 rma/testlist +# Sunf90 forbid passing cray pointer as integer +* solstudio * * * /^allocmemf90/ xfail=ticket0 f90/ext/testlist + # Job-sepecific xfails # Our Arm servers are too slow for some tests mpich-main-arm.* * * * * /^sendflood / xfail=ticket0 pt2pt/testlist From fc9a469a2c503c0f201671b270f48bc00e43de66 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 1 Mar 2022 16:22:23 -0600 Subject: [PATCH 532/607] f08: add elemental to eq/neq operator functions Adding elemental allows user to apply the operator to scalar/array comparisons. --- maint/local_python/binding_f08.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maint/local_python/binding_f08.py b/maint/local_python/binding_f08.py index 4c65197e7d3..f78a46b3ce1 100644 --- a/maint/local_python/binding_f08.py +++ b/maint/local_python/binding_f08.py @@ -1143,7 +1143,7 @@ def dump_handle_routines(): for a in G.handle_list: # e.g. MPI_Comm_eq G.out.append("") - G.out.append("FUNCTION MPI_%s_%s(x, y) result(res)" % (a, op)) + G.out.append("elemental FUNCTION MPI_%s_%s(x, y) result(res)" % (a, op)) G.out.append(" TYPE(MPI_%s), INTENT(in) :: x, y" % a) G.out.append(" LOGICAL :: res") if op == "eq": @@ -1156,7 +1156,7 @@ def dump_handle_routines(): for p in [("f08", "f"), ("f", "f08")]: func_name = "MPI_%s_%s_%s_%s" % (a, p[0], op, p[1]) G.out.append("") - G.out.append("FUNCTION %s(%s, %s) result(res)" % (func_name, p[0], p[1])) + G.out.append("elemental FUNCTION %s(%s, %s) result(res)" % (func_name, p[0], p[1])) G.out.append(" TYPE(MPI_%s), INTENT(in) :: f08" % a) G.out.append(" INTEGER, INTENT(in) :: f") G.out.append(" LOGICAL :: res") From 337f6858853a982a31d2bfecd6a92980c7eb3acb Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 15 Mar 2022 22:24:30 -0500 Subject: [PATCH 533/607] ch4/posix: workaround for inter-process mutex on FreeBSD On FreeBSD (at lease for ver 12.2), destroying the mutex and recreate the mutex, the new mutex will not work for inter-process. As workaround, delay destroying window mutex until finalize. This applies the same fix as the one we did for ch3. --- configure.ac | 6 ++++ src/mpid/ch3/channels/nemesis/subconfigure.m4 | 6 ---- src/mpid/ch4/shm/posix/posix_impl.h | 2 ++ src/mpid/ch4/shm/posix/posix_init.c | 32 +++++++++++++++++++ src/mpid/ch4/shm/posix/posix_win.c | 8 +++++ 5 files changed, 48 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 4ffd91efa4d..868bf1cd777 100644 --- a/configure.ac +++ b/configure.ac @@ -4183,6 +4183,12 @@ if test "$enable_f08" = "yes" ; then fi fi +case "$host_os" in + freebsd*) + AC_DEFINE(DELAY_SHM_MUTEX_DESTROY, 1, [Define to workaround interprocess mutex issue on FreeBSD]) + ;; +esac + dnl This includes an experimental pkgconfig file for ch3 in the src/pkgconfig dnl directory AC_CONFIG_FILES([Makefile \ diff --git a/src/mpid/ch3/channels/nemesis/subconfigure.m4 b/src/mpid/ch3/channels/nemesis/subconfigure.m4 index 59aa54702c7..ad5de9d8f94 100644 --- a/src/mpid/ch3/channels/nemesis/subconfigure.m4 +++ b/src/mpid/ch3/channels/nemesis/subconfigure.m4 @@ -98,12 +98,6 @@ This turns off error checking and timing collection],,enable_fast=no) AC_CHECK_HEADERS(signal.h) AC_CHECK_FUNCS(signal) -case "$host_os" in - freebsd*) - AC_DEFINE(DELAY_SHM_MUTEX_DESTROY, 1, [Define to workaround interprocess mutex issue on FreeBSD]) - ;; -esac - nemesis_nets_dirs="" nemesis_nets_strings="" nemesis_nets_array="" diff --git a/src/mpid/ch4/shm/posix/posix_impl.h b/src/mpid/ch4/shm/posix/posix_impl.h index 676befdf946..b800d6df21f 100644 --- a/src/mpid/ch4/shm/posix/posix_impl.h +++ b/src/mpid/ch4/shm/posix/posix_impl.h @@ -14,6 +14,8 @@ #include "posix_eager_impl.h" #include "posix_progress.h" +void MPIDI_POSIX_delay_shm_mutex_destroy(int rank, MPL_proc_mutex_t * shm_mutex_ptr); + MPL_STATIC_INLINE_PREFIX int MPIDI_POSIX_get_vsi(int flag, MPIR_Comm * comm_ptr, int src_rank, int dst_rank, int tag) { diff --git a/src/mpid/ch4/shm/posix/posix_init.c b/src/mpid/ch4/shm/posix/posix_init.c index 9a4e95c9cd0..43fa4c8c5c1 100644 --- a/src/mpid/ch4/shm/posix/posix_init.c +++ b/src/mpid/ch4/shm/posix/posix_init.c @@ -39,6 +39,7 @@ #include "posix_csel_container.h" #include "mpidu_genq.h" +#include "utarray.h" #include /* for strncasecmp */ extern MPL_atomic_uint64_t *MPIDI_POSIX_shm_limit_counter; @@ -185,6 +186,24 @@ int MPIDI_POSIX_init_local(int *tag_bits /* unused */) static int posix_world_initialized; +/* FreeBSD work around: only destroy inter-process mutex at finalize */ +struct shm_mutex_entry { + int rank; + MPL_proc_mutex_t *shm_mutex_ptr; +}; + +static UT_icd shm_mutex_icd = { sizeof(struct shm_mutex_entry), NULL, NULL, NULL }; + +static UT_array *shm_mutex_free_list; + +void MPIDI_POSIX_delay_shm_mutex_destroy(int rank, MPL_proc_mutex_t * shm_mutex_ptr) +{ + struct shm_mutex_entry entry; + entry.rank = rank; + entry.shm_mutex_ptr = shm_mutex_ptr; + utarray_push_back(shm_mutex_free_list, &entry, MPL_MEM_OTHER); +} + int MPIDI_POSIX_init_world(void) { int mpi_errno = MPI_SUCCESS; @@ -198,6 +217,8 @@ int MPIDI_POSIX_init_world(void) mpi_errno = MPIDI_POSIX_coll_init(rank, size); MPIR_ERR_CHECK(mpi_errno); + utarray_new(shm_mutex_free_list, &shm_mutex_icd, MPL_MEM_OTHER); + posix_world_initialized = 1; fn_exit: @@ -217,6 +238,17 @@ int MPIDI_POSIX_mpi_finalize_hook(void) mpi_errno = MPIDI_POSIX_coll_finalize(); MPIR_ERR_CHECK(mpi_errno); + + struct shm_mutex_entry *p; + for (p = (struct shm_mutex_entry *) utarray_front(shm_mutex_free_list); p != NULL; + p = (struct shm_mutex_entry *) utarray_next(shm_mutex_free_list, p)) { + if (p->rank == 0) { + MPIDI_POSIX_RMA_MUTEX_DESTROY(p->shm_mutex_ptr); + } + mpi_errno = MPIDU_shm_free(p->shm_mutex_ptr); + MPIR_ERR_CHECK(mpi_errno); + } + utarray_free(shm_mutex_free_list); } for (int vsi = 0; vsi < MPIDI_CH4_MAX_VCIS; vsi++) { diff --git a/src/mpid/ch4/shm/posix/posix_win.c b/src/mpid/ch4/shm/posix/posix_win.c index ce4fe29185f..34157db87b1 100644 --- a/src/mpid/ch4/shm/posix/posix_win.c +++ b/src/mpid/ch4/shm/posix/posix_win.c @@ -305,12 +305,20 @@ int MPIDI_POSIX_mpi_win_free_hook(MPIR_Win * win) /* all outstanding RMAs should complete before free. */ MPIR_Assert(!posix_win->outstanding_reqs_head && !posix_win->outstanding_reqs_tail); +#ifdef DELAY_SHM_MUTEX_DESTROY + /* On FreeBSD (tested on ver 12.2) destroying a mutex and create a new one may result + * in the same address and the new mutex will not work for inter-process. To work + * around, we delay the destroying of inter-process mutex until finalize. + */ + MPIDI_POSIX_delay_shm_mutex_destroy(win->comm_ptr->rank, posix_win->shm_mutex_ptr); +#else /* destroy and detach shared mutex */ if (win->comm_ptr->rank == 0) MPIDI_POSIX_RMA_MUTEX_DESTROY(posix_win->shm_mutex_ptr); mpi_errno = MPIDU_shm_free(posix_win->shm_mutex_ptr); MPIR_ERR_CHECK(mpi_errno); +#endif } fn_exit: From a6ad5ea4e1f30796e4cb5e9b229096a6db298ddf Mon Sep 17 00:00:00 2001 From: Adam Moody Date: Mon, 7 Mar 2022 11:56:26 -0800 Subject: [PATCH 534/607] romio_synchronized_sync: move barrier after fsync --- src/mpi/romio/adio/common/ad_flush.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/mpi/romio/adio/common/ad_flush.c b/src/mpi/romio/adio/common/ad_flush.c index d5ee07fd040..c01dbaa181f 100644 --- a/src/mpi/romio/adio/common/ad_flush.c +++ b/src/mpi/romio/adio/common/ad_flush.c @@ -14,11 +14,8 @@ void ADIOI_GEN_Flush(ADIO_File fd, int *error_code) int err; static char myname[] = "ADIOI_GEN_FLUSH"; - /* If MPI_File_sync is a temporally synchronizing sync, the caller can - * avoid the 'sync/barrier/sync' process to ensure visibility and just call - * 'sync' */ - if (fd->hints->synchronizing_flush > 0) - MPI_Barrier(fd->comm); + *error_code = MPI_SUCCESS; + /* the deferred-open optimization may mean that a file has not been opened * on this processor */ /* additionally, if this process did no writes, there is no work to be done */ @@ -29,11 +26,15 @@ void ADIOI_GEN_Flush(ADIO_File fd, int *error_code) *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", strerror(errno)); - return; + } else { + fd->dirty_write = 0; } /* --END ERROR HANDLING-- */ } - fd->dirty_write = 0; - *error_code = MPI_SUCCESS; + /* If MPI_File_sync is a temporally synchronizing sync, the caller can + * avoid the 'sync/barrier/sync' process to ensure visibility and just call + * 'sync' */ + if (fd->hints->synchronizing_flush > 0) + MPI_Barrier(fd->comm); } From 4be705b2e6cadcf88cb17010fb00b39b05ab038b Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 30 Jul 2019 01:55:13 -0500 Subject: [PATCH 535/607] maint: add maint/gen_cross.pl to help generating crossfile Run this script on the host machine to generate cross_values.txt that can be passed to MPICH configure with --with-cross=path/to/cross_values.txt. --- maint/gen_cross.pl | 362 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 362 insertions(+) create mode 100644 maint/gen_cross.pl diff --git a/maint/gen_cross.pl b/maint/gen_cross.pl new file mode 100644 index 00000000000..6671e99f353 --- /dev/null +++ b/maint/gen_cross.pl @@ -0,0 +1,362 @@ +#!/usr/bin/perl +use strict; + +my $method = "direct"; +for my $a (@ARGV) { + if ($a eq "-h") { + print " Run this script on the target system to generate a cross file for\n"; + print " MPICH configure. Set compiler via CC and FC environment variables.\n"; + print " You may also use the generated file as template and manually set\n"; + print " the type sizes.\n\n"; + print " Accepted options:\n\n"; + print " -h\n"; + print " Print this message\n\n"; + print " -hybrid\n"; + print " Link Fortran with C code to check sizes. May require compiler\n"; + print " flags, e.g. setting FC='gfortran -fallow-argument-mismatch'.\n\n"; + print " -direct\n"; + print " Use Fortran SIZEOF. Most Fortran compilers support this.\n\n"; + print " -asm\n"; + print " Parse assembly output using heuristic. May work on build system.\n\n"; + exit 1; + } elsif ($a eq "-hybrid") { + $method = "hybrid"; + } elsif ($a eq "-direct") { + $method = "direct"; + } elsif ($a eq "-asm") { + $method = "asm"; + } +} + +my $CC = $ENV{CC}; +if(!$CC){ + $CC = "gcc"; +} + +my $FC = $ENV{FC}; +if(!$FC){ + $FC = "gfortran"; +} + +print "CC: $CC\n"; +print "FC: $FC\n"; + +# global hash to store crossfile values +our %cross_hash; + +my @c_types=("void *", "char", "short", "int", "long", "long long", "size_t", "off_t", "float", "double", "long double"); +get_c_sizes_direct(\@c_types); + +# tuple list of [ range, kind, size ] +my $range_kind_list = get_f90_kinds_direct(); +my @f77_types=qw(INTEGER REAL DOUBLE_PRECISION); +my $i = -1; +foreach my $t (@$range_kind_list){ + $i++; + push @f77_types, "KIND-$i-$t->[1]"; +} + +if ($method eq "hybrid") { + get_f77_sizes_hybrid(\@f77_types); +} elsif ($method eq "direct") { + get_f77_sizes_direct(\@f77_types); +} elsif ($method eq "asm") { + get_f77_sizes_asm(\@f77_types); +} + +get_f77_true_false_hybrid(); + +my @f90_names=qw(ADDRESS_KIND OFFSET_KIND INTEGER_KIND REAL_MODEL DOUBLE_MODEL INTEGER_MODEL); +get_f90_names_direct(\@f90_names); + +open Out, ">cross_values.txt" or die "Can't write cross_values.txt.\n"; +print " --> [cross_values.txt]\n"; +foreach my $t (@c_types){ + my $name = get_type_name($t); + my $val = $cross_hash{$name}; + my $var = "ac_cv_sizeof_$name"; + print Out "$var=$val\n"; +} + +foreach my $T (@f77_types){ + my $size = $cross_hash{$T}; + if($T=~/KIND-(\d+)-(\d+)/){ + $range_kind_list->[$1]->[2]=$size; + } + else{ + print Out "CROSS_F77_SIZEOF_$T=$size\n"; + } +} + +foreach my $t ("TRUE_VALUE", "FALSE_VALUE"){ + print Out "CROSS_F77_$t=$cross_hash{$t}\n"; +} + +foreach my $name (@f90_names){ + print Out "CROSS_F90_$name=$cross_hash{$name}\n"; +} + +my (@t1, @t2); +foreach my $t (@$range_kind_list){ + push @t1, "$t->[0], $t->[1]"; + push @t2, "{ $t->[0] , $t->[1] , $t->[2] }"; +} +my $t1 = join(', ', @t1); +my $t2 = join(', ', @t2); +print Out "CROSS_F90_ALL_INTEGER_MODELS=\"$t1\"\n"; +print Out "CROSS_F90_INTEGER_MODEL_MAP=\"$t2\"\n"; +close Out; + +system "rm -f t.f t.f90 t.s t t.mod t.o tlib.o"; +system "cat cross_values.txt"; +print "\n"; +print "Crossfile generated in cross_values.txt.\n"; +print "Pass to MPICH configure with --with-cross=path/to/cross_values.txt.\n"; + +# ---- subroutines -------------------------------------------- +sub get_c_sizes_direct { + my ($typelist) = @_; + open Out, ">t.c" or die "Can't write t.c.\n"; + print Out "#include \n"; + print Out "int main(){\n"; + my $i = -1; + foreach my $type (@$typelist){ + $i++; + print Out " printf(\"A$i: %lu\\n\", sizeof($type));\n"; + } + print Out " return 0;\n"; + print Out "}\n"; + close Out; + my $t=`$CC t.c -o t && ./t`; + while($t=~/A(\d+):\s+(\d+)/g){ + my $name = get_type_name($typelist->[$1]); + $cross_hash{$name} = $2; + } +} + +sub get_c_sizes_asm { + my ($typelist) = @_; + open Out, ">t.c" or die "Can't write t.c.\n"; + my $i = -1; + foreach my $type (@$typelist){ + $i++; + print Out "$type A$i;\n"; + } + close Out; + my $t=`$CC -S t.c -o t.s`; + open In, "t.s" or die "Can't open t.s.\n"; + while(){ + if(/.comm\s+A(\d+),(\d+),(\d+)/){ + my $name = get_type_name($typelist->[$1]); + $cross_hash{$name} = $2; + } + } + close In; +} + +sub get_f77_sizes_direct { + my ($typelist) = @_; + my $sp = ' 'x6; + my $sp = ' 'x6; + open Out, ">t.f" or die "Can't write t.f.\n"; + print Out "$sp PROGRAM t\n"; + my $i = -1; + foreach my $T (@$typelist){ + $i++; + if($T=~/KIND-(\d+)-(\d+)/){ + print Out "$sp INTEGER (KIND=$2) :: A$i\n"; + } + else{ + my $t = $T; + $t=~s/_/ /g; + print Out "$sp $t :: A$i\n"; + } + } + print Out "\n"; + my $i = -1; + foreach my $T (@$typelist){ + $i++; + print Out "$sp print *, 'A$i:', sizeof(A$i)\n"; + } + print Out "$sp END\n"; + close Out; + my $t=`$FC t.f -o t && ./t`; + while($t=~/A(\d+):\s+(\d+)/g){ + my $name = $typelist->[$1]; + $cross_hash{$name}=$2; + } +} + +sub get_f77_sizes_asm { + my ($typelist) = @_; + my $sp; + open Out, ">t.f90" or die "Can't write t.f90.\n"; + print " --> [t.f90]\n"; + print Out "MODULE t\n"; + my $i = -1; + foreach my $T (@$typelist){ + $i++; + if($T=~/KIND-(\d+)-(\d+)/){ + print Out "$sp INTEGER (KIND=$2) :: A$i\n"; + } + else{ + my $t = $T; + $t=~s/_/ /g; + print Out "$sp $t :: A$i\n"; + } + } + print Out "\n"; + print Out "END MODULE t\n"; + close Out; + my $t=`$FC -S t.f90 -o t.s`; + open In, "t.s" or die "Can't open t.s.\n"; + while(){ + if(/.size\s+__t_MOD_a(\d+),\s*(\d+)/){ + my $name = $typelist->[$1]; + $cross_hash{$name}=$2; + } elsif(/.zerofill\s+.*__t_MOD_a(\d+),\s*(\d+),\s*(\d+)/){ + my $name = $typelist->[$1]; + $cross_hash{$name}=$2; + } + } + close In; +} + +sub get_f77_sizes_hybrid { + my ($typelist) = @_; + open Out, ">t.c" or die "Can't write t.c.\n"; + print Out "int cisize_(char *, char *);\n"; + print Out "int cisize_(char *p1, char *p2){return (int)(p2-p1);}\n"; + close Out; + system "$CC -c -o tlib.o t.c"; + my $sp = ' 'x6; + my $sp = ' 'x6; + open Out, ">t.f" or die "Can't write t.f.\n"; + print Out "$sp PROGRAM t\n"; + print Out "$sp INTEGER cisize\n"; + my $i = -1; + foreach my $T (@$typelist){ + $i++; + if($T=~/KIND-(\d+)-(\d+)/){ + print Out "$sp INTEGER (KIND=$2) :: A$i(2)\n"; + } + else{ + my $t = $T; + $t=~s/_/ /g; + print Out "$sp $t :: A$i(2)\n"; + } + } + print Out "\n"; + my $i = -1; + foreach my $T (@$typelist){ + $i++; + print Out "$sp print *, 'A$i:', cisize(A$i(1), A$i(2))\n"; + } + print Out "$sp END\n"; + close Out; + my $t = `$FC t.f tlib.o -o t && ./t`; + while($t=~/A(\d+):\s+(\d+)/g){ + my $name = $typelist->[$1]; + $cross_hash{$name}=$2; + } +} + +sub get_f77_true_false_hybrid { + open Out, ">t.c" or die "Can't write t.c.\n"; + print Out "#include \n"; + print Out "void ftest_(int *, int *);\n"; + print Out "void ftest_(int * t, int * f){printf(\"T:%d F:%d\\n\", *t, *f);}\n"; + close Out; + system "$CC -c -o tlib.o t.c"; + my $sp = ' 'x6; + my $sp = ' 'x6; + open Out, ">t.f" or die "Can't write t.f.\n"; + print Out "$sp PROGRAM t\n"; + print Out "$sp LOGICAL itrue, ifalse\n"; + print Out "$sp itrue = .TRUE.\n"; + print Out "$sp ifalse = .FALSE.\n"; + print Out "$sp call ftest(itrue, ifalse)\n"; + print Out "$sp END\n"; + close Out; + my $t = `$FC t.f tlib.o -o t && ./t`; + if($t=~/T:(-?\d+)\s*F:(-?\d+)/){ + $cross_hash{TRUE_VALUE}=$1; + $cross_hash{FALSE_VALUE}=$2; + } +} + +sub get_f90_kinds_direct { + open Out, ">t.f90" or die "Can't write t.f90.\n"; + print Out "PROGRAM t\n"; + print Out "INTEGER I, k, lastkind\n"; + print Out "\n"; + print Out "lastkind=SELECTED_INT_KIND(1)\n"; + print Out "DO I=2,30\n"; + print Out "k = SELECTED_INT_KIND(I)\n"; + print Out "IF (k .ne. lastkind) THEN\n"; + print Out "PRINT *, 'K:',I-1, ', ', lastkind\n"; + print Out "lastkind = k\n"; + print Out "ENDIF\n"; + print Out "IF (k .le. 0) THEN\n"; + print Out "exit\n"; + print Out "ENDIF\n"; + print Out "ENDDO\n"; + print Out "IF (k .ne. lastkind) THEN\n"; + print Out "PRINT *, 31, ', ', k\n"; + print Out "ENDIF\n"; + print Out "END\n"; + close Out; + my $t=`$FC t.f90 -o t && ./t`; + my @range_kind_size; + while($t=~/K:\s*(\d+)\s*,\s*(\d+)/g){ + push @range_kind_size, [$1, $2]; + } + return \@range_kind_size; +} + +sub get_f90_names_direct { + my ($namelist) = @_; + my %byte_map=("ADDRESS"=>$cross_hash{void_p}, "OFFSET"=>8, "INTEGER"=>$cross_hash{INTEGER}); + my %size_map=(1=>2, 2=>4, 4=>8, 8=>16, 16=>30); + open Out, ">t.f90" or die "Can't write t.f90.\n"; + print Out "PROGRAM t\n"; + foreach my $name (@$namelist){ + if($name=~/(\w+)_MODEL/){ + my $T=$1; + if($T eq "DOUBLE"){ + $T="DOUBLE PRECISION"; + } + print Out "$T :: A_$1\n"; + } + } + print Out "\n"; + + foreach my $name (@$namelist){ + if($name=~/(\w+)_KIND/){ + my $n = $size_map{$byte_map{$1}}; + print Out "PRINT *, '$name:', SELECTED_INT_KIND($n)\n"; + } + elsif($name=~/(REAL|DOUBLE)_MODEL/){ + print Out "PRINT *, '$name:', precision(A_$1), ',', range(A_$1)\n"; + } + elsif($name=~/(INTEGER)_MODEL/){ + print Out "PRINT *, '$name:', range(A_$1)\n"; + } + } + print Out "END\n"; + close Out; + my $t = `$FC t.f90 -o t && ./t`; + while($t=~/(\w+):\s*([\d, ]+)/g){ + $cross_hash{$1}=$2; + $cross_hash{$1}=~s/ +//g; + } +} + +sub get_type_name { + my ($type) = @_; + my $t = $type; + $t=~s/ /_/g; + $t=~s/\*/p/g; + return $t; +} + From 3957f9da4f6d5839ff6955800e778e94697ae8aa Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 20 Jan 2022 22:16:48 -0600 Subject: [PATCH 536/607] misc: update configure help text on cross files The error message is out-of-date. Update it with instruction on using the new script maint/gen_cross.pl. --- .gitignore | 1 - configure.ac | 11 ++++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 2ab80263d3b..59d0bad5245 100644 --- a/.gitignore +++ b/.gitignore @@ -370,7 +370,6 @@ Makefile.am-stamp /maint/getcoverage /maint/createcoverage /maint/showsizes -/maint/getcross /maint/makerpm /maint/clmake /maint/conftimestamp diff --git a/configure.ac b/configure.ac index 868bf1cd777..2a31d32e83a 100644 --- a/configure.ac +++ b/configure.ac @@ -2841,11 +2841,12 @@ for type in short int long float double \ eval len=\$ac_cv_sizeof_$type if test -z "$len" ; then AC_MSG_ERROR([Configure was unable to determine the size of $type ; if cross compiling, -use the environment variables CROSS_SIZEOF_typename, e.g., CROSS_SIZEOF_SHORT, -or use the --with-cross=file configure option to specify a file containing -Bourne (sh) shell assignments to CROSS_SIZEOF_typename for all datatype -types. The program maint/getcross.c can be compiled and run on the target -system; this program outputs an appropriate file for the --with-cross option]) +use the --with-cross=file configure option to specify a file containing +Bourne (sh) shell assignments to sizeof values for all datatype types. +The Perl script maint/gen_cross.pl can be run on the target +system to generate an appropriate file for the --with-cross option. You +may also run the script on local system and use the generated file as +template and manually set the correct values.]) fi done From a3f73784c21ee0143995ba4b861d82c1914d014d Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 18 Mar 2022 15:06:25 -0500 Subject: [PATCH 537/607] init: add explicit MPIR_pmi_barrier in init Add explicit MPIR_pmi_barrier to hold the process to give debugger an opportunity to attach. There are other mechanism, e.g. using MPIR_CVAR_DEBUG_HOLD. But this is the default mechanism and conforms to the MPIR Process Acquisition Interface spec. --- src/mpi/init/mpir_init.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/mpi/init/mpir_init.c b/src/mpi/init/mpir_init.c index ce8e89a7fef..d84f361f4f5 100644 --- a/src/mpi/init/mpir_init.c +++ b/src/mpi/init/mpir_init.c @@ -207,6 +207,21 @@ int MPII_Init_thread(int *argc, char ***argv, int user_required, int *provided, mpi_errno = MPID_Init(required, &MPIR_ThreadInfo.thread_provided); MPIR_ERR_CHECK(mpi_errno); + /* The current default mechanism of MPIR Process Acquisition Interface is to + * break on MPIR_Breakpoint in mpiexec.hydra. Adding a PMI call that need + * response from mpiexec will hold the MPI process to provide opportunity for + * debugger to attach. Currently, the only effective call is PMI_Barrier. + */ + /* NOTE: potentially we already calls PMI barrier during device business + * card exchange. But there may be optimizations that make it not true. + * We are adding a separate PMI barrier call here to ensure the debugger + * mechanism. And it is also cleaner. If init latency is a concern, we may + * add a config option to skip it. But focus on optimize PMI Barrier may + * be a better effort. + */ + mpi_errno = MPIR_pmi_barrier(); + MPIR_ERR_CHECK(mpi_errno); + bool need_init_builtin_comms = true; #ifdef ENABLE_LOCAL_SESSION_INIT need_init_builtin_comms = is_world_model; From 6b9896433937a3a760e9f75a4b5b81696eb598f3 Mon Sep 17 00:00:00 2001 From: Brice Videau Date: Thu, 10 Mar 2022 18:33:28 -0600 Subject: [PATCH 538/607] mpl: fix level zero properties initialization The fields stype and pNext of level zero structures that contain them must be initialized before passing them to the runtime. --- src/mpl/src/gpu/mpl_gpu_ze.c | 2 ++ test/mpi/util/mtest_common.c | 12 ++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/mpl/src/gpu/mpl_gpu_ze.c b/src/mpl/src/gpu/mpl_gpu_ze.c index 75f684d73a6..d912fa2784c 100644 --- a/src/mpl/src/gpu/mpl_gpu_ze.c +++ b/src/mpl/src/gpu/mpl_gpu_ze.c @@ -112,6 +112,8 @@ static int gpu_ze_init_driver(void) /* Check if the driver supports a gpu */ for (d = 0; d < global_ze_device_count; ++d) { ze_device_properties_t device_properties; + device_properties.stype = ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES; + device_properties.pNext = NULL; ret = zeDeviceGetProperties(global_ze_devices_handle[d], &device_properties); ZE_ERR_CHECK(ret); diff --git a/test/mpi/util/mtest_common.c b/test/mpi/util/mtest_common.c index 83cee5813ce..c447fb50038 100644 --- a/test/mpi/util/mtest_common.c +++ b/test/mpi/util/mtest_common.c @@ -386,6 +386,8 @@ void MTestAlloc(size_t size, mtest_mem_type_e type, void **hostbuf, void **devic for (int j = 0; j < num_devices; j++) { ze_device_properties_t device_properties; + device_properties.stype = ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES; + device_properties.pNext = NULL; zerr = zeDeviceGetProperties(all_devices[j], &device_properties); assert(zerr == ZE_RESULT_SUCCESS); @@ -429,6 +431,10 @@ void MTestAlloc(size_t size, mtest_mem_type_e type, void **hostbuf, void **devic ze_command_queue_group_properties_t *queueProperties = (ze_command_queue_group_properties_t *) malloc(sizeof(ze_command_queue_group_properties_t) * numQueueGroups); + for (int i = 0; i < numQueueGroups; i++) { + queueProperties[i].stype = ZE_STRUCTURE_TYPE_COMMAND_QUEUE_GROUP_PROPERTIES; + queueProperties[i].pNext = NULL; + } zerr = zeDeviceGetCommandQueueGroupProperties(device[0], &numQueueGroups, queueProperties); descriptor.ordinal = -1; for (int i = 0; i < numQueueGroups; i++) { @@ -640,8 +646,10 @@ void MTestCopyContent(const void *sbuf, void *dbuf, size_t size, mtest_mem_type_ ze_memory_allocation_properties_t prop; ze_device_handle_t device; } s_attr, d_attr; - memset(&s_attr.prop, 0, sizeof(ze_memory_allocation_properties_t)); - memset(&d_attr.prop, 0, sizeof(ze_memory_allocation_properties_t)); + s_attr.prop.stype = ZE_STRUCTURE_TYPE_MEMORY_ALLOCATION_PROPERTIES; + s_attr.prop.pNext = NULL; + d_attr.prop.stype = ZE_STRUCTURE_TYPE_MEMORY_ALLOCATION_PROPERTIES; + d_attr.prop.pNext = NULL; zerr = zeMemGetAllocProperties(context, sbuf, &s_attr.prop, &s_attr.device); assert(zerr == ZE_RESULT_SUCCESS); if (s_attr.device) { From 5b57b0d9f24c8430973bb29dcdf1d5378418f4f7 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 19 Mar 2022 22:11:06 -0500 Subject: [PATCH 539/607] ch3: remove unneeded configure check These configure check, I believe, were made undeeded when we adopted MPL_sockaddr. --- src/mpid/ch3/channels/nemesis/subconfigure.m4 | 52 --------------- src/mpid/ch3/util/sock/ch3u_getinterfaces.c | 17 ----- src/mpid/ch3/util/sock/subconfigure.m4 | 65 ------------------- 3 files changed, 134 deletions(-) diff --git a/src/mpid/ch3/channels/nemesis/subconfigure.m4 b/src/mpid/ch3/channels/nemesis/subconfigure.m4 index ad5de9d8f94..f0c8c17594a 100644 --- a/src/mpid/ch3/channels/nemesis/subconfigure.m4 +++ b/src/mpid/ch3/channels/nemesis/subconfigure.m4 @@ -196,58 +196,6 @@ AC_DEFINE(MPID_NEM_INLINE,1,[Define to turn on the inlining optimizations in Nem AC_DEFINE(PREFETCH_CELL,1,[Define to turn on the prefetching optimization in Nemesis code]) AC_DEFINE(USE_FASTBOX,1,[Define to use the fastboxes in Nemesis code]) -# We may need this only for tcp and related netmodules -# Check for h_addr or h_addr_list -AC_CACHE_CHECK([whether struct hostent contains h_addr_list], pac_cv_have_haddr_list,[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include - ]],[[ - struct hostent hp;hp.h_addr_list[0]=0; - ]])], pac_cv_have_haddr_list=yes,pac_cv_have_haddr_list=no) -]) -if test "$pac_cv_have_haddr_list" = "yes" ; then - AC_DEFINE(HAVE_H_ADDR_LIST,1,[Define if struct hostent contains h_addr_list]) -fi - -# If we need the socket code, see if we can use struct ifconf -# sys/socket.h is needed on Solaris -AC_CACHE_CHECK([whether we can use struct ifconf], pac_cv_have_struct_ifconf,[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include - #ifdef HAVE_SYS_SOCKET_H - #include - #endif - #include - ]],[[ - struct ifconf conftest; int s; s = sizeof(conftest); - ]])], pac_cv_have_struct_ifconf=yes,pac_cv_have_struct_ifconf=no) -]) - -# Intentionally not testing whether _SVID_SOURCE or _POSIX_C_SOURCE affects -# ifconf availability. Making those sort of modifications at this stage -# invalidates nearly all of our previous tests, since those macros fundamentally -# change many features of the compiler on most platforms. See ticket #1568. - -if test "$pac_cv_have_struct_ifconf" = "yes" ; then - AC_DEFINE(HAVE_STRUCT_IFCONF,1,[Define if struct ifconf can be used]) -fi - -AC_CACHE_CHECK([whether we can use struct ifreq], pac_cv_have_struct_ifreq,[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include - #ifdef HAVE_SYS_SOCKET_H - #include - #endif - #include - ]],[[ - struct ifreq conftest; int s; s = sizeof(conftest); - ]])], pac_cv_have_struct_ifreq=yes,pac_cv_have_struct_ifreq=no) -]) - -if test "$pac_cv_have_struct_ifreq" = "yes" ; then - AC_DEFINE(HAVE_STRUCT_IFREQ,1,[Define if struct ifreq can be used]) -fi - # allow the user to select different local LMT implementations AC_ARG_WITH(nemesis-local-lmt, [--with-nemesis-local-lmt=method - specify an implementation for local large message transfers (LMT). Method is one of: 'default', 'shm_copy', or 'none'. 'default' is the same as 'shm_copy'.],,with_nemesis_local_lmt=default) case "$with_nemesis_local_lmt" in diff --git a/src/mpid/ch3/util/sock/ch3u_getinterfaces.c b/src/mpid/ch3/util/sock/ch3u_getinterfaces.c index 0497167d445..6180e6abe92 100644 --- a/src/mpid/ch3/util/sock/ch3u_getinterfaces.c +++ b/src/mpid/ch3/util/sock/ch3u_getinterfaces.c @@ -3,24 +3,7 @@ * See COPYRIGHT in top-level directory */ -/* We need to include the conf file first so that we can use - the _SVID_SOURCE if needed before any file includes features.h - on GNU systems */ #include "mpichconf.h" - - -#ifdef USE_NOPOSIX_FOR_IFCONF -/* This is a very special case. Allow the use of some extensions for - just the rest of this file so that we can get the ifconf structure */ -#undef _POSIX_C_SOURCE -#endif - -#ifdef USE_SVIDSOURCE_FOR_IFCONF -/* This is a very special case. Allow the use of some extensions for just - the rest of this file so that we can get the ifconf structure */ -#define _SVID_SOURCE -#endif - #include "mpidi_ch3_impl.h" #include diff --git a/src/mpid/ch3/util/sock/subconfigure.m4 b/src/mpid/ch3/util/sock/subconfigure.m4 index b310744690d..63590ea7d28 100644 --- a/src/mpid/ch3/util/sock/subconfigure.m4 +++ b/src/mpid/ch3/util/sock/subconfigure.m4 @@ -28,71 +28,6 @@ AC_DEFUN([PAC_SUBCFG_BODY_]PAC_SUBCFG_AUTO_SUFFIX,[ dnl AC_CHECK_FUNCS(CFUUIDCreate uuid_generate time) dnl AC_SEARCH_LIBS(uuid_generate, uuid) - # If we need the socket code, see if we can use struct ifconf - # sys/socket.h is needed on Solaris - AC_CACHE_CHECK([whether we can use struct ifconf], pac_cv_have_struct_ifconf,[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include - #ifdef HAVE_SYS_SOCKET_H - #include - #endif - #include - ]],[[ - struct ifconf conftest; - ]])], pac_cv_have_struct_ifconf=yes,pac_cv_have_struct_ifconf=no) - ]) - - if test "$pac_cv_have_struct_ifconf" = "no" ; then - # Try again with _SVID_SOURCE - AC_CACHE_CHECK([whether we can use struct ifconf with _SVID_SOURCE], - [pac_cv_have_struct_ifconf_with_svid],[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #define _SVID_SOURCE - #include - #ifdef HAVE_SYS_SOCKET_H - #include - #endif - #include - ]],[[ - struct ifconf conftest; - ]])], - pac_cv_have_struct_ifconf_with_svid=yes, - pac_cv_have_struct_ifconf_with_svid=no) - ]) - if test "$pac_cv_have_struct_ifconf_with_svid" = yes ; then - AC_DEFINE(USE_SVIDSOURCE_FOR_IFCONF,1,[Define if _SVID_SOURCE needs to be defined for struct ifconf]) - fi - fi - - if test "$pac_cv_have_struct_ifconf" = "no" -a \ - "$pac_cv_have_struct_ifconf_with_svid" = "no" ; then - # Try again with undef _POSIX_C_SOURCE - AC_CACHE_CHECK([whether we can use struct ifconf without _POSIX_C_SOURCE], - pac_cv_have_struct_ifconf_without_posix,[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #undef _POSIX_C_SOURCE - #include - #ifdef HAVE_SYS_SOCKET_H - #include - #endif - #include - ]],[[ - struct ifconf conftest; - ]])], - pac_cv_have_struct_ifconf_without_posix=yes, - pac_cv_have_struct_ifconf_without_posix=no) - ]) - if test "$pac_cv_have_struct_ifconf_without_posix" = yes ; then - AC_DEFINE(USE_NOPOSIX_FOR_IFCONF,1,[Define if _POSIX_C_SOURCE needs to be undefined for struct ifconf]) - fi - fi - - if test "$pac_cv_have_struct_ifconf" = "yes" -o \ - "$pac_cv_have_struct_ifconf_with_svid" = "yes" -o \ - "$pac_cv_have_struct_ifconf_without_posix" ; then - AC_DEFINE(HAVE_STRUCT_IFCONF,1,[Define if struct ifconf can be used]) - fi - ])dnl end AM_COND_IF(BUILD_CH3U_SOCK,...) ])dnl end _BODY From 48759d2718fc343e976f8cba73b26abf64bf3d7f Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 19 Mar 2022 22:16:42 -0500 Subject: [PATCH 540/607] ch3/nemesis: remove unneeded function prototypes These interface functions were deleted when we adopted MPL_sockaddr. --- .../ch3/channels/nemesis/netmod/tcp/tcp_impl.h | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/mpid/ch3/channels/nemesis/netmod/tcp/tcp_impl.h b/src/mpid/ch3/channels/nemesis/netmod/tcp/tcp_impl.h index e25dcb5a6c4..6cebebe5ff3 100644 --- a/src/mpid/ch3/channels/nemesis/netmod/tcp/tcp_impl.h +++ b/src/mpid/ch3/channels/nemesis/netmod/tcp/tcp_impl.h @@ -167,22 +167,6 @@ int MPID_nem_tcp_pkt_unpause_handler(MPIDI_VC_t * vc, MPIDI_CH3_Pkt_t * pkt, #define S_PUSH_MULTIPLE(sp, ep0, ep1) GENERIC_S_PUSH_MULTIPLE (sp, ep0, ep1, next) #define S_POP(sp, ep) GENERIC_S_POP (sp, ep, next) -/* interface utilities */ -/*S - MPIDI_CH3I_nem_tcp_ifaddr_t - Structure to hold an Internet address. - -+ len - Length of the address. 4 for IPv4, 16 for IPv6. -- ifaddr - Address bytes (as bytes, not characters) - -S*/ -typedef struct MPIDI_CH3I_nem_tcp_ifaddr_t { - unsigned int len; - int type; - unsigned char ifaddr[16]; -} MPIDI_CH3I_nem_tcp_ifaddr_t; -int MPIDI_GetIPInterface(MPIDI_CH3I_nem_tcp_ifaddr_t * ifaddr, int *found); -int MPIDI_Get_IP_for_iface(const char *ifname, MPIDI_CH3I_nem_tcp_ifaddr_t * ifaddr, int *found); - /* Keys for business cards */ #define MPIDI_CH3I_PORT_KEY "port" #define MPIDI_CH3I_HOST_DESCRIPTION_KEY "description" From ac7295bfcf0dd8e4619063ca782c214c12a46982 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 4 Mar 2022 13:20:57 -0600 Subject: [PATCH 541/607] pmi2: do not expose MPIR_Info MPIR_Info is an mpich internal data type. It should not be exposed in a PMI interface. Define and use PMI2_keyval_t instead. NOTE: this commit changes following PMI-v2 APIs: * PMI2_Job_Spawn * PMI2_Nameserv_publish * PMI2_Nameserv_lookup * PMI2_Nameserv_unpublish The old interfaces for the above routines depends on MPICH's internal MPIR_Info structure. Thus it should never have worked other than the trivial case where the info pointers are NULL. This change does not affect the applications that use NULL info pointers. --- src/include/mpir_pmi.h | 3 +++ src/nameserv/pmi/pmi_nameserv.c | 6 ++--- src/pmi/pmi2/include/pmi2.h | 27 +++++++++++--------- src/pmi/pmi2/simple/simple2pmi.c | 17 ++++++------ src/util/mpir_pmi.c | 44 ++++++++------------------------ 5 files changed, 40 insertions(+), 57 deletions(-) diff --git a/src/include/mpir_pmi.h b/src/include/mpir_pmi.h index b28e8fe8ac7..45a5ffc4d77 100644 --- a/src/include/mpir_pmi.h +++ b/src/include/mpir_pmi.h @@ -14,8 +14,11 @@ #ifdef USE_PMI1_API #include + #elif defined(USE_PMI2_API) #include +#define PMI_keyval_t PMI2_keyval_t + #elif defined(USE_PMIX_API) #include #endif diff --git a/src/nameserv/pmi/pmi_nameserv.c b/src/nameserv/pmi/pmi_nameserv.c index 2b211a7f36f..9f8a367cd77 100644 --- a/src/nameserv/pmi/pmi_nameserv.c +++ b/src/nameserv/pmi/pmi_nameserv.c @@ -40,7 +40,7 @@ int MPID_NS_Publish(MPID_NS_Handle handle, const MPIR_Info * info_ptr, #ifdef USE_PMI2_API /* release the global CS for PMI calls */ MPID_THREAD_CS_EXIT(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); - rc = PMI2_Nameserv_publish(service_name, info_ptr, port); + rc = PMI2_Nameserv_publish(service_name, NULL, port); MPID_THREAD_CS_ENTER(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); #elif defined(USE_PMIX_API) MPIR_Assert(0); @@ -65,7 +65,7 @@ int MPID_NS_Lookup(MPID_NS_Handle handle, const MPIR_Info * info_ptr, #ifdef USE_PMI2_API /* release the global CS for PMI calls */ MPID_THREAD_CS_EXIT(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); - rc = PMI2_Nameserv_lookup(service_name, info_ptr, port, MPI_MAX_PORT_NAME); + rc = PMI2_Nameserv_lookup(service_name, NULL, port, MPI_MAX_PORT_NAME); MPID_THREAD_CS_ENTER(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); #elif defined(USE_PMIX_API) MPIR_Assert(0); @@ -89,7 +89,7 @@ int MPID_NS_Unpublish(MPID_NS_Handle handle, const MPIR_Info * info_ptr, const c #ifdef USE_PMI2_API /* release the global CS for PMI calls */ MPID_THREAD_CS_EXIT(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); - rc = PMI2_Nameserv_unpublish(service_name, info_ptr); + rc = PMI2_Nameserv_unpublish(service_name, NULL); MPID_THREAD_CS_ENTER(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); #elif defined(USE_PMIX_API) MPIR_Assert(0); diff --git a/src/pmi/pmi2/include/pmi2.h b/src/pmi/pmi2/include/pmi2.h index 7072fd54efa..ebcd8ec0a63 100644 --- a/src/pmi/pmi2/include/pmi2.h +++ b/src/pmi/pmi2/include/pmi2.h @@ -58,13 +58,18 @@ D*/ #define PMI2_ERR_INVALID_SIZE 13 #define PMI2_ERR_OTHER 14 -/* This is here to allow spawn multiple functions to compile. This - needs to be removed once those functions are fixed for pmi2 */ - typedef struct PMI_keyval_t { +/*S +PMI2_keyval_t - keyval structure used by PMI2_Spawn_multiple + +Fields: ++ key - name of the key +- val - value of the key + +S*/ + typedef struct PMI2_keyval_t { char *key; char *val; - } PMI_keyval_t; - + } PMI2_keyval_t; /*@ PMI2_Connect_comm_t - connection structure used when connecting to other jobs @@ -99,8 +104,6 @@ D*/ int isMain; } PMI2_Connect_comm_t; - struct MPIR_Info; - /*@ PMI2_Init - initialize the Process Manager Interface @@ -197,9 +200,9 @@ D*/ int argcs[], const char **argvs[], const int maxprocs[], const int info_keyval_sizes[], - const struct MPIR_Info *info_keyval_vectors[], + const PMI2_keyval_t * info_keyval_vectors[], int preput_keyval_size, - const struct MPIR_Info *preput_keyval_vector[], + const PMI2_keyval_t preput_keyval_vector[], char jobId[], int jobIdSize, int errors[]); @@ -508,7 +511,7 @@ D*/ Returns 'MPI_SUCCESS' on success and an MPI error code on failure. @*/ - int PMI2_Nameserv_publish(const char service_name[], const struct MPIR_Info *info_ptr, + int PMI2_Nameserv_publish(const char service_name[], const PMI2_keyval_t * info_ptr, const char port[]); /*@ @@ -526,7 +529,7 @@ D*/ Returns 'MPI_SUCCESS' on success and an MPI error code on failure. @*/ - int PMI2_Nameserv_lookup(const char service_name[], const struct MPIR_Info *info_ptr, + int PMI2_Nameserv_lookup(const char service_name[], const PMI2_keyval_t * info_ptr, char port[], int portLen); /*@ PMI2_Nameserv_unpublish - unpublish a name @@ -539,7 +542,7 @@ D*/ Returns 'MPI_SUCCESS' on success and an MPI error code on failure. @*/ - int PMI2_Nameserv_unpublish(const char service_name[], const struct MPIR_Info *info_ptr); + int PMI2_Nameserv_unpublish(const char service_name[], const PMI2_keyval_t * info_ptr); diff --git a/src/pmi/pmi2/simple/simple2pmi.c b/src/pmi/pmi2/simple/simple2pmi.c index 00249bc7bdf..a54be5d9021 100644 --- a/src/pmi/pmi2/simple/simple2pmi.c +++ b/src/pmi/pmi2/simple/simple2pmi.c @@ -421,9 +421,9 @@ int PMI2_Job_Spawn(int count, const char *cmds[], int argcs[], const char **argvs[], const int maxprocs[], const int info_keyval_sizes[], - const struct MPIR_Info *info_keyval_vectors[], + const PMI2_keyval_t * info_keyval_vectors[], int preput_keyval_size, - const struct MPIR_Info *preput_keyval_vector[], + const PMI2_keyval_t preput_keyval_vector[], char jobId[], int jobIdSize, int errors[]) { int i, rc, spawncnt, total_num_processes, num_errcodes_found; @@ -486,8 +486,8 @@ cmd=spawn;thrid=string;ncmds=count;preputcount=n;ppkey0=name;ppval0=string;...;\ init_kv_strdup_int(pairs_p[npairs++], "preputcount", preput_keyval_size); for (i = 0; i < preput_keyval_size; ++i) { - init_kv_strdup_intsuffix(pairs_p[npairs++], "ppkey", i, preput_keyval_vector[i]->key); - init_kv_strdup_intsuffix(pairs_p[npairs++], "ppval", i, preput_keyval_vector[i]->value); + init_kv_strdup_intsuffix(pairs_p[npairs++], "ppkey", i, preput_keyval_vector[i].key); + init_kv_strdup_intsuffix(pairs_p[npairs++], "ppval", i, preput_keyval_vector[i].val); } for (spawncnt = 0; spawncnt < count; ++spawncnt) { @@ -507,7 +507,7 @@ cmd=spawn;thrid=string;ncmds=count;preputcount=n;ppkey0=name;ppval0=string;...;\ init_kv_strdup_intsuffix(pairs_p[npairs++], "infokey", i, info_keyval_vectors[spawncnt][i].key); init_kv_strdup_intsuffix(pairs_p[npairs++], "infoval", i, - info_keyval_vectors[spawncnt][i].value); + info_keyval_vectors[spawncnt][i].val); } } } @@ -983,7 +983,8 @@ int PMI2_Info_GetJobAttrIntArray(const char name[], int array[], int arraylen, i goto fn_exit; } -int PMI2_Nameserv_publish(const char service_name[], const PMI2U_Info * info_ptr, const char port[]) +int PMI2_Nameserv_publish(const char service_name[], const PMI2_keyval_t * info_ptr, + const char port[]) { int pmi2_errno = PMI2_SUCCESS; PMI2_Command cmd = { 0 }; @@ -1012,7 +1013,7 @@ int PMI2_Nameserv_publish(const char service_name[], const PMI2U_Info * info_ptr } -int PMI2_Nameserv_lookup(const char service_name[], const PMI2U_Info * info_ptr, +int PMI2_Nameserv_lookup(const char service_name[], const PMI2_keyval_t * info_ptr, char port[], int portLen) { int pmi2_errno = PMI2_SUCCESS; @@ -1047,7 +1048,7 @@ int PMI2_Nameserv_lookup(const char service_name[], const PMI2U_Info * info_ptr, goto fn_exit; } -int PMI2_Nameserv_unpublish(const char service_name[], const PMI2U_Info * info_ptr) +int PMI2_Nameserv_unpublish(const char service_name[], const PMI2_keyval_t * info_ptr) { int pmi2_errno = PMI2_SUCCESS; int found; diff --git a/src/util/mpir_pmi.c b/src/util/mpir_pmi.c index 629af28ee61..09b4ec69719 100644 --- a/src/util/mpir_pmi.c +++ b/src/util/mpir_pmi.c @@ -852,7 +852,7 @@ int MPIR_pmi_spawn_multiple(int count, char *commands[], char **argvs[], int mpi_errno = MPI_SUCCESS; int pmi_errno; -#ifdef USE_PMI1_API +#if defined(USE_PMI1_API) || defined(USE_PMI2_API) int *info_keyval_sizes = NULL; PMI_keyval_t **info_keyval_vectors = NULL; @@ -875,7 +875,9 @@ int MPIR_pmi_spawn_multiple(int count, char *commands[], char **argvs[], MPIR_ERR_CHECK(mpi_errno); } } +#endif +#ifdef USE_PMI1_API pmi_errno = PMI_Spawn_multiple(count, (const char **) commands, (const char ***) argvs, maxprocs, info_keyval_sizes, @@ -886,12 +888,8 @@ int MPIR_pmi_spawn_multiple(int count, char *commands[], char **argvs[], MPIR_ERR_CHKANDJUMP1(pmi_errno != PMI_SUCCESS, mpi_errno, MPI_ERR_OTHER, "**pmi_spawn_multiple", "**pmi_spawn_multiple %d", pmi_errno); #elif defined(USE_PMI2_API) - struct MPIR_Info preput; - struct MPIR_Info *preput_p[1] = { &preput }; int *argcs = MPL_malloc(count * sizeof(int), MPL_MEM_DYNAMIC); - int *info_keyval_sizes = MPL_malloc(count * sizeof(int), MPL_MEM_DYNAMIC); MPIR_Assert(argcs); - MPIR_Assert(info_keyval_sizes); /* compute argcs array */ for (int i = 0; i < count; ++i) { @@ -903,45 +901,23 @@ int MPIR_pmi_spawn_multiple(int count, char *commands[], char **argvs[], } } - /* FIXME cheating on constness */ - preput.key = (char *) preput_keyvals->key; - preput.value = preput_keyvals->val; - preput.next = NULL; - - /* determine info sizes */ - if (!info_ptrs) { - for (int i = 0; i < count; i++) { - info_keyval_sizes[i] = 0; - } - } else { - for (int i = 0; i < count; i++) { - if (info_ptrs[i] != NULL) { - MPIR_Info_get_nkeys_impl(info_ptrs[i], &info_keyval_sizes[i]); - info_ptrs[i] = info_ptrs[i]->next; /* skip empty MPIR_Info struct */ - } else { - info_keyval_sizes[i] = 0; - } - } - } - pmi_errno = PMI2_Job_Spawn(count, (const char **) commands, argcs, (const char ***) argvs, maxprocs, - info_keyval_sizes, (const MPIR_Info **) info_ptrs, - 1, (const struct MPIR_Info **) preput_p, NULL, 0, pmi_errcodes); + info_keyval_sizes, + (const PMI_keyval_t **) info_keyval_vectors, + num_preput_keyval, (const PMI_keyval_t *) preput_keyvals, + NULL, 0, pmi_errcodes); MPL_free(argcs); - MPL_free(info_keyval_sizes); - if (pmi_errno != PMI2_SUCCESS) { - MPIR_ERR_SETANDJUMP1(mpi_errno, MPI_ERR_OTHER, - "**pmi_spawn_multiple", "**pmi_spawn_multiple %d", pmi_errno); - } + MPIR_ERR_CHKANDJUMP1(mpi_errno != PMI2_SUCCESS, mpi_errno, MPI_ERR_OTHER, + "**pmi_spawn_multiple", "**pmi_spawn_multiple %d", pmi_errno); #elif defined(USE_PMIX_API) /* not supported yet */ MPIR_Assert(0); #endif fn_exit: -#ifdef USE_PMI1_API +#if defined(USE_PMI1_API) || defined(USE_PMI2_API) if (info_keyval_vectors) { free_pmi_keyvals(info_keyval_vectors, count, info_keyval_sizes); MPL_free(info_keyval_vectors); From 21d4721f94c9aaba4b8cb43ff0d084f3df8a3d72 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 4 Mar 2022 17:06:12 -0600 Subject: [PATCH 542/607] pmi2: remove reference of MPICH internals Because the pmi implementation may be used without MPICH, we should not refer to any MPICH internals. This commit removes references of - * mpiimpl.h * MPIR_Assert * MPIR_Memcpy * MPICH_IS_THREADED * MPIR_THREAD_CHECK_BEGIN Because we need a way to tell the implementation whether thread protection is required, this commit adds a necessary API - * PMI2_Set_threaded(int is_threaded) Ideally, we should add parameters to PMI2_Init to pass the thread-level requirement. Use a spearate API keeps backward compatibility. --- src/pmi/pmi2/include/pmi2.h | 13 +++++++ src/pmi/pmi2/simple/pmi2compat.h | 8 ++-- src/pmi/pmi2/simple/simple2pmi.c | 56 ++++++++-------------------- src/pmi/pmi2/simple/simple_pmiutil.c | 2 +- src/pmi/simple/simple_pmi.c | 2 - 5 files changed, 33 insertions(+), 48 deletions(-) diff --git a/src/pmi/pmi2/include/pmi2.h b/src/pmi/pmi2/include/pmi2.h index ebcd8ec0a63..d9b7109be96 100644 --- a/src/pmi/pmi2/include/pmi2.h +++ b/src/pmi/pmi2/include/pmi2.h @@ -136,6 +136,19 @@ S*/ @*/ int PMI2_Finalize(void); +/*@ + PMI2_Set_threaded - set whether the PMI will be called from multiple threads + + Return values: + Returns 'MPI_SUCCESS' on success and an MPI error code on failure. + + Notes: + The default is to assume all PMI is issued from a single thread. Use this + function to set is_threaded to TRUE before calling PMI from multiple threads. + +@*/ + int PMI2_Set_threaded(int is_threaded); + /*@ PMI2_Initialized - check if PMI has been initialized diff --git a/src/pmi/pmi2/simple/pmi2compat.h b/src/pmi/pmi2/simple/pmi2compat.h index 9ba179a24b8..8c762eb4f83 100644 --- a/src/pmi/pmi2/simple/pmi2compat.h +++ b/src/pmi/pmi2/simple/pmi2compat.h @@ -6,15 +6,15 @@ #ifndef PMI2COMPAT_H_INCLUDED #define PMI2COMPAT_H_INCLUDED -#include "mpiimpl.h" +#include +#include #define PMI2U_Malloc(size_) MPL_malloc(size_, MPL_MEM_PM) #define PMI2U_Free MPL_free #define PMI2U_Strdup MPL_strdup #define PMI2U_Strnapp MPL_strnapp -#define PMI2U_Assert MPIR_Assert +#define PMI2U_Assert assert #define PMI2U_Exit MPL_exit -#define PMI2U_Info MPIR_Info -#define PMI2U_Memcpy MPIR_Memcpy +#define PMI2U_Memcpy memcpy #endif /* PMI2COMPAT_H_INCLUDED */ diff --git a/src/pmi/pmi2/simple/simple2pmi.c b/src/pmi/pmi2/simple/simple2pmi.c index a54be5d9021..1c6f677b4f4 100644 --- a/src/pmi/pmi2/simple/simple2pmi.c +++ b/src/pmi/pmi2/simple/simple2pmi.c @@ -52,15 +52,14 @@ static int PMI2_fd = -1; static int PMI2_size = 1; static int PMI2_rank = 0; +static int PMI2_is_threaded = 0; /* Set this to true to require thread safety */ static int PMI2_debug_init = 0; /* Set this to true to debug the init */ int PMI2_pmiverbose = 0; /* Set this to true to print PMI debugging info */ -#ifdef MPICH_IS_THREADED static MPL_thread_mutex_t mutex; static int blocked = FALSE; static MPL_thread_cond_t cond; -#endif /* XXX DJG the "const"s on both of these functions and the Keyvalpair * struct are wrong in the isCopy==TRUE case! */ @@ -190,6 +189,13 @@ static inline int SEARCH_REMOVE(PMI2_Command * cmd) /* ------------------------------------------------------------------------- */ /* PMI API Routines */ /* ------------------------------------------------------------------------- */ +int PMI2_Set_threaded(int is_threaded) +{ + PMI2_is_threaded = is_threaded; + + return PMI2_SUCCESS; +} + int PMI2_Init(int *spawned, int *size, int *rank, int *appnum) { int pmi2_errno = PMI2_SUCCESS; @@ -268,7 +274,6 @@ int PMI2_Init(int *spawned, int *size, int *rank, int *appnum) PMI2_Keyvalpair pairs[3]; PMI2_Keyvalpair *pairs_p[] = { pairs, pairs + 1, pairs + 2 }; int npairs = 0; - int isThreaded = 0; const char *errmsg; int rc; int found; @@ -297,14 +302,7 @@ int PMI2_Init(int *spawned, int *size, int *rank, int *appnum) } } -#ifdef MPICH_IS_THREADED - MPIR_THREAD_CHECK_BEGIN; - { - isThreaded = 1; - } - MPIR_THREAD_CHECK_END; -#endif - init_kv_str(&pairs[npairs], THREADED_KEY, isThreaded ? "TRUE" : "FALSE"); + init_kv_str(&pairs[npairs], THREADED_KEY, PMI2_is_threaded ? "TRUE" : "FALSE"); ++npairs; @@ -1318,9 +1316,7 @@ int PMIi_ReadCommand(int fd, PMI2_Command * cmd) memset(cmd_len_str, 0, sizeof(cmd_len_str)); -#ifdef MPICH_IS_THREADED - MPIR_THREAD_CHECK_BEGIN; - { + if (PMI2_is_threaded) { MPL_thread_mutex_lock(&mutex, &err, MPL_THREAD_PRIO_HIGH); while (blocked && !cmd->complete) @@ -1334,8 +1330,6 @@ int PMIi_ReadCommand(int fd, PMI2_Command * cmd) blocked = TRUE; MPL_thread_mutex_unlock(&mutex, &err); } - MPIR_THREAD_CHECK_END; -#endif do { @@ -1454,26 +1448,17 @@ int PMIi_ReadCommand(int fd, PMI2_Command * cmd) target_cmd->command = command; target_cmd->nPairs = nPairs; target_cmd->pairs = pairs; -#ifdef MPICH_IS_THREADED target_cmd->complete = TRUE; -#endif PMI2U_Free(cmd_buf); } while (!cmd->complete); -#ifdef MPICH_IS_THREADED - MPIR_THREAD_CHECK_BEGIN; - { + if (PMI2_is_threaded) { MPL_thread_mutex_lock(&mutex, &err, MPL_THREAD_PRIO_HIGH); blocked = FALSE; MPL_thread_cond_broadcast(&cond, &err); MPL_thread_mutex_unlock(&mutex, &err); } - MPIR_THREAD_CHECK_END; -#endif - - - fn_exit: return pmi2_errno; @@ -1543,17 +1528,13 @@ int PMIi_WriteSimpleCommand(int fd, PMI2_Command * resp, const char cmd[], c += ret; remaining_len -= ret; -#ifdef MPICH_IS_THREADED - MPIR_THREAD_CHECK_BEGIN; - if (resp) { + if (PMI2_is_threaded && resp) { ret = MPL_snprintf(c, remaining_len, "thrid=%p;", resp); PMI2U_ERR_CHKANDJUMP1(ret >= remaining_len, pmi2_errno, PMI2_ERR_OTHER, "**intern", "**intern %s", "Ran out of room for command"); c += ret; remaining_len -= ret; } - MPIR_THREAD_CHECK_END; -#endif for (pair_index = 0; pair_index < npairs; ++pair_index) { /* write key= */ @@ -1597,9 +1578,7 @@ int PMIi_WriteSimpleCommand(int fd, PMI2_Command * resp, const char cmd[], printf_d("PMI sending: %s\n", cmdbuf); -#ifdef MPICH_IS_THREADED - MPIR_THREAD_CHECK_BEGIN; - { + if (PMI2_is_threaded) { MPL_thread_mutex_lock(&mutex, &err, MPL_THREAD_PRIO_HIGH); while (blocked) @@ -1608,8 +1587,6 @@ int PMIi_WriteSimpleCommand(int fd, PMI2_Command * resp, const char cmd[], blocked = TRUE; MPL_thread_mutex_unlock(&mutex, &err); } - MPIR_THREAD_CHECK_END; -#endif if (PMI2_debug) ENQUEUE(resp); @@ -1625,16 +1602,13 @@ int PMIi_WriteSimpleCommand(int fd, PMI2_Command * resp, const char cmd[], offset += nbytes; } while (offset < cmdlen + PMII_COMMANDLEN_SIZE); -#ifdef MPICH_IS_THREADED - MPIR_THREAD_CHECK_BEGIN; - { + + if (PMI2_is_threaded) { MPL_thread_mutex_lock(&mutex, &err, MPL_THREAD_PRIO_HIGH); blocked = FALSE; MPL_thread_cond_broadcast(&cond, &err); MPL_thread_mutex_unlock(&mutex, &err); } - MPIR_THREAD_CHECK_END; -#endif fn_exit: return pmi2_errno; diff --git a/src/pmi/pmi2/simple/simple_pmiutil.c b/src/pmi/pmi2/simple/simple_pmiutil.c index 72c9f89752b..72c68449983 100644 --- a/src/pmi/pmi2/simple/simple_pmiutil.c +++ b/src/pmi/pmi2/simple/simple_pmiutil.c @@ -11,8 +11,8 @@ key=value messages */ #include "mpichconf.h" - #include "pmi2compat.h" +#include "mpl.h" #include #ifdef HAVE_STDLIB_H diff --git a/src/pmi/simple/simple_pmi.c b/src/pmi/simple/simple_pmi.c index f1c71abf6aa..5d0e6e2dea1 100644 --- a/src/pmi/simple/simple_pmi.c +++ b/src/pmi/simple/simple_pmi.c @@ -45,8 +45,6 @@ #endif #include "mpl.h" /* Get ATTRIBUTE, some base functions */ -/* mpimem includes the definitions for MPL_malloc and MPL_free */ -#include "mpir_mem.h" /* Temporary debug definitions */ /* #define DBG_PRINTF(args) printf args ; fflush(stdout) */ From efb412dbd6dcf3775904663dfbaf58543fec7a7f Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 4 Mar 2022 17:31:02 -0600 Subject: [PATCH 543/607] mpir_pmi: add MPIR_pmi_set_threaded Add wrappers to enable PMI thread safety. However, since not all PMI interfaces support thread safety and in mpich we always call PMI functions from single thread or within a critical section, we currently do not need to enable threaded in PMI. --- src/include/mpir_pmi.h | 1 + src/util/mpir_pmi.c | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/src/include/mpir_pmi.h b/src/include/mpir_pmi.h index 45a5ffc4d77..bafed0a72f0 100644 --- a/src/include/mpir_pmi.h +++ b/src/include/mpir_pmi.h @@ -40,6 +40,7 @@ typedef struct MPIR_PMI_KEYVAL { int MPIR_pmi_init(void); void MPIR_pmi_finalize(void); void MPIR_pmi_abort(int exit_code, const char *error_msg); +int MPIR_pmi_set_threaded(int is_threaded); /* PMI getters for private fields */ int MPIR_pmi_max_key_size(void); diff --git a/src/util/mpir_pmi.c b/src/util/mpir_pmi.c index 09b4ec69719..9d505f833cb 100644 --- a/src/util/mpir_pmi.c +++ b/src/util/mpir_pmi.c @@ -217,6 +217,17 @@ void MPIR_pmi_abort(int exit_code, const char *error_msg) #endif } +/* This function is currently unused in MPICH because we always call + * PMI functions from a single thread or within a critical section. + */ +int MPIR_pmi_set_threaded(int is_threaded) +{ +#if defined(USE_PMI2_API) + PMI2_Set_threaded(is_threaded); +#endif + return MPI_SUCCESS; +} + /* getters for internal constants */ int MPIR_pmi_max_key_size(void) { From 0bfaae41db5273487fb130d88ec470e0a173cae8 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 18 Mar 2022 21:08:21 -0500 Subject: [PATCH 544/607] configure: check and fail when AC_CHECK_SIZEOF fails When AC_CHECK_SIZEOF fails, resulting in type size of 0, fail rather than propagating the error into mysterious places. --- configure.ac | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/configure.ac b/configure.ac index 2a31d32e83a..e352e9d9f8f 100644 --- a/configure.ac +++ b/configure.ac @@ -2719,6 +2719,14 @@ AC_CHECK_SIZEOF(double) AC_CHECK_SIZEOF(long double) AC_CHECK_SIZEOF(void *) +# Let's not continue if we cannot detect these basic types +for type in char int void_p ; do + eval len=\$ac_cv_sizeof_$type + if test "$len" = "0" ; then + AC_MSG_ERROR([Could not get size of "$type".]) + fi +done + AC_CHECK_HEADERS([stddef.h]) AC_CHECK_SIZEOF(wchar_t, 0, [ #ifdef HAVE_STDDEF_H From 5b82911532b3da57c61051a9393dc3126c7f09f6 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Mon, 28 Mar 2022 14:27:52 -0500 Subject: [PATCH 545/607] mtest: Add GPU flags to libmtest_cxx.la library This library includes mtest_common.c which contains GPU dependencies. Make sure GPU flags are added in order to build it correctly. --- test/mpi/util/Makefile.am | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/mpi/util/Makefile.am b/test/mpi/util/Makefile.am index 8f33dcc2630..9ba5d7c9340 100644 --- a/test/mpi/util/Makefile.am +++ b/test/mpi/util/Makefile.am @@ -24,6 +24,9 @@ if HAS_CXX ## to emit a rule for building mtest_cxx.o from mtest_cxx.cxx noinst_LTLIBRARIES += libmtest_cxx.la libmtest_cxx_la_SOURCES = mtest_cxx.cxx mtest_common.c +libmtest_cxx_la_LIBADD = @cuda_LIBS@ @ze_LIBS@ @hip_LIBS@ +libmtest_cxx_la_LDFLAGS = @cuda_LDFLAGS@ @ze_LDFLAGS@ @hip_LDFLAGS@ +libmtest_cxx_la_CPPFLAGS = $(AM_CPPFLAGS) @cuda_CPPFLAGS@ @ze_CPPFLAGS@ @hip_CPPFLAGS@ endif From a055769f7e4fa552e6d025abb07e10525a52724c Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 3 Mar 2022 11:41:06 -0600 Subject: [PATCH 546/607] pmi: simplify subconfigure for bgq/cray/slurm All these are just cases of external pmi library. It is a overkill to use the subconfigure system. This cleans up the pmi folder and make it possible to refactor it into a submodule (as mpl and romio). --- configure.ac | 36 +++++++++++++++++++++++++++++++++++ src/pmi/Makefile.mk | 1 - src/pmi/bgq/Makefile.mk | 15 --------------- src/pmi/bgq/bgq_pmi.c | 28 --------------------------- src/pmi/bgq/subconfigure.m4 | 19 ------------------ src/pmi/cray/subconfigure.m4 | 25 ------------------------ src/pmi/slurm/subconfigure.m4 | 24 ----------------------- src/util/mpir_pmi.c | 6 ++++++ 8 files changed, 42 insertions(+), 112 deletions(-) delete mode 100644 src/pmi/bgq/Makefile.mk delete mode 100644 src/pmi/bgq/bgq_pmi.c delete mode 100644 src/pmi/bgq/subconfigure.m4 delete mode 100644 src/pmi/cray/subconfigure.m4 delete mode 100644 src/pmi/slurm/subconfigure.m4 diff --git a/configure.ac b/configure.ac index e352e9d9f8f..2b6439dc5ff 100644 --- a/configure.ac +++ b/configure.ac @@ -1479,6 +1479,10 @@ else # Make device_name available to subdirs fi +# --------------------------------------------------------------------------- +# Configuring pmi and pm +# + PAC_CHECK_HEADER_LIB_EXPLICIT(pmix, pmix.h, pmix, PMIx_Init) if test "$pac_have_pmix" = "yes" ; then # disable built-in PMI and process managers @@ -1631,6 +1635,38 @@ for this_pm_name in $pm_names ; do fi done +# Step 4: complete external pmi setup +# +case "$pmi_name" in + slurm) + PAC_SET_HEADER_LIB_PATH([slurm]) + AC_CHECK_HEADER([slurm/pmi.h], [], [AC_MSG_ERROR([could not find slurm/pmi.h. Configure aborted])]) + # FIXME: what if user choose pmi2? + AC_CHECK_LIB([pmi], [PMI_Init], + [PAC_PREPEND_FLAG([-lpmi],[LIBS]) + PAC_PREPEND_FLAG([-lpmi], [WRAPPER_LIBS])], + [AC_MSG_ERROR([could not find the Slurm libpmi. Configure aborted])]) + ;; + cray) + # set CPPFLAGS and LDFLAGS + PAC_PREPEND_FLAG([$CRAY_PMI_INCLUDE_OPTS], [CPPFLAGS]) + PAC_PREPEND_FLAG([$CRAY_PMI_POST_LINK_OPTS], [LDFLAGS]) + + AC_CHECK_HEADER([pmi.h], [], [AC_MSG_ERROR([could not find pmi.h. Configure aborted])]) + AC_CHECK_LIB([pmi], [PMI_Init], [], [AC_MSG_ERROR([could not find the cray libpmi. Configure aborted])]) + + AC_DEFINE(USE_PMI2_API, 1, [Define if Cray PMI API must be used]) + PAC_APPEND_FLAG([-lpmi], [WRAPPER_LIBS]) + ;; + bgq) + # This is a hack to include the pmi.h header. The OFI/BGQ provider + # includes PMI functions, but no header file. + PAC_PREPEND_FLAG([-I${use_top_srcdir}/src/pmi/include], [CPPFLAGS]) + AC_DEFINE([NO_PMI_SPAWN_MULTIPLE], 1, [The PMI library does not have PMI_Spawn_multiple.]) + ;; +esac + +# --------------------------------------------------------------------------- # Check for whether the compiler defines a symbol that contains the # function name. The MPICH code uses this for debugging purposes. diff --git a/src/pmi/Makefile.mk b/src/pmi/Makefile.mk index 4787d35f12a..da732a8136b 100644 --- a/src/pmi/Makefile.mk +++ b/src/pmi/Makefile.mk @@ -5,6 +5,5 @@ include $(top_srcdir)/src/pmi/pmi2/Makefile.mk include $(top_srcdir)/src/pmi/simple/Makefile.mk -include $(top_srcdir)/src/pmi/bgq/Makefile.mk errnames_txt_files += src/pmi/errnames.txt diff --git a/src/pmi/bgq/Makefile.mk b/src/pmi/bgq/Makefile.mk deleted file mode 100644 index 8cfe1375d7f..00000000000 --- a/src/pmi/bgq/Makefile.mk +++ /dev/null @@ -1,15 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -if BUILD_PMI_BGQ - -mpi_core_sources += \ - src/pmi/bgq/bgq_pmi.c - -noinst_HEADERS += - -AM_CPPFLAGS += -I$(top_srcdir)/src/pmi/bgq - -endif BUILD_PMI_BGQ diff --git a/src/pmi/bgq/bgq_pmi.c b/src/pmi/bgq/bgq_pmi.c deleted file mode 100644 index 13042b6239d..00000000000 --- a/src/pmi/bgq/bgq_pmi.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) by Argonne National Laboratory - * See COPYRIGHT in top-level directory - */ - -#include "mpichconf.h" - -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif - -#include "pmi.h" - -int PMI_Spawn_multiple(int count, - const char *cmds[], - const char **argvs[], - const int maxprocs[], - const int info_keyval_sizes[], - const PMI_keyval_t * info_keyval_vectors[], - int preput_keyval_size, - const PMI_keyval_t preput_keyval_vector[], int errors[]) -{ - PMI_Abort(-1, NULL); - return PMI_SUCCESS; -} diff --git a/src/pmi/bgq/subconfigure.m4 b/src/pmi/bgq/subconfigure.m4 deleted file mode 100644 index 073674489b1..00000000000 --- a/src/pmi/bgq/subconfigure.m4 +++ /dev/null @@ -1,19 +0,0 @@ -[#] start of __file__ - -AC_DEFUN([PAC_SUBCFG_PREREQ_]PAC_SUBCFG_AUTO_SUFFIX,[ -]) - -AC_DEFUN([PAC_SUBCFG_BODY_]PAC_SUBCFG_AUTO_SUFFIX,[ - -AM_CONDITIONAL([BUILD_PMI_BGQ],[test "x$pmi_name" = "xbgq"]) -AM_COND_IF([BUILD_PMI_BGQ],[ - -# This is a hack to include the pmi.h header. The OFI/BGQ provider -# includes PMI functions, but no header file. -PAC_PREPEND_FLAG([-I${use_top_srcdir}/src/pmi/include], [CPPFLAGS]) - -])dnl end COND_IF - -])dnl end BODY macro - -[#] end of __file__ diff --git a/src/pmi/cray/subconfigure.m4 b/src/pmi/cray/subconfigure.m4 deleted file mode 100644 index 7596ec090d5..00000000000 --- a/src/pmi/cray/subconfigure.m4 +++ /dev/null @@ -1,25 +0,0 @@ -[#] start of __file__ - -AC_DEFUN([PAC_SUBCFG_PREREQ_]PAC_SUBCFG_AUTO_SUFFIX,[ -]) - -AC_DEFUN([PAC_SUBCFG_BODY_]PAC_SUBCFG_AUTO_SUFFIX,[ - -AM_CONDITIONAL([BUILD_PMI_CRAY],[test "x$pmi_name" = "xcray"]) -AM_COND_IF([BUILD_PMI_CRAY],[ - -# set CPPFLAGS and LDFLAGS -PAC_PREPEND_FLAG([$CRAY_PMI_INCLUDE_OPTS], [CPPFLAGS]) -PAC_PREPEND_FLAG([$CRAY_PMI_POST_LINK_OPTS], [LDFLAGS]) - -AC_CHECK_HEADER([pmi.h], [], [AC_MSG_ERROR([could not find pmi.h. Configure aborted])]) -AC_CHECK_LIB([pmi], [PMI_Init], [], [AC_MSG_ERROR([could not find the cray libpmi. Configure aborted])]) - -AC_DEFINE(USE_PMI2_API, 1, [Define if Cray PMI API must be used]) -PAC_APPEND_FLAG([-lpmi], [WRAPPER_LIBS]) - -])dnl end COND_IF - -])dnl end BODY macro - -[#] end of __file__ diff --git a/src/pmi/slurm/subconfigure.m4 b/src/pmi/slurm/subconfigure.m4 deleted file mode 100644 index c9f81da6220..00000000000 --- a/src/pmi/slurm/subconfigure.m4 +++ /dev/null @@ -1,24 +0,0 @@ -[#] start of __file__ - -AC_DEFUN([PAC_SUBCFG_PREREQ_]PAC_SUBCFG_AUTO_SUFFIX,[ -]) - -AC_DEFUN([PAC_SUBCFG_BODY_]PAC_SUBCFG_AUTO_SUFFIX,[ - -AM_CONDITIONAL([BUILD_PMI_SLURM],[test "x$pmi_name" = "xslurm"]) -AM_COND_IF([BUILD_PMI_SLURM],[ - -# sets CPPFLAGS and LDFLAGS -PAC_SET_HEADER_LIB_PATH([slurm]) - -AC_CHECK_HEADER([slurm/pmi.h], [], [AC_MSG_ERROR([could not find slurm/pmi.h. Configure aborted])]) -AC_CHECK_LIB([pmi], [PMI_Init], - [PAC_PREPEND_FLAG([-lpmi],[LIBS]) - PAC_PREPEND_FLAG([-lpmi], [WRAPPER_LIBS])], - [AC_MSG_ERROR([could not find the Slurm libpmi. Configure aborted])]) - -])dnl end COND_IF - -])dnl end BODY macro - -[#] end of __file__ diff --git a/src/util/mpir_pmi.c b/src/util/mpir_pmi.c index 9d505f833cb..d42a3f64b4a 100644 --- a/src/util/mpir_pmi.c +++ b/src/util/mpir_pmi.c @@ -889,6 +889,11 @@ int MPIR_pmi_spawn_multiple(int count, char *commands[], char **argvs[], #endif #ifdef USE_PMI1_API +#ifdef NO_PMI_SPAWN_MULTIPLE + /* legacy bgq system does not have PMI_Spawn_multiple */ + MPIR_ERR_SETANDJUMP1(mpi_errno, MPI_ERR_OTHER, + "**pmi_spawn_multiple", "**pmi_spawn_multiple %d", 0); +#else pmi_errno = PMI_Spawn_multiple(count, (const char **) commands, (const char ***) argvs, maxprocs, info_keyval_sizes, @@ -898,6 +903,7 @@ int MPIR_pmi_spawn_multiple(int count, char *commands[], char **argvs[], MPIR_ERR_CHKANDJUMP1(pmi_errno != PMI_SUCCESS, mpi_errno, MPI_ERR_OTHER, "**pmi_spawn_multiple", "**pmi_spawn_multiple %d", pmi_errno); +#endif #elif defined(USE_PMI2_API) int *argcs = MPL_malloc(count * sizeof(int), MPL_MEM_DYNAMIC); MPIR_Assert(argcs); From 1ef665ea4dd0ab37fa6c7253e533a43b266e469c Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 3 Mar 2022 13:39:43 -0600 Subject: [PATCH 547/607] configure: move AC_ARG_WITH locations for pmi and pm So the code are together. --- configure.ac | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/configure.ac b/configure.ac index 2b6439dc5ff..4cbf87221a9 100644 --- a/configure.ac +++ b/configure.ac @@ -486,21 +486,6 @@ AC_ARG_WITH(device, AS_HELP_STRING([--with-device=name], [Specify the communication device for MPICH]),, with_device=ch4) -AC_ARG_WITH(pmi, - AS_HELP_STRING([--with-pmi=name], [Specify the pmi interface for MPICH]),, - with_pmi=default) - -AC_ARG_WITH(pm, - AS_HELP_STRING([--with-pm=name], - [Specify the process manager for MPICH. "no" or "none" are - valid values. Multiple process managers may be specified as - long as they all use the same pmi interface by separating them - with colons. The mpiexec for the first named process manager - will be installed. Example: "--with-pm=hydra:gforker" - builds the two process managers hydra, and gforker; - only the mpiexec from hydra is installed into the bin - directory.]),,with_pm=default) - AC_ARG_ENABLE(threads, [ --enable-threads=level - Control the level of thread support in the MPICH implementation. The following levels @@ -1483,6 +1468,21 @@ fi # Configuring pmi and pm # +AC_ARG_WITH(pmi, + AS_HELP_STRING([--with-pmi=name], [Specify the pmi interface for MPICH]),, + with_pmi=default) + +AC_ARG_WITH(pm, + AS_HELP_STRING([--with-pm=name], + [Specify the process manager for MPICH. "no" or "none" are + valid values. Multiple process managers may be specified as + long as they all use the same pmi interface by separating them + with colons. The mpiexec for the first named process manager + will be installed. Example: "--with-pm=hydra:gforker" + builds the two process managers hydra, and gforker; + only the mpiexec from hydra is installed into the bin + directory.]),,with_pm=default) + PAC_CHECK_HEADER_LIB_EXPLICIT(pmix, pmix.h, pmix, PMIx_Init) if test "$pac_have_pmix" = "yes" ; then # disable built-in PMI and process managers From 462550d0ec6db4bf51209133a2912f142bbed040 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 3 Mar 2022 17:04:19 -0600 Subject: [PATCH 548/607] configure: revamp options for pm and pmi The current options are not ituitive and not easy for some options such as with slurm either PMI1 or PMI2: * --with-pmi=simple --with-pm=hydra * --with-pmi=pmi2/simpl --with-pm=hydra * --with-pmi=cray --with-pm=no * --with-pmi=slurm --with-pm=no * --with-pmix=[path] This commit makes 3 orthogonal options: * --with-pmi={pmi1, pmi2, pmix} * --with-pmilib={mpich, slurm, cray, pmix} * --with-pm={no,hydra,hydra2,gforker,remshell} The --with-pm option is unchanged. The separation of --with-pmi and --with-pmilib allows all possible combinations to be chosen. We make it backward compatible with the old option such as --with-pmi=cray by adding specific checks. Extra complexities such as sourcing mpichprereq, sourcing pm_setup, are removed, preferring explicit settings via case switches. --- configure.ac | 248 ++++++++++++++++------------ src/pm/gforker/subconfigure.m4 | 22 --- src/pm/hydra/mpichprereq | 22 --- src/pm/hydra2/mpichprereq | 21 --- src/pm/remshell/subconfigure.m4 | 22 --- src/pmi/pmi2/simple/subconfigure.m4 | 2 - src/pmi/simple/subconfigure.m4 | 2 - 7 files changed, 146 insertions(+), 193 deletions(-) delete mode 100755 src/pm/hydra/mpichprereq delete mode 100755 src/pm/hydra2/mpichprereq diff --git a/configure.ac b/configure.ac index 4cbf87221a9..7dc3fb351e7 100644 --- a/configure.ac +++ b/configure.ac @@ -1465,13 +1465,26 @@ else fi # --------------------------------------------------------------------------- -# Configuring pmi and pm +# Configuring pmi, pmilib, and pm # AC_ARG_WITH(pmi, AS_HELP_STRING([--with-pmi=name], [Specify the pmi interface for MPICH]),, with_pmi=default) +AC_ARG_WITH(pmilib, + AS_HELP_STRING([--with-pmilib=name], + [Specify the PMI library. Accepted options are: + mpich - use MPICH PMI library (default). + slurm - use Slurm PMI library. Use --with-slurm=path to configure + Slurm library path. + cray - use Cray PMI library. Use --with-craypmi=path to configure + Cray PMI library path. + pmix - use PMIx library. Use --with-pmix=path to configure + PMIx library path. + ]),, + with_pmilib=default) + AC_ARG_WITH(pm, AS_HELP_STRING([--with-pm=name], [Specify the process manager for MPICH. "no" or "none" are @@ -1483,18 +1496,91 @@ AC_ARG_WITH(pm, only the mpiexec from hydra is installed into the bin directory.]),,with_pm=default) +# --- check and normalize the options ---- + +case "$with_pmi" in + slurm) + with_pmilib=slurm + with_pm=no + ;; + cray) + with_pmilib=cray + with_pm=no + ;; + pmix) + with_pmi=pmix + with_pmilib=pmix + with_pm=no + ;; + bgq) + with_pmi=pmi1 + with_pmilib=no + ;; + simple) + with_pmi=pmi1 + with_pmilib=mpich + ;; + pmi2/simple) + with_pmi=pmi2 + with_pmilib=mpich + ;; +esac + +case "$with_pmilib" in + slurm) + with_pm=no + ;; + cray) + with_pm=no + ;; + pmix) + with_pmi=pmix + with_pm=no + ;; +esac + PAC_CHECK_HEADER_LIB_EXPLICIT(pmix, pmix.h, pmix, PMIx_Init) if test "$pac_have_pmix" = "yes" ; then - # disable built-in PMI and process managers - with_pmi="no" - with_pm="no" + with_pmi=pmix + with_pmilib=pmix + with_pm=no +fi + +if test "$with_pmi" = "default" ; then + case "$with_pmilib" in + slurm|cray) + with_pmi=pmi2 + ;; + *) + with_pmi=pmi1 + ;; + esac +fi + +if test "$with_pmilib" = "default" ; then + with_pmilib=mpich +fi + +if test "$with_pm" = "default" ; then + with_pm=hydra +fi + +# --- $with_pmi ---- + +case "$with_pmi" in + pmi2) + AC_DEFINE(USE_PMI2_API, 1, [Define if PMI2 API must be used]) + ;; + pmix) if test "${device_name}" != "ch4" ; then AC_MSG_ERROR([$device_name does not support PMIx]) fi AC_DEFINE(USE_PMIX_API, 1, [Define if PMIx API must be used]) -fi + ;; +esac + +# --- $with_pm ---- -# with-pm if test "$with_pm" = "none" ; then # add "none" as synonym for "no" to agree with older erroneous docs with_pm="no" @@ -1529,55 +1615,45 @@ else fi # hasError=no -# We need to be careful about PM's that have either conflicting -# requirements (e.g., different PMI implementations) or different -# optional features (e.g., MPID_PM_NAMESERVER). -# In addition, we need to interleave the setup of the PMI and PM -# modules. The order is as follows: -# -# For each PM, execute the mpichprereq script for that pm (if present). -# This script provides information about the PM, including which PMI -# implementations are supported. -# -# Then, for the selected PMI, the setup script (if any) is run. This is -# necessary because the setup of the PM may require information discovered -# or provided duing the PMI setup step. -# -# Finally, for each PM, the setup script is executed. -# -# Step 1: invoke the mpichprereq for each PM + for pm_name in $pm_names ; do if test -z "$first_pm_name" ; then first_pm_name=$pm_name export first_pm_name fi - if test ! -d $use_top_srcdir/src/pm/$pm_name ; then - AC_MSG_WARN([$use_top_srcdir/src/pm/$pm_name does not exist. PM is unknown]) - hasError=yes - elif test ! -x $use_top_srcdir/src/pm/$pm_name/configure -a \ - ! -f $use_top_srcdir/src/pm/$pm_name/subconfigure.m4 ; then - if test -s $use_top_srcdir/src/pm/$pm_name/configure ; then - AC_MSG_WARN([The configure in $use_top_srcdir/src/pm/$pm_name exists but is not executable]) - else - AC_MSG_WARN([pm $pm_name has no configure or subconfigure.m4]) + + case "$pm_name" in + gforker) + build_gforker=yes + if test "$with_pmi" != "pmi1" ; then + AC_MSG_ERROR([$pm_name requires PMI-v1, but $with_pmi was chosen.]) + fi + ;; + remshell) + build_refshell=yes + if test "$with_pmi" != "pmi1" ; then + AC_MSG_ERROR([$pm_name requires PMI-v1, but $with_pmi was chosen.]) fi - pm_name="" + ;; + hydra) + if test "$with_pmi" = "pmix" ; then + AC_MSG_ERROR([$pm_name does not support $with_pmi.]) + fi + subsystems="$subsystems src/pm/hydra" + ;; + hydra2) + if test "$with_pmi" = "pmix" ; then + AC_MSG_ERROR([$pm_name does not support $with_pmi.]) + fi + subsystems="$subsystems src/pm/hydra2" + ;; + *) + AC_MSG_WARN([PM $pm_name is unknown]) hasError=yes - else - nameserver=$MPID_PM_NAMESERVER - if test -f $use_top_srcdir/src/pm/$pm_name/mpichprereq ; then - echo sourcing $use_top_srcdir/src/pm/$pm_name/mpichprereq - . $use_top_srcdir/src/pm/$pm_name/mpichprereq - fi - # Check for a change; if found, we'll take the default - if test "$MPID_PM_NAMESERVER" != "$nameserver" ; then - if test "$first_pm_name" != "$pm_name" ; then - # Reject suggestion (use the default, common mode) - MPID_PM_NAMESERVER="" - fi - fi - fi + ;; + esac done + if test "$hasError" != no ; then AC_MSG_ERROR([Aborting configure because an error was seen in the selection of process managers]) fi @@ -1586,58 +1662,25 @@ fi pm_name=$first_pm_name AC_SUBST(pm_name) -# Step 2: -# Once we've selected the process manager (or managers), we can -# check that we have a compatible PMI implementation. -# with-pmi -if test "$with_pmi" != "no" ; then - if test "$with_pmi" = "default" -o "$with_pmi" = "yes" ; then - if test -n "$PM_REQUIRES_PMI" ; then - with_pmi=$PM_REQUIRES_PMI - else - with_pmi=simple - fi - elif test -n "$PM_REQUIRES_PMI" ; then - # Test for compatibility between pm and pmi choices - if test "$PM_REQUIRES_PMI" != "$with_pmi" ; then - AC_MSG_ERROR([The PM chosen ($with_pm) requires the PMI implementation $PM_REQUIRES_PMI but $with_pmi was selected as the PMI implementation.]) - fi - fi - pmi_name=$with_pmi - - if test ! -d $use_top_srcdir/src/pmi/$pmi_name ; then - AC_MSG_WARN([$use_top_srcdir/src/pmi/$pmi_name does not exist. PMI is unknown]) - elif test ! -x $use_top_srcdir/src/pmi/$pmi_name/configure ; then - if test ! -f $use_top_srcdir/src/pmi/$pmi_name/subconfigure.m4 ; then - AC_MSG_WARN([pmi $pmi_name has no configure or subconfigure.m4]) - pmi_name="" - fi - else - # only add to subsystems if a full configure is present - subsystems="$subsystems src/pmi/$pmi_name" - fi -fi +dnl +dnl gforker and remshell does not use separate configure. +dnl +AM_CONDITIONAL([BUILD_PM_GFORKER],[test "X$build_gforker" = "Xyes"]) +AM_CONDITIONAL([BUILD_PM_REMSHELL],[test "X$build_refshell" = "Xyes"]) +AM_CONDITIONAL([PRIMARY_PM_GFORKER],[test "X$first_pm_name" = "Xgforker"]) +AM_CONDITIONAL([PRIMARY_PM_REMSHELL],[test "X$first_pm_name" = "Xremshell"]) -# Step 3: complete pm setup. -# Note that checks for errors have already been performed, so this -# loop does not need to perform any extra error checks. -# Note that this uses this_pm_name because pm_name must be the *first* -# of the PM names -for this_pm_name in $pm_names ; do - # only add the PM to the subsystems if it has a full configure to be - # executed - if test -f $use_top_srcdir/src/pm/$this_pm_name/configure ; then - subsystems="$subsystems src/pm/$this_pm_name" - fi - if test -f $use_top_srcdir/src/pm/$this_pm_name/setup_pm ; then - echo sourcing $use_top_srcdir/src/pm/$this_pm_name/setup_pm - . $use_top_srcdir/src/pm/$this_pm_name/setup_pm - fi -done +# ---- $with_pmilib ---- -# Step 4: complete external pmi setup -# -case "$pmi_name" in +AM_CONDITIONAL([BUILD_PMI_SIMPLE], [test "$with_pmilib" = "mpich" -a "$with_pmi" = "pmi1"]) +AM_CONDITIONAL([BUILD_PMI_PMI2_SIMPLE], [test "$with_pmilib" = "mpich" -a "$with_pmi" = "pmi2"]) + +case "$with_pmilib" in + mpich) + if test "$with_pmi" != "pmi1" -a "$with_pmi" != "pmi2" ; then + AC_MSG_ERROR([pmilib=%with_pmilib is incompatible with $with_pmi]); + fi + ;; slurm) PAC_SET_HEADER_LIB_PATH([slurm]) AC_CHECK_HEADER([slurm/pmi.h], [], [AC_MSG_ERROR([could not find slurm/pmi.h. Configure aborted])]) @@ -1655,7 +1698,6 @@ case "$pmi_name" in AC_CHECK_HEADER([pmi.h], [], [AC_MSG_ERROR([could not find pmi.h. Configure aborted])]) AC_CHECK_LIB([pmi], [PMI_Init], [], [AC_MSG_ERROR([could not find the cray libpmi. Configure aborted])]) - AC_DEFINE(USE_PMI2_API, 1, [Define if Cray PMI API must be used]) PAC_APPEND_FLAG([-lpmi], [WRAPPER_LIBS]) ;; bgq) @@ -1664,6 +1706,12 @@ case "$pmi_name" in PAC_PREPEND_FLAG([-I${use_top_srcdir}/src/pmi/include], [CPPFLAGS]) AC_DEFINE([NO_PMI_SPAWN_MULTIPLE], 1, [The PMI library does not have PMI_Spawn_multiple.]) ;; + pmix) + # taken care of by PAC_CHECK_HEADER_LIB_EXPLICIT + ;; + *) + AC_MSG_ERROR([pmilib $with_pmilib not supported.]) + ;; esac # --------------------------------------------------------------------------- @@ -4059,10 +4107,6 @@ AC_CONFIG_COMMANDS([chmod],[chmod a+x test/commands/cmdtests]) AC_DEFINE(HAVE_MPICHCONF,1,[Define so that we can test whether the mpichconf.h file has been included]) -if test "$USE_PMI2_API" = "yes" ; then - AC_DEFINE(USE_PMI2_API, 1, [Define if PMI2 API must be used]) -fi - ######################################################################## # cause libtool script to be built now so that we can use it to test one last diff --git a/src/pm/gforker/subconfigure.m4 b/src/pm/gforker/subconfigure.m4 index 36a29e269f1..898a7544456 100644 --- a/src/pm/gforker/subconfigure.m4 +++ b/src/pm/gforker/subconfigure.m4 @@ -7,31 +7,9 @@ AC_DEFUN([PAC_SUBCFG_PREREQ_]PAC_SUBCFG_AUTO_SUFFIX,[ dnl _BODY handles the former role of configure in the subsystem AC_DEFUN([PAC_SUBCFG_BODY_]PAC_SUBCFG_AUTO_SUFFIX,[ -# the pm_names variable is set by the top level configure -build_gforker=no -for pm_name in $pm_names ; do - if test "X$pm_name" = "Xgforker" ; then - build_gforker=yes - fi -done -AM_CONDITIONAL([BUILD_PM_GFORKER],[test "X$build_gforker" = "Xyes"]) - -# first_pm_name is set by the top level configure -AM_CONDITIONAL([PRIMARY_PM_GFORKER],[test "X$first_pm_name" = "Xgforker"]) - AM_COND_IF([BUILD_PM_GFORKER],[ AC_MSG_NOTICE([RUNNING CONFIGURE FOR src/pm/gforker]) -# Check that we are using the simple PMI implementation -# (Selecting multiple PMs may require incompatible PMI implementations -# (e.g., gforker and SMPD). -if test -z "$PM_REQUIRES_PMI" ; then - PM_REQUIRES_PMI=simple -elif test "$PM_REQUIRES_PMI" != "simple" ; then - echo "gforker requires the simple PMI implementation; $PM_REQUIRES_PMI has already been selected" - exit 1 -fi - # tell src/pm/util to configure itself build_pm_util=yes diff --git a/src/pm/hydra/mpichprereq b/src/pm/hydra/mpichprereq deleted file mode 100755 index f186eb3743f..00000000000 --- a/src/pm/hydra/mpichprereq +++ /dev/null @@ -1,22 +0,0 @@ -#! /bin/sh -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -# Check that we are using the simple PMI implementation -# (Selecting multiple PM's may require incompatible PMI implementations -# (e.g., gforker and SMPD). - - -if test -z "$PM_REQUIRES_PMI" ; then - if test "$with_pmi" = "pmi2/simple" -o "$with_pmi" = "simple" ; then - PM_REQUIRES_PMI=$with_pmi - else - PM_REQUIRES_PMI=simple - fi -elif test "$PM_REQUIRES_PMI" != "simple" -a "$PM_REQUIRES_PMI" != "pmi2/simple" ; then - echo "hydra requires the \"simple\" or \"pmi2\" PMI implementation; \"$PM_REQUIRES_PMI\" has already been selected" - exit 1 -fi - diff --git a/src/pm/hydra2/mpichprereq b/src/pm/hydra2/mpichprereq deleted file mode 100755 index afad9bbf9e6..00000000000 --- a/src/pm/hydra2/mpichprereq +++ /dev/null @@ -1,21 +0,0 @@ -#! /bin/sh -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -# Check that we are using the simple PMI implementation -# (Selecting multiple PM's may require incompatible PMI implementations -# (e.g., gforker and SMPD). - - -if test -z "$PM_REQUIRES_PMI" ; then - if test "$with_pmi" = "pmi2/simple" -o "$with_pmi" = "simple" ; then - PM_REQUIRES_PMI=$with_pmi - else - PM_REQUIRES_PMI=simple - fi -elif test "$PM_REQUIRES_PMI" != "simple" -a "$PM_REQUIRES_PMI" != "pmi2/simple" ; then - echo "hydra requires the \"simple\" or \"pmi2\" PMI implementation; \"$PM_REQUIRES_PMI\" has already been selected" - exit 1 -fi diff --git a/src/pm/remshell/subconfigure.m4 b/src/pm/remshell/subconfigure.m4 index e0ab031aaeb..f6efaf36f5e 100644 --- a/src/pm/remshell/subconfigure.m4 +++ b/src/pm/remshell/subconfigure.m4 @@ -7,31 +7,9 @@ AC_DEFUN([PAC_SUBCFG_PREREQ_]PAC_SUBCFG_AUTO_SUFFIX,[ dnl _BODY handles the former role of configure in the subsystem AC_DEFUN([PAC_SUBCFG_BODY_]PAC_SUBCFG_AUTO_SUFFIX,[ -# the pm_names variable is set by the top level configure -build_remshell=no -for pm_name in $pm_names ; do - if test "X$pm_name" = "Xremshell" ; then - build_remshell=yes - fi -done -AM_CONDITIONAL([BUILD_PM_REMSHELL],[test "X$build_remshell" = "Xyes"]) - -# first_pm_name is set by the top level configure -AM_CONDITIONAL([PRIMARY_PM_REMSHELL],[test "X$first_pm_name" = "Xremshell"]) - AM_COND_IF([BUILD_PM_REMSHELL],[ AC_MSG_NOTICE([RUNNING CONFIGURE FOR src/pm/remshell]) -# Check that we are using the simple PMI implementation -# (Selecting multiple PMs may require incompatible PMI implementations -# (e.g., remshell and SMPD). -if test -z "$PM_REQUIRES_PMI" ; then - PM_REQUIRES_PMI=simple -elif test "$PM_REQUIRES_PMI" != "simple" ; then - echo "remshell requires the simple PMI implementation; $PM_REQUIRES_PMI has already been selected" - exit 1 -fi - # tell src/pm/util to configure itself build_pm_util=yes diff --git a/src/pmi/pmi2/simple/subconfigure.m4 b/src/pmi/pmi2/simple/subconfigure.m4 index 0027345e15b..35431ec2b4d 100644 --- a/src/pmi/pmi2/simple/subconfigure.m4 +++ b/src/pmi/pmi2/simple/subconfigure.m4 @@ -6,8 +6,6 @@ AC_DEFUN([PAC_SUBCFG_PREREQ_]PAC_SUBCFG_AUTO_SUFFIX,[ AC_DEFUN([PAC_SUBCFG_BODY_]PAC_SUBCFG_AUTO_SUFFIX,[ -AM_CONDITIONAL([BUILD_PMI_PMI2_SIMPLE],[test "x$pmi_name" = "xpmi2/simple"]) - AM_COND_IF([BUILD_PMI_PMI2_SIMPLE],[ if test "$enable_pmiport" != "no" ; then enable_pmiport=yes diff --git a/src/pmi/simple/subconfigure.m4 b/src/pmi/simple/subconfigure.m4 index 0a0b743eef7..670d480a23f 100644 --- a/src/pmi/simple/subconfigure.m4 +++ b/src/pmi/simple/subconfigure.m4 @@ -6,8 +6,6 @@ AC_DEFUN([PAC_SUBCFG_PREREQ_]PAC_SUBCFG_AUTO_SUFFIX,[ AC_DEFUN([PAC_SUBCFG_BODY_]PAC_SUBCFG_AUTO_SUFFIX,[ -AM_CONDITIONAL([BUILD_PMI_SIMPLE],[test "x$pmi_name" = "xsimple"]) - AM_COND_IF([BUILD_PMI_SIMPLE],[ if test "$enable_pmiport" != "no" ; then enable_pmiport=yes From e77184661068078f96535cd9e0a037575147c5b9 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 4 Mar 2022 08:16:50 -0600 Subject: [PATCH 549/607] configure: use PAC_SKIP_MPL_LIB When building romio within mpich, we only need set mpl_includedir since libmpl is included in mpich already. Define and use a specific m4 macro, PAC_SKIP_MPL_LIB, for this purpose rather than making the exception based on AC_PACKAGE_NAME. This easily allows additional package, e.g. pmi, to do the same. --- confdb/aclocal_modules.m4 | 2 +- src/mpi/romio/configure.ac | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/confdb/aclocal_modules.m4 b/confdb/aclocal_modules.m4 index 629f47ee2b3..2189ab90b0a 100644 --- a/confdb/aclocal_modules.m4 +++ b/confdb/aclocal_modules.m4 @@ -24,7 +24,7 @@ AC_DEFUN([PAC_CONFIG_MPL],[ dnl ---- sub-configure (e.g. hydra, romio) ---- if test "$FROM_MPICH" = "yes"; then dnl skip ROMIO since mpich already links libmpl.la - m4_if(AC_PACKAGE_NAME, [ROMIO], [], [ + m4_ifndef([PAC_SKIP_MPL_LIB], [ mpl_lib="$main_top_builddir/src/mpl/libmpl.la" ]) mpl_includedir="-I$main_top_builddir/src/mpl/include -I$main_top_srcdir/src/mpl/include" diff --git a/src/mpi/romio/configure.ac b/src/mpi/romio/configure.ac index ed801b2f235..142f7bc2f0e 100644 --- a/src/mpi/romio/configure.ac +++ b/src/mpi/romio/configure.ac @@ -151,6 +151,7 @@ if test "$FROM_MPICH" = "no" ; then else # we are configuring romio inside mpich. MPICH should configured MPL already, following # macro will just set mpl_includedir and source mpl/localdefs if any. + m4_define([PAC_SKIP_MPL_LIB], [yes]) PAC_CONFIG_MPL fi From 1836650000a34b50bbdd023bfea552233c76103f Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Thu, 3 Mar 2022 22:48:52 -0600 Subject: [PATCH 550/607] pmi: make pmi a submodule Make pmi a submodule like mpl and romio. This allows to just build and install libpmi, allowing applications and tests to use PMI interface without mpi. --- Makefile.am | 4 +- autogen.sh | 15 ++- configure.ac | 14 ++- src/Makefile.mk | 1 - src/pmi/Makefile.am | 29 ++++++ src/pmi/Makefile.mk | 9 -- src/pmi/autogen.sh | 12 +++ .../{simple/subconfigure.m4 => configure.ac} | 91 +++++++++++++++---- src/pmi/include/pmi.h | 3 + src/pmi/{pmi2 => }/include/pmi2.h | 5 +- src/pmi/pmi2/Makefile.mk | 6 -- src/pmi/pmi2/simple/Makefile.mk | 21 ----- src/pmi/pmi2/simple/pmi2compat.h | 3 + src/pmi/pmi2/simple/simple2pmi.c | 8 +- src/pmi/pmi2/simple/simple2pmi.h | 2 +- src/pmi/pmi2/simple/simple_pmiutil.c | 2 +- src/pmi/pmi2/simple/simple_pmiutil.h | 2 - src/pmi/pmi2/simple/subconfigure.m4 | 85 ----------------- src/pmi/pmi2/subconfigure.m4 | 90 ------------------ src/pmi/simple/Makefile.mk | 19 ---- src/pmi/simple/simple_pmi.c | 18 +++- src/pmi/simple/simple_pmiutil.c | 2 +- src/pmi/subconfigure.m4 | 14 --- 23 files changed, 167 insertions(+), 288 deletions(-) create mode 100644 src/pmi/Makefile.am delete mode 100644 src/pmi/Makefile.mk create mode 100755 src/pmi/autogen.sh rename src/pmi/{simple/subconfigure.m4 => configure.ac} (55%) rename src/pmi/{pmi2 => }/include/pmi2.h (99%) delete mode 100644 src/pmi/pmi2/Makefile.mk delete mode 100644 src/pmi/pmi2/simple/Makefile.mk delete mode 100644 src/pmi/pmi2/simple/subconfigure.m4 delete mode 100644 src/pmi/pmi2/subconfigure.m4 delete mode 100644 src/pmi/simple/Makefile.mk delete mode 100644 src/pmi/subconfigure.m4 diff --git a/Makefile.am b/Makefile.am index 7ae7d44195c..4b27d78fece 100644 --- a/Makefile.am +++ b/Makefile.am @@ -48,11 +48,11 @@ pkgconfigdir = @pkgconfigdir@ # to build src/mpi/errhan/defmsg.h errnames_txt_files = -external_subdirs = @mplsrcdir@ @zmsrcdir@ @hwlocsrcdir@ @jsonsrcdir@ @yaksasrcdir@ +external_subdirs = @mplsrcdir@ @zmsrcdir@ @hwlocsrcdir@ @jsonsrcdir@ @yaksasrcdir@ @pmisrcdir@ external_ldflags = @mpllibdir@ @zmlibdir@ @yaksalibdir@ external_libs = @WRAPPER_LIBS@ mpi_convenience_libs = -pmpi_convenience_libs = @mpllib@ @zmlib@ @hwloclib@ @jsonlib@ @yaksalib@ +pmpi_convenience_libs = @mpllib@ @zmlib@ @hwloclib@ @jsonlib@ @yaksalib@ @pmilib@ # NOTE on our semi-unconventional usage of DIST_SUBDIRS: # The automake manual recommends thinking of DIST_SUBDIRS as the list of all diff --git a/autogen.sh b/autogen.sh index e1e515f52cf..fd2ae714e21 100755 --- a/autogen.sh +++ b/autogen.sh @@ -65,6 +65,7 @@ do_test=yes do_hydra=yes do_hydra2=yes do_romio=yes +do_pmi=yes do_doc=no do_quick=no @@ -95,7 +96,7 @@ done MAKE=${MAKE-make} # amdirs are the directories that make use of autoreconf -amdirs=". src/mpl" +amdirs=". src/mpl src/pmi" autoreconf_args="-if" export autoreconf_args @@ -208,6 +209,10 @@ set_externals() { externals="${externals} src/mpi/romio" fi + if [ "yes" = "$do_pmi" ] ; then + externals="${externals} src/pmi" + fi + if [ "yes" = "$do_hwloc" ] ; then check_submodule_presence modules/hwloc externals="${externals} modules/hwloc" @@ -297,6 +302,13 @@ fn_copy_confdb_etc() { confdb_dirs= confdb_dirs="${confdb_dirs} src/mpl/confdb" + if test "$do_pmi" = "yes" ; then + confdb_dirs="${confdb_dirs} src/pmi/confdb" + if test "$do_quick" = "no" ; then + sync_external src/mpl src/pmi/mpl + confdb_dirs="${confdb_dirs} src/pmi/mpl/confdb" + fi + fi if test "$do_romio" = "yes" ; then confdb_dirs="${confdb_dirs} src/mpi/romio/confdb" if test "$do_quick" = "no" ; then @@ -337,6 +349,7 @@ fn_copy_confdb_etc() { cp -pPR maint/version.m4 src/pm/hydra/version.m4 cp -pPR maint/version.m4 src/pm/hydra2/version.m4 cp -pPR maint/version.m4 src/mpi/romio/version.m4 + cp -pPR maint/version.m4 src/pmi/version.m4 cp -pPR maint/version.m4 test/mpi/version.m4 fi diff --git a/configure.ac b/configure.ac index 7dc3fb351e7..46c9cf89870 100644 --- a/configure.ac +++ b/configure.ac @@ -1672,8 +1672,18 @@ AM_CONDITIONAL([PRIMARY_PM_REMSHELL],[test "X$first_pm_name" = "Xremshell"]) # ---- $with_pmilib ---- -AM_CONDITIONAL([BUILD_PMI_SIMPLE], [test "$with_pmilib" = "mpich" -a "$with_pmi" = "pmi1"]) -AM_CONDITIONAL([BUILD_PMI_PMI2_SIMPLE], [test "$with_pmilib" = "mpich" -a "$with_pmi" = "pmi2"]) +pmisrcdir="" +AC_SUBST([pmisrcdir]) +pmilib="" +AC_SUBST([pmilib]) + +if test "$with_pmilib" = "mpich" ; then + pmisrcdir="src/pmi" + pmilib="src/pmi/libpmi.la" + PAC_CONFIG_SUBDIR_ARGS([src/pmi], [--enable-embedded]) + PAC_APPEND_FLAG([-I${use_top_srcdir}/src/pmi/include], [CPPFLAGS]) + PAC_APPEND_FLAG([-I${main_top_builddir}/src/pmi/include], [CPPFLAGS]) +fi case "$with_pmilib" in mpich) diff --git a/src/Makefile.mk b/src/Makefile.mk index ab003174422..05c3acb0391 100644 --- a/src/Makefile.mk +++ b/src/Makefile.mk @@ -16,4 +16,3 @@ include $(top_srcdir)/src/mpi_t/Makefile.mk include $(top_srcdir)/src/nameserv/Makefile.mk include $(top_srcdir)/src/packaging/Makefile.mk include $(top_srcdir)/src/pm/Makefile.mk -include $(top_srcdir)/src/pmi/Makefile.mk diff --git a/src/pmi/Makefile.am b/src/pmi/Makefile.am new file mode 100644 index 00000000000..fb68089ad7b --- /dev/null +++ b/src/pmi/Makefile.am @@ -0,0 +1,29 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +ACLOCAL_AMFLAGS = -I confdb +AM_CPPFLAGS = -I$(top_srcdir)/include + +if EMBEDDED_MODE +noinst_LTLIBRARIES = libpmi.la + +else +include_HEADERS = \ + include/pmi.h \ + include/pmi2.h + +lib_LTLIBRARIES = libpmi.la +endif + +SUBDIRS = @mpl_srcdir@ +AM_CPPFLAGS += @mpl_includedir@ + +libpmi_la_LIBADD = @mpl_lib@ + +libpmi_la_SOURCES = \ + simple/simple_pmi.c \ + simple/simple_pmiutil.c \ + pmi2/simple/simple2pmi.c \ + pmi2/simple/simple_pmiutil.c diff --git a/src/pmi/Makefile.mk b/src/pmi/Makefile.mk deleted file mode 100644 index da732a8136b..00000000000 --- a/src/pmi/Makefile.mk +++ /dev/null @@ -1,9 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -include $(top_srcdir)/src/pmi/pmi2/Makefile.mk -include $(top_srcdir)/src/pmi/simple/Makefile.mk - -errnames_txt_files += src/pmi/errnames.txt diff --git a/src/pmi/autogen.sh b/src/pmi/autogen.sh new file mode 100755 index 00000000000..c4e258b321f --- /dev/null +++ b/src/pmi/autogen.sh @@ -0,0 +1,12 @@ +#! /bin/sh +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +${AUTORECONF:-autoreconf} ${autoreconf_args:-"-vif"} -I confdb + +if test -d mpl ; then + echo "=== running autoreconf in 'mpl' ===" + (cd mpl && ${AUTORECONF:-autoreconf} ${autoreconf_args:-"-vif"}) || exit 1 +fi diff --git a/src/pmi/simple/subconfigure.m4 b/src/pmi/configure.ac similarity index 55% rename from src/pmi/simple/subconfigure.m4 rename to src/pmi/configure.ac index 670d480a23f..a2d980fad16 100644 --- a/src/pmi/simple/subconfigure.m4 +++ b/src/pmi/configure.ac @@ -1,15 +1,78 @@ -[#] start of __file__ -dnl MPICH_SUBCFG_AFTER=src/pmi +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## -AC_DEFUN([PAC_SUBCFG_PREREQ_]PAC_SUBCFG_AUTO_SUFFIX,[ -]) +AC_PREREQ([2.69]) + +AC_INIT([PMI], [1.2]) + +AC_CONFIG_AUX_DIR(confdb) +AC_CONFIG_MACRO_DIR(confdb) +AC_USE_SYSTEM_EXTENSIONS +AM_INIT_AUTOMAKE([-Wall -Werror foreign 1.12.3 subdir-objects no-dist]) +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +AM_PROG_AR + +AC_PROG_CC +AM_PROG_CC_C_O + +PAC_C_NO_COMMON -AC_DEFUN([PAC_SUBCFG_BODY_]PAC_SUBCFG_AUTO_SUFFIX,[ +LT_PREREQ([2.2.6]) + +PAC_PUSH_FLAG([CFLAGS]) +LT_INIT() +PAC_POP_FLAG([CFLAGS]) + +AC_CONFIG_HEADERS([include/pmi_config.h]) + +AC_ARG_ENABLE([embedded], + AS_HELP_STRING([--enable-embedded], [Build in embedded mode]), + [enable_embedded=yes], + [enable_embedded=no]) +AM_CONDITIONAL([EMBEDDED_MODE], [test "$enable_embedded" = "yes"]) + +# MPL +mpl_srcdir= +AC_SUBST([mpl_srcdir]) +mpl_includedir= +AC_SUBST([mpl_includedir]) +mpl_lib= +AC_SUBST([mpl_lib]) + +if test "$FROM_MPICH" = "yes" ; then + m4_define([PAC_SKIP_MPL_LIB], [yes]) + PAC_CONFIG_MPL +else + mpl_srcdir="mpl" + mpl_subdir_args="--disable-versioning --enable-embedded" + PAC_CONFIG_SUBDIR_ARGS([mpl],[$mpl_subdir_args],[],[AC_MSG_ERROR(MPL configure failed)]) + mpl_includedir='-I$(top_builddir)/mpl/include -I$(top_srcdir)/mpl/include' + mpl_lib="mpl/libmpl.la" +fi + +# check "mpi.h" for MPI_MAX_PORT_NAME +if test "$FROM_MPICH" = "yes" ; then + PAC_APPEND_FLAG([-I${main_top_srcdir}/src/include], [CPPFLAGS]) + AC_DEFINE([HAVE_MPI_H], 1, [define if we have mpi.h]) +else + AC_CHECK_HEADER([mpi.h]) +fi + +if test "$enable_error_checking" != "no" ; then + AC_DEFINE([HAVE_ERROR_CHECKING], 1, [Define to enable error checking]) +fi + +AC_ARG_ENABLE(pmiport, +[--enable-pmiport - Allow PMI interface to use a host-port pair to contact + for PMI services],,enable_pmiport=default) -AM_COND_IF([BUILD_PMI_SIMPLE],[ if test "$enable_pmiport" != "no" ; then enable_pmiport=yes fi + AC_CHECK_HEADERS(unistd.h string.h stdlib.h sys/socket.h strings.h assert.h arpa/inet.h) dnl Use snprintf if possible when creating messages AC_CHECK_FUNCS(snprintf) @@ -18,14 +81,6 @@ if test "$ac_cv_func_snprintf" = "yes" ; then fi AC_CHECK_FUNCS(strncasecmp) -# -# PM's that need support for a port can set the environment variable -# NEED_PMIPORT in their setup_pm script. -if test "$NEED_PMIPORT" = "yes" -a "$enable_pmiport" != "yes" ; then - AC_MSG_WARN([The process manager requires the pmiport capability. Do not specify --disable-pmiport.]) - enable_pmiport=yes -fi -# if test "$enable_pmiport" = "yes" ; then # Check for the necessary includes and functions missing_headers=no @@ -42,7 +97,7 @@ if test "$enable_pmiport" = "yes" ; then AC_SEARCH_LIBS(socket,socket,,[missing_functions=yes]) AC_SEARCH_LIBS(gethostbyname,nsl,,[missing_functions=yes]) AC_SEARCH_LIBS(setsockopt,,,[missing_functions=yes]) - + if test "$missing_functions" = "no" ; then AC_DEFINE(USE_PMI_PORT,1,[Define if access to PMI information through a port rather than just an fd is allowed]) else @@ -76,8 +131,6 @@ if test "$pac_cv_have_haddr_list" = "yes" ; then AC_DEFINE(HAVE_H_ADDR_LIST,1,[Define if struct hostent contains h_addr_list]) fi PAC_C_GNU_ATTRIBUTE -])dnl end COND_IF - -])dnl end BODY macro -[#] end of __file__ +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/src/pmi/include/pmi.h b/src/pmi/include/pmi.h index 14141f027b2..4200cc66278 100644 --- a/src/pmi/include/pmi.h +++ b/src/pmi/include/pmi.h @@ -6,6 +6,9 @@ #ifndef PMI_H_INCLUDED #define PMI_H_INCLUDED +#define PMI_VERSION 1 +#define PMI_SUBVERSION 1 + #ifdef USE_PMI2_API #error This header file defines the PMI v1 API, but PMI2 was selected #endif diff --git a/src/pmi/pmi2/include/pmi2.h b/src/pmi/include/pmi2.h similarity index 99% rename from src/pmi/pmi2/include/pmi2.h rename to src/pmi/include/pmi2.h index d9b7109be96..ab63bf8415c 100644 --- a/src/pmi/pmi2/include/pmi2.h +++ b/src/pmi/include/pmi2.h @@ -6,9 +6,8 @@ #ifndef PMI2_H_INCLUDED #define PMI2_H_INCLUDED -#ifndef USE_PMI2_API -#error This header file defines the PMI2 API, but PMI2 was not selected -#endif +#define PMI_VERSION 2 +#define PMI_SUBVERSION 0 #define PMI2_MAX_KEYLEN 64 #define PMI2_MAX_VALLEN 1024 diff --git a/src/pmi/pmi2/Makefile.mk b/src/pmi/pmi2/Makefile.mk deleted file mode 100644 index 3be21474058..00000000000 --- a/src/pmi/pmi2/Makefile.mk +++ /dev/null @@ -1,6 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -include $(top_srcdir)/src/pmi/pmi2/simple/Makefile.mk diff --git a/src/pmi/pmi2/simple/Makefile.mk b/src/pmi/pmi2/simple/Makefile.mk deleted file mode 100644 index 8f70657b516..00000000000 --- a/src/pmi/pmi2/simple/Makefile.mk +++ /dev/null @@ -1,21 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -if BUILD_PMI_PMI2_SIMPLE - -mpi_core_sources += \ - src/pmi/pmi2/simple/simple2pmi.c \ - src/pmi/pmi2/simple/simple_pmiutil.c - -noinst_HEADERS += \ - src/pmi/pmi2/simple/simple_pmiutil.h \ - src/pmi/pmi2/simple/simple2pmi.h \ - src/pmi/pmi2/simple/pmi2compat.h \ - src/pmi/pmi2/include/pmi2.h - -AM_CPPFLAGS += -I$(top_srcdir)/src/pmi/pmi2/simple -AM_CPPFLAGS += -I$(top_srcdir)/src/pmi/pmi2/include - -endif BUILD_PMI_PMI2_SIMPLE diff --git a/src/pmi/pmi2/simple/pmi2compat.h b/src/pmi/pmi2/simple/pmi2compat.h index 8c762eb4f83..db50b14ebba 100644 --- a/src/pmi/pmi2/simple/pmi2compat.h +++ b/src/pmi/pmi2/simple/pmi2compat.h @@ -17,4 +17,7 @@ #define PMI2U_Exit MPL_exit #define PMI2U_Memcpy memcpy +#define TRUE 1 +#define FALSE 0 + #endif /* PMI2COMPAT_H_INCLUDED */ diff --git a/src/pmi/pmi2/simple/simple2pmi.c b/src/pmi/pmi2/simple/simple2pmi.c index 1c6f677b4f4..8360a7c9688 100644 --- a/src/pmi/pmi2/simple/simple2pmi.c +++ b/src/pmi/pmi2/simple/simple2pmi.c @@ -3,13 +3,14 @@ * See COPYRIGHT in top-level directory */ +#include "pmi_config.h" + #include "pmi2compat.h" #include "simple2pmi.h" #include "simple_pmiutil.h" #include "pmi2.h" #include "mpl.h" - #include #ifdef HAVE_UNISTD_H #include @@ -27,17 +28,12 @@ #include #endif -#ifdef USE_PMI_PORT #ifndef MAXHOSTNAME #define MAXHOSTNAME 256 #endif -#endif #define PMII_EXIT_CODE -1 -#define PMI_VERSION 2 -#define PMI_SUBVERSION 0 - #define MAX_INT_STR_LEN 11 /* number of digits in MAX_UINT + 1 */ typedef enum { PMI2_UNINITIALIZED = 0, diff --git a/src/pmi/pmi2/simple/simple2pmi.h b/src/pmi/pmi2/simple/simple2pmi.h index bac23341f46..9a6eb421a1a 100644 --- a/src/pmi/pmi2/simple/simple2pmi.h +++ b/src/pmi/pmi2/simple/simple2pmi.h @@ -6,7 +6,7 @@ #ifndef SIMPLE2PMI_H_INCLUDED #define SIMPLE2PMI_H_INCLUDED -#include "mpichconf.h" +#include "pmi_config.h" #define PMII_COMMANDLEN_SIZE 6 diff --git a/src/pmi/pmi2/simple/simple_pmiutil.c b/src/pmi/pmi2/simple/simple_pmiutil.c index 72c68449983..c995171110b 100644 --- a/src/pmi/pmi2/simple/simple_pmiutil.c +++ b/src/pmi/pmi2/simple/simple_pmiutil.c @@ -10,7 +10,7 @@ the PMI interface itself. Reading and writing on pipes, signals, and parsing key=value messages */ -#include "mpichconf.h" +#include "pmi_config.h" #include "pmi2compat.h" #include "mpl.h" diff --git a/src/pmi/pmi2/simple/simple_pmiutil.h b/src/pmi/pmi2/simple/simple_pmiutil.h index 68908180fcb..4d15062b6a2 100644 --- a/src/pmi/pmi2/simple/simple_pmiutil.h +++ b/src/pmi/pmi2/simple/simple_pmiutil.h @@ -6,8 +6,6 @@ #ifndef SIMPLE_PMIUTIL_H_INCLUDED #define SIMPLE_PMIUTIL_H_INCLUDED -#include "mpichconf.h" - /* maximum sizes for arrays */ #define PMI2U_MAXLINE 1024 #define PMI2U_IDSIZE 32 diff --git a/src/pmi/pmi2/simple/subconfigure.m4 b/src/pmi/pmi2/simple/subconfigure.m4 deleted file mode 100644 index 35431ec2b4d..00000000000 --- a/src/pmi/pmi2/simple/subconfigure.m4 +++ /dev/null @@ -1,85 +0,0 @@ -[#] start of __file__ -dnl MPICH_SUBCFG_AFTER=src/pmi - -AC_DEFUN([PAC_SUBCFG_PREREQ_]PAC_SUBCFG_AUTO_SUFFIX,[ -]) - -AC_DEFUN([PAC_SUBCFG_BODY_]PAC_SUBCFG_AUTO_SUFFIX,[ - -AM_COND_IF([BUILD_PMI_PMI2_SIMPLE],[ -if test "$enable_pmiport" != "no" ; then - enable_pmiport=yes -fi - -dnl causes USE_PMI2_API to be AC_DEFINE'ed by the top-level configure.ac -USE_PMI2_API=yes - -AC_CHECK_HEADERS([unistd.h string.h stdlib.h sys/socket.h strings.h assert.h]) -dnl Use snprintf if possible when creating messages -AC_CHECK_FUNCS(snprintf) -if test "$ac_cv_func_snprintf" = "yes" ; then - PAC_FUNC_NEEDS_DECL([#include ],snprintf) -fi -AC_CHECK_FUNCS(strncasecmp) -# -# PM's that need support for a port can set the environment variable -# NEED_PMIPORT in their setup_pm script. -if test "$NEED_PMIPORT" = "yes" -a "$enable_pmiport" != "yes" ; then - AC_MSG_WARN([The process manager requires the pmiport capability. Do not specify --disable-pmiport.]) - enable_pmiport=yes -fi -# -if test "$enable_pmiport" = "yes" ; then - # Check for the necessary includes and functions - missing_headers=no - AC_CHECK_HEADERS([ \ - sys/types.h \ - sys/param.h \ - sys/socket.h \ - netinet/in.h \ - netinet/tcp.h \ - sys/un.h \ - netdb.h \ - ],,missing_headers=yes ) - missing_functions=no - AC_SEARCH_LIBS(socket,socket,,[missing_functions=yes]) - AC_SEARCH_LIBS(gethostbyname,nsl,,[missing_functions=yes]) - AC_SEARCH_LIBS(setsockopt,,,[missing_functions=yes]) - - if test "$missing_functions" = "no" ; then - AC_DEFINE(USE_PMI_PORT,1,[Define if access to PMI information through a port rather than just an fd is allowed]) - else - AC_MSG_ERROR([Cannot build simple PMI with support for an IP port because of missing functions]) - fi -fi - -# Check for socklen_t . If undefined, define it as int -# (note the conditional inclusion of sys/socket.h) -AC_CACHE_CHECK([whether socklen_t is defined (in sys/socket.h if present)], pac_cv_have_socklen_t,[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include - #ifdef HAVE_SYS_SOCKET_H - #include - #endif - typedef struct { double a; int b; } socklen_t; - ]],[[ - socklen_t a;a.a=1.0; - ]])],pac_cv_have_socklen_t=no,pac_cv_have_socklen_t=yes) -]) -if test "$pac_cv_have_socklen_t" = no ; then - AC_DEFINE(socklen_t,int,[Define if socklen_t is not defined]) -fi -# Check for h_addr or h_addr_list -AC_CACHE_CHECK([whether struct hostent contains h_addr_list], pac_cv_have_haddr_list,[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]],[[struct hostent hp;hp.h_addr_list[0]=0;]])], - pac_cv_have_haddr_list=yes,pac_cv_have_haddr_list=no) -]) -if test "$pac_cv_have_haddr_list" = "yes" ; then - AC_DEFINE(HAVE_H_ADDR_LIST,1,[Define if struct hostent contains h_addr_list]) -fi -PAC_C_GNU_ATTRIBUTE -])dnl end COND_IF - -])dnl end BODY macro - -[#] end of __file__ diff --git a/src/pmi/pmi2/subconfigure.m4 b/src/pmi/pmi2/subconfigure.m4 deleted file mode 100644 index b3cd38b0c3b..00000000000 --- a/src/pmi/pmi2/subconfigure.m4 +++ /dev/null @@ -1,90 +0,0 @@ -[#] start of __file__ -dnl MPICH_SUBCFG_AFTER=src/pmi - -AC_DEFUN([PAC_SUBCFG_PREREQ_]PAC_SUBCFG_AUTO_SUFFIX,[ -]) - -AC_DEFUN([PAC_SUBCFG_BODY_]PAC_SUBCFG_AUTO_SUFFIX,[ - -AM_CONDITIONAL([BUILD_PMI_PMI2],[test "x$pmi_name" = "xpmi2"]) - -AM_COND_IF([BUILD_PMI_PMI2],[ -if test "$enable_pmiport" != "no" ; then - enable_pmiport=yes -fi - -dnl causes USE_PMI2_API to be AC_DEFINE'ed by the top-level configure.ac -USE_PMI2_API=yes - -AC_ARG_ENABLE(pmiport, -[--enable-pmiport - Allow PMI interface to use a host-port pair to contact - for PMI services],,enable_pmiport=default) -AC_CHECK_HEADERS([unistd.h string.h stdlib.h sys/socket.h strings.h assert.h]) -dnl Use snprintf if possible when creating messages -AC_CHECK_FUNCS(snprintf) -if test "$ac_cv_func_snprintf" = "yes" ; then - PAC_FUNC_NEEDS_DECL([#include ],snprintf) -fi -AC_CHECK_FUNCS(strncasecmp) -# -# PM's that need support for a port can set the environment variable -# NEED_PMIPORT in their setup_pm script. -if test "$NEED_PMIPORT" = "yes" -a "$enable_pmiport" != "yes" ; then - AC_MSG_WARN([The process manager requires the pmiport capability. Do not specify --disable-pmiport.]) - enable_pmiport=yes -fi -# -if test "$enable_pmiport" = "yes" ; then - # Check for the necessary includes and functions - missing_headers=no - AC_CHECK_HEADERS([ \ - sys/types.h \ - sys/param.h \ - sys/socket.h \ - netinet/in.h \ - netinet/tcp.h \ - sys/un.h \ - netdb.h \ - ],,missing_headers=yes ) - missing_functions=no - AC_SEARCH_LIBS(socket,socket,,[missing_functions=yes]) - AC_SEARCH_LIBS(gethostbyname,nsl,,[missing_functions=yes]) - AC_SEARCH_LIBS(setsockopt,,,[missing_functions=yes]) - - if test "$missing_functions" = "no" ; then - AC_DEFINE(USE_PMI_PORT,1,[Define if access to PMI information through a port rather than just an fd is allowed]) - else - AC_MSG_ERROR([Cannot build simple PMI with support for an IP port because of missing functions]) - fi -fi - -# Check for socklen_t . If undefined, define it as int -# (note the conditional inclusion of sys/socket.h) -AC_CACHE_CHECK([whether socklen_t is defined (in sys/socket.h if present)], pac_cv_have_socklen_t,[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include - #ifdef HAVE_SYS_SOCKET_H - #include - #endif - typedef struct { double a; int b; } socklen_t; - ]],[[ - socklen_t a;a.a=1.0; - ]])],pac_cv_have_socklen_t=no,pac_cv_have_socklen_t=yes) -]) -if test "$pac_cv_have_socklen_t" = no ; then - AC_DEFINE(socklen_t,int,[Define if socklen_t is not defined]) -fi -# Check for h_addr or h_addr_list -AC_CACHE_CHECK([whether struct hostent contains h_addr_list], pac_cv_have_haddr_list,[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]],[[struct hostent hp;hp.h_addr_list[0]=0;]])], - pac_cv_have_haddr_list=yes,pac_cv_have_haddr_list=no) -]) -if test "$pac_cv_have_haddr_list" = "yes" ; then - AC_DEFINE(HAVE_H_ADDR_LIST,1,[Define if struct hostent contains h_addr_list]) -fi -PAC_C_GNU_ATTRIBUTE -])dnl end COND_IF - -])dnl end BODY macro - -[#] end of __file__ diff --git a/src/pmi/simple/Makefile.mk b/src/pmi/simple/Makefile.mk deleted file mode 100644 index 79914c48fb4..00000000000 --- a/src/pmi/simple/Makefile.mk +++ /dev/null @@ -1,19 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -if BUILD_PMI_SIMPLE - -mpi_core_sources += \ - src/pmi/simple/simple_pmiutil.c \ - src/pmi/simple/simple_pmi.c - -noinst_HEADERS += \ - src/pmi/simple/simple_pmiutil.h \ - src/pmi/include/pmi.h - -AM_CPPFLAGS += -I$(top_srcdir)/src/pmi/simple -AM_CPPFLAGS += -I$(top_srcdir)/src/pmi/include - -endif BUILD_PMI_SIMPLE diff --git a/src/pmi/simple/simple_pmi.c b/src/pmi/simple/simple_pmi.c index 5d0e6e2dea1..4ae44cb9711 100644 --- a/src/pmi/simple/simple_pmi.c +++ b/src/pmi/simple/simple_pmi.c @@ -16,10 +16,7 @@ */ /***************************************************************************/ -#include "mpichconf.h" - -#define PMI_VERSION 1 -#define PMI_SUBVERSION 1 +#include "pmi_config.h" #include #ifdef HAVE_UNISTD_H @@ -52,7 +49,12 @@ #include "pmi.h" #include "simple_pmiutil.h" + +#ifdef HAVE_MPI_H #include "mpi.h" /* to get MPI_MAX_PORT_NAME */ +#else +#define MPI_MAX_PORT_NAME 256 +#endif /* These are global variable used *ONLY* in this file, and are hence @@ -847,7 +849,13 @@ static int GetResponse(const char request[], const char expectedCmd[], int check /* ----------------------------------------------------------------------- */ -#ifdef USE_PMI_PORT +#ifndef USE_PMI_PORT +static int PMIi_InitIfSingleton(void) +{ + return PMI_FAIL; +} + +#else /* * This code allows a program to contact a host/port for the PMI socket. */ diff --git a/src/pmi/simple/simple_pmiutil.c b/src/pmi/simple/simple_pmiutil.c index cd7e98039ff..9516f5b3f6d 100644 --- a/src/pmi/simple/simple_pmiutil.c +++ b/src/pmi/simple/simple_pmiutil.c @@ -11,7 +11,7 @@ key=value messages */ -#include "mpichconf.h" +#include "pmi_config.h" #include #ifdef HAVE_STDLIB_H diff --git a/src/pmi/subconfigure.m4 b/src/pmi/subconfigure.m4 deleted file mode 100644 index bc91ab223f0..00000000000 --- a/src/pmi/subconfigure.m4 +++ /dev/null @@ -1,14 +0,0 @@ -[#] start of __file__ - -AC_DEFUN([PAC_SUBCFG_PREREQ_]PAC_SUBCFG_AUTO_SUFFIX,[ -]) - -AC_DEFUN([PAC_SUBCFG_BODY_]PAC_SUBCFG_AUTO_SUFFIX,[ - -# common ARG_ENABLE, shared by "simple" and "pmi2" -AC_ARG_ENABLE(pmiport, -[--enable-pmiport - Allow PMI interface to use a host-port pair to contact - for PMI services],,enable_pmiport=default) - -])dnl end BODY macro -[#] end of __file__ From 1e3433cfaed83239e65a6edc61168089c321e169 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 5 Mar 2022 09:45:39 -0600 Subject: [PATCH 551/607] pmi: add examples Add two basic examples on using PMI interfaces. --- src/pmi/examples/test_pmi1.c | 49 ++++++++++++++++++++++++++++++++++++ src/pmi/examples/test_pmi2.c | 33 ++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 src/pmi/examples/test_pmi1.c create mode 100644 src/pmi/examples/test_pmi2.c diff --git a/src/pmi/examples/test_pmi1.c b/src/pmi/examples/test_pmi1.c new file mode 100644 index 00000000000..e496cc365d7 --- /dev/null +++ b/src/pmi/examples/test_pmi1.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +/* Simple example using PMI-v1 interface. + * + * To compile: + * cc test_pmi1.c -lpmi + * + * To run: + * mpirun -n 2 ./a.out + */ + +#include +#include +#include "pmi.h" + +int main(int argc, char **argv) +{ + + char kvsname[1024]; + int has_parent, rank, size; + + PMI_Init(&has_parent); + PMI_Get_rank(&rank); + PMI_Get_size(&size); + fprintf(stdout, " :has_parent=%d, rank=%d, size=%d\n", has_parent, rank, size); + + PMI_KVS_Get_my_name(kvsname, 1024); + + if (rank == 0) { + /* NOTE: PMI-v1 does not allow space in both key and value */ + PMI_KVS_Put(kvsname, "key0", "got-key0"); + } + + PMI_Barrier(); + + if (rank == 1) { + char buf[100]; + int out_len; + + PMI_KVS_Get(kvsname, "key0", buf, 100); + fprintf(stdout, " Got key0 = [%s]\n", buf); + } + + PMI_Finalize(); + return 0; +} diff --git a/src/pmi/examples/test_pmi2.c b/src/pmi/examples/test_pmi2.c new file mode 100644 index 00000000000..7ef64ec1123 --- /dev/null +++ b/src/pmi/examples/test_pmi2.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include "pmi2.h" + +int main(int argc, char **argv) +{ + char jobid[1024]; + int has_paraent, rank, size, appnum; + + PMI2_Init(&has_paraent, &size, &rank, &appnum); + fprintf(stdout, " :has_paraent=%d, rank=%d, size=%d, appnum=%d\n", + has_paraent, rank, size, appnum); + + PMI2_Job_GetId(jobid, 1024); + + if (rank == 0) { + PMI2_KVS_Put("key0", "got key0"); + } + + PMI2_KVS_Fence(); + + if (rank == 1) { + char buf[100]; + int out_len; + + PMI2_KVS_Get(jobid, 0, "key0", buf, 100, &out_len); + fprintf(stdout, " got key0: %s (%d bytes)\n", buf, out_len); + } + + PMI2_Finalize(); + return 0; +} From b461cd6eaceeb9248b7582e982bf5a5e66fbe30f Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 5 Mar 2022 10:59:33 -0600 Subject: [PATCH 552/607] pmi: remove CHKLMEM and CHKPMEM macros There is a bug in these macros when HAVE_ERROR_CHECKING is not defined. There are only a single usage for both set of macros, and the code without using these macros is clean enough. Thus, rather than fixing the macros, we remove them. --- src/pmi/pmi2/simple/simple2pmi.c | 32 +++++++------- src/pmi/pmi2/simple/simple_pmiutil.h | 66 +++------------------------- 2 files changed, 22 insertions(+), 76 deletions(-) diff --git a/src/pmi/pmi2/simple/simple2pmi.c b/src/pmi/pmi2/simple/simple2pmi.c index 8360a7c9688..ffa7b968561 100644 --- a/src/pmi/pmi2/simple/simple2pmi.c +++ b/src/pmi/pmi2/simple/simple2pmi.c @@ -1264,16 +1264,15 @@ static int parse_keyval(char **cmdptr, int *len, char **key, char **val, int *va static int create_keyval(PMI2_Keyvalpair ** kv, const char *key, const char *val, int vallen) { int pmi2_errno = PMI2_SUCCESS; - char *key_p; - char *value_p; - PMI2U_CHKPMEM_DECL(3); + char *key_p = NULL; + char *value_p = NULL; - PMI2U_CHKPMEM_MALLOC(*kv, PMI2_Keyvalpair *, sizeof(PMI2_Keyvalpair), pmi2_errno, "pair"); + PMI2U_CHK_MALLOC(*kv, PMI2_Keyvalpair *, sizeof(PMI2_Keyvalpair), pmi2_errno, "pair"); - PMI2U_CHKPMEM_MALLOC(key_p, char *, strlen(key) + 1, pmi2_errno, "key"); + PMI2U_CHK_MALLOC(key_p, char *, strlen(key) + 1, pmi2_errno, "key"); MPL_strncpy(key_p, key, PMI2_MAX_KEYLEN + 1); - PMI2U_CHKPMEM_MALLOC(value_p, char *, vallen + 1, pmi2_errno, "value"); + PMI2U_CHK_MALLOC(value_p, char *, vallen + 1, pmi2_errno, "value"); PMI2U_Memcpy(value_p, val, vallen); value_p[vallen] = '\0'; @@ -1283,10 +1282,11 @@ static int create_keyval(PMI2_Keyvalpair ** kv, const char *key, const char *val (*kv)->isCopy = TRUE; fn_exit: - PMI2U_CHKPMEM_COMMIT(); return pmi2_errno; fn_fail: - PMI2U_CHKPMEM_REAP(); + PMI2U_Free(*kv); + PMI2U_Free(key_p); + PMI2U_Free(value_p); goto fn_exit; } @@ -1616,13 +1616,12 @@ int PMIi_WriteSimpleCommandStr(int fd, PMI2_Command * resp, const char cmd[], .. { int pmi2_errno = PMI2_SUCCESS; va_list ap; - PMI2_Keyvalpair *pairs; - PMI2_Keyvalpair **pairs_p; + PMI2_Keyvalpair *pairs = NULL; + PMI2_Keyvalpair **pairs_p = NULL; int npairs; int i; const char *key; const char *val; - PMI2U_CHKLMEM_DECL(2); npairs = 0; va_start(ap, cmd); @@ -1633,10 +1632,10 @@ int PMIi_WriteSimpleCommandStr(int fd, PMI2_Command * resp, const char cmd[], .. } va_end(ap); - PMI2U_CHKLMEM_MALLOC(pairs, PMI2_Keyvalpair *, sizeof(PMI2_Keyvalpair) * npairs, pmi2_errno, - "pairs"); - PMI2U_CHKLMEM_MALLOC(pairs_p, PMI2_Keyvalpair **, sizeof(PMI2_Keyvalpair *) * npairs, - pmi2_errno, "pairs_p"); + PMI2U_CHK_MALLOC(pairs, PMI2_Keyvalpair *, sizeof(PMI2_Keyvalpair) * npairs, pmi2_errno, + "pairs"); + PMI2U_CHK_MALLOC(pairs_p, PMI2_Keyvalpair **, sizeof(PMI2_Keyvalpair *) * npairs, + pmi2_errno, "pairs_p"); i = 0; va_start(ap, cmd); @@ -1659,7 +1658,8 @@ int PMIi_WriteSimpleCommandStr(int fd, PMI2_Command * resp, const char cmd[], .. PMI2U_ERR_POP(pmi2_errno); fn_exit: - PMI2U_CHKLMEM_FREEALL(); + PMI2U_Free(pairs); + PMI2U_Free(pairs_p); return pmi2_errno; fn_fail: goto fn_exit; diff --git a/src/pmi/pmi2/simple/simple_pmiutil.h b/src/pmi/pmi2/simple/simple_pmiutil.h index 4d15062b6a2..f89c44c020b 100644 --- a/src/pmi/pmi2/simple/simple_pmiutil.h +++ b/src/pmi/pmi2/simple/simple_pmiutil.h @@ -112,66 +112,12 @@ extern int PMI2_pmiverbose; /* Set this to true to print PMI debugging info #define PMI2U_CHKMEM_SETERR(rc_, nbytes_, name_) rc_ = PMI2_ERR_NOMEM #endif - -#define PMI2U_CHKLMEM_DECL(n_) \ - void *(pmi2u_chklmem_stk_[n_]) = {0}; \ - int pmi2u_chklmem_stk_sp_=0; \ - PMI2U_AssertDeclValue(const int pmi2u_chklmem_stk_sz_,n_) - -#define PMI2U_CHKLMEM_MALLOC_ORSTMT(pointer_,type_,nbytes_,rc_,name_,stmt_) do { \ - pointer_ = (type_)PMI2U_Malloc(nbytes_); \ - if (pointer_) { \ - PMI2U_Assert(pmi2u_chklmem_stk_sp_ 0) { \ - PMI2U_Free(pmi2u_chklmem_stk_[--pmi2u_chklmem_stk_sp_]); } - -#define PMI2U_CHKLMEM_MALLOC(pointer_,type_,nbytes_,rc_,name_) \ - PMI2U_CHKLMEM_MALLOC_ORJUMP(pointer_,type_,nbytes_,rc_,name_) -#define PMI2U_CHKLMEM_MALLOC_ORJUMP(pointer_,type_,nbytes_,rc_,name_) \ - PMI2U_CHKLMEM_MALLOC_ORSTMT(pointer_,type_,nbytes_,rc_,name_,goto fn_fail) - -/* Persistent memory that we may want to recover if something goes wrong */ -#define PMI2U_CHKPMEM_DECL(n_) \ - void *(pmi2u_chkpmem_stk_[n_]) = {0}; \ - int pmi2u_chkpmem_stk_sp_=0; \ - PMI2U_AssertDeclValue(const int pmi2u_chkpmem_stk_sz_,n_) -#define PMI2U_CHKPMEM_MALLOC_ORSTMT(pointer_,type_,nbytes_,rc_,name_,stmt_) do { \ - pointer_ = (type_)PMI2U_Malloc(nbytes_); \ - if (pointer_) { \ - PMI2U_Assert(pmi2u_chkpmem_stk_sp_ 0) { \ - PMI2U_Free(pmi2u_chkpmem_stk_[--pmi2u_chkpmem_stk_sp_]); } -#define PMI2U_CHKPMEM_COMMIT() pmi2u_chkpmem_stk_sp_ = 0 -#define PMI2U_CHKPMEM_MALLOC(pointer_,type_,nbytes_,rc_,name_) \ - PMI2U_CHKPMEM_MALLOC_ORJUMP(pointer_,type_,nbytes_,rc_,name_) -#define PMI2U_CHKPMEM_MALLOC_ORJUMP(pointer_,type_,nbytes_,rc_,name_) \ - PMI2U_CHKPMEM_MALLOC_ORSTMT(pointer_,type_,nbytes_,rc_,name_,goto fn_fail) - -/* A special version for routines that only allocate one item */ -#define PMI2U_CHKPMEM_MALLOC1(pointer_,type_,nbytes_,rc_,name_,stmt_) do { \ - pointer_ = (type_)PMI2U_Malloc(nbytes_); \ - if (!(pointer_)) { \ - PMI2U_CHKMEM_SETERR(rc_,nbytes_,name_); \ - stmt_; \ - } \ +#define PMI2U_CHK_MALLOC(pointer_,type_,nbytes_,rc_,name_) do { \ + pointer_ = (type_)PMI2U_Malloc(nbytes_); \ + if (!pointer_) { \ + PMI2U_CHKMEM_SETERR(rc_,nbytes_,name_); \ + goto fn_fail; \ + } \ } while (0) /* Provides a easy way to use realloc safely and avoid the temptation to use From cfa8c02e6466fbcd34024015efc97e782fec7559 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 7 Mar 2022 12:47:45 -0600 Subject: [PATCH 553/607] pmi: fix warnings Cleanup warnings. Mostly these are unused static variables and functions. We can easily add them back if needed. However, we are likely to consolidate PMI1 and PMI2 implementation, and most of these stub holders won't be needed. --- src/pmi/pmi2/simple/simple2pmi.c | 76 ---------------------------- src/pmi/pmi2/simple/simple_pmiutil.c | 2 - 2 files changed, 78 deletions(-) diff --git a/src/pmi/pmi2/simple/simple2pmi.c b/src/pmi/pmi2/simple/simple2pmi.c index ffa7b968561..5073fbb96eb 100644 --- a/src/pmi/pmi2/simple/simple2pmi.c +++ b/src/pmi/pmi2/simple/simple2pmi.c @@ -49,7 +49,6 @@ static int PMI2_size = 1; static int PMI2_rank = 0; static int PMI2_is_threaded = 0; /* Set this to true to require thread safety */ -static int PMI2_debug_init = 0; /* Set this to true to debug the init */ int PMI2_pmiverbose = 0; /* Set this to true to print PMI debugging info */ @@ -122,10 +121,6 @@ static int getvalint(PMI2_Keyvalpair * const pairs[], int npairs, const char *ke static int getvalptr(PMI2_Keyvalpair * const pairs[], int npairs, const char *key, void *val); static int getvalbool(PMI2_Keyvalpair * const pairs[], int npairs, const char *key, int *val); -static int accept_one_connection(int list_sock); -static int GetResponse(const char request[], const char expectedCmd[], int checkRc); - -static void dump_PMI2_Command(FILE * file, PMI2_Command * cmd); static void dump_PMI2_Keyvalpair(FILE * file, PMI2_Keyvalpair * kv); @@ -1045,12 +1040,9 @@ int PMI2_Nameserv_lookup(const char service_name[], const PMI2_keyval_t * info_p int PMI2_Nameserv_unpublish(const char service_name[], const PMI2_keyval_t * info_ptr) { int pmi2_errno = PMI2_SUCCESS; - int found; int rc; PMI2_Command cmd = { 0 }; - int plen; const char *errmsg; - const char *found_port; pmi2_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, NAMEUNPUBLISH_CMD, NAME_KEY, service_name, INFOKEYCOUNT_KEY, "0", NULL); @@ -1797,20 +1789,6 @@ static int PMII_Connect_to_pm(char *hostname, int portnum) * (This is the usual init sequence). * */ -/* ------------------------------------------------------------------------- */ -/* This is a special routine used to re-initialize PMI when it is in - the singleton init case. That is, the executable was started without - mpiexec, and PMI2_Init returned as if there was only one process. - - Note that PMI routines should not call PMII_singinit; they should - call PMIi_InitIfSingleton(), which both connects to the process manager - and sets up the initial KVS connection entry. -*/ - -static int PMII_singinit(void) -{ - return 0; -} /* Promote PMI to a fully initialized version if it was started as a singleton init */ @@ -1819,30 +1797,6 @@ static int PMIi_InitIfSingleton(void) return 0; } -static int accept_one_connection(int list_sock) -{ - int gotit, new_sock; - MPL_sockaddr_t addr; - socklen_t len; - - len = sizeof(addr); - gotit = 0; - while (!gotit) { - new_sock = accept(list_sock, (struct sockaddr *) &addr, &len); - if (new_sock == -1) { - if (errno == EINTR) /* interrupted? If so, try again */ - continue; - else { - PMI2U_printf(1, "accept failed in accept_one_connection\n"); - exit(-1); - } - } else - gotit = 1; - } - return (new_sock); -} - - /* Get the FD to use for PMI operations. If a port is used, rather than a pre-established FD (i.e., via pipe), this routine will handle the initial handshake. @@ -1899,25 +1853,6 @@ static int getPMIFD(void) goto fn_exit; } -/* ----------------------------------------------------------------------- */ -/* - * This function is used to request information from the server and check - * that the response uses the expected command name. On a successful - * return from this routine, additional PMI2U_getval calls may be used - * to access information about the returned value. - * - * If checkRc is true, this routine also checks that the rc value returned - * was 0. If not, it uses the "msg" value to report on the reason for - * the failure. - */ -static int GetResponse(const char request[], const char expectedCmd[], int checkRc) -{ - int err = 0; - - return err; -} - - static void dump_PMI2_Keyvalpair(FILE * file, PMI2_Keyvalpair * kv) { fprintf(file, " key = %s\n", kv->key); @@ -1925,14 +1860,3 @@ static void dump_PMI2_Keyvalpair(FILE * file, PMI2_Keyvalpair * kv) fprintf(file, " valueLen = %d\n", kv->valueLen); fprintf(file, " isCopy = %s\n", kv->isCopy ? "TRUE" : "FALSE"); } - -static void dump_PMI2_Command(FILE * file, PMI2_Command * cmd) -{ - int i; - - fprintf(file, "cmd = %s\n", cmd->command); - fprintf(file, "nPairs = %d\n", cmd->nPairs); - - for (i = 0; i < cmd->nPairs; ++i) - dump_PMI2_Keyvalpair(file, cmd->pairs[i]); -} diff --git a/src/pmi/pmi2/simple/simple_pmiutil.c b/src/pmi/pmi2/simple/simple_pmiutil.c index c995171110b..61d463b99ca 100644 --- a/src/pmi/pmi2/simple/simple_pmiutil.c +++ b/src/pmi/pmi2/simple/simple_pmiutil.c @@ -110,7 +110,6 @@ int PMI2U_readline(int fd, char *buf, int maxlen) static char readbuf[MAX_READLINE]; static char *nextChar = 0, *lastChar = 0; /* lastChar is really one past * last char */ - static int lastErrno = 0; static int lastfd = -1; int curlen, n; char *p, ch; @@ -136,7 +135,6 @@ int PMI2U_readline(int fd, char *buf, int maxlen) /* Error. Return a negative value if there is no * data. Save the errno in case we need to return it * later. */ - lastErrno = errno; if (curlen == 1) { curlen = 0; } From ef9dde28d25722f8058e16838af1ef56b5364736 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 25 Mar 2022 17:02:40 -0500 Subject: [PATCH 554/607] pmi: amend notes on PMI_Barrier and PMI_KVS_Commit Add note that emphasize PMI_Barrier implies PMI_KVS_Commit. It means we can safely omit PMI_KVS_Commit if all PMI_KVS_Get is issues after a PMI_Barrier. Having additional PMI_KVS_Commit is harmless other than potential cost. PMI_KVS_Commit is a no op in our current implementation and hydra flushes local puts at barrier_in, so this notes reflect better our actual code. It is backward compatible anyway. --- src/pmi/include/pmi.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pmi/include/pmi.h b/src/pmi/include/pmi.h index 4200cc66278..30d9651ebe6 100644 --- a/src/pmi/include/pmi.h +++ b/src/pmi/include/pmi.h @@ -238,7 +238,7 @@ Return values: Notes: This function is a collective call across all processes in the process group the local process belongs to. It will not return until all the processes -have called 'PMI_Barrier()'. +have called 'PMI_Barrier()'. 'PMI_Barrier' automatically applies 'PMI_KVS_Commit'. @*/ int PMI_Barrier(void); @@ -354,7 +354,8 @@ Return values: Notes: This function puts the key/value pair in the specified keyval space. The -value is not visible to other processes until 'PMI_KVS_Commit()' is called. +value is not visible to other processes until 'PMI_KVS_Commit()' or +'PMI_Barrier' is called. 'PMI_Barrier' automatically applies 'PMI_KVS_Commit'. The function may complete locally. After 'PMI_KVS_Commit()' is called, the value may be retrieved by calling 'PMI_KVS_Get()'. All keys put to a keyval space must be unique to the keyval space. You may not put more than once From 4e61b73173e5a5e9b50da49a4e41fbb97ebbeb22 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 28 Mar 2022 14:16:07 -0500 Subject: [PATCH 555/607] autogen: add message when submodule is missing Add message to advise users to run git submodule checkout when they just cloned the repository. --- autogen.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autogen.sh b/autogen.sh index fd2ae714e21..6b3fdea3d2d 100755 --- a/autogen.sh +++ b/autogen.sh @@ -125,7 +125,10 @@ ProgHomeDir() { # checking and patching submodules check_submodule_presence() { if test ! -f "$SRCROOTDIR/$1/configure.ac"; then - error "Submodule $1 is not checked out" + error "Submodule $1 is not checked out." + error "if you just git cloned this repository, run" + error " git submodule update --init" + error "to checkout the submodules." exit 1 fi } @@ -191,9 +194,6 @@ set_externals() { if test -z "$externals" ; then #TODO: if necessary, run: git submodule update --init - # hwloc is always required - check_submodule_presence modules/hwloc - # external packages that require autogen.sh to be run for each of them externals="test/mpi" From a0c11f619c4c67aa6925c535f5a089431397ddc7 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 27 Mar 2022 10:39:41 -0500 Subject: [PATCH 556/607] test: add cuda test framework Add framework to run tests in CUDA's .cu format. --- test/mpi/Makefile_cuda.mtest | 32 ++++++++ test/mpi/configure.ac | 11 ++- test/mpi/impls/mpich/Makefile.am | 8 +- test/mpi/impls/mpich/cuda/Makefile.am | 11 +++ test/mpi/impls/mpich/cuda/saxpy.cu | 106 ++++++++++++++++++++++++++ test/mpi/impls/mpich/cuda/testlist | 1 + test/mpi/impls/mpich/testlist.in | 1 + 7 files changed, 162 insertions(+), 8 deletions(-) create mode 100644 test/mpi/Makefile_cuda.mtest create mode 100644 test/mpi/impls/mpich/cuda/Makefile.am create mode 100644 test/mpi/impls/mpich/cuda/saxpy.cu create mode 100644 test/mpi/impls/mpich/cuda/testlist diff --git a/test/mpi/Makefile_cuda.mtest b/test/mpi/Makefile_cuda.mtest new file mode 100644 index 00000000000..9e22e56a47d --- /dev/null +++ b/test/mpi/Makefile_cuda.mtest @@ -0,0 +1,32 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +## This is an automake makefile fragment that should be included by: +## +## include $(top_srcdir)/Makefile_cuda.mtest +## +## This makefile is for CUDA tests (compiled with nvcc). + +include $(top_srcdir)/Makefile_single.mtest + +AM_DEFAULT_SOURCE_EXT = .cu + +# Because libtool does not have a .cu language tag yet, some of the key +# variables and patter rule is not generated. We manually supply them here. + +# Automake silent build macros +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_0) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = + +# the LINK variable +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXX) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ + +# How to compile .cu files -- compile with mpicc, but using nvcc +.cu.o: + MPICH_CC=$(NVCC) $(CC) -c -o $@ $< diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index 15fd13d6f4d..e397fcace6a 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -477,7 +477,7 @@ AC_SUBST(comm_overlap) # The multi-thread tests can be disabled by --disable-threads threadsdir="threads" if test "$enable_threads" = "no"; then - threadsdir="#threads" + threadsdir="" fi # # Only run the checkpointing tests if enabled @@ -658,6 +658,9 @@ PAC_CHECK_HEADER_LIB_OPTIONAL([cuda],[cuda_runtime_api.h],[cudart],[cudaStreamSy cuda_CPPFLAGS="" cuda_LDFLAGS="" cuda_LIBS="" +cudadir= +AC_SUBST(cudadir) +AC_ARG_VAR([NVCC], [nvcc compiler to use]) if test "X${pac_have_cuda}" = "Xyes" ; then AC_DEFINE([HAVE_CUDA],[1],[Define if CUDA is available]) have_gpu="yes" @@ -668,8 +671,13 @@ if test "X${pac_have_cuda}" = "Xyes" ; then else cuda_LDFLAGS="-L${with_cuda}/lib" fi + AC_PATH_PROG([NVCC], [nvcc], [nvcc_not_found], [$with_cuda/bin:$PATH]) + else + AC_PATH_PROG([NVCC], [nvcc], [nvcc_not_found]) fi cuda_LIBS="-lcudart" + + cudadir="cuda" fi AM_CONDITIONAL([HAVE_CUDA],[test "X${pac_have_cuda}" = "Xyes"]) AC_SUBST([cuda_CPPFLAGS]) @@ -1661,6 +1669,7 @@ AC_OUTPUT(maint/testmerge \ impls/mpich/comm/testlist \ impls/mpich/threads/Makefile \ impls/mpich/threads/pt2pt/Makefile \ + impls/mpich/cuda/Makefile \ impls/mpich/misc/Makefile \ ) diff --git a/test/mpi/impls/mpich/Makefile.am b/test/mpi/impls/mpich/Makefile.am index 8d393a364fd..1f04f19665d 100644 --- a/test/mpi/impls/mpich/Makefile.am +++ b/test/mpi/impls/mpich/Makefile.am @@ -8,10 +8,4 @@ include $(top_srcdir)/Makefile_single.mtest EXTRA_DIST = testlist.in static_subdirs = mpi_t comm misc -# For future tests - note that the IO and RMA directories are optional, -# and need to be handled as shown in this comment -#SUBDIRS = $(static_subdirs) $(iodir) $(rmadir) -SUBDIRS = $(static_subdirs) $(threadsdir) -# For future tests, as noted above -#DIST_SUBDIRS = $(static_subdirs) io rma -DIST_SUBDIRS = $(static_subdirs) +SUBDIRS = $(static_subdirs) $(threadsdir) $(cudadir) diff --git a/test/mpi/impls/mpich/cuda/Makefile.am b/test/mpi/impls/mpich/cuda/Makefile.am new file mode 100644 index 00000000000..59b18b8778e --- /dev/null +++ b/test/mpi/impls/mpich/cuda/Makefile.am @@ -0,0 +1,11 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +include $(top_srcdir)/Makefile_cuda.mtest + +LDADD += -lm + +noinst_PROGRAMS = \ + saxpy diff --git a/test/mpi/impls/mpich/cuda/saxpy.cu b/test/mpi/impls/mpich/cuda/saxpy.cu new file mode 100644 index 00000000000..dba7ccd840f --- /dev/null +++ b/test/mpi/impls/mpich/cuda/saxpy.cu @@ -0,0 +1,106 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include +#include +#include + +const int N = 1000000; +const int a = 2.0; + +static void init_x(float *x) +{ + for (int i = 0; i < N; i++) { + x[i] = 1.0f; + } +} + +static void init_y(float *y) +{ + for (int i = 0; i < N; i++) { + y[i] = 2.0f; + } +} + +static int check_result(float *y) +{ + float maxError = 0.0f; + int errs = 0; + for (int i = 0; i < N; i++) { + if (abs(y[i] - 4.0f) > 0.01) { + errs++; + maxError = max(maxError, abs(y[i]-4.0f)); + } + } + if (errs > 0) { + printf("%d errors, Max error: %f\n", errs, maxError); + } + return errs; +} + +__global__ +void saxpy(int n, float a, float *x, float *y) +{ + int i = blockIdx.x*blockDim.x + threadIdx.x; + if (i < n) y[i] = a*x[i] + y[i]; +} + +int main(void) +{ + int errs = 0; + + int mpi_errno; + int rank, size; + MPI_Init(NULL, NULL); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + if (size < 2) { + printf("This test require 2 processes\n"); + } + + float *x, *y, *d_x, *d_y; + x = (float*)malloc(N*sizeof(float)); + y = (float*)malloc(N*sizeof(float)); + + cudaMalloc(&d_x, N*sizeof(float)); + cudaMalloc(&d_y, N*sizeof(float)); + + if (rank == 0) { + init_x(x); + } else if (rank == 1) { + init_y(y); + } + + // P0 send x to P1, P1 run saxpy and check + + if (rank == 0) { + cudaMemcpy(d_x, x, N*sizeof(float), cudaMemcpyHostToDevice); + mpi_errno = MPI_Send(d_x, N, MPI_FLOAT, 1, 0, MPI_COMM_WORLD); + assert(mpi_errno == MPI_SUCCESS); + } else if (rank == 1) { + cudaMemcpy(d_y, y, N*sizeof(float), cudaMemcpyHostToDevice); + mpi_errno = MPI_Recv(d_x, N, MPI_FLOAT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + assert(mpi_errno == MPI_SUCCESS); + + saxpy<<<(N+255)/256, 256, 0>>>(N, a, d_x, d_y); + + cudaMemcpy(y, d_y, N*sizeof(float), cudaMemcpyDeviceToHost); + } + + if (rank == 1) { + errs = check_result(y); + if (errs == 0) { + printf("No Errors\n"); + } + } + + cudaFree(d_x); + cudaFree(d_y); + free(x); + free(y); + + MPI_Finalize(); +} diff --git a/test/mpi/impls/mpich/cuda/testlist b/test/mpi/impls/mpich/cuda/testlist new file mode 100644 index 00000000000..68bfd0db9cc --- /dev/null +++ b/test/mpi/impls/mpich/cuda/testlist @@ -0,0 +1 @@ +saxpy 2 diff --git a/test/mpi/impls/mpich/testlist.in b/test/mpi/impls/mpich/testlist.in index 62a569ca772..38011146bf9 100644 --- a/test/mpi/impls/mpich/testlist.in +++ b/test/mpi/impls/mpich/testlist.in @@ -2,6 +2,7 @@ mpi_t comm misc @threadsdir@ +@cudadir@ # The IO and RMA directories are optional and need to be handled in # a special way. Uncomment these as appropriate when a test is added. #@iodir@ From fe41e25f62621d45b83398ccdabc9ce84a824f6e Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 27 Mar 2022 13:39:58 -0500 Subject: [PATCH 557/607] env: install mpicxx even when cxx is disabled It is common to use MPI in C++ projects without using the cxx binding. Install the mpicxx wrapper script as long as CXX is found. --- configure.ac | 9 +++++++++ src/env/Makefile.mk | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 46c9cf89870..4382cb8dfe6 100644 --- a/configure.ac +++ b/configure.ac @@ -2428,12 +2428,21 @@ if test "$enable_cxx" = "yes" ; then # so that it may be used in #if statements without adding to # the CPP name space AC_SUBST(FORTRAN_BINDING) +fi +# we install mpicxx as long as CXX is defined. In the case of enable_cxx=no, +# it is essentially the same as mpicc with CXX compiler. +if test -n "$CXX" ; then # determine shared library flags for CXX cxx_shlib_conf=src/env/cxx_shlib.conf PAC_COMPILER_SHLIB_FLAGS([CXX],[$cxx_shlib_conf]) AC_SUBST_FILE([cxx_shlib_conf]) + + if test "$enable_cxx" != yes; then + MPICXXLIBNAME="$MPILIBNAME" + fi fi +AM_CONDITIONAL([INSTALL_MPICXX],[test -n "$CXX"]) if test "$enable_cxx" = yes; then # Check if $MPI_DEFAULT_CXXOPTS is valid with $CXX diff --git a/src/env/Makefile.mk b/src/env/Makefile.mk index b448fbf883a..4233cb50fce 100644 --- a/src/env/Makefile.mk +++ b/src/env/Makefile.mk @@ -23,9 +23,9 @@ if BUILD_FC_BINDING bin_SCRIPTS += src/env/mpifort endif BUILD_FC_BINDING -if BUILD_CXX_BINDING +if INSTALL_MPICXX bin_SCRIPTS += src/env/mpicxx -endif BUILD_CXX_BINDING +endif INSTALL_MPICXX # create a local copy of the compiler wrapper that will actually be installed if BUILD_BASH_SCRIPTS From 139840014abbc847914462e00b267f8362fa9a3c Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sun, 27 Mar 2022 20:44:56 -0500 Subject: [PATCH 558/607] test: set MPIR_CVAR_ENABLE_GPU for cuda tests --- test/mpi/runtests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/mpi/runtests b/test/mpi/runtests index 1c36d49d4b5..4f1d8e912e6 100755 --- a/test/mpi/runtests +++ b/test/mpi/runtests @@ -449,7 +449,7 @@ sub LoadTests { my $test_opt = {args=>[], envs=>[], mpiexecargs=>[]}; if ($g_opt{has_gpu_test}) { - if ($_f ne "testlist.gpu") { + if ($_f ne "testlist.gpu" and $curdir !~ /\bcuda$/) { push @{$test_opt->{envs}}, "MPIR_CVAR_ENABLE_GPU=0"; } else { push @{$test_opt->{envs}}, "MPIR_CVAR_ENABLE_GPU=1"; From 252c48f8ead43c44bd4443bf461a659a04fbbacc Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 29 Mar 2022 08:49:55 -0500 Subject: [PATCH 559/607] pmi: add option --with-pmilib=install Add configure option to install libpmi.so. This will allow direct use and testing of PMI APIs. --- configure.ac | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index 4382cb8dfe6..a5be7fbfa82 100644 --- a/configure.ac +++ b/configure.ac @@ -1677,19 +1677,22 @@ AC_SUBST([pmisrcdir]) pmilib="" AC_SUBST([pmilib]) -if test "$with_pmilib" = "mpich" ; then - pmisrcdir="src/pmi" - pmilib="src/pmi/libpmi.la" - PAC_CONFIG_SUBDIR_ARGS([src/pmi], [--enable-embedded]) - PAC_APPEND_FLAG([-I${use_top_srcdir}/src/pmi/include], [CPPFLAGS]) - PAC_APPEND_FLAG([-I${main_top_builddir}/src/pmi/include], [CPPFLAGS]) -fi - case "$with_pmilib" in - mpich) + mpich|install) if test "$with_pmi" != "pmi1" -a "$with_pmi" != "pmi2" ; then AC_MSG_ERROR([pmilib=%with_pmilib is incompatible with $with_pmi]); fi + pmisrcdir="src/pmi" + pmilib="src/pmi/libpmi.la" + + pmi_subdir_args="" + if test "$with_pmilib" != "install" ; then + pmi_subdir_args="--enable-embedded" + fi + PAC_CONFIG_SUBDIR_ARGS([src/pmi], [$pmi_subdir_args]) + + PAC_APPEND_FLAG([-I${use_top_srcdir}/src/pmi/include], [CPPFLAGS]) + PAC_APPEND_FLAG([-I${main_top_builddir}/src/pmi/include], [CPPFLAGS]) ;; slurm) PAC_SET_HEADER_LIB_PATH([slurm]) From bfde250318608385f790517327367bd2ade8aac9 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 29 Mar 2022 09:30:59 -0500 Subject: [PATCH 560/607] config: fix mpl config in pmi We can't always skip linking libmpl.la when we are install pmi separately. Use shell variable $pac_skip_mpl_lib instead of m4 macro PAC_SKIP_MPL_LIB. Just use PAC_CONFIG_MPL, which should take care of all paths. --- confdb/aclocal_modules.m4 | 4 ++-- src/mpi/romio/configure.ac | 6 +++--- src/pmi/configure.ac | 14 +++++--------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/confdb/aclocal_modules.m4 b/confdb/aclocal_modules.m4 index 2189ab90b0a..7c2fb3d5121 100644 --- a/confdb/aclocal_modules.m4 +++ b/confdb/aclocal_modules.m4 @@ -24,9 +24,9 @@ AC_DEFUN([PAC_CONFIG_MPL],[ dnl ---- sub-configure (e.g. hydra, romio) ---- if test "$FROM_MPICH" = "yes"; then dnl skip ROMIO since mpich already links libmpl.la - m4_ifndef([PAC_SKIP_MPL_LIB], [ + if test "$pac_skip_mpl_lib" != "yes" ; then mpl_lib="$main_top_builddir/src/mpl/libmpl.la" - ]) + fi mpl_includedir="-I$main_top_builddir/src/mpl/include -I$main_top_srcdir/src/mpl/include" # source variables that are configured by MPL AC_MSG_NOTICE([sourcing $main_top_srcdir/src/mpl/localdefs]) diff --git a/src/mpi/romio/configure.ac b/src/mpi/romio/configure.ac index 142f7bc2f0e..2825691cb50 100644 --- a/src/mpi/romio/configure.ac +++ b/src/mpi/romio/configure.ac @@ -149,9 +149,9 @@ if test "$FROM_MPICH" = "no" ; then mpl_lib="-l${MPLLIBNAME}" fi else - # we are configuring romio inside mpich. MPICH should configured MPL already, following - # macro will just set mpl_includedir and source mpl/localdefs if any. - m4_define([PAC_SKIP_MPL_LIB], [yes]) + # we are configuring romio inside mpich. MPICH should configured MPL already, + # just set mpl_includedir and source mpl/localdefs if any. + pac_skip_mpl_lib=yes PAC_CONFIG_MPL fi diff --git a/src/pmi/configure.ac b/src/pmi/configure.ac index a2d980fad16..c8dee6b13c9 100644 --- a/src/pmi/configure.ac +++ b/src/pmi/configure.ac @@ -35,6 +35,8 @@ AC_ARG_ENABLE([embedded], AM_CONDITIONAL([EMBEDDED_MODE], [test "$enable_embedded" = "yes"]) # MPL +m4_define([mpl_embedded_dir],[mpl]) + mpl_srcdir= AC_SUBST([mpl_srcdir]) mpl_includedir= @@ -42,16 +44,10 @@ AC_SUBST([mpl_includedir]) mpl_lib= AC_SUBST([mpl_lib]) -if test "$FROM_MPICH" = "yes" ; then - m4_define([PAC_SKIP_MPL_LIB], [yes]) - PAC_CONFIG_MPL -else - mpl_srcdir="mpl" - mpl_subdir_args="--disable-versioning --enable-embedded" - PAC_CONFIG_SUBDIR_ARGS([mpl],[$mpl_subdir_args],[],[AC_MSG_ERROR(MPL configure failed)]) - mpl_includedir='-I$(top_builddir)/mpl/include -I$(top_srcdir)/mpl/include' - mpl_lib="mpl/libmpl.la" +if test "$enable_embedded" = "yes" ; then + pac_skip_mpl_lib=yes fi +PAC_CONFIG_MPL # check "mpi.h" for MPI_MAX_PORT_NAME if test "$FROM_MPICH" = "yes" ; then From 3b863099000cb7bbe185c0c3e1094c679a9ad410 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 29 Mar 2022 11:21:37 -0500 Subject: [PATCH 561/607] pmi: add visibility flag We need prevent symbols leak into libmpi.so and libpmi.so. --- src/pmi/configure.ac | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/pmi/configure.ac b/src/pmi/configure.ac index c8dee6b13c9..f8b915ea0e4 100644 --- a/src/pmi/configure.ac +++ b/src/pmi/configure.ac @@ -34,6 +34,23 @@ AC_ARG_ENABLE([embedded], [enable_embedded=no]) AM_CONDITIONAL([EMBEDDED_MODE], [test "$enable_embedded" = "yes"]) +if test "$enable_embedded" = "yes" ; then + AC_DEFINE([EMBEDDED_MODE], 1, [define if build in embedded mode]) +fi + +PAC_CHECK_VISIBILITY +if test -n "$VISIBILITY_CFLAGS" ; then + CFLAGS="$CFLAGS $VISIBILITY_CFLAGS" +fi + +AH_BOTTOM([ +#if defined(HAVE_VISIBILITY) && !defined(EMBEDDED_MODE) +#define PMI_API_PUBLIC __attribute__((visibility ("default"))) +#else +#define PMI_API_PUBLIC +#endif +]) + # MPL m4_define([mpl_embedded_dir],[mpl]) From 104cf394ade71f2f2ae5a68e3ff8fb7ee354d4c7 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 29 Mar 2022 12:06:16 -0500 Subject: [PATCH 562/607] pmi: add PMI_API_PUBLIC attribute When building libpmi.so separately, we need expose the PMI API functions. --- src/pmi/pmi2/simple/simple2pmi.c | 72 ++++++++++++++++++-------------- src/pmi/simple/simple_pmi.c | 55 ++++++++++++------------ 2 files changed, 68 insertions(+), 59 deletions(-) diff --git a/src/pmi/pmi2/simple/simple2pmi.c b/src/pmi/pmi2/simple/simple2pmi.c index 5073fbb96eb..6134a01625a 100644 --- a/src/pmi/pmi2/simple/simple2pmi.c +++ b/src/pmi/pmi2/simple/simple2pmi.c @@ -180,14 +180,14 @@ static inline int SEARCH_REMOVE(PMI2_Command * cmd) /* ------------------------------------------------------------------------- */ /* PMI API Routines */ /* ------------------------------------------------------------------------- */ -int PMI2_Set_threaded(int is_threaded) +PMI_API_PUBLIC int PMI2_Set_threaded(int is_threaded) { PMI2_is_threaded = is_threaded; return PMI2_SUCCESS; } -int PMI2_Init(int *spawned, int *size, int *rank, int *appnum) +PMI_API_PUBLIC int PMI2_Init(int *spawned, int *size, int *rank, int *appnum) { int pmi2_errno = PMI2_SUCCESS; char *p; @@ -355,7 +355,7 @@ int PMI2_Init(int *spawned, int *size, int *rank, int *appnum) goto fn_exit; } -int PMI2_Finalize(void) +PMI_API_PUBLIC int PMI2_Finalize(void) { int pmi2_errno = PMI2_SUCCESS; int rc; @@ -385,7 +385,7 @@ int PMI2_Finalize(void) goto fn_exit; } -int PMI2_Initialized(void) +PMI_API_PUBLIC int PMI2_Initialized(void) { /* Turn this into a logical value (1 or 0) . This allows us * to use PMI2_initialized to distinguish between initialized with @@ -394,7 +394,7 @@ int PMI2_Initialized(void) return PMI2_initialized != 0; } -int PMI2_Abort(int flag, const char msg[]) +PMI_API_PUBLIC int PMI2_Abort(int flag, const char msg[]) { PMI2U_printf(1, "aborting job:\n%s\n", msg); @@ -406,14 +406,15 @@ int PMI2_Abort(int flag, const char msg[]) return PMI2_SUCCESS; } -int PMI2_Job_Spawn(int count, const char *cmds[], - int argcs[], const char **argvs[], - const int maxprocs[], - const int info_keyval_sizes[], - const PMI2_keyval_t * info_keyval_vectors[], - int preput_keyval_size, - const PMI2_keyval_t preput_keyval_vector[], - char jobId[], int jobIdSize, int errors[]) +PMI_API_PUBLIC + int PMI2_Job_Spawn(int count, const char *cmds[], + int argcs[], const char **argvs[], + const int maxprocs[], + const int info_keyval_sizes[], + const PMI2_keyval_t * info_keyval_vectors[], + int preput_keyval_size, + const PMI2_keyval_t preput_keyval_vector[], + char jobId[], int jobIdSize, int errors[]) { int i, rc, spawncnt, total_num_processes, num_errcodes_found; int found; @@ -557,7 +558,7 @@ cmd=spawn;thrid=string;ncmds=count;preputcount=n;ppkey0=name;ppval0=string;...;\ return pmi2_errno; } -int PMI2_Job_GetId(char jobid[], int jobid_size) +PMI_API_PUBLIC int PMI2_Job_GetId(char jobid[], int jobid_size) { int pmi2_errno = PMI2_SUCCESS; int found; @@ -590,7 +591,7 @@ int PMI2_Job_GetId(char jobid[], int jobid_size) goto fn_exit; } -int PMI2_Job_Connect(const char jobid[], PMI2_Connect_comm_t * conn) +PMI_API_PUBLIC int PMI2_Job_Connect(const char jobid[], PMI2_Connect_comm_t * conn) { int pmi2_errno = PMI2_SUCCESS; PMI2_Command cmd = { 0 }; @@ -623,7 +624,7 @@ int PMI2_Job_Connect(const char jobid[], PMI2_Connect_comm_t * conn) goto fn_exit; } -int PMI2_Job_Disconnect(const char jobid[]) +PMI_API_PUBLIC int PMI2_Job_Disconnect(const char jobid[]) { int pmi2_errno = PMI2_SUCCESS; PMI2_Command cmd = { 0 }; @@ -648,7 +649,7 @@ int PMI2_Job_Disconnect(const char jobid[]) goto fn_exit; } -int PMI2_KVS_Put(const char key[], const char value[]) +PMI_API_PUBLIC int PMI2_KVS_Put(const char key[], const char value[]) { int pmi2_errno = PMI2_SUCCESS; PMI2_Command cmd = { 0 }; @@ -673,7 +674,7 @@ int PMI2_KVS_Put(const char key[], const char value[]) goto fn_exit; } -int PMI2_KVS_Fence(void) +PMI_API_PUBLIC int PMI2_KVS_Fence(void) { int pmi2_errno = PMI2_SUCCESS; PMI2_Command cmd = { 0 }; @@ -697,8 +698,9 @@ int PMI2_KVS_Fence(void) goto fn_exit; } -int PMI2_KVS_Get(const char *jobid, int src_pmi_id, const char key[], char value[], int maxValue, - int *valLen) +PMI_API_PUBLIC + int PMI2_KVS_Get(const char *jobid, int src_pmi_id, const char key[], char value[], + int maxValue, int *valLen) { int pmi2_errno = PMI2_SUCCESS; int found, keyfound; @@ -747,7 +749,8 @@ int PMI2_KVS_Get(const char *jobid, int src_pmi_id, const char key[], char value goto fn_exit; } -int PMI2_Info_GetNodeAttr(const char name[], char value[], int valuelen, int *flag, int waitfor) +PMI_API_PUBLIC + int PMI2_Info_GetNodeAttr(const char name[], char value[], int valuelen, int *flag, int waitfor) { int pmi2_errno = PMI2_SUCCESS; int found; @@ -789,8 +792,9 @@ int PMI2_Info_GetNodeAttr(const char name[], char value[], int valuelen, int *fl goto fn_exit; } -int PMI2_Info_GetNodeAttrIntArray(const char name[], int array[], int arraylen, int *outlen, - int *flag) +PMI_API_PUBLIC + int PMI2_Info_GetNodeAttrIntArray(const char name[], int array[], int arraylen, int *outlen, + int *flag) { int pmi2_errno = PMI2_SUCCESS; int found; @@ -848,7 +852,7 @@ int PMI2_Info_GetNodeAttrIntArray(const char name[], int array[], int arraylen, goto fn_exit; } -int PMI2_Info_PutNodeAttr(const char name[], const char value[]) +PMI_API_PUBLIC int PMI2_Info_PutNodeAttr(const char name[], const char value[]) { int pmi2_errno = PMI2_SUCCESS; PMI2_Command cmd = { 0 }; @@ -874,7 +878,7 @@ int PMI2_Info_PutNodeAttr(const char name[], const char value[]) goto fn_exit; } -int PMI2_Info_GetJobAttr(const char name[], char value[], int valuelen, int *flag) +PMI_API_PUBLIC int PMI2_Info_GetJobAttr(const char name[], char value[], int valuelen, int *flag) { int pmi2_errno = PMI2_SUCCESS; int found; @@ -915,8 +919,9 @@ int PMI2_Info_GetJobAttr(const char name[], char value[], int valuelen, int *fla goto fn_exit; } -int PMI2_Info_GetJobAttrIntArray(const char name[], int array[], int arraylen, int *outlen, - int *flag) +PMI_API_PUBLIC + int PMI2_Info_GetJobAttrIntArray(const char name[], int array[], int arraylen, int *outlen, + int *flag) { int pmi2_errno = PMI2_SUCCESS; int found; @@ -972,8 +977,9 @@ int PMI2_Info_GetJobAttrIntArray(const char name[], int array[], int arraylen, i goto fn_exit; } -int PMI2_Nameserv_publish(const char service_name[], const PMI2_keyval_t * info_ptr, - const char port[]) +PMI_API_PUBLIC + int PMI2_Nameserv_publish(const char service_name[], const PMI2_keyval_t * info_ptr, + const char port[]) { int pmi2_errno = PMI2_SUCCESS; PMI2_Command cmd = { 0 }; @@ -1002,8 +1008,9 @@ int PMI2_Nameserv_publish(const char service_name[], const PMI2_keyval_t * info_ } -int PMI2_Nameserv_lookup(const char service_name[], const PMI2_keyval_t * info_ptr, - char port[], int portLen) +PMI_API_PUBLIC + int PMI2_Nameserv_lookup(const char service_name[], const PMI2_keyval_t * info_ptr, + char port[], int portLen) { int pmi2_errno = PMI2_SUCCESS; int found; @@ -1037,7 +1044,8 @@ int PMI2_Nameserv_lookup(const char service_name[], const PMI2_keyval_t * info_p goto fn_exit; } -int PMI2_Nameserv_unpublish(const char service_name[], const PMI2_keyval_t * info_ptr) +PMI_API_PUBLIC + int PMI2_Nameserv_unpublish(const char service_name[], const PMI2_keyval_t * info_ptr) { int pmi2_errno = PMI2_SUCCESS; int rc; diff --git a/src/pmi/simple/simple_pmi.c b/src/pmi/simple/simple_pmi.c index 4ae44cb9711..387654425d7 100644 --- a/src/pmi/simple/simple_pmi.c +++ b/src/pmi/simple/simple_pmi.c @@ -110,7 +110,7 @@ static char singinit_kvsname[256]; /******************************** Group functions *************************/ -int PMI_Init(int *spawned) +PMI_API_PUBLIC int PMI_Init(int *spawned) { char *p; int notset = 1; @@ -228,7 +228,7 @@ int PMI_Init(int *spawned) return PMI_SUCCESS; } -int PMI_Initialized(int *initialized) +PMI_API_PUBLIC int PMI_Initialized(int *initialized) { /* Turn this into a logical value (1 or 0) . This allows us * to use PMI_initialized to distinguish between initialized with @@ -238,7 +238,7 @@ int PMI_Initialized(int *initialized) return PMI_SUCCESS; } -int PMI_Get_size(int *size) +PMI_API_PUBLIC int PMI_Get_size(int *size) { if (PMI_initialized) *size = PMI_size; @@ -247,7 +247,7 @@ int PMI_Get_size(int *size) return PMI_SUCCESS; } -int PMI_Get_rank(int *rank) +PMI_API_PUBLIC int PMI_Get_rank(int *rank) { if (PMI_initialized) *rank = PMI_rank; @@ -262,7 +262,7 @@ int PMI_Get_rank(int *rank) * we first need to connect to the process manager and acquire the * needed information. */ -int PMI_Get_universe_size(int *size) +PMI_API_PUBLIC int PMI_Get_universe_size(int *size) { int err; char size_c[PMIU_MAXLINE]; @@ -284,7 +284,7 @@ int PMI_Get_universe_size(int *size) return PMI_SUCCESS; } -int PMI_Get_appnum(int *appnum) +PMI_API_PUBLIC int PMI_Get_appnum(int *appnum) { int err; char appnum_c[PMIU_MAXLINE]; @@ -304,7 +304,7 @@ int PMI_Get_appnum(int *appnum) return PMI_SUCCESS; } -int PMI_Barrier(void) +PMI_API_PUBLIC int PMI_Barrier(void) { int err = PMI_SUCCESS; @@ -316,7 +316,7 @@ int PMI_Barrier(void) } /* Inform the process manager that we're in finalize */ -int PMI_Finalize(void) +PMI_API_PUBLIC int PMI_Finalize(void) { int err = PMI_SUCCESS; @@ -329,7 +329,7 @@ int PMI_Finalize(void) return err; } -int PMI_Abort(int exit_code, const char error_msg[]) +PMI_API_PUBLIC int PMI_Abort(int exit_code, const char error_msg[]) { char buf[PMIU_MAXLINE]; @@ -349,7 +349,7 @@ int PMI_Abort(int exit_code, const char error_msg[]) truncated because it is larger than length */ /* FIXME: My name should be cached rather than re-acquired, as it is unchanging (after singleton init) */ -int PMI_KVS_Get_my_name(char kvsname[], int length) +PMI_API_PUBLIC int PMI_KVS_Get_my_name(char kvsname[], int length) { int err; @@ -367,7 +367,7 @@ int PMI_KVS_Get_my_name(char kvsname[], int length) return err; } -int PMI_KVS_Get_name_length_max(int *maxlen) +PMI_API_PUBLIC int PMI_KVS_Get_name_length_max(int *maxlen) { if (maxlen == NULL) return PMI_ERR_INVALID_ARG; @@ -375,7 +375,7 @@ int PMI_KVS_Get_name_length_max(int *maxlen) return PMI_SUCCESS; } -int PMI_KVS_Get_key_length_max(int *maxlen) +PMI_API_PUBLIC int PMI_KVS_Get_key_length_max(int *maxlen) { if (maxlen == NULL) return PMI_ERR_INVALID_ARG; @@ -383,7 +383,7 @@ int PMI_KVS_Get_key_length_max(int *maxlen) return PMI_SUCCESS; } -int PMI_KVS_Get_value_length_max(int *maxlen) +PMI_API_PUBLIC int PMI_KVS_Get_value_length_max(int *maxlen) { if (maxlen == NULL) return PMI_ERR_INVALID_ARG; @@ -391,7 +391,7 @@ int PMI_KVS_Get_value_length_max(int *maxlen) return PMI_SUCCESS; } -int PMI_KVS_Put(const char kvsname[], const char key[], const char value[]) +PMI_API_PUBLIC int PMI_KVS_Put(const char kvsname[], const char key[], const char value[]) { char buf[PMIU_MAXLINE]; int err = PMI_SUCCESS; @@ -419,7 +419,7 @@ int PMI_KVS_Put(const char kvsname[], const char key[], const char value[]) return err; } -int PMI_KVS_Commit(const char kvsname[]ATTRIBUTE((unused))) +PMI_API_PUBLIC int PMI_KVS_Commit(const char kvsname[]ATTRIBUTE((unused))) { /* no-op in this implementation */ return PMI_SUCCESS; @@ -427,7 +427,7 @@ int PMI_KVS_Commit(const char kvsname[]ATTRIBUTE((unused))) /*FIXME: need to return an error if the value returned is truncated because it is larger than length */ -int PMI_KVS_Get(const char kvsname[], const char key[], char value[], int length) +PMI_API_PUBLIC int PMI_KVS_Get(const char kvsname[], const char key[], char value[], int length) { char buf[PMIU_MAXLINE]; int err = PMI_SUCCESS; @@ -461,7 +461,7 @@ int PMI_KVS_Get(const char kvsname[], const char key[], char value[], int length /*************************** Name Publishing functions **********************/ -int PMI_Publish_name(const char service_name[], const char port[]) +PMI_API_PUBLIC int PMI_Publish_name(const char service_name[], const char port[]) { char buf[PMIU_MAXLINE], cmd[PMIU_MAXLINE]; int err; @@ -487,7 +487,7 @@ int PMI_Publish_name(const char service_name[], const char port[]) return PMI_SUCCESS; } -int PMI_Unpublish_name(const char service_name[]) +PMI_API_PUBLIC int PMI_Unpublish_name(const char service_name[]) { char buf[PMIU_MAXLINE], cmd[PMIU_MAXLINE]; int err = PMI_SUCCESS; @@ -512,7 +512,7 @@ int PMI_Unpublish_name(const char service_name[]) return PMI_SUCCESS; } -int PMI_Lookup_name(const char service_name[], char port[]) +PMI_API_PUBLIC int PMI_Lookup_name(const char service_name[], char port[]) { char buf[PMIU_MAXLINE], cmd[PMIU_MAXLINE]; int err; @@ -541,14 +541,15 @@ int PMI_Lookup_name(const char service_name[], char port[]) /************************** Process Creation functions **********************/ -int PMI_Spawn_multiple(int count, - const char *cmds[], - const char **argvs[], - const int maxprocs[], - const int info_keyval_sizes[], - const PMI_keyval_t * info_keyval_vectors[], - int preput_keyval_size, - const PMI_keyval_t preput_keyval_vector[], int errors[]) +PMI_API_PUBLIC + int PMI_Spawn_multiple(int count, + const char *cmds[], + const char **argvs[], + const int maxprocs[], + const int info_keyval_sizes[], + const PMI_keyval_t * info_keyval_vectors[], + int preput_keyval_size, + const PMI_keyval_t preput_keyval_vector[], int errors[]) { int i, rc, argcnt, spawncnt, total_num_processes, num_errcodes_found; char buf[PMIU_MAXLINE], tempbuf[PMIU_MAXLINE], cmd[PMIU_MAXLINE]; From 85b4d5228c63721eb559db37692b24a56e233299 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 29 Mar 2022 14:20:59 -0500 Subject: [PATCH 563/607] test: add pmi tests Run pmi tests when we have libpmi.so installed. --- test/mpi/configure.ac | 23 ++++++++- test/mpi/impls/Makefile.am | 2 +- test/mpi/impls/pmi/Makefile.am | 14 ++++++ test/mpi/impls/pmi/test_pmi1.c | 88 ++++++++++++++++++++++++++++++++++ test/mpi/impls/pmi/test_pmi2.c | 79 ++++++++++++++++++++++++++++++ test/mpi/impls/pmi/testlist | 2 + test/mpi/impls/testlist.in | 1 + 7 files changed, 207 insertions(+), 2 deletions(-) create mode 100644 test/mpi/impls/pmi/Makefile.am create mode 100644 test/mpi/impls/pmi/test_pmi1.c create mode 100644 test/mpi/impls/pmi/test_pmi2.c create mode 100644 test/mpi/impls/pmi/testlist diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index e397fcace6a..00fe982b108 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -1418,7 +1418,7 @@ if test "$enable_romio" != no -a "$mpi_io_works" = yes ; then fi AC_SUBST(iodir) -impldir="#" +impldir="" # # Check for implementation to enable implementation-specific options if test $enable_strictmpi != "yes" ; then @@ -1427,6 +1427,26 @@ if test $enable_strictmpi != "yes" ; then fi fi AC_SUBST(impldir) + +pmidir="" +PAC_PUSH_FLAG([LIBS]) +LIBS="$LIBS -lpmi" +AC_MSG_CHECKING([that we have pmi library]) +AC_LINK_IFELSE([ + AC_LANG_PROGRAM([#include "pmi.h"], [ + int has_parent; + PMI_Init(&has_parent); + PMI_Finalize(); + ]) +],[ + AC_MSG_RESULT(yes) + pmidir=pmi +],[ + AC_MSG_RESULT(no) +]) +PAC_POP_FLAG([LIBS]) +AC_SUBST(pmidir) + # # MPI_INTEGER16 is mentioned in only one place in MPI 2.1, and some # implementations may have missed it. Check to see if it is available in @@ -1662,6 +1682,7 @@ AC_OUTPUT(maint/testmerge \ impls/Makefile \ impls/hydra/Makefile \ impls/hydra/proc_binding.sh \ + impls/pmi/Makefile \ impls/mpich/Makefile \ impls/mpich/testlist \ impls/mpich/mpi_t/Makefile \ diff --git a/test/mpi/impls/Makefile.am b/test/mpi/impls/Makefile.am index 3a10c4a3f83..bb4e4dcc864 100644 --- a/test/mpi/impls/Makefile.am +++ b/test/mpi/impls/Makefile.am @@ -8,5 +8,5 @@ include $(top_srcdir)/Makefile_single.mtest EXTRA_DIST = testlist.in static_subdirs = -SUBDIRS = $(static_subdirs) $(impldir) +SUBDIRS = $(static_subdirs) $(impldir) $(pmidir) DIST_SUBDIRS = $(static_subdirs) mpich hydra diff --git a/test/mpi/impls/pmi/Makefile.am b/test/mpi/impls/pmi/Makefile.am new file mode 100644 index 00000000000..0037d964efe --- /dev/null +++ b/test/mpi/impls/pmi/Makefile.am @@ -0,0 +1,14 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +LDADD = -lpmi + +testing: + $(top_srcdir)/runtests -srcdir=$(srcdir) -tests=$(TESTLIST) -testdirs=$(TESTDIRS) \ + -mpiexec="${MPIEXEC}" $(RUNTESTS_OPTS) -xmlfile=$(SUMMARY_BASENAME).xml + +noinst_PROGRAMS = \ + test_pmi1 \ + test_pmi2 diff --git a/test/mpi/impls/pmi/test_pmi1.c b/test/mpi/impls/pmi/test_pmi1.c new file mode 100644 index 00000000000..052b8da3ac6 --- /dev/null +++ b/test/mpi/impls/pmi/test_pmi1.c @@ -0,0 +1,88 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include +#include +#include +#include "pmi.h" + +#define KEY_NAME "key0" +#define KEY_VALUE "got-key0" + +#define EXPECT_INT(var, expect) \ + do { \ + if (var != expect) { \ + printf("Expect " #var " = %d, got %d\n", expect, var); \ + return 1; \ + } \ + } while (0) + +#define EXPECT_STR(var, expect) \ + do { \ + if (strcmp(var, expect) != 0) { \ + printf("Expect " #var " = %s, got %s\n", expect, var); \ + return 1; \ + } \ + } while (0) + +#define CHECK_PMI_ERRNO(name) \ + do { \ + if (pmi_errno != PMI_SUCCESS) { \ + printf("%s returned error: %d\n", name, pmi_errno); \ + return 1; \ + } \ + } while (0) + +int main(int argc, char **argv) +{ + int pmi_errno; + char kvsname[1024]; + int has_parent, rank, size; + + pmi_errno = PMI_Init(&has_parent); + CHECK_PMI_ERRNO("PMI_Init"); + + pmi_errno = PMI_Get_rank(&rank); + CHECK_PMI_ERRNO("PMI_Get_rank"); + + pmi_errno = PMI_Get_size(&size); + CHECK_PMI_ERRNO("PMI_Get_size"); + + if (size < 2) { + printf("This test requires 2 processes\n"); + return 1; + } + + EXPECT_INT(has_parent, 0); + + pmi_errno = PMI_KVS_Get_my_name(kvsname, 1024); + CHECK_PMI_ERRNO("PMI_KVS_Get_my_name"); + + if (rank == 0) { + /* NOTE: PMI-v1 does not allow space in both key and value */ + pmi_errno = PMI_KVS_Put(kvsname, KEY_NAME, KEY_VALUE); + } + + pmi_errno = PMI_Barrier(); + CHECK_PMI_ERRNO("PMI_Barrier"); + + if (rank == 1) { + char buf[100]; + + pmi_errno = PMI_KVS_Get(kvsname, KEY_NAME, buf, 100); + CHECK_PMI_ERRNO("PMI_KVS_Get"); + + EXPECT_STR(buf, KEY_VALUE); + } + + pmi_errno = PMI_Finalize(); + CHECK_PMI_ERRNO("PMI_Finalize"); + + if (rank == 0) { + printf("No Errors\n"); + } + + return 0; +} diff --git a/test/mpi/impls/pmi/test_pmi2.c b/test/mpi/impls/pmi/test_pmi2.c new file mode 100644 index 00000000000..7f39dcf19b1 --- /dev/null +++ b/test/mpi/impls/pmi/test_pmi2.c @@ -0,0 +1,79 @@ +#include +#include +#include +#include "pmi2.h" + +#define KEY_NAME "key0" +#define KEY_VALUE "got key0" + +#define EXPECT_INT(var, expect) \ + do { \ + if (var != expect) { \ + printf("Expect " #var " = %d, got %d\n", expect, var); \ + return 1; \ + } \ + } while (0) + +#define EXPECT_STR(var, expect) \ + do { \ + if (strcmp(var, expect) != 0) { \ + printf("Expect " #var " = %s, got %s\n", expect, var); \ + return 1; \ + } \ + } while (0) + +#define CHECK_PMI_ERRNO(name) \ + do { \ + if (pmi_errno != PMI2_SUCCESS) { \ + printf("%s returned error: %d\n", name, pmi_errno); \ + return 1; \ + } \ + } while (0) + +int main(int argc, char **argv) +{ + int pmi_errno; + char jobid[1024]; + int has_parent, rank, size, appnum; + + pmi_errno = PMI2_Init(&has_parent, &size, &rank, &appnum); + CHECK_PMI_ERRNO("PMI2_Init"); + + if (size < 2) { + printf("This test requires 2 processes\n"); + return 1; + } + + EXPECT_INT(has_parent, 0); + EXPECT_INT(appnum, 0); + + pmi_errno = PMI2_Job_GetId(jobid, 1024); + CHECK_PMI_ERRNO("PMI2_Job_GetId"); + + if (rank == 0) { + pmi_errno = PMI2_KVS_Put(KEY_NAME, KEY_VALUE); + CHECK_PMI_ERRNO("PMI2_KVS_Put"); + } + + pmi_errno = PMI2_KVS_Fence(); + CHECK_PMI_ERRNO("PMI2_KVS_Fence"); + + if (rank == 1) { + char buf[100]; + int out_len; + + pmi_errno = PMI2_KVS_Get(jobid, 0, KEY_NAME, buf, 100, &out_len); + CHECK_PMI_ERRNO("PMI2_KVS_Get"); + + EXPECT_STR(buf, KEY_VALUE); + } + + pmi_errno = PMI2_Finalize(); + CHECK_PMI_ERRNO("PMI2_Finalize"); + + if (rank == 0) { + printf("No Errors\n"); + } + + return 0; +} diff --git a/test/mpi/impls/pmi/testlist b/test/mpi/impls/pmi/testlist new file mode 100644 index 00000000000..6b829cecee6 --- /dev/null +++ b/test/mpi/impls/pmi/testlist @@ -0,0 +1,2 @@ +test_pmi1 2 +test_pmi2 2 diff --git a/test/mpi/impls/testlist.in b/test/mpi/impls/testlist.in index 9bac5303cf6..68d1d416bfb 100644 --- a/test/mpi/impls/testlist.in +++ b/test/mpi/impls/testlist.in @@ -1 +1,2 @@ @impldir@ +@pmidir@ From cde3b13dda9140de572585b7318e8883fa0020c6 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 29 Mar 2022 21:51:29 -0500 Subject: [PATCH 564/607] build: require Perl We use Perl in MPL's configure command -- confdb/cmd_prefix_config_h.pl. --- README.vin | 4 ++++ configure.ac | 12 +++++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/README.vin b/README.vin index 32460a1c950..9b8fccc26ae 100644 --- a/README.vin +++ b/README.vin @@ -44,6 +44,8 @@ shared memory), Hydra process management) of MPICH up and running. - REQUIRED: This tar file mpich-%VERSION%.tar.gz + - REQUIRED: Perl + - REQUIRED: A C compiler (C99 support is required. See https://wiki.mpich.org/mpich/index.php/Shifting_toward_C99) @@ -59,6 +61,8 @@ shared memory), Hydra process management) of MPICH up and running. --disable-fortran (configuring MPICH is described in step 1(d) below). + - OPTIONAL: Python 3. Python 3 is needed to generate Fortran bindings. + Also, you need to know what shell you are using since different shell has different command syntax. Command "echo $SHELL" prints out the current shell used by your terminal program. diff --git a/configure.ac b/configure.ac index a5be7fbfa82..7f221cde9bb 100644 --- a/configure.ac +++ b/configure.ac @@ -2473,13 +2473,11 @@ AC_LANG([C]) # subsystems to build # ---------------------------------------------------------------------------- -# Look for perl. Perl is used *only* in the tests of the commands such as -# mpiexec, mpicc, etc, in test/commands, and in some of the utility -# programs for processing log files . If perl is not found, -# MPICH may still be built and used. -# We need the full path to perl since we'll use it as the interpreter for -# a shell script. -AC_PATH_PROG(PERL,perl) +# Look for perl. Perl is needed in configure MPL (confdb/cmd_prefix_config_h.pl). +AC_PATH_PROG(PERL,perl,[no]) +if test "$PERL" = "no" ; then + AC_MSG_ERROR([Perl is required but not found.]) +fi # Check for the killall program; this can be used in some of the tests # in test/commands From dd5a9c36fa0d2df5f66d75e4a8f72fa9c312ec16 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Fri, 18 Mar 2022 09:18:49 -0500 Subject: [PATCH 565/607] modules: update yaksa pmodels/yaksa#213: backend/ze: fix warnings about unused labels pmodels/yaksa#214: cuda: Delay stream creation pmodels/yaksa#215: cuda: Allow configure to continue after nvcc check pmodels/yaksa#216: cuda: delay query p2p accessibility pmodels/yaksa#217: backend: Use correct device for peer access check Fixes pmodels/mpich#5810 --- modules/yaksa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/yaksa b/modules/yaksa index 8f0f232b4f5..e4063c04b6c 160000 --- a/modules/yaksa +++ b/modules/yaksa @@ -1 +1 @@ -Subproject commit 8f0f232b4f57c087ab42ad6599df6a565422a3a0 +Subproject commit e4063c04b6ceeda7d863449a4e92124feb5b739a From 351104b4c83643af157b1757baa0b9f107a8fb5e Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 22 Mar 2022 14:33:15 -0500 Subject: [PATCH 566/607] mpl/cuda: Set device before querying address range With the change to lazily create GPU resources in Yaksa, cuMemGetAddressRange may return CUDA_ERROR_NOT_FOUND if the pointer being queried lives on a device different from the current one. --- src/mpl/src/gpu/mpl_gpu_cuda.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/mpl/src/gpu/mpl_gpu_cuda.c b/src/mpl/src/gpu/mpl_gpu_cuda.c index 0bc5da5e1a3..346de7e0dda 100644 --- a/src/mpl/src/gpu/mpl_gpu_cuda.c +++ b/src/mpl/src/gpu/mpl_gpu_cuda.c @@ -323,9 +323,24 @@ int MPL_gpu_get_buffer_bounds(const void *ptr, void **pbase, uintptr_t * len) int mpl_err = MPL_SUCCESS; CUresult curet; + /* get the device where the pointer is located */ + int device; + struct cudaPointerAttributes attr; + cudaPointerGetAttributes(&attr, ptr); + device = attr.device; + + /* set the device to query the address range, otherwise the driver + * might return CUDA_ERROR_NOT_FOUND */ + int device_save; + cudaGetDevice(&device_save); + cudaSetDevice(device); + curet = cuMemGetAddressRange((CUdeviceptr *) pbase, (size_t *) len, (CUdeviceptr) ptr); CU_ERR_CHECK(curet); + /* set device back to saved value */ + cudaSetDevice(device_save); + fn_exit: return mpl_err; fn_fail: From 0fca6b9f23d72e421e5f09291d7e2e7228af817e Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 29 Mar 2022 14:52:45 -0500 Subject: [PATCH 567/607] mpid/common/shm: Remove unnecessary declaration mkstemp is not used in this file. --- src/mpid/common/shm/mpidu_init_shm_alloc.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/mpid/common/shm/mpidu_init_shm_alloc.c b/src/mpid/common/shm/mpidu_init_shm_alloc.c index a2433a69972..f90e8fe92f0 100644 --- a/src/mpid/common/shm/mpidu_init_shm_alloc.c +++ b/src/mpid/common/shm/mpidu_init_shm_alloc.c @@ -19,10 +19,6 @@ #include #endif -#if defined(HAVE_MKSTEMP) && defined(NEEDS_MKSTEMP_DECL) -extern int mkstemp(char *t); -#endif - typedef struct memory_list { void *ptr; MPIDU_shm_seg_t *memory; From a734ac42fac09c349ecd8f6d8af3a08d2d6e490d Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 29 Mar 2022 14:49:25 -0500 Subject: [PATCH 568/607] mpl/dbg: Remove dead code The macros defines here are never set by configure, so this code is never compiled. --- src/mpl/src/dbg/mpl_dbg.c | 42 --------------------------------------- 1 file changed, 42 deletions(-) diff --git a/src/mpl/src/dbg/mpl_dbg.c b/src/mpl/src/dbg/mpl_dbg.c index bc047274d84..25ec247041c 100644 --- a/src/mpl/src/dbg/mpl_dbg.c +++ b/src/mpl/src/dbg/mpl_dbg.c @@ -615,48 +615,6 @@ static int dbg_open_tmpfile(FILE ** dbg_fp) goto fn_exit; } -#elif defined(MPL_HAVE__MKTEMP_S) && defined(MPL_HAVE_FOPEN_S) - -/* creates a temporary file in the same directory the user specified - * for the log file */ -static int dbg_open_tmpfile(FILE ** dbg_fp) -{ - int mpl_errno = MPL_SUCCESS; - const char temp_pattern[] = "templogXXXXXX"; - int fd; - char *basename; - int ret; - errno_t ret_errno; - - ret = MPL_strncpy(temp_filename, file_pattern, MAXPATHLEN); - if (ret) - goto fn_fail; - - find_basename(temp_filename, &basename); - - /* make sure there's enough room in temp_filename to store temp_pattern */ - if (basename - temp_filename > MAXPATHLEN - sizeof(temp_pattern)) - goto fn_fail; - - MPL_strncpy(basename, temp_pattern, sizeof(temp_pattern)); - - ret_errno = _mktemp_s(temp_filename, MAXPATHLEN); - if (ret_errno != 0) - goto fn_fail; - - ret_errno = fopen_s(dbg_fp, temp_filename, "a+"); - if (ret_errno != 0) - goto fn_fail; - - fn_exit: - return mpl_errno; - fn_fail: - MPL_error_printf("Could not open log file %s\n", temp_filename); - dbg_initialized = DBG_ERROR; - mpl_errno = MPL_ERR_DBG_INTERN; - goto fn_exit; -} - #else /* creates a temporary file in some directory, which may not be where From a6a6aca1e2f18c447d548f2cd3404bf7fcae70d3 Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 29 Mar 2022 14:04:22 -0500 Subject: [PATCH 569/607] mpl: Move mkstemp decl to header file This will allow use of mkstemp in all MPL sources files instead of a single place. --- src/mpl/include/mpl_misc.h | 4 ++++ src/mpl/src/dbg/mpl_dbg.c | 4 ---- src/mpl/src/shm/mpl_shm_mmap.c | 4 ---- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/mpl/include/mpl_misc.h b/src/mpl/include/mpl_misc.h index fa00e969a0b..748b3eb8232 100644 --- a/src/mpl/include/mpl_misc.h +++ b/src/mpl/include/mpl_misc.h @@ -13,4 +13,8 @@ /* Returns the number of processors currently available in the system */ int MPL_get_nprocs(void); +#if defined (MPL_HAVE_MKSTEMP) && defined (MPL_NEEDS_MKSTEMP_DECL) +int mkstemp(char *template); +#endif + #endif /* MPL_MISC_H_INCLUDED */ diff --git a/src/mpl/src/dbg/mpl_dbg.c b/src/mpl/src/dbg/mpl_dbg.c index 25ec247041c..fce6d6dfa96 100644 --- a/src/mpl/src/dbg/mpl_dbg.c +++ b/src/mpl/src/dbg/mpl_dbg.c @@ -18,10 +18,6 @@ #include #endif -#if defined(MPL_HAVE_MKSTEMP) && defined(MPL_NEEDS_MKSTEMP_DECL) -extern int mkstemp(char *t); -#endif - #if defined(MPL_HAVE_FDOPEN) && defined(MPL_NEEDS_FDOPEN_DECL) extern FILE *fdopen(int fd, const char *mode); #endif diff --git a/src/mpl/src/shm/mpl_shm_mmap.c b/src/mpl/src/shm/mpl_shm_mmap.c index bbc89191951..2cef0e98fa0 100644 --- a/src/mpl/src/shm/mpl_shm_mmap.c +++ b/src/mpl/src/shm/mpl_shm_mmap.c @@ -15,10 +15,6 @@ MPL_SUPPRESS_OSX_HAS_NO_SYMBOLS_WARNING; #include #endif -#if defined (MPL_HAVE_MKSTEMP) && defined (MPL_NEEDS_MKSTEMP_DECL) -extern int mkstemp(char *template); -#endif - inline int MPLI_shm_lhnd_close(MPL_shm_hnd_t hnd) { MPLI_shm_lhnd_t lhnd = MPLI_SHM_LHND_INVALID; From 64a995da57236ab808429856ea5b92421fa57caa Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 29 Mar 2022 14:50:39 -0500 Subject: [PATCH 570/607] mpl: Add MPL_mkstemp Add a portable version of mkstemp that can be used by various components in MPL and MPICH. --- src/mpl/configure.ac | 2 + src/mpl/include/mpl_misc.h | 6 +++ src/mpl/src/dbg/mpl_dbg.c | 4 +- src/mpl/src/misc/Makefile.mk | 3 +- src/mpl/src/misc/mpl_mkstemp.c | 67 ++++++++++++++++++++++++++++++++++ src/mpl/src/shm/mpl_shm_mmap.c | 4 +- 6 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 src/mpl/src/misc/mpl_mkstemp.c diff --git a/src/mpl/configure.ac b/src/mpl/configure.ac index d45b7b92af0..c1e10906d9e 100644 --- a/src/mpl/configure.ac +++ b/src/mpl/configure.ac @@ -1006,6 +1006,8 @@ fi AC_CHECK_FUNCS(mkstemp) if test "$ac_cv_func_mkstemp" = "yes" ; then PAC_FUNC_NEEDS_DECL([#include ],mkstemp) +else + AC_MSG_WARN([The mkstemp function is not provided in the standard library. Using a possibly insecure replacement function.]) fi # fdopen() converts from an fd to a FILE* AC_CHECK_FUNCS(fdopen) diff --git a/src/mpl/include/mpl_misc.h b/src/mpl/include/mpl_misc.h index 748b3eb8232..e3b96fe7604 100644 --- a/src/mpl/include/mpl_misc.h +++ b/src/mpl/include/mpl_misc.h @@ -17,4 +17,10 @@ int MPL_get_nprocs(void); int mkstemp(char *template); #endif +#if defined MPL_HAVE_MKSTEMP +#define MPL_mkstemp mkstemp +#else +int MPL_mkstemp(char *template); +#endif + #endif /* MPL_MISC_H_INCLUDED */ diff --git a/src/mpl/src/dbg/mpl_dbg.c b/src/mpl/src/dbg/mpl_dbg.c index fce6d6dfa96..faba7d31ca3 100644 --- a/src/mpl/src/dbg/mpl_dbg.c +++ b/src/mpl/src/dbg/mpl_dbg.c @@ -570,7 +570,7 @@ Environment variables\n\ return 0; } -#if defined (MPL_HAVE_MKSTEMP) && defined (MPL_HAVE_FDOPEN) +#ifdef MPL_HAVE_FDOPEN /* creates a temporary file in the same directory the user specified * for the log file */ @@ -594,7 +594,7 @@ static int dbg_open_tmpfile(FILE ** dbg_fp) MPL_strncpy(basename, temp_pattern, sizeof(temp_pattern)); - fd = mkstemp(temp_filename); + fd = MPL_mkstemp(temp_filename); if (fd == -1) goto fn_fail; diff --git a/src/mpl/src/misc/Makefile.mk b/src/mpl/src/misc/Makefile.mk index 37c83ad17d6..fed120d0658 100644 --- a/src/mpl/src/misc/Makefile.mk +++ b/src/mpl/src/misc/Makefile.mk @@ -4,4 +4,5 @@ # See COPYRIGHT in top-level directory. # -lib@MPLLIBNAME@_la_SOURCES += src/misc/mpl_misc.c +lib@MPLLIBNAME@_la_SOURCES += src/misc/mpl_misc.c \ + src/misc/mpl_mkstemp.c diff --git a/src/mpl/src/misc/mpl_mkstemp.c b/src/mpl/src/misc/mpl_mkstemp.c new file mode 100644 index 00000000000..143605c862e --- /dev/null +++ b/src/mpl/src/misc/mpl_mkstemp.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpl.h" + +#include +#include +#include +#include +#include + +/* here to prevent "has no symbols" warnings from ranlib on OS X */ +static int dummy ATTRIBUTE((unused)) MPL_USED = 0; + +#ifndef MPL_HAVE_MKSTEMP + +#define MAX_TRIES 100 /* max number of filenames we try before giving up */ +#define NUM_XS 6 /* number of X's in the template */ + +/* replaces NUM_XS characters in xs with random characters + xs must be at least NUM_XS chars long */ +static void randchar(char xs[]) +{ + char chararray[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"; + int i; + + for (i = 0; i < NUM_XS; ++i) + xs[i] = chararray[rand() % (sizeof(chararray) - 1)]; +} + + +int MPL_mkstemp(char *template) +{ + int fd; + unsigned int seed = (unsigned int) getpid(); /* can probably use something better */ + char *X; /* points to the XXXXXX substring in template */ + int i; + + srand(seed); + + /* find the end of the template string */ + X = template; + while (*X) + ++X; + + /* back up NUM_XS characters and check to make sure they're all 'X' */ + for (i = 0; i < NUM_XS; ++i) { + --X; + if (X < template || *X != 'X') { + errno = EINVAL; + return -1; + } + } + + for (i = 0; i < MAX_TRIES; ++i) { + randchar(X); + fd = open(template, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); + if (fd != -1) + return fd; + } + + errno = EEXIST; + return -1; +} +#endif diff --git a/src/mpl/src/shm/mpl_shm_mmap.c b/src/mpl/src/shm/mpl_shm_mmap.c index 2cef0e98fa0..51ab4a43856 100644 --- a/src/mpl/src/shm/mpl_shm_mmap.c +++ b/src/mpl/src/shm/mpl_shm_mmap.c @@ -70,10 +70,10 @@ static inline int MPL_shm_seg_create_attach_templ(MPL_shm_hnd_t hnd, intptr_t se char *chosen_fname = NULL; chosen_fname = dev_shm_fname; - lhnd = mkstemp(chosen_fname); + lhnd = MPL_mkstemp(chosen_fname); if (lhnd == -1) { chosen_fname = tmp_fname; - lhnd = mkstemp(chosen_fname); + lhnd = MPL_mkstemp(chosen_fname); if (lhnd == -1) { rc = MPL_ERR_SHM_INTERN; goto fn_fail; From 615055973f730cbdb786ec78615b0f7c7aa77ede Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 29 Mar 2022 14:56:32 -0500 Subject: [PATCH 571/607] ch3/nemesis: Remove unused Makefile --- src/mpid/ch3/channels/nemesis/utils/Makefile.mk | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 src/mpid/ch3/channels/nemesis/utils/Makefile.mk diff --git a/src/mpid/ch3/channels/nemesis/utils/Makefile.mk b/src/mpid/ch3/channels/nemesis/utils/Makefile.mk deleted file mode 100644 index 9deb08c361e..00000000000 --- a/src/mpid/ch3/channels/nemesis/utils/Makefile.mk +++ /dev/null @@ -1,7 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -include $(top_srcdir)/src/mpid/ch3/channels/nemesis/utils/monitor/Makefile.mk -include $(top_srcdir)/src/mpid/ch3/channels/nemesis/utils/replacements/Makefile.mk From 081f0e52c98b75860176127af5233df4bcabb06c Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 29 Mar 2022 14:57:47 -0500 Subject: [PATCH 572/607] ch3/nemesis: Remove mkstemp fallback implementation This is now provided by MPL. --- src/mpid/ch3/channels/nemesis/Makefile.mk | 1 - src/mpid/ch3/channels/nemesis/subconfigure.m4 | 5 -- .../nemesis/utils/replacements/Makefile.mk | 7 -- .../nemesis/utils/replacements/mkstemp.c | 81 ------------------- 4 files changed, 94 deletions(-) delete mode 100644 src/mpid/ch3/channels/nemesis/utils/replacements/Makefile.mk delete mode 100644 src/mpid/ch3/channels/nemesis/utils/replacements/mkstemp.c diff --git a/src/mpid/ch3/channels/nemesis/Makefile.mk b/src/mpid/ch3/channels/nemesis/Makefile.mk index b30e200bd97..ffdf0366e32 100644 --- a/src/mpid/ch3/channels/nemesis/Makefile.mk +++ b/src/mpid/ch3/channels/nemesis/Makefile.mk @@ -28,6 +28,5 @@ noinst_HEADERS += \ include $(top_srcdir)/src/mpid/ch3/channels/nemesis/src/Makefile.mk include $(top_srcdir)/src/mpid/ch3/channels/nemesis/netmod/Makefile.mk include $(top_srcdir)/src/mpid/ch3/channels/nemesis/utils/monitor/Makefile.mk -include $(top_srcdir)/src/mpid/ch3/channels/nemesis/utils/replacements/Makefile.mk endif BUILD_CH3_NEMESIS diff --git a/src/mpid/ch3/channels/nemesis/subconfigure.m4 b/src/mpid/ch3/channels/nemesis/subconfigure.m4 index f0c8c17594a..4615868b7a9 100644 --- a/src/mpid/ch3/channels/nemesis/subconfigure.m4 +++ b/src/mpid/ch3/channels/nemesis/subconfigure.m4 @@ -176,11 +176,6 @@ if test "${with_papi}" != "no" ; then # AC_CHECK_LIB(perfctr, perfctr_info, , [AC_MSG_ERROR(['perfctr library not found. Did you specify --with-papi=?'])]) fi -# handle missing mkstemp, or missing mkstemp declaration -AC_CHECK_FUNCS(mkstemp) -AC_CHECK_FUNCS(rand) -AC_CHECK_FUNCS(srand) - # Check for available shared memory functions #PAC_ARG_SHARED_MEMORY #if test "$with_shared_memory" != "mmap" -a "$with_shared_memory" != "sysv"; then diff --git a/src/mpid/ch3/channels/nemesis/utils/replacements/Makefile.mk b/src/mpid/ch3/channels/nemesis/utils/replacements/Makefile.mk deleted file mode 100644 index 144cb523c47..00000000000 --- a/src/mpid/ch3/channels/nemesis/utils/replacements/Makefile.mk +++ /dev/null @@ -1,7 +0,0 @@ -## -## Copyright (C) by Argonne National Laboratory -## See COPYRIGHT in top-level directory -## - -mpi_core_sources += \ - src/mpid/ch3/channels/nemesis/utils/replacements/mkstemp.c diff --git a/src/mpid/ch3/channels/nemesis/utils/replacements/mkstemp.c b/src/mpid/ch3/channels/nemesis/utils/replacements/mkstemp.c deleted file mode 100644 index 060476330d3..00000000000 --- a/src/mpid/ch3/channels/nemesis/utils/replacements/mkstemp.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) by Argonne National Laboratory - * See COPYRIGHT in top-level directory - */ - -/* for ATTRIBUTE */ -#include "mpichconf.h" -#include "mpl.h" - -#include -#include -#include -#include -#include - -/* here to prevent "has no symbols" warnings from ranlib on OS X */ -static int dummy ATTRIBUTE((unused)) MPL_USED = 0; - -#if !defined (HAVE_MKSTEMP) || !HAVE_MKSTEMP - -#warning The mkstemp function is not provided in the standard library. -#warning Using a possibly insecure replacement function. - -#if !defined (HAVE_RAND) || !HAVE_RAND -static notrand = 0; -#define srand(x) notrand = x -#define rand() (++notrand) -#endif - -#define MAX_TRIES 100 /* max number of filenames we try before giving up */ -#define NUM_XS 6 /* number of X's in the template */ - -/* replaces NUM_XS characters in xs with random characters - xs must be at least NUM_XS chars long */ -static void randchar (char xs[]) -{ - char chararray[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"; - int i; - - for (i = 0; i < NUM_XS; ++i) - xs[i] = chararray[rand() % (sizeof(chararray) - 1)]; -} - - -int mkstemp (char *template) -{ - int fd; - unsigned int seed = (unsigned int) getpid(); /* can probably use something better */ - char *X; /* points to the XXXXXX substring in template */ - int i; - - srand (seed); - - /* find the end of the template string */ - X = template; - while (*X) - ++X; - - /* back up NUM_XS characters and check to make sure they're all 'X' */ - for (i = 0 ; i < NUM_XS; ++i) - { - --X; - if (X < template || *X != 'X') - { - errno = EINVAL; - return -1; - } - } - - for (i = 0; i < MAX_TRIES; ++i) - { - randchar (X); - fd = open (template, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); - if (fd != -1) - return fd; - } - - errno = EEXIST; - return -1; -} -#endif From 7864e1d201d9dc05ecaf1f3378e7109b3363551f Mon Sep 17 00:00:00 2001 From: Ken Raffenetti Date: Tue, 29 Mar 2022 14:58:26 -0500 Subject: [PATCH 573/607] config: Remove leftover check for mkstemp Configure logic for mkstemp is now contained in MPL. --- configure.ac | 5 ----- 1 file changed, 5 deletions(-) diff --git a/configure.ac b/configure.ac index 7f221cde9bb..bd5810a1a7c 100644 --- a/configure.ac +++ b/configure.ac @@ -3804,11 +3804,6 @@ fi # ---------------------------------------------------------------------------- # Look for some non-posix, but commonly provided functions # ---------------------------------------------------------------------------- -# mkstemp() is a better replacement for mktemp() -AC_CHECK_FUNCS(mkstemp) -if test "$ac_cv_func_mkstemp" = "yes" ; then - PAC_FUNC_NEEDS_DECL([#include ],mkstemp) -fi # putenv() sets environment variable AC_CHECK_FUNCS(putenv) if test "$ac_cv_func_putenv" = "yes" ; then From 81a1db8703da1a9ec0e6b99104f19617489c765b Mon Sep 17 00:00:00 2001 From: Sagar Thapaliya Date: Thu, 24 Feb 2022 20:09:02 -0600 Subject: [PATCH 574/607] doc: Add a doc for tuning parameters This document will discuss various tuning parameters in MPICH. --- doc/mpich/TUNING_PARAMETERS | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 doc/mpich/TUNING_PARAMETERS diff --git a/doc/mpich/TUNING_PARAMETERS b/doc/mpich/TUNING_PARAMETERS new file mode 100644 index 00000000000..ac0e06385f8 --- /dev/null +++ b/doc/mpich/TUNING_PARAMETERS @@ -0,0 +1,14 @@ +This document discusses some of the new features added to the MPICH-based MPI +implementation for the Aurora computer and the environment variables (CVARs) +that the user can set to modify its behavior. MPICH is configured to use +sensible default values for all the environment variables to provide overall +good performance. However, users can change those defaults values to better tune +their applications. This report provides documentation on how those CVARS work +and the possible values that they can take. This documentation also provides +information about per-communicator info hints that MPICH utilizes to make +runtime decisions at a finer granularity. + +Notice that performance of the application depends on how ranks are mapped to +the cores of the processor. For information on how to specify process-core +binding with mpirun, information is provided here: +https://wiki.mpich.org/mpich/index.php/Using_the_Hydra_Process_Manager#Process-core_Binding. From 58f272bedaef9bf34a299eb592b46e70492870d0 Mon Sep 17 00:00:00 2001 From: Sagar Thapaliya Date: Thu, 24 Feb 2022 20:18:59 -0600 Subject: [PATCH 575/607] doc: add tuning parameters for MPI_THREAD_MULTIPLE These are the currently supported tuning parameters for MPI_THREAD_MULTIPLE. --- doc/mpich/TUNING_PARAMETERS | 100 ++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/doc/mpich/TUNING_PARAMETERS b/doc/mpich/TUNING_PARAMETERS index ac0e06385f8..75233bfb100 100644 --- a/doc/mpich/TUNING_PARAMETERS +++ b/doc/mpich/TUNING_PARAMETERS @@ -12,3 +12,103 @@ Notice that performance of the application depends on how ranks are mapped to the cores of the processor. For information on how to specify process-core binding with mpirun, information is provided here: https://wiki.mpich.org/mpich/index.php/Using_the_Hydra_Process_Manager#Process-core_Binding. + +This following section of this document provides information about threading +optimizations (Section 1). + +**1. Multi-threading** + +MPI provides four different threading modes: MPI_THREAD_SINGLE, +MPI_THREAD_FUNNELED, MPI_THREAD_SERIALIZED, and MPI_THREAD_MULTIPLE. +MPI_THREAD_MULTIPLE is the most advanced threading mode and the focus of this +Section. With this mode, an application runs with several threads, and any +thread can make calls to MPI at any time. Thus, the MPI library needs to protect +access to its internal data structures appropriately. It also tries to exploit +concurrency by taking advantage of the availability of multiple hardware +contexts in the network card, which we call VCIs (Virtual Communication +Interfaces). + +MPICH provides two threading synchronization strategies. One strategy is to use +a `global` coarse-grained lock to protect every MPI call that accesses shared +state inside the MPI runtime. With this model, if two threads call concurrently +the MPI runtime, the runtime will serialize the calls. Another strategy uses a +fine-grained lock to protect the access to each network context or VCI. With +this approach, threads trying to access the same VCI get serialized, but threads +accessing different VCIs can execute in parallel. With the fine-grained locking +model, MPICH supports a `direct` mode where the MPI runtime itself grabs a per +VCI lock and a `lockless` mode where MPI does not grab a lock and relies on the +network provider to provide fine grain synchronization (MPICH uses the +FI_THREAD_SAFE mode from OFI to support the `lockless` mode). + +A threading synchronization strategy can be selected at the configuration time +as: + --enable-thread-cs=global + to select coarse-grained locking, and + --enable-thread-cs=per-vci + to select fine-grained locking. + +Under fine-grained locking, a specific locking mode at configuration time as: + --enable-ch4-mt= + mode can be one of direct, lockless and runtime. + +If configuration is done with --enable-ch4-mt=runtime, user can select a +threading mode at runtime using the environment MPIR_CVAR_CH4_MT_MODEL +(described below in Section 1.1). + +**1.1 CVARs (Environment Variables)** + +MPICH users can use the CVAR MPIR_CVAR_CH4_MT_MODEL to select at runtime among +the threading synchronization models, `global`, `direct`, or `lockless`. If the +CVAR is not set, the default model is `direct`. + +e.g., export MPIR_CVAR_CH4_MT_MODEL=direct + +Users can specify the number of VCIs to use by setting the environment variable +`MPIR_CVAR_CH4_NUM_VCIS=`, where the value `` should be +less or equal than the number of network contexts provided by the OFI provider. +This number can be retrieved from the OFI provider. Running the `fi_info -v` +command should return the number of transmit contexts (max_ep_tx_ctx) and +receive contexts (max_ep_rx_ctx) it supports. MPICH uses the minimum of +max_ep_tx_ctx and max_ep_rx_ctx as the maximum number of VCIs it can support. If +the system has multiple NICS, this value is the `minimum across all the NICS`. + +e.g., export MPIR_CVAR_CH4_NUM_VCIS=16 + +When multiple VCIs are used, MPICH tries to make per-vci progress to avoid lock +contention inside the progress engine. However, it also progresses all VCIs, +i.e., make global progress, once in a while to avoid potential deadlocks. Such +global progress is turned on by default but can be turned off by setting +`MPIR_CVAR_CH4_GLOBAL_PROGRESS=0`, which can improve performance under the use +of multiple VCIs. However, caution should be taken as it can result in a deadlock. + +**1.2 Communicator Info Hints** + +When selecting the fine-grain modes (`direct` or `lockless`), messages sent +using different communicators can be sent/received using different VCIs. +However, messages using the same communicator may have to be sent/received +through the same VCI, to guarantee the ordering semantics imposed by the MPI +standard. However, messages sent through the same communicator can be +sent/received through different VCIs if the MPI runtime knows that wildcards +will not be used on that communicator. Thus, MPICH implements the MPI 4.0 +per-communicator info hints and recommend users to use them to indicate the +MPI runtime when wildcards are not used, specially when using `direct` or +`lockless` threading modes with multiple VCIs if the threads use the same +communicator. +Here are the standard hints from the MPI 4.0 standard that are supported +(we recommend using both info hints if the application is not using wildcards): + +* `mpi_assert_no_any_source`: Set this info hint if the application does + not use the wildcard MPI_ANY_SOURCE on the given communicator. +* `mpi_assert_no_any_tag`: Set this hint if the application does not use + MPI_ANY_TAG on the given communciator. + +MPICH also supports a non-standard per-communicator info hint that provides the +user with more control of a communicator-VCI mapping: +* `vci`: Specific sender and receiver VCI can be selected for each communicator + using this hint. Applications can utilize this feature to control how + messages are spread across the VCIs. +For instance, programmers can write the applications so that pairs of threads +communicate by using different communicator, where each communicator can be +mapped to a different VCI through the `vci` info hint. Valid values for this +info hints are 0 to (total vcis - 1). This hint is also utilized by MPICH to +select a progress thread to process reduction collective operation. From 3d9ed35854ffca2397f391a0554d1f101a3050ea Mon Sep 17 00:00:00 2001 From: Sagar Thapaliya Date: Fri, 1 Apr 2022 16:38:14 -0700 Subject: [PATCH 576/607] doc: change format of the tuning paramerers file This is now formatted as MARKDOWN (.md) file. This patch also fixes some of the formatting issues that appeared during the format change. --- .../{TUNING_PARAMETERS => tuning_parameters.md} | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) rename doc/mpich/{TUNING_PARAMETERS => tuning_parameters.md} (94%) diff --git a/doc/mpich/TUNING_PARAMETERS b/doc/mpich/tuning_parameters.md similarity index 94% rename from doc/mpich/TUNING_PARAMETERS rename to doc/mpich/tuning_parameters.md index 75233bfb100..65835dd88a0 100644 --- a/doc/mpich/TUNING_PARAMETERS +++ b/doc/mpich/tuning_parameters.md @@ -1,3 +1,5 @@ +# MPICH Tuning Parameters + This document discusses some of the new features added to the MPICH-based MPI implementation for the Aurora computer and the environment variables (CVARs) that the user can set to modify its behavior. MPICH is configured to use @@ -16,16 +18,16 @@ https://wiki.mpich.org/mpich/index.php/Using_the_Hydra_Process_Manager#Process-c This following section of this document provides information about threading optimizations (Section 1). -**1. Multi-threading** +## 1. Multi-threading -MPI provides four different threading modes: MPI_THREAD_SINGLE, -MPI_THREAD_FUNNELED, MPI_THREAD_SERIALIZED, and MPI_THREAD_MULTIPLE. +MPI provides four different threading modes: `MPI_THREAD_SINGLE`, +`MPI_THREAD_FUNNELED`, `MPI_THREAD_SERIALIZED`, and `MPI_THREAD_MULTIPLE`. MPI_THREAD_MULTIPLE is the most advanced threading mode and the focus of this Section. With this mode, an application runs with several threads, and any thread can make calls to MPI at any time. Thus, the MPI library needs to protect access to its internal data structures appropriately. It also tries to exploit concurrency by taking advantage of the availability of multiple hardware -contexts in the network card, which we call VCIs (Virtual Communication +contexts in the network card, which we call `VCIs` (Virtual Communication Interfaces). MPICH provides two threading synchronization strategies. One strategy is to use @@ -55,7 +57,7 @@ If configuration is done with --enable-ch4-mt=runtime, user can select a threading mode at runtime using the environment MPIR_CVAR_CH4_MT_MODEL (described below in Section 1.1). -**1.1 CVARs (Environment Variables)** +### 1.1 CVARs (Environment Variables) MPICH users can use the CVAR MPIR_CVAR_CH4_MT_MODEL to select at runtime among the threading synchronization models, `global`, `direct`, or `lockless`. If the @@ -81,7 +83,7 @@ global progress is turned on by default but can be turned off by setting `MPIR_CVAR_CH4_GLOBAL_PROGRESS=0`, which can improve performance under the use of multiple VCIs. However, caution should be taken as it can result in a deadlock. -**1.2 Communicator Info Hints** +### 1.2 Communicator Info Hints When selecting the fine-grain modes (`direct` or `lockless`), messages sent using different communicators can be sent/received using different VCIs. From d2e80c0639e283c4f74b1c46e706f4a3d8d71ccf Mon Sep 17 00:00:00 2001 From: wkliao Date: Sat, 2 Apr 2022 16:48:36 -0500 Subject: [PATCH 577/607] Add include path that contains mpi.h Otherwise, make failed with error message below. ../../../mpich/src/pmi/simple/simple_pmi.c:54:10: fatal error: mpi.h: No such file or directory #include "mpi.h" /* to get MPI_MAX_PORT_NAME */ ^~~~~~~ compilation terminated. --- src/pmi/configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pmi/configure.ac b/src/pmi/configure.ac index f8b915ea0e4..24605dc70da 100644 --- a/src/pmi/configure.ac +++ b/src/pmi/configure.ac @@ -69,6 +69,7 @@ PAC_CONFIG_MPL # check "mpi.h" for MPI_MAX_PORT_NAME if test "$FROM_MPICH" = "yes" ; then PAC_APPEND_FLAG([-I${main_top_srcdir}/src/include], [CPPFLAGS]) + PAC_APPEND_FLAG([-I${main_top_builddir}/src/include], [CPPFLAGS]) AC_DEFINE([HAVE_MPI_H], 1, [define if we have mpi.h]) else AC_CHECK_HEADER([mpi.h]) From abdfd354174b58dba2facfd0f0aee052ebc0f583 Mon Sep 17 00:00:00 2001 From: wkliao Date: Sat, 2 Apr 2022 15:11:29 -0500 Subject: [PATCH 578/607] configure ROMIO before checking MPI_OFFSET_TYPE Data type MPI_Offset is checked and set in ROMIO, but if ROMIO is configured after checking after MPI_OFFSET_TYPE is set, then MPI_Offset will be set to inconsistent data types, e.g. long in src/mpi.h v.s. long long in src/mpi/romio/include/mpio.h --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index bd5810a1a7c..ef876f8d38f 100644 --- a/configure.ac +++ b/configure.ac @@ -1423,7 +1423,6 @@ fi # This goes here because we need the top_srcdir if test "$enable_romio" = "yes" ; then if test -d $use_top_srcdir/src/mpi/romio ; then - subsystems="$subsystems src/mpi/romio" AC_DEFINE(HAVE_ROMIO,1,[Define if ROMIO is enabled]) # make it possible to "#include" mpio.h at build time @@ -1443,6 +1442,7 @@ if test "$enable_romio" = "yes" ; then if test ! -d lib ; then mkdir lib ; fi # tell mpi.h to include mpio.h PAC_HAVE_ROMIO + PAC_CONFIG_SUBDIR_ARGS([src/mpi/romio],[$subsys_config_args],[],[AC_MSG_ERROR([src/mpi/romio configure failed])]) else AC_MSG_WARN([ROMIO src directory is not available]) fi From 1a522802585250d8f2d2b81f294944381b50948b Mon Sep 17 00:00:00 2001 From: Wei-keng Liao Date: Sun, 3 Apr 2022 00:19:30 -0500 Subject: [PATCH 579/607] Update configure.ac Co-authored-by: Hui Zhou --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index ef876f8d38f..df9e2e5dd95 100644 --- a/configure.ac +++ b/configure.ac @@ -1442,7 +1442,7 @@ if test "$enable_romio" = "yes" ; then if test ! -d lib ; then mkdir lib ; fi # tell mpi.h to include mpio.h PAC_HAVE_ROMIO - PAC_CONFIG_SUBDIR_ARGS([src/mpi/romio],[$subsys_config_args],[],[AC_MSG_ERROR([src/mpi/romio configure failed])]) + PAC_CONFIG_SUBDIR_ARGS([src/mpi/romio],[],[],[AC_MSG_ERROR([src/mpi/romio configure failed])]) else AC_MSG_WARN([ROMIO src directory is not available]) fi From 78125a91be8a5ef425a76196ccf9de039534bebe Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 7 Mar 2022 16:36:44 -0600 Subject: [PATCH 580/607] pmi: move and rename source files Move both pmi1 and pmi2 source code into the src directory. --- src/pmi/Makefile.am | 8 +- .../simple/README => doc/pmi2_design.txt} | 0 src/pmi/pmi2/simple/simple2pmi.h | 122 ------------------ .../simple_pmiutil.c => src/pmi2_util.c} | 2 +- .../simple_pmiutil.h => src/pmi2_util.h} | 0 src/pmi/{pmi2/simple => src}/pmi2compat.h | 0 .../simple_pmiutil.c => src/pmi_util.c} | 2 +- .../simple_pmiutil.h => src/pmi_util.h} | 0 src/pmi/{simple/simple_pmi.c => src/pmi_v1.c} | 2 +- .../simple/simple2pmi.c => src/pmi_v2.c} | 93 ++++++++++++- 10 files changed, 98 insertions(+), 131 deletions(-) rename src/pmi/{pmi2/simple/README => doc/pmi2_design.txt} (100%) delete mode 100644 src/pmi/pmi2/simple/simple2pmi.h rename src/pmi/{pmi2/simple/simple_pmiutil.c => src/pmi2_util.c} (99%) rename src/pmi/{pmi2/simple/simple_pmiutil.h => src/pmi2_util.h} (100%) rename src/pmi/{pmi2/simple => src}/pmi2compat.h (100%) rename src/pmi/{simple/simple_pmiutil.c => src/pmi_util.c} (99%) rename src/pmi/{simple/simple_pmiutil.h => src/pmi_util.h} (100%) rename src/pmi/{simple/simple_pmi.c => src/pmi_v1.c} (99%) rename src/pmi/{pmi2/simple/simple2pmi.c => src/pmi_v2.c} (93%) diff --git a/src/pmi/Makefile.am b/src/pmi/Makefile.am index fb68089ad7b..a910cef1cd3 100644 --- a/src/pmi/Makefile.am +++ b/src/pmi/Makefile.am @@ -23,7 +23,7 @@ AM_CPPFLAGS += @mpl_includedir@ libpmi_la_LIBADD = @mpl_lib@ libpmi_la_SOURCES = \ - simple/simple_pmi.c \ - simple/simple_pmiutil.c \ - pmi2/simple/simple2pmi.c \ - pmi2/simple/simple_pmiutil.c + src/pmi_v1.c \ + src/pmi_v2.c \ + src/pmi_util.c \ + src/pmi2_util.c diff --git a/src/pmi/pmi2/simple/README b/src/pmi/doc/pmi2_design.txt similarity index 100% rename from src/pmi/pmi2/simple/README rename to src/pmi/doc/pmi2_design.txt diff --git a/src/pmi/pmi2/simple/simple2pmi.h b/src/pmi/pmi2/simple/simple2pmi.h deleted file mode 100644 index 9a6eb421a1a..00000000000 --- a/src/pmi/pmi2/simple/simple2pmi.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) by Argonne National Laboratory - * See COPYRIGHT in top-level directory - */ - -#ifndef SIMPLE2PMI_H_INCLUDED -#define SIMPLE2PMI_H_INCLUDED - -#include "pmi_config.h" - - -#define PMII_COMMANDLEN_SIZE 6 -#define PMII_MAX_COMMAND_LEN (64*1024) - -static const char FULLINIT_CMD[] = "fullinit"; -static const char FULLINITRESP_CMD[] = "fullinit-response"; -static const char FINALIZE_CMD[] = "finalize"; -static const char FINALIZERESP_CMD[] = "finalize-response"; -static const char ABORT_CMD[] = "abort"; -static const char JOBGETID_CMD[] = "job-getid"; -static const char JOBGETIDRESP_CMD[] = "job-getid-response"; -static const char JOBCONNECT_CMD[] = "job-connect"; -static const char JOBCONNECTRESP_CMD[] = "job-connect-response"; -static const char JOBDISCONNECT_CMD[] = "job-disconnect"; -static const char JOBDISCONNECTRESP_CMD[] = "job-disconnect-response"; -static const char KVSPUT_CMD[] = "kvs-put"; -static const char KVSPUTRESP_CMD[] = "kvs-put-response"; -static const char KVSFENCE_CMD[] = "kvs-fence"; -static const char KVSFENCERESP_CMD[] = "kvs-fence-response"; -static const char KVSGET_CMD[] = "kvs-get"; -static const char KVSGETRESP_CMD[] = "kvs-get-response"; -static const char GETNODEATTR_CMD[] = "info-getnodeattr"; -static const char GETNODEATTRRESP_CMD[] = "info-getnodeattr-response"; -static const char PUTNODEATTR_CMD[] = "info-putnodeattr"; -static const char PUTNODEATTRRESP_CMD[] = "info-putnodeattr-response"; -static const char GETJOBATTR_CMD[] = "info-getjobattr"; -static const char GETJOBATTRRESP_CMD[] = "info-getjobattr-response"; -static const char NAMEPUBLISH_CMD[] = "name-publish"; -static const char NAMEPUBLISHRESP_CMD[] = "name-publish-response"; -static const char NAMEUNPUBLISH_CMD[] = "name-unpublish"; -static const char NAMEUNPUBLISHRESP_CMD[] = "name-unpublish-response"; -static const char NAMELOOKUP_CMD[] = "name-lookup"; -static const char NAMELOOKUPRESP_CMD[] = "name-lookup-response"; - - -static const char PMIJOBID_KEY[] = "pmijobid"; -static const char PMIRANK_KEY[] = "pmirank"; -static const char SRCID_KEY[] = "srcid"; -static const char THREADED_KEY[] = "threaded"; -static const char RC_KEY[] = "rc"; -static const char ERRMSG_KEY[] = "errmsg"; -static const char PMIVERSION_KEY[] = "pmi-version"; -static const char PMISUBVER_KEY[] = "pmi-subversion"; -static const char RANK_KEY[] = "rank"; -static const char SIZE_KEY[] = "size"; -static const char APPNUM_KEY[] = "appnum"; -static const char SPAWNERJOBID_KEY[] = "spawner-jobid"; -static const char DEBUGGED_KEY[] = "debugged"; -static const char PMIVERBOSE_KEY[] = "pmiverbose"; -static const char ISWORLD_KEY[] = "isworld"; -static const char MSG_KEY[] = "msg"; -static const char JOBID_KEY[] = "jobid"; -static const char KVSCOPY_KEY[] = "kvscopy"; -static const char KEY_KEY[] = "key"; -static const char VALUE_KEY[] = "value"; -static const char FOUND_KEY[] = "found"; -static const char WAIT_KEY[] = "wait"; -static const char NAME_KEY[] = "name"; -static const char PORT_KEY[] = "port"; -static const char THRID_KEY[] = "thrid"; -static const char INFOKEYCOUNT_KEY[] = "infokeycount"; -static const char INFOKEY_KEY[] = "infokey%d"; -static const char INFOVAL_KEY[] = "infoval%d"; - -static const char TRUE_VAL[] = "TRUE"; -static const char FALSE_VAL[] = "FALSE"; - - -/* Local types */ - -/* Parse commands are in this structure. Fields in this structure are - dynamically allocated as necessary */ -typedef struct PMI2_Keyvalpair { - const char *key; - const char *value; - int valueLen; /* Length of a value (values may contain nulls, so - * we need this) */ - int isCopy; /* The value is a copy (and will need to be freed) - * if this is true, otherwise, - * it is a null-terminated string in the original - * buffer */ -} PMI2_Keyvalpair; - -typedef struct PMI2_Command { - int nPairs; /* Number of key=value pairs */ - char *command; /* Overall command buffer */ - PMI2_Keyvalpair **pairs; /* Array of pointers to pairs */ - int complete; -} PMI2_Command; - -/* Debug value */ -extern int MPIE_Debug; - -/* For mpiexec, we should normally enable debugging. Comment out this - definition of HAVE_DEBUGGING if you want to leave these out of the code */ -#define HAVE_DEBUGGING - -#ifdef HAVE_DEBUGGING -#define DBG_COND(cond,stmt) {if (cond) { stmt;}} -#else -#define DBG_COND(cond,a) -#endif -#define DBG(stmt) DBG_COND(MPIE_Debug,stmt) -#define DBG_PRINTFCOND(cond,a) DBG_COND(cond,printf a ; fflush(stdout)) -#define DBG_EPRINTFCOND(cond,a) DBG_COND(cond,fprintf a ; fflush(stderr)) -#define DBG_EPRINTF(a) DBG_EPRINTFCOND(MPIE_Debug,a) -#define DBG_PRINTF(a) DBG_PRINTFCOND(MPIE_Debug,a) - - - - -#endif /* SIMPLE2PMI_H_INCLUDED */ diff --git a/src/pmi/pmi2/simple/simple_pmiutil.c b/src/pmi/src/pmi2_util.c similarity index 99% rename from src/pmi/pmi2/simple/simple_pmiutil.c rename to src/pmi/src/pmi2_util.c index 61d463b99ca..74f724f8125 100644 --- a/src/pmi/pmi2/simple/simple_pmiutil.c +++ b/src/pmi/src/pmi2_util.c @@ -28,7 +28,7 @@ #include #include "pmi2.h" -#include "simple_pmiutil.h" +#include "pmi2_util.h" #define MAXVALLEN 1024 #define MAXKEYLEN 32 diff --git a/src/pmi/pmi2/simple/simple_pmiutil.h b/src/pmi/src/pmi2_util.h similarity index 100% rename from src/pmi/pmi2/simple/simple_pmiutil.h rename to src/pmi/src/pmi2_util.h diff --git a/src/pmi/pmi2/simple/pmi2compat.h b/src/pmi/src/pmi2compat.h similarity index 100% rename from src/pmi/pmi2/simple/pmi2compat.h rename to src/pmi/src/pmi2compat.h diff --git a/src/pmi/simple/simple_pmiutil.c b/src/pmi/src/pmi_util.c similarity index 99% rename from src/pmi/simple/simple_pmiutil.c rename to src/pmi/src/pmi_util.c index 9516f5b3f6d..baa4e44aaae 100644 --- a/src/pmi/simple/simple_pmiutil.c +++ b/src/pmi/src/pmi_util.c @@ -29,7 +29,7 @@ #include "mpl.h" #include "pmi.h" -#include "simple_pmiutil.h" +#include "pmi_util.h" #define MAXVALLEN 1024 #define MAXKEYLEN 32 diff --git a/src/pmi/simple/simple_pmiutil.h b/src/pmi/src/pmi_util.h similarity index 100% rename from src/pmi/simple/simple_pmiutil.h rename to src/pmi/src/pmi_util.h diff --git a/src/pmi/simple/simple_pmi.c b/src/pmi/src/pmi_v1.c similarity index 99% rename from src/pmi/simple/simple_pmi.c rename to src/pmi/src/pmi_v1.c index 387654425d7..fd0bd3d6c8f 100644 --- a/src/pmi/simple/simple_pmi.c +++ b/src/pmi/src/pmi_v1.c @@ -48,7 +48,7 @@ #define DBG_PRINTF(args) #include "pmi.h" -#include "simple_pmiutil.h" +#include "pmi_util.h" #ifdef HAVE_MPI_H #include "mpi.h" /* to get MPI_MAX_PORT_NAME */ diff --git a/src/pmi/pmi2/simple/simple2pmi.c b/src/pmi/src/pmi_v2.c similarity index 93% rename from src/pmi/pmi2/simple/simple2pmi.c rename to src/pmi/src/pmi_v2.c index 6134a01625a..bdd7e2139bc 100644 --- a/src/pmi/pmi2/simple/simple2pmi.c +++ b/src/pmi/src/pmi_v2.c @@ -6,8 +6,7 @@ #include "pmi_config.h" #include "pmi2compat.h" -#include "simple2pmi.h" -#include "simple_pmiutil.h" +#include "pmi2_util.h" #include "pmi2.h" #include "mpl.h" @@ -36,6 +35,96 @@ #define MAX_INT_STR_LEN 11 /* number of digits in MAX_UINT + 1 */ +#define PMII_COMMANDLEN_SIZE 6 +#define PMII_MAX_COMMAND_LEN (64*1024) + +static const char FULLINIT_CMD[] = "fullinit"; +static const char FULLINITRESP_CMD[] = "fullinit-response"; +static const char FINALIZE_CMD[] = "finalize"; +static const char FINALIZERESP_CMD[] = "finalize-response"; +static const char ABORT_CMD[] = "abort"; +static const char JOBGETID_CMD[] = "job-getid"; +static const char JOBGETIDRESP_CMD[] = "job-getid-response"; +static const char JOBCONNECT_CMD[] = "job-connect"; +static const char JOBCONNECTRESP_CMD[] = "job-connect-response"; +static const char JOBDISCONNECT_CMD[] = "job-disconnect"; +static const char JOBDISCONNECTRESP_CMD[] = "job-disconnect-response"; +static const char KVSPUT_CMD[] = "kvs-put"; +static const char KVSPUTRESP_CMD[] = "kvs-put-response"; +static const char KVSFENCE_CMD[] = "kvs-fence"; +static const char KVSFENCERESP_CMD[] = "kvs-fence-response"; +static const char KVSGET_CMD[] = "kvs-get"; +static const char KVSGETRESP_CMD[] = "kvs-get-response"; +static const char GETNODEATTR_CMD[] = "info-getnodeattr"; +static const char GETNODEATTRRESP_CMD[] = "info-getnodeattr-response"; +static const char PUTNODEATTR_CMD[] = "info-putnodeattr"; +static const char PUTNODEATTRRESP_CMD[] = "info-putnodeattr-response"; +static const char GETJOBATTR_CMD[] = "info-getjobattr"; +static const char GETJOBATTRRESP_CMD[] = "info-getjobattr-response"; +static const char NAMEPUBLISH_CMD[] = "name-publish"; +static const char NAMEPUBLISHRESP_CMD[] = "name-publish-response"; +static const char NAMEUNPUBLISH_CMD[] = "name-unpublish"; +static const char NAMEUNPUBLISHRESP_CMD[] = "name-unpublish-response"; +static const char NAMELOOKUP_CMD[] = "name-lookup"; +static const char NAMELOOKUPRESP_CMD[] = "name-lookup-response"; + + +static const char PMIJOBID_KEY[] = "pmijobid"; +static const char PMIRANK_KEY[] = "pmirank"; +static const char SRCID_KEY[] = "srcid"; +static const char THREADED_KEY[] = "threaded"; +static const char RC_KEY[] = "rc"; +static const char ERRMSG_KEY[] = "errmsg"; +static const char PMIVERSION_KEY[] = "pmi-version"; +static const char PMISUBVER_KEY[] = "pmi-subversion"; +static const char RANK_KEY[] = "rank"; +static const char SIZE_KEY[] = "size"; +static const char APPNUM_KEY[] = "appnum"; +static const char SPAWNERJOBID_KEY[] = "spawner-jobid"; +static const char DEBUGGED_KEY[] = "debugged"; +static const char PMIVERBOSE_KEY[] = "pmiverbose"; +static const char ISWORLD_KEY[] = "isworld"; +static const char MSG_KEY[] = "msg"; +static const char JOBID_KEY[] = "jobid"; +static const char KVSCOPY_KEY[] = "kvscopy"; +static const char KEY_KEY[] = "key"; +static const char VALUE_KEY[] = "value"; +static const char FOUND_KEY[] = "found"; +static const char WAIT_KEY[] = "wait"; +static const char NAME_KEY[] = "name"; +static const char PORT_KEY[] = "port"; +static const char THRID_KEY[] = "thrid"; +static const char INFOKEYCOUNT_KEY[] = "infokeycount"; +static const char INFOKEY_KEY[] = "infokey%d"; +static const char INFOVAL_KEY[] = "infoval%d"; + +static const char TRUE_VAL[] = "TRUE"; +static const char FALSE_VAL[] = "FALSE"; + + +/* Local types */ + +/* Parse commands are in this structure. Fields in this structure are + dynamically allocated as necessary */ +typedef struct PMI2_Keyvalpair { + const char *key; + const char *value; + int valueLen; /* Length of a value (values may contain nulls, so + * we need this) */ + int isCopy; /* The value is a copy (and will need to be freed) + * if this is true, otherwise, + * it is a null-terminated string in the original + * buffer */ +} PMI2_Keyvalpair; + +typedef struct PMI2_Command { + int nPairs; /* Number of key=value pairs */ + char *command; /* Overall command buffer */ + PMI2_Keyvalpair **pairs; /* Array of pointers to pairs */ + int complete; +} PMI2_Command; + + typedef enum { PMI2_UNINITIALIZED = 0, SINGLETON_INIT_BUT_NO_PM = 1, NORMAL_INIT_WITH_PM, From 27e1363b84b6d33f4fd91b31152ad30f583459c8 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 8 Mar 2022 12:06:53 -0600 Subject: [PATCH 581/607] pmi: remove pmi2_util.c There is no practical difference between pmi_util.c and pmi2_util.c other than the PMI2U namespace. Remove pmi2_util.c and just use pmi_util.c. --- src/pmi/Makefile.am | 3 +- src/pmi/src/pmi2_util.c | 292 ---------------------------------------- src/pmi/src/pmi2_util.h | 21 +-- src/pmi/src/pmi_v2.c | 63 ++++----- 4 files changed, 29 insertions(+), 350 deletions(-) delete mode 100644 src/pmi/src/pmi2_util.c diff --git a/src/pmi/Makefile.am b/src/pmi/Makefile.am index a910cef1cd3..d4cfd568993 100644 --- a/src/pmi/Makefile.am +++ b/src/pmi/Makefile.am @@ -25,5 +25,4 @@ libpmi_la_LIBADD = @mpl_lib@ libpmi_la_SOURCES = \ src/pmi_v1.c \ src/pmi_v2.c \ - src/pmi_util.c \ - src/pmi2_util.c + src/pmi_util.c diff --git a/src/pmi/src/pmi2_util.c b/src/pmi/src/pmi2_util.c deleted file mode 100644 index 74f724f8125..00000000000 --- a/src/pmi/src/pmi2_util.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (C) by Argonne National Laboratory - * See COPYRIGHT in top-level directory - */ - -/* Allow fprintf to logfile */ -/* style: allow:fprintf:1 sig:0 */ - -/* Utility functions associated with PMI implementation, but not part of - the PMI interface itself. Reading and writing on pipes, signals, and parsing - key=value messages -*/ -#include "pmi_config.h" -#include "pmi2compat.h" -#include "mpl.h" - -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#include -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#include - -#include "pmi2.h" -#include "pmi2_util.h" - -#define MAXVALLEN 1024 -#define MAXKEYLEN 32 - -/* These are not the keyvals in the keyval space that is part of the - PMI specification. - They are just part of this implementation's internal utilities. -*/ -struct PMI2U_keyval_pairs { - char key[MAXKEYLEN]; - char value[MAXVALLEN]; -}; -static struct PMI2U_keyval_pairs PMI2U_keyval_tab[64]; - -static int PMI2U_keyval_tab_idx = 0; - -/* This is used to prepend printed output. Set the initial value to - "unset" */ -static char PMI2U_print_id[PMI2U_IDSIZE] = "unset"; - -void PMI2U_Set_rank(int PMI_rank) -{ - MPL_snprintf(PMI2U_print_id, PMI2U_IDSIZE, "cli_%d", PMI_rank); -} - -void PMI2U_SetServer(void) -{ - MPL_strncpy(PMI2U_print_id, "server", PMI2U_IDSIZE); -} - -/* Note that vfprintf is part of C89 */ - -/* style: allow:fprintf:1 sig:0 */ -/* style: allow:vfprintf:1 sig:0 */ -/* This should be combined with the message routines */ -void PMI2U_printf(int print_flag, const char *fmt, ...) -{ - va_list ap; - static FILE *logfile = 0; - - /* In some cases when we are debugging, the handling of stdout or - * stderr may be unreliable. In that case, we make it possible to - * select an output file. */ - if (!logfile) { - char *p; - p = getenv("PMI_USE_LOGFILE"); - if (p) { - char filename[1024]; - p = getenv("PMI_ID"); - if (p) { - MPL_snprintf(filename, sizeof(filename), "testclient-%s.out", p); - logfile = fopen(filename, "w"); - } else { - logfile = fopen("testserver.out", "w"); - } - } else - logfile = stderr; - } - - if (print_flag) { - /* PMI2U_Error_printf("[%s]: ", PMI2U_print_id); */ - /* FIXME: Decide what role PMI2U_printf should have (if any) and - * select the appropriate PMI2U routine */ - fprintf(logfile, "[%s]: ", PMI2U_print_id); - va_start(ap, fmt); - vfprintf(logfile, fmt, ap); - va_end(ap); - fflush(logfile); - } -} - -#define MAX_READLINE 1024 -/* - * Return the next newline-terminated string of maximum length maxlen. - * This is a buffered version, and reads from fd as necessary. A - */ -int PMI2U_readline(int fd, char *buf, int maxlen) -{ - static char readbuf[MAX_READLINE]; - static char *nextChar = 0, *lastChar = 0; /* lastChar is really one past - * last char */ - static int lastfd = -1; - int curlen, n; - char *p, ch; - - /* Note: On the client side, only one thread at a time should - * be calling this, and there should only be a single fd. - * Server side code should not use this routine (see the - * replacement version in src/pm/util/pmiserv.c) */ - PMI2U_Assert(nextChar == lastChar || fd == lastfd); - - p = buf; - curlen = 1; /* Make room for the null */ - while (curlen < maxlen) { - if (nextChar == lastChar) { - lastfd = fd; - do { - n = read(fd, readbuf, sizeof(readbuf) - 1); - } while (n == -1 && errno == EINTR); - if (n == 0) { - /* EOF */ - break; - } else if (n < 0) { - /* Error. Return a negative value if there is no - * data. Save the errno in case we need to return it - * later. */ - if (curlen == 1) { - curlen = 0; - } - break; - } - nextChar = readbuf; - lastChar = readbuf + n; - /* Add a null at the end just to make it easier to print - * the read buffer */ - readbuf[n] = 0; - /* FIXME: Make this an optional output */ - /* printf("Readline %s\n", readbuf); */ - } - - ch = *nextChar++; - *p++ = ch; - curlen++; - if (ch == '\n') - break; - } - - /* We null terminate the string for convenience in printing */ - *p = 0; - - printf_d("PMI received: %s\n", buf); - - /* Return the number of characters, not counting the null */ - return curlen - 1; -} - -int PMI2U_writeline(int fd, char *buf) -{ - int size, n; - - size = strlen(buf); - /* - * if (size > PMI2U_MAXLINE) { - * buf[PMI2U_MAXLINE-1] = '\0'; - * PMI2U_printf(1, "write_line: message string too big: :%s:\n", buf); - * } - * else */ if (buf[strlen(buf) - 1] != '\n') - /* error: no newline at end */ - PMI2U_printf(1, "write_line: message string doesn't end in newline: :%s:\n", buf); - else { - printf_d("PMI sending: %s\n", buf); - - do { - n = write(fd, buf, size); - } while (n == -1 && errno == EINTR); - - if (n < 0) { - PMI2U_printf(1, "write_line error; fd=%d buf=:%s:\n", fd, buf); - perror("system msg for write_line failure "); - return PMI2_FAIL; - } - if (n < size) - PMI2U_printf(1, "write_line failed to write entire message\n"); - } - return PMI2_SUCCESS; -} - -/* - * Given an input string st, parse it into internal storage that can be - * queried by routines such as PMI2U_getval. - */ -int PMI2U_parse_keyvals(char *st) -{ - char *p, *keystart, *valstart; - int offset; - - if (!st) - return PMI2_FAIL; - - PMI2U_keyval_tab_idx = 0; - p = st; - while (1) { - while (*p == ' ') - p++; - /* got non-blank */ - if (*p == '=') { - PMI2U_printf(1, "PMI2U_parse_keyvals: unexpected = at character %d in %s\n", - p - st, st); - return PMI2_FAIL; - } - if (*p == '\n' || *p == '\0') - return PMI2_SUCCESS; /* normal exit */ - /* got normal character */ - keystart = p; /* remember where key started */ - while (*p != ' ' && *p != '=' && *p != '\n' && *p != '\0') - p++; - if (*p == ' ' || *p == '\n' || *p == '\0') { - PMI2U_printf(1, - "PMI2U_parse_keyvals: unexpected key delimiter at character %d in %s\n", - p - st, st); - return PMI2_FAIL; - } - /* Null terminate the key */ - *p = 0; - /* store key */ - MPL_strncpy(PMI2U_keyval_tab[PMI2U_keyval_tab_idx].key, keystart, MAXKEYLEN); - - valstart = ++p; /* start of value */ - while (*p != ' ' && *p != '\n' && *p != '\0') - p++; - /* store value */ - MPL_strncpy(PMI2U_keyval_tab[PMI2U_keyval_tab_idx].value, valstart, MAXVALLEN); - offset = p - valstart; - /* When compiled with -fPIC, the pgcc compiler generates incorrect - * code if "p - valstart" is used instead of using the - * intermediate offset */ - PMI2U_keyval_tab[PMI2U_keyval_tab_idx].value[offset] = '\0'; - PMI2U_keyval_tab_idx++; - if (*p == ' ') - continue; - if (*p == '\n' || *p == '\0') - return PMI2_FAIL; /* value has been set to empty */ - } -} - -void PMI2U_dump_keyvals(void) -{ - int i; - for (i = 0; i < PMI2U_keyval_tab_idx; i++) - PMI2U_printf(1, " %s=%s\n", PMI2U_keyval_tab[i].key, PMI2U_keyval_tab[i].value); -} - -char *PMI2U_getval(const char *keystr, char *valstr, int vallen) -{ - int i, rc; - - for (i = 0; i < PMI2U_keyval_tab_idx; i++) { - if (strcmp(keystr, PMI2U_keyval_tab[i].key) == 0) { - rc = MPL_strncpy(valstr, PMI2U_keyval_tab[i].value, vallen); - if (rc != 0) { - PMI2U_printf(1, "MPL_strncpy failed in PMI2U_getval\n"); - return NULL; - } - return valstr; - } - } - valstr[0] = '\0'; - return NULL; -} - -void PMI2U_chgval(const char *keystr, char *valstr) -{ - int i; - - for (i = 0; i < PMI2U_keyval_tab_idx; i++) { - if (strcmp(keystr, PMI2U_keyval_tab[i].key) == 0) { - MPL_strncpy(PMI2U_keyval_tab[i].value, valstr, MAXVALLEN - 1); - PMI2U_keyval_tab[i].value[MAXVALLEN - 1] = '\0'; - } - } -} diff --git a/src/pmi/src/pmi2_util.h b/src/pmi/src/pmi2_util.h index f89c44c020b..f12b4161010 100644 --- a/src/pmi/src/pmi2_util.h +++ b/src/pmi/src/pmi2_util.h @@ -3,23 +3,8 @@ * See COPYRIGHT in top-level directory */ -#ifndef SIMPLE_PMIUTIL_H_INCLUDED -#define SIMPLE_PMIUTIL_H_INCLUDED - -/* maximum sizes for arrays */ -#define PMI2U_MAXLINE 1024 -#define PMI2U_IDSIZE 32 - -/* prototypes for PMIU routines */ -void PMI2U_Set_rank(int PMI_rank); -void PMI2U_SetServer(void); -void PMI2U_printf(int print_flag, const char *fmt, ...); -int PMI2U_readline(int fd, char *buf, int max); -int PMI2U_writeline(int fd, char *buf); -int PMI2U_parse_keyvals(char *st); -void PMI2U_dump_keyvals(void); -char *PMI2U_getval(const char *keystr, char *valstr, int vallen); -void PMI2U_chgval(const char *keystr, char *valstr); +#ifndef PMI2_UTIL_H_INCLUDED +#define PMI2_UTIL_H_INCLUDED extern int PMI2_pmiverbose; /* Set this to true to print PMI debugging info */ #define printf_d(x...) do { if (PMI2_pmiverbose) printf(x); } while (0) @@ -141,4 +126,4 @@ extern int PMI2_pmiverbose; /* Set this to true to print PMI debugging info (ptr_) = realloc_tmp_; \ } while (0) -#endif /* SIMPLE_PMIUTIL_H_INCLUDED */ +#endif /* PMI2_UTIL_H_INCLUDED */ diff --git a/src/pmi/src/pmi_v2.c b/src/pmi/src/pmi_v2.c index bdd7e2139bc..f93885171f5 100644 --- a/src/pmi/src/pmi_v2.c +++ b/src/pmi/src/pmi_v2.c @@ -6,6 +6,7 @@ #include "pmi_config.h" #include "pmi2compat.h" +#include "pmi_util.h" #include "pmi2_util.h" #include "pmi2.h" #include "mpl.h" @@ -280,7 +281,7 @@ PMI_API_PUBLIC int PMI2_Init(int *spawned, int *size, int *rank, int *appnum) { int pmi2_errno = PMI2_SUCCESS; char *p; - char buf[PMI2U_MAXLINE], cmdline[PMI2U_MAXLINE]; + char buf[PMIU_MAXLINE], cmdline[PMIU_MAXLINE]; char *jobid; char *pmiid; int ret; @@ -295,7 +296,7 @@ PMI_API_PUBLIC int PMI2_Init(int *spawned, int *size, int *rank, int *appnum) * unbuffered (user explicitly set?) */ /* setvbuf(stdout,0,_IONBF,0); */ setbuf(stdout, NULL); - /* PMI2U_printf(1, "PMI2_INIT\n"); */ + /* PMIU_printf(1, "PMI2_INIT\n"); */ /* Get the value of PMI2_DEBUG from the environment if possible, since * we may have set it to help debug the setup process */ @@ -322,29 +323,29 @@ PMI_API_PUBLIC int PMI2_Init(int *spawned, int *size, int *rank, int *appnum) /* do initial PMI1 init */ ret = - MPL_snprintf(buf, PMI2U_MAXLINE, "cmd=init pmi_version=%d pmi_subversion=%d\n", PMI_VERSION, + MPL_snprintf(buf, PMIU_MAXLINE, "cmd=init pmi_version=%d pmi_subversion=%d\n", PMI_VERSION, PMI_SUBVERSION); PMI2U_ERR_CHKANDJUMP1(ret < 0, pmi2_errno, PMI2_ERR_OTHER, "**intern", "**intern %s", "failed to generate init line"); - ret = PMI2U_writeline(PMI2_fd, buf); + ret = PMIU_writeline(PMI2_fd, buf); PMI2U_ERR_CHKANDJUMP(ret < 0, pmi2_errno, PMI2_ERR_OTHER, "**pmi2_init_send"); - ret = PMI2U_readline(PMI2_fd, buf, PMI2U_MAXLINE); + ret = PMIU_readline(PMI2_fd, buf, PMIU_MAXLINE); PMI2U_ERR_CHKANDJUMP1(ret < 0, pmi2_errno, PMI2_ERR_OTHER, "**pmi2_initack", "**pmi2_initack %s", strerror(errno)); - PMI2U_parse_keyvals(buf); + PMIU_parse_keyvals(buf); cmdline[0] = 0; - PMI2U_getval("cmd", cmdline, PMI2U_MAXLINE); - PMI2U_ERR_CHKANDJUMP(strncmp(cmdline, "response_to_init", PMI2U_MAXLINE) != 0, pmi2_errno, + PMIU_getval("cmd", cmdline, PMIU_MAXLINE); + PMI2U_ERR_CHKANDJUMP(strncmp(cmdline, "response_to_init", PMIU_MAXLINE) != 0, pmi2_errno, PMI2_ERR_OTHER, "**bad_cmd"); - PMI2U_getval("rc", buf, PMI2U_MAXLINE); - if (strncmp(buf, "0", PMI2U_MAXLINE) != 0) { - char buf1[PMI2U_MAXLINE]; - PMI2U_getval("pmi_version", buf, PMI2U_MAXLINE); - PMI2U_getval("pmi_subversion", buf1, PMI2U_MAXLINE); + PMIU_getval("rc", buf, PMIU_MAXLINE); + if (strncmp(buf, "0", PMIU_MAXLINE) != 0) { + char buf1[PMIU_MAXLINE]; + PMIU_getval("pmi_version", buf, PMIU_MAXLINE); + PMIU_getval("pmi_subversion", buf1, PMIU_MAXLINE); PMI2U_ERR_SETANDJUMP4(pmi2_errno, PMI2_ERR_OTHER, "**pmi2_version", "**pmi2_version %s %s %d %d", buf, buf1, PMI_VERSION, PMI_SUBVERSION); } @@ -485,7 +486,7 @@ PMI_API_PUBLIC int PMI2_Initialized(void) PMI_API_PUBLIC int PMI2_Abort(int flag, const char msg[]) { - PMI2U_printf(1, "aborting job:\n%s\n", msg); + PMIU_printf(1, "aborting job:\n%s\n", msg); /* ignoring return code, because we're exiting anyway */ PMIi_WriteSimpleCommandStr(PMI2_fd, NULL, ABORT_CMD, ISWORLD_KEY, flag ? TRUE_VAL : FALSE_VAL, @@ -509,7 +510,7 @@ PMI_API_PUBLIC int found; const char *jid; int jidlen; - char tempbuf[PMI2U_MAXLINE]; + char tempbuf[PMIU_MAXLINE]; char *lead, *lag; int spawn_rc; const char *errmsg = NULL; @@ -618,24 +619,10 @@ cmd=spawn;thrid=string;ncmds=count;preputcount=n;ppkey0=name;ppval0=string;...;\ MPL_strncpy(jobId, jid, jobIdSize); } - if (PMI2U_getval("errcodes", tempbuf, PMI2U_MAXLINE)) { - num_errcodes_found = 0; - lag = &tempbuf[0]; - do { - lead = strchr(lag, ','); - if (lead) - *lead = '\0'; - errors[num_errcodes_found++] = atoi(lag); - lag = lead + 1; /* move past the null char */ - PMI2U_Assert(num_errcodes_found <= total_num_processes); - } while (lead != NULL); - PMI2U_Assert(num_errcodes_found == total_num_processes); - } else { - /* gforker doesn't return errcodes, so we'll just pretend that means - * that it was going to send all `0's. */ - for (i = 0; i < total_num_processes; ++i) { - errors[i] = 0; - } + /* PMI2 does not return error codes, so we'll just pretend that means + * that it was going to send all `0's. */ + for (i = 0; i < total_num_processes; ++i) { + errors[i] = 0; } fn_fail: @@ -1796,13 +1783,13 @@ static int PMII_Connect_to_pm(char *hostname, int portnum) ret = MPL_get_sockaddr(hostname, &addr); if (ret) { - PMI2U_printf(1, "Unable to get host entry for %s\n", hostname); + PMIU_printf(1, "Unable to get host entry for %s\n", hostname); return -1; } fd = MPL_socket(); if (fd < 0) { - PMI2U_printf(1, "Unable to get AF_INET socket\n"); + PMIU_printf(1, "Unable to get AF_INET socket\n"); return -1; } @@ -1815,7 +1802,7 @@ static int PMII_Connect_to_pm(char *hostname, int portnum) if (ret) { switch (errno) { case ECONNREFUSED: - PMI2U_printf(1, "connect failed with connection refused\n"); + PMIU_printf(1, "connect failed with connection refused\n"); /* (close socket, get new socket, try again) */ if (q_wait) close(fd); @@ -1828,11 +1815,11 @@ static int PMII_Connect_to_pm(char *hostname, int portnum) break; case ETIMEDOUT: /* timed out */ - PMI2U_printf(1, "connect failed with timeout\n"); + PMIU_printf(1, "connect failed with timeout\n"); return -1; default: - PMI2U_printf(1, "connect failed with errno %d\n", errno); + PMIU_printf(1, "connect failed with errno %d\n", errno); return -1; } } From 21f1500f6ea623aa1f659d686994004bc916f70a Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 9 Mar 2022 08:42:15 -0600 Subject: [PATCH 582/607] pmi: merge pmi2_util to pmi_util The util code does not have PMI version context. Merge and convert them to PMIU namespace. --- src/pmi/src/pmi2_util.h | 129 ------- src/pmi/src/pmi2compat.h | 23 -- src/pmi/src/pmi_util.c | 2 + src/pmi/src/pmi_util.h | 132 +++++++ src/pmi/src/pmi_v2.c | 732 +++++++++++++++++++-------------------- 5 files changed, 497 insertions(+), 521 deletions(-) delete mode 100644 src/pmi/src/pmi2_util.h delete mode 100644 src/pmi/src/pmi2compat.h diff --git a/src/pmi/src/pmi2_util.h b/src/pmi/src/pmi2_util.h deleted file mode 100644 index f12b4161010..00000000000 --- a/src/pmi/src/pmi2_util.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) by Argonne National Laboratory - * See COPYRIGHT in top-level directory - */ - -#ifndef PMI2_UTIL_H_INCLUDED -#define PMI2_UTIL_H_INCLUDED - -extern int PMI2_pmiverbose; /* Set this to true to print PMI debugging info */ -#define printf_d(x...) do { if (PMI2_pmiverbose) printf(x); } while (0) - -/* error reporting macros */ - -#define PMI2U_ERR_POP(err) do { pmi2_errno = err; printf_d("ERROR: %s (%d)\n", __func__, __LINE__); goto fn_fail; } while (0) -#define PMI2U_ERR_SETANDJUMP(err, class, str) do { \ - printf_d("ERROR: "str" in %s (%d)\n", __func__, __LINE__); \ - pmi2_errno = class; \ - goto fn_fail; \ - } while (0) -#define PMI2U_ERR_SETANDJUMP1(err, class, str, str1, arg) do { \ - printf_d("ERROR: "str1" in %s (%d)\n", arg, __func__, __LINE__); \ - pmi2_errno = class; \ - goto fn_fail; \ - } while (0) -#define PMI2U_ERR_SETANDJUMP2(err, class, str, str1, arg1, arg2) do { \ - printf_d("ERROR: "str1" in %s (%d)\n", arg1, arg2, __func__, __LINE__); \ - pmi2_errno = class; \ - goto fn_fail; \ - } while (0) -#define PMI2U_ERR_SETANDJUMP3(err, class, str, str1, arg1, arg2, arg3) do { \ - printf_d("ERROR: "str1" in %s (%d)\n", arg1, arg2, arg3, __func__, __LINE__); \ - pmi2_errno = class; \ - goto fn_fail; \ - } while (0) -#define PMI2U_ERR_SETANDJUMP4(err, class, str, str1, arg1, arg2, arg3, arg4) do { \ - printf_d("ERROR: "str1" in %s (%d)\n", arg1, arg2, arg3, arg4, __func__, __LINE__); \ - pmi2_errno = class; \ - goto fn_fail; \ - } while (0) -#define PMI2U_ERR_SETANDJUMP5(err, class, str, str1, arg1, arg2, arg3, arg4, arg5) do { \ - printf_d("ERROR: "str1" in %s (%d)\n", arg1, arg2, arg3, arg4, arg5, __func__, __LINE__); \ - pmi2_errno = class; \ - goto fn_fail; \ - } while (0) -#define PMI2U_ERR_SETANDJUMP6(err, class, str, str1, arg1, arg2, arg3, arg4, arg5, arg6) do { \ - printf_d("ERROR: "str1" in %s (%d)\n", arg1, arg2, arg3, arg4, arg5, arg6, __func__, __LINE__); \ - pmi2_errno = class; \ - goto fn_fail; \ - } while (0) - - -#define PMI2U_ERR_CHKANDJUMP(cond, err, class, str) do { \ - if (cond) \ - PMI2U_ERR_SETANDJUMP(err, class, str); \ - } while (0) -#define PMI2U_ERR_CHKANDJUMP1(cond, err, class, str, str1, arg) do { \ - if (cond) \ - PMI2U_ERR_SETANDJUMP1(err, class, str, str1, arg); \ - } while (0) -#define PMI2U_ERR_CHKANDJUMP2(cond, err, class, str, str1, arg1, arg2) do { \ - if (cond) \ - PMI2U_ERR_SETANDJUMP2(err, class, str, str1, arg1, arg2); \ - } while (0) -#define PMI2U_ERR_CHKANDJUMP3(cond, err, class, str, str1, arg1, arg2, arg3) do { \ - if (cond) \ - PMI2U_ERR_SETANDJUMP3(err, class, str, str1, arg1, arg2, arg3); \ - } while (0) -#define PMI2U_ERR_CHKANDJUMP4(cond, err, class, str, str1, arg1, arg2, arg3, arg4) do { \ - if (cond) \ - PMI2U_ERR_SETANDJUMP4(err, class, str, str1, arg1, arg2, arg3, arg4); \ - } while (0) -#define PMI2U_ERR_CHKANDJUMP5(cond, err, class, str, str1, arg1, arg2, arg3, arg4, arg5) do { \ - if (cond) \ - PMI2U_ERR_SETANDJUMP5(err, class, str, str1, arg1, arg2, arg3, arg4, arg5); \ - } while (0) -#define PMI2U_ERR_CHKANDJUMP6(cond, err, class, str, str1, arg1, arg2, arg3, arg4, arg5, arg6) do { \ - if (cond) \ - PMI2U_ERR_SETANDJUMP6(err, class, str, str1, arg1, arg2, arg3, arg4, arg5, arg6); \ - } while (0) - -#if (!defined(NDEBUG) && defined(HAVE_ERROR_CHECKING)) -#define PMI2U_AssertDecl(a_) a_ -#define PMI2U_AssertDeclValue(_a, _b) _a = _b -#else -/* Empty decls not allowed in C */ -#define PMI2U_AssertDecl(a_) a_ -#define PMI2U_AssertDeclValue(_a, _b) _a ATTRIBUTE((unused)) -#endif - -#ifdef HAVE_ERROR_CHECKING -#define PMI2U_CHKMEM_SETERR(rc_, nbytes_, name_) do { \ - rc_ = PMI2_ERR_NOMEM; \ - printf_d("ERROR: memory allocation of %lu bytes failed for %s in %s (%d)\n", \ - (size_t)nbytes_, name_, __func__, __LINE__); \ - } while (0) -#else -#define PMI2U_CHKMEM_SETERR(rc_, nbytes_, name_) rc_ = PMI2_ERR_NOMEM -#endif - -#define PMI2U_CHK_MALLOC(pointer_,type_,nbytes_,rc_,name_) do { \ - pointer_ = (type_)PMI2U_Malloc(nbytes_); \ - if (!pointer_) { \ - PMI2U_CHKMEM_SETERR(rc_,nbytes_,name_); \ - goto fn_fail; \ - } \ - } while (0) - -/* Provides a easy way to use realloc safely and avoid the temptation to use - * realloc unsafely (direct ptr assignment). Zero-size reallocs returning NULL - * are handled and are not considered an error. */ -#define PMI2U_REALLOC_OR_FREE_AND_JUMP(ptr_,size_,rc_) do { \ - void *realloc_tmp_ = PMI2U_Realloc((ptr_), (size_)); \ - if ((size_) && !realloc_tmp_) { \ - PMI2U_Free(ptr_); \ - PMI2U_ERR_SETANDJUMP2(rc_,PMI2U_CHKMEM_ISFATAL, \ - "**nomem2","**nomem2 %d %s",(size_),PMI2U_QUOTE(ptr_)); \ - } \ - (ptr_) = realloc_tmp_; \ - } while (0) -/* this version does not free ptr_ */ -#define PMI2U_REALLOC_ORJUMP(ptr_,size_,rc_) do { \ - void *realloc_tmp_ = PMI2U_Realloc((ptr_), (size_)); \ - if (size_) \ - PMI2U_ERR_CHKANDJUMP2(!realloc_tmp_,rc_,PMI2U_CHKMEM_ISFATAL,\ \ - "**nomem2","**nomem2 %d %s",(size_),PMI2U_QUOTE(ptr_)); \ - (ptr_) = realloc_tmp_; \ - } while (0) - -#endif /* PMI2_UTIL_H_INCLUDED */ diff --git a/src/pmi/src/pmi2compat.h b/src/pmi/src/pmi2compat.h deleted file mode 100644 index db50b14ebba..00000000000 --- a/src/pmi/src/pmi2compat.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) by Argonne National Laboratory - * See COPYRIGHT in top-level directory - */ - -#ifndef PMI2COMPAT_H_INCLUDED -#define PMI2COMPAT_H_INCLUDED - -#include -#include - -#define PMI2U_Malloc(size_) MPL_malloc(size_, MPL_MEM_PM) -#define PMI2U_Free MPL_free -#define PMI2U_Strdup MPL_strdup -#define PMI2U_Strnapp MPL_strnapp -#define PMI2U_Assert assert -#define PMI2U_Exit MPL_exit -#define PMI2U_Memcpy memcpy - -#define TRUE 1 -#define FALSE 0 - -#endif /* PMI2COMPAT_H_INCLUDED */ diff --git a/src/pmi/src/pmi_util.c b/src/pmi/src/pmi_util.c index baa4e44aaae..e3de37d0270 100644 --- a/src/pmi/src/pmi_util.c +++ b/src/pmi/src/pmi_util.c @@ -34,6 +34,8 @@ #define MAXVALLEN 1024 #define MAXKEYLEN 32 +int PMIU_verbose = 0; /* Set this to true to print PMI debugging info */ + /* These are not the keyvals in the keyval space that is part of the PMI specification. They are just part of this implementation's internal utilities. diff --git a/src/pmi/src/pmi_util.h b/src/pmi/src/pmi_util.h index 3f6e20c0e88..d9a82ec55d0 100644 --- a/src/pmi/src/pmi_util.h +++ b/src/pmi/src/pmi_util.h @@ -34,4 +34,136 @@ void PMIU_dump_keyvals(void); char *PMIU_getval(const char *keystr, char *valstr, int vallen); void PMIU_chgval(const char *keystr, char *valstr); +#define PMIU_Malloc(size_) MPL_malloc(size_, MPL_MEM_PM) +#define PMIU_Free MPL_free +#define PMIU_Strdup MPL_strdup +#define PMIU_Strnapp MPL_strnapp +#define PMIU_Exit MPL_exit +#define PMIU_Memcpy memcpy + +#define PMIU_TRUE 1 +#define PMIU_FALSE 0 + +extern int PMIU_verbose; /* Set this to true to print PMI debugging info */ +#define printf_d(x...) do { if (PMIU_verbose) printf(x); } while (0) + +/* error reporting macros */ +/* NOTE: we assume error codes are matching between PMI-1 and PMI-2 */ +/* FIXME: do not assume error code, make it a macro parameter */ + +#define PMIU_ERR_POP(err) do { pmi_errno = err; printf_d("ERROR: %s (%d)\n", __func__, __LINE__); goto fn_fail; } while (0) +#define PMIU_ERR_SETANDJUMP(err, class, str) do { \ + printf_d("ERROR: "str" in %s (%d)\n", __func__, __LINE__); \ + pmi_errno = class; \ + goto fn_fail; \ + } while (0) +#define PMIU_ERR_SETANDJUMP1(err, class, str, str1, arg) do { \ + printf_d("ERROR: "str1" in %s (%d)\n", arg, __func__, __LINE__); \ + pmi_errno = class; \ + goto fn_fail; \ + } while (0) +#define PMIU_ERR_SETANDJUMP2(err, class, str, str1, arg1, arg2) do { \ + printf_d("ERROR: "str1" in %s (%d)\n", arg1, arg2, __func__, __LINE__); \ + pmi_errno = class; \ + goto fn_fail; \ + } while (0) +#define PMIU_ERR_SETANDJUMP3(err, class, str, str1, arg1, arg2, arg3) do { \ + printf_d("ERROR: "str1" in %s (%d)\n", arg1, arg2, arg3, __func__, __LINE__); \ + pmi_errno = class; \ + goto fn_fail; \ + } while (0) +#define PMIU_ERR_SETANDJUMP4(err, class, str, str1, arg1, arg2, arg3, arg4) do { \ + printf_d("ERROR: "str1" in %s (%d)\n", arg1, arg2, arg3, arg4, __func__, __LINE__); \ + pmi_errno = class; \ + goto fn_fail; \ + } while (0) +#define PMIU_ERR_SETANDJUMP5(err, class, str, str1, arg1, arg2, arg3, arg4, arg5) do { \ + printf_d("ERROR: "str1" in %s (%d)\n", arg1, arg2, arg3, arg4, arg5, __func__, __LINE__); \ + pmi_errno = class; \ + goto fn_fail; \ + } while (0) +#define PMIU_ERR_SETANDJUMP6(err, class, str, str1, arg1, arg2, arg3, arg4, arg5, arg6) do { \ + printf_d("ERROR: "str1" in %s (%d)\n", arg1, arg2, arg3, arg4, arg5, arg6, __func__, __LINE__); \ + pmi_errno = class; \ + goto fn_fail; \ + } while (0) + + +#define PMIU_ERR_CHKANDJUMP(cond, err, class, str) do { \ + if (cond) \ + PMIU_ERR_SETANDJUMP(err, class, str); \ + } while (0) +#define PMIU_ERR_CHKANDJUMP1(cond, err, class, str, str1, arg) do { \ + if (cond) \ + PMIU_ERR_SETANDJUMP1(err, class, str, str1, arg); \ + } while (0) +#define PMIU_ERR_CHKANDJUMP2(cond, err, class, str, str1, arg1, arg2) do { \ + if (cond) \ + PMIU_ERR_SETANDJUMP2(err, class, str, str1, arg1, arg2); \ + } while (0) +#define PMIU_ERR_CHKANDJUMP3(cond, err, class, str, str1, arg1, arg2, arg3) do { \ + if (cond) \ + PMIU_ERR_SETANDJUMP3(err, class, str, str1, arg1, arg2, arg3); \ + } while (0) +#define PMIU_ERR_CHKANDJUMP4(cond, err, class, str, str1, arg1, arg2, arg3, arg4) do { \ + if (cond) \ + PMIU_ERR_SETANDJUMP4(err, class, str, str1, arg1, arg2, arg3, arg4); \ + } while (0) +#define PMIU_ERR_CHKANDJUMP5(cond, err, class, str, str1, arg1, arg2, arg3, arg4, arg5) do { \ + if (cond) \ + PMIU_ERR_SETANDJUMP5(err, class, str, str1, arg1, arg2, arg3, arg4, arg5); \ + } while (0) +#define PMIU_ERR_CHKANDJUMP6(cond, err, class, str, str1, arg1, arg2, arg3, arg4, arg5, arg6) do { \ + if (cond) \ + PMIU_ERR_SETANDJUMP6(err, class, str, str1, arg1, arg2, arg3, arg4, arg5, arg6); \ + } while (0) + +#if (!defined(NDEBUG) && defined(HAVE_ERROR_CHECKING)) +#define PMIU_AssertDecl(a_) a_ +#define PMIU_AssertDeclValue(_a, _b) _a = _b +#else +/* Empty decls not allowed in C */ +#define PMIU_AssertDecl(a_) a_ +#define PMIU_AssertDeclValue(_a, _b) _a ATTRIBUTE((unused)) +#endif + +#ifdef HAVE_ERROR_CHECKING +#define PMIU_CHKMEM_SETERR(rc_, nbytes_, name_) do { \ + rc_ = PMI_ERR_NOMEM; \ + printf_d("ERROR: memory allocation of %lu bytes failed for %s in %s (%d)\n", \ + (size_t)nbytes_, name_, __func__, __LINE__); \ + } while (0) +#else +#define PMIU_CHKMEM_SETERR(rc_, nbytes_, name_) rc_ = PMI_ERR_NOMEM +#endif + +#define PMIU_CHK_MALLOC(pointer_,type_,nbytes_,rc_,name_) do { \ + pointer_ = (type_)PMIU_Malloc(nbytes_); \ + if (!pointer_) { \ + PMIU_CHKMEM_SETERR(rc_,nbytes_,name_); \ + goto fn_fail; \ + } \ + } while (0) + +/* Provides a easy way to use realloc safely and avoid the temptation to use + * realloc unsafely (direct ptr assignment). Zero-size reallocs returning NULL + * are handled and are not considered an error. */ +#define PMIU_REALLOC_OR_FREE_AND_JUMP(ptr_,size_,rc_) do { \ + void *realloc_tmp_ = PMIU_Realloc((ptr_), (size_)); \ + if ((size_) && !realloc_tmp_) { \ + PMIU_Free(ptr_); \ + PMIU_ERR_SETANDJUMP2(rc_,PMIU_CHKMEM_ISFATAL, \ + "**nomem2","**nomem2 %d %s",(size_),PMIU_QUOTE(ptr_)); \ + } \ + (ptr_) = realloc_tmp_; \ + } while (0) +/* this version does not free ptr_ */ +#define PMIU_REALLOC_ORJUMP(ptr_,size_,rc_) do { \ + void *realloc_tmp_ = PMIU_Realloc((ptr_), (size_)); \ + if (size_) \ + PMIU_ERR_CHKANDJUMP2(!realloc_tmp_,rc_,PMIU_CHKMEM_ISFATAL,\ \ + "**nomem2","**nomem2 %d %s",(size_),PMIU_QUOTE(ptr_)); \ + (ptr_) = realloc_tmp_; \ + } while (0) + #endif /* SIMPLE_PMIUTIL_H_INCLUDED */ diff --git a/src/pmi/src/pmi_v2.c b/src/pmi/src/pmi_v2.c index f93885171f5..86d8eddcd0d 100644 --- a/src/pmi/src/pmi_v2.c +++ b/src/pmi/src/pmi_v2.c @@ -5,9 +5,7 @@ #include "pmi_config.h" -#include "pmi2compat.h" #include "pmi_util.h" -#include "pmi2_util.h" #include "pmi2.h" #include "mpl.h" @@ -140,10 +138,8 @@ static int PMI2_rank = 0; static int PMI2_is_threaded = 0; /* Set this to true to require thread safety */ -int PMI2_pmiverbose = 0; /* Set this to true to print PMI debugging info */ - static MPL_thread_mutex_t mutex; -static int blocked = FALSE; +static int blocked = PMIU_FALSE; static MPL_thread_cond_t cond; /* XXX DJG the "const"s on both of these functions and the Keyvalpair @@ -157,15 +153,15 @@ static void init_kv_str(PMI2_Keyvalpair * kv, const char key[], const char val[] kv->key = key; kv->value = val; kv->valueLen = strlen(val); - kv->isCopy = FALSE; + kv->isCopy = PMIU_FALSE; } /* same as init_kv_str, but strdup's the key and val first, and sets isCopy=TRUE */ static void init_kv_strdup(PMI2_Keyvalpair * kv, const char key[], const char val[]) { /* XXX DJG could be slightly more efficient */ - init_kv_str(kv, PMI2U_Strdup(key), PMI2U_Strdup(val)); - kv->isCopy = TRUE; + init_kv_str(kv, PMIU_Strdup(key), PMIU_Strdup(val)); + kv->isCopy = PMIU_TRUE; } /* same as init_kv_strdup, but converts val into a string first */ @@ -176,7 +172,7 @@ static void init_kv_strdup_int(PMI2_Keyvalpair * kv, const char key[], int val) int rc = PMI2_SUCCESS; rc = MPL_snprintf(tmpbuf, sizeof(tmpbuf), "%d", val); - PMI2U_Assert(rc >= 0); + PMIU_Assert(rc >= 0); init_kv_strdup(kv, key, tmpbuf); } @@ -189,7 +185,7 @@ static void init_kv_strdup_intsuffix(PMI2_Keyvalpair * kv, const char key_prefix int rc = PMI2_SUCCESS; rc = MPL_snprintf(tmpbuf, sizeof(tmpbuf), "%s%d", key_prefix, suffix); - PMI2U_Assert(rc >= 0); + PMIU_Assert(rc >= 0); init_kv_strdup(kv, tmpbuf, val); } @@ -224,7 +220,7 @@ pending_item_t *pendingq_tail = NULL; static inline void ENQUEUE(PMI2_Command * cmd) { - pending_item_t *pi = PMI2U_Malloc(sizeof(pending_item_t)); + pending_item_t *pi = PMIU_Malloc(sizeof(pending_item_t)); pi->next = NULL; pi->cmd = cmd; @@ -246,7 +242,7 @@ static inline int SEARCH_REMOVE(PMI2_Command * cmd) pendingq_head = pi->next; if (pendingq_head == NULL) pendingq_tail = NULL; - PMI2U_Free(pi); + PMIU_Free(pi); return 1; } prev = pi; @@ -257,7 +253,7 @@ static inline int SEARCH_REMOVE(PMI2_Command * cmd) prev->next = pi->next; if (prev->next == NULL) pendingq_tail = prev; - PMI2U_Free(pi); + PMIU_Free(pi); return 1; } } @@ -279,7 +275,7 @@ PMI_API_PUBLIC int PMI2_Set_threaded(int is_threaded) PMI_API_PUBLIC int PMI2_Init(int *spawned, int *size, int *rank, int *appnum) { - int pmi2_errno = PMI2_SUCCESS; + int pmi_errno = PMI2_SUCCESS; char *p; char buf[PMIU_MAXLINE], cmdline[PMIU_MAXLINE]; char *jobid; @@ -287,9 +283,9 @@ PMI_API_PUBLIC int PMI2_Init(int *spawned, int *size, int *rank, int *appnum) int ret; MPL_thread_mutex_create(&mutex, &ret); - PMI2U_Assert(!ret); + PMIU_Assert(!ret); MPL_thread_cond_create(&cond, &ret); - PMI2U_Assert(!ret); + PMIU_Assert(!ret); /* FIXME: Why is setvbuf commented out? */ /* FIXME: What if the output should be fully buffered (directed to file)? @@ -305,9 +301,9 @@ PMI_API_PUBLIC int PMI2_Init(int *spawned, int *size, int *rank, int *appnum) PMI2_debug = atoi(p); /* Get the fd for PMI commands; if none, we're a singleton */ - pmi2_errno = getPMIFD(); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); + pmi_errno = getPMIFD(); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); if (PMI2_fd == -1) { /* Singleton init: Process not started with mpiexec, @@ -325,29 +321,29 @@ PMI_API_PUBLIC int PMI2_Init(int *spawned, int *size, int *rank, int *appnum) ret = MPL_snprintf(buf, PMIU_MAXLINE, "cmd=init pmi_version=%d pmi_subversion=%d\n", PMI_VERSION, PMI_SUBVERSION); - PMI2U_ERR_CHKANDJUMP1(ret < 0, pmi2_errno, PMI2_ERR_OTHER, "**intern", "**intern %s", - "failed to generate init line"); + PMIU_ERR_CHKANDJUMP1(ret < 0, pmi_errno, PMI2_ERR_OTHER, "**intern", "**intern %s", + "failed to generate init line"); ret = PMIU_writeline(PMI2_fd, buf); - PMI2U_ERR_CHKANDJUMP(ret < 0, pmi2_errno, PMI2_ERR_OTHER, "**pmi2_init_send"); + PMIU_ERR_CHKANDJUMP(ret < 0, pmi_errno, PMI2_ERR_OTHER, "**pmi2_init_send"); ret = PMIU_readline(PMI2_fd, buf, PMIU_MAXLINE); - PMI2U_ERR_CHKANDJUMP1(ret < 0, pmi2_errno, PMI2_ERR_OTHER, "**pmi2_initack", - "**pmi2_initack %s", strerror(errno)); + PMIU_ERR_CHKANDJUMP1(ret < 0, pmi_errno, PMI2_ERR_OTHER, "**pmi2_initack", + "**pmi2_initack %s", strerror(errno)); PMIU_parse_keyvals(buf); cmdline[0] = 0; PMIU_getval("cmd", cmdline, PMIU_MAXLINE); - PMI2U_ERR_CHKANDJUMP(strncmp(cmdline, "response_to_init", PMIU_MAXLINE) != 0, pmi2_errno, - PMI2_ERR_OTHER, "**bad_cmd"); + PMIU_ERR_CHKANDJUMP(strncmp(cmdline, "response_to_init", PMIU_MAXLINE) != 0, pmi_errno, + PMI2_ERR_OTHER, "**bad_cmd"); PMIU_getval("rc", buf, PMIU_MAXLINE); if (strncmp(buf, "0", PMIU_MAXLINE) != 0) { char buf1[PMIU_MAXLINE]; PMIU_getval("pmi_version", buf, PMIU_MAXLINE); PMIU_getval("pmi_subversion", buf1, PMIU_MAXLINE); - PMI2U_ERR_SETANDJUMP4(pmi2_errno, PMI2_ERR_OTHER, "**pmi2_version", - "**pmi2_version %s %s %d %d", buf, buf1, PMI_VERSION, PMI_SUBVERSION); + PMIU_ERR_SETANDJUMP4(pmi_errno, PMI2_ERR_OTHER, "**pmi2_version", + "**pmi2_version %s %s %d %d", buf, buf1, PMI_VERSION, PMI_SUBVERSION); } /* do full PMI2 init */ @@ -387,51 +383,51 @@ PMI_API_PUBLIC int PMI2_Init(int *spawned, int *size, int *rank, int *appnum) ++npairs; - pmi2_errno = PMIi_WriteSimpleCommand(PMI2_fd, 0, FULLINIT_CMD, pairs_p, npairs); /* don't pass in thread id for init */ - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); + pmi_errno = PMIi_WriteSimpleCommand(PMI2_fd, 0, FULLINIT_CMD, pairs_p, npairs); /* don't pass in thread id for init */ + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); /* Read auth-response */ /* Send auth-response-complete */ /* Read fullinit-response */ - pmi2_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, FULLINITRESP_CMD, &rc, &errmsg); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - PMI2U_ERR_CHKANDJUMP1(rc, pmi2_errno, PMI2_ERR_OTHER, "**pmi2_fullinit", - "**pmi2_fullinit %s", errmsg ? errmsg : "unknown"); + pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, FULLINITRESP_CMD, &rc, &errmsg); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_fullinit", + "**pmi2_fullinit %s", errmsg ? errmsg : "unknown"); found = getvalint(cmd.pairs, cmd.nPairs, PMIVERSION_KEY, &version); - PMI2U_ERR_CHKANDJUMP(found != 1, pmi2_errno, PMI2_ERR_OTHER, "**intern"); + PMIU_ERR_CHKANDJUMP(found != 1, pmi_errno, PMI2_ERR_OTHER, "**intern"); found = getvalint(cmd.pairs, cmd.nPairs, PMISUBVER_KEY, &subver); - PMI2U_ERR_CHKANDJUMP(found != 1, pmi2_errno, PMI2_ERR_OTHER, "**intern"); + PMIU_ERR_CHKANDJUMP(found != 1, pmi_errno, PMI2_ERR_OTHER, "**intern"); found = getvalint(cmd.pairs, cmd.nPairs, RANK_KEY, rank); - PMI2U_ERR_CHKANDJUMP(found != 1, pmi2_errno, PMI2_ERR_OTHER, "**intern"); + PMIU_ERR_CHKANDJUMP(found != 1, pmi_errno, PMI2_ERR_OTHER, "**intern"); found = getvalint(cmd.pairs, cmd.nPairs, SIZE_KEY, size); - PMI2U_ERR_CHKANDJUMP(found != 1, pmi2_errno, PMI2_ERR_OTHER, "**intern"); + PMIU_ERR_CHKANDJUMP(found != 1, pmi_errno, PMI2_ERR_OTHER, "**intern"); found = getvalint(cmd.pairs, cmd.nPairs, APPNUM_KEY, appnum); - PMI2U_ERR_CHKANDJUMP(found != 1, pmi2_errno, PMI2_ERR_OTHER, "**intern"); + PMIU_ERR_CHKANDJUMP(found != 1, pmi_errno, PMI2_ERR_OTHER, "**intern"); found = getval(cmd.pairs, cmd.nPairs, SPAWNERJOBID_KEY, &spawner_jobid, &spawner_jobid_len); - PMI2U_ERR_CHKANDJUMP(found == -1, pmi2_errno, PMI2_ERR_OTHER, "**intern"); + PMIU_ERR_CHKANDJUMP(found == -1, pmi_errno, PMI2_ERR_OTHER, "**intern"); if (found) - *spawned = TRUE; + *spawned = PMIU_TRUE; else - *spawned = FALSE; + *spawned = PMIU_FALSE; debugged = 0; found = getvalbool(cmd.pairs, cmd.nPairs, DEBUGGED_KEY, &debugged); - PMI2U_ERR_CHKANDJUMP(found == -1, pmi2_errno, PMI2_ERR_OTHER, "**intern"); + PMIU_ERR_CHKANDJUMP(found == -1, pmi_errno, PMI2_ERR_OTHER, "**intern"); PMI2_debug |= debugged; - found = getvalbool(cmd.pairs, cmd.nPairs, PMIVERBOSE_KEY, &PMI2_pmiverbose); - PMI2U_ERR_CHKANDJUMP(found == -1, pmi2_errno, PMI2_ERR_OTHER, "**intern"); + found = getvalbool(cmd.pairs, cmd.nPairs, PMIVERBOSE_KEY, &PMIU_verbose); + PMIU_ERR_CHKANDJUMP(found == -1, pmi_errno, PMI2_ERR_OTHER, "**intern"); - PMI2U_Free(cmd.command); + PMIU_Free(cmd.command); freepairs(cmd.pairs, cmd.nPairs); } @@ -439,7 +435,7 @@ PMI_API_PUBLIC int PMI2_Init(int *spawned, int *size, int *rank, int *appnum) PMI2_initialized = NORMAL_INIT_WITH_PM; fn_exit: - return pmi2_errno; + return pmi_errno; fn_fail: goto fn_exit; @@ -447,21 +443,21 @@ PMI_API_PUBLIC int PMI2_Init(int *spawned, int *size, int *rank, int *appnum) PMI_API_PUBLIC int PMI2_Finalize(void) { - int pmi2_errno = PMI2_SUCCESS; + int pmi_errno = PMI2_SUCCESS; int rc; const char *errmsg; PMI2_Command cmd = { 0 }; if (PMI2_initialized > SINGLETON_INIT_BUT_NO_PM) { - pmi2_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, FINALIZE_CMD, NULL); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - pmi2_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, FINALIZERESP_CMD, &rc, &errmsg); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - PMI2U_ERR_CHKANDJUMP1(rc, pmi2_errno, PMI2_ERR_OTHER, "**pmi2_finalize", - "**pmi2_finalize %s", errmsg ? errmsg : "unknown"); - PMI2U_Free(cmd.command); + pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, FINALIZE_CMD, NULL); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, FINALIZERESP_CMD, &rc, &errmsg); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_finalize", + "**pmi2_finalize %s", errmsg ? errmsg : "unknown"); + PMIU_Free(cmd.command); freepairs(cmd.pairs, cmd.nPairs); shutdown(PMI2_fd, SHUT_RDWR); @@ -469,7 +465,7 @@ PMI_API_PUBLIC int PMI2_Finalize(void) } fn_exit: - return pmi2_errno; + return pmi_errno; fn_fail: goto fn_exit; @@ -492,7 +488,7 @@ PMI_API_PUBLIC int PMI2_Abort(int flag, const char msg[]) PMIi_WriteSimpleCommandStr(PMI2_fd, NULL, ABORT_CMD, ISWORLD_KEY, flag ? TRUE_VAL : FALSE_VAL, MSG_KEY, msg, NULL); - PMI2U_Exit(PMII_EXIT_CODE); + PMIU_Exit(PMII_EXIT_CODE); return PMI2_SUCCESS; } @@ -515,7 +511,7 @@ PMI_API_PUBLIC int spawn_rc; const char *errmsg = NULL; PMI2_Command resp_cmd = { 0 }; - int pmi2_errno = 0; + int pmi_errno = 0; PMI2_Keyvalpair **pairs_p = NULL; int npairs = 0; int total_pairs = 0; @@ -554,12 +550,12 @@ cmd=spawn;thrid=string;ncmds=count;preputcount=n;ppkey0=name;ppval0=string;...;\ } } - pairs_p = PMI2U_Malloc(total_pairs * sizeof(PMI2_Keyvalpair *)); + pairs_p = PMIU_Malloc(total_pairs * sizeof(PMI2_Keyvalpair *)); /* individiually allocating instead of batch alloc b/c freepairs assumes it */ for (i = 0; i < total_pairs; ++i) { /* FIXME we are somehow still leaking some of this memory */ - pairs_p[i] = PMI2U_Malloc(sizeof(PMI2_Keyvalpair)); - PMI2U_Assert(pairs_p[i]); + pairs_p[i] = PMIU_Malloc(sizeof(PMI2_Keyvalpair)); + PMIU_Assert(pairs_p[i]); } init_kv_strdup_int(pairs_p[npairs++], "ncmds", count); @@ -595,11 +591,11 @@ cmd=spawn;thrid=string;ncmds=count;preputcount=n;ppkey0=name;ppval0=string;...;\ if (npairs < total_pairs) { printf_d("about to fail assertion, npairs=%d total_pairs=%d\n", npairs, total_pairs); } - PMI2U_Assert(npairs == total_pairs); + PMIU_Assert(npairs == total_pairs); - pmi2_errno = PMIi_WriteSimpleCommand(PMI2_fd, &resp_cmd, "spawn", pairs_p, npairs); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); + pmi_errno = PMIi_WriteSimpleCommand(PMI2_fd, &resp_cmd, "spawn", pairs_p, npairs); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); freepairs(pairs_p, npairs); pairs_p = NULL; @@ -611,11 +607,11 @@ cmd=spawn;thrid=string;ncmds=count;preputcount=n;ppkey0=name;ppval0=string;...;\ } /* XXX DJG TODO deal with the response */ - PMI2U_Assert(errors != NULL); + PMIU_Assert(errors != NULL); if (jobId && jobIdSize) { found = getval(resp_cmd.pairs, resp_cmd.nPairs, JOBID_KEY, &jid, &jidlen); - PMI2U_ERR_CHKANDJUMP(found != 1, pmi2_errno, PMI2_ERR_OTHER, "**intern"); + PMIU_ERR_CHKANDJUMP(found != 1, pmi_errno, PMI2_ERR_OTHER, "**intern"); MPL_strncpy(jobId, jid, jobIdSize); } @@ -626,17 +622,17 @@ cmd=spawn;thrid=string;ncmds=count;preputcount=n;ppkey0=name;ppval0=string;...;\ } fn_fail: - PMI2U_Free(resp_cmd.command); + PMIU_Free(resp_cmd.command); freepairs(resp_cmd.pairs, resp_cmd.nPairs); if (pairs_p) freepairs(pairs_p, npairs); - return pmi2_errno; + return pmi_errno; } PMI_API_PUBLIC int PMI2_Job_GetId(char jobid[], int jobid_size) { - int pmi2_errno = PMI2_SUCCESS; + int pmi_errno = PMI2_SUCCESS; int found; const char *jid; int jidlen; @@ -644,24 +640,24 @@ PMI_API_PUBLIC int PMI2_Job_GetId(char jobid[], int jobid_size) const char *errmsg; PMI2_Command cmd = { 0 }; - pmi2_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, JOBGETID_CMD, NULL); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - pmi2_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, JOBGETIDRESP_CMD, &rc, &errmsg); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - PMI2U_ERR_CHKANDJUMP1(rc, pmi2_errno, PMI2_ERR_OTHER, "**pmi2_jobgetid", "**pmi2_jobgetid %s", - errmsg ? errmsg : "unknown"); + pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, JOBGETID_CMD, NULL); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, JOBGETIDRESP_CMD, &rc, &errmsg); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_jobgetid", "**pmi2_jobgetid %s", + errmsg ? errmsg : "unknown"); found = getval(cmd.pairs, cmd.nPairs, JOBID_KEY, &jid, &jidlen); - PMI2U_ERR_CHKANDJUMP(found != 1, pmi2_errno, PMI2_ERR_OTHER, "**intern"); + PMIU_ERR_CHKANDJUMP(found != 1, pmi_errno, PMI2_ERR_OTHER, "**intern"); MPL_strncpy(jobid, jid, jobid_size); fn_exit: - PMI2U_Free(cmd.command); + PMIU_Free(cmd.command); freepairs(cmd.pairs, cmd.nPairs); - return pmi2_errno; + return pmi_errno; fn_fail: goto fn_exit; @@ -669,32 +665,32 @@ PMI_API_PUBLIC int PMI2_Job_GetId(char jobid[], int jobid_size) PMI_API_PUBLIC int PMI2_Job_Connect(const char jobid[], PMI2_Connect_comm_t * conn) { - int pmi2_errno = PMI2_SUCCESS; + int pmi_errno = PMI2_SUCCESS; PMI2_Command cmd = { 0 }; int found; int kvscopy; int rc; const char *errmsg; - pmi2_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, JOBCONNECT_CMD, JOBID_KEY, jobid, NULL); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - pmi2_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, JOBCONNECTRESP_CMD, &rc, &errmsg); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - PMI2U_ERR_CHKANDJUMP1(rc, pmi2_errno, PMI2_ERR_OTHER, "**pmi2_jobconnect", - "**pmi2_jobconnect %s", errmsg ? errmsg : "unknown"); + pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, JOBCONNECT_CMD, JOBID_KEY, jobid, NULL); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, JOBCONNECTRESP_CMD, &rc, &errmsg); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_jobconnect", + "**pmi2_jobconnect %s", errmsg ? errmsg : "unknown"); found = getvalbool(cmd.pairs, cmd.nPairs, KVSCOPY_KEY, &kvscopy); - PMI2U_ERR_CHKANDJUMP(found != 1, pmi2_errno, PMI2_ERR_OTHER, "**intern"); + PMIU_ERR_CHKANDJUMP(found != 1, pmi_errno, PMI2_ERR_OTHER, "**intern"); - PMI2U_ERR_CHKANDJUMP(kvscopy, pmi2_errno, PMI2_ERR_OTHER, "**notimpl"); + PMIU_ERR_CHKANDJUMP(kvscopy, pmi_errno, PMI2_ERR_OTHER, "**notimpl"); fn_exit: - PMI2U_Free(cmd.command); + PMIU_Free(cmd.command); freepairs(cmd.pairs, cmd.nPairs); - return pmi2_errno; + return pmi_errno; fn_fail: goto fn_exit; @@ -702,74 +698,74 @@ PMI_API_PUBLIC int PMI2_Job_Connect(const char jobid[], PMI2_Connect_comm_t * co PMI_API_PUBLIC int PMI2_Job_Disconnect(const char jobid[]) { - int pmi2_errno = PMI2_SUCCESS; + int pmi_errno = PMI2_SUCCESS; PMI2_Command cmd = { 0 }; int rc; const char *errmsg; - pmi2_errno = + pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, JOBDISCONNECT_CMD, JOBID_KEY, jobid, NULL); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - pmi2_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, JOBDISCONNECTRESP_CMD, &rc, &errmsg); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - PMI2U_ERR_CHKANDJUMP1(rc, pmi2_errno, PMI2_ERR_OTHER, "**pmi2_jobdisconnect", - "**pmi2_jobdisconnect %s", errmsg ? errmsg : "unknown"); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, JOBDISCONNECTRESP_CMD, &rc, &errmsg); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_jobdisconnect", + "**pmi2_jobdisconnect %s", errmsg ? errmsg : "unknown"); fn_exit: - PMI2U_Free(cmd.command); + PMIU_Free(cmd.command); freepairs(cmd.pairs, cmd.nPairs); - return pmi2_errno; + return pmi_errno; fn_fail: goto fn_exit; } PMI_API_PUBLIC int PMI2_KVS_Put(const char key[], const char value[]) { - int pmi2_errno = PMI2_SUCCESS; + int pmi_errno = PMI2_SUCCESS; PMI2_Command cmd = { 0 }; int rc; const char *errmsg; - pmi2_errno = + pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, KVSPUT_CMD, KEY_KEY, key, VALUE_KEY, value, NULL); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - pmi2_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, KVSPUTRESP_CMD, &rc, &errmsg); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - PMI2U_ERR_CHKANDJUMP1(rc, pmi2_errno, PMI2_ERR_OTHER, "**pmi2_kvsput", "**pmi2_kvsput %s", - errmsg ? errmsg : "unknown"); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, KVSPUTRESP_CMD, &rc, &errmsg); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_kvsput", "**pmi2_kvsput %s", + errmsg ? errmsg : "unknown"); fn_exit: - PMI2U_Free(cmd.command); + PMIU_Free(cmd.command); freepairs(cmd.pairs, cmd.nPairs); - return pmi2_errno; + return pmi_errno; fn_fail: goto fn_exit; } PMI_API_PUBLIC int PMI2_KVS_Fence(void) { - int pmi2_errno = PMI2_SUCCESS; + int pmi_errno = PMI2_SUCCESS; PMI2_Command cmd = { 0 }; int rc; const char *errmsg; - pmi2_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, KVSFENCE_CMD, NULL); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - pmi2_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, KVSFENCERESP_CMD, &rc, &errmsg); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - PMI2U_ERR_CHKANDJUMP1(rc, pmi2_errno, PMI2_ERR_OTHER, "**pmi2_kvsfence", "**pmi2_kvsfence %s", - errmsg ? errmsg : "unknown"); + pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, KVSFENCE_CMD, NULL); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, KVSFENCERESP_CMD, &rc, &errmsg); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_kvsfence", "**pmi2_kvsfence %s", + errmsg ? errmsg : "unknown"); fn_exit: - PMI2U_Free(cmd.command); + PMIU_Free(cmd.command); freepairs(cmd.pairs, cmd.nPairs); - return pmi2_errno; + return pmi_errno; fn_fail: goto fn_exit; } @@ -778,7 +774,7 @@ PMI_API_PUBLIC int PMI2_KVS_Get(const char *jobid, int src_pmi_id, const char key[], char value[], int maxValue, int *valLen) { - int pmi2_errno = PMI2_SUCCESS; + int pmi_errno = PMI2_SUCCESS; int found, keyfound; const char *kvsvalue; int kvsvallen; @@ -790,36 +786,36 @@ PMI_API_PUBLIC MPL_snprintf(src_pmi_id_str, sizeof(src_pmi_id_str), "%d", src_pmi_id); - pmi2_errno = PMIi_InitIfSingleton(); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); + pmi_errno = PMIi_InitIfSingleton(); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); - pmi2_errno = + pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, KVSGET_CMD, JOBID_KEY, jobid, SRCID_KEY, src_pmi_id_str, KEY_KEY, key, NULL); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - pmi2_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, KVSGETRESP_CMD, &rc, &errmsg); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - PMI2U_ERR_CHKANDJUMP1(rc, pmi2_errno, PMI2_ERR_OTHER, "**pmi2_kvsget", "**pmi2_kvsget %s", - errmsg ? errmsg : "unknown"); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, KVSGETRESP_CMD, &rc, &errmsg); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_kvsget", "**pmi2_kvsget %s", + errmsg ? errmsg : "unknown"); found = getvalbool(cmd.pairs, cmd.nPairs, FOUND_KEY, &keyfound); - PMI2U_ERR_CHKANDJUMP(found != 1, pmi2_errno, PMI2_ERR_OTHER, "**intern"); - PMI2U_ERR_CHKANDJUMP(!keyfound, pmi2_errno, PMI2_ERR_OTHER, "**pmi2_kvsget_notfound"); + PMIU_ERR_CHKANDJUMP(found != 1, pmi_errno, PMI2_ERR_OTHER, "**intern"); + PMIU_ERR_CHKANDJUMP(!keyfound, pmi_errno, PMI2_ERR_OTHER, "**pmi2_kvsget_notfound"); found = getval(cmd.pairs, cmd.nPairs, VALUE_KEY, &kvsvalue, &kvsvallen); - PMI2U_ERR_CHKANDJUMP(found != 1, pmi2_errno, PMI2_ERR_OTHER, "**intern"); + PMIU_ERR_CHKANDJUMP(found != 1, pmi_errno, PMI2_ERR_OTHER, "**intern"); ret = MPL_strncpy(value, kvsvalue, maxValue); *valLen = ret ? -kvsvallen : kvsvallen; fn_exit: - PMI2U_Free(cmd.command); + PMIU_Free(cmd.command); freepairs(cmd.pairs, cmd.nPairs); - return pmi2_errno; + return pmi_errno; fn_fail: goto fn_exit; @@ -828,7 +824,7 @@ PMI_API_PUBLIC PMI_API_PUBLIC int PMI2_Info_GetNodeAttr(const char name[], char value[], int valuelen, int *flag, int waitfor) { - int pmi2_errno = PMI2_SUCCESS; + int pmi_errno = PMI2_SUCCESS; int found; const char *kvsvalue; int kvsvallen; @@ -836,34 +832,34 @@ PMI_API_PUBLIC int rc; const char *errmsg; - pmi2_errno = PMIi_InitIfSingleton(); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); + pmi_errno = PMIi_InitIfSingleton(); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); - pmi2_errno = + pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, GETNODEATTR_CMD, KEY_KEY, name, WAIT_KEY, waitfor ? "TRUE" : "FALSE", NULL); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - pmi2_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, GETNODEATTRRESP_CMD, &rc, &errmsg); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - PMI2U_ERR_CHKANDJUMP1(rc, pmi2_errno, PMI2_ERR_OTHER, "**pmi2_getnodeattr", - "**pmi2_getnodeattr %s", errmsg ? errmsg : "unknown"); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, GETNODEATTRRESP_CMD, &rc, &errmsg); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_getnodeattr", + "**pmi2_getnodeattr %s", errmsg ? errmsg : "unknown"); found = getvalbool(cmd.pairs, cmd.nPairs, FOUND_KEY, flag); - PMI2U_ERR_CHKANDJUMP(found != 1, pmi2_errno, PMI2_ERR_OTHER, "**intern"); + PMIU_ERR_CHKANDJUMP(found != 1, pmi_errno, PMI2_ERR_OTHER, "**intern"); if (*flag) { found = getval(cmd.pairs, cmd.nPairs, VALUE_KEY, &kvsvalue, &kvsvallen); - PMI2U_ERR_CHKANDJUMP(found != 1, pmi2_errno, PMI2_ERR_OTHER, "**intern"); + PMIU_ERR_CHKANDJUMP(found != 1, pmi_errno, PMI2_ERR_OTHER, "**intern"); MPL_strncpy(value, kvsvalue, valuelen); } fn_exit: - PMI2U_Free(cmd.command); + PMIU_Free(cmd.command); freepairs(cmd.pairs, cmd.nPairs); - return pmi2_errno; + return pmi_errno; fn_fail: goto fn_exit; } @@ -872,7 +868,7 @@ PMI_API_PUBLIC int PMI2_Info_GetNodeAttrIntArray(const char name[], int array[], int arraylen, int *outlen, int *flag) { - int pmi2_errno = PMI2_SUCCESS; + int pmi_errno = PMI2_SUCCESS; int found; const char *kvsvalue; int kvsvallen; @@ -882,38 +878,38 @@ PMI_API_PUBLIC int i; const char *valptr; - pmi2_errno = PMIi_InitIfSingleton(); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); + pmi_errno = PMIi_InitIfSingleton(); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); - pmi2_errno = + pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, GETNODEATTR_CMD, KEY_KEY, name, WAIT_KEY, "FALSE", NULL); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - pmi2_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, GETNODEATTRRESP_CMD, &rc, &errmsg); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - PMI2U_ERR_CHKANDJUMP1(rc, pmi2_errno, PMI2_ERR_OTHER, "**pmi2_getnodeattr", - "**pmi2_getnodeattr %s", errmsg ? errmsg : "unknown"); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, GETNODEATTRRESP_CMD, &rc, &errmsg); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_getnodeattr", + "**pmi2_getnodeattr %s", errmsg ? errmsg : "unknown"); found = getvalbool(cmd.pairs, cmd.nPairs, FOUND_KEY, flag); - PMI2U_ERR_CHKANDJUMP(found != 1, pmi2_errno, PMI2_ERR_OTHER, "**intern"); + PMIU_ERR_CHKANDJUMP(found != 1, pmi_errno, PMI2_ERR_OTHER, "**intern"); if (*flag) { found = getval(cmd.pairs, cmd.nPairs, VALUE_KEY, &kvsvalue, &kvsvallen); - PMI2U_ERR_CHKANDJUMP(found != 1, pmi2_errno, PMI2_ERR_OTHER, "**intern"); + PMIU_ERR_CHKANDJUMP(found != 1, pmi_errno, PMI2_ERR_OTHER, "**intern"); valptr = kvsvalue; i = 0; rc = sscanf(valptr, "%d", &array[i]); - PMI2U_ERR_CHKANDJUMP1(rc != 1, pmi2_errno, PMI2_ERR_OTHER, "**intern", "**intern %s", - "unable to parse intarray"); + PMIU_ERR_CHKANDJUMP1(rc != 1, pmi_errno, PMI2_ERR_OTHER, "**intern", "**intern %s", + "unable to parse intarray"); ++i; while ((valptr = strchr(valptr, ',')) && i < arraylen) { ++valptr; /* skip over the ',' */ rc = sscanf(valptr, "%d", &array[i]); - PMI2U_ERR_CHKANDJUMP1(rc != 1, pmi2_errno, PMI2_ERR_OTHER, "**intern", "**intern %s", - "unable to parse intarray"); + PMIU_ERR_CHKANDJUMP1(rc != 1, pmi_errno, PMI2_ERR_OTHER, "**intern", "**intern %s", + "unable to parse intarray"); ++i; } @@ -921,42 +917,42 @@ PMI_API_PUBLIC } fn_exit: - PMI2U_Free(cmd.command); + PMIU_Free(cmd.command); freepairs(cmd.pairs, cmd.nPairs); - return pmi2_errno; + return pmi_errno; fn_fail: goto fn_exit; } PMI_API_PUBLIC int PMI2_Info_PutNodeAttr(const char name[], const char value[]) { - int pmi2_errno = PMI2_SUCCESS; + int pmi_errno = PMI2_SUCCESS; PMI2_Command cmd = { 0 }; int rc; const char *errmsg; - pmi2_errno = + pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, PUTNODEATTR_CMD, KEY_KEY, name, VALUE_KEY, value, NULL); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - pmi2_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, PUTNODEATTRRESP_CMD, &rc, &errmsg); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - PMI2U_ERR_CHKANDJUMP1(rc, pmi2_errno, PMI2_ERR_OTHER, "**pmi2_putnodeattr", - "**pmi2_putnodeattr %s", errmsg ? errmsg : "unknown"); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, PUTNODEATTRRESP_CMD, &rc, &errmsg); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_putnodeattr", + "**pmi2_putnodeattr %s", errmsg ? errmsg : "unknown"); fn_exit: - PMI2U_Free(cmd.command); + PMIU_Free(cmd.command); freepairs(cmd.pairs, cmd.nPairs); - return pmi2_errno; + return pmi_errno; fn_fail: goto fn_exit; } PMI_API_PUBLIC int PMI2_Info_GetJobAttr(const char name[], char value[], int valuelen, int *flag) { - int pmi2_errno = PMI2_SUCCESS; + int pmi_errno = PMI2_SUCCESS; int found; const char *kvsvalue; int kvsvallen; @@ -964,33 +960,33 @@ PMI_API_PUBLIC int PMI2_Info_GetJobAttr(const char name[], char value[], int val int rc; const char *errmsg; - pmi2_errno = PMIi_InitIfSingleton(); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); + pmi_errno = PMIi_InitIfSingleton(); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); - pmi2_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, GETJOBATTR_CMD, KEY_KEY, name, NULL); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - pmi2_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, GETJOBATTRRESP_CMD, &rc, &errmsg); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - PMI2U_ERR_CHKANDJUMP1(rc, pmi2_errno, PMI2_ERR_OTHER, "**pmi2_getjobattr", - "**pmi2_getjobattr %s", errmsg ? errmsg : "unknown"); + pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, GETJOBATTR_CMD, KEY_KEY, name, NULL); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, GETJOBATTRRESP_CMD, &rc, &errmsg); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_getjobattr", + "**pmi2_getjobattr %s", errmsg ? errmsg : "unknown"); found = getvalbool(cmd.pairs, cmd.nPairs, FOUND_KEY, flag); - PMI2U_ERR_CHKANDJUMP(found != 1, pmi2_errno, PMI2_ERR_OTHER, "**intern"); + PMIU_ERR_CHKANDJUMP(found != 1, pmi_errno, PMI2_ERR_OTHER, "**intern"); if (*flag) { found = getval(cmd.pairs, cmd.nPairs, VALUE_KEY, &kvsvalue, &kvsvallen); - PMI2U_ERR_CHKANDJUMP(found != 1, pmi2_errno, PMI2_ERR_OTHER, "**intern"); + PMIU_ERR_CHKANDJUMP(found != 1, pmi_errno, PMI2_ERR_OTHER, "**intern"); MPL_strncpy(value, kvsvalue, valuelen); } fn_exit: - PMI2U_Free(cmd.command); + PMIU_Free(cmd.command); freepairs(cmd.pairs, cmd.nPairs); - return pmi2_errno; + return pmi_errno; fn_fail: goto fn_exit; } @@ -999,7 +995,7 @@ PMI_API_PUBLIC int PMI2_Info_GetJobAttrIntArray(const char name[], int array[], int arraylen, int *outlen, int *flag) { - int pmi2_errno = PMI2_SUCCESS; + int pmi_errno = PMI2_SUCCESS; int found; const char *kvsvalue; int kvsvallen; @@ -1009,36 +1005,36 @@ PMI_API_PUBLIC int i; const char *valptr; - pmi2_errno = PMIi_InitIfSingleton(); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); + pmi_errno = PMIi_InitIfSingleton(); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); - pmi2_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, GETJOBATTR_CMD, KEY_KEY, name, NULL); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - pmi2_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, GETJOBATTRRESP_CMD, &rc, &errmsg); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - PMI2U_ERR_CHKANDJUMP1(rc, pmi2_errno, PMI2_ERR_OTHER, "**pmi2_getjobattr", - "**pmi2_getjobattr %s", errmsg ? errmsg : "unknown"); + pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, GETJOBATTR_CMD, KEY_KEY, name, NULL); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, GETJOBATTRRESP_CMD, &rc, &errmsg); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_getjobattr", + "**pmi2_getjobattr %s", errmsg ? errmsg : "unknown"); found = getvalbool(cmd.pairs, cmd.nPairs, FOUND_KEY, flag); - PMI2U_ERR_CHKANDJUMP(found != 1, pmi2_errno, PMI2_ERR_OTHER, "**intern"); + PMIU_ERR_CHKANDJUMP(found != 1, pmi_errno, PMI2_ERR_OTHER, "**intern"); if (*flag) { found = getval(cmd.pairs, cmd.nPairs, VALUE_KEY, &kvsvalue, &kvsvallen); - PMI2U_ERR_CHKANDJUMP(found != 1, pmi2_errno, PMI2_ERR_OTHER, "**intern"); + PMIU_ERR_CHKANDJUMP(found != 1, pmi_errno, PMI2_ERR_OTHER, "**intern"); valptr = kvsvalue; i = 0; rc = sscanf(valptr, "%d", &array[i]); - PMI2U_ERR_CHKANDJUMP1(rc != 1, pmi2_errno, PMI2_ERR_OTHER, "**intern", "**intern %s", - "unable to parse intarray"); + PMIU_ERR_CHKANDJUMP1(rc != 1, pmi_errno, PMI2_ERR_OTHER, "**intern", "**intern %s", + "unable to parse intarray"); ++i; while ((valptr = strchr(valptr, ',')) && i < arraylen) { ++valptr; /* skip over the ',' */ rc = sscanf(valptr, "%d", &array[i]); - PMI2U_ERR_CHKANDJUMP1(rc != 1, pmi2_errno, PMI2_ERR_OTHER, "**intern", "**intern %s", - "unable to parse intarray"); + PMIU_ERR_CHKANDJUMP1(rc != 1, pmi_errno, PMI2_ERR_OTHER, "**intern", "**intern %s", + "unable to parse intarray"); ++i; } @@ -1046,9 +1042,9 @@ PMI_API_PUBLIC } fn_exit: - PMI2U_Free(cmd.command); + PMIU_Free(cmd.command); freepairs(cmd.pairs, cmd.nPairs); - return pmi2_errno; + return pmi_errno; fn_fail: goto fn_exit; } @@ -1057,28 +1053,28 @@ PMI_API_PUBLIC int PMI2_Nameserv_publish(const char service_name[], const PMI2_keyval_t * info_ptr, const char port[]) { - int pmi2_errno = PMI2_SUCCESS; + int pmi_errno = PMI2_SUCCESS; PMI2_Command cmd = { 0 }; int rc; const char *errmsg; /* ignoring infokey functionality for now */ - pmi2_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, NAMEPUBLISH_CMD, - NAME_KEY, service_name, PORT_KEY, port, - INFOKEYCOUNT_KEY, "0", NULL); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - pmi2_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, NAMEPUBLISHRESP_CMD, &rc, &errmsg); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - PMI2U_ERR_CHKANDJUMP1(rc, pmi2_errno, PMI2_ERR_OTHER, "**pmi2_nameservpublish", - "**pmi2_nameservpublish %s", errmsg ? errmsg : "unknown"); + pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, NAMEPUBLISH_CMD, + NAME_KEY, service_name, PORT_KEY, port, + INFOKEYCOUNT_KEY, "0", NULL); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, NAMEPUBLISHRESP_CMD, &rc, &errmsg); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_nameservpublish", + "**pmi2_nameservpublish %s", errmsg ? errmsg : "unknown"); fn_exit: - PMI2U_Free(cmd.command); + PMIU_Free(cmd.command); freepairs(cmd.pairs, cmd.nPairs); - return pmi2_errno; + return pmi_errno; fn_fail: goto fn_exit; } @@ -1088,7 +1084,7 @@ PMI_API_PUBLIC int PMI2_Nameserv_lookup(const char service_name[], const PMI2_keyval_t * info_ptr, char port[], int portLen) { - int pmi2_errno = PMI2_SUCCESS; + int pmi_errno = PMI2_SUCCESS; int found; int rc; PMI2_Command cmd = { 0 }; @@ -1097,25 +1093,25 @@ PMI_API_PUBLIC const char *found_port; /* ignoring infos for now */ - pmi2_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, NAMELOOKUP_CMD, - NAME_KEY, service_name, INFOKEYCOUNT_KEY, "0", NULL); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - pmi2_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, NAMELOOKUPRESP_CMD, &rc, &errmsg); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - PMI2U_ERR_CHKANDJUMP1(rc, pmi2_errno, PMI2_ERR_OTHER, "**pmi2_nameservlookup", - "**pmi2_nameservlookup %s", errmsg ? errmsg : "unknown"); + pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, NAMELOOKUP_CMD, + NAME_KEY, service_name, INFOKEYCOUNT_KEY, "0", NULL); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, NAMELOOKUPRESP_CMD, &rc, &errmsg); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_nameservlookup", + "**pmi2_nameservlookup %s", errmsg ? errmsg : "unknown"); found = getval(cmd.pairs, cmd.nPairs, PORT_KEY, &found_port, &plen); - PMI2U_ERR_CHKANDJUMP1(!found, pmi2_errno, PMI2_ERR_OTHER, "**pmi2_nameservlookup", - "**pmi2_nameservlookup %s", "not found"); + PMIU_ERR_CHKANDJUMP1(!found, pmi_errno, PMI2_ERR_OTHER, "**pmi2_nameservlookup", + "**pmi2_nameservlookup %s", "not found"); MPL_strncpy(port, found_port, portLen); fn_exit: - PMI2U_Free(cmd.command); + PMIU_Free(cmd.command); freepairs(cmd.pairs, cmd.nPairs); - return pmi2_errno; + return pmi_errno; fn_fail: goto fn_exit; } @@ -1123,25 +1119,25 @@ PMI_API_PUBLIC PMI_API_PUBLIC int PMI2_Nameserv_unpublish(const char service_name[], const PMI2_keyval_t * info_ptr) { - int pmi2_errno = PMI2_SUCCESS; + int pmi_errno = PMI2_SUCCESS; int rc; PMI2_Command cmd = { 0 }; const char *errmsg; - pmi2_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, NAMEUNPUBLISH_CMD, - NAME_KEY, service_name, INFOKEYCOUNT_KEY, "0", NULL); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - pmi2_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, NAMEUNPUBLISHRESP_CMD, &rc, &errmsg); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); - PMI2U_ERR_CHKANDJUMP1(rc, pmi2_errno, PMI2_ERR_OTHER, "**pmi2_nameservunpublish", - "**pmi2_nameservunpublish %s", errmsg ? errmsg : "unknown"); + pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, NAMEUNPUBLISH_CMD, + NAME_KEY, service_name, INFOKEYCOUNT_KEY, "0", NULL); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, NAMEUNPUBLISHRESP_CMD, &rc, &errmsg); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_nameservunpublish", + "**pmi2_nameservunpublish %s", errmsg ? errmsg : "unknown"); fn_exit: - PMI2U_Free(cmd.command); + PMIU_Free(cmd.command); freepairs(cmd.pairs, cmd.nPairs); - return pmi2_errno; + return pmi_errno; fn_fail: goto fn_exit; } @@ -1175,11 +1171,11 @@ static void freepairs(PMI2_Keyvalpair ** pairs, int npairs) for (i = 0; i < npairs; ++i) if (pairs[i]->isCopy) { /* FIXME casts are here to suppress legitimate constness warnings */ - PMI2U_Free((void *) pairs[i]->key); - PMI2U_Free((void *) pairs[i]->value); - PMI2U_Free(pairs[i]); + PMIU_Free((void *) pairs[i]->key); + PMIU_Free((void *) pairs[i]->value); + PMIU_Free(pairs[i]); } - PMI2U_Free(pairs); + PMIU_Free(pairs); } /* getval & friends -- these functions search the pairs list for a @@ -1266,9 +1262,9 @@ static int getvalbool(PMI2_Keyvalpair * const pairs[], int npairs, const char *k return found; if (strlen("TRUE") == vallen && !strncmp(value, "TRUE", vallen)) - *val = TRUE; + *val = PMIU_TRUE; else if (strlen("FALSE") == vallen && !strncmp(value, "FALSE", vallen)) - *val = FALSE; + *val = PMIU_FALSE; else return -1; @@ -1291,7 +1287,7 @@ static int getvalbool(PMI2_Keyvalpair * const pairs[], int npairs, const char *k */ static int parse_keyval(char **cmdptr, int *len, char **key, char **val, int *vallen) { - int pmi2_errno = PMI2_SUCCESS; + int pmi_errno = PMI2_SUCCESS; char *c = *cmdptr; char *d; @@ -1302,8 +1298,8 @@ static int parse_keyval(char **cmdptr, int *len, char **key, char **val, int *va --*len; ++c; } - PMI2U_ERR_CHKANDJUMP(*len == 0, pmi2_errno, PMI2_ERR_OTHER, "**bad_keyval"); - PMI2U_ERR_CHKANDJUMP(c - *key > PMI2_MAX_KEYLEN, pmi2_errno, PMI2_ERR_OTHER, "**bad_keyval"); + PMIU_ERR_CHKANDJUMP(*len == 0, pmi_errno, PMI2_ERR_OTHER, "**bad_keyval"); + PMIU_ERR_CHKANDJUMP(c - *key > PMI2_MAX_KEYLEN, pmi_errno, PMI2_ERR_OTHER, "**bad_keyval"); *c = '\0'; /* terminate the key string */ /* skip over the '=' */ @@ -1324,45 +1320,45 @@ static int parse_keyval(char **cmdptr, int *len, char **key, char **val, int *va --*len; *(d++) = *(c++); } - PMI2U_ERR_CHKANDJUMP(*len == 0, pmi2_errno, PMI2_ERR_OTHER, "**bad_keyval"); - PMI2U_ERR_CHKANDJUMP(d - *val > PMI2_MAX_VALLEN, pmi2_errno, PMI2_ERR_OTHER, "**bad_keyval"); + PMIU_ERR_CHKANDJUMP(*len == 0, pmi_errno, PMI2_ERR_OTHER, "**bad_keyval"); + PMIU_ERR_CHKANDJUMP(d - *val > PMI2_MAX_VALLEN, pmi_errno, PMI2_ERR_OTHER, "**bad_keyval"); *vallen = d - *val; *cmdptr = c + 1; /* skip over the ';' */ --*len; fn_exit: - return pmi2_errno; + return pmi_errno; fn_fail: goto fn_exit; } static int create_keyval(PMI2_Keyvalpair ** kv, const char *key, const char *val, int vallen) { - int pmi2_errno = PMI2_SUCCESS; + int pmi_errno = PMI2_SUCCESS; char *key_p = NULL; char *value_p = NULL; - PMI2U_CHK_MALLOC(*kv, PMI2_Keyvalpair *, sizeof(PMI2_Keyvalpair), pmi2_errno, "pair"); + PMIU_CHK_MALLOC(*kv, PMI2_Keyvalpair *, sizeof(PMI2_Keyvalpair), pmi_errno, "pair"); - PMI2U_CHK_MALLOC(key_p, char *, strlen(key) + 1, pmi2_errno, "key"); + PMIU_CHK_MALLOC(key_p, char *, strlen(key) + 1, pmi_errno, "key"); MPL_strncpy(key_p, key, PMI2_MAX_KEYLEN + 1); - PMI2U_CHK_MALLOC(value_p, char *, vallen + 1, pmi2_errno, "value"); - PMI2U_Memcpy(value_p, val, vallen); + PMIU_CHK_MALLOC(value_p, char *, vallen + 1, pmi_errno, "value"); + PMIU_Memcpy(value_p, val, vallen); value_p[vallen] = '\0'; (*kv)->key = key_p; (*kv)->value = value_p; (*kv)->valueLen = vallen; - (*kv)->isCopy = TRUE; + (*kv)->isCopy = PMIU_TRUE; fn_exit: - return pmi2_errno; + return pmi_errno; fn_fail: - PMI2U_Free(*kv); - PMI2U_Free(key_p); - PMI2U_Free(value_p); + PMIU_Free(*kv); + PMIU_Free(key_p); + PMIU_Free(value_p); goto fn_exit; } @@ -1371,7 +1367,7 @@ static int create_keyval(PMI2_Keyvalpair ** kv, const char *key, const char *val We may want to share these routines with the PMI version 2 server */ int PMIi_ReadCommand(int fd, PMI2_Command * cmd) { - int pmi2_errno = PMI2_SUCCESS, err; + int pmi_errno = PMI2_SUCCESS, err; char cmd_len_str[PMII_COMMANDLEN_SIZE + 1]; int cmd_len, remaining_len, vallen = 0; char *c, *cmd_buf = NULL; @@ -1399,7 +1395,7 @@ int PMIi_ReadCommand(int fd, PMI2_Command * cmd) goto fn_exit; } - blocked = TRUE; + blocked = PMIU_TRUE; MPL_thread_mutex_unlock(&mutex, &err); } @@ -1412,8 +1408,8 @@ int PMIi_ReadCommand(int fd, PMI2_Command * cmd) nbytes = read(fd, &cmd_len_str[offset], PMII_COMMANDLEN_SIZE - offset); } while (nbytes == -1 && errno == EINTR); - PMI2U_ERR_CHKANDJUMP1(nbytes <= 0, pmi2_errno, PMI2_ERR_OTHER, "**read", "**read %s", - strerror(errno)); + PMIU_ERR_CHKANDJUMP1(nbytes <= 0, pmi_errno, PMI2_ERR_OTHER, "**read", "**read %s", + strerror(errno)); offset += nbytes; } @@ -1421,9 +1417,9 @@ int PMIi_ReadCommand(int fd, PMI2_Command * cmd) cmd_len = atoi(cmd_len_str); - cmd_buf = PMI2U_Malloc(cmd_len + 1); + cmd_buf = PMIU_Malloc(cmd_len + 1); if (!cmd_buf) { - PMI2U_CHKMEM_SETERR(pmi2_errno, cmd_len + 1, "cmd_buf"); + PMIU_CHKMEM_SETERR(pmi_errno, cmd_len + 1, "cmd_buf"); goto fn_exit; } @@ -1436,8 +1432,8 @@ int PMIi_ReadCommand(int fd, PMI2_Command * cmd) nbytes = read(fd, &cmd_buf[offset], cmd_len - offset); } while (nbytes == -1 && errno == EINTR); - PMI2U_ERR_CHKANDJUMP1(nbytes <= 0, pmi2_errno, PMI2_ERR_OTHER, "**read", "**read %s", - strerror(errno)); + PMIU_ERR_CHKANDJUMP1(nbytes <= 0, pmi_errno, PMI2_ERR_OTHER, "**read", "**read %s", + strerror(errno)); offset += nbytes; } @@ -1467,26 +1463,26 @@ int PMIi_ReadCommand(int fd, PMI2_Command * cmd) c = cmd_buf; remaining_len = cmd_len; - pmi2_errno = parse_keyval(&c, &remaining_len, &key, &val, &vallen); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); + pmi_errno = parse_keyval(&c, &remaining_len, &key, &val, &vallen); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); - PMI2U_ERR_CHKANDJUMP(strncmp(key, "cmd", PMI2_MAX_KEYLEN) != 0, pmi2_errno, PMI2_ERR_OTHER, - "**bad_cmd"); + PMIU_ERR_CHKANDJUMP(strncmp(key, "cmd", PMI2_MAX_KEYLEN) != 0, pmi_errno, PMI2_ERR_OTHER, + "**bad_cmd"); - command = PMI2U_Malloc(vallen + 1); + command = PMIU_Malloc(vallen + 1); if (!command) { - PMI2U_CHKMEM_SETERR(pmi2_errno, vallen + 1, "command"); + PMIU_CHKMEM_SETERR(pmi_errno, vallen + 1, "command"); goto fn_exit; } - PMI2U_Memcpy(command, val, vallen); + PMIU_Memcpy(command, val, vallen); val[vallen] = '\0'; nPairs = num_pairs - 1; /* num_pairs-1 because the first pair is the command */ - pairs = PMI2U_Malloc(sizeof(PMI2_Keyvalpair *) * nPairs); + pairs = PMIU_Malloc(sizeof(PMI2_Keyvalpair *) * nPairs); if (!pairs) { - PMI2U_CHKMEM_SETERR(pmi2_errno, sizeof(PMI2_Keyvalpair *) * nPairs, "pairs"); + PMIU_CHKMEM_SETERR(pmi_errno, sizeof(PMI2_Keyvalpair *) * nPairs, "pairs"); goto fn_exit; } @@ -1494,13 +1490,13 @@ int PMIi_ReadCommand(int fd, PMI2_Command * cmd) while (remaining_len) { PMI2_Keyvalpair *pair; - pmi2_errno = parse_keyval(&c, &remaining_len, &key, &val, &vallen); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); + pmi_errno = parse_keyval(&c, &remaining_len, &key, &val, &vallen); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); - pmi2_errno = create_keyval(&pair, key, val, vallen); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); + pmi_errno = create_keyval(&pair, key, val, vallen); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); pairs[pair_index] = pair; ++pair_index; @@ -1520,22 +1516,22 @@ int PMIi_ReadCommand(int fd, PMI2_Command * cmd) target_cmd->command = command; target_cmd->nPairs = nPairs; target_cmd->pairs = pairs; - target_cmd->complete = TRUE; + target_cmd->complete = PMIU_TRUE; - PMI2U_Free(cmd_buf); + PMIU_Free(cmd_buf); } while (!cmd->complete); if (PMI2_is_threaded) { MPL_thread_mutex_lock(&mutex, &err, MPL_THREAD_PRIO_HIGH); - blocked = FALSE; + blocked = PMIU_FALSE; MPL_thread_cond_broadcast(&cond, &err); MPL_thread_mutex_unlock(&mutex, &err); } fn_exit: - return pmi2_errno; + return pmi_errno; fn_fail: - PMI2U_Free(cmd_buf); + PMIU_Free(cmd_buf); goto fn_exit; } @@ -1543,29 +1539,29 @@ int PMIi_ReadCommand(int fd, PMI2_Command * cmd) * expected command string exp, and parses the return code */ int PMIi_ReadCommandExp(int fd, PMI2_Command * cmd, const char *exp, int *rc, const char **errmsg) { - int pmi2_errno = PMI2_SUCCESS; + int pmi_errno = PMI2_SUCCESS; int found; int msglen; - pmi2_errno = PMIi_ReadCommand(fd, cmd); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); + pmi_errno = PMIi_ReadCommand(fd, cmd); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); - PMI2U_ERR_CHKANDJUMP(strncmp(cmd->command, exp, strlen(exp)) != 0, pmi2_errno, PMI2_ERR_OTHER, - "**bad_cmd"); + PMIU_ERR_CHKANDJUMP(strncmp(cmd->command, exp, strlen(exp)) != 0, pmi_errno, PMI2_ERR_OTHER, + "**bad_cmd"); found = getvalint(cmd->pairs, cmd->nPairs, RC_KEY, rc); - PMI2U_ERR_CHKANDJUMP(found != 1, pmi2_errno, PMI2_ERR_OTHER, "**intern"); + PMIU_ERR_CHKANDJUMP(found != 1, pmi_errno, PMI2_ERR_OTHER, "**intern"); found = getval(cmd->pairs, cmd->nPairs, ERRMSG_KEY, errmsg, &msglen); - PMI2U_ERR_CHKANDJUMP(found == -1, pmi2_errno, PMI2_ERR_OTHER, "**intern"); + PMIU_ERR_CHKANDJUMP(found == -1, pmi_errno, PMI2_ERR_OTHER, "**intern"); if (!found) *errmsg = NULL; fn_exit: - return pmi2_errno; + return pmi_errno; fn_fail: goto fn_exit; @@ -1575,7 +1571,7 @@ int PMIi_ReadCommandExp(int fd, PMI2_Command * cmd, const char *exp, int *rc, co int PMIi_WriteSimpleCommand(int fd, PMI2_Command * resp, const char cmd[], PMI2_Keyvalpair * pairs[], int npairs) { - int pmi2_errno = PMI2_SUCCESS, err; + int pmi_errno = PMI2_SUCCESS, err; char cmdbuf[PMII_MAX_COMMAND_LEN]; char cmdlenbuf[PMII_COMMANDLEN_SIZE + 1]; char *c = cmdbuf; @@ -1591,36 +1587,35 @@ int PMIi_WriteSimpleCommand(int fd, PMI2_Command * resp, const char cmd[], memset(c, ' ', PMII_COMMANDLEN_SIZE); c += PMII_COMMANDLEN_SIZE; - PMI2U_ERR_CHKANDJUMP(strlen(cmd) > PMI2_MAX_VALLEN, pmi2_errno, PMI2_ERR_OTHER, - "**cmd_too_long"); + PMIU_ERR_CHKANDJUMP(strlen(cmd) > PMI2_MAX_VALLEN, pmi_errno, PMI2_ERR_OTHER, "**cmd_too_long"); ret = MPL_snprintf(c, remaining_len, "cmd=%s;", cmd); - PMI2U_ERR_CHKANDJUMP1(ret >= remaining_len, pmi2_errno, PMI2_ERR_OTHER, "**intern", - "**intern %s", "Ran out of room for command"); + PMIU_ERR_CHKANDJUMP1(ret >= remaining_len, pmi_errno, PMI2_ERR_OTHER, "**intern", + "**intern %s", "Ran out of room for command"); c += ret; remaining_len -= ret; if (PMI2_is_threaded && resp) { ret = MPL_snprintf(c, remaining_len, "thrid=%p;", resp); - PMI2U_ERR_CHKANDJUMP1(ret >= remaining_len, pmi2_errno, PMI2_ERR_OTHER, "**intern", - "**intern %s", "Ran out of room for command"); + PMIU_ERR_CHKANDJUMP1(ret >= remaining_len, pmi_errno, PMI2_ERR_OTHER, "**intern", + "**intern %s", "Ran out of room for command"); c += ret; remaining_len -= ret; } for (pair_index = 0; pair_index < npairs; ++pair_index) { /* write key= */ - PMI2U_ERR_CHKANDJUMP(strlen(pairs[pair_index]->key) > PMI2_MAX_KEYLEN, pmi2_errno, - PMI2_ERR_OTHER, "**key_too_long"); + PMIU_ERR_CHKANDJUMP(strlen(pairs[pair_index]->key) > PMI2_MAX_KEYLEN, pmi_errno, + PMI2_ERR_OTHER, "**key_too_long"); ret = MPL_snprintf(c, remaining_len, "%s=", pairs[pair_index]->key); - PMI2U_ERR_CHKANDJUMP1(ret >= remaining_len, pmi2_errno, PMI2_ERR_OTHER, "**intern", - "**intern %s", "Ran out of room for command"); + PMIU_ERR_CHKANDJUMP1(ret >= remaining_len, pmi_errno, PMI2_ERR_OTHER, "**intern", + "**intern %s", "Ran out of room for command"); c += ret; remaining_len -= ret; /* write value and escape ;'s as ;; */ - PMI2U_ERR_CHKANDJUMP(pairs[pair_index]->valueLen > PMI2_MAX_VALLEN, pmi2_errno, - PMI2_ERR_OTHER, "**val_too_long"); + PMIU_ERR_CHKANDJUMP(pairs[pair_index]->valueLen > PMI2_MAX_VALLEN, pmi_errno, + PMI2_ERR_OTHER, "**val_too_long"); for (i = 0; i < pairs[pair_index]->valueLen; ++i) { if (pairs[pair_index]->value[i] == ';') { *c = ';'; @@ -1641,10 +1636,10 @@ int PMIi_WriteSimpleCommand(int fd, PMI2_Command * resp, const char cmd[], /* prepend the buffer length stripping off the trailing '\0' */ cmdlen = PMII_MAX_COMMAND_LEN - remaining_len; ret = MPL_snprintf(cmdlenbuf, sizeof(cmdlenbuf), "%d", cmdlen); - PMI2U_ERR_CHKANDJUMP1(ret >= PMII_COMMANDLEN_SIZE, pmi2_errno, PMI2_ERR_OTHER, "**intern", - "**intern %s", "Command length won't fit in length buffer"); + PMIU_ERR_CHKANDJUMP1(ret >= PMII_COMMANDLEN_SIZE, pmi_errno, PMI2_ERR_OTHER, "**intern", + "**intern %s", "Command length won't fit in length buffer"); - PMI2U_Memcpy(cmdbuf, cmdlenbuf, ret); + PMIU_Memcpy(cmdbuf, cmdlenbuf, ret); cmdbuf[cmdlen + PMII_COMMANDLEN_SIZE] = '\0'; /* silence valgrind warnings in printf_d */ printf_d("PMI sending: %s\n", cmdbuf); @@ -1656,7 +1651,7 @@ int PMIi_WriteSimpleCommand(int fd, PMI2_Command * resp, const char cmd[], while (blocked) MPL_thread_cond_wait(&cond, &mutex, &err); - blocked = TRUE; + blocked = PMIU_TRUE; MPL_thread_mutex_unlock(&mutex, &err); } @@ -1669,28 +1664,28 @@ int PMIi_WriteSimpleCommand(int fd, PMI2_Command * resp, const char cmd[], nbytes = write(fd, &cmdbuf[offset], cmdlen + PMII_COMMANDLEN_SIZE - offset); } while (nbytes == -1 && errno == EINTR); - PMI2U_ERR_CHKANDJUMP1(nbytes <= 0, pmi2_errno, PMI2_ERR_OTHER, "**write", "**write %s", - strerror(errno)); + PMIU_ERR_CHKANDJUMP1(nbytes <= 0, pmi_errno, PMI2_ERR_OTHER, "**write", "**write %s", + strerror(errno)); offset += nbytes; } while (offset < cmdlen + PMII_COMMANDLEN_SIZE); if (PMI2_is_threaded) { MPL_thread_mutex_lock(&mutex, &err, MPL_THREAD_PRIO_HIGH); - blocked = FALSE; + blocked = PMIU_FALSE; MPL_thread_cond_broadcast(&cond, &err); MPL_thread_mutex_unlock(&mutex, &err); } fn_exit: - return pmi2_errno; + return pmi_errno; fn_fail: goto fn_exit; } int PMIi_WriteSimpleCommandStr(int fd, PMI2_Command * resp, const char cmd[], ...) { - int pmi2_errno = PMI2_SUCCESS; + int pmi_errno = PMI2_SUCCESS; va_list ap; PMI2_Keyvalpair *pairs = NULL; PMI2_Keyvalpair **pairs_p = NULL; @@ -1708,10 +1703,9 @@ int PMIi_WriteSimpleCommandStr(int fd, PMI2_Command * resp, const char cmd[], .. } va_end(ap); - PMI2U_CHK_MALLOC(pairs, PMI2_Keyvalpair *, sizeof(PMI2_Keyvalpair) * npairs, pmi2_errno, - "pairs"); - PMI2U_CHK_MALLOC(pairs_p, PMI2_Keyvalpair **, sizeof(PMI2_Keyvalpair *) * npairs, - pmi2_errno, "pairs_p"); + PMIU_CHK_MALLOC(pairs, PMI2_Keyvalpair *, sizeof(PMI2_Keyvalpair) * npairs, pmi_errno, "pairs"); + PMIU_CHK_MALLOC(pairs_p, PMI2_Keyvalpair **, sizeof(PMI2_Keyvalpair *) * npairs, + pmi_errno, "pairs_p"); i = 0; va_start(ap, cmd); @@ -1724,19 +1718,19 @@ int PMIi_WriteSimpleCommandStr(int fd, PMI2_Command * resp, const char cmd[], .. pairs[i].valueLen = strlen(val); else pairs[i].valueLen = 0; - pairs[i].isCopy = FALSE; + pairs[i].isCopy = PMIU_FALSE; ++i; } va_end(ap); - pmi2_errno = PMIi_WriteSimpleCommand(fd, resp, cmd, pairs_p, npairs); - if (pmi2_errno) - PMI2U_ERR_POP(pmi2_errno); + pmi_errno = PMIi_WriteSimpleCommand(fd, resp, cmd, pairs_p, npairs); + if (pmi_errno) + PMIU_ERR_POP(pmi_errno); fn_exit: - PMI2U_Free(pairs); - PMI2U_Free(pairs_p); - return pmi2_errno; + PMIU_Free(pairs); + PMIU_Free(pairs_p); + return pmi_errno; fn_fail: goto fn_exit; } @@ -1887,7 +1881,7 @@ static int PMIi_InitIfSingleton(void) */ static int getPMIFD(void) { - int pmi2_errno = PMI2_SUCCESS; + int pmi_errno = PMI2_SUCCESS; char *p; /* Set the default */ @@ -1916,8 +1910,8 @@ static int getPMIFD(void) } *ph = 0; - PMI2U_ERR_CHKANDJUMP1(*pn != ':', pmi2_errno, PMI2_ERR_OTHER, "**pmi2_port", - "**pmi2_port %s", p); + PMIU_ERR_CHKANDJUMP1(*pn != ':', pmi_errno, PMI2_ERR_OTHER, "**pmi2_port", + "**pmi2_port %s", p); portnum = atoi(pn + 1); /* FIXME: Check for valid integer after : */ @@ -1925,14 +1919,14 @@ static int getPMIFD(void) * the process manager. The handshake below is used * to setup the initial values */ PMI2_fd = PMII_Connect_to_pm(hostname, portnum); - PMI2U_ERR_CHKANDJUMP2(PMI2_fd < 0, pmi2_errno, PMI2_ERR_OTHER, "**connect_to_pm", - "**connect_to_pm %s %d", hostname, portnum); + PMIU_ERR_CHKANDJUMP2(PMI2_fd < 0, pmi_errno, PMI2_ERR_OTHER, "**connect_to_pm", + "**connect_to_pm %s %d", hostname, portnum); } /* OK to return success for singleton init */ fn_exit: - return pmi2_errno; + return pmi_errno; fn_fail: goto fn_exit; } From 3f8d070adeed8f6e7fa8ff2953c6a1474073a466 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 9 Mar 2022 08:57:54 -0600 Subject: [PATCH 583/607] pmi: move common header inclusions into pmi_util.h Common util matter should be in pmi_util.h. --- src/pmi/src/pmi_util.h | 22 +++++++++++++++++++++- src/pmi/src/pmi_v1.c | 28 ++-------------------------- src/pmi/src/pmi_v2.c | 23 +---------------------- 3 files changed, 24 insertions(+), 49 deletions(-) diff --git a/src/pmi/src/pmi_util.h b/src/pmi/src/pmi_util.h index d9a82ec55d0..57c84f6cd3a 100644 --- a/src/pmi/src/pmi_util.h +++ b/src/pmi/src/pmi_util.h @@ -10,7 +10,20 @@ #define PMIU_MAXLINE 1024 #define PMIU_IDSIZE 32 -/* we don't have access to MPIR_Assert and friends here in the PMI code */ +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_STDLIB_H +#include +#endif +#ifdef HAVE_STRING_H +#include +#endif +#ifdef HAVE_STRINGS_H +#include +#endif + #if defined(HAVE_ASSERT_H) #include #define PMIU_Assert(expr) assert(expr) @@ -22,6 +35,13 @@ #include #endif /* HAVE_ARPA_INET_H */ +#if defined(HAVE_SYS_SOCKET_H) +#include +#endif + +#ifndef MAXHOSTNAME +#define MAXHOSTNAME 256 +#endif /* prototypes for PMIU routines */ void PMIU_Set_rank(int PMI_rank); diff --git a/src/pmi/src/pmi_v1.c b/src/pmi/src/pmi_v1.c index fd0bd3d6c8f..88f08064ab8 100644 --- a/src/pmi/src/pmi_v1.c +++ b/src/pmi/src/pmi_v1.c @@ -18,38 +18,14 @@ #include "pmi_config.h" -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_STRINGS_H -#include -#endif -#ifdef USE_PMI_PORT -#ifndef MAXHOSTNAME -#define MAXHOSTNAME 256 -#endif -#endif -/* This should be moved to pmiu for shutdown */ -#if defined(HAVE_SYS_SOCKET_H) -#include -#endif - +#include "pmi_util.h" #include "mpl.h" /* Get ATTRIBUTE, some base functions */ +#include "pmi.h" /* Temporary debug definitions */ /* #define DBG_PRINTF(args) printf args ; fflush(stdout) */ #define DBG_PRINTF(args) -#include "pmi.h" -#include "pmi_util.h" - #ifdef HAVE_MPI_H #include "mpi.h" /* to get MPI_MAX_PORT_NAME */ #else diff --git a/src/pmi/src/pmi_v2.c b/src/pmi/src/pmi_v2.c index 86d8eddcd0d..2577456e94e 100644 --- a/src/pmi/src/pmi_v2.c +++ b/src/pmi/src/pmi_v2.c @@ -6,29 +6,8 @@ #include "pmi_config.h" #include "pmi_util.h" -#include "pmi2.h" #include "mpl.h" - -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_STRINGS_H -#include -#endif -#if defined(HAVE_SYS_SOCKET_H) -#include -#endif - -#ifndef MAXHOSTNAME -#define MAXHOSTNAME 256 -#endif +#include "pmi2.h" #define PMII_EXIT_CODE -1 From 0b2b219054df7205b65fc0978e9e8656fbaa741e Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 9 Mar 2022 09:00:24 -0600 Subject: [PATCH 584/607] pmi: remove DBG_PRINTF DBG_PRINTF is defined as empty thus not being used. Remove for now. In any case, we can use printf_d. --- src/pmi/src/pmi_v1.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/pmi/src/pmi_v1.c b/src/pmi/src/pmi_v1.c index 88f08064ab8..5b3023f874d 100644 --- a/src/pmi/src/pmi_v1.c +++ b/src/pmi/src/pmi_v1.c @@ -22,10 +22,6 @@ #include "mpl.h" /* Get ATTRIBUTE, some base functions */ #include "pmi.h" -/* Temporary debug definitions */ -/* #define DBG_PRINTF(args) printf args ; fflush(stdout) */ -#define DBG_PRINTF(args) - #ifdef HAVE_MPI_H #include "mpi.h" /* to get MPI_MAX_PORT_NAME */ #else @@ -1013,11 +1009,6 @@ static int PMII_Set_from_port(int fd, int id) PMIU_getval("debug", cmd, PMIU_MAXLINE); PMI_debug = atoi(cmd); - if (PMI_debug) { - DBG_PRINTF(("end of handshake, rank = %d, size = %d\n", PMI_rank, PMI_size)); - DBG_PRINTF(("Completed init\n")); - } - return PMI_SUCCESS; } @@ -1291,9 +1282,6 @@ static int getPMIFD(int *notset) } *ph = 0; - if (PMI_debug) { - DBG_PRINTF(("Connecting to %s\n", p)); - } if (*pn == ':') { portnum = atoi(pn + 1); /* FIXME: Check for valid integer after : */ From 451efa9c4f7780efde86ba29258126338c935525 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 9 Mar 2022 13:53:39 -0600 Subject: [PATCH 585/607] pmi: cleanup error macros PMIU_ERR_POP is setting pmi_errno = pmi_errno. Instead, make it similar to HYDY_ERR_POP and MPIR_ERR_CHECK. PMIU_ERR_SETANDJUMP ignore the err parameter and sets pmi_errno. It should set err instead. The PMI code does not use the short message and long message systems like mpich does. The extra parameter for short message is not used. This patch removes it. Do not assume PMI_ERR_NOMEM in the util macros since it will be used in either PMI1 or PMI2. --- src/pmi/src/pmi_util.h | 82 +++++++------- src/pmi/src/pmi_v2.c | 240 +++++++++++++++++------------------------ 2 files changed, 143 insertions(+), 179 deletions(-) diff --git a/src/pmi/src/pmi_util.h b/src/pmi/src/pmi_util.h index 57c84f6cd3a..22d49f5f684 100644 --- a/src/pmi/src/pmi_util.h +++ b/src/pmi/src/pmi_util.h @@ -71,40 +71,46 @@ extern int PMIU_verbose; /* Set this to true to print PMI debugging info /* NOTE: we assume error codes are matching between PMI-1 and PMI-2 */ /* FIXME: do not assume error code, make it a macro parameter */ -#define PMIU_ERR_POP(err) do { pmi_errno = err; printf_d("ERROR: %s (%d)\n", __func__, __LINE__); goto fn_fail; } while (0) +#define PMIU_ERR_POP(err) do { \ + if (err) { \ + printf_d("ERROR: %s (%d)\n", __func__, __LINE__); \ + goto fn_fail; \ + } \ +} while (0) + #define PMIU_ERR_SETANDJUMP(err, class, str) do { \ printf_d("ERROR: "str" in %s (%d)\n", __func__, __LINE__); \ - pmi_errno = class; \ + err = class; \ goto fn_fail; \ } while (0) -#define PMIU_ERR_SETANDJUMP1(err, class, str, str1, arg) do { \ - printf_d("ERROR: "str1" in %s (%d)\n", arg, __func__, __LINE__); \ - pmi_errno = class; \ +#define PMIU_ERR_SETANDJUMP1(err, class, str, arg) do { \ + printf_d("ERROR: "str" in %s (%d)\n", arg, __func__, __LINE__); \ + err = class; \ goto fn_fail; \ } while (0) -#define PMIU_ERR_SETANDJUMP2(err, class, str, str1, arg1, arg2) do { \ - printf_d("ERROR: "str1" in %s (%d)\n", arg1, arg2, __func__, __LINE__); \ - pmi_errno = class; \ +#define PMIU_ERR_SETANDJUMP2(err, class, str, arg1, arg2) do { \ + printf_d("ERROR: "str" in %s (%d)\n", arg1, arg2, __func__, __LINE__); \ + err = class; \ goto fn_fail; \ } while (0) -#define PMIU_ERR_SETANDJUMP3(err, class, str, str1, arg1, arg2, arg3) do { \ - printf_d("ERROR: "str1" in %s (%d)\n", arg1, arg2, arg3, __func__, __LINE__); \ - pmi_errno = class; \ +#define PMIU_ERR_SETANDJUMP3(err, class, str, arg1, arg2, arg3) do { \ + printf_d("ERROR: "str" in %s (%d)\n", arg1, arg2, arg3, __func__, __LINE__); \ + err = class; \ goto fn_fail; \ } while (0) -#define PMIU_ERR_SETANDJUMP4(err, class, str, str1, arg1, arg2, arg3, arg4) do { \ - printf_d("ERROR: "str1" in %s (%d)\n", arg1, arg2, arg3, arg4, __func__, __LINE__); \ - pmi_errno = class; \ +#define PMIU_ERR_SETANDJUMP4(err, class, str, arg1, arg2, arg3, arg4) do { \ + printf_d("ERROR: "str" in %s (%d)\n", arg1, arg2, arg3, arg4, __func__, __LINE__); \ + err = class; \ goto fn_fail; \ } while (0) -#define PMIU_ERR_SETANDJUMP5(err, class, str, str1, arg1, arg2, arg3, arg4, arg5) do { \ - printf_d("ERROR: "str1" in %s (%d)\n", arg1, arg2, arg3, arg4, arg5, __func__, __LINE__); \ - pmi_errno = class; \ +#define PMIU_ERR_SETANDJUMP5(err, class, str, arg1, arg2, arg3, arg4, arg5) do { \ + printf_d("ERROR: "str" in %s (%d)\n", arg1, arg2, arg3, arg4, arg5, __func__, __LINE__); \ + err = class; \ goto fn_fail; \ } while (0) -#define PMIU_ERR_SETANDJUMP6(err, class, str, str1, arg1, arg2, arg3, arg4, arg5, arg6) do { \ - printf_d("ERROR: "str1" in %s (%d)\n", arg1, arg2, arg3, arg4, arg5, arg6, __func__, __LINE__); \ - pmi_errno = class; \ +#define PMIU_ERR_SETANDJUMP6(err, class, str, arg1, arg2, arg3, arg4, arg5, arg6) do { \ + printf_d("ERROR: "str" in %s (%d)\n", arg1, arg2, arg3, arg4, arg5, arg6, __func__, __LINE__); \ + err = class; \ goto fn_fail; \ } while (0) @@ -113,29 +119,29 @@ extern int PMIU_verbose; /* Set this to true to print PMI debugging info if (cond) \ PMIU_ERR_SETANDJUMP(err, class, str); \ } while (0) -#define PMIU_ERR_CHKANDJUMP1(cond, err, class, str, str1, arg) do { \ +#define PMIU_ERR_CHKANDJUMP1(cond, err, class, str, arg) do { \ if (cond) \ - PMIU_ERR_SETANDJUMP1(err, class, str, str1, arg); \ + PMIU_ERR_SETANDJUMP1(err, class, str, arg); \ } while (0) -#define PMIU_ERR_CHKANDJUMP2(cond, err, class, str, str1, arg1, arg2) do { \ +#define PMIU_ERR_CHKANDJUMP2(cond, err, class, str, arg1, arg2) do { \ if (cond) \ - PMIU_ERR_SETANDJUMP2(err, class, str, str1, arg1, arg2); \ + PMIU_ERR_SETANDJUMP2(err, class, str, arg1, arg2); \ } while (0) -#define PMIU_ERR_CHKANDJUMP3(cond, err, class, str, str1, arg1, arg2, arg3) do { \ +#define PMIU_ERR_CHKANDJUMP3(cond, err, class, str, arg1, arg2, arg3) do { \ if (cond) \ - PMIU_ERR_SETANDJUMP3(err, class, str, str1, arg1, arg2, arg3); \ + PMIU_ERR_SETANDJUMP3(err, class, str, arg1, arg2, arg3); \ } while (0) -#define PMIU_ERR_CHKANDJUMP4(cond, err, class, str, str1, arg1, arg2, arg3, arg4) do { \ +#define PMIU_ERR_CHKANDJUMP4(cond, err, class, str, arg1, arg2, arg3, arg4) do { \ if (cond) \ - PMIU_ERR_SETANDJUMP4(err, class, str, str1, arg1, arg2, arg3, arg4); \ + PMIU_ERR_SETANDJUMP4(err, class, str, arg1, arg2, arg3, arg4); \ } while (0) -#define PMIU_ERR_CHKANDJUMP5(cond, err, class, str, str1, arg1, arg2, arg3, arg4, arg5) do { \ +#define PMIU_ERR_CHKANDJUMP5(cond, err, class, str, arg1, arg2, arg3, arg4, arg5) do { \ if (cond) \ - PMIU_ERR_SETANDJUMP5(err, class, str, str1, arg1, arg2, arg3, arg4, arg5); \ + PMIU_ERR_SETANDJUMP5(err, class, str, arg1, arg2, arg3, arg4, arg5); \ } while (0) -#define PMIU_ERR_CHKANDJUMP6(cond, err, class, str, str1, arg1, arg2, arg3, arg4, arg5, arg6) do { \ +#define PMIU_ERR_CHKANDJUMP6(cond, err, class, str, arg1, arg2, arg3, arg4, arg5, arg6) do { \ if (cond) \ - PMIU_ERR_SETANDJUMP6(err, class, str, str1, arg1, arg2, arg3, arg4, arg5, arg6); \ + PMIU_ERR_SETANDJUMP6(err, class, str, arg1, arg2, arg3, arg4, arg5, arg6); \ } while (0) #if (!defined(NDEBUG) && defined(HAVE_ERROR_CHECKING)) @@ -148,19 +154,21 @@ extern int PMIU_verbose; /* Set this to true to print PMI debugging info #endif #ifdef HAVE_ERROR_CHECKING -#define PMIU_CHKMEM_SETERR(rc_, nbytes_, name_) do { \ - rc_ = PMI_ERR_NOMEM; \ +#define PMIU_CHKMEM_SETERR(rc_, errcode, nbytes_, name_) do { \ + rc_ = errcode; \ printf_d("ERROR: memory allocation of %lu bytes failed for %s in %s (%d)\n", \ (size_t)nbytes_, name_, __func__, __LINE__); \ } while (0) #else -#define PMIU_CHKMEM_SETERR(rc_, nbytes_, name_) rc_ = PMI_ERR_NOMEM +#define PMIU_CHKMEM_SETERR(rc_, errcode, nbytes_, name_) do { \ + rc_ = errcode; \ + } while (0) #endif -#define PMIU_CHK_MALLOC(pointer_,type_,nbytes_,rc_,name_) do { \ +#define PMIU_CHK_MALLOC(pointer_,type_,nbytes_,rc_,errcode,name_) do { \ pointer_ = (type_)PMIU_Malloc(nbytes_); \ if (!pointer_) { \ - PMIU_CHKMEM_SETERR(rc_,nbytes_,name_); \ + PMIU_CHKMEM_SETERR(rc_,errcode,nbytes_,name_); \ goto fn_fail; \ } \ } while (0) diff --git a/src/pmi/src/pmi_v2.c b/src/pmi/src/pmi_v2.c index 2577456e94e..c0f6722a56d 100644 --- a/src/pmi/src/pmi_v2.c +++ b/src/pmi/src/pmi_v2.c @@ -281,8 +281,7 @@ PMI_API_PUBLIC int PMI2_Init(int *spawned, int *size, int *rank, int *appnum) /* Get the fd for PMI commands; if none, we're a singleton */ pmi_errno = getPMIFD(); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); if (PMI2_fd == -1) { /* Singleton init: Process not started with mpiexec, @@ -300,15 +299,14 @@ PMI_API_PUBLIC int PMI2_Init(int *spawned, int *size, int *rank, int *appnum) ret = MPL_snprintf(buf, PMIU_MAXLINE, "cmd=init pmi_version=%d pmi_subversion=%d\n", PMI_VERSION, PMI_SUBVERSION); - PMIU_ERR_CHKANDJUMP1(ret < 0, pmi_errno, PMI2_ERR_OTHER, "**intern", "**intern %s", - "failed to generate init line"); + PMIU_ERR_CHKANDJUMP1(ret < 0, pmi_errno, PMI2_ERR_OTHER, + "**intern %s", "failed to generate init line"); ret = PMIU_writeline(PMI2_fd, buf); PMIU_ERR_CHKANDJUMP(ret < 0, pmi_errno, PMI2_ERR_OTHER, "**pmi2_init_send"); ret = PMIU_readline(PMI2_fd, buf, PMIU_MAXLINE); - PMIU_ERR_CHKANDJUMP1(ret < 0, pmi_errno, PMI2_ERR_OTHER, "**pmi2_initack", - "**pmi2_initack %s", strerror(errno)); + PMIU_ERR_CHKANDJUMP1(ret < 0, pmi_errno, PMI2_ERR_OTHER, "**pmi2_initack %s", strerror(errno)); PMIU_parse_keyvals(buf); cmdline[0] = 0; @@ -321,7 +319,7 @@ PMI_API_PUBLIC int PMI2_Init(int *spawned, int *size, int *rank, int *appnum) char buf1[PMIU_MAXLINE]; PMIU_getval("pmi_version", buf, PMIU_MAXLINE); PMIU_getval("pmi_subversion", buf1, PMIU_MAXLINE); - PMIU_ERR_SETANDJUMP4(pmi_errno, PMI2_ERR_OTHER, "**pmi2_version", + PMIU_ERR_SETANDJUMP4(pmi_errno, PMI2_ERR_OTHER, "**pmi2_version %s %s %d %d", buf, buf1, PMI_VERSION, PMI_SUBVERSION); } @@ -363,17 +361,15 @@ PMI_API_PUBLIC int PMI2_Init(int *spawned, int *size, int *rank, int *appnum) pmi_errno = PMIi_WriteSimpleCommand(PMI2_fd, 0, FULLINIT_CMD, pairs_p, npairs); /* don't pass in thread id for init */ - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); /* Read auth-response */ /* Send auth-response-complete */ /* Read fullinit-response */ pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, FULLINITRESP_CMD, &rc, &errmsg); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); - PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_fullinit", + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_fullinit %s", errmsg ? errmsg : "unknown"); found = getvalint(cmd.pairs, cmd.nPairs, PMIVERSION_KEY, &version); @@ -429,12 +425,10 @@ PMI_API_PUBLIC int PMI2_Finalize(void) if (PMI2_initialized > SINGLETON_INIT_BUT_NO_PM) { pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, FINALIZE_CMD, NULL); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, FINALIZERESP_CMD, &rc, &errmsg); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); - PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_finalize", + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_finalize %s", errmsg ? errmsg : "unknown"); PMIU_Free(cmd.command); freepairs(cmd.pairs, cmd.nPairs); @@ -573,8 +567,7 @@ cmd=spawn;thrid=string;ncmds=count;preputcount=n;ppkey0=name;ppval0=string;...;\ PMIU_Assert(npairs == total_pairs); pmi_errno = PMIi_WriteSimpleCommand(PMI2_fd, &resp_cmd, "spawn", pairs_p, npairs); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); freepairs(pairs_p, npairs); pairs_p = NULL; @@ -620,12 +613,10 @@ PMI_API_PUBLIC int PMI2_Job_GetId(char jobid[], int jobid_size) PMI2_Command cmd = { 0 }; pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, JOBGETID_CMD, NULL); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, JOBGETIDRESP_CMD, &rc, &errmsg); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); - PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_jobgetid", "**pmi2_jobgetid %s", + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_jobgetid %s", errmsg ? errmsg : "unknown"); found = getval(cmd.pairs, cmd.nPairs, JOBID_KEY, &jid, &jidlen); @@ -652,12 +643,10 @@ PMI_API_PUBLIC int PMI2_Job_Connect(const char jobid[], PMI2_Connect_comm_t * co const char *errmsg; pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, JOBCONNECT_CMD, JOBID_KEY, jobid, NULL); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, JOBCONNECTRESP_CMD, &rc, &errmsg); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); - PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_jobconnect", + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_jobconnect %s", errmsg ? errmsg : "unknown"); found = getvalbool(cmd.pairs, cmd.nPairs, KVSCOPY_KEY, &kvscopy); @@ -684,12 +673,10 @@ PMI_API_PUBLIC int PMI2_Job_Disconnect(const char jobid[]) pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, JOBDISCONNECT_CMD, JOBID_KEY, jobid, NULL); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, JOBDISCONNECTRESP_CMD, &rc, &errmsg); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); - PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_jobdisconnect", + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_jobdisconnect %s", errmsg ? errmsg : "unknown"); fn_exit: @@ -709,13 +696,11 @@ PMI_API_PUBLIC int PMI2_KVS_Put(const char key[], const char value[]) pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, KVSPUT_CMD, KEY_KEY, key, VALUE_KEY, value, NULL); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, KVSPUTRESP_CMD, &rc, &errmsg); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); - PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_kvsput", "**pmi2_kvsput %s", - errmsg ? errmsg : "unknown"); + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, + "**pmi2_kvsput %s", errmsg ? errmsg : "unknown"); fn_exit: PMIU_Free(cmd.command); @@ -733,13 +718,11 @@ PMI_API_PUBLIC int PMI2_KVS_Fence(void) const char *errmsg; pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, KVSFENCE_CMD, NULL); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, KVSFENCERESP_CMD, &rc, &errmsg); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); - PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_kvsfence", "**pmi2_kvsfence %s", - errmsg ? errmsg : "unknown"); + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, + "**pmi2_kvsfence %s", errmsg ? errmsg : "unknown"); fn_exit: PMIU_Free(cmd.command); @@ -766,19 +749,16 @@ PMI_API_PUBLIC MPL_snprintf(src_pmi_id_str, sizeof(src_pmi_id_str), "%d", src_pmi_id); pmi_errno = PMIi_InitIfSingleton(); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, KVSGET_CMD, JOBID_KEY, jobid, SRCID_KEY, src_pmi_id_str, KEY_KEY, key, NULL); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, KVSGETRESP_CMD, &rc, &errmsg); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); - PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_kvsget", "**pmi2_kvsget %s", - errmsg ? errmsg : "unknown"); + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, + "**pmi2_kvsget %s", errmsg ? errmsg : "unknown"); found = getvalbool(cmd.pairs, cmd.nPairs, FOUND_KEY, &keyfound); PMIU_ERR_CHKANDJUMP(found != 1, pmi_errno, PMI2_ERR_OTHER, "**intern"); @@ -812,18 +792,15 @@ PMI_API_PUBLIC const char *errmsg; pmi_errno = PMIi_InitIfSingleton(); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, GETNODEATTR_CMD, KEY_KEY, name, WAIT_KEY, waitfor ? "TRUE" : "FALSE", NULL); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, GETNODEATTRRESP_CMD, &rc, &errmsg); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); - PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_getnodeattr", + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_getnodeattr %s", errmsg ? errmsg : "unknown"); found = getvalbool(cmd.pairs, cmd.nPairs, FOUND_KEY, flag); @@ -858,18 +835,15 @@ PMI_API_PUBLIC const char *valptr; pmi_errno = PMIi_InitIfSingleton(); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, GETNODEATTR_CMD, KEY_KEY, name, WAIT_KEY, "FALSE", NULL); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, GETNODEATTRRESP_CMD, &rc, &errmsg); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); - PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_getnodeattr", + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_getnodeattr %s", errmsg ? errmsg : "unknown"); found = getvalbool(cmd.pairs, cmd.nPairs, FOUND_KEY, flag); @@ -881,14 +855,14 @@ PMI_API_PUBLIC valptr = kvsvalue; i = 0; rc = sscanf(valptr, "%d", &array[i]); - PMIU_ERR_CHKANDJUMP1(rc != 1, pmi_errno, PMI2_ERR_OTHER, "**intern", "**intern %s", - "unable to parse intarray"); + PMIU_ERR_CHKANDJUMP1(rc != 1, pmi_errno, PMI2_ERR_OTHER, + "**intern %s", "unable to parse intarray"); ++i; while ((valptr = strchr(valptr, ',')) && i < arraylen) { ++valptr; /* skip over the ',' */ rc = sscanf(valptr, "%d", &array[i]); - PMIU_ERR_CHKANDJUMP1(rc != 1, pmi_errno, PMI2_ERR_OTHER, "**intern", "**intern %s", - "unable to parse intarray"); + PMIU_ERR_CHKANDJUMP1(rc != 1, pmi_errno, PMI2_ERR_OTHER, + "**intern %s", "unable to parse intarray"); ++i; } @@ -913,12 +887,10 @@ PMI_API_PUBLIC int PMI2_Info_PutNodeAttr(const char name[], const char value[]) pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, PUTNODEATTR_CMD, KEY_KEY, name, VALUE_KEY, value, NULL); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, PUTNODEATTRRESP_CMD, &rc, &errmsg); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); - PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_putnodeattr", + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_putnodeattr %s", errmsg ? errmsg : "unknown"); fn_exit: @@ -940,16 +912,13 @@ PMI_API_PUBLIC int PMI2_Info_GetJobAttr(const char name[], char value[], int val const char *errmsg; pmi_errno = PMIi_InitIfSingleton(); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, GETJOBATTR_CMD, KEY_KEY, name, NULL); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, GETJOBATTRRESP_CMD, &rc, &errmsg); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); - PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_getjobattr", + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_getjobattr %s", errmsg ? errmsg : "unknown"); found = getvalbool(cmd.pairs, cmd.nPairs, FOUND_KEY, flag); @@ -985,16 +954,13 @@ PMI_API_PUBLIC const char *valptr; pmi_errno = PMIi_InitIfSingleton(); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, GETJOBATTR_CMD, KEY_KEY, name, NULL); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, GETJOBATTRRESP_CMD, &rc, &errmsg); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); - PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_getjobattr", + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_getjobattr %s", errmsg ? errmsg : "unknown"); found = getvalbool(cmd.pairs, cmd.nPairs, FOUND_KEY, flag); @@ -1006,14 +972,14 @@ PMI_API_PUBLIC valptr = kvsvalue; i = 0; rc = sscanf(valptr, "%d", &array[i]); - PMIU_ERR_CHKANDJUMP1(rc != 1, pmi_errno, PMI2_ERR_OTHER, "**intern", "**intern %s", - "unable to parse intarray"); + PMIU_ERR_CHKANDJUMP1(rc != 1, pmi_errno, PMI2_ERR_OTHER, + "**intern %s", "unable to parse intarray"); ++i; while ((valptr = strchr(valptr, ',')) && i < arraylen) { ++valptr; /* skip over the ',' */ rc = sscanf(valptr, "%d", &array[i]); - PMIU_ERR_CHKANDJUMP1(rc != 1, pmi_errno, PMI2_ERR_OTHER, "**intern", "**intern %s", - "unable to parse intarray"); + PMIU_ERR_CHKANDJUMP1(rc != 1, pmi_errno, PMI2_ERR_OTHER, + "**intern %s", "unable to parse intarray"); ++i; } @@ -1041,12 +1007,10 @@ PMI_API_PUBLIC pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, NAMEPUBLISH_CMD, NAME_KEY, service_name, PORT_KEY, port, INFOKEYCOUNT_KEY, "0", NULL); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, NAMEPUBLISHRESP_CMD, &rc, &errmsg); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); - PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_nameservpublish", + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_nameservpublish %s", errmsg ? errmsg : "unknown"); @@ -1074,16 +1038,14 @@ PMI_API_PUBLIC /* ignoring infos for now */ pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, NAMELOOKUP_CMD, NAME_KEY, service_name, INFOKEYCOUNT_KEY, "0", NULL); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, NAMELOOKUPRESP_CMD, &rc, &errmsg); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); - PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_nameservlookup", + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_nameservlookup %s", errmsg ? errmsg : "unknown"); found = getval(cmd.pairs, cmd.nPairs, PORT_KEY, &found_port, &plen); - PMIU_ERR_CHKANDJUMP1(!found, pmi_errno, PMI2_ERR_OTHER, "**pmi2_nameservlookup", + PMIU_ERR_CHKANDJUMP1(!found, pmi_errno, PMI2_ERR_OTHER, "**pmi2_nameservlookup %s", "not found"); MPL_strncpy(port, found_port, portLen); @@ -1105,12 +1067,10 @@ PMI_API_PUBLIC pmi_errno = PMIi_WriteSimpleCommandStr(PMI2_fd, &cmd, NAMEUNPUBLISH_CMD, NAME_KEY, service_name, INFOKEYCOUNT_KEY, "0", NULL); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); pmi_errno = PMIi_ReadCommandExp(PMI2_fd, &cmd, NAMEUNPUBLISHRESP_CMD, &rc, &errmsg); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); - PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_nameservunpublish", + PMIU_ERR_POP(pmi_errno); + PMIU_ERR_CHKANDJUMP1(rc, pmi_errno, PMI2_ERR_OTHER, "**pmi2_nameservunpublish %s", errmsg ? errmsg : "unknown"); fn_exit: @@ -1318,12 +1278,13 @@ static int create_keyval(PMI2_Keyvalpair ** kv, const char *key, const char *val char *key_p = NULL; char *value_p = NULL; - PMIU_CHK_MALLOC(*kv, PMI2_Keyvalpair *, sizeof(PMI2_Keyvalpair), pmi_errno, "pair"); + PMIU_CHK_MALLOC(*kv, PMI2_Keyvalpair *, sizeof(PMI2_Keyvalpair), + pmi_errno, PMI2_ERR_NOMEM, "pair"); - PMIU_CHK_MALLOC(key_p, char *, strlen(key) + 1, pmi_errno, "key"); + PMIU_CHK_MALLOC(key_p, char *, strlen(key) + 1, pmi_errno, PMI2_ERR_NOMEM, "key"); MPL_strncpy(key_p, key, PMI2_MAX_KEYLEN + 1); - PMIU_CHK_MALLOC(value_p, char *, vallen + 1, pmi_errno, "value"); + PMIU_CHK_MALLOC(value_p, char *, vallen + 1, pmi_errno, PMI2_ERR_NOMEM, "value"); PMIU_Memcpy(value_p, val, vallen); value_p[vallen] = '\0'; @@ -1387,8 +1348,8 @@ int PMIi_ReadCommand(int fd, PMI2_Command * cmd) nbytes = read(fd, &cmd_len_str[offset], PMII_COMMANDLEN_SIZE - offset); } while (nbytes == -1 && errno == EINTR); - PMIU_ERR_CHKANDJUMP1(nbytes <= 0, pmi_errno, PMI2_ERR_OTHER, "**read", "**read %s", - strerror(errno)); + PMIU_ERR_CHKANDJUMP1(nbytes <= 0, pmi_errno, PMI2_ERR_OTHER, + "**read %s", strerror(errno)); offset += nbytes; } @@ -1398,7 +1359,7 @@ int PMIi_ReadCommand(int fd, PMI2_Command * cmd) cmd_buf = PMIU_Malloc(cmd_len + 1); if (!cmd_buf) { - PMIU_CHKMEM_SETERR(pmi_errno, cmd_len + 1, "cmd_buf"); + PMIU_CHKMEM_SETERR(pmi_errno, PMI2_ERR_NOMEM, cmd_len + 1, "cmd_buf"); goto fn_exit; } @@ -1411,8 +1372,8 @@ int PMIi_ReadCommand(int fd, PMI2_Command * cmd) nbytes = read(fd, &cmd_buf[offset], cmd_len - offset); } while (nbytes == -1 && errno == EINTR); - PMIU_ERR_CHKANDJUMP1(nbytes <= 0, pmi_errno, PMI2_ERR_OTHER, "**read", "**read %s", - strerror(errno)); + PMIU_ERR_CHKANDJUMP1(nbytes <= 0, pmi_errno, PMI2_ERR_OTHER, + "**read %s", strerror(errno)); offset += nbytes; } @@ -1443,15 +1404,14 @@ int PMIi_ReadCommand(int fd, PMI2_Command * cmd) c = cmd_buf; remaining_len = cmd_len; pmi_errno = parse_keyval(&c, &remaining_len, &key, &val, &vallen); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); PMIU_ERR_CHKANDJUMP(strncmp(key, "cmd", PMI2_MAX_KEYLEN) != 0, pmi_errno, PMI2_ERR_OTHER, "**bad_cmd"); command = PMIU_Malloc(vallen + 1); if (!command) { - PMIU_CHKMEM_SETERR(pmi_errno, vallen + 1, "command"); + PMIU_CHKMEM_SETERR(pmi_errno, PMI2_ERR_NOMEM, vallen + 1, "command"); goto fn_exit; } PMIU_Memcpy(command, val, vallen); @@ -1461,7 +1421,8 @@ int PMIi_ReadCommand(int fd, PMI2_Command * cmd) pairs = PMIU_Malloc(sizeof(PMI2_Keyvalpair *) * nPairs); if (!pairs) { - PMIU_CHKMEM_SETERR(pmi_errno, sizeof(PMI2_Keyvalpair *) * nPairs, "pairs"); + PMIU_CHKMEM_SETERR(pmi_errno, PMI2_ERR_NOMEM, sizeof(PMI2_Keyvalpair *) * nPairs, + "pairs"); goto fn_exit; } @@ -1470,12 +1431,10 @@ int PMIi_ReadCommand(int fd, PMI2_Command * cmd) PMI2_Keyvalpair *pair; pmi_errno = parse_keyval(&c, &remaining_len, &key, &val, &vallen); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); pmi_errno = create_keyval(&pair, key, val, vallen); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); pairs[pair_index] = pair; ++pair_index; @@ -1523,8 +1482,7 @@ int PMIi_ReadCommandExp(int fd, PMI2_Command * cmd, const char *exp, int *rc, co int msglen; pmi_errno = PMIi_ReadCommand(fd, cmd); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); PMIU_ERR_CHKANDJUMP(strncmp(cmd->command, exp, strlen(exp)) != 0, pmi_errno, PMI2_ERR_OTHER, "**bad_cmd"); @@ -1569,14 +1527,14 @@ int PMIi_WriteSimpleCommand(int fd, PMI2_Command * resp, const char cmd[], PMIU_ERR_CHKANDJUMP(strlen(cmd) > PMI2_MAX_VALLEN, pmi_errno, PMI2_ERR_OTHER, "**cmd_too_long"); ret = MPL_snprintf(c, remaining_len, "cmd=%s;", cmd); - PMIU_ERR_CHKANDJUMP1(ret >= remaining_len, pmi_errno, PMI2_ERR_OTHER, "**intern", + PMIU_ERR_CHKANDJUMP1(ret >= remaining_len, pmi_errno, PMI2_ERR_OTHER, "**intern %s", "Ran out of room for command"); c += ret; remaining_len -= ret; if (PMI2_is_threaded && resp) { ret = MPL_snprintf(c, remaining_len, "thrid=%p;", resp); - PMIU_ERR_CHKANDJUMP1(ret >= remaining_len, pmi_errno, PMI2_ERR_OTHER, "**intern", + PMIU_ERR_CHKANDJUMP1(ret >= remaining_len, pmi_errno, PMI2_ERR_OTHER, "**intern %s", "Ran out of room for command"); c += ret; remaining_len -= ret; @@ -1587,7 +1545,7 @@ int PMIi_WriteSimpleCommand(int fd, PMI2_Command * resp, const char cmd[], PMIU_ERR_CHKANDJUMP(strlen(pairs[pair_index]->key) > PMI2_MAX_KEYLEN, pmi_errno, PMI2_ERR_OTHER, "**key_too_long"); ret = MPL_snprintf(c, remaining_len, "%s=", pairs[pair_index]->key); - PMIU_ERR_CHKANDJUMP1(ret >= remaining_len, pmi_errno, PMI2_ERR_OTHER, "**intern", + PMIU_ERR_CHKANDJUMP1(ret >= remaining_len, pmi_errno, PMI2_ERR_OTHER, "**intern %s", "Ran out of room for command"); c += ret; remaining_len -= ret; @@ -1615,7 +1573,7 @@ int PMIi_WriteSimpleCommand(int fd, PMI2_Command * resp, const char cmd[], /* prepend the buffer length stripping off the trailing '\0' */ cmdlen = PMII_MAX_COMMAND_LEN - remaining_len; ret = MPL_snprintf(cmdlenbuf, sizeof(cmdlenbuf), "%d", cmdlen); - PMIU_ERR_CHKANDJUMP1(ret >= PMII_COMMANDLEN_SIZE, pmi_errno, PMI2_ERR_OTHER, "**intern", + PMIU_ERR_CHKANDJUMP1(ret >= PMII_COMMANDLEN_SIZE, pmi_errno, PMI2_ERR_OTHER, "**intern %s", "Command length won't fit in length buffer"); PMIU_Memcpy(cmdbuf, cmdlenbuf, ret); @@ -1643,8 +1601,7 @@ int PMIi_WriteSimpleCommand(int fd, PMI2_Command * resp, const char cmd[], nbytes = write(fd, &cmdbuf[offset], cmdlen + PMII_COMMANDLEN_SIZE - offset); } while (nbytes == -1 && errno == EINTR); - PMIU_ERR_CHKANDJUMP1(nbytes <= 0, pmi_errno, PMI2_ERR_OTHER, "**write", "**write %s", - strerror(errno)); + PMIU_ERR_CHKANDJUMP1(nbytes <= 0, pmi_errno, PMI2_ERR_OTHER, "**write %s", strerror(errno)); offset += nbytes; } while (offset < cmdlen + PMII_COMMANDLEN_SIZE); @@ -1682,9 +1639,10 @@ int PMIi_WriteSimpleCommandStr(int fd, PMI2_Command * resp, const char cmd[], .. } va_end(ap); - PMIU_CHK_MALLOC(pairs, PMI2_Keyvalpair *, sizeof(PMI2_Keyvalpair) * npairs, pmi_errno, "pairs"); + PMIU_CHK_MALLOC(pairs, PMI2_Keyvalpair *, sizeof(PMI2_Keyvalpair) * npairs, + pmi_errno, PMI2_ERR_NOMEM, "pairs"); PMIU_CHK_MALLOC(pairs_p, PMI2_Keyvalpair **, sizeof(PMI2_Keyvalpair *) * npairs, - pmi_errno, "pairs_p"); + pmi_errno, PMI2_ERR_NOMEM, "pairs_p"); i = 0; va_start(ap, cmd); @@ -1703,8 +1661,7 @@ int PMIi_WriteSimpleCommandStr(int fd, PMI2_Command * resp, const char cmd[], .. va_end(ap); pmi_errno = PMIi_WriteSimpleCommand(fd, resp, cmd, pairs_p, npairs); - if (pmi_errno) - PMIU_ERR_POP(pmi_errno); + PMIU_ERR_POP(pmi_errno); fn_exit: PMIU_Free(pairs); @@ -1889,8 +1846,7 @@ static int getPMIFD(void) } *ph = 0; - PMIU_ERR_CHKANDJUMP1(*pn != ':', pmi_errno, PMI2_ERR_OTHER, "**pmi2_port", - "**pmi2_port %s", p); + PMIU_ERR_CHKANDJUMP1(*pn != ':', pmi_errno, PMI2_ERR_OTHER, "**pmi2_port %s", p); portnum = atoi(pn + 1); /* FIXME: Check for valid integer after : */ @@ -1898,7 +1854,7 @@ static int getPMIFD(void) * the process manager. The handshake below is used * to setup the initial values */ PMI2_fd = PMII_Connect_to_pm(hostname, portnum); - PMIU_ERR_CHKANDJUMP2(PMI2_fd < 0, pmi_errno, PMI2_ERR_OTHER, "**connect_to_pm", + PMIU_ERR_CHKANDJUMP2(PMI2_fd < 0, pmi_errno, PMI2_ERR_OTHER, "**connect_to_pm %s %d", hostname, portnum); } From 3c75b378f711734dc1dfd93907deda1c44120b26 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 1 Apr 2022 22:51:50 -0500 Subject: [PATCH 586/607] ulfm: add MPIX_Comm_get_failed This routine -- int MPI_Comm_get_failed(MPI_Comm comm, MPI_Group *failed_group) , which returns a group of failed process, is in the current working ULFM proposal. --- src/binding/c/comm_api.txt | 11 ++++ src/mpi/comm/Makefile.mk | 1 + src/mpi/comm/ulfm_impl.c | 108 +++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 src/mpi/comm/ulfm_impl.c diff --git a/src/binding/c/comm_api.txt b/src/binding/c/comm_api.txt index d84c4ef9cde..c4bd404ece1 100644 --- a/src/binding/c/comm_api.txt +++ b/src/binding/c/comm_api.txt @@ -368,3 +368,14 @@ MPIX_Comm_agree: After MPIX_Comm_agree raised an error of class MPI_ERR_PROC_FAILED, a subse-quent call to MPIX_Comm_failure_ack on comm acknowledges the failure of every MPI process that didn't contribute to the computation offlag. */ + +MPIX_Comm_get_failed: + comm: COMMUNICATOR, [communicator] + failedgrp: GROUP, direction=out, [group of failed processes] + .desc: This local operation returns the group of processes that are locally known to have failed. +/* + Notes: + The returned failedgrp can be empty, that is, equal to MPI_GROUP_EMPTY. + + For any two groups obtained from calls to this routine at the same MPI process with the same comm, the smaller group is a prefix of the larger group, that is, the same failed process will have the same rank in the returned failedgrp. +*/ diff --git a/src/mpi/comm/Makefile.mk b/src/mpi/comm/Makefile.mk index 9b8b5b1563c..ec7c5f46950 100644 --- a/src/mpi/comm/Makefile.mk +++ b/src/mpi/comm/Makefile.mk @@ -8,6 +8,7 @@ mpi_core_sources += \ src/mpi/comm/comm_split.c \ src/mpi/comm/comm_split_type.c \ src/mpi/comm/comm_split_type_nbhd.c \ + src/mpi/comm/ulfm_impl.c \ src/mpi/comm/builtin_comms.c \ src/mpi/comm/commutil.c \ src/mpi/comm/contextid.c diff --git a/src/mpi/comm/ulfm_impl.c b/src/mpi/comm/ulfm_impl.c new file mode 100644 index 00000000000..81f602c8832 --- /dev/null +++ b/src/mpi/comm/ulfm_impl.c @@ -0,0 +1,108 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpiimpl.h" +#include "utarray.h" + +/* TODO: extend ULFM to support dynamic processes */ + +/* maintain a list of failed process in comm_world */ +/* NOTE: we need maintain the order of failed_procs as the show up. We do it here because + * it isn't fair to require PMI to do it. + */ +static UT_array *failed_procs; + +static void add_failed_proc(int rank) +{ + if (!failed_procs) { + utarray_new(failed_procs, &ut_int_icd, MPL_MEM_OTHER); + } + + /* NOTE: if failed procs gets too large, we may consider add a hash for O(1) search; + * but currently it is limited by PMI_MAXVALLEN anyway */ + int found = 0; + for (int i = 0; i < utarray_len(failed_procs); i++) { + int *p = (int *) utarray_eltptr(failed_procs, i); + if (*p == rank) { + found = 1; + break; + } + } + + if (!found) { + utarray_push_back(failed_procs, &rank, MPL_MEM_OTHER); + } +} + +static void parse_failed_procs_string(char *failed_procs_string) +{ + /* failed_procs_string is a comma separated list + * of ranks or ranges of ranks (e.g., "1, 3-5, 11") */ + const char *delim = ","; + char *token; + + token = strtok(failed_procs_string, delim); + while (token != NULL) { + char *p = strchr(token, '-'); + if (p) { + /* a-b */ + int a = atoi(token); + int b = atoi(p + 1); + MPIR_Assertp(a <= b); + for (int i = a; i <= b; i++) { + add_failed_proc(i); + } + } else { + int a = atoi(token); + add_failed_proc(a); + } + token = strtok(NULL, delim); + } +} + +int MPIR_Comm_get_failed_impl(MPIR_Comm * comm_ptr, MPIR_Group ** failed_group_ptr) +{ + int mpi_errno = MPI_SUCCESS; + MPIR_FUNC_ENTER; + + char *failed_procs_string = MPIR_pmi_get_failed_procs(); + + if (!failed_procs_string) { + *failed_group_ptr = MPIR_Group_empty; + } else if (failed_procs_string[0] == '\0') { + *failed_group_ptr = MPIR_Group_empty; + MPL_free(failed_procs_string); + } else { + parse_failed_procs_string(failed_procs_string); + MPL_free(failed_procs_string); + + /* create failed_group */ + int n = utarray_len(failed_procs); + + MPIR_Group *new_group; + mpi_errno = MPIR_Group_create(n, &new_group); + MPIR_ERR_CHECK(mpi_errno); + + new_group->rank = MPI_UNDEFINED; + for (int i = 0; i < utarray_len(failed_procs); i++) { + int *p = (int *) utarray_eltptr(failed_procs, i); + new_group->lrank_to_lpid[i].lpid = *p; + /* if calling process is part of the group, set the rank */ + if (*p == MPIR_Process.rank) { + new_group->rank = i; + } + } + new_group->size = n; + new_group->idx_of_first_lpid = -1; + + *failed_group_ptr = new_group; + } + + fn_exit: + MPIR_FUNC_EXIT; + return mpi_errno; + fn_fail: + goto fn_exit; +} From 81d040b6a146e225be02756c9459d4701b461edd Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 1 Apr 2022 23:14:21 -0500 Subject: [PATCH 587/607] ulfm: move ulfm impl functions to ulfm_impl.c Gather ULFM related functions together. These functions are related and are unstable. Gather them together to reduce conflicts when we change them. --- src/mpi/comm/comm_impl.c | 145 ----------------------------------- src/mpi/comm/ulfm_impl.c | 160 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 159 insertions(+), 146 deletions(-) diff --git a/src/mpi/comm/comm_impl.c b/src/mpi/comm/comm_impl.c index c30dc893968..e8027f84000 100644 --- a/src/mpi/comm/comm_impl.c +++ b/src/mpi/comm/comm_impl.c @@ -98,81 +98,6 @@ static int comm_create_local_group(MPIR_Comm * comm_ptr) goto fn_exit; } -int MPIR_Comm_agree_impl(MPIR_Comm * comm_ptr, int *flag) -{ - int mpi_errno = MPI_SUCCESS, mpi_errno_tmp = MPI_SUCCESS; - MPIR_Group *comm_grp = NULL, *failed_grp = NULL, *new_group_ptr = NULL, *global_failed = NULL; - int result, success = 1; - MPIR_Errflag_t errflag = MPIR_ERR_NONE; - int values[2]; - - MPIR_FUNC_ENTER; - - MPIR_Comm_group_impl(comm_ptr, &comm_grp); - - /* Get the locally known (not acknowledged) group of failed procs */ - mpi_errno = MPID_Comm_failure_get_acked(comm_ptr, &failed_grp); - MPIR_ERR_CHECK(mpi_errno); - - /* First decide on the group of failed procs. */ - mpi_errno = MPID_Comm_get_all_failed_procs(comm_ptr, &global_failed, MPIR_AGREE_TAG); - if (mpi_errno) - errflag = MPIR_ERR_PROC_FAILED; - - mpi_errno = MPIR_Group_compare_impl(failed_grp, global_failed, &result); - MPIR_ERR_CHECK(mpi_errno); - - /* Create a subgroup without the failed procs */ - mpi_errno = MPIR_Group_difference_impl(comm_grp, global_failed, &new_group_ptr); - MPIR_ERR_CHECK(mpi_errno); - - /* If that group isn't the same as what we think is failed locally, then - * mark it as such. */ - if (result == MPI_UNEQUAL || errflag) - success = 0; - - /* Do an allreduce to decide whether or not anyone thinks the group - * has changed */ - mpi_errno_tmp = MPII_Allreduce_group(MPI_IN_PLACE, &success, 1, MPI_INT, MPI_MIN, comm_ptr, - new_group_ptr, MPIR_AGREE_TAG, &errflag); - if (!success || errflag || mpi_errno_tmp) - success = 0; - - values[0] = success; - values[1] = *flag; - - /* Determine both the result of this function (mpi_errno) and the result - * of flag that will be returned to the user. */ - MPII_Allreduce_group(MPI_IN_PLACE, values, 2, MPI_INT, MPI_BAND, comm_ptr, - new_group_ptr, MPIR_AGREE_TAG, &errflag); - /* Ignore the result of the operation this time. Everyone will either - * return a failure because of !success earlier or they will return - * something useful for flag because of this operation. If there was a new - * failure in between the first allreduce and the second one, it's ignored - * here. */ - - if (failed_grp != MPIR_Group_empty) - MPIR_Group_release(failed_grp); - MPIR_Group_release(new_group_ptr); - MPIR_Group_release(comm_grp); - if (global_failed != MPIR_Group_empty) - MPIR_Group_release(global_failed); - - success = values[0]; - *flag = values[1]; - - if (!success) { - MPIR_ERR_SET(mpi_errno_tmp, MPIX_ERR_PROC_FAILED, "**mpix_comm_agree"); - MPIR_ERR_ADD(mpi_errno, mpi_errno_tmp); - } - - fn_exit: - MPIR_FUNC_EXIT; - return mpi_errno; - fn_fail: - goto fn_exit; -} - int MPIR_Comm_compare_impl(MPIR_Comm * comm_ptr1, MPIR_Comm * comm_ptr2, int *result) { int mpi_errno = MPI_SUCCESS; @@ -1029,76 +954,6 @@ int MPIR_Comm_set_info_impl(MPIR_Comm * comm_ptr, MPIR_Info * info_ptr) goto fn_exit; } -/* comm shrink impl; assumes that standard error checking has already taken - * place in the calling function */ -int MPIR_Comm_shrink_impl(MPIR_Comm * comm_ptr, MPIR_Comm ** newcomm_ptr) -{ - int mpi_errno = MPI_SUCCESS; - MPIR_Group *global_failed = NULL, *comm_grp = NULL, *new_group_ptr = NULL; - int attempts = 0; - MPIR_Errflag_t errflag = MPIR_ERR_NONE; - - MPIR_FUNC_ENTER; - - /* TODO - Implement this function for intercommunicators */ - MPIR_Comm_group_impl(comm_ptr, &comm_grp); - - do { - errflag = MPIR_ERR_NONE; - - MPID_Comm_get_all_failed_procs(comm_ptr, &global_failed, MPIR_SHRINK_TAG); - /* Ignore the mpi_errno value here as it will definitely communicate - * with failed procs */ - - mpi_errno = MPIR_Group_difference_impl(comm_grp, global_failed, &new_group_ptr); - MPIR_ERR_CHECK(mpi_errno); - if (MPIR_Group_empty != global_failed) - MPIR_Group_release(global_failed); - - mpi_errno = MPIR_Comm_create_group_impl(comm_ptr, new_group_ptr, MPIR_SHRINK_TAG, - newcomm_ptr); - if (*newcomm_ptr == NULL) { - errflag = MPIR_ERR_PROC_FAILED; - } else if (mpi_errno) { - errflag = - MPIX_ERR_PROC_FAILED == - MPIR_ERR_GET_CLASS(mpi_errno) ? MPIR_ERR_PROC_FAILED : MPIR_ERR_OTHER; - MPIR_Comm_release(*newcomm_ptr); - } - - mpi_errno = MPII_Allreduce_group(MPI_IN_PLACE, &errflag, 1, MPI_INT, MPI_MAX, comm_ptr, - new_group_ptr, MPIR_SHRINK_TAG, &errflag); - MPIR_Group_release(new_group_ptr); - - if (errflag) { - if (*newcomm_ptr != NULL && MPIR_Object_get_ref(*newcomm_ptr) > 0) { - MPIR_Object_set_ref(*newcomm_ptr, 1); - MPIR_Comm_release(*newcomm_ptr); - } - if (MPIR_Object_get_ref(new_group_ptr) > 0) { - MPIR_Object_set_ref(new_group_ptr, 1); - MPIR_Group_release(new_group_ptr); - } - } - } while (errflag && ++attempts < 5); - - if (errflag && attempts >= 5) - goto fn_fail; - else - mpi_errno = MPI_SUCCESS; - - fn_exit: - MPIR_Group_release(comm_grp); - MPIR_FUNC_EXIT; - return mpi_errno; - fn_fail: - if (*newcomm_ptr) - MPIR_Object_set_ref(*newcomm_ptr, 0); - MPIR_Object_set_ref(global_failed, 0); - MPIR_Object_set_ref(new_group_ptr, 0); - goto fn_exit; -} - int MPIR_Intercomm_create_impl(MPIR_Comm * local_comm_ptr, int local_leader, MPIR_Comm * peer_comm_ptr, int remote_leader, int tag, MPIR_Comm ** new_intercomm_ptr) diff --git a/src/mpi/comm/ulfm_impl.c b/src/mpi/comm/ulfm_impl.c index 81f602c8832..917854a1a20 100644 --- a/src/mpi/comm/ulfm_impl.c +++ b/src/mpi/comm/ulfm_impl.c @@ -6,7 +6,13 @@ #include "mpiimpl.h" #include "utarray.h" +/* MPIR_Comm_get_failed_impl - + * use PMI to get list of dead process (PMI_dead_processes) in MPI_COMM_WORLD + */ /* TODO: extend ULFM to support dynamic processes */ +/* NOTE: src/mpid/ch3/src/mpid_comm_get_all_failed_procs.c contains a non-local + * implementation. Since ULFM require local discovery, we should remove that + */ /* maintain a list of failed process in comm_world */ /* NOTE: we need maintain the order of failed_procs as the show up. We do it here because @@ -97,7 +103,159 @@ int MPIR_Comm_get_failed_impl(MPIR_Comm * comm_ptr, MPIR_Group ** failed_group_p new_group->size = n; new_group->idx_of_first_lpid = -1; - *failed_group_ptr = new_group; + MPIR_Group *comm_group; + MPIR_Comm_group_impl(comm_ptr, &comm_group); + + mpi_errno = MPIR_Group_intersection_impl(comm_group, new_group, failed_group_ptr); + MPIR_ERR_CHECK(mpi_errno); + + MPIR_Group_release(comm_group); + MPIR_Group_release(new_group); + } + + fn_exit: + MPIR_FUNC_EXIT; + return mpi_errno; + fn_fail: + goto fn_exit; +} + +/* comm shrink impl; assumes that standard error checking has already taken + * place in the calling function */ +int MPIR_Comm_shrink_impl(MPIR_Comm * comm_ptr, MPIR_Comm ** newcomm_ptr) +{ + int mpi_errno = MPI_SUCCESS; + MPIR_Group *global_failed = NULL, *comm_grp = NULL, *new_group_ptr = NULL; + int attempts = 0; + MPIR_Errflag_t errflag = MPIR_ERR_NONE; + + MPIR_FUNC_ENTER; + + /* TODO - Implement this function for intercommunicators */ + MPIR_Comm_group_impl(comm_ptr, &comm_grp); + + do { + errflag = MPIR_ERR_NONE; + + MPID_Comm_get_all_failed_procs(comm_ptr, &global_failed, MPIR_SHRINK_TAG); + /* Ignore the mpi_errno value here as it will definitely communicate + * with failed procs */ + + mpi_errno = MPIR_Group_difference_impl(comm_grp, global_failed, &new_group_ptr); + MPIR_ERR_CHECK(mpi_errno); + if (MPIR_Group_empty != global_failed) + MPIR_Group_release(global_failed); + + mpi_errno = MPIR_Comm_create_group_impl(comm_ptr, new_group_ptr, MPIR_SHRINK_TAG, + newcomm_ptr); + if (*newcomm_ptr == NULL) { + errflag = MPIR_ERR_PROC_FAILED; + } else if (mpi_errno) { + errflag = + MPIX_ERR_PROC_FAILED == + MPIR_ERR_GET_CLASS(mpi_errno) ? MPIR_ERR_PROC_FAILED : MPIR_ERR_OTHER; + MPIR_Comm_release(*newcomm_ptr); + } + + mpi_errno = MPII_Allreduce_group(MPI_IN_PLACE, &errflag, 1, MPI_INT, MPI_MAX, comm_ptr, + new_group_ptr, MPIR_SHRINK_TAG, &errflag); + MPIR_Group_release(new_group_ptr); + + if (errflag) { + if (*newcomm_ptr != NULL && MPIR_Object_get_ref(*newcomm_ptr) > 0) { + MPIR_Object_set_ref(*newcomm_ptr, 1); + MPIR_Comm_release(*newcomm_ptr); + } + if (MPIR_Object_get_ref(new_group_ptr) > 0) { + MPIR_Object_set_ref(new_group_ptr, 1); + MPIR_Group_release(new_group_ptr); + } + } + } while (errflag && ++attempts < 5); + + if (errflag && attempts >= 5) + goto fn_fail; + else + mpi_errno = MPI_SUCCESS; + + fn_exit: + MPIR_Group_release(comm_grp); + MPIR_FUNC_EXIT; + return mpi_errno; + fn_fail: + if (*newcomm_ptr) + MPIR_Object_set_ref(*newcomm_ptr, 0); + MPIR_Object_set_ref(global_failed, 0); + MPIR_Object_set_ref(new_group_ptr, 0); + goto fn_exit; +} + +int MPIR_Comm_agree_impl(MPIR_Comm * comm_ptr, int *flag) +{ + int mpi_errno = MPI_SUCCESS, mpi_errno_tmp = MPI_SUCCESS; + MPIR_Group *comm_grp = NULL, *failed_grp = NULL, *new_group_ptr = NULL, *global_failed = NULL; + int result, success = 1; + MPIR_Errflag_t errflag = MPIR_ERR_NONE; + int values[2]; + + MPIR_FUNC_ENTER; + + MPIR_Comm_group_impl(comm_ptr, &comm_grp); + + /* Get the locally known (not acknowledged) group of failed procs */ + mpi_errno = MPID_Comm_failure_get_acked(comm_ptr, &failed_grp); + MPIR_ERR_CHECK(mpi_errno); + + /* First decide on the group of failed procs. */ + mpi_errno = MPID_Comm_get_all_failed_procs(comm_ptr, &global_failed, MPIR_AGREE_TAG); + if (mpi_errno) + errflag = MPIR_ERR_PROC_FAILED; + + mpi_errno = MPIR_Group_compare_impl(failed_grp, global_failed, &result); + MPIR_ERR_CHECK(mpi_errno); + + /* Create a subgroup without the failed procs */ + mpi_errno = MPIR_Group_difference_impl(comm_grp, global_failed, &new_group_ptr); + MPIR_ERR_CHECK(mpi_errno); + + /* If that group isn't the same as what we think is failed locally, then + * mark it as such. */ + if (result == MPI_UNEQUAL || errflag) + success = 0; + + /* Do an allreduce to decide whether or not anyone thinks the group + * has changed */ + mpi_errno_tmp = MPII_Allreduce_group(MPI_IN_PLACE, &success, 1, MPI_INT, MPI_MIN, comm_ptr, + new_group_ptr, MPIR_AGREE_TAG, &errflag); + if (!success || errflag || mpi_errno_tmp) + success = 0; + + values[0] = success; + values[1] = *flag; + + /* Determine both the result of this function (mpi_errno) and the result + * of flag that will be returned to the user. */ + MPII_Allreduce_group(MPI_IN_PLACE, values, 2, MPI_INT, MPI_BAND, comm_ptr, + new_group_ptr, MPIR_AGREE_TAG, &errflag); + /* Ignore the result of the operation this time. Everyone will either + * return a failure because of !success earlier or they will return + * something useful for flag because of this operation. If there was a new + * failure in between the first allreduce and the second one, it's ignored + * here. */ + + if (failed_grp != MPIR_Group_empty) + MPIR_Group_release(failed_grp); + MPIR_Group_release(new_group_ptr); + MPIR_Group_release(comm_grp); + if (global_failed != MPIR_Group_empty) + MPIR_Group_release(global_failed); + + success = values[0]; + *flag = values[1]; + + if (!success) { + MPIR_ERR_SET(mpi_errno_tmp, MPIX_ERR_PROC_FAILED, "**mpix_comm_agree"); + MPIR_ERR_ADD(mpi_errno, mpi_errno_tmp); } fn_exit: From 635a7a99d1650332dd202fe0482a4c18d4ca9f8c Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 1 Apr 2022 23:41:35 -0500 Subject: [PATCH 588/607] test: add impls/mpich/ulfm/get_failed.c This is adapted from ft/failure_ack.c. The current ft tests are disabled by wholesale. Add to impls to get it tested. MPIX functions need be in impls folder anyway. Unlike ft/failure_ack.c, this test only test the functionality of MPIX_Comm_get_failed. It does not test other fault-tolerance behaviors such as MPI_Recv and MPI_Finalize when some of the processes abruptly exit/fail. --- test/mpi/configure.ac | 1 + test/mpi/impls/mpich/Makefile.am | 2 +- test/mpi/impls/mpich/ulfm/Makefile.am | 11 +++ test/mpi/impls/mpich/ulfm/get_failed.c | 92 ++++++++++++++++++++++++++ test/mpi/impls/mpich/ulfm/testlist | 1 + 5 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 test/mpi/impls/mpich/ulfm/Makefile.am create mode 100644 test/mpi/impls/mpich/ulfm/get_failed.c create mode 100644 test/mpi/impls/mpich/ulfm/testlist diff --git a/test/mpi/configure.ac b/test/mpi/configure.ac index 00fe982b108..c81c6d6d66c 100644 --- a/test/mpi/configure.ac +++ b/test/mpi/configure.ac @@ -1692,5 +1692,6 @@ AC_OUTPUT(maint/testmerge \ impls/mpich/threads/pt2pt/Makefile \ impls/mpich/cuda/Makefile \ impls/mpich/misc/Makefile \ + impls/mpich/ulfm/Makefile \ ) diff --git a/test/mpi/impls/mpich/Makefile.am b/test/mpi/impls/mpich/Makefile.am index 1f04f19665d..66ad0e68b08 100644 --- a/test/mpi/impls/mpich/Makefile.am +++ b/test/mpi/impls/mpich/Makefile.am @@ -7,5 +7,5 @@ include $(top_srcdir)/Makefile_single.mtest EXTRA_DIST = testlist.in -static_subdirs = mpi_t comm misc +static_subdirs = mpi_t comm misc ulfm SUBDIRS = $(static_subdirs) $(threadsdir) $(cudadir) diff --git a/test/mpi/impls/mpich/ulfm/Makefile.am b/test/mpi/impls/mpich/ulfm/Makefile.am new file mode 100644 index 00000000000..a1099d2fa42 --- /dev/null +++ b/test/mpi/impls/mpich/ulfm/Makefile.am @@ -0,0 +1,11 @@ +## +## Copyright (C) by Argonne National Laboratory +## See COPYRIGHT in top-level directory +## + +include $(top_srcdir)/Makefile_single.mtest + +EXTRA_DIST = testlist + +noinst_PROGRAMS = \ + get_failed diff --git a/test/mpi/impls/mpich/ulfm/get_failed.c b/test/mpi/impls/mpich/ulfm/get_failed.c new file mode 100644 index 00000000000..28d8c498cfa --- /dev/null +++ b/test/mpi/impls/mpich/ulfm/get_failed.c @@ -0,0 +1,92 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include +#include +#include + +/* + * This test makes sure that after a failure, the correct group of failed + * processes is returned from MPIX_Comm_get_failed. + * + * A bug will likely make test timeout. + */ + +#define CHECK_ERR(mpi_errno, name) do { \ + if (mpi_errno != MPI_SUCCESS) { \ + int ec, size; \ + char error[MPI_MAX_ERROR_STRING]; \ + MPI_Error_class(mpi_errno, &ec); \ + MPI_Error_string(mpi_errno, error, &size); \ + printf("%s returned an error: %d - %s\n", name, ec, error); \ + MPI_Abort(MPI_COMM_WORLD, 1); \ + } \ +} while (0) + +static void wait_for_fail(MPI_Group expected_fail_group) +{ + while (1) { + MPI_Group failed_grp; + int err = MPIX_Comm_get_failed(MPI_COMM_WORLD, &failed_grp); + CHECK_ERR(err, "MPIX_Comm_get_failed"); + + if (failed_grp != MPI_GROUP_EMPTY) { + int result; + MPI_Group_compare(expected_fail_group, failed_grp, &result); + MPI_Group_free(&failed_grp); + if (result == MPI_IDENT) { + break; + } + } + } +} + +char buf[10] = " No errors"; + +int main(int argc, char **argv) +{ + MPI_Init(&argc, &argv); + + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + if (size < 3) { + fprintf(stderr, "Must run with at least 3 processes\n"); + MPI_Abort(MPI_COMM_WORLD, 1); + } + + MPI_Group world_grp; + MPI_Comm_group(MPI_COMM_WORLD, &world_grp); + MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN); + + if (rank == 0) { + MPI_Group one_grp; + int one[] = { 1 }; + MPI_Group_incl(world_grp, 1, one, &one_grp); + wait_for_fail(one_grp); + MPI_Group_free(&one_grp); + + int err = MPI_Recv(buf, 10, MPI_CHAR, 2, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + CHECK_ERR(err, "MPI_Recv from rank 2"); + + MPI_Group two_grp; + int two[] = { 1, 2 }; + MPI_Group_incl(world_grp, 2, two, &two_grp); + wait_for_fail(two_grp); + MPI_Group_free(&two_grp); + + fprintf(stdout, " No errors\n"); + + } else if (rank == 1) { + exit(EXIT_FAILURE); + + } else if (rank == 2) { + MPI_Ssend(buf, 10, MPI_CHAR, 0, 0, MPI_COMM_WORLD); + exit(EXIT_FAILURE); + } + + MPI_Group_free(&world_grp); + /* This test does not test MPI_Finalize */ +} diff --git a/test/mpi/impls/mpich/ulfm/testlist b/test/mpi/impls/mpich/ulfm/testlist new file mode 100644 index 00000000000..3cdd673c77f --- /dev/null +++ b/test/mpi/impls/mpich/ulfm/testlist @@ -0,0 +1 @@ +get_failed 3 mpiexecarg=-disable-auto-cleanup resultTest=TestStatusNoErrors timeLimit=10 From 1cb2d25f8ea648ac38f5576502cf44bc08816bb6 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 4 Apr 2022 23:27:33 -0500 Subject: [PATCH 589/607] pmi: fix warnings - unused variables in pmi_v2.c --- src/pmi/src/pmi_v2.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pmi/src/pmi_v2.c b/src/pmi/src/pmi_v2.c index c0f6722a56d..7907d97c35a 100644 --- a/src/pmi/src/pmi_v2.c +++ b/src/pmi/src/pmi_v2.c @@ -475,12 +475,10 @@ PMI_API_PUBLIC const PMI2_keyval_t preput_keyval_vector[], char jobId[], int jobIdSize, int errors[]) { - int i, rc, spawncnt, total_num_processes, num_errcodes_found; + int i, rc, spawncnt, total_num_processes; int found; const char *jid; int jidlen; - char tempbuf[PMIU_MAXLINE]; - char *lead, *lag; int spawn_rc; const char *errmsg = NULL; PMI2_Command resp_cmd = { 0 }; From 589e21caaa6b7a783879104bfa1dffc19de0ea91 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 2 Apr 2022 09:19:37 -0500 Subject: [PATCH 590/607] release.pl: add creation of libpmi tarball There are users who would like to use libpmi (and hydra) without mpich. --- maint/release.pl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/maint/release.pl b/maint/release.pl index c50e3e29597..44f4ae41f09 100755 --- a/maint/release.pl +++ b/maint/release.pl @@ -298,6 +298,13 @@ sub run_cmd run_cmd("cp -a hydra-${version}.tar.gz ${root}/"); print("done\n"); +# Create the pmi tarball +print("===> Creating the final libpmi tarball... "); +run_cmd("cp -a ${expdir}/src/pmi libpmi-${version}"); +run_cmd("tar -czvf libpmi-${version}.tar.gz libpmi-${version}"); +run_cmd("cp -a libpmi-${version}.tar.gz ${root}/"); +print("done\n"); + # Create the testsuite tarball print("===> Creating the final mpich-testsuite tarball... "); my $target = "mpich-testsuite-$version"; From 42df8d271bc2b7c487832521da0ace281ff53218 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 19 Mar 2022 21:30:32 -0500 Subject: [PATCH 591/607] hydra: enhance proxy initial handshake Add a signaure to the first packet when proxy first connect to server. This guards against random connection and port scans. --- src/pm/hydra/lib/pmiserv_common.h | 6 ++++++ src/pm/hydra/mpiexec/pmiserv_cb.c | 16 +++++++++++++--- src/pm/hydra/proxy/pmip.c | 6 ++++-- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/pm/hydra/lib/pmiserv_common.h b/src/pm/hydra/lib/pmiserv_common.h index e9145fe7e72..6398e7fa773 100644 --- a/src/pm/hydra/lib/pmiserv_common.h +++ b/src/pm/hydra/lib/pmiserv_common.h @@ -28,6 +28,12 @@ struct HYD_pmcd_pmi_kvs { struct HYD_pmcd_pmi_kvs_pair *tail; }; +/* init header proxy send to server upon connection */ +struct HYD_pmcd_init_hdr { + char signature[4]; /* HYD\0 */ ; + int proxy_id; +}; + struct HYD_pmcd_hdr { /* The set of commands supported */ enum HYD_pmcd_cmd { diff --git a/src/pm/hydra/mpiexec/pmiserv_cb.c b/src/pm/hydra/mpiexec/pmiserv_cb.c index 531163cf12c..631c1ccd99b 100644 --- a/src/pm/hydra/mpiexec/pmiserv_cb.c +++ b/src/pm/hydra/mpiexec/pmiserv_cb.c @@ -10,6 +10,7 @@ #include "debugger.h" #include "pmiserv.h" #include "pmiserv_utils.h" +#include "pmiserv_common.h" #include "pmiserv_pmi.h" static HYD_status handle_pmi_cmd(int fd, int pgid, int pid, char *buf, int pmi_version) @@ -441,9 +442,18 @@ HYD_status HYD_pmcd_pmiserv_proxy_init_cb(int fd, HYD_event_t events, void *user pgid = ((int) (size_t) userp); /* Read the proxy ID */ - status = HYDU_sock_read(fd, &proxy_id, sizeof(int), &count, &closed, HYDU_SOCK_COMM_MSGWAIT); - HYDU_ERR_POP(status, "sock read returned error\n"); - HYDU_ASSERT(!closed, status); + struct HYD_pmcd_init_hdr init_hdr; + status = + HYDU_sock_read(fd, &init_hdr, sizeof(init_hdr), &count, &closed, HYDU_SOCK_COMM_MSGWAIT); + if (status != HYD_SUCCESS || strcmp(init_hdr.signature, "HYD") != 0) { + /* Ignore random connections (e.g. port scanner) */ + status = HYDT_dmx_deregister_fd(fd); + HYDU_ERR_POP(status, "unable to register fd\n"); + + close(fd); + goto fn_exit; + } + proxy_id = init_hdr.proxy_id; /* Find the process group */ for (pg = &HYD_server_info.pg_list; pg; pg = pg->next) diff --git a/src/pm/hydra/proxy/pmip.c b/src/pm/hydra/proxy/pmip.c index 6c222960cff..133420273dc 100644 --- a/src/pm/hydra/proxy/pmip.c +++ b/src/pm/hydra/proxy/pmip.c @@ -151,9 +151,11 @@ int main(int argc, char **argv) HYD_pmcd_pmip.upstream.server_name, HYD_pmcd_pmip.upstream.server_port); } + struct HYD_pmcd_init_hdr init_hdr; + strncpy(init_hdr.signature, "HYD", 4); + init_hdr.proxy_id = HYD_pmcd_pmip.local.id; status = HYDU_sock_write(HYD_pmcd_pmip.upstream.control, - &HYD_pmcd_pmip.local.id, sizeof(HYD_pmcd_pmip.local.id), &sent, - &closed, HYDU_SOCK_COMM_MSGWAIT); + &init_hdr, sizeof(init_hdr), &sent, &closed, HYDU_SOCK_COMM_MSGWAIT); HYDU_ERR_POP(status, "unable to send the proxy ID to the server\n"); if (closed) goto fn_fail; From 2e7a0bbe4a175b9bf60f95f5d844e30c36261fe8 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Fri, 25 Mar 2022 16:43:59 -0500 Subject: [PATCH 592/607] romio: fix MPIU_external32_buffer_setup It should allocate a buffer size of true_lb + true_extent rather than just true_extent. --- src/mpi/romio/mpi-io/mpiu_external32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mpi/romio/mpi-io/mpiu_external32.c b/src/mpi/romio/mpi-io/mpiu_external32.c index d4da99bd70e..1817ade05ad 100644 --- a/src/mpi/romio/mpi-io/mpiu_external32.c +++ b/src/mpi/romio/mpi-io/mpiu_external32.c @@ -124,7 +124,7 @@ int MPIU_datatype_full_size(MPI_Datatype datatype, MPI_Aint * size) if (error_code != MPI_SUCCESS) goto fn_exit; - *size = true_extent; + *size = true_lb + true_extent; fn_exit: return error_code; } From 55ebf1416f59706879839df7b3968c6c9fd5df8a Mon Sep 17 00:00:00 2001 From: Sriraj Date: Thu, 27 Jan 2022 05:56:15 -0600 Subject: [PATCH 593/607] coll: Add allreduce blocking ring algorithm Author: Taru Doodi --- src/mpi/coll/allreduce/Makefile.mk | 1 + src/mpi/coll/allreduce/allreduce_intra_ring.c | 158 ++++++++++++++++++ src/mpi/coll/coll_algorithms.txt | 2 + src/mpi/coll/cvars.txt | 1 + src/mpi/coll/include/csel_container.h | 1 + src/mpi/coll/src/csel_container.c | 2 + 6 files changed, 165 insertions(+) create mode 100644 src/mpi/coll/allreduce/allreduce_intra_ring.c diff --git a/src/mpi/coll/allreduce/Makefile.mk b/src/mpi/coll/allreduce/Makefile.mk index 6eb5a97ea30..15acacfd990 100644 --- a/src/mpi/coll/allreduce/Makefile.mk +++ b/src/mpi/coll/allreduce/Makefile.mk @@ -14,4 +14,5 @@ mpi_core_sources += \ src/mpi/coll/allreduce/allreduce_intra_smp.c \ src/mpi/coll/allreduce/allreduce_intra_tree.c \ src/mpi/coll/allreduce/allreduce_intra_recexch.c \ + src/mpi/coll/allreduce/allreduce_intra_ring.c \ src/mpi/coll/allreduce/allreduce_inter_reduce_exchange_bcast.c diff --git a/src/mpi/coll/allreduce/allreduce_intra_ring.c b/src/mpi/coll/allreduce/allreduce_intra_ring.c new file mode 100644 index 00000000000..34b6a2082d6 --- /dev/null +++ b/src/mpi/coll/allreduce/allreduce_intra_ring.c @@ -0,0 +1,158 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * Copyright (C) by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + * + */ +/* Routine to schedule a ring exchange based allreduce. The algorithm is + * based on Baidu's ring based allreduce. http://andrew.gibiansky.com/ */ + +#include "mpiimpl.h" + +int MPIR_Allreduce_intra_ring(const void *sendbuf, void *recvbuf, MPI_Aint count, + MPI_Datatype datatype, MPI_Op op, + MPIR_Comm * comm, MPIR_Errflag_t * errflag) +{ + int mpi_errno = MPI_SUCCESS, mpi_errno_ret = MPI_SUCCESS; + int i, src, dst; + int nranks, is_inplace, rank; + size_t extent; + MPI_Aint lb, true_extent; + MPI_Aint *cnts, *displs; /* Created for the allgatherv call */ + int send_rank, recv_rank, total_count; + void *tmpbuf; + int tag; + MPIR_Request **reqs; + int num_reqs = 2; /* one send and one recv per transfer */ + + is_inplace = (sendbuf == MPI_IN_PLACE); + nranks = MPIR_Comm_size(comm); + rank = MPIR_Comm_rank(comm); + + MPIR_CHKLMEM_DECL(1); + + MPIR_Datatype_get_extent_macro(datatype, extent); + MPIR_Type_get_true_extent_impl(datatype, &lb, &true_extent); + extent = MPL_MAX(extent, true_extent); + + cnts = (MPI_Aint *) MPL_malloc(nranks * sizeof(MPI_Aint), MPL_MEM_COLL); + MPIR_ERR_CHKANDJUMP(!cnts, mpi_errno, MPI_ERR_OTHER, "**nomem"); + displs = (MPI_Aint *) MPL_malloc(nranks * sizeof(MPI_Aint), MPL_MEM_COLL); + MPIR_ERR_CHKANDJUMP(!displs, mpi_errno, MPI_ERR_OTHER, "**nomem"); + + MPIR_CHKLMEM_MALLOC(reqs, MPIR_Request **, (num_reqs * sizeof(MPIR_Request *)), mpi_errno, + "reqs", MPL_MEM_BUFFER); + + for (i = 0; i < nranks; i++) + cnts[i] = 0; + + total_count = 0; + for (i = 0; i < nranks; i++) { + cnts[i] = (count + nranks - 1) / nranks; + if (total_count + cnts[i] > count) { + cnts[i] = count - total_count; + break; + } else + total_count += cnts[i]; + } + + displs[0] = 0; + for (i = 1; i < nranks; i++) + displs[i] = displs[i - 1] + cnts[i - 1]; + + /* Phase 1: copy to tmp buf */ + if (!is_inplace) { + mpi_errno = MPIR_Localcopy(sendbuf, count, datatype, recvbuf, count, datatype); + if (mpi_errno) { + MPIR_ERR_POP(mpi_errno); + } + } + + /* Phase 2: Ring based send recv reduce scatter */ + /* Need only 2 spaces for current and previous reduce_id(s) */ + tmpbuf = MPL_malloc(count * extent, MPL_MEM_COLL); + MPIR_ERR_CHKANDJUMP(!tmpbuf, mpi_errno, MPI_ERR_OTHER, "**nomem"); + + src = (nranks + rank - 1) % nranks; + dst = (rank + 1) % nranks; + + for (i = 0; i < nranks - 1; i++) { + num_reqs = 0; + recv_rank = (nranks + rank - 2 - i) % nranks; + send_rank = (nranks + rank - 1 - i) % nranks; + + /* get a new tag to prevent out of order messages */ + mpi_errno = MPIR_Sched_next_tag(comm, &tag); + if (mpi_errno) + MPIR_ERR_POP(mpi_errno); + + mpi_errno = + MPIC_Irecv(tmpbuf, cnts[recv_rank], datatype, src, tag, comm, &reqs[num_reqs++]); + if (mpi_errno) { + /* for communication errors, just record the error but continue */ + *errflag = MPIR_ERR_OTHER; + MPIR_ERR_SET(mpi_errno, *errflag, "**fail"); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + + + mpi_errno = MPIC_Isend((char *) recvbuf + displs[send_rank] * extent, cnts[send_rank], + datatype, dst, tag, comm, &reqs[num_reqs++], errflag); + if (mpi_errno) { + /* for communication errors, just record the error but continue */ + *errflag = MPIR_ERR_OTHER; + MPIR_ERR_SET(mpi_errno, *errflag, "**fail"); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + + mpi_errno = MPIC_Waitall(num_reqs, reqs, MPI_STATUSES_IGNORE, errflag); + if (mpi_errno) { + /* for communication errors, just record the error but continue */ + *errflag = MPIR_ERR_OTHER; + MPIR_ERR_SET(mpi_errno, *errflag, "**fail"); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + + + mpi_errno = + MPIR_Reduce_local(tmpbuf, (char *) recvbuf + displs[recv_rank] * extent, + cnts[recv_rank], datatype, op); + if (mpi_errno) { + /* for communication errors, just record the error but continue */ + *errflag = MPIR_ERR_OTHER; + MPIR_ERR_SET(mpi_errno, *errflag, "**fail"); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + + MPL_DBG_MSG_FMT(MPIR_DBG_COLL, VERBOSE, + (MPL_DBG_FDEST, + "displs[recv_rank:%d]:%d, cnts[recv_rank:%d, displs[send_rank:%d]:%d, cnts[send_rank:%d]:%d]:%d ", + recv_rank, displs[recv_rank], recv_rank, cnts[recv_rank], send_rank, + displs[send_rank], send_rank, cnts[send_rank])); + } + + /* Phase 3: Allgatherv ring, so everyone has the reduced data */ + mpi_errno = MPIR_Allgatherv_intra_ring(MPI_IN_PLACE, -1, MPI_DATATYPE_NULL, recvbuf, cnts, + displs, datatype, comm, errflag); + if (mpi_errno) { + /* for communication errors, just record the error but continue */ + *errflag = MPIR_ERR_OTHER; + MPIR_ERR_SET(mpi_errno, *errflag, "**fail"); + MPIR_ERR_ADD(mpi_errno_ret, mpi_errno); + } + + MPL_free(cnts); + MPL_free(displs); + MPL_free(tmpbuf); + MPIR_CHKLMEM_FREEALL(); + + fn_exit: + if (mpi_errno_ret) + mpi_errno = mpi_errno_ret; + else if (*errflag != MPIR_ERR_NONE) + MPIR_ERR_SET(mpi_errno, *errflag, "**coll_fail"); + return mpi_errno; + + fn_fail: + goto fn_exit; +} diff --git a/src/mpi/coll/coll_algorithms.txt b/src/mpi/coll/coll_algorithms.txt index d96fd7f76d3..07c427dba24 100644 --- a/src/mpi/coll/coll_algorithms.txt +++ b/src/mpi/coll/coll_algorithms.txt @@ -338,6 +338,8 @@ allreduce-intra: recexch extra_params: k, single_phase_recv cvar_params: RECEXCH_KVAL, RECEXCH_SINGLE_PHASE_RECV + ring + restrictions: commutative allreduce-inter: reduce_exchange_bcast iallreduce-intra: diff --git a/src/mpi/coll/cvars.txt b/src/mpi/coll/cvars.txt index ecbb7ad4de1..e3a73ab89cf 100644 --- a/src/mpi/coll/cvars.txt +++ b/src/mpi/coll/cvars.txt @@ -1255,6 +1255,7 @@ cvars: reduce_scatter_allgather - Force reduce scatter allgather algorithm tree - Force pipelined tree algorithm recexch - Force generic transport recursive exchange algorithm + ring - Force ring algorithm - name : MPIR_CVAR_ALLREDUCE_TREE_TYPE category : COLLECTIVE diff --git a/src/mpi/coll/include/csel_container.h b/src/mpi/coll/include/csel_container.h index 73c4caf2f24..1a2cf41a24f 100644 --- a/src/mpi/coll/include/csel_container.h +++ b/src/mpi/coll/include/csel_container.h @@ -27,6 +27,7 @@ typedef enum { MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_intra_smp, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_intra_tree, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_intra_recexch, + MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_intra_ring, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_inter_reduce_exchange_bcast, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_allcomm_nb, MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Alltoall_intra_brucks, diff --git a/src/mpi/coll/src/csel_container.c b/src/mpi/coll/src/csel_container.c index d88fd61122c..c7c71295707 100644 --- a/src/mpi/coll/src/csel_container.c +++ b/src/mpi/coll/src/csel_container.c @@ -308,6 +308,8 @@ void *MPII_Create_container(struct json_object *obj) cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_intra_tree; else if (!strcmp(ckey, "algorithm=MPIR_Allreduce_intra_recexch")) cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_intra_recexch; + else if (!strcmp(ckey, "algorithm=MPIR_Allreduce_intra_ring")) + cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_intra_ring; else if (!strcmp(ckey, "algorithm=MPIR_Allreduce_inter_reduce_exchange_bcast")) cnt->id = MPII_CSEL_CONTAINER_TYPE__ALGORITHM__MPIR_Allreduce_inter_reduce_exchange_bcast; From efdcf6512e500356a2f67c3bf6b7f4303b4a1641 Mon Sep 17 00:00:00 2001 From: Sriraj Date: Wed, 16 Feb 2022 13:39:56 -0600 Subject: [PATCH 594/607] test: Add tests for ring based allreduce --- test/mpi/maint/coll_cvars.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test/mpi/maint/coll_cvars.txt b/test/mpi/maint/coll_cvars.txt index a371dd8b43b..979cabc9784 100644 --- a/test/mpi/maint/coll_cvars.txt +++ b/test/mpi/maint/coll_cvars.txt @@ -236,6 +236,7 @@ algorithms: recexch .MPIR_CVAR_ALLREDUCE_RECEXCH_KVAL=2,3,4,5,9 .MPIR_CVAR_ALLREDUCE_RECEXCH_SINGLE_PHASE_RECV=0,1 + ring posix:release_gather .MPIR_CVAR_COLL_SHM_LIMIT_PER_NODE=131072 .MPIR_CVAR_REDUCE_INTRANODE_BUFFER_TOTAL_SIZE=16384 From 8a7b09433f4186d1be951ec436eb57e5b8670e99 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Wed, 6 Apr 2022 09:27:02 -0500 Subject: [PATCH 595/607] pmi: add configure option to disable threads Add the same --with-thread-package options as in MPL for consistent thread support. This fixes compile error when MPL is configured with --with-thread-package=none --- src/pmi/configure.ac | 13 +++++++++++++ src/pmi/src/pmi_v2.c | 30 +++++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/pmi/configure.ac b/src/pmi/configure.ac index 24605dc70da..b211d020251 100644 --- a/src/pmi/configure.ac +++ b/src/pmi/configure.ac @@ -51,6 +51,19 @@ AH_BOTTOM([ #endif ]) +AC_ARG_WITH([thread-package], + AS_HELP_STRING([--with-thread-package], [whether to enable threads])) + +case "$with_thread_package" in + no|none) + : + ;; + *) + AC_DEFINE([HAVE_THREADS], 1, [Define if MPL supports threads]) + ;; +esac + + # MPL m4_define([mpl_embedded_dir],[mpl]) diff --git a/src/pmi/src/pmi_v2.c b/src/pmi/src/pmi_v2.c index 7907d97c35a..7ddf43cc0fe 100644 --- a/src/pmi/src/pmi_v2.c +++ b/src/pmi/src/pmi_v2.c @@ -117,9 +117,11 @@ static int PMI2_rank = 0; static int PMI2_is_threaded = 0; /* Set this to true to require thread safety */ +#ifdef HAVE_THREADS static MPL_thread_mutex_t mutex; static int blocked = PMIU_FALSE; static MPL_thread_cond_t cond; +#endif /* XXX DJG the "const"s on both of these functions and the Keyvalpair * struct are wrong in the isCopy==TRUE case! */ @@ -247,9 +249,17 @@ static inline int SEARCH_REMOVE(PMI2_Command * cmd) /* ------------------------------------------------------------------------- */ PMI_API_PUBLIC int PMI2_Set_threaded(int is_threaded) { - PMI2_is_threaded = is_threaded; +#ifndef HAVE_THREADS + if (is_threaded) { + return PMI2_FAIL; + } + return PMI2_SUCCESS; +#else + PMI2_is_threaded = is_threaded; return PMI2_SUCCESS; + +#endif } PMI_API_PUBLIC int PMI2_Init(int *spawned, int *size, int *rank, int *appnum) @@ -261,10 +271,12 @@ PMI_API_PUBLIC int PMI2_Init(int *spawned, int *size, int *rank, int *appnum) char *pmiid; int ret; +#if HAVE_THREADS MPL_thread_mutex_create(&mutex, &ret); PMIU_Assert(!ret); MPL_thread_cond_create(&cond, &ret); PMIU_Assert(!ret); +#endif /* FIXME: Why is setvbuf commented out? */ /* FIXME: What if the output should be fully buffered (directed to file)? @@ -1323,6 +1335,7 @@ int PMIi_ReadCommand(int fd, PMI2_Command * cmd) memset(cmd_len_str, 0, sizeof(cmd_len_str)); if (PMI2_is_threaded) { +#ifdef HAVE_THREADS MPL_thread_mutex_lock(&mutex, &err, MPL_THREAD_PRIO_HIGH); while (blocked && !cmd->complete) @@ -1335,6 +1348,9 @@ int PMIi_ReadCommand(int fd, PMI2_Command * cmd) blocked = PMIU_TRUE; MPL_thread_mutex_unlock(&mutex, &err); +#else + PMIU_Assert(0); +#endif } do { @@ -1458,10 +1474,14 @@ int PMIi_ReadCommand(int fd, PMI2_Command * cmd) } while (!cmd->complete); if (PMI2_is_threaded) { +#ifdef HAVE_THREADS MPL_thread_mutex_lock(&mutex, &err, MPL_THREAD_PRIO_HIGH); blocked = PMIU_FALSE; MPL_thread_cond_broadcast(&cond, &err); MPL_thread_mutex_unlock(&mutex, &err); +#else + PMIU_Assert(0); +#endif } fn_exit: @@ -1581,6 +1601,7 @@ int PMIi_WriteSimpleCommand(int fd, PMI2_Command * resp, const char cmd[], if (PMI2_is_threaded) { +#ifdef HAVE_THREADS MPL_thread_mutex_lock(&mutex, &err, MPL_THREAD_PRIO_HIGH); while (blocked) @@ -1588,6 +1609,9 @@ int PMIi_WriteSimpleCommand(int fd, PMI2_Command * resp, const char cmd[], blocked = PMIU_TRUE; MPL_thread_mutex_unlock(&mutex, &err); +#else + PMIU_Assert(0); +#endif } if (PMI2_debug) @@ -1605,10 +1629,14 @@ int PMIi_WriteSimpleCommand(int fd, PMI2_Command * resp, const char cmd[], } while (offset < cmdlen + PMII_COMMANDLEN_SIZE); if (PMI2_is_threaded) { +#ifdef HAVE_THREADS MPL_thread_mutex_lock(&mutex, &err, MPL_THREAD_PRIO_HIGH); blocked = PMIU_FALSE; MPL_thread_cond_broadcast(&cond, &err); MPL_thread_mutex_unlock(&mutex, &err); +#else + PMIU_Assert(0); +#endif } fn_exit: From 819f697d3404b8e6e4a91ee19cd0e6872b4ae076 Mon Sep 17 00:00:00 2001 From: Mohamad Chaarawi Date: Fri, 8 Apr 2022 16:37:28 +0000 Subject: [PATCH 596/607] use nowait for MPI test on async event Signed-off-by: Mohamad Chaarawi --- src/mpi/romio/adio/ad_daos/ad_daos_io.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/mpi/romio/adio/ad_daos/ad_daos_io.c b/src/mpi/romio/adio/ad_daos/ad_daos_io.c index 91ed8588f87..5efa09b63a9 100644 --- a/src/mpi/romio/adio/ad_daos/ad_daos_io.c +++ b/src/mpi/romio/adio/ad_daos/ad_daos_io.c @@ -169,15 +169,14 @@ int ADIOI_DAOS_aio_poll_fn(void *extra_state, MPI_Status * status) int ret; bool flag; - /* MSC - MPICH hangs if we just test with NOWAIT.. */ - ret = daos_event_test(&aio_req->daos_event, DAOS_EQ_WAIT, &flag); + ret = daos_event_test(&aio_req->daos_event, DAOS_EQ_NOWAIT, &flag); if (ret != 0) return MPI_UNDEFINED; if (flag) MPI_Grequest_complete(aio_req->req); else - return MPI_UNDEFINED; + return ret; if (aio_req->daos_event.ev_error != 0) ret = ADIOI_DAOS_err("ADIOI_DAOS_aio_poll_fn", "DAOS Event Error", __LINE__, ret); From cdc162c94803828e29e7248156019d9c24dae983 Mon Sep 17 00:00:00 2001 From: Mohamad Chaarawi Date: Fri, 8 Apr 2022 16:40:26 +0000 Subject: [PATCH 597/607] update packaging Signed-off-by: Mohamad Chaarawi --- packaging/Dockerfile.mockbuild | 8 ++++---- packaging/Makefile_packaging.mk | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packaging/Dockerfile.mockbuild b/packaging/Dockerfile.mockbuild index 3f6fe67b9d0..89d494f59a0 100644 --- a/packaging/Dockerfile.mockbuild +++ b/packaging/Dockerfile.mockbuild @@ -1,11 +1,11 @@ # -# Copyright 2018-2021, Intel Corporation +# Copyright 2018-2022, Intel Corporation # # 'recipe' for Docker to build an RPM # # Pull base image -FROM fedora:latest +FROM fedora:35 LABEL maintainer="daos@daos.groups.io>" # use same UID as host and default value of 1000 if not specified @@ -14,7 +14,7 @@ ARG UID=1000 # Install basic tools RUN dnf -y install mock make \ rpm-build curl createrepo rpmlint redhat-lsb-core git \ - python-srpm-macros rpmdevtools + python-srpm-macros rpmdevtools mock-core-configs\ \<\ 37.1 # Add build user (to keep rpmbuild happy) ENV USER build @@ -29,5 +29,5 @@ RUN grep use_nspawn /etc/mock/site-defaults.cfg || \ echo "config_opts['use_nspawn'] = False" >> /etc/mock/site-defaults.cfg ARG CACHEBUST -RUN dnf -y upgrade && \ +RUN dnf -y upgrade --exclude mock-core-configs && \ dnf clean all diff --git a/packaging/Makefile_packaging.mk b/packaging/Makefile_packaging.mk index 42b8e281c80..b59782ec5c9 100644 --- a/packaging/Makefile_packaging.mk +++ b/packaging/Makefile_packaging.mk @@ -154,6 +154,10 @@ ifeq ($(DL_NAME),) DL_NAME = $(NAME) endif +$(DL_NAME)$(DL_VERSION).linux-amd64.tar.$(SRC_EXT): $(SPEC) $(CALLING_MAKEFILE) + rm -f ./$(DL_NAME)*.tar{gz,bz*,xz} + $(SPECTOOL) -g $(SPEC) + $(DL_NAME)-$(DL_VERSION).tar.$(SRC_EXT).asc: $(SPEC) $(CALLING_MAKEFILE) rm -f ./$(DL_NAME)-*.tar.{gz,bz*,xz}.asc $(SPECTOOL) -g $(SPEC) From 320e87f4ee6aa87a13e20b721d20d52699ab6648 Mon Sep 17 00:00:00 2001 From: Mohamad Chaarawi Date: Fri, 8 Apr 2022 16:45:31 +0000 Subject: [PATCH 598/607] replace centos8 with el8 Signed-off-by: Mohamad Chaarawi --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index fe51e513bc5..215ff1bdded 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -42,7 +42,7 @@ // no debian/ support yet // no pmix for leap15 yet -packageBuildingPipeline(['distros' : ['centos7', 'centos8', 'leap15'], +packageBuildingPipeline(['distros' : ['centos7', 'el8', 'leap15'], 'publish_branch': 'daos_adio-rpm', 'make args' : 'CHROOT=true -f Makefile-rpm.mk', 'add_make_targets': 'romio-tarball', From 31de445748b09d3910245c86f5e862825bc0cda3 Mon Sep 17 00:00:00 2001 From: Taru Doodi Date: Thu, 24 Feb 2022 13:29:05 -0600 Subject: [PATCH 599/607] coll: Add support functions for multi-leader allreduce Co-authored-by: Surabhi Jain --- src/include/mpir_comm.h | 1 + src/mpi/comm/commutil.c | 47 +++++++++++++++++ src/mpid/ch4/include/mpidpre.h | 16 ++++++ src/mpid/ch4/src/ch4_coll.h | 31 ++++++++++++ src/mpid/ch4/src/ch4_comm.c | 92 ++++++++++++++++++++++++++++++++++ src/mpid/ch4/src/ch4_comm.h | 1 + src/mpl/include/mpl_math.h | 29 +++++++++++ 7 files changed, 217 insertions(+) diff --git a/src/include/mpir_comm.h b/src/include/mpir_comm.h index fdc3a5bd335..e83b627af1e 100644 --- a/src/include/mpir_comm.h +++ b/src/include/mpir_comm.h @@ -374,6 +374,7 @@ extern struct MPIR_Commops *MPIR_Comm_fns; /* Communicator creation functio int MPII_Comm_init(MPIR_Comm *); int MPII_Comm_is_node_consecutive(MPIR_Comm *); +int MPII_Comm_is_node_balanced(MPIR_Comm *, int *, bool *); int MPII_Comm_copy(MPIR_Comm * comm_ptr, int size, MPIR_Info * info, MPIR_Comm ** outcomm_ptr); int MPII_Comm_copy_data(MPIR_Comm * comm_ptr, MPIR_Info * info, MPIR_Comm ** outcomm_ptr); diff --git a/src/mpi/comm/commutil.c b/src/mpi/comm/commutil.c index bb897a7ff66..0cb8bd58af2 100644 --- a/src/mpi/comm/commutil.c +++ b/src/mpi/comm/commutil.c @@ -1190,3 +1190,50 @@ int MPII_compare_info_hint(const char *hint_str, MPIR_Comm * comm_ptr, int *info fn_fail: goto fn_exit; } + +/* Returns true if the communicator is node-aware and the number of processes in all the nodes are + * same */ +int MPII_Comm_is_node_balanced(MPIR_Comm * comm, int *num_nodes, bool * node_balanced) +{ + int i = 0; + int mpi_errno = MPI_SUCCESS; + int *ranks_per_node; + *num_nodes = 0; + + MPIR_CHKPMEM_DECL(1); + + if (!MPIR_Comm_is_parent_comm(comm)) { + *node_balanced = false; + goto fn_exit; + } + + /* Find maximum value in the internode_table */ + for (i = 0; i < comm->local_size; i++) { + if (comm->internode_table[i] > *num_nodes) { + *num_nodes = comm->internode_table[i]; + } + } + /* number of nodes is max_node_id + 1 */ + (*num_nodes)++; + + MPIR_CHKPMEM_CALLOC(ranks_per_node, int *, + *num_nodes * sizeof(int), mpi_errno, "ranks per node", MPL_MEM_OTHER); + + for (i = 0; i < comm->local_size; i++) { + ranks_per_node[comm->internode_table[i]]++; + } + + for (i = 1; i < *num_nodes; i++) { + if (ranks_per_node[i - 1] != ranks_per_node[i]) { + *node_balanced = false; + goto fn_exit; + } + } + + *node_balanced = true; + fn_exit: + MPIR_CHKPMEM_REAP(); + return mpi_errno; + fn_fail: + goto fn_exit; +} diff --git a/src/mpid/ch4/include/mpidpre.h b/src/mpid/ch4/include/mpidpre.h index b1008be4aa7..ef63c5bdda6 100644 --- a/src/mpid/ch4/include/mpidpre.h +++ b/src/mpid/ch4/include/mpidpre.h @@ -609,11 +609,27 @@ typedef struct MPIDI_Devcomm_t { MPIDI_rank_map_t map; MPIDI_rank_map_t local_map; + struct MPIR_Comm *multi_leads_comm; + /* sub communicators related for multi-leaders based implementation */ + struct MPIR_Comm *inter_node_leads_comm, *sub_node_comm, *intra_node_leads_comm; + int spanned_num_nodes; /* comm spans over these number of nodes */ + /* Pointers to store info of multi-leaders based compositions */ + struct MPIDI_Multileads_comp_info_t *allreduce_comp_info; + int shm_size_per_lead; + void *csel_comm; /* collective selection handle */ } ch4; } MPIDI_Devcomm_t; + +typedef struct MPIDI_Multileads_comp_info_t { + int use_multi_leads; /* if multi-leaders based composition can be used for comm */ + void *shm_addr; +} MPIDI_Multileads_comp_info_t; + #define MPIDIG_COMM(comm,field) ((comm)->dev.ch4.am).field #define MPIDI_COMM(comm,field) ((comm)->dev.ch4).field +#define MPIDI_COMM_ALLREDUCE(comm,field) ((comm)->dev.ch4.allreduce_comp_info)->field + typedef struct { union { diff --git a/src/mpid/ch4/src/ch4_coll.h b/src/mpid/ch4/src/ch4_coll.h index f456466f7f1..31c10656519 100644 --- a/src/mpid/ch4/src/ch4_coll.h +++ b/src/mpid/ch4/src/ch4_coll.h @@ -285,6 +285,37 @@ MPL_STATIC_INLINE_PREFIX int MPID_Bcast(void *buffer, MPI_Aint count, MPI_Dataty goto fn_exit; } +MPL_STATIC_INLINE_PREFIX void MPIDI_Allreduce_fill_multi_leads_info(MPIR_Comm * comm) +{ + int node_comm_size = 0, num_nodes; + bool node_balanced = false; + + if (MPIDI_COMM(comm, allreduce_comp_info) == NULL) { + /* If multi-leads allreduce is enabled and the info object is not yet set */ + MPIDI_COMM(comm, allreduce_comp_info) = + MPL_malloc(sizeof(MPIDI_Multileads_comp_info_t), MPL_MEM_OTHER); + MPIR_Assert(MPIDI_COMM(comm, allreduce_comp_info)); + MPIDI_COMM_ALLREDUCE(comm, use_multi_leads) = -1; + MPIDI_COMM_ALLREDUCE(comm, shm_addr) = NULL; + MPIDI_COMM(comm, shm_size_per_lead) = 1; + } + /* Find if the comm meets the constraints and store that info in the data structure */ + if (MPIDI_COMM_ALLREDUCE(comm, use_multi_leads) == -1) { + if (comm->node_comm) + node_comm_size = MPIR_Comm_size(comm->node_comm); + /* Get number of nodes it spans over and if it has equal number of ranks per node */ + MPII_Comm_is_node_balanced(comm, &num_nodes, &node_balanced); + MPIDI_COMM(comm, spanned_num_nodes) = num_nodes; + + if (num_nodes > 1 && node_comm_size > 1 && node_balanced) { + MPIDI_COMM_ALLREDUCE(comm, use_multi_leads) = 1; + } else { + MPIDI_COMM_ALLREDUCE(comm, use_multi_leads) = 0; + } + } + +} + MPL_STATIC_INLINE_PREFIX int MPIDI_Allreduce_allcomm_composition_json(const void *sendbuf, void *recvbuf, MPI_Aint count, MPI_Datatype datatype, diff --git a/src/mpid/ch4/src/ch4_comm.c b/src/mpid/ch4/src/ch4_comm.c index 40aaa60e387..eec26d97032 100644 --- a/src/mpid/ch4/src/ch4_comm.c +++ b/src/mpid/ch4/src/ch4_comm.c @@ -189,6 +189,13 @@ int MPID_Comm_commit_pre_hook(MPIR_Comm * comm) } } + MPIDI_COMM(comm, multi_leads_comm) = NULL; + MPIDI_COMM(comm, inter_node_leads_comm) = NULL; + MPIDI_COMM(comm, sub_node_comm) = NULL; + MPIDI_COMM(comm, intra_node_leads_comm) = NULL; + MPIDI_COMM(comm, spanned_num_nodes) = -1; + MPIDI_COMM(comm, allreduce_comp_info) = NULL; + mpi_errno = MPIDIG_init_comm(comm); MPIR_ERR_CHECK(mpi_errno); @@ -244,6 +251,37 @@ int MPID_Comm_free_hook(MPIR_Comm * comm) { int mpi_errno; MPIR_FUNC_ENTER; + + if (MPIDI_COMM(comm, multi_leads_comm) != NULL) { + MPIR_Comm_release(MPIDI_COMM(comm, multi_leads_comm)); + } + + if (MPIDI_COMM(comm, inter_node_leads_comm) != NULL) { + MPIR_Comm_release(MPIDI_COMM(comm, inter_node_leads_comm)); + } + + if (MPIDI_COMM(comm, sub_node_comm) != NULL) { + MPIR_Comm_release(MPIDI_COMM(comm, sub_node_comm)); + } + + if (MPIDI_COMM(comm, intra_node_leads_comm) != NULL) { + MPIR_Comm_release(MPIDI_COMM(comm, intra_node_leads_comm)); + } + + + if (MPIDI_COMM(comm, allreduce_comp_info) != NULL) { + /* Destroy the associated shared memory region used by multi-leads Allreduce */ + if (MPIDI_COMM_ALLREDUCE(comm, shm_addr) != NULL) { + mpi_errno = MPIDU_shm_free(MPIDI_COMM_ALLREDUCE(comm, shm_addr)); + if (mpi_errno != MPI_SUCCESS) { + MPIR_ERR_POP(mpi_errno); + } + } + MPL_free(MPIDI_COMM(comm, allreduce_comp_info)); + } + + + /* release ref to avts */ switch (MPIDI_COMM(comm, map).mode) { case MPIDI_RANK_MAP_NONE: @@ -638,3 +676,57 @@ int MPID_Create_intercomm_from_lpids(MPIR_Comm * newcomm_ptr, int size, const ui fn_fail: goto fn_exit; } + +/* Example: Ranks 0-3 on node 0 and 4-7 on node 1. Num_leaders = 2 */ +/* This function creates 3 kinds of communicators - + * 1. Inter-node sub-comms. A comm out of first leaders from each node, next comm out of second + * leaders from each node and so on. (Example: (0,4), (2,6)) + * 2. Intra-node sub-communicators. A leader and its followers. (Example: (0,1), (2,3), (4,5), (6,7)) + * 3. Intra-node sub-comm consisting of all the leaders on that node. (Example: (0,2), (4,6)) + */ +int MPIDI_Comm_create_multi_leader_subcomms(MPIR_Comm * comm, int num_leaders) +{ + int mpi_errno = MPI_SUCCESS; + int is_leader_color = MPI_UNDEFINED; + int sub_node_comm_size; + + MPIR_FUNC_ENTER; + + sub_node_comm_size = MPIR_Comm_size(comm->node_comm) / num_leaders; + /* If node_comm_size is same as number of leaders, each rank should be a leader */ + if (MPIR_Comm_size(comm->node_comm) == num_leaders) + is_leader_color = MPIR_Comm_rank(comm->node_comm); + else if (MPIR_Comm_rank(comm->node_comm) % sub_node_comm_size == 0) + is_leader_color = MPIR_Comm_rank(comm->node_comm) / sub_node_comm_size; + + /* Create the inter-node leaders sub comms */ + mpi_errno = MPIR_Comm_split_impl(comm, is_leader_color, MPIR_Comm_rank(comm->node_comm), + &(MPIDI_COMM(comm, inter_node_leads_comm))); + if (mpi_errno) + MPIR_ERR_POP(mpi_errno); + + /* Create the intra-node sub comms */ + mpi_errno = + MPIR_Comm_split_impl(comm->node_comm, MPIR_Comm_rank(comm->node_comm) / sub_node_comm_size, + MPIR_Comm_rank(comm->node_comm), &(MPIDI_COMM(comm, sub_node_comm))); + if (mpi_errno) + MPIR_ERR_POP(mpi_errno); + + if (MPIR_Comm_rank(comm->node_comm) % sub_node_comm_size == 0) + is_leader_color = 1; + else + is_leader_color = MPI_UNDEFINED; + + /* Create an intra-node comm consisting of all leader ranks on that node */ + mpi_errno = MPIR_Comm_split_impl(comm->node_comm, is_leader_color, + MPIR_Comm_rank(comm->node_comm), + &(MPIDI_COMM(comm, intra_node_leads_comm))); + if (mpi_errno) + MPIR_ERR_POP(mpi_errno); + + fn_exit: + MPIR_FUNC_EXIT; + return mpi_errno; + fn_fail: + goto fn_exit; +} diff --git a/src/mpid/ch4/src/ch4_comm.h b/src/mpid/ch4/src/ch4_comm.h index f021d33ff02..0a225c563ef 100644 --- a/src/mpid/ch4/src/ch4_comm.h +++ b/src/mpid/ch4/src/ch4_comm.h @@ -15,6 +15,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_set_comm_hint_sender_vci(MPIR_Comm * comm, in MPL_STATIC_INLINE_PREFIX int MPIDI_set_comm_hint_receiver_vci(MPIR_Comm * comm, int type, int value); MPL_STATIC_INLINE_PREFIX int MPIDI_set_comm_hint_vci(MPIR_Comm * comm, int type, int value); +int MPIDI_Comm_create_multi_leader_subcomms(MPIR_Comm * comm, int num_leads); MPL_STATIC_INLINE_PREFIX int MPID_Comm_AS_enabled(MPIR_Comm * comm) { diff --git a/src/mpl/include/mpl_math.h b/src/mpl/include/mpl_math.h index 65ace4b4208..35e8004f5e9 100644 --- a/src/mpl/include/mpl_math.h +++ b/src/mpl/include/mpl_math.h @@ -112,6 +112,35 @@ static inline int MPL_mirror_permutation(unsigned int x, int bits) return retval; } +/* Round denominator to the closest integer to divide numerator completely. Rounded value lies + * within +/- range of denominator*/ +static inline int MPL_round_closest_multiple(int numerator, int denominator, int range) +{ + /* increase and decrease denominator until it divides numerator completely. Break if it takes + * more than range iterations and return numerator */ + int iter = 1; + int increased_val = denominator, decreased_val = denominator; + + if (numerator % denominator == 0) + return denominator; + + while (true) { + increased_val += 1; + if (decreased_val > 1) + decreased_val -= 1; + + if (numerator % decreased_val == 0) + return decreased_val; + else if (numerator % increased_val == 0) + return increased_val; + else if (iter >= range) + return numerator; + + iter += 1; + } +} + + /* *INDENT-ON* */ #if defined(__cplusplus) } From fbf34aca59c7092dc8ce528516b358528cce18ec Mon Sep 17 00:00:00 2001 From: Taru Doodi Date: Mon, 31 Jan 2022 13:43:17 -0600 Subject: [PATCH 600/607] coll: Add multi-leader allreduce composition Multi-leaders based composition: It has `num_leaders` per node, which reduce the data within sub-node_comm. It is followed by intra_node reduce and inter_node allreduce on the piece of data the leader is responsible for. A shared memory buffer is allocated per leader. If size of message exceeds this shm buffer, the message is chunked. Constraints: For a comm, all nodes should have same number of ranks per node, op should be commutative. Co-authored-by: Surabhi Jain --- src/mpid/ch4/src/ch4_coll.h | 1 + src/mpid/ch4/src/ch4_coll_impl.h | 269 +++++++++++++++++++++++++++++++ 2 files changed, 270 insertions(+) diff --git a/src/mpid/ch4/src/ch4_coll.h b/src/mpid/ch4/src/ch4_coll.h index 31c10656519..c779039b550 100644 --- a/src/mpid/ch4/src/ch4_coll.h +++ b/src/mpid/ch4/src/ch4_coll.h @@ -54,6 +54,7 @@ 1 NM + SHM with reduce + bcast 2 NM only composition 3 SHM only composition + 4 Multi leaders based inter node + intra node composition - name : MPIR_CVAR_ALLGATHER_COMPOSITION category : COLLECTIVE diff --git a/src/mpid/ch4/src/ch4_coll_impl.h b/src/mpid/ch4/src/ch4_coll_impl.h index 58132b232d6..3446ad824d3 100644 --- a/src/mpid/ch4/src/ch4_coll_impl.h +++ b/src/mpid/ch4/src/ch4_coll_impl.h @@ -3,10 +3,65 @@ * See COPYRIGHT in top-level directory */ +/* +=== BEGIN_MPI_T_CVAR_INFO_BLOCK === + +cvars: + - name : MPIR_CVAR_NUM_MULTI_LEADS + category : COLLECTIVE + type : int + default : 4 + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + Number of leader ranks per node to be used for multi-leaders based collective algorithms + + - name : MPIR_CVAR_ALLREDUCE_SHM_PER_LEADER + category : COLLECTIVE + type : int + default : -1 + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + Shared memory region per node-leader for multi-leaders based composition for MPI_Allreduce (in bytes) + If it is undefined by the user, it is set to the message size of the first call to the algorithm. + Max shared memory size is limited to 4MB. + + - name : MPIR_CVAR_ALLREDUCE_CACHE_PER_LEADER + category : COLLECTIVE + type : int + default : 512 + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + Amount of data reduced in allreduce delta composition's reduce local step (in bytes). Smaller msg size + per leader avoids cache misses and improves performance. Experiments indicate 512 to be the best value. + + - name : MPIR_CVAR_ALLREDUCE_LOCAL_COPY_OFFSETS + category : COLLECTIVE + type : int + default : 2 + class : none + verbosity : MPI_T_VERBOSITY_USER_BASIC + scope : MPI_T_SCOPE_ALL_EQ + description : >- + number of offsets in the allreduce delta composition's local copy + The value of 2 performed the best in our 2 NIC test cases. + +=== END_MPI_T_CVAR_INFO_BLOCK === +*/ + #ifndef CH4_COLL_IMPL_H_INCLUDED #define CH4_COLL_IMPL_H_INCLUDED #include "ch4_csel_container.h" +#include "ch4_comm.h" +#include "algo_common.h" + +#define MPIR_ALLREDUCE_SHM_PER_LEADER_MAX 4194304 MPL_STATIC_INLINE_PREFIX int MPIDI_Barrier_intra_composition_alpha(MPIR_Comm * comm, MPIR_Errflag_t * errflag) @@ -325,6 +380,220 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_Allreduce_intra_composition_gamma(const void goto fn_exit; } +/* Multi-leaders based composition. Have num_leaders per node, which reduce the data within + * sub-node_comm. It is followed by intra_node reduce and inter_node allreduce on the piece of data + * the leader is responsible for. A shared memory buffer is allocated per leader. If size of + * message exceeds this shm buffer, the message is chunked. + * Constraints: For a comm, all nodes should have same number of ranks per node, op should be + * commutative. + */ +MPL_STATIC_INLINE_PREFIX int MPIDI_Allreduce_intra_composition_delta(const void *sendbuf, + void *recvbuf, int count, + MPI_Datatype datatype, + MPI_Op op, + int num_leads, + MPIR_Comm * comm_ptr, + MPIR_Errflag_t * errflag) +{ + int mpi_errno = MPI_SUCCESS, coll_ret = MPI_SUCCESS; + bool mapfail_flag = false; + char *shm_addr; + int my_leader_rank = -1, iter; + MPI_Aint num_chunks, chunk_size_floor, chunk_size_ceil; + int offset = 0, is_contig, i; + MPI_Aint lb, true_extent, extent; + int num_offsets = MPIR_CVAR_ALLREDUCE_LOCAL_COPY_OFFSETS; + int local_copy_rank = MPIR_Comm_rank(comm_ptr->node_comm); + int local_copy_offset = 0; + int local_copy_group = 0; + int shm_size_per_lead = MPIR_CVAR_ALLREDUCE_SHM_PER_LEADER; + + MPIR_Type_get_extent_impl(datatype, &lb, &extent); + MPIR_Type_get_true_extent_impl(datatype, &lb, &true_extent); + extent = MPL_MAX(extent, true_extent); + + MPIR_Datatype_is_contig(datatype, &is_contig); + + if (sendbuf == MPI_IN_PLACE) + sendbuf = recvbuf; + + if (MPIDI_COMM(comm_ptr, sub_node_comm) == NULL) { + /* Create multi-leaders comm in a lazily */ + coll_ret = MPIDI_Comm_create_multi_leader_subcomms(comm_ptr, num_leads); + if (coll_ret) + MPIR_ERR_ADD(mpi_errno, coll_ret); + } + + /* Allocate the shared memory buffer per node, if it is not already done */ + if (MPIDI_COMM(comm_ptr, allreduce_comp_info->shm_addr) == NULL) { + /* Determine the shm_size_per_lead */ + /* If user didn't set anything, set shm_size_per_lead according to the first call */ + /* since CVAR is set only once this check should only happen once during the course of + * execution. */ + if (shm_size_per_lead == -1) { + shm_size_per_lead = count * sizeof(datatype); + } + /* Do not create shm_size_per_lead buffers greater than 4MB. */ + if (shm_size_per_lead > MPIR_ALLREDUCE_SHM_PER_LEADER_MAX) { + shm_size_per_lead = MPIR_ALLREDUCE_SHM_PER_LEADER_MAX; + } + MPIDI_COMM(comm_ptr, shm_size_per_lead) = shm_size_per_lead; + + coll_ret = MPIDU_shm_alloc(comm_ptr->node_comm, num_leads * shm_size_per_lead, + (void **) &MPIDI_COMM_ALLREDUCE(comm_ptr, shm_addr), + &mapfail_flag); + if (coll_ret || mapfail_flag) + MPIR_ERR_ADD(mpi_errno, coll_ret); + } + + /* Store the address of shared buffer into a local variable */ + shm_addr = MPIDI_COMM_ALLREDUCE(comm_ptr, shm_addr); + /* Retrieve the shm_size_per_lead for subsequent calls */ + shm_size_per_lead = MPIDI_COMM(comm_ptr, shm_size_per_lead); + + if (MPIDI_COMM(comm_ptr, intra_node_leads_comm) != NULL) { + my_leader_rank = MPIR_Comm_rank(MPIDI_COMM(comm_ptr, intra_node_leads_comm)); + } + + /* Calculate chunking information. Extent handles contiguous and non-contiguous datatypes both */ + MPIR_Algo_calculate_pipeline_chunk_info(shm_size_per_lead, + extent, count, &num_chunks, + &chunk_size_floor, &chunk_size_ceil); + + for (iter = 0; iter < num_chunks; iter++) { + int chunk_count = (iter == 0) ? chunk_size_floor : chunk_size_ceil; + int per_leader_count = chunk_count / num_leads; + if (my_leader_rank == (num_leads - 1)) { + /* If chunk_count is not perfectly divisible by num_leaders. The last leader gets the + * leftover count as well */ + per_leader_count = ((chunk_count / num_leads) + (chunk_count % num_leads)); + } + + /* Step 0: Barrier to make sure the shm_buffer can be reused after the previous call */ +#ifndef MPIDI_CH4_DIRECT_NETMOD + coll_ret = MPIDI_SHM_mpi_barrier(comm_ptr->node_comm, errflag); +#else + coll_ret = MPIDI_NM_mpi_barrier(comm_ptr->node_comm, errflag); +#endif + if (coll_ret) + MPIR_ERR_ADD(mpi_errno, coll_ret); + + /* Step 1: Leaders perform reduce on is intra_node_sub_communicator. Reduced data is + * available in the leader's shared buffer */ +#ifndef MPIDI_CH4_DIRECT_NETMOD + coll_ret = + MPIDI_SHM_mpi_reduce((char *) sendbuf + offset * extent, + (char *) shm_addr + my_leader_rank * shm_size_per_lead, + chunk_count, datatype, op, 0, MPIDI_COMM(comm_ptr, sub_node_comm), + errflag); +#else + coll_ret = + MPIDI_NM_mpi_reduce((char *) sendbuf + offset * extent, + (char *) shm_addr + my_leader_rank * shm_size_per_lead, chunk_count, + datatype, op, 0, MPIDI_COMM(comm_ptr, sub_node_comm), errflag); +#endif + if (coll_ret) + MPIR_ERR_ADD(mpi_errno, coll_ret); + + /* Step 2: Barrier to make sure all the leaders have data reduced into is respective shm + * buffers. */ + if (MPIDI_COMM(comm_ptr, intra_node_leads_comm) != NULL) { +#ifndef MPIDI_CH4_DIRECT_NETMOD + coll_ret = MPIDI_SHM_mpi_barrier(MPIDI_COMM(comm_ptr, intra_node_leads_comm), errflag); +#else + coll_ret = MPIDI_NM_mpi_barrier(MPIDI_COMM(comm_ptr, intra_node_leads_comm), errflag); +#endif + if (coll_ret) + MPIR_ERR_ADD(mpi_errno, coll_ret); + } + + /* Step 3: Each leader is responsible to reduce a portion of the data (chunk_count/num_leads), + * from shm_buffer of every leader into shm_buffer of leader 0 */ + if (MPIDI_COMM(comm_ptr, intra_node_leads_comm) != NULL) { + + int j; + MPI_Aint cache_tile_size, cache_chunk_count; + int leader_offset = my_leader_rank * (chunk_count / num_leads) * extent; + cache_tile_size = MPIR_CVAR_ALLREDUCE_CACHE_PER_LEADER; + MPI_Aint cache_chunk_size_floor = 0, cache_chunk_size_ceil = 0; + + /* The reduce local is executed for cache_tile_size sized chunks by all the leaders. So + * each leader finishes reduce on one cache_tile_size sized chunk and moves to the next + * chunk till it reduces a total of per_leader_count bytes data. */ + MPIR_Algo_calculate_pipeline_chunk_info(cache_tile_size, + extent, per_leader_count, &cache_chunk_count, + &cache_chunk_size_floor, + &cache_chunk_size_ceil); + for (j = 0; j < cache_chunk_count; j++) { + for (i = 1; i < num_leads; i++) { + coll_ret = + MPIR_Reduce_local((char *) shm_addr + + (i * shm_size_per_lead + leader_offset + + j * cache_tile_size), + (char *) shm_addr + leader_offset + + (j * cache_tile_size), + (j == + (cache_chunk_count - + 1)) ? cache_chunk_size_floor : cache_chunk_size_ceil, + datatype, op); + if (coll_ret) + MPIR_ERR_ADD(mpi_errno, coll_ret); + } + } + } + + /* Step 4: Inter-node Allreduce on all the inter_node_multi_leader_comm. Each leader is + * responsible for (chunk_count/num_leads) data */ + if (MPIDI_COMM(comm_ptr, inter_node_leads_comm != NULL)) { + coll_ret = MPIDI_NM_mpi_allreduce(MPI_IN_PLACE, (char *) shm_addr + + my_leader_rank * ((chunk_count / num_leads) * extent), + per_leader_count, datatype, op, MPIDI_COMM(comm_ptr, + inter_node_leads_comm), + errflag); + if (coll_ret) + MPIR_ERR_ADD(mpi_errno, coll_ret); + } + + /* Step 5: Barrier to make sure non-leaders wait for leaders to finish reducing the data + * from other nodes */ +#ifndef MPIDI_CH4_DIRECT_NETMOD + coll_ret = MPIDI_SHM_mpi_barrier(comm_ptr->node_comm, errflag); +#else + coll_ret = MPIDI_NM_mpi_barrier(comm_ptr->node_comm, errflag); +#endif + if (coll_ret) + MPIR_ERR_ADD(mpi_errno, coll_ret); + + /* Step 6: Copy data from shm buffer into the recvbuf buffer */ + /* TODO: Do not use offsets for single NIC runs, it shows a slowdown of 0.95x with 2 offsets. + * Implementing the discrimation in number of offsets depending on number of NICs will be + * possible when MPICH has a function to tell how many NICs we are using. + * For now we are using 2 offsets with single NIC too since we do not see impact on overall + * performance of the composition. This only works when chunk count perfectly divides by + * number of offsets. */ + + if ((chunk_count % num_offsets) != 0) + num_offsets = 1; + + local_copy_offset = chunk_count * extent / num_offsets; + local_copy_group = (local_copy_rank / num_offsets); + for (i = 0; i < num_offsets; i++) { + coll_ret = + MPIR_Localcopy(shm_addr + + ((local_copy_group + i) % num_offsets) * local_copy_offset, + chunk_count / num_offsets, datatype, + (char *) recvbuf + offset * extent + + ((local_copy_group + i) % num_offsets) * local_copy_offset, + chunk_count / num_offsets, datatype); + if (coll_ret) + MPIR_ERR_ADD(mpi_errno, coll_ret); + } + offset += chunk_count; + } + + return mpi_errno; +} + MPL_STATIC_INLINE_PREFIX int MPIDI_Reduce_intra_composition_alpha(const void *sendbuf, void *recvbuf, MPI_Aint count, MPI_Datatype datatype, From af0db7efd7bbfff94f12b860743cae9e3353c530 Mon Sep 17 00:00:00 2001 From: Taru Doodi Date: Thu, 24 Feb 2022 13:32:00 -0600 Subject: [PATCH 601/607] coll: Add multi-leader allreduce selection Co-authored-by: Surabhi Jain --- src/mpid/ch4/src/ch4_coll.h | 50 +++++++++++++++++++++++++++ src/mpid/ch4/src/ch4_csel_container.h | 1 + 2 files changed, 51 insertions(+) diff --git a/src/mpid/ch4/src/ch4_coll.h b/src/mpid/ch4/src/ch4_coll.h index c779039b550..9817c3f2942 100644 --- a/src/mpid/ch4/src/ch4_coll.h +++ b/src/mpid/ch4/src/ch4_coll.h @@ -325,6 +325,7 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_Allreduce_allcomm_composition_json(const void { int mpi_errno = MPI_SUCCESS; const MPIDI_Csel_container_s *cnt = NULL; + int num_leads = 0, node_comm_size = 0; MPIR_Csel_coll_sig_s coll_sig = { .coll_type = MPIR_CSEL_COLL_TYPE__ALLREDUCE, @@ -361,6 +362,28 @@ MPL_STATIC_INLINE_PREFIX int MPIDI_Allreduce_allcomm_composition_json(const void MPIDI_Allreduce_intra_composition_gamma(sendbuf, recvbuf, count, datatype, op, comm, errflag); break; + case MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Allreduce_intra_composition_delta: + if (comm->comm_kind == MPIR_COMM_KIND__INTRACOMM) { + MPIDI_Allreduce_fill_multi_leads_info(comm); + if (comm->node_comm) + node_comm_size = MPIR_Comm_size(comm->node_comm); + /* Reset number of leaders, so that (node_comm_size % num_leads) is zero. The new number of + * leaders must lie within a range +/- from the leaders specified, or every rank is made + * as a leader. Currently we use range as 15. */ + num_leads = + MPL_round_closest_multiple(node_comm_size, MPIR_CVAR_NUM_MULTI_LEADS, 15); + } + /* make sure that the algo can be run */ + if (MPIDI_COMM_ALLREDUCE(comm, use_multi_leads) == 1 && + comm->comm_kind == MPIR_COMM_KIND__INTRACOMM && + count >= num_leads && MPIR_Op_is_commutative(op)) { + mpi_errno = + MPIDI_Allreduce_intra_composition_delta(sendbuf, recvbuf, count, datatype, op, + num_leads, comm, errflag); + } else + mpi_errno = + MPIR_Allreduce_impl(sendbuf, recvbuf, count, datatype, op, comm, errflag); + break; default: MPIR_Assert(0); } @@ -379,6 +402,7 @@ MPL_STATIC_INLINE_PREFIX int MPID_Allreduce(const void *sendbuf, void *recvbuf, { int mpi_errno = MPI_SUCCESS; int is_commutative = -1; + int num_leads = 0, node_comm_size = 0; MPIR_FUNC_ENTER; @@ -415,6 +439,32 @@ MPL_STATIC_INLINE_PREFIX int MPID_Allreduce(const void *sendbuf, void *recvbuf, MPIDI_Allreduce_intra_composition_gamma(sendbuf, recvbuf, count, datatype, op, comm, errflag); break; + case 4: + if (comm->comm_kind == MPIR_COMM_KIND__INTRACOMM) { + MPIDI_Allreduce_fill_multi_leads_info(comm); + if (comm->node_comm) + node_comm_size = MPIR_Comm_size(comm->node_comm); + /* Reset number of leaders, so that (node_comm_size % num_leads) is zero. The new number of + * leaders must lie within a range +/- from the leaders specified, or every rank is made + * as a leader. Currently we use range as 15. */ + num_leads = + MPL_round_closest_multiple(node_comm_size, MPIR_CVAR_NUM_MULTI_LEADS, 15); + } + + MPII_COLLECTIVE_FALLBACK_CHECK(comm->rank, comm->comm_kind == MPIR_COMM_KIND__INTRACOMM + && MPIDI_COMM_ALLREDUCE(comm, use_multi_leads) == 1 && + count >= num_leads && is_commutative, mpi_errno, + "Allreduce composition delta cannot be applied.\n"); + /* Multi-leaders based composition can only be used if the comm is spanned over more than + * 1 node, has equal number of ranks on each node, count is more than number of leaders and + * the operation is commutative. This composition is beneficial for large messages. + */ + + mpi_errno = + MPIDI_Allreduce_intra_composition_delta(sendbuf, recvbuf, count, datatype, op, + num_leads, comm, errflag); + break; + default: mpi_errno = MPIDI_Allreduce_allcomm_composition_json(sendbuf, recvbuf, count, datatype, op, diff --git a/src/mpid/ch4/src/ch4_csel_container.h b/src/mpid/ch4/src/ch4_csel_container.h index cd5144d3964..5efee6b0cd9 100644 --- a/src/mpid/ch4/src/ch4_csel_container.h +++ b/src/mpid/ch4/src/ch4_csel_container.h @@ -19,6 +19,7 @@ typedef struct { MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Allreduce_intra_composition_alpha, MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Allreduce_intra_composition_beta, MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Allreduce_intra_composition_gamma, + MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Allreduce_intra_composition_delta, MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Alltoall_intra_composition_alpha, MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Alltoall_intra_composition_beta, MPIDI_CSEL_CONTAINER_TYPE__COMPOSITION__MPIDI_Alltoallv_intra_composition_alpha, From 8e9504a343a3f16f87f99e8cde1742215a274fec Mon Sep 17 00:00:00 2001 From: Taru Doodi Date: Thu, 3 Mar 2022 09:13:44 -0600 Subject: [PATCH 602/607] test: Add test for multi-leader allreduce --- test/mpi/maint/coll_cvars.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test/mpi/maint/coll_cvars.txt b/test/mpi/maint/coll_cvars.txt index 979cabc9784..5d769b80101 100644 --- a/test/mpi/maint/coll_cvars.txt +++ b/test/mpi/maint/coll_cvars.txt @@ -226,6 +226,7 @@ algorithms: composition:1 composition:2 composition:3 + composition:4 smp recursive_doubling reduce_scatter_allgather From 5f9a1f0e998ebfb657cdd56a57ca6e218d500610 Mon Sep 17 00:00:00 2001 From: Mohamad Chaarawi Date: Mon, 11 Apr 2022 14:35:18 +0000 Subject: [PATCH 603/607] update packaging Signed-off-by: Mohamad Chaarawi --- packaging/Dockerfile.mockbuild | 8 ++++---- packaging/Makefile_distro_vars.mk | 16 ++++++++++++++-- packaging/Makefile_packaging.mk | 16 +++++++++++----- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/packaging/Dockerfile.mockbuild b/packaging/Dockerfile.mockbuild index 89d494f59a0..38d376034cd 100644 --- a/packaging/Dockerfile.mockbuild +++ b/packaging/Dockerfile.mockbuild @@ -5,8 +5,8 @@ # # Pull base image -FROM fedora:35 -LABEL maintainer="daos@daos.groups.io>" +FROM fedora:latest +LABEL maintainer="daos@daos.groups.io" # use same UID as host and default value of 1000 if not specified ARG UID=1000 @@ -14,7 +14,7 @@ ARG UID=1000 # Install basic tools RUN dnf -y install mock make \ rpm-build curl createrepo rpmlint redhat-lsb-core git \ - python-srpm-macros rpmdevtools mock-core-configs\ \<\ 37.1 + python-srpm-macros rpmdevtools # Add build user (to keep rpmbuild happy) ENV USER build @@ -29,5 +29,5 @@ RUN grep use_nspawn /etc/mock/site-defaults.cfg || \ echo "config_opts['use_nspawn'] = False" >> /etc/mock/site-defaults.cfg ARG CACHEBUST -RUN dnf -y upgrade --exclude mock-core-configs && \ +RUN dnf -y upgrade && \ dnf clean all diff --git a/packaging/Makefile_distro_vars.mk b/packaging/Makefile_distro_vars.mk index 44006e066f0..d1e5767e14e 100644 --- a/packaging/Makefile_distro_vars.mk +++ b/packaging/Makefile_distro_vars.mk @@ -26,7 +26,7 @@ SPECTOOL := spectool # DISTRO_ID (i.e. el7) # DISTRO_BASE (i.e. EL_7) # from the CHROOT_NAME -ifeq ($(CHROOT_NAME),epel-7-x86_64) +ifeq ($(patsubst %epel-7-x86_64,,$(lastword $(subst +, ,$(CHROOT_NAME)))),) DIST := $(shell rpm $(COMMON_RPM_ARGS) --eval %{?dist}) VERSION_ID := 7 DISTRO_ID := el7 @@ -35,7 +35,7 @@ DISTRO_VERSION ?= $(VERSION_ID) ORIG_TARGET_VER := 7 SED_EXPR := 1s/$(DIST)//p endif -ifeq ($(CHROOT_NAME),epel-8-x86_64) +ifeq ($(patsubst %epel-8-x86_64,,$(lastword $(subst +, ,$(CHROOT_NAME)))),) DIST := $(shell rpm $(COMMON_RPM_ARGS) --eval %{?dist}) VERSION_ID := 8 DISTRO_ID := el8 @@ -62,6 +62,18 @@ SED_EXPR := 1p endif endif ifeq ($(ID),centos) +ID = el +endif +ifeq ($(ID),rocky) +ID = el +endif +ifeq ($(ID),almalinux) +ID = el +endif +ifeq ($(ID),rhel) +ID = el +endif +ifeq ($(ID),el) DISTRO_ID := el$(VERSION_ID) DISTRO_BASE := $(basename EL_$(VERSION_ID)) DIST := $(shell rpm $(COMMON_RPM_ARGS) --eval %{?dist}) diff --git a/packaging/Makefile_packaging.mk b/packaging/Makefile_packaging.mk index b59782ec5c9..a7c2469246a 100644 --- a/packaging/Makefile_packaging.mk +++ b/packaging/Makefile_packaging.mk @@ -10,7 +10,7 @@ SHELL=/bin/bash -include Makefile.local # default to Leap 15 distro for chrootbuild -CHROOT_NAME ?= opensuse-leap-15.2-x86_64 +CHROOT_NAME ?= opensuse-leap-15.3-x86_64 include packaging/Makefile_distro_vars.mk ifeq ($(DEB_NAME),) @@ -86,7 +86,7 @@ define distro_map case $(DISTRO_ID) in \ el7) distro="centos7" \ ;; \ - el8) distro="centos8" \ + el8) distro="el8" \ ;; \ sle12.3) distro="sles12.3" \ ;; \ @@ -354,7 +354,7 @@ ifeq ($(LOCAL_REPOS),true) endif # ifeq ($(ID_LIKE),debian) ifeq ($(DISTRO_BASE), EL_8) # hack to use 8.3 non-group repos on EL_8 - $(DISTRO_BASE)_LOCAL_REPOS := $($(DISTRO_BASE)_LOCAL_REPOS)|$(subst $(ORIG_TARGET_VER),$(DISTRO_VERSION),$(REPOSITORY_URL)repository/centos-8.3-base-x86_64-proxy|$(REPOSITORY_URL)repository/centos-8.3-extras-x86_64-proxy|$(REPOSITORY_URL)repository/epel-el-8-x86_64-proxy) + $(DISTRO_BASE)_LOCAL_REPOS := $($(DISTRO_BASE)_LOCAL_REPOS)|$(subst $(ORIG_TARGET_VER),$(DISTRO_VERSION),$(REPOSITORY_URL)repository/rocky-8.5-base-x86_64-proxy|$(REPOSITORY_URL)repository/rocky-8.5-extras-x86_64-proxy|$(REPOSITORY_URL)repository/epel-el-8-x86_64-proxy) else ifeq ($(DISTRO_BASE), EL_7) # hack to use 7.9 non-group repos on EL_7 $(DISTRO_BASE)_LOCAL_REPOS := $($(DISTRO_BASE)_LOCAL_REPOS)|$(subst $(ORIG_TARGET_VER),$(DISTRO_VERSION),$(REPOSITORY_URL)repository/centos-7.9-base-x86_64-proxy|$(REPOSITORY_URL)repository/centos-7.9-extras-x86_64-proxy|$(REPOSITORY_URL)repository/centos-7.9-updates-x86_64-proxy|$(REPOSITORY_URL)repository/epel-el-7-x86_64-proxy) @@ -367,11 +367,11 @@ ifeq ($(LOCAL_REPOS),true) endif # ifeq ($(DISTRO_BASE), *) endif #ifneq ($(DAOS_STACK_$(DISTRO_BASE)_$(DAOS_REPO_TYPE)_REPO),) ifneq ($(DAOS_STACK_$(DISTRO_BASE)_APPSTREAM_REPO),) - $(DISTRO_BASE)_LOCAL_REPOS := $($(DISTRO_BASE)_LOCAL_REPOS)|$(REPOSITORY_URL)$(DAOS_STACK_$(DISTRO_BASE)_APPSTREAM_REPO) + $(DISTRO_BASE)_LOCAL_REPOS := $($(DISTRO_BASE)_LOCAL_REPOS)|$(subst centos-8.3,rocky-8.5,$(REPOSITORY_URL)$(DAOS_STACK_$(DISTRO_BASE)_APPSTREAM_REPO)) endif # group repos are not working in Nexus so we hack in the group members directly above ifneq ($(DAOS_STACK_$(DISTRO_BASE)_POWERTOOLS_REPO),) - $(DISTRO_BASE)_LOCAL_REPOS := $($(DISTRO_BASE)_LOCAL_REPOS)|$(REPOSITORY_URL)$(DAOS_STACK_$(DISTRO_BASE)_POWERTOOLS_REPO) + $(DISTRO_BASE)_LOCAL_REPOS := $($(DISTRO_BASE)_LOCAL_REPOS)|$(subst centos-8.3,rocky-8.5,$(REPOSITORY_URL)$(DAOS_STACK_$(DISTRO_BASE)_POWERTOOLS_REPO)) endif ifneq ($(ID_LIKE),debian) ifneq ($(DAOS_STACK_INTEL_ONEAPI_REPO),) @@ -456,6 +456,12 @@ test: $(call install_repos,$(REPO_NAME)@$(BRANCH_NAME):$(BUILD_NUMBER)) dnf -y install $(TEST_PACKAGES) +show_DISTRO_ID: + @echo '$(DISTRO_ID)' + +show_distro_map: + @$(call distro_map) echo "$$distro" + show_spec: @echo '$(SPEC)' From 24d189d7f1f730b6fc84cc180f9b1c1de39602c4 Mon Sep 17 00:00:00 2001 From: Mohamad Chaarawi Date: Mon, 11 Apr 2022 15:18:25 +0000 Subject: [PATCH 604/607] remove -with-pm config option and use default. Signed-off-by: Mohamad Chaarawi --- mpich-EL_7.spec | 6 ++++-- mpich-EL_8.spec | 6 ++++-- mpich-LEAP_15.spec | 6 ++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/mpich-EL_7.spec b/mpich-EL_7.spec index 79d4e1b203a..5423dfd90b3 100644 --- a/mpich-EL_7.spec +++ b/mpich-EL_7.spec @@ -1,7 +1,7 @@ Summary: A high-performance implementation of MPI Name: mpich Version: 4.0~a2 -Release: 2%{?dist} +Release: 3%{?dist} License: MIT URL: http://www.mpich.org/ @@ -181,7 +181,6 @@ mpich support for Python 3. --disable-silent-rules \ --enable-fc \ --with-device=%{selected_channels} \ - --with-pm=hydra:gforker \ --includedir=%{_includedir}/%{name}-%{_arch} \ --bindir=%{_libdir}/%{name}/bin \ --libdir=%{_libdir}/%{name}/lib \ @@ -345,6 +344,9 @@ find %{buildroot} -type f -name "*.la" -delete %{python3_sitearch}/%{name}.pth %changelog +* Mon Apr 11 2022 Mohamad Chaarawi - 4.0~a2-3 +- remove with-pm setting and use default + * Mon Nov 15 2021 Wang Shilong - 4.0~a2-2 - Rebuilt for breaking DAOS API change diff --git a/mpich-EL_8.spec b/mpich-EL_8.spec index d1ba58bec77..effb5aed66c 100644 --- a/mpich-EL_8.spec +++ b/mpich-EL_8.spec @@ -5,7 +5,7 @@ Summary: A high-performance implementation of MPI Name: mpich Version: 4.0~a2 -Release: 2%{?dist} +Release: 3%{?dist} License: MIT URL: http://www.mpich.org/ @@ -118,7 +118,6 @@ CONFIGURE_OPTS=( --disable-silent-rules --enable-fc --with-device=ch3:nemesis - --with-pm=hydra:gforker --includedir=%{_includedir}/%{name}-%{_arch} --bindir=%{_libdir}/%{name}/bin --libdir=%{_libdir}/%{name}/lib @@ -243,6 +242,9 @@ make check VERBOSE=1 \ %{python3_sitearch}/%{name}.pth %changelog +* Mon Apr 11 2022 Mohamad Chaarawi - 4.0~a2-3 +- remove with-pm setting and use default + * Mon Nov 15 2021 Wang Shilong - 4.0~a2-2 - Rebuilt for breaking DAOS API change diff --git a/mpich-LEAP_15.spec b/mpich-LEAP_15.spec index 7b34c9e82b3..9820ee6abe3 100644 --- a/mpich-LEAP_15.spec +++ b/mpich-LEAP_15.spec @@ -61,7 +61,7 @@ Name: %{package_name}%{?testsuite:-testsuite} Version: %{vers} -Release: 3%{?dist} +Release: 4%{?dist} Summary: High-performance and widely portable implementation of MPI License: MIT Group: Development/Libraries/Parallel @@ -231,7 +231,6 @@ echo without HPC --exec-prefix=%{p_prefix} \ --libexecdir=%{p_libexecdir} \ %endif - --with-pm=hydra:gforker \ --includedir=%{p_includedir} \ --bindir=%{p_bindir} \ --libdir=%{p_libdir} \ @@ -461,6 +460,9 @@ fi %endif # !testsuite %changelog +* Mon Apr 11 2022 Mohamad Chaarawi - 4.0~a2-4 +- remove with-pm setting and use default + * Mon Nov 15 2021 Wang Shilong - 4.0~a2-3 - Rebuilt for breaking DAOS API change From a9572c86e8ba748c0b913eda459284f2b11ad75d Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Sat, 9 Apr 2022 10:51:20 -0500 Subject: [PATCH 605/607] pm/util: restore simple_pmiutil.h The header file simple_pmiutil.h was in src/pmi/simple and it is now being refactored. It is still needed by gforker and remshell. This commit restore the file into src/pm/util where it belongs. This fixes the build for gforker and remshell. --- src/pm/util/Makefile.mk | 1 - src/pm/util/simple_pmiutil.h | 37 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 src/pm/util/simple_pmiutil.h diff --git a/src/pm/util/Makefile.mk b/src/pm/util/Makefile.mk index dd82e98b6ee..501ac9f1965 100644 --- a/src/pm/util/Makefile.mk +++ b/src/pm/util/Makefile.mk @@ -7,7 +7,6 @@ # managers that use utility code from this directory common_pm_includes = \ -I${top_builddir}/src/include -I${top_srcdir}/src/include \ - -I${top_builddir}/src/pmi/simple -I${top_srcdir}/src/pmi/simple \ -I${top_builddir}/src/pm/util -I${top_srcdir}/src/pm/util if BUILD_PM_UTIL diff --git a/src/pm/util/simple_pmiutil.h b/src/pm/util/simple_pmiutil.h new file mode 100644 index 00000000000..3f6e20c0e88 --- /dev/null +++ b/src/pm/util/simple_pmiutil.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#ifndef SIMPLE_PMIUTIL_H_INCLUDED +#define SIMPLE_PMIUTIL_H_INCLUDED + +/* maximum sizes for arrays */ +#define PMIU_MAXLINE 1024 +#define PMIU_IDSIZE 32 + +/* we don't have access to MPIR_Assert and friends here in the PMI code */ +#if defined(HAVE_ASSERT_H) +#include +#define PMIU_Assert(expr) assert(expr) +#else +#define PMIU_Assert(expr) +#endif + +#if defined HAVE_ARPA_INET_H +#include +#endif /* HAVE_ARPA_INET_H */ + + +/* prototypes for PMIU routines */ +void PMIU_Set_rank(int PMI_rank); +void PMIU_SetServer(void); +void PMIU_printf(int print_flag, const char *fmt, ...); +int PMIU_readline(int fd, char *buf, int max); +int PMIU_writeline(int fd, char *buf); +int PMIU_parse_keyvals(char *st); +void PMIU_dump_keyvals(void); +char *PMIU_getval(const char *keystr, char *valstr, int vallen); +void PMIU_chgval(const char *keystr, char *valstr); + +#endif /* SIMPLE_PMIUTIL_H_INCLUDED */ From b3d08f9b7f7628a498a8c70f47ba28bf6a46c0f9 Mon Sep 17 00:00:00 2001 From: Mohamad Chaarawi Date: Mon, 11 Apr 2022 16:36:18 +0000 Subject: [PATCH 606/607] adio/daos: make daos_event_wait non-blocking test on an MPI request should not block when using the daos driver as the event API has a mode to make progress without waiting. Fix the issue in the poll callback to use the NOWAIT option on event test. Signed-off-by: Mohamad Chaarawi --- src/mpi/romio/adio/ad_daos/ad_daos_io.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/mpi/romio/adio/ad_daos/ad_daos_io.c b/src/mpi/romio/adio/ad_daos/ad_daos_io.c index 91ed8588f87..5efa09b63a9 100644 --- a/src/mpi/romio/adio/ad_daos/ad_daos_io.c +++ b/src/mpi/romio/adio/ad_daos/ad_daos_io.c @@ -169,15 +169,14 @@ int ADIOI_DAOS_aio_poll_fn(void *extra_state, MPI_Status * status) int ret; bool flag; - /* MSC - MPICH hangs if we just test with NOWAIT.. */ - ret = daos_event_test(&aio_req->daos_event, DAOS_EQ_WAIT, &flag); + ret = daos_event_test(&aio_req->daos_event, DAOS_EQ_NOWAIT, &flag); if (ret != 0) return MPI_UNDEFINED; if (flag) MPI_Grequest_complete(aio_req->req); else - return MPI_UNDEFINED; + return ret; if (aio_req->daos_event.ev_error != 0) ret = ADIOI_DAOS_err("ADIOI_DAOS_aio_poll_fn", "DAOS Event Error", __LINE__, ret); From 981170fd97118443920b99c75cbae9010ebbfc9f Mon Sep 17 00:00:00 2001 From: Mohamad Chaarawi Date: Tue, 12 Apr 2022 13:57:16 +0000 Subject: [PATCH 607/607] Revert "use nowait for MPI test on async event" This reverts commit 819f697d3404b8e6e4a91ee19cd0e6872b4ae076. --- src/mpi/romio/adio/ad_daos/ad_daos_io.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mpi/romio/adio/ad_daos/ad_daos_io.c b/src/mpi/romio/adio/ad_daos/ad_daos_io.c index 5efa09b63a9..91ed8588f87 100644 --- a/src/mpi/romio/adio/ad_daos/ad_daos_io.c +++ b/src/mpi/romio/adio/ad_daos/ad_daos_io.c @@ -169,14 +169,15 @@ int ADIOI_DAOS_aio_poll_fn(void *extra_state, MPI_Status * status) int ret; bool flag; - ret = daos_event_test(&aio_req->daos_event, DAOS_EQ_NOWAIT, &flag); + /* MSC - MPICH hangs if we just test with NOWAIT.. */ + ret = daos_event_test(&aio_req->daos_event, DAOS_EQ_WAIT, &flag); if (ret != 0) return MPI_UNDEFINED; if (flag) MPI_Grequest_complete(aio_req->req); else - return ret; + return MPI_UNDEFINED; if (aio_req->daos_event.ev_error != 0) ret = ADIOI_DAOS_err("ADIOI_DAOS_aio_poll_fn", "DAOS Event Error", __LINE__, ret);
$line