コード例 #1
0
ファイル: iprobe.c プロジェクト: carsten-clauss/MP-MPICH
/*@
    MPI_Iprobe - Nonblocking test for a message

Input Parameters:
+ source - source rank, or  'MPI_ANY_SOURCE' (integer) 
. tag - tag value or  'MPI_ANY_TAG' (integer) 
- comm - communicator (handle) 

Output Parameter:
+ flag - (logical) 
- status - status object (Status) 

.N fortran

.N Errors
.N MPI_SUCCESS
.N MPI_ERR_COMM
.N MPI_ERR_TAG
.N MPI_ERR_RANK

@*/
EXPORT_MPI_API int MPI_Iprobe( int source, int tag, MPI_Comm comm, int *flag, 
		MPI_Status *status )
{
    MPI_Status __status;
    int mpi_errno = MPI_SUCCESS;
    struct MPIR_COMMUNICATOR *comm_ptr;
    static char myname[] = "MPI_IPROBE";

    TR_PUSH(myname);

    if(status == MPI_STATUS_IGNORE) status = &__status;

    comm_ptr = MPIR_GET_COMM_PTR(comm);

#ifndef MPIR_NO_ERROR_CHECKING
    MPIR_TEST_MPI_COMM(comm,comm_ptr,comm_ptr,myname);
    MPIR_TEST_RECV_TAG(tag);
    MPIR_TEST_RECV_RANK(comm_ptr,source);
    if (mpi_errno)
	return MPIR_ERROR(comm_ptr, mpi_errno, myname );
#endif

    if (source == MPI_PROC_NULL) {
	status->MPI_SOURCE = MPI_PROC_NULL;
	status->MPI_TAG	   = MPI_ANY_TAG;
	MPID_ZERO_STATUS_COUNT(status);
	return MPI_SUCCESS;
	}
    MPID_Iprobe( comm_ptr, tag, comm_ptr->recv_context, source, flag, 
		 &mpi_errno, status );
    TR_POP;
    MPIR_RETURN( comm_ptr, mpi_errno, myname );
}
コード例 #2
0
ファイル: recv.c プロジェクト: hpc/mvapich-cce
/*@
    MPI_Recv - Basic receive

Output Parameters:
+ buf - initial address of receive buffer (choice)
- status - status object (Status)

Input Parameters:
+ count - maximum number of elements in receive buffer (integer)
. datatype - datatype of each receive buffer element (handle)
. source - rank of source (integer)
. tag - message tag (integer)
- comm - communicator (handle)

Notes:
The 'count' argument indicates the maximum length of a message; the actual
number can be determined with 'MPI_Get_count'.

.N fortran

.N Errors
.N MPI_SUCCESS
.N MPI_ERR_COMM
.N MPI_ERR_TYPE
.N MPI_ERR_COUNT
.N MPI_ERR_TAG
.N MPI_ERR_RANK

@*/
int MPI_Recv( void *buf, int count, MPI_Datatype datatype, int source,
              int tag, MPI_Comm comm, MPI_Status *status )
{
    struct MPIR_COMMUNICATOR *comm_ptr;
    struct MPIR_DATATYPE     *dtype_ptr;
    static char myname[] = "MPI_RECV";
    int         mpi_errno = MPI_SUCCESS;
    /*
       Because this is a very common routine, we show how it can be
       optimized to be run "inline"; In addition, this lets us exploit
       features in the ADI to simplify the execution of blocking receive
       calls.
     */
    if (source != MPI_PROC_NULL)
    {
        disableSignal();
        comm_ptr = MPIR_GET_COMM_PTR(comm);
        MPIR_TEST_MPI_COMM(comm,comm_ptr,comm_ptr,myname);

        dtype_ptr = MPIR_GET_DTYPE_PTR(datatype);
        MPIR_TEST_DTYPE(datatype,dtype_ptr,comm_ptr,myname);

#ifndef MPIR_NO_ERROR_CHECKING
        MPIR_TEST_COUNT(count);
        MPIR_TEST_RECV_TAG(tag);
        MPIR_TEST_RECV_RANK(comm_ptr,source);
        if (mpi_errno) {
            revertSignal();
            return MPIR_ERROR(comm_ptr, mpi_errno, myname );
        }
#endif

        MPID_RecvDatatype( comm_ptr, buf, count, dtype_ptr, source, tag,
                           comm_ptr->recv_context, status, &mpi_errno );
        revertSignal();
        MPIR_RETURN(comm_ptr, mpi_errno, myname );
    }
    else {
        if (status != MPI_STATUS_IGNORE) {
            /* See MPI standard section 3.11 */
            MPID_ZERO_STATUS_COUNT(status);
            status->MPI_SOURCE     = MPI_PROC_NULL;
            status->MPI_TAG        = MPI_ANY_TAG;
        }
    }
    return MPI_SUCCESS;
}
コード例 #3
0
ファイル: testall.c プロジェクト: hpc/mvapich-cce
/*@
    MPI_Testall - Tests for the completion of all previously initiated
    communications

Input Parameters:
+ count - lists length (integer) 
- array_of_requests - array of requests (array of handles) 

Output Parameters:
+ flag - (logical) 
- array_of_statuses - array of status objects (array of Status).  May be
 'MPI_STATUSES_IGNORE'.

Notes:
  'flag' is true only if all requests have completed.  Otherwise, flag is
  false and neither the 'array_of_requests' nor the 'array_of_statuses' is
  modified.

.N waitstatus

.N fortran

.N Errors
.N MPI_SUCCESS
.N MPI_ERR_IN_STATUS

@*/
int MPI_Testall( 
	int count, 
	MPI_Request array_of_requests[], 
	int *flag, 
	MPI_Status array_of_statuses[] )
{
    int i, mpi_errno = MPI_SUCCESS;
    MPI_Request request;
    int nready;
    static char myname[] = "MPI_TESTALL";

    disableSignal();
    TR_PUSH(myname);

    MPID_DeviceCheck( MPID_NOTBLOCKING );
  /* It is a good thing that the receive requests contain the status object!
     We need this to save the status information in the case where not
     all of the requests have completed.

     Note that this routine forces some changes on the ADI test routines.
     It must be possible to test a completed request multiple times;
     once the "is_complete" field is set, the data must be saved until
     the request is explicitly freed.  That is, unlike the MPI tests,
     the ADI tests must be nondestructive.
   */
    nready = 0;
    for (i = 0; i < count; i++ ) {
	request = array_of_requests[i];
	if (!request) {
	    nready ++;
	    continue;
	}
	switch (request->handle_type) {
	case MPIR_SEND:
	    if (MPID_SendRequestCancelled(request)) {
		if (array_of_statuses) {
		    array_of_statuses[i].MPI_TAG = MPIR_MSG_CANCELLED; 
		    array_of_statuses[i].MPI_ERROR = MPI_SUCCESS;
		}
	        nready++; }
	    else if (!request->shandle.is_complete) {
		if (MPID_SendIcomplete( request, &mpi_errno ))
		    nready++;
	    }
	    else nready++;
	    break;
	case MPIR_RECV:
	    if (request->rhandle.s.MPI_TAG == MPIR_MSG_CANCELLED) {
		if (array_of_statuses) 
		    array_of_statuses[i].MPI_TAG = MPIR_MSG_CANCELLED; 
	        nready++; }
	    else if (!request->rhandle.is_complete) {
		if (MPID_RecvIcomplete( request, (MPI_Status *)0, &mpi_errno ))
		    nready++;
	    }
	    else nready++;
	    break;
	case MPIR_PERSISTENT_SEND:
	    if (request->persistent_shandle.active &&
		!request->persistent_shandle.shandle.is_complete) {
		if (MPID_SendIcomplete( request, &mpi_errno ))
		    nready++;
	    }
	    else nready++;
	    break;
	case MPIR_PERSISTENT_RECV:
	    if (request->persistent_rhandle.active &&
		!request->persistent_rhandle.rhandle.is_complete) {
		if (MPID_RecvIcomplete( request, (MPI_Status *)0, &mpi_errno ))
		    nready++;
	    }
	    else nready++;
	    break;
	}
	if (mpi_errno) {
	    if (array_of_statuses) 
		MPIR_Set_Status_error_array( array_of_requests, count, i, 
					     mpi_errno, array_of_statuses );
	    mpi_errno = MPI_ERR_IN_STATUS;
	    TR_POP;
            revertSignal();
	    MPIR_RETURN(MPIR_COMM_WORLD, mpi_errno, myname );
	}
    }
    *flag = (nready == count);
    /* Because a request may have completed with an error (such as 
       MPI_ERR_TRUNCATE), we need to check here as well.
       Only if all are ready do we set complete the requests.  Fortunately,
       the standard allows us to say that the values in array_of_statuses
       is undefined if all requests are not ready. */
    if (nready == count) {
	for (i=0; i<count; i++) {
	    request = array_of_requests[i];
	    if (!request) {
		/* See MPI Standard, 3.7 */
		if (array_of_statuses) {
		    array_of_statuses[i].MPI_TAG	= MPI_ANY_TAG;
		    array_of_statuses[i].MPI_SOURCE	= MPI_ANY_SOURCE;
		    array_of_statuses[i].MPI_ERROR	= MPI_SUCCESS;
		    MPID_ZERO_STATUS_COUNT(&array_of_statuses[i]);
		}
		continue;
	    }
	    switch (request->handle_type) {
	    case MPIR_SEND:
		/* There was a test on 	
		   array_of_statuses[i].MPI_TAG != MPIR_MSG_CANCELLED
		   here to avoid the MPID_SendRequestCancelled call,
		   but that depends on setting the MPI_TAG field
		   in the array of statuses.  It would be better to 
		   make the MPID_SendRequestCancelled routine a 
		   macro */
		if (!MPID_SendRequestCancelled(request)) {
		    MPIR_FORGET_SEND( &request->shandle );
		    MPID_SendFree( array_of_requests[i] );
		    array_of_requests[i] = MPI_REQUEST_NULL;
		}
		break;
	    case MPIR_RECV:
		if (request->rhandle.s.MPI_TAG != MPIR_MSG_CANCELLED) {
		    if (request->rhandle.s.MPI_ERROR) 
			mpi_errno = request->rhandle.s.MPI_ERROR;
/*
		if (request->rhandle.s.MPI_ERROR && mpi_errno == MPI_SUCCESS) {
		    for (j=0; j<count; j++) {
			if (!array_of_requests[i] || 
			    array_of_requests[i].is_complete)
			    array_of_statuses[j].MPI_ERROR = MPI_SUCCESS;
			else
			    array_of_statuses[j].MPI_ERROR = MPI_ERR_PENDING;
		    }
		    mpi_errno = MPI_ERR_IN_STATUS;
		}
 */
		 
		    if (array_of_statuses) 
			array_of_statuses[i] = request->rhandle.s;
		    MPID_RecvFree( array_of_requests[i] );
		    array_of_requests[i] = MPI_REQUEST_NULL;
		}
		break;
	    case MPIR_PERSISTENT_SEND:
		if (request->persistent_shandle.active) {
		    /* array_of_statuses[i] =
			request->persistent_shandle.shandle.s; */
		    if (array_of_statuses)
			array_of_statuses[i].MPI_ERROR = 
			    MPID_SendRequestErrval(&request->persistent_shandle.shandle);
		    request->persistent_shandle.active = 0;
		}
		else {
		    /* See MPI Standard, 3.7 */
		    /* Thanks to [email protected] for this fix */
		    if (array_of_statuses) {
			if (MPID_SendRequestCancelled(&request->persistent_shandle))
			    array_of_statuses[i].MPI_TAG = MPIR_MSG_CANCELLED;
			else
			    array_of_statuses[i].MPI_TAG = MPI_ANY_TAG;
			
			array_of_statuses[i].MPI_SOURCE = MPI_ANY_SOURCE;
			array_of_statuses[i].MPI_ERROR  = MPI_SUCCESS;
			MPID_ZERO_STATUS_COUNT(&array_of_statuses[i]);
		    }
		}
		break;
	    case MPIR_PERSISTENT_RECV:
		if (request->persistent_rhandle.active) {
		    if (array_of_statuses) 
			array_of_statuses[i] = 
			    request->persistent_rhandle.rhandle.s;
		    mpi_errno = request->persistent_rhandle.rhandle.s.MPI_ERROR;
		    request->persistent_rhandle.active = 0;
		}
		else {
		    /* See MPI Standard, 3.7 */
		    /* Thanks to [email protected] for this fix */
		    if (array_of_statuses) {
			if (request->persistent_rhandle.rhandle.s.MPI_TAG ==
			    MPIR_MSG_CANCELLED) 
			    array_of_statuses[i].MPI_TAG = MPIR_MSG_CANCELLED;
			else
			    array_of_statuses[i].MPI_TAG = MPI_ANY_TAG;
			
			array_of_statuses[i].MPI_SOURCE = MPI_ANY_SOURCE;
			array_of_statuses[i].MPI_ERROR  = MPI_SUCCESS;
			MPID_ZERO_STATUS_COUNT(&array_of_statuses[i]);
		    }
		}
		break;
	    }
	    if (mpi_errno) {
		if (array_of_statuses) 
		    MPIR_Set_Status_error_array( array_of_requests, count, i, 
						mpi_errno, array_of_statuses );
		mpi_errno = MPI_ERR_IN_STATUS;
		TR_POP;
                revertSignal();
		MPIR_RETURN(MPIR_COMM_WORLD, mpi_errno, myname );
	    }
	}
    }
    TR_POP;
    revertSignal();
    MPIR_RETURN(MPIR_COMM_WORLD, mpi_errno, myname );
}
コード例 #4
0
ファイル: waitany.c プロジェクト: carsten-clauss/MP-MPICH
/*@
    MPI_Waitany - Waits for any specified send or receive to complete

Input Parameters:
+ count - list length (integer) 
- array_of_requests - array of requests (array of handles) 

Output Parameters:
+ index - index of handle for operation that completed (integer).  In the
range '0' to 'count-1'.  In Fortran, the range is '1' to 'count'.
- status - status object (Status) 

Notes:
If all of the requests are 'MPI_REQUEST_NULL', then 'index' is returned as 
'MPI_UNDEFINED', and 'status' is returned as an empty status.

.N waitstatus

.N fortran

.N Errors
.N MPI_SUCCESS
.N MPI_ERR_REQUEST
.N MPI_ERR_ARG
@*/
EXPORT_MPI_API int MPI_Waitany(
	int count, 
	MPI_Request array_of_requests[], 
	int *index, 
	MPI_Status *status )
{
    int i, mpi_errno = MPI_SUCCESS;
    int done;
    MPI_Request request;
    static char myname[] = "MPI_WAITANY";

    TR_PUSH(myname);
    *index = MPI_UNDEFINED;

    /* Check for all requests either null or inactive persistent */
    for (i=0; i < count; i++) {
	request = array_of_requests[i];
	if (!request) continue;
	if (request->handle_type == MPIR_PERSISTENT_SEND) {
	    if (request->persistent_shandle.active) break;
	    if (MPID_SendRequestCancelled(&request->persistent_shandle))
		break;
	}
	else if (request->handle_type == MPIR_PERSISTENT_RECV) {
	    if (request->persistent_rhandle.active) break;
	    if (request->persistent_rhandle.rhandle.s.MPI_TAG ==
		MPIR_MSG_CANCELLED) break;
	}
	else 
	    break;
    }

    if (i == count) {
	/* MPI Standard 1.1 requires an empty status in this case */
 	status->MPI_TAG	   = MPI_ANY_TAG;
	status->MPI_SOURCE = MPI_ANY_SOURCE;
	status->MPI_ERROR  = MPI_SUCCESS;
	MPID_ZERO_STATUS_COUNT(status);
        *index             = MPI_UNDEFINED;
	TR_POP;
	return mpi_errno;
	}
    done = 0;
    while (!done) {
	for (i=0; !done && i<count; i++) {
	    request = array_of_requests[i];
	    if (!request) continue;
	    switch (request->handle_type) {
	    case MPIR_SEND:
		if (MPID_SendRequestCancelled(request)) {
		    status->MPI_TAG = MPIR_MSG_CANCELLED; 
		    *index = i;
		    done = 1;
		}
		else {
		    if (MPID_SendIcomplete( request, &mpi_errno )) {
			if (mpi_errno) 
			    MPIR_ERROR( MPIR_COMM_WORLD, mpi_errno, myname );
			MPIR_FORGET_SEND( &request->shandle );
			MPID_Send_free( array_of_requests[i] );
			*index = i;
			array_of_requests[i] = 0;
			done = 1;
		    }
		}
		break;
	    case MPIR_RECV:
		if (request->rhandle.s.MPI_TAG == MPIR_MSG_CANCELLED) {
		    status->MPI_TAG = MPIR_MSG_CANCELLED;
		    MPID_Recv_free( array_of_requests[i] );
		    *index = i;
		    array_of_requests[i] = 0; 
		    done = 1;
		}
		else {
		    if (MPID_RecvIcomplete( request, status, &mpi_errno )) {
			if (mpi_errno) 
			    MPIR_ERROR( MPIR_COMM_WORLD, mpi_errno, myname );
			MPID_Recv_free( array_of_requests[i] );
			*index = i;
			array_of_requests[i] = 0;
			done = 1;
		    }
		}
		break;
	    case MPIR_PERSISTENT_SEND:
		if (request->persistent_shandle.active) {
		    if (MPID_SendIcomplete( request, &mpi_errno )) {
			if (mpi_errno) 
			    MPIR_ERROR( MPIR_COMM_WORLD, mpi_errno, myname );
			request->persistent_shandle.active = 0;
			*index = i;
			done = 1;
		    }
		}
		else {
		    if (MPID_SendRequestCancelled(&request->persistent_shandle)) {
			status->MPI_TAG = MPIR_MSG_CANCELLED; 
			*index = i;
			done = 1;
		    }
		}
		break;
	    case MPIR_PERSISTENT_RECV:
		if (request->persistent_rhandle.active) {
		    if (MPID_RecvIcomplete( request, status, &mpi_errno )) {
			if (mpi_errno) 
			    MPIR_ERROR( MPIR_COMM_WORLD, mpi_errno, myname );
			request->persistent_rhandle.active = 0;
			*index = i;
			done   = 1;
		    }
		}
		else {
		    if (request->persistent_rhandle.rhandle.s.MPI_TAG ==
			MPIR_MSG_CANCELLED) {
			status->MPI_TAG = MPIR_MSG_CANCELLED; 
			*index = i;
			done = 1;
		    }
		}
		break;
	    }
	}
	if (!done) {
	    /* Do a NON blocking check */
	    MPID_DeviceCheck( MPID_NOTBLOCKING );
	}
	else 
	    break;
    }
    TR_POP;
    return mpi_errno;
}