Commit 0418d495 authored by Wesley Bland's avatar Wesley Bland Committed by Huiwei Lu
Browse files

Handle anysource in the wait* functions



If a wait operation involves an anysource, we need to first check to
make sure that they haven't been disabled. If they have been, convert
the wait* function to a test* function to prevent deadlocking inside the
progress engine.
Signed-off-by: default avatarHuiwei Lu <huiweilu@mcs.anl.gov>
parent 50d85e51
......@@ -46,7 +46,17 @@ int MPIR_Wait_impl(MPI_Request *request, MPI_Status *status)
if (!MPID_Request_is_complete(request_ptr))
{
MPID_Progress_state progress_state;
/* If this is an anysource request including a communicator with
* anysource disabled, convert the call to an MPI_Test instead so we
* don't get stuck in the progress engine. */
if (unlikely(MPIR_CVAR_ENABLE_FT &&
MPI_ANY_SOURCE == request_ptr->dev.match.parts.rank &&
!MPIDI_CH3I_Comm_AS_enabled(request_ptr->comm))) {
mpi_errno = MPIR_Test_impl(request, &active_flag, status);
goto fn_exit;
}
MPID_Progress_start(&progress_state);
while (!MPID_Request_is_complete(request_ptr))
{
......
......@@ -48,6 +48,7 @@ int MPIR_Waitall_impl(int count, MPI_Request array_of_requests[],
int rc;
int n_greqs;
int proc_failure = FALSE;
int disabled_anysource = FALSE;
const int ignoring_statuses = (array_of_statuses == MPI_STATUSES_IGNORE);
int optimize = ignoring_statuses; /* see NOTE-O1 */
MPIU_CHKLMEM_DECL(1);
......@@ -86,6 +87,16 @@ int MPIR_Waitall_impl(int count, MPI_Request array_of_requests[],
if (request_ptrs[i]->kind == MPID_UREQUEST)
++n_greqs;
/* If one of the requests is an anysource on a communicator that's
* disabled such communication, convert this operation to a testall
* instead to prevent getting stuck in the progress engine. */
if (unlikely(MPIR_CVAR_ENABLE_FT &&
MPI_ANY_SOURCE == request_ptrs[i]->dev.match.parts.rank &&
!MPID_Request_is_complete(request_ptrs[i]) &&
!MPIDI_CH3I_Comm_AS_enabled(request_ptrs[i]->comm))) {
disabled_anysource = TRUE;
}
}
else
{
......@@ -102,6 +113,11 @@ int MPIR_Waitall_impl(int count, MPI_Request array_of_requests[],
goto fn_exit;
}
if (unlikely(disabled_anysource)) {
mpi_errno = MPI_Testall(count, array_of_requests, &disabled_anysource, array_of_statuses);
goto fn_exit;
}
/* NOTE-O1: high-message-rate optimization. For simple send and recv
* operations and MPI_STATUSES_IGNORE we use a fastpath approach that strips
* out as many unnecessary jumps and error handling as possible.
......
......@@ -96,6 +96,7 @@ int MPI_Waitsome(int incount, MPI_Request array_of_requests[],
int n_inactive;
int active_flag;
int rc;
int disabled_anysource = FALSE;
int mpi_errno = MPI_SUCCESS;
MPIU_CHKLMEM_DECL(1);
MPID_MPI_STATE_DECL(MPID_STATE_MPI_WAITSOME);
......@@ -159,6 +160,16 @@ int MPI_Waitsome(int incount, MPI_Request array_of_requests[],
MPID_END_ERROR_CHECKS;
}
# endif
/* If one of the requests is an anysource on a communicator that's
* disabled such communication, convert this operation to a testall
* instead to prevent getting stuck in the progress engine. */
if (unlikely(MPIR_CVAR_ENABLE_FT &&
MPI_ANY_SOURCE == request_ptrs[i]->dev.match.parts.rank &&
!MPID_Request_is_complete(request_ptrs[i]) &&
!MPIDI_CH3I_Comm_AS_enabled(request_ptrs[i]->comm))) {
disabled_anysource = TRUE;
}
}
else
{
......@@ -172,7 +183,12 @@ int MPI_Waitsome(int incount, MPI_Request array_of_requests[],
*outcount = MPI_UNDEFINED;
goto fn_exit;
}
if (unlikely(disabled_anysource)) {
mpi_errno = MPI_Testsome(incount, array_of_requests, outcount, array_of_indices, array_of_statuses);
goto fn_exit;
}
/* Bill Gropp says MPI_Waitsome() is expected to try to make
progress even if some requests have already completed;
therefore, we kick the pipes once and then fall into a loop
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment