10
10
* Copyright (c) 2004-2005 The Regents of the University of California.
11
11
* All rights reserved.
12
12
* Copyright (c) 2010-2012 Oracle and/or its affiliates. All rights reserved.
13
- * Copyright (c) 2015 Research Organization for Information Science
14
- * and Technology (RIST). All rights reserved.
13
+ * Copyright (c) 2015-2021 Research Organization for Information Science
14
+ * and Technology (RIST). All rights reserved.
15
15
* Copyright (c) 2017 IBM Corporation. All rights reserved.
16
16
* $COPYRIGHT$
17
17
*
@@ -47,7 +47,11 @@ int MPI_Sendrecv_replace(void * buf, int count, MPI_Datatype datatype,
47
47
MPI_Comm comm , MPI_Status * status )
48
48
49
49
{
50
+ ompi_request_t * req ;
50
51
int rc = MPI_SUCCESS ;
52
+ #if OPAL_ENABLE_FT_MPI
53
+ int rcs = MPI_SUCCESS ;
54
+ #endif
51
55
52
56
SPC_RECORD (OMPI_SPC_SENDRECV_REPLACE , 1 );
53
57
@@ -104,7 +108,6 @@ int MPI_Sendrecv_replace(void * buf, int count, MPI_Datatype datatype,
104
108
struct iovec iov = { .iov_base = packed_data , .iov_len = sizeof (packed_data ) };
105
109
size_t packed_size , max_data ;
106
110
uint32_t iov_count ;
107
- ompi_status_public_t recv_status ;
108
111
ompi_proc_t * proc = ompi_comm_peer_lookup (comm , dest );
109
112
if (proc == NULL ) {
110
113
rc = MPI_ERR_RANK ;
@@ -116,7 +119,7 @@ int MPI_Sendrecv_replace(void * buf, int count, MPI_Datatype datatype,
116
119
opal_convertor_copy_and_prepare_for_send ( proc -> super .proc_convertor , & (datatype -> super ),
117
120
count , buf , 0 , & convertor );
118
121
119
- /* setup a buffer for recv */
122
+ /* setup a temporary buffer to send */
120
123
opal_convertor_get_packed_size ( & convertor , & packed_size );
121
124
if ( packed_size > sizeof (packed_data ) ) {
122
125
rc = PMPI_Alloc_mem (packed_size , MPI_INFO_NULL , & iov .iov_base );
@@ -130,15 +133,45 @@ int MPI_Sendrecv_replace(void * buf, int count, MPI_Datatype datatype,
130
133
iov_count = 1 ;
131
134
rc = opal_convertor_pack (& convertor , & iov , & iov_count , & max_data );
132
135
133
- /* recv into temporary buffer */
134
- rc = PMPI_Sendrecv ( iov .iov_base , packed_size , MPI_PACKED , dest , sendtag , buf , count ,
135
- datatype , source , recvtag , comm , & recv_status );
136
+ /* receive into the buffer */
137
+ rc = MCA_PML_CALL (irecv (buf , count , datatype ,
138
+ source , recvtag , comm , & req ));
139
+ if (OMPI_SUCCESS != rc ) {
140
+ goto cleanup_and_return ;
141
+ }
136
142
137
- cleanup_and_return :
138
- /* return status to user */
139
- if (status != MPI_STATUS_IGNORE ) {
140
- * status = recv_status ;
143
+ /* send from the temporary buffer */
144
+ rc = MCA_PML_CALL (send (iov .iov_base , packed_size , MPI_PACKED , dest ,
145
+ sendtag , MCA_PML_BASE_SEND_STANDARD , comm ));
146
+ #if OPAL_ENABLE_FT_MPI
147
+ /* If ULFM is enabled we need to wait for the posted receive to
148
+ * complete, hence we cannot return here */
149
+ rcs = rc ;
150
+ #else
151
+ if (OMPI_SUCCESS != rc ) {
152
+ goto cleanup_and_return ;
153
+ }
154
+ #endif /* OPAL_ENABLE_FT_MPI */
155
+
156
+ rc = ompi_request_wait (& req , status );
157
+ #if OPAL_ENABLE_FT_MPI
158
+ /* Sendrecv_replace never returns ERR_PROC_FAILED_PENDING because it is
159
+ * blocking. Lets complete now that irecv and promote the error
160
+ * to ERR_PROC_FAILED */
161
+ if ( OPAL_UNLIKELY (MPI_ERR_PROC_FAILED_PENDING == rc ) ) {
162
+ ompi_request_cancel (req );
163
+ ompi_request_wait (& req , MPI_STATUS_IGNORE );
164
+ rc = MPI_ERR_PROC_FAILED ;
141
165
}
166
+ #endif
167
+
168
+ #if OPAL_ENABLE_FT_MPI
169
+ if ( OPAL_UNLIKELY (MPI_SUCCESS != rcs && MPI_SUCCESS == rc ) ) {
170
+ rc = rcs ;
171
+ }
172
+ #endif
173
+
174
+ cleanup_and_return :
142
175
143
176
/* release resources */
144
177
if (packed_size > sizeof (packed_data )) {
0 commit comments