A function, which both initialises and then finalises can only be called once, because MPI can be only initialised once during the lifetime of the program and can only be finalised once. To prevent multiple initialisation calls, put the call to MPI_Init()
or MPI_Init_thread()
in a conditional:
int already_initialised;
MPI_Initialized(&already_initialised);
if (!already_initialised)
MPI_Init(NULL, NULL);
As for the finalisation, it should be moved outside of your function, probably in an atexit(3)
handler if you don't want to pollute the outer scope with MPI calls. For example:
void finalise_mpi(void)
{
int already_finalised;
MPI_Finalized(&already_finalised);
if (!already_finalised)
MPI_Finalize();
}
...
atexit(finalise_mpi);
...
The atexit()
call could be part of the initialisation code, e.g.:
int already_initialised;
MPI_Initialized(&already_initialised);
if (!already_initialised)
{
MPI_Init(NULL, NULL);
atexit(finalise_mpi);
}
This would not install the atexit(3)
handler if MPI was already initialised. The basic idea is that if MPI was initialised on entry to the function, then it would mean that MPI_Init()
was called in the outer scope and one would normally expect that MPI_Finalize()
is also called there.
If I were you, I would move MPI initialisation and finalisation out of the parallel processing function. The proper calling sequence would be to initialise MPI, run the tests, then finalise MPI.
I've used the C bindings in the above text as the C++ bindings were deprecated in MPI-2.2 and then deleted in MPI-3.0.