1
1
openmpi/ompi/mca/pml/ob1/pml_ob1_iprobe.c
KAWASHIMA Takahiro 6510800c16 ompi/request: Fix a persistent request creation bug
According to the MPI-3.1 p.52 and p.53 (cited below), a request
created by `MPI_*_INIT` but not yet started by `MPI_START` or
`MPI_STARTALL` is inactive therefore `MPI_WAIT` or its friends
must return immediately if such a request is passed.

The current implementation hangs in `MPI_WAIT` and its friends
in such case because a persistent request is initialized as
`req_complete = REQUEST_PENDING`. This commit fixes the
initialization.

Also, this commit fixes internal requests used in `MPI_PROBE`
and `MPI_IPROBE` which was marked wrongly as persistent.

MPI-3.1 p.52:

We shall use the following terminology: A null handle is a handle
with value MPI_REQUEST_NULL. A persistent request and the handle
to it are inactive if the request is not associated with any ongoing
communication (see Section 3.9). A handle is active if it is neither
null nor inactive. An empty status is a status which is set to return
tag = MPI_ANY_TAG, source = MPI_ANY_SOURCE, error = MPI_SUCCESS, and
is also internally configured so that calls to MPI_GET_COUNT,
MPI_GET_ELEMENTS, and MPI_GET_ELEMENTS_X return count = 0 and
MPI_TEST_CANCELLED returns false. We set a status variable to empty
when the value returned by it is not significant. Status is set in
this way so as to prevent errors due to accesses of stale information.

MPI-3.1 p.53:

One is allowed to call MPI_WAIT with a null or inactive request
argument. In this case the operation returns immediately with empty
status.

Signed-off-by: KAWASHIMA Takahiro <t-kawashima@jp.fujitsu.com>
2016-12-08 21:42:05 +09:00

177 строки
5.9 KiB
C

