Ejemplo n.º 1
0
 bool _request_get_status(const MPI_Request& req, MPI_Status& status) {
     int flag;
     MPI_Request_get_status(req, &flag, &status);
     //Work around a bug prestn in Open MPI 1.3.3
     //and eailer.
     //MPI_Request_get_status may return false on
     //the first call even though a message
     //is waiting. The second call should work.
     if(!flag)
         MPI_Request_get_status(req, &flag, &status);
     return flag;
 }
Ejemplo n.º 2
0
int MPI_Recv_Nospin(void* buff, const int count, MPI_Datatype datatype,
                    const int from, const int tag, MPI_Comm comm,
                    MPI_Status* status)
{
    MPI_Request req;
    const int ret = MPI_Irecv(buff, count, datatype, from, tag, comm, &req);
    if (ret != MPI_SUCCESS)
        return ret;

    timespec ts{0, nsec_start};
    int flag = 0;
    while (!flag)
    {
        nanosleep(&ts, nullptr);
        ts.tv_nsec = std::min(size_t(ts.tv_nsec << 1), nsec_max);
        MPI_Request_get_status(req, &flag, status); // Always returns success
    }
    return MPI_Wait(&req, status); // release the request object
}
Ejemplo n.º 3
0
int MPI_Send_Nospin(void* buff, const int count, MPI_Datatype datatype,
                    const int dest, const int tag, MPI_Comm comm)
{
    MPI_Request req;
    const int ret = MPI_Isend(buff, count, datatype, dest, tag, comm, &req);
    if (ret != MPI_SUCCESS)
        return ret;

    timespec ts{0, nsec_start};
    int flag = 0;
    while (!flag)
    {
        nanosleep(&ts, nullptr);
        ts.tv_nsec = std::min(size_t(ts.tv_nsec << 1), nsec_max);
        // Always returns success. Status unused for single send operations.
        MPI_Request_get_status(req, &flag, MPI_STATUS_IGNORE);
    }
    return MPI_Wait(&req, MPI_STATUS_IGNORE); // release the request object
}
void mpi_request_get_status_f(MPI_Fint *request, ompi_fortran_logical_t *flag,
                              MPI_Fint *status, MPI_Fint *ierr)
{
    MPI_Status c_status;
    MPI_Request c_req = MPI_Request_f2c( *request ); 
    OMPI_LOGICAL_NAME_DECL(flag);

    /* This seems silly, but someone will do it */

    if (OMPI_IS_FORTRAN_STATUS_IGNORE(status)) {
        *flag = OMPI_INT_2_LOGICAL(0);
        *ierr = OMPI_INT_2_FINT(MPI_SUCCESS);
    } else {
        *ierr = OMPI_INT_2_FINT(MPI_Request_get_status(c_req, 
                                                       OMPI_LOGICAL_SINGLE_NAME_CONVERT(flag),
                                                       &c_status));
        OMPI_SINGLE_INT_2_LOGICAL(flag);
        MPI_Status_c2f( &c_status, status );
    }
}
Ejemplo n.º 5
0
/*
 *  Probe for and deal with incoming messages
 */
void CMPIManager::processQueue()
{
	MPI_Status pStatus;
	int		   iFlag = 0;
		
	bReceiving = false;
	
	if ( this->iNodeCount <= 1 )
		return;
		
	// Pending send operation has completed?
	if ( this->sendOps.size() > 0 )
	{
		for( int i = this->sendOps.size() - 1; i >= 0; i-- )
		{
			wrapError( MPI_Request_get_status(
					this->sendOps[i].pRequest,
					&iFlag,
					&pStatus
			) );
			
			if ( iFlag )
			{
			
				MPI_Test( &this->sendOps[i].pRequest, &iFlag, &pStatus );
				if ( iFlag )
				{
					delete [] this->sendOps[i].pData;
					this->sendOps.erase( this->sendOps.begin() + i );
				}
				
			} else {
				
				if ( this->sendOps[i].iTarget < this->iNodeID )
				{
					MPI_Wait(
						&this->sendOps[i].pRequest,
						&pStatus
					);
					delete [] this->sendOps[i].pData;
					this->sendOps.erase( this->sendOps.begin() + i );
				}
				
			}
		
		}
	}
	
	int iSize = 0;
	iFlag = 0;

	// Check for new messages
	wrapError( 
		MPI_Iprobe(
			MPI_ANY_SOURCE,
			MPI_ANY_TAG,
			MPI_COMM_WORLD,
			&iFlag,
			&pStatus
		)
	);

	if ( !iFlag )
	{
		return;
	}
	
	// A broadcast is likely to come in with a negative tag...
	if ( pStatus.MPI_TAG < 0 )
		return;
	
	// Some MPI implementations (incl. Microsoft) can supply the count
	// within the status struct...
	wrapError( MPI_Get_count( &pStatus, MPI_BYTE, &iSize ) );

	if ( iSize <= 0 )
		return;
		
	if ( iSize == MPI_UNDEFINED )
	{
		model::doError(
			"Got undefined size from an MPI receive...",
			model::errorCodes::kLevelWarning
		);
		return;
	}
		
	// Fetch...
	if ( this->pRecvBuffer == NULL || iSize > this->uiRecvBufferSize )
	{
		if ( this->pRecvBuffer != NULL )
			delete [] this->pRecvBuffer;
		this->pRecvBuffer = new char[ iSize ];
		this->uiRecvBufferSize = iSize;
	}

	bReceiving = true;
	
	wrapError( 
		MPI_Recv(
			this->pRecvBuffer,
			iSize,
			MPI_BYTE,
			pStatus.MPI_SOURCE,
			pStatus.MPI_TAG,
			MPI_COMM_WORLD,
			&pStatus
		)
	);
	
	this->processIncoming( pStatus.MPI_TAG );
	
	bReceiving = false;
}