Summary
Repeated MPI Sessions usage — MPI_Session_init after a prior MPI_Session_finalize has dropped the instance refcount to zero — intermittently deadlocks on macOS. The second MPI_Session_init fails to open() the sm/OPAL shmem backing file with ENOENT and then hangs forever in the modex PMIx_Fence_nb wait.
This reproduces on a clean main (no PRs applied), so it is a pre-existing bug, not tied to any in-flight work.
The stock example examples/hello_sessions_c (which does two MPI_Session_init/MPI_Session_finalize cycles) is enough to trigger it; it is what surfaced this, hanging the ompi-pr-builds macOS job.
Environment
- Open MPI
main (6.1.0a1), e.g. f267e427cf; embedded OpenPMIx cb89026, internal PRRTE/hwloc/libevent.
- GitHub Actions
macos-15 runner, arm64, 3 logical CPUs, macOS 15.7.7 (24G720).
mpirun --map-by ppr:1:core ./hello_sessions_c → 3 ranks.
- Built with
.opal_ignore removed (all components), but that is not required.
Reproducer
Either the stock example:
/* examples/hello_sessions_c.c: MPI_Session_init/finalize twice */
or, to hit it faster, a loop of full init/finalize cycles:
#include <mpi.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int iters = (argc > 1) ? atoi(argv[1]) : 100;
for (int i = 0; i < iters; i++) {
MPI_Session s;
MPI_Session_init(MPI_INFO_NULL, MPI_ERRORS_RETURN, &s);
MPI_Session_finalize(&s);
}
return 0;
}
Run repeatedly with multiple local ranks:
mpirun --map-by ppr:1:core ./hello_sessions_c # loop this; hangs within a handful of runs
A self-contained diagnostic CI workflow that builds Open MPI on macos-15, hammers the example, and on the first hang captures sample/lldb backtraces of every stuck rank + prte and dumps the session directories is here: jsquyres#30 (based on clean main).
Symptom
All ranks print the OPAL shmem/mmap "sys call fail" help on the second MPI_Session_init:
A system call failed during shared memory initialization that should not have.
System call: open(2)
Error: No such file or directory (errno 2)
then the surviving ranks deadlock.
Where it hangs
Both hung ranks are in the second MPI_Session_init (hello_sessions_c.c:17), spinning in the modex fence wait:
main (hello_sessions_c.c:17)
MPI_Session_init
ompi_mpi_instance_init + 3528
usleep(100) <-- ~99% of samples
That usleep is OMPI_LAZY_WAIT_FOR_COMPLETION(active) (ompi/runtime/ompi_rte.h:276, while (active) { opal_progress(); usleep(100); }) guarding the modex PMIx_Fence_nb(...) in ompi/instance/instance.c (~line 614). The fence completion callback (fence_release) never fires, so active never clears. prterun itself is healthy/idle (in kevent).
Analysis
The first MPI_Session_finalize takes the instance refcount to zero and tears the entire runtime down — PMIx finalize and removal of the PRRTE/OPAL session directory. The second MPI_Session_init then runs against a torn-down session directory, so:
- the sm BTL's OPAL shmem backing-file
open() lands in a directory that no longer exists → ENOENT, and
- the modex
PMIx_Fence_nb never completes → the lazy-wait loop spins forever.
In other words, a full MPI_Session_finalize → MPI_Session_init round-trip does not correctly re-establish the session directory / PMIx fence machinery (at least on macOS). This looks like an OMPI instance ↔ PMIx/PRRTE session-directory lifecycle issue.
Notes
- Intermittent/probabilistic — it hit iteration 3 of the stock example in the linked run, but the timing window depends on load (a 3-vCPU runner makes it more likely).
- The
sessions_stress loop reproducer makes it far easier to hit.
Summary
Repeated MPI Sessions usage —
MPI_Session_initafter a priorMPI_Session_finalizehas dropped the instance refcount to zero — intermittently deadlocks on macOS. The secondMPI_Session_initfails toopen()the sm/OPAL shmem backing file with ENOENT and then hangs forever in the modexPMIx_Fence_nbwait.This reproduces on a clean
main(no PRs applied), so it is a pre-existing bug, not tied to any in-flight work.The stock example
examples/hello_sessions_c(which does twoMPI_Session_init/MPI_Session_finalizecycles) is enough to trigger it; it is what surfaced this, hanging theompi-pr-buildsmacOS job.Environment
main(6.1.0a1), e.g.f267e427cf; embedded OpenPMIxcb89026, internal PRRTE/hwloc/libevent.macos-15runner, arm64, 3 logical CPUs, macOS 15.7.7 (24G720).mpirun --map-by ppr:1:core ./hello_sessions_c→ 3 ranks..opal_ignoreremoved (all components), but that is not required.Reproducer
Either the stock example:
/* examples/hello_sessions_c.c: MPI_Session_init/finalize twice */or, to hit it faster, a loop of full init/finalize cycles:
Run repeatedly with multiple local ranks:
mpirun --map-by ppr:1:core ./hello_sessions_c # loop this; hangs within a handful of runsA self-contained diagnostic CI workflow that builds Open MPI on
macos-15, hammers the example, and on the first hang capturessample/lldbbacktraces of every stuck rank +prteand dumps the session directories is here: jsquyres#30 (based on cleanmain).Symptom
All ranks print the OPAL
shmem/mmap"sys call fail" help on the secondMPI_Session_init:then the surviving ranks deadlock.
Where it hangs
Both hung ranks are in the second
MPI_Session_init(hello_sessions_c.c:17), spinning in the modex fence wait:That
usleepisOMPI_LAZY_WAIT_FOR_COMPLETION(active)(ompi/runtime/ompi_rte.h:276,while (active) { opal_progress(); usleep(100); }) guarding the modexPMIx_Fence_nb(...)inompi/instance/instance.c(~line 614). The fence completion callback (fence_release) never fires, soactivenever clears.prterunitself is healthy/idle (inkevent).Analysis
The first
MPI_Session_finalizetakes the instance refcount to zero and tears the entire runtime down — PMIx finalize and removal of the PRRTE/OPAL session directory. The secondMPI_Session_initthen runs against a torn-down session directory, so:open()lands in a directory that no longer exists → ENOENT, andPMIx_Fence_nbnever completes → the lazy-wait loop spins forever.In other words, a full
MPI_Session_finalize→MPI_Session_initround-trip does not correctly re-establish the session directory / PMIx fence machinery (at least on macOS). This looks like an OMPI instance ↔ PMIx/PRRTE session-directory lifecycle issue.Notes
sessions_stressloop reproducer makes it far easier to hit.