Skip to content

Call MPI_Abort when a test process fails - #985

Open
eschnett wants to merge 1 commit into
masterfrom
claude/mpi-abort-test-failures-96a335
Open

eschnett wants to merge 1 commit into
masterfrom
claude/mpi-abort-test-failures-96a335

Conversation

@eschnett

Copy link
Copy Markdown
Contributor

Failing self-tests exit via an exception. Depending on the MPI implementation, this may lead to a hang, which leads to a time-out in Github CI, which leads to a cancelled classification instead of an error.

This PR calls MPI_Abort when a test fails by adding a respective atexit hook.

This is done only for the self-tests. It might be useful to do the same for all MPI applications – it doesn't really make sense to just exit the Unix process, we should either call MPI_Finalize or MPI_Abort in either case, and if we exit without the app calling MPI_Finalize the we should probably abort. But that's a different issue.

A test file that dies from an uncaught exception (a failing `@test`, an
`MPIError`, ...) exits nonzero, and `MPI.Init`'s atexit hook then skips
`MPI.Finalize()`, correctly, since it is collective. But the failing rank
still runs its object finalizers afterwards, and `free(::Win)`,
`free(::Comm)` and `close(::FileHandle)` all make collective MPI calls,
gated only on `!Finalized()` -- which is false on this path.

So the failing rank *enters* a collective while its peers are blocked
somewhere else entirely. Every process is still alive, so there is no dead
process for the launcher to notice, and the job hangs until the CI job-level
`timeout-minutes: 20` expires. The run is then reported as a job timeout
rather than as a named failing test, with no information about the other
test files.

Julia runs atexit hooks before object finalizers, so an atexit hook is the
right place to call `MPI_Abort`: it preempts both the blocked peers and the
finalizer deadlock. Load it into every test process with `julia -L` rather
than editing each test file, since only 26 of the 50 test files include
`common.jl` and a new test file would otherwise have to remember to opt in.

Note that launchers truncate the abort code to 8 bits when reporting it as
the job's exit status, so the errcode has to be sanitized: passing a raw
exit code of 256 makes mpiexec exit 0, turning a hard failure into a green
run. Verified on both MPICH and Open MPI.

Also correct usage.md and external.md, which both described the atexit hook
as calling `MPI.Finalize` when Julia exits, omitting the exit-code condition
that causes all of the above.
@eschnett

Copy link
Copy Markdown
Contributor Author

The failing test is probably cured by #982.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant