コード例 #1
0
ファイル: shmem_coll.c プロジェクト: hpc/mvapich-cce
/* Shared memory gather: rank zero is the root always*/
void MPID_SHMEM_COLL_GetShmemBuf(int size, int rank, int shmem_comm_rank, void** output_buf)
{
    int i,myid;
    char* shmem_coll_buf = shmem_coll_obj.shmem_coll_buf;

    myid = rank;

    if (myid == 0) {

        for (i=1; i < size; i++) {
            while (shmem_coll_obj.child_complete_gather[shmem_comm_rank][i] == 0)
            {
                MPID_DeviceCheck(MPID_NOTBLOCKING);
            };
        }
        /* Set the completion flags back to zero */
        for (i=1; i < size; i++) {
            shmem_coll_obj.child_complete_gather[shmem_comm_rank][i] = 0;
        }
        *output_buf = (char*)shmem_coll_buf + shmem_comm_rank*SHMEM_COLL_BLOCK_SIZE;
    }
    else {
        while (shmem_coll_obj.root_complete_gather[shmem_comm_rank][myid] == 0)
        {
            MPID_DeviceCheck(MPID_NOTBLOCKING);
        };
        shmem_coll_obj.root_complete_gather[shmem_comm_rank][myid] = 0;
        *output_buf = (char*)shmem_coll_buf + shmem_comm_rank*SHMEM_COLL_BLOCK_SIZE;
    }
}
コード例 #2
0
ファイル: mpid_hsend.c プロジェクト: grondo/mvapich-cce
/*
 * Noncontiguous datatype isend
 * This is a simple implementation.  Note that in the rendezvous case, the
 * "pack" could be deferred until the "ok to send" message arrives.  To
 * implement this, the individual "send" routines would have to know how to
 * handle general datatypes.  
 */
void MPID_IsendDatatype(struct MPIR_COMMUNICATOR *comm_ptr,
                        void *buf,
                        int count,
                        struct MPIR_DATATYPE *dtype_ptr,
                        int src_lrank,
                        int tag,
                        int context_id,
                        int dest_grank,
                        MPI_Request request, int *error_code)
{
    int len, contig_size;
    void *mybuf;
    MPID_Msgrep_t msgrep = MPID_MSGREP_RECEIVER;
    MPID_Msg_pack_t msgact = MPID_MSG_OK;

    request->shandle.finish = NULL;

    contig_size = MPIR_GET_DTYPE_SIZE(datatype, dtype_ptr);
    if (contig_size > 0 || count == 0) {
        if (Is_MPI_Bottom(buf, count, dtype_ptr)) {
            buf = MPID_Adjust_Bottom(buf, dtype_ptr);
        }
        len = contig_size * count;
        MPID_IsendContig(comm_ptr, buf, len, src_lrank, tag, context_id,
                         dest_grank, msgrep, request, error_code);

        if((&viadev.connections[dest_grank])->ext_sendq_size >= 
                viadev_progress_threshold) {
            MPID_DeviceCheck(MPID_NOTBLOCKING);
        }

        return;
    }

    mybuf = 0;
    MPID_PackMessage(buf, count, dtype_ptr, comm_ptr, dest_grank,
                     msgrep, msgact, (void **) &mybuf, &len, error_code);
    if (*error_code)
        return;

    request->shandle.finish = MPID_IsendDatatypeFinish;

    request->shandle.local_address = mybuf;

    MPID_IsendContig(comm_ptr, mybuf, len, src_lrank, tag, context_id,
                     dest_grank, msgrep, request, error_code);

    if((&viadev.connections[dest_grank])->ext_sendq_size >= 
            viadev_progress_threshold) {
        MPID_DeviceCheck(MPID_NOTBLOCKING);
    }

    /* Note that, from the users perspective, the message is now complete
       (!) since the data is out of the input buffer (!) */
}
コード例 #3
0
ファイル: shmem_coll.c プロジェクト: hpc/mvapich-cce
void MPID_SHMEM_COLL_Barrier_bcast(int size, int rank, int shmem_comm_rank)
{
    int i, myid;
    myid = rank;

    if (rank == 0) {
        for (i=1; i < size; i++) {
            shmem_coll_obj.barrier_bcast[shmem_comm_rank][i] = 1;
        }
    }
    else {
        while (shmem_coll_obj.barrier_bcast[shmem_comm_rank][myid] == 0)
        {
            MPID_DeviceCheck(MPID_NOTBLOCKING);
        }
        shmem_coll_obj.barrier_bcast[shmem_comm_rank][myid] = 0;
    }
    MPID_DeviceCheck(MPID_NOTBLOCKING);
}
コード例 #4
0
ファイル: shmem_coll.c プロジェクト: hpc/mvapich-cce
void wait_for_signal(int step, int index, char** output_buf, int* offset, int* bytes, void* mmap_ptr) {

    char* shmem_coll_buf = (char*)(mmap_ptr);
    volatile char* bcast_flags;
    bcast_flags = (char*)shmem_coll_buf +  index*shmem_bcast_flags;
    char* tmp = (char*)shmem_coll_buf + 3*shmem_bcast_flags + step*SHMEM_BCAST_METADATA;
    void* buffer;
    while (bcast_flags[step] == 0) {
        MPID_DeviceCheck(MPID_NOTBLOCKING);
    }
    buffer = (aint_t*)tmp;
    buffer = (int*)(tmp + sizeof(aint_t));
    *offset = *((int*)buffer);
    *output_buf = (char*)(mmap_ptr) + 3*shmem_bcast_flags + shmem_bcast_leaders*SHMEM_BCAST_METADATA + *offset;
    buffer = (int*)(tmp + sizeof(aint_t) + sizeof(int));
    *bytes = *((int*)buffer);

}
コード例 #5
0
ファイル: testsome.c プロジェクト: hpc/mvapich-cce
/*@
    MPI_Testsome - Tests for some given communications to complete

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

Output Parameters:
+ outcount - number of completed requests (integer) 
. array_of_indices - array of indices of operations that 
completed (array of integers) 
- array_of_statuses - array of status objects for 
    operations that completed (array of Status).  May be 'MPI_STATUSES_IGNORE'.

.N waitstatus

.N fortran

.N Errors
.N MPI_SUCCESS
.N MPI_ERR_IN_STATUS

@*/
int MPI_Testsome( 
	int incount, 
	MPI_Request array_of_requests[], 
	int *outcount, 
	int array_of_indices[], 
	MPI_Status array_of_statuses[] )
{
    int i, j, mpi_errno = MPI_SUCCESS;
    int nfound = 0;
    int nnull  = 0;
    int mpi_lerr;
    MPI_Request request;
    static char myname[] = "MPI_TESTSOME";
  
    disableSignal();

    TR_PUSH(myname);
    /* NOTE:
       This implementation will not work correctly if the device requires
       messages to be received in some particular order.  In that case, 
       this routine needs to try and complete the messages in ANY order.
       
       The same is true for testall.c .
     */
    MPID_DeviceCheck( MPID_NOTBLOCKING );
    for (i = 0; i < incount; i++) {
	/* Skip over null handles.  We need this for handles generated
	   when MPI_PROC_NULL is the source or destination of an 
	   operation */
	request = array_of_requests[i];

	if (!request) {/*  || !request->chandle.active) { */
	    nnull ++;
	    continue;
	    }

	mpi_lerr = 0;
	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;
		}
	        nfound++; }
	    else {
		if (request->shandle.is_complete || 
		    MPID_SendIcomplete( request, &mpi_lerr )) {
		    array_of_indices[nfound] = i;
		    if (mpi_lerr) {
			if (mpi_errno == MPI_SUCCESS) {
			    if (array_of_statuses) {
				for (j=0; j<incount; j++) 
				    array_of_statuses[j].MPI_ERROR = MPI_SUCCESS;
			    }
			    mpi_errno = MPI_ERR_IN_STATUS;
			}
			if (array_of_statuses) 
			    array_of_statuses[nfound].MPI_ERROR = mpi_lerr;
		    }
		    MPIR_FORGET_SEND( &request->shandle );
		    MPID_SendFree( request );
		    array_of_requests[i] = 0;
		    nfound++;
		}
	    }
	    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; 
	        nfound++; }
	    else {
		if (request->rhandle.is_complete || 
		    MPID_RecvIcomplete( request, (MPI_Status *)0, 
					&mpi_lerr )) {
		    array_of_indices[nfound]  = i;
		    if (request->rhandle.s.MPI_ERROR) {
			if (mpi_errno == MPI_SUCCESS) {
			    if (array_of_statuses) {
				for (j=0; j<incount; j++) 
				    array_of_statuses[j].MPI_ERROR = MPI_SUCCESS;
			    }
			    mpi_errno = MPI_ERR_IN_STATUS;
			}
		    }
		    if (array_of_statuses)
			array_of_statuses[nfound] = request->rhandle.s;
		    MPID_RecvFree( request );
		    array_of_requests[i] = 0;
		    nfound++;
		}
	    }
	    break;
	case MPIR_PERSISTENT_SEND:
	    if (!request->persistent_shandle.active) {
		if (MPID_SendRequestCancelled(&request->persistent_shandle)) {
		    if (array_of_statuses) 
			array_of_statuses[i].MPI_TAG = MPIR_MSG_CANCELLED;
		    nfound++;
		}
		else
		    nnull++;
	    }
	    else if (request->persistent_shandle.shandle.is_complete ||
		     MPID_SendIcomplete( request, &mpi_lerr )) {
		array_of_indices[nfound] = i;
		if (mpi_lerr) {
		    if (mpi_errno == MPI_SUCCESS) {
			if (array_of_statuses) {
			    for (j=0; j<incount; j++) 
				array_of_statuses[j].MPI_ERROR = MPI_SUCCESS;
			}
		    mpi_errno = MPI_ERR_IN_STATUS;
		    }
		    if (array_of_statuses) 
			array_of_statuses[nfound].MPI_ERROR = mpi_lerr;
		}
		request->persistent_shandle.active = 0;
		nfound++;
	    }
	    break;
	case MPIR_PERSISTENT_RECV:
	    if (!request->persistent_rhandle.active) {
		if (request->persistent_rhandle.rhandle.s.MPI_TAG ==
		    MPIR_MSG_CANCELLED) {
		    if (array_of_statuses) 
			array_of_statuses[i].MPI_TAG = MPIR_MSG_CANCELLED;
		    nfound++;
		}
		else
		    nnull++;
	    }
	    else if (request->persistent_rhandle.rhandle.is_complete ||
		     MPID_RecvIcomplete( request, (MPI_Status *)0, 
					 &mpi_lerr )) {
		array_of_indices[nfound] = i;
		if (mpi_lerr) {
		    if (mpi_errno == MPI_SUCCESS) {
			if (array_of_statuses) {
			    for (j=0; j<incount; j++) 
				array_of_statuses[j].MPI_ERROR = MPI_SUCCESS;
			}
			mpi_errno = MPI_ERR_IN_STATUS;
		    }
		}
		if (array_of_statuses) 
		    array_of_statuses[nfound] = 
			request->persistent_rhandle.rhandle.s;
		request->persistent_rhandle.active = 0;
		nfound++;
	    }
	    break;
	}
    }
    if (nnull == incount)
	*outcount = MPI_UNDEFINED;
    else
	*outcount = nfound;
    if (mpi_errno) {
        revertSignal();
	return MPIR_ERROR(MPIR_COMM_WORLD, mpi_errno, myname );
	}
    TR_POP;
    revertSignal();
    return mpi_errno;
}
コード例 #6
0
ファイル: wsockshort.c プロジェクト: carsten-clauss/MP-MPICH
int MPID_CH_Eagerb_send_short( 
			      void *buf, 
			      int len, 
			      int src_lrank, 
			      int tag, 
			      int context_id, 
			      int dest,
			      MPID_Msgrep_t msgrep,
			      struct MPIR_DATATYPE* dtypeptr)
{
    int pkt_len;
    MPID_PKT_SHORT_T pkt;
    MPIR_SHANDLE  shandle;
    
    
    DEBUG_PRINT_MSG("S Starting Eagerb_send_short");
#ifdef WSOCK2
    if(dest==MPID_MyWorldRank) {
	DEBUG_INIT_STRUCT(&shandle,sizeof(shandle));
//	MPIR_SET_COOKIE((&shandle),MPIR_REQUEST_COOKIE);
//	MPID_Send_init( &shandle );
	shandle.finish=0;
	return MPID_SHMEM_Eagern_send_local(buf, len, src_lrank, tag, context_id, dest,
	msgrep, &shandle,MPID_BLOCKING,dtypeptr );
    } 
#endif
#ifdef MPID_PACK_CONTROL
    while (!MPID_PACKET_CHECK_OK(dest)) {  /* begin while !ok loop */
	/* Wait for a protocol ACK packet */
#ifdef MPID_DEBUG_ALL
	if (MPID_DebugFlag || MPID_DebugFlow) {
	    FPRINTF(MPID_DEBUG_FILE,
		"[%d] S Waiting for a protocol ACK packet (in eagerb_send_short) from %d\n",
		MPID_MyWorldRank, dest);
	}
#endif
	MPID_DeviceCheck( MPID_BLOCKING );
    }  /* end while !ok loop */
    
    MPID_PACKET_ADD_SENT(MPID_MyWorldRank, dest)
#endif
	
    /* These references are ordered to match the order they appear in the 
    structure */
    pkt_len        = sizeof(MPID_PKT_HEAD_T) + sizeof(MPID_Aint);
    pkt.mode	   = MPID_PKT_SHORT;
    pkt.context_id = context_id;
    pkt.lrank	   = src_lrank;
    pkt.tag		   = tag;
    pkt.len	       = len;
    MPID_DO_HETERO(pkt.msgrep = (int)msgrep);
    
    DEBUG_PRINT_SEND_PKT("S Sending",&pkt);
    MPID_PKT_PACK( &pkt, pkt_len, dest );
    
    if (len > 0) {
	MEMCPY( pkt.buffer, buf, len );
	DEBUG_PRINT_PKT_DATA("S Getting data from buf",&pkt);
    }
    /* Always use a blocking send for short messages.
    (May fail with systems that do not provide adequate
    buffering.  These systems should switch to non-blocking sends)
    */
    DEBUG_PRINT_SEND_PKT("S Sending message in a single packet",&pkt);
    
    /* In case the message is marked as non-blocking, indicate that we don't
    need to wait on it.  We may also want to use nonblocking operations
    to send the envelopes.... */
    MPID_DRAIN_INCOMING_FOR_TINY(1);
    MPID_SendControlBlock( (MPID_PKT_T*)&pkt, len + pkt_len, dest );
    DEBUG_PRINT_MSG("S Sent message in a single packet");
    
    return MPI_SUCCESS;
}
コード例 #7
0
ファイル: testall.c プロジェクト: carsten-clauss/MP-MPICH
/*@
    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) 

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

@*/
EXPORT_MPI_API 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";

    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)) {
		array_of_statuses[i].MPI_TAG = MPIR_MSG_CANCELLED; 
	        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) {
		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) {
	    MPIR_Set_Status_error_array( array_of_requests, count, i, 
					 mpi_errno, array_of_statuses );
	    mpi_errno = MPI_ERR_IN_STATUS;
	    TR_POP;
	    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 */
    if (nready == count) {
	for (i=0; i<count; i++) {
	    request = array_of_requests[i];
	    if (!request) {
		/* See MPI Standard, 3.7 */
		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;
		array_of_statuses[i].count	= 0;
		continue;
	    }
	    switch (request->handle_type) {
	    case MPIR_SEND:
		if (array_of_statuses[i].MPI_TAG != MPIR_MSG_CANCELLED) {
		    MPIR_FORGET_SEND( &request->shandle );
		    MPID_Send_free( array_of_requests[i] );
		    array_of_requests[i] = 0;
		}
		break;
	    case MPIR_RECV:
		if (array_of_statuses[i].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;
		}
 */
		array_of_statuses[i] = request->rhandle.s;
		MPID_Recv_free( array_of_requests[i] );
		array_of_requests[i] = 0;
		}
		break;
	    case MPIR_PERSISTENT_SEND:
		if (request->persistent_shandle.active) {
		    /* array_of_statuses[i] =
			request->persistent_shandle.shandle.s; */
		    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 (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;
		    array_of_statuses[i].count	    = 0;
		}
		break;
	    case MPIR_PERSISTENT_RECV:
		if (request->persistent_rhandle.active) {
		    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 (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;
		    array_of_statuses[i].count	    = 0;
		}
		break;
	    }
	    if (mpi_errno) {
		MPIR_Set_Status_error_array( array_of_requests, count, i, 
					     mpi_errno, array_of_statuses );
		mpi_errno = MPI_ERR_IN_STATUS;
		TR_POP;
		MPIR_RETURN(MPIR_COMM_WORLD, mpi_errno, myname );
	    }
	}
    }
    TR_POP;
    MPIR_RETURN(MPIR_COMM_WORLD, mpi_errno, myname );
}
コード例 #8
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;
}
コード例 #9
0
ファイル: adi2req.c プロジェクト: carsten-clauss/MP-MPICH
void MPID_Request_free (MPI_Request request )
{
    MPID_Device *dev = NULL;
    MPI_Request rq = request ; /* MPID_devset->req_pending; */
    int mpi_errno = MPI_SUCCESS;
    
    switch (rq->handle_type) {
    case MPIR_SEND:
	if (MPID_SendIcomplete( rq, &mpi_errno )) {
	    MPIR_FORGET_SEND( &rq->shandle );
	    MPID_Send_free( rq );
	    /* MPID_devset->req_pending = 0;*/
	    rq = 0;
	}
	break;
    case MPIR_RECV:
	if (MPID_RecvIcomplete( rq, (MPI_Status *)0, &mpi_errno )) {
	    MPID_Recv_free( rq );
	    /* MPID_devset->req_pending = 0; */
	    rq = 0;
	}
	break;
    case MPIR_PERSISTENT_SEND:
	if (rq->persistent_shandle.active) {
	    MPID_Abort( (struct MPIR_COMMUNICATOR *)0, 1, "MPI internal", 
			"Unimplemented operation - active persistent send free" );
	} else {
  	    dev = MPID_devset->dev[((rq->persistent_shandle.perm_comm)->lrank_to_grank)
				  [rq->persistent_shandle.perm_dest]];
	    if (dev->persistent_free != NULL)
	      MPID_Device_call_persistent_free (rq, dev);
	    
	    MPID_PSend_free( rq );
	}
	break;
    case MPIR_PERSISTENT_RECV:
	if (rq->persistent_rhandle.active) {
	    MPID_Abort( (struct MPIR_COMMUNICATOR *)0, 1, "MPI internal", 
			"Unimplemented operation - active persistent recv free" );
	} else {
	    if (rq->persistent_rhandle.perm_source >= 0) {
		dev = MPID_devset->dev[rq->persistent_rhandle.perm_source];
	    } else {
		/* For a single device, we can use the related function, 
		   but what to do for multiple available devices? Multiple
		   persistent initialization? */
		if (MPID_devset->ndev == 1) {
		    dev = MPID_devset->dev_list;
		}
	    }
	    
	    if (dev != NULL && dev->persistent_free != NULL)
	      MPID_Device_call_persistent_free (rq, dev);
	}
	break;
    }

    MPID_DeviceCheck( MPID_NOTBLOCKING );
    /* 
     * If we couldn't complete it, decrement it's reference count
     * and forget about it.  This requires that the device detect
     * orphaned requests when they do complete, and process them
     * independent of any wait/test.
     */
    /*if (MPID_devset->req_pending) {*/
    if (rq) {
	rq->chandle.ref_count--;
/*	PRINTF( "Setting ref count to %d for %x\n", 
		rq->chandle.ref_count, (long)rq ); */
	/* MPID_devset->req_pending = 0; */
    }
}