Blame src/mpi/pt2pt/testany.c

Packit 0848f5
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
Packit 0848f5
/*
Packit 0848f5
 *
Packit 0848f5
 *  (C) 2001 by Argonne National Laboratory.
Packit 0848f5
 *      See COPYRIGHT in top-level directory.
Packit 0848f5
 */
Packit 0848f5
Packit 0848f5
#include "mpiimpl.h"
Packit 0848f5
Packit 0848f5
#if !defined(MPID_REQUEST_PTR_ARRAY_SIZE)
Packit 0848f5
#define MPID_REQUEST_PTR_ARRAY_SIZE 16
Packit 0848f5
#endif
Packit 0848f5
Packit 0848f5
/* -- Begin Profiling Symbol Block for routine MPI_Testany */
Packit 0848f5
#if defined(HAVE_PRAGMA_WEAK)
Packit 0848f5
#pragma weak MPI_Testany = PMPI_Testany
Packit 0848f5
#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
Packit 0848f5
#pragma _HP_SECONDARY_DEF PMPI_Testany  MPI_Testany
Packit 0848f5
#elif defined(HAVE_PRAGMA_CRI_DUP)
Packit 0848f5
#pragma _CRI duplicate MPI_Testany as PMPI_Testany
Packit 0848f5
#elif defined(HAVE_WEAK_ATTRIBUTE)
Packit 0848f5
int MPI_Testany(int count, MPI_Request array_of_requests[], int *indx, int *flag,
Packit 0848f5
                MPI_Status *status) __attribute__((weak,alias("PMPI_Testany")));
Packit 0848f5
#endif
Packit 0848f5
/* -- End Profiling Symbol Block */
Packit 0848f5
Packit 0848f5
/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
Packit 0848f5
   the MPI routines */
Packit 0848f5
#ifndef MPICH_MPI_FROM_PMPI
Packit 0848f5
#undef MPI_Testany
Packit 0848f5
#define MPI_Testany PMPI_Testany
Packit 0848f5
Packit 0848f5
#endif
Packit 0848f5
Packit 0848f5
#undef FUNCNAME
Packit 0848f5
#define FUNCNAME MPI_Testany
Packit 0848f5
Packit 0848f5
/*@
Packit 0848f5
    MPI_Testany - Tests for completion of any previdously initiated 
Packit 0848f5
                  requests
Packit 0848f5
Packit 0848f5
Input Parameters:
Packit 0848f5
+ count - list length (integer) 
Packit 0848f5
- array_of_requests - array of requests (array of handles) 
Packit 0848f5
Packit 0848f5
Output Parameters:
Packit 0848f5
+ indx - index of operation that completed, or 'MPI_UNDEFINED'  if none
Packit 0848f5
  completed (integer) 
Packit 0848f5
. flag - true if one of the operations is complete (logical) 
Packit 0848f5
- status - status object (Status).  May be 'MPI_STATUS_IGNORE'.
Packit 0848f5
Packit 0848f5
Notes:
Packit 0848f5
Packit 0848f5
While it is possible to list a request handle more than once in the
Packit 0848f5
'array_of_requests', such an action is considered erroneous and may cause the
Packit 0848f5
program to unexecpectedly terminate or produce incorrect results.
Packit 0848f5
Packit 0848f5
.N ThreadSafe
Packit 0848f5
Packit 0848f5
.N waitstatus
Packit 0848f5
Packit 0848f5
.N Fortran
Packit 0848f5
Packit 0848f5
.N Errors
Packit 0848f5
.N MPI_SUCCESS
Packit 0848f5
@*/
Packit 0848f5
int MPI_Testany(int count, MPI_Request array_of_requests[], int *indx,
Packit 0848f5
		int *flag, MPI_Status *status)
