From 8ad75792a4e0e61add528183bbed7c2a06aa0b6f Mon Sep 17 00:00:00 2001 From: Aurelien Bouteiller Date: Fri, 25 Apr 2025 11:01:13 -0400 Subject: [PATCH] bugfix: Setting OMPI_MPI_THREAD_LEVEL to a value different than `requested` in `MPI_Init_thread` would invoke the error handler, even though it is an useful override in some threaded library use cases. Signed-off-by: Aurelien Bouteiller --- ompi/mpi/c/init.c.in | 4 +++- ompi/mpi/c/init_thread.c.in | 28 ++++++++++++++++++++-------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/ompi/mpi/c/init.c.in b/ompi/mpi/c/init.c.in index b9e5d513482..15f41fbc434 100644 --- a/ompi/mpi/c/init.c.in +++ b/ompi/mpi/c/init.c.in @@ -15,6 +15,7 @@ * and Technology (RIST). All rights reserved. * Copyright (c) 2024 Triad National Security, LLC. All rights * reserved. + * Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -46,7 +47,8 @@ PROTOTYPE INT init(INT_OUT argc, ARGV argv) if (NULL != (env = getenv("OMPI_MPI_THREAD_LEVEL"))) { required = atoi(env); - if (required < MPI_THREAD_SINGLE || required > MPI_THREAD_MULTIPLE) { + if (required != MPI_THREAD_SINGLE && required != MPI_THREAD_FUNNELED && + required != MPI_THREAD_SERIALIZED && required != MPI_THREAD_MULTIPLE) { required = MPI_THREAD_MULTIPLE; } } diff --git a/ompi/mpi/c/init_thread.c.in b/ompi/mpi/c/init_thread.c.in index f56728ee262..5b20c7953e6 100644 --- a/ompi/mpi/c/init_thread.c.in +++ b/ompi/mpi/c/init_thread.c.in @@ -18,6 +18,7 @@ * reserved. * Copyright (c) 2024 Triad National Security, LLC. All rights * reserved. + * Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -40,6 +41,7 @@ PROTOTYPE ERROR_CLASS init_thread(INT_OUT argc, ARGV argv, INT required, INT_OUT provided) { int err, safe_required = MPI_THREAD_SERIALIZED; + bool err_arg_required = false; char *env; ompi_hook_base_mpi_init_thread_top(argc, argv, required, provided); @@ -47,14 +49,24 @@ PROTOTYPE ERROR_CLASS init_thread(INT_OUT argc, ARGV argv, INT required, /* 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) ) { + err_arg_required = (required != MPI_THREAD_SINGLE && required != MPI_THREAD_FUNNELED && + required != MPI_THREAD_SERIALIZED && required != MPI_THREAD_MULTIPLE); + if (!err_arg_required) { + safe_required = required; + } - if (NULL != (env = getenv("OMPI_MPI_THREAD_LEVEL"))) { - safe_required = atoi(env); - } - else { - safe_required = required; + /* check for environment overrides for required thread level. If + * there is, check to see that it is a valid/supported thread level. + * If valid, the environment variable always override the provided thread + * level (even if lower than argument `required`). A user program can + * check `provided != required` to check if `required` has been overruled. + */ + if (NULL != (env = getenv("OMPI_MPI_THREAD_LEVEL"))) { + int env_required = atoi(env); + err_arg_required |= (env_required != MPI_THREAD_SINGLE && env_required != MPI_THREAD_FUNNELED && + env_required != MPI_THREAD_SERIALIZED && env_required != MPI_THREAD_MULTIPLE); + if (!err_arg_required) { + safe_required = env_required; } } @@ -70,7 +82,7 @@ PROTOTYPE ERROR_CLASS init_thread(INT_OUT argc, ARGV argv, INT required, err = ompi_mpi_init(0, NULL, safe_required, provided, false); } - if( safe_required != required ) { + if (err_arg_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. */