@@ -42,75 +42,102 @@ mca_coll_basic_gatherv_intra(const void *sbuf, int scount,
42
42
void * rbuf , const int * rcounts , const int * disps ,
43
43
struct ompi_datatype_t * rdtype , int root ,
44
44
struct ompi_communicator_t * comm ,
45
- mca_coll_base_module_t * module )
45
+ mca_coll_base_module_t * module )
46
46
{
47
- int i , rank , size , err ;
47
+ int err , i , peer , rank , size ;
48
48
char * ptmp ;
49
49
ptrdiff_t lb , extent ;
50
50
size_t rdsize ;
51
51
52
52
size = ompi_comm_size (comm );
53
53
rank = ompi_comm_rank (comm );
54
54
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
+ }
60
62
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 ;
68
66
}
69
- return MPI_SUCCESS ;
70
- }
71
67
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
+ }
73
77
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 ;
79
80
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
+ }
84
87
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
+ }
87
92
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 ]);
95
98
/* 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 ++ ]));
100
102
}
101
103
}
102
104
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
+ }
105
120
}
121
+
122
+ ompi_coll_base_free_reqs (reqs , nrecv );
123
+ return err ;
106
124
}
107
125
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) */
109
131
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
+ }
110
138
return MPI_SUCCESS ;
111
139
}
112
140
113
-
114
141
/*
115
142
* gatherv_inter
116
143
*
0 commit comments