Allow MPI_ANY_SOURCE in MPI_Sendrecv_replace.
Signed-off-by: George Bosilca <bosilca@icl.utk.edu>
Этот коммит содержится в:
родитель
d7ebcca93f
Коммит
86a7b317a5
@ -2,7 +2,7 @@
|
|||||||
* Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
|
* Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
|
||||||
* University Research and Technology
|
* University Research and Technology
|
||||||
* Corporation. All rights reserved.
|
* Corporation. All rights reserved.
|
||||||
* Copyright (c) 2004-2010 The University of Tennessee and The University
|
* Copyright (c) 2004-2017 The University of Tennessee and The University
|
||||||
* of Tennessee Research Foundation. All rights
|
* of Tennessee Research Foundation. All rights
|
||||||
* reserved.
|
* reserved.
|
||||||
* Copyright (c) 2004-2008 High Performance Computing Center Stuttgart,
|
* Copyright (c) 2004-2008 High Performance Computing Center Stuttgart,
|
||||||
@ -80,15 +80,24 @@ int MPI_Sendrecv_replace(void * buf, int count, MPI_Datatype datatype,
|
|||||||
|
|
||||||
OPAL_CR_EXIT_LIBRARY();
|
OPAL_CR_EXIT_LIBRARY();
|
||||||
return rc;
|
return rc;
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If we look for an optimal solution, then we should receive the data into a temporary buffer
|
||||||
|
* and once the send completes we would unpack back into the original buffer. However, if the
|
||||||
|
* sender is unknown, this approach can only be implementing by receiving with the recv datatype
|
||||||
|
* (potentially non-contiguous) and thus the allocated memory will be larger than the size of the
|
||||||
|
* datatype. A simpler, but potentially less efficient approach is to work on the data we have
|
||||||
|
* control of, aka the sent data, and pack it into a contiguous buffer before posting the receive.
|
||||||
|
* Once the send completes, we free it.
|
||||||
|
*/
|
||||||
opal_convertor_t convertor;
|
opal_convertor_t convertor;
|
||||||
struct iovec iov;
|
unsigned char packed_data[2048];
|
||||||
unsigned char recv_data[2048];
|
struct iovec iov = { .iov_base = packed_data, .iov_len = sizeof(packed_data) };
|
||||||
size_t packed_size, max_data;
|
size_t packed_size, max_data;
|
||||||
uint32_t iov_count;
|
uint32_t iov_count;
|
||||||
ompi_status_public_t recv_status;
|
ompi_status_public_t recv_status;
|
||||||
ompi_proc_t* proc = ompi_comm_peer_lookup(comm,source);
|
ompi_proc_t* proc = ompi_comm_peer_lookup(comm, dest);
|
||||||
if(proc == NULL) {
|
if(proc == NULL) {
|
||||||
rc = MPI_ERR_RANK;
|
rc = MPI_ERR_RANK;
|
||||||
OMPI_ERRHANDLER_RETURN(rc, comm, rc, FUNC_NAME);
|
OMPI_ERRHANDLER_RETURN(rc, comm, rc, FUNC_NAME);
|
||||||
@ -96,48 +105,38 @@ int MPI_Sendrecv_replace(void * buf, int count, MPI_Datatype datatype,
|
|||||||
|
|
||||||
/* initialize convertor to unpack recv buffer */
|
/* initialize convertor to unpack recv buffer */
|
||||||
OBJ_CONSTRUCT(&convertor, opal_convertor_t);
|
OBJ_CONSTRUCT(&convertor, opal_convertor_t);
|
||||||
opal_convertor_copy_and_prepare_for_recv( proc->super.proc_convertor, &(datatype->super),
|
opal_convertor_copy_and_prepare_for_send( proc->super.proc_convertor, &(datatype->super),
|
||||||
count, buf, 0, &convertor );
|
count, buf, 0, &convertor );
|
||||||
|
|
||||||
/* setup a buffer for recv */
|
/* setup a buffer for recv */
|
||||||
opal_convertor_get_packed_size( &convertor, &packed_size );
|
opal_convertor_get_packed_size( &convertor, &packed_size );
|
||||||
if( packed_size > sizeof(recv_data) ) {
|
if( packed_size > sizeof(packed_data) ) {
|
||||||
rc = PMPI_Alloc_mem(packed_size, MPI_INFO_NULL, &iov.iov_base);
|
rc = PMPI_Alloc_mem(packed_size, MPI_INFO_NULL, &iov.iov_base);
|
||||||
if(OMPI_SUCCESS != rc) {
|
if(OMPI_SUCCESS != rc) {
|
||||||
OMPI_ERRHANDLER_RETURN(OMPI_ERR_OUT_OF_RESOURCE, comm, MPI_ERR_BUFFER, FUNC_NAME);
|
rc = OMPI_ERR_OUT_OF_RESOURCE;
|
||||||
|
goto cleanup_and_return;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
iov.iov_base = (caddr_t)recv_data;
|
|
||||||
}
|
}
|
||||||
|
max_data = packed_size;
|
||||||
|
iov_count = 1;
|
||||||
|
rc = opal_convertor_pack(&convertor, &iov, &iov_count, &max_data);
|
||||||
|
|
||||||
/* recv into temporary buffer */
|
/* recv into temporary buffer */
|
||||||
rc = PMPI_Sendrecv( buf, count, datatype, dest, sendtag, iov.iov_base, packed_size,
|
rc = PMPI_Sendrecv( iov.iov_base, packed_size, MPI_PACKED, dest, sendtag, buf, count,
|
||||||
MPI_BYTE, source, recvtag, comm, &recv_status );
|
datatype, source, recvtag, comm, &recv_status );
|
||||||
if (rc != MPI_SUCCESS) {
|
|
||||||
if(packed_size > sizeof(recv_data))
|
|
||||||
PMPI_Free_mem(iov.iov_base);
|
|
||||||
OBJ_DESTRUCT(&convertor);
|
|
||||||
OMPI_ERRHANDLER_RETURN(rc, comm, rc, FUNC_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* unpack into users buffer */
|
|
||||||
iov.iov_len = recv_status._ucount;
|
|
||||||
iov_count = 1;
|
|
||||||
max_data = recv_status._ucount;
|
|
||||||
opal_convertor_unpack(&convertor, &iov, &iov_count, &max_data );
|
|
||||||
|
|
||||||
|
cleanup_and_return:
|
||||||
/* return status to user */
|
/* return status to user */
|
||||||
if(status != MPI_STATUS_IGNORE) {
|
if(status != MPI_STATUS_IGNORE) {
|
||||||
*status = recv_status;
|
*status = recv_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* release resources */
|
/* release resources */
|
||||||
if(packed_size > sizeof(recv_data)) {
|
if(packed_size > sizeof(packed_data)) {
|
||||||
PMPI_Free_mem(iov.iov_base);
|
PMPI_Free_mem(iov.iov_base);
|
||||||
}
|
}
|
||||||
OBJ_DESTRUCT(&convertor);
|
OBJ_DESTRUCT(&convertor);
|
||||||
|
|
||||||
OPAL_CR_EXIT_LIBRARY();
|
OPAL_CR_EXIT_LIBRARY();
|
||||||
return MPI_SUCCESS;
|
OMPI_ERRHANDLER_RETURN(rc, comm, rc, FUNC_NAME);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user