From ecbd842ca8d5177f649789408652d586dc9b6424 Mon Sep 17 00:00:00 2001 From: George Bosilca Date: Tue, 21 Jan 2020 10:29:10 -0500 Subject: [PATCH] Trap wrong parameters to MPI_Init_thread. Instead of triggering the fault early in the initialization process, do a serialized initialization and report the error once all the supporting infrastructure is up and running. Signed-off-by: George Bosilca --- ompi/errhandler/errhandler_predefined.c | 2 +- ompi/mpi/c/init_thread.c | 26 +++++++++++++++++-------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/ompi/errhandler/errhandler_predefined.c b/ompi/errhandler/errhandler_predefined.c index 8eb4954db5..8392f493ca 100644 --- a/ompi/errhandler/errhandler_predefined.c +++ b/ompi/errhandler/errhandler_predefined.c @@ -61,7 +61,7 @@ void ompi_mpi_errors_are_fatal_comm_handler(struct ompi_communicator_t **comm, va_start(arglist, error_code); - if (NULL != comm) { + if ( (NULL != comm) && (NULL != *comm) ) { name = (*comm)->c_name; abort_comm = *comm; } else { diff --git a/ompi/mpi/c/init_thread.c b/ompi/mpi/c/init_thread.c index 48fc53a154..fc53703b1a 100644 --- a/ompi/mpi/c/init_thread.c +++ b/ompi/mpi/c/init_thread.c @@ -47,26 +47,36 @@ static const char FUNC_NAME[] = "MPI_Init_thread"; int MPI_Init_thread(int *argc, char ***argv, int required, int *provided) { - int err; + int err, safe_required = MPI_THREAD_SERIALIZED; ompi_hook_base_mpi_init_thread_top(argc, argv, required, provided); - if ( MPI_PARAM_CHECK ) { - if (required < MPI_THREAD_SINGLE || required > MPI_THREAD_MULTIPLE) { - ompi_mpi_errors_are_fatal_comm_handler(NULL, NULL, FUNC_NAME); - } + /* Detect an incorrect thread support level, but dont report until we have the minimum + * infrastructure setup. + */ + if( (MPI_THREAD_SINGLE == required) || (MPI_THREAD_SERIALIZED == required) || + (MPI_THREAD_FUNNELED == required) || (MPI_THREAD_MULTIPLE == required) ) { + safe_required = required; } - *provided = required; + *provided = safe_required; /* Call the back-end initialization function (we need to put as little in this function as possible so that if it's profiled, we don't lose anything) */ if (NULL != argc && NULL != argv) { - err = ompi_mpi_init(*argc, *argv, required, provided, false); + err = ompi_mpi_init(*argc, *argv, safe_required, provided, false); } else { - err = ompi_mpi_init(0, NULL, required, provided, false); + err = ompi_mpi_init(0, NULL, safe_required, provided, false); + } + + if( safe_required != required ) { + /* Trigger the error handler for the incorrect argument. Keep it separate from the + * check on the ompi_mpi_init return and report a nice, meaningful error message to + * the user. */ + return ompi_errhandler_invoke((ompi_errhandler_t*)&ompi_mpi_errors_are_fatal, NULL, OMPI_ERRHANDLER_TYPE_COMM, + MPI_ERR_ARG, FUNC_NAME); } /* Since we don't have a communicator to invoke an errorhandler on