/*
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2016 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2009-2012 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011-2012 Sandia National Laboratories. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "ompi_config.h"
#include "ompi/request/request.h"
#include "ompi/message/message.h"
#include "pml_ob1_recvreq.h"
int mca_pml_ob1_iprobe(int src,
int tag,
struct ompi_communicator_t *comm,
int *matched, ompi_status_public_t * status)
{
int rc = OMPI_SUCCESS;
mca_pml_ob1_recv_request_t recvreq;
OBJ_CONSTRUCT( &recvreq, mca_pml_ob1_recv_request_t );
recvreq.req_recv.req_base.req_ompi.req_type = OMPI_REQUEST_PML;
recvreq.req_recv.req_base.req_type = MCA_PML_REQUEST_IPROBE;
MCA_PML_OB1_RECV_REQUEST_INIT(&recvreq, NULL, 0, &ompi_mpi_char.dt, src, tag, comm, false);
MCA_PML_OB1_RECV_REQUEST_START(&recvreq);
if( REQUEST_COMPLETE( &(recvreq.req_recv.req_base.req_ompi)) ) {
if( NULL != status ) {
*status = recvreq.req_recv.req_base.req_ompi.req_status;
}
rc = recvreq.req_recv.req_base.req_ompi.req_status.MPI_ERROR;
*matched = 1;
} else {
*matched = 0;
opal_progress();
}
MCA_PML_BASE_RECV_REQUEST_FINI( &recvreq.req_recv );
return rc;
}
int mca_pml_ob1_probe(int src,
int tag,
struct ompi_communicator_t *comm,
ompi_status_public_t * status)
{
int rc = OMPI_SUCCESS;
mca_pml_ob1_recv_request_t recvreq;
OBJ_CONSTRUCT( &recvreq, mca_pml_ob1_recv_request_t );
recvreq.req_recv.req_base.req_ompi.req_type = OMPI_REQUEST_PML;
recvreq.req_recv.req_base.req_type = MCA_PML_REQUEST_PROBE;
MCA_PML_OB1_RECV_REQUEST_INIT(&recvreq, NULL, 0, &ompi_mpi_char.dt, src, tag, comm, false);
MCA_PML_OB1_RECV_REQUEST_START(&recvreq);
ompi_request_wait_completion(&recvreq.req_recv.req_base.req_ompi);
rc = recvreq.req_recv.req_base.req_ompi.req_status.MPI_ERROR;
if (NULL != status) {
*status = recvreq.req_recv.req_base.req_ompi.req_status;
}
MCA_PML_BASE_RECV_REQUEST_FINI( &recvreq.req_recv );
return rc;
}
int
mca_pml_ob1_improbe(int src,
int tag,
struct ompi_communicator_t *comm,
int *matched,
struct ompi_message_t **message,
ompi_status_public_t * status)
{
int rc = OMPI_SUCCESS;
mca_pml_ob1_recv_request_t *recvreq;
*message = ompi_message_alloc();
if (NULL == *message) return OMPI_ERR_TEMP_OUT_OF_RESOURCE;
MCA_PML_OB1_RECV_REQUEST_ALLOC(recvreq);
if (NULL == recvreq) {
ompi_message_return(*message);
return OMPI_ERR_TEMP_OUT_OF_RESOURCE;
}
recvreq->req_recv.req_base.req_type = MCA_PML_REQUEST_IMPROBE;
/* initialize the request enough to probe and get the status */
MCA_PML_OB1_RECV_REQUEST_INIT(recvreq, NULL, 0, &ompi_mpi_char.dt,
src, tag, comm, false);
MCA_PML_OB1_RECV_REQUEST_START(recvreq);
if( REQUEST_COMPLETE( &(recvreq->req_recv.req_base.req_ompi)) ) {
if( NULL != status ) {
*status = recvreq->req_recv.req_base.req_ompi.req_status;
}
*matched = 1;
(*message)->comm = comm;
(*message)->req_ptr = recvreq;
(*message)->peer = recvreq->req_recv.req_base.req_ompi.req_status.MPI_SOURCE;
(*message)->count = recvreq->req_recv.req_base.req_ompi.req_status._ucount;
rc = recvreq->req_recv.req_base.req_ompi.req_status.MPI_ERROR;
} else {
*matched = 0;
/* we only free if we didn't match, because we're going to
translate the request into a receive request later on if it
was matched */
MCA_PML_OB1_RECV_REQUEST_RETURN( recvreq );
ompi_message_return(*message);
*message = MPI_MESSAGE_NULL;
opal_progress();
}
return rc;
}
int
mca_pml_ob1_mprobe(int src,
int tag,
struct ompi_communicator_t *comm,
struct ompi_message_t **message,
ompi_status_public_t * status)
{
int rc = OMPI_SUCCESS;
mca_pml_ob1_recv_request_t *recvreq;
*message = ompi_message_alloc();
if (NULL == *message) return OMPI_ERR_TEMP_OUT_OF_RESOURCE;
MCA_PML_OB1_RECV_REQUEST_ALLOC(recvreq);
if (NULL == recvreq) {
ompi_message_return(*message);
return OMPI_ERR_TEMP_OUT_OF_RESOURCE;
}
recvreq->req_recv.req_base.req_type = MCA_PML_REQUEST_MPROBE;
/* initialize the request enough to probe and get the status */
MCA_PML_OB1_RECV_REQUEST_INIT(recvreq, NULL, 0, &ompi_mpi_char.dt,
src, tag, comm, false);
MCA_PML_OB1_RECV_REQUEST_START(recvreq);
ompi_request_wait_completion(&recvreq->req_recv.req_base.req_ompi);
rc = recvreq->req_recv.req_base.req_ompi.req_status.MPI_ERROR;
if( NULL != status ) {
*status = recvreq->req_recv.req_base.req_ompi.req_status;
}
(*message)->comm = comm;
(*message)->req_ptr = recvreq;
(*message)->peer = recvreq->req_recv.req_base.req_ompi.req_status.MPI_SOURCE;
(*message)->count = recvreq->req_recv.req_base.req_ompi.req_status._ucount;
return rc;
}