Add support for MPI_ERR_PENDING - Per MPI 2.2 p 60
Tested with: ompi-tests/mpich_tester/mpich_pt2pt/truncmult.c This commit was SVN r26172.
Этот коммит содержится в:
родитель
f7c66f54b6
Коммит
03a33417d5
@ -10,6 +10,7 @@
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2006-2008 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012 Oak Ridge National Labs. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
@ -141,10 +142,14 @@ int ompi_errhandler_request_invoke(int count,
|
||||
/* Since errors on requests cause them to not be freed (until we
|
||||
can examine them here), go through and free all requests with
|
||||
errors. We only invoke the exception on the *first* request
|
||||
that had an error. */
|
||||
that had an error.
|
||||
Make sure we do not free the reqeust if it is marked as pending
|
||||
since the user will need to wait on it again for completion.
|
||||
*/
|
||||
for (; i < count; ++i) {
|
||||
if (MPI_REQUEST_NULL != requests[i] &&
|
||||
MPI_SUCCESS != requests[i]->req_status.MPI_ERROR) {
|
||||
MPI_SUCCESS != requests[i]->req_status.MPI_ERROR &&
|
||||
MPI_ERR_PENDING != requests[i]->req_status.MPI_ERROR ) {
|
||||
/* Ignore the error -- what are we going to do? We're
|
||||
already going to invoke an exception */
|
||||
ompi_request_free(&(requests[i]));
|
||||
|
@ -11,6 +11,7 @@
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2006-2008 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012 Oak Ridge National Labs. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
@ -44,7 +45,15 @@ int ompi_request_default_test( ompi_request_t ** rptr,
|
||||
}
|
||||
return OMPI_SUCCESS;
|
||||
}
|
||||
|
||||
if (request->req_complete) {
|
||||
/*
|
||||
* Reset the error code of a previously pending request.
|
||||
*/
|
||||
if( MPI_ERR_PENDING == request->req_status.MPI_ERROR ) {
|
||||
request->req_status.MPI_ERROR = MPI_SUCCESS;
|
||||
}
|
||||
|
||||
OMPI_CRCP_REQUEST_COMPLETE(request);
|
||||
|
||||
*completed = true;
|
||||
@ -114,7 +123,15 @@ int ompi_request_default_test_any(
|
||||
num_requests_null_inactive++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( request->req_complete ) {
|
||||
/*
|
||||
* Reset the error code of a previously pending request.
|
||||
*/
|
||||
if( MPI_ERR_PENDING == request->req_status.MPI_ERROR ) {
|
||||
request->req_status.MPI_ERROR = MPI_SUCCESS;
|
||||
}
|
||||
|
||||
OMPI_CRCP_REQUEST_COMPLETE(request);
|
||||
|
||||
*index = i;
|
||||
@ -188,8 +205,16 @@ int ompi_request_default_test_all(
|
||||
rptr = requests;
|
||||
for (i = 0; i < count; i++, rptr++) {
|
||||
request = *rptr;
|
||||
|
||||
if( request->req_state == OMPI_REQUEST_INACTIVE ||
|
||||
request->req_complete) {
|
||||
/*
|
||||
* Reset the error code of a previously pending request.
|
||||
*/
|
||||
if( MPI_ERR_PENDING == request->req_status.MPI_ERROR ) {
|
||||
request->req_status.MPI_ERROR = MPI_SUCCESS;
|
||||
}
|
||||
|
||||
OMPI_CRCP_REQUEST_COMPLETE(request);
|
||||
num_completed++;
|
||||
}
|
||||
@ -295,6 +320,13 @@ int ompi_request_default_test_some(
|
||||
continue;
|
||||
}
|
||||
if (true == request->req_complete) {
|
||||
/*
|
||||
* Reset the error code of a previously pending request.
|
||||
*/
|
||||
if( MPI_ERR_PENDING == request->req_status.MPI_ERROR ) {
|
||||
request->req_status.MPI_ERROR = MPI_SUCCESS;
|
||||
}
|
||||
|
||||
OMPI_CRCP_REQUEST_COMPLETE(request);
|
||||
indices[num_requests_done++] = i;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2006-2008 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012 Oak Ridge National Labs. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
@ -35,6 +36,16 @@ int ompi_request_default_wait(
|
||||
{
|
||||
ompi_request_t *req = *req_ptr;
|
||||
|
||||
/*
|
||||
* Reset the error code of a previously pending request.
|
||||
*/
|
||||
if( MPI_ERR_PENDING == req->req_status.MPI_ERROR ) {
|
||||
req->req_status.MPI_ERROR = MPI_SUCCESS;
|
||||
if( MPI_STATUS_IGNORE != status ) {
|
||||
status->MPI_ERROR = MPI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
ompi_request_wait_completion(req);
|
||||
|
||||
#if OPAL_ENABLE_FT_CR == 1
|
||||
@ -145,6 +156,12 @@ int ompi_request_default_wait_any(
|
||||
continue;
|
||||
}
|
||||
if (request->req_complete == true) {
|
||||
/*
|
||||
* Reset the error code of a previously pending request.
|
||||
*/
|
||||
if( MPI_ERR_PENDING == request->req_status.MPI_ERROR ) {
|
||||
request->req_status.MPI_ERROR = MPI_SUCCESS;
|
||||
}
|
||||
completed = i;
|
||||
break;
|
||||
}
|
||||
@ -214,7 +231,7 @@ int ompi_request_default_wait_all( size_t count,
|
||||
ompi_request_t ** requests,
|
||||
ompi_status_public_t * statuses )
|
||||
{
|
||||
size_t completed = 0, i;
|
||||
size_t completed = 0, i, failed = 0;
|
||||
ompi_request_t **rptr;
|
||||
ompi_request_t *request;
|
||||
int mpi_error = OMPI_SUCCESS;
|
||||
@ -222,11 +239,25 @@ int ompi_request_default_wait_all( size_t count,
|
||||
rptr = requests;
|
||||
for (i = 0; i < count; i++) {
|
||||
request = *rptr++;
|
||||
|
||||
if (request->req_complete == true) {
|
||||
/*
|
||||
* Reset the error code of a previously pending request.
|
||||
*/
|
||||
if( MPI_ERR_PENDING == request->req_status.MPI_ERROR ) {
|
||||
request->req_status.MPI_ERROR = MPI_SUCCESS;
|
||||
}
|
||||
else if( MPI_SUCCESS != request->req_status.MPI_ERROR ) {
|
||||
failed++;
|
||||
}
|
||||
completed++;
|
||||
}
|
||||
}
|
||||
|
||||
if( failed > 0 ) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* if all requests have not completed -- defer acquiring lock
|
||||
* unless required
|
||||
*/
|
||||
@ -248,27 +279,50 @@ int ompi_request_default_wait_all( size_t count,
|
||||
for( completed = i = 0; i < count; i++ ) {
|
||||
request = *rptr++;
|
||||
if (request->req_complete == true) {
|
||||
if( MPI_SUCCESS != request->req_status.MPI_ERROR ) {
|
||||
failed++;
|
||||
}
|
||||
completed++;
|
||||
}
|
||||
}
|
||||
if( failed > 0 ) {
|
||||
ompi_request_waiting--;
|
||||
OPAL_THREAD_UNLOCK(&ompi_request_lock);
|
||||
goto finish;
|
||||
}
|
||||
#endif /* OPAL_ENABLE_MULTI_THREADS */
|
||||
while( completed != count ) {
|
||||
/* check number of pending requests */
|
||||
size_t start = ompi_request_completed;
|
||||
size_t pending = count - completed;
|
||||
size_t start_failed = ompi_request_failed;
|
||||
/*
|
||||
* wait until at least pending requests complete
|
||||
*/
|
||||
while (pending > ompi_request_completed - start) {
|
||||
opal_condition_wait(&ompi_request_cond, &ompi_request_lock);
|
||||
/*
|
||||
* Check for failed requests. If one request fails, then
|
||||
* this operation completes in error marking the remaining
|
||||
* requests as PENDING.
|
||||
*/
|
||||
if( 0 < (ompi_request_failed - start_failed) ) {
|
||||
failed += (ompi_request_failed - start_failed);
|
||||
ompi_request_waiting--;
|
||||
OPAL_THREAD_UNLOCK(&ompi_request_lock);
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* confirm that all pending operations have completed.
|
||||
*/
|
||||
rptr = requests;
|
||||
for( completed = i = 0; i < count; i++ ) {
|
||||
for( failed = completed = i = 0; i < count; i++ ) {
|
||||
request = *rptr++;
|
||||
if (request->req_complete == true) {
|
||||
if( MPI_SUCCESS != request->req_status.MPI_ERROR ) {
|
||||
failed++;
|
||||
}
|
||||
completed++;
|
||||
}
|
||||
}
|
||||
@ -289,12 +343,27 @@ int ompi_request_default_wait_all( size_t count,
|
||||
}
|
||||
#endif
|
||||
|
||||
finish:
|
||||
rptr = requests;
|
||||
if (MPI_STATUSES_IGNORE != statuses) {
|
||||
/* fill out status and free request if required */
|
||||
for( i = 0; i < count; i++, rptr++ ) {
|
||||
request = *rptr;
|
||||
assert( true == request->req_complete );
|
||||
|
||||
/*
|
||||
* Per MPI 2.2 p 60:
|
||||
* Allows requests to be marked as MPI_ERR_PENDING if they are
|
||||
* "neither failed nor completed." Which can only happen if
|
||||
* there was an error in one of the other requests.
|
||||
*/
|
||||
if( 0 < failed ) {
|
||||
if( !request->req_complete ) {
|
||||
request->req_status.MPI_ERROR = MPI_ERR_PENDING;
|
||||
}
|
||||
} else {
|
||||
assert( true == request->req_complete );
|
||||
}
|
||||
|
||||
if (OMPI_REQUEST_GEN == request->req_type) {
|
||||
ompi_grequest_invoke_query(request, &request->req_status);
|
||||
}
|
||||
@ -310,7 +379,7 @@ int ompi_request_default_wait_all( size_t count,
|
||||
assume that the request is still there.
|
||||
Otherwise, Bad Things will happen later! */
|
||||
int tmp = ompi_request_free(rptr);
|
||||
if (OMPI_SUCCESS != tmp) {
|
||||
if (OMPI_SUCCESS == mpi_error && OMPI_SUCCESS != tmp) {
|
||||
mpi_error = tmp;
|
||||
}
|
||||
}
|
||||
@ -325,7 +394,21 @@ int ompi_request_default_wait_all( size_t count,
|
||||
int rc;
|
||||
request = *rptr;
|
||||
|
||||
assert( true == request->req_complete );
|
||||
/*
|
||||
* Per MPI 2.2 p 60:
|
||||
* Some requests are allowed to be pending if there was an error.
|
||||
* However, without a status argument, it is difficult to tell
|
||||
* the user. For completeness mark the status appropriately,
|
||||
* even though it is not exposed to the user.
|
||||
*/
|
||||
if( 0 < failed ) {
|
||||
if( !request->req_complete ) {
|
||||
request->req_status.MPI_ERROR = MPI_ERR_PENDING;
|
||||
}
|
||||
} else {
|
||||
assert( true == request->req_complete );
|
||||
}
|
||||
|
||||
/* Per note above, we have to call gen request query_fn
|
||||
even if STATUSES_IGNORE was provided */
|
||||
if (OMPI_REQUEST_GEN == request->req_type) {
|
||||
@ -341,12 +424,19 @@ int ompi_request_default_wait_all( size_t count,
|
||||
} else if (MPI_SUCCESS == rc) {
|
||||
/* Only free the request if there is no error on it */
|
||||
int tmp = ompi_request_free(rptr);
|
||||
if (OMPI_SUCCESS != tmp) {
|
||||
if (OMPI_SUCCESS == mpi_error && OMPI_SUCCESS != tmp) {
|
||||
mpi_error = tmp;
|
||||
}
|
||||
}
|
||||
if( rc != OMPI_SUCCESS) {
|
||||
mpi_error = rc;
|
||||
/*
|
||||
* Per MPI 2.2 p34:
|
||||
* "It is possible for an MPI function to return MPI_ERR_IN_STATUS
|
||||
* even when MPI_STATUS_IGNORE or MPI_STATUSES_IGNORE has been
|
||||
* passed to that function."
|
||||
* So we should do so here as well.
|
||||
*/
|
||||
if( OMPI_SUCCESS == mpi_error && rc != OMPI_SUCCESS) {
|
||||
mpi_error = MPI_ERR_IN_STATUS;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -392,6 +482,13 @@ int ompi_request_default_wait_some(
|
||||
continue;
|
||||
}
|
||||
if (true == request->req_complete) {
|
||||
/*
|
||||
* Reset the error code of a previously pending request.
|
||||
*/
|
||||
if( MPI_ERR_PENDING == request->req_status.MPI_ERROR ) {
|
||||
request->req_status.MPI_ERROR = MPI_SUCCESS;
|
||||
}
|
||||
|
||||
indices[i] = 1;
|
||||
num_requests_done++;
|
||||
}
|
||||
@ -427,6 +524,13 @@ int ompi_request_default_wait_some(
|
||||
continue;
|
||||
}
|
||||
if (request->req_complete == true) {
|
||||
/*
|
||||
* Reset the error code of a previously pending request.
|
||||
*/
|
||||
if( MPI_ERR_PENDING == request->req_status.MPI_ERROR ) {
|
||||
request->req_status.MPI_ERROR = MPI_SUCCESS;
|
||||
}
|
||||
|
||||
indices[i] = 1;
|
||||
num_requests_done++;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2006 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012 Oak Ridge National Labs. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
@ -30,6 +31,7 @@
|
||||
opal_pointer_array_t ompi_request_f_to_c_table;
|
||||
size_t ompi_request_waiting = 0;
|
||||
size_t ompi_request_completed = 0;
|
||||
size_t ompi_request_failed = 0;
|
||||
opal_mutex_t ompi_request_lock;
|
||||
opal_condition_t ompi_request_cond;
|
||||
ompi_predefined_request_t ompi_request_null;
|
||||
|
@ -12,6 +12,7 @@
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2006 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2009-2010 Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012 Oak Ridge National Labs. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
@ -306,6 +307,7 @@ typedef struct ompi_request_fns_t {
|
||||
OMPI_DECLSPEC extern opal_pointer_array_t ompi_request_f_to_c_table;
|
||||
OMPI_DECLSPEC extern size_t ompi_request_waiting;
|
||||
OMPI_DECLSPEC extern size_t ompi_request_completed;
|
||||
OMPI_DECLSPEC extern size_t ompi_request_failed;
|
||||
OMPI_DECLSPEC extern int32_t ompi_request_poll;
|
||||
OMPI_DECLSPEC extern opal_mutex_t ompi_request_lock;
|
||||
OMPI_DECLSPEC extern opal_condition_t ompi_request_cond;
|
||||
@ -400,6 +402,9 @@ static inline int ompi_request_complete(ompi_request_t* request, bool with_signa
|
||||
}
|
||||
ompi_request_completed++;
|
||||
request->req_complete = true;
|
||||
if( MPI_SUCCESS != request->req_status.MPI_ERROR ) {
|
||||
ompi_request_failed++;
|
||||
}
|
||||
if(with_signal && ompi_request_waiting) {
|
||||
/* Broadcast the condition, otherwise if there is already a thread
|
||||
* waiting on another request it can use all signals.
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user