Packit 0848f5
{
Packit 0848f5
    static const char FCNAME[] = "MPI_Testany";
Packit 0848f5
    MPID_Request * request_ptr_array[MPID_REQUEST_PTR_ARRAY_SIZE];
Packit 0848f5
    MPID_Request ** request_ptrs = request_ptr_array;
Packit 0848f5
    int i;
Packit 0848f5
    int n_inactive;
Packit 0848f5
    int active_flag;
Packit 0848f5
    int last_disabled_anysource = -1;
Packit 0848f5
    int mpi_errno = MPI_SUCCESS;
Packit 0848f5
    MPIU_CHKLMEM_DECL(1);
Packit 0848f5
    MPID_MPI_STATE_DECL(MPID_STATE_MPI_TESTANY);
Packit 0848f5
Packit 0848f5
    MPIR_ERRTEST_INITIALIZED_ORDIE();
Packit 0848f5
    
Packit 0848f5
    MPID_THREAD_CS_ENTER(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX);
Packit 0848f5
    MPID_MPI_PT2PT_FUNC_ENTER(MPID_STATE_MPI_TESTANY);
Packit 0848f5
Packit 0848f5
    /* Check the arguments */
Packit 0848f5
#   ifdef HAVE_ERROR_CHECKING
Packit 0848f5
    {
Packit 0848f5
        MPID_BEGIN_ERROR_CHECKS;
Packit 0848f5
        {
Packit 0848f5
	    MPIR_ERRTEST_COUNT(count, mpi_errno);
Packit 0848f5
Packit 0848f5
	    if (count != 0) {
Packit 0848f5
		MPIR_ERRTEST_ARGNULL(array_of_requests, "array_of_requests", mpi_errno);
Packit 0848f5
		/* NOTE: MPI_STATUS_IGNORE != NULL */
Packit 0848f5
		MPIR_ERRTEST_ARGNULL(status, "status", mpi_errno);
Packit 0848f5
	    }
Packit 0848f5
	    MPIR_ERRTEST_ARGNULL(indx, "indx", mpi_errno);
Packit 0848f5
	    MPIR_ERRTEST_ARGNULL(flag, "flag", mpi_errno);
Packit 0848f5
	    
Packit 0848f5
	    for (i = 0; i < count; i++) {
Packit 0848f5
		MPIR_ERRTEST_ARRAYREQUEST_OR_NULL(array_of_requests[i], i, mpi_errno);
Packit 0848f5
	    }
Packit 0848f5
	}
Packit 0848f5
        MPID_END_ERROR_CHECKS;
Packit 0848f5
    }
Packit 0848f5
#   endif /* HAVE_ERROR_CHECKING */
Packit 0848f5
Packit 0848f5
    /* ... body of routine ...  */
Packit 0848f5
    
Packit 0848f5
    /* Convert MPI request handles to a request object pointers */
Packit 0848f5
    if (count > MPID_REQUEST_PTR_ARRAY_SIZE)
Packit 0848f5
    {
Packit 0848f5
	MPIU_CHKLMEM_MALLOC_ORJUMP(request_ptrs, MPID_Request **, count * sizeof(MPID_Request *), mpi_errno, "request pointers");
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    n_inactive = 0;
Packit 0848f5
    for (i = 0; i < count; i++)
Packit 0848f5
    {
Packit 0848f5
	if (array_of_requests[i] != MPI_REQUEST_NULL)
Packit 0848f5
	{
Packit 0848f5
	    MPID_Request_get_ptr(array_of_requests[i], request_ptrs[i]);
Packit 0848f5
	    /* Validate object pointers if error checking is enabled */
Packit 0848f5
#           ifdef HAVE_ERROR_CHECKING
Packit 0848f5
	    {
Packit 0848f5
		MPID_BEGIN_ERROR_CHECKS;
Packit 0848f5
		{
Packit 0848f5
		    MPID_Request_valid_ptr( request_ptrs[i], mpi_errno );
Packit 0848f5
		    if (mpi_errno) goto fn_fail;
Packit 0848f5
		}
Packit 0848f5
		MPID_END_ERROR_CHECKS;
Packit 0848f5
	    }
Packit 0848f5
#           endif	    
Packit 0848f5
	}
Packit 0848f5
	else
Packit 0848f5
	{
Packit 0848f5
	    request_ptrs[i] = NULL;
Packit 0848f5
	    n_inactive += 1;
Packit 0848f5
	}
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    if (n_inactive == count)
Packit 0848f5
    {
Packit 0848f5
	*flag = TRUE;
Packit 0848f5
	*indx = MPI_UNDEFINED;
Packit 0848f5
	if (status != NULL)  /* could be null if count=0 */
Packit 0848f5
	    MPIR_Status_set_empty(status);
Packit 0848f5
	goto fn_exit;
Packit 0848f5
    }
Packit 0848f5
    
Packit 0848f5
    *flag = FALSE;
Packit 0848f5
    *indx = MPI_UNDEFINED;
Packit 0848f5
    
Packit 0848f5
    mpi_errno = MPID_Progress_test();
Packit 0848f5
    /* --BEGIN ERROR HANDLING-- */
Packit 0848f5
    if (mpi_errno != MPI_SUCCESS)
Packit 0848f5
    {
Packit 0848f5
	goto fn_fail;
Packit 0848f5
    }
Packit 0848f5
    /* --END ERROR HANDLING-- */
Packit 0848f5
	
Packit 0848f5
    for (i = 0; i < count; i++)
Packit 0848f5
    {
Packit 0848f5
	if (request_ptrs[i] != NULL && 
Packit 0848f5
            request_ptrs[i]->kind == MPID_UREQUEST &&
Packit 0848f5
            request_ptrs[i]->greq_fns->poll_fn != NULL)
Packit 0848f5
	{
Packit 0848f5
            mpi_errno = (request_ptrs[i]->greq_fns->poll_fn)(request_ptrs[i]->greq_fns->grequest_extra_state,
Packit 0848f5
                                                             status);
Packit 0848f5
	    if (mpi_errno != MPI_SUCCESS) goto fn_fail;
Packit 0848f5
	}
Packit 0848f5
        if (request_ptrs[i] != NULL)
Packit 0848f5
        {
Packit 0848f5
            if (MPID_Request_is_complete(request_ptrs[i]))
Packit 0848f5
            {
Packit 0848f5
                mpi_errno = MPIR_Request_complete(&array_of_requests[i],
Packit 0848f5
                        request_ptrs[i],
Packit 0848f5
                        status, &active_flag);
Packit 0848f5
                if (active_flag)
Packit 0848f5
                {
Packit 0848f5
                    *flag = TRUE;
Packit 0848f5
                    *indx = i;
Packit 0848f5
                    goto fn_exit;
Packit 0848f5
                }
Packit 0848f5
                else
Packit 0848f5
                {
Packit 0848f5
                    n_inactive += 1;
Packit 0848f5
                }
Packit 0848f5
            } else if (unlikely(MPIR_CVAR_ENABLE_FT &&
Packit 0848f5
                        MPID_Request_is_anysource(request_ptrs[i]) &&
Packit 0848f5
                        !MPID_Comm_AS_enabled(request_ptrs[i]->comm)))
Packit 0848f5
            {
Packit 0848f5
                last_disabled_anysource = i;
Packit 0848f5
            }
Packit 0848f5
        }
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    /* If none of the requests completed, mark the last anysource request as
Packit 0848f5
     * pending failure. */
Packit 0848f5
    if (unlikely(last_disabled_anysource != -1))
Packit 0848f5
    {
Packit 0848f5
        MPIR_ERR_SET(mpi_errno, MPIX_ERR_PROC_FAILED_PENDING, "**failure_pending");
Packit 0848f5
        if (status != MPI_STATUS_IGNORE) status->MPI_ERROR = mpi_errno;
Packit 0848f5
        *flag = TRUE;
Packit 0848f5
        goto fn_fail;
Packit 0848f5
    }
Packit 0848f5
    
Packit 0848f5
    if (n_inactive == count)
Packit 0848f5
    {
Packit 0848f5
	*flag = TRUE;
Packit 0848f5
	*indx = MPI_UNDEFINED;
Packit 0848f5
	/* status set to empty by MPIR_Request_complete() */
Packit 0848f5
    }
Packit 0848f5
    
Packit 0848f5
    /* ... end of body of routine ... */
Packit 0848f5
    
Packit 0848f5
  fn_exit:
Packit 0848f5
    if (count > MPID_REQUEST_PTR_ARRAY_SIZE)
Packit 0848f5
    {
Packit 0848f5
	MPIU_CHKLMEM_FREEALL();
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    MPID_MPI_PT2PT_FUNC_EXIT(MPID_STATE_MPI_TESTANY);
Packit 0848f5
    MPID_THREAD_CS_EXIT(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX);
Packit 0848f5
    return mpi_errno;
Packit 0848f5
Packit 0848f5
  fn_fail:
Packit 0848f5
    /* --BEGIN ERROR HANDLING-- */
Packit 0848f5
#   ifdef HAVE_ERROR_CHECKING
Packit 0848f5
    {
Packit 0848f5
	mpi_errno = MPIR_Err_create_code(
Packit 0848f5
	    mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**mpi_testany",
Packit 0848f5
	    "**mpi_testany %d %p %p %p %p", count, array_of_requests, indx, flag, status);
Packit 0848f5
    }
Packit 0848f5
#   endif
Packit 0848f5
    mpi_errno = MPIR_Err_return_comm(NULL, FCNAME, mpi_errno);
Packit 0848f5
    goto fn_exit;
Packit 0848f5
    /* --END ERROR HANDLING-- */
Packit 0848f5
}