Skip to content

Commit 9fc7ee4

Browse files
authored
Merge pull request #12305 from wenduwan/gatherv_irecv
coll/basic: mca_coll_basic_gatherv_intra root posts irecv
2 parents 921e3db + 3aefc86 commit 9fc7ee4

File tree

1 file changed

+70
-43
lines changed

1 file changed

+70
-43
lines changed

ompi/mca/coll/basic/coll_basic_gatherv.c

Lines changed: 70 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -42,75 +42,102 @@ mca_coll_basic_gatherv_intra(const void *sbuf, int scount,
4242
void *rbuf, const int *rcounts, const int *disps,
4343
struct ompi_datatype_t *rdtype, int root,
4444
struct ompi_communicator_t *comm,
45-
mca_coll_base_module_t *module)
45+
mca_coll_base_module_t *module)
4646
{
47-
int i, rank, size, err;
47+
int err, i, peer, rank, size;
4848
char *ptmp;
4949
ptrdiff_t lb, extent;
5050
size_t rdsize;
5151

5252
size = ompi_comm_size(comm);
5353
rank = ompi_comm_rank(comm);
5454

55-
/* Everyone but root sends data and returns. Don't send anything
56-
for sendcounts of 0 (even though MPI_Gatherv has a guard for 0
57-
counts, this routine is used elsewhere, like the implementation
58-
of allgatherv, so it's possible to get here with a scount of
59-
0) */
55+
if (root == rank) {
56+
/* Root receives from everyone else */
57+
ompi_datatype_type_size(rdtype, &rdsize);
58+
if (OPAL_UNLIKELY(0 == rdsize)) {
59+
/* bozzo case */
60+
return MPI_SUCCESS;
61+
}
6062

61-
if (rank != root) {
62-
size_t sdsize;
63-
ompi_datatype_type_size(sdtype, &sdsize);
64-
if (scount > 0 && sdsize > 0) {
65-
return MCA_PML_CALL(send(sbuf, scount, sdtype, root,
66-
MCA_COLL_BASE_TAG_GATHERV,
67-
MCA_PML_BASE_SEND_STANDARD, comm));
63+
err = ompi_datatype_get_extent(rdtype, &lb, &extent);
64+
if (OMPI_SUCCESS != err) {
65+
return OMPI_ERROR;
6866
}
69-
return MPI_SUCCESS;
70-
}
7167

72-
/* I am the root, loop receiving data. */
68+
if (MPI_IN_PLACE != sbuf && (0 < scount) && (0 < rcounts[rank])) {
69+
/* Directly copy self sbuf to rbuf */
70+
err = ompi_datatype_sndrcv(sbuf, scount, sdtype,
71+
((char *) rbuf) + (extent * disps[rank]), rcounts[rank],
72+
rdtype);
73+
if (MPI_SUCCESS != err) {
74+
return err;
75+
}
76+
}
7377

74-
ompi_datatype_type_size(rdtype, &rdsize);
75-
if (OPAL_UNLIKELY(0 == rdsize)) {
76-
/* bozzo case */
77-
return MPI_SUCCESS;
78-
}
78+
ompi_request_t **reqs;
79+
size_t nrecv = 0, recv_iter = 0;
7980

80-
err = ompi_datatype_get_extent(rdtype, &lb, &extent);
81-
if (OMPI_SUCCESS != err) {
82-
return OMPI_ERROR;
83-
}
81+
for (i = 0; i < size; ++i) {
82+
/* We directly copied the data from self */
83+
if (0 < rcounts[i] && rank != i) {
84+
++nrecv;
85+
}
86+
}
8487

85-
for (i = 0; i < size; ++i) {
86-
ptmp = ((char *) rbuf) + (extent * disps[i]);
88+
if (0 == nrecv) {
89+
/* Nothing to receive */
90+
return MPI_SUCCESS;
91+
}
8792

88-
if (i == rank) {
89-
/* simple optimization */
90-
if (MPI_IN_PLACE != sbuf && (0 < scount) && (0 < rcounts[i])) {
91-
err = ompi_datatype_sndrcv(sbuf, scount, sdtype,
92-
ptmp, rcounts[i], rdtype);
93-
}
94-
} else {
93+
reqs = ompi_coll_base_comm_get_reqs(module->base_data, nrecv);
94+
95+
for (i = 1; i < size; ++i) {
96+
peer = (rank + i) % size;
97+
ptmp = ((char *) rbuf) + (extent * disps[peer]);
9598
/* Only receive if there is something to receive */
96-
if (rcounts[i] > 0) {
97-
err = MCA_PML_CALL(recv(ptmp, rcounts[i], rdtype, i,
98-
MCA_COLL_BASE_TAG_GATHERV,
99-
comm, MPI_STATUS_IGNORE));
99+
if (0 < rcounts[peer]) {
100+
err = MCA_PML_CALL(irecv(ptmp, rcounts[peer], rdtype, peer,
101+
MCA_COLL_BASE_TAG_GATHERV, comm, &reqs[recv_iter++]));
100102
}
101103
}
102104

103-
if (MPI_SUCCESS != err) {
104-
return err;
105+
assert(nrecv == recv_iter);
106+
107+
err = ompi_request_wait_all(nrecv, reqs, MPI_STATUSES_IGNORE);
108+
109+
if (MPI_ERR_IN_STATUS == err) {
110+
for (int i = 0; i < nrecv; i++) {
111+
if (MPI_REQUEST_NULL == reqs[i])
112+
continue;
113+
if (MPI_ERR_PENDING == reqs[i]->req_status.MPI_ERROR)
114+
continue;
115+
if (MPI_SUCCESS != reqs[i]->req_status.MPI_ERROR) {
116+
err = reqs[i]->req_status.MPI_ERROR;
117+
break;
118+
}
119+
}
105120
}
121+
122+
ompi_coll_base_free_reqs(reqs, nrecv);
123+
return err;
106124
}
107125

108-
/* All done */
126+
/* Everyone but root sends data and returns. Don't send anything
127+
for sendcounts of 0 (even though MPI_Gatherv has a guard for 0
128+
counts, this routine is used elsewhere, like the implementation
129+
of allgatherv, so it's possible to get here with a scount of
130+
0) */
109131

132+
size_t sdsize;
133+
ompi_datatype_type_size(sdtype, &sdsize);
134+
if (scount > 0 && sdsize > 0) {
135+
return MCA_PML_CALL(send(sbuf, scount, sdtype, root, MCA_COLL_BASE_TAG_GATHERV,
136+
MCA_PML_BASE_SEND_STANDARD, comm));
137+
}
110138
return MPI_SUCCESS;
111139
}
112140

113-
114141
/*
115142
* gatherv_inter
116143
*

0 commit comments

Comments
 (0)