This source file includes following definitions.
- mca_coll_basic_neighbor_alltoall_cart
- mca_coll_basic_neighbor_alltoall_graph
- mca_coll_basic_neighbor_alltoall_dist_graph
- mca_coll_basic_neighbor_alltoall
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 #include "ompi_config.h"
26 #include "coll_basic.h"
27
28 #include <stdlib.h>
29
30 #include "mpi.h"
31 #include "ompi/constants.h"
32 #include "ompi/datatype/ompi_datatype.h"
33 #include "ompi/mca/coll/coll.h"
34 #include "ompi/mca/pml/pml.h"
35 #include "ompi/mca/coll/base/coll_tags.h"
36 #include "coll_basic.h"
37 #include "ompi/mca/topo/base/base.h"
38
39 static int
40 mca_coll_basic_neighbor_alltoall_cart(const void *sbuf, int scount, struct ompi_datatype_t *sdtype, void *rbuf,
41 int rcount, struct ompi_datatype_t *rdtype, struct ompi_communicator_t *comm,
42 mca_coll_base_module_t *module)
43 {
44 const mca_topo_base_comm_cart_2_2_0_t *cart = comm->c_topo->mtc.cart;
45 const int rank = ompi_comm_rank (comm);
46 ompi_request_t **reqs, **preqs;
47 ptrdiff_t lb, rdextent, sdextent;
48 int rc = MPI_SUCCESS, dim, nreqs;
49
50 if( 0 == cart->ndims ) return OMPI_SUCCESS;
51
52 ompi_datatype_get_extent(rdtype, &lb, &rdextent);
53 ompi_datatype_get_extent(sdtype, &lb, &sdextent);
54 reqs = preqs = ompi_coll_base_comm_get_reqs( module->base_data, 4 * cart->ndims);
55 if( NULL == reqs ) { return OMPI_ERR_OUT_OF_RESOURCE; }
56
57
58 for (dim = 0, nreqs = 0; dim < cart->ndims ; ++dim) {
59 int srank = MPI_PROC_NULL, drank = MPI_PROC_NULL;
60
61 if (cart->dims[dim] > 1) {
62 mca_topo_base_cart_shift (comm, dim, 1, &srank, &drank);
63 } else if (1 == cart->dims[dim] && cart->periods[dim]) {
64 srank = drank = rank;
65 }
66
67 if (MPI_PROC_NULL != srank) {
68 nreqs++;
69 rc = MCA_PML_CALL(irecv(rbuf, rcount, rdtype, srank,
70 MCA_COLL_BASE_TAG_ALLTOALL,
71 comm, preqs++));
72 if (OMPI_SUCCESS != rc) break;
73 }
74
75 rbuf = (char *) rbuf + rdextent * rcount;
76
77 if (MPI_PROC_NULL != drank) {
78 nreqs++;
79 rc = MCA_PML_CALL(irecv(rbuf, rcount, rdtype, drank,
80 MCA_COLL_BASE_TAG_ALLTOALL,
81 comm, preqs++));
82 if (OMPI_SUCCESS != rc) break;
83 }
84
85 rbuf = (char *) rbuf + rdextent * rcount;
86 }
87
88 if (OMPI_SUCCESS != rc) {
89 ompi_coll_base_free_reqs( reqs, nreqs);
90 return rc;
91 }
92
93 for (dim = 0 ; dim < cart->ndims ; ++dim) {
94 int srank = MPI_PROC_NULL, drank = MPI_PROC_NULL;
95
96 if (cart->dims[dim] > 1) {
97 mca_topo_base_cart_shift (comm, dim, 1, &srank, &drank);
98 } else if (1 == cart->dims[dim] && cart->periods[dim]) {
99 srank = drank = rank;
100 }
101
102 if (MPI_PROC_NULL != srank) {
103
104
105 nreqs++;
106 rc = MCA_PML_CALL(isend((void *) sbuf, scount, sdtype, srank,
107 MCA_COLL_BASE_TAG_ALLTOALL,
108 MCA_PML_BASE_SEND_STANDARD,
109 comm, preqs++));
110 if (OMPI_SUCCESS != rc) break;
111 }
112
113 sbuf = (const char *) sbuf + sdextent * scount;
114
115 if (MPI_PROC_NULL != drank) {
116 nreqs++;
117 rc = MCA_PML_CALL(isend((void *) sbuf, scount, sdtype, drank,
118 MCA_COLL_BASE_TAG_ALLTOALL,
119 MCA_PML_BASE_SEND_STANDARD,
120 comm, preqs++));
121 if (OMPI_SUCCESS != rc) break;
122 }
123
124 sbuf = (const char *) sbuf + sdextent * scount;
125 }
126
127 if (OMPI_SUCCESS != rc) {
128 ompi_coll_base_free_reqs( reqs, nreqs);
129 return rc;
130 }
131
132 rc = ompi_request_wait_all (nreqs, reqs, MPI_STATUSES_IGNORE);
133 if (OMPI_SUCCESS != rc) {
134 ompi_coll_base_free_reqs( reqs, nreqs);
135 }
136 return rc;
137 }
138
139 static int
140 mca_coll_basic_neighbor_alltoall_graph(const void *sbuf, int scount, struct ompi_datatype_t *sdtype, void *rbuf,
141 int rcount, struct ompi_datatype_t *rdtype, struct ompi_communicator_t *comm,
142 mca_coll_base_module_t *module)
143 {
144 const mca_topo_base_comm_graph_2_2_0_t *graph = comm->c_topo->mtc.graph;
145 const int rank = ompi_comm_rank (comm);
146 int rc = MPI_SUCCESS, neighbor, degree;
147 ptrdiff_t lb, rdextent, sdextent;
148 ompi_request_t **reqs, **preqs;
149 const int *edges;
150
151 mca_topo_base_graph_neighbors_count (comm, rank, °ree);
152 if( 0 == degree ) return OMPI_SUCCESS;
153
154 edges = graph->edges;
155 if (rank > 0) {
156 edges += graph->index[rank - 1];
157 }
158
159 ompi_datatype_get_extent(rdtype, &lb, &rdextent);
160 ompi_datatype_get_extent(sdtype, &lb, &sdextent);
161 reqs = preqs = ompi_coll_base_comm_get_reqs( module->base_data, 2 * degree);
162 if( NULL == reqs ) { return OMPI_ERR_OUT_OF_RESOURCE; }
163
164
165 for (neighbor = 0; neighbor < degree ; ++neighbor) {
166 rc = MCA_PML_CALL(irecv(rbuf, rcount, rdtype, edges[neighbor], MCA_COLL_BASE_TAG_ALLTOALL,
167 comm, preqs++));
168 if (OMPI_SUCCESS != rc) break;
169 rbuf = (char *) rbuf + rdextent * rcount;
170 }
171 if( MPI_SUCCESS != rc ) {
172 ompi_coll_base_free_reqs( reqs, neighbor + 1 );
173 return rc;
174 }
175
176 for (neighbor = 0 ; neighbor < degree ; ++neighbor) {
177
178
179 rc = MCA_PML_CALL(isend((void *) sbuf, scount, sdtype, edges[neighbor],
180 MCA_COLL_BASE_TAG_ALLTOALL, MCA_PML_BASE_SEND_STANDARD,
181 comm, preqs++));
182 if (OMPI_SUCCESS != rc) break;
183 sbuf = (const char *) sbuf + sdextent * scount;
184 }
185
186 if( MPI_SUCCESS != rc ) {
187 ompi_coll_base_free_reqs( reqs, degree + neighbor + 1 );
188 return rc;
189 }
190
191 rc = ompi_request_wait_all (degree * 2, reqs, MPI_STATUSES_IGNORE);
192 if( MPI_SUCCESS != rc ) {
193 ompi_coll_base_free_reqs( reqs, 2 * degree );
194 }
195 return rc;
196 }
197
198 static int
199 mca_coll_basic_neighbor_alltoall_dist_graph(const void *sbuf, int scount,struct ompi_datatype_t *sdtype, void *rbuf,
200 int rcount, struct ompi_datatype_t *rdtype, struct ompi_communicator_t *comm,
201 mca_coll_base_module_t *module)
202 {
203 const mca_topo_base_comm_dist_graph_2_2_0_t *dist_graph = comm->c_topo->mtc.dist_graph;
204 ptrdiff_t lb, rdextent, sdextent;
205 int rc = MPI_SUCCESS, neighbor;
206 const int *inedges, *outedges;
207 int indegree, outdegree;
208 ompi_request_t **reqs, **preqs;
209
210 indegree = dist_graph->indegree;
211 outdegree = dist_graph->outdegree;
212 if( 0 == (indegree + outdegree) ) return OMPI_SUCCESS;
213
214 inedges = dist_graph->in;
215 outedges = dist_graph->out;
216
217 ompi_datatype_get_extent(rdtype, &lb, &rdextent);
218 ompi_datatype_get_extent(sdtype, &lb, &sdextent);
219 reqs = preqs = ompi_coll_base_comm_get_reqs( module->base_data, indegree + outdegree);
220 if( NULL == reqs ) { return OMPI_ERR_OUT_OF_RESOURCE; }
221
222
223 for (neighbor = 0; neighbor < indegree ; ++neighbor) {
224 rc = MCA_PML_CALL(irecv(rbuf, rcount, rdtype, inedges[neighbor],
225 MCA_COLL_BASE_TAG_ALLTOALL,
226 comm, preqs++));
227 if (OMPI_SUCCESS != rc) break;
228 rbuf = (char *) rbuf + rdextent * rcount;
229 }
230
231 if (OMPI_SUCCESS != rc) {
232 ompi_coll_base_free_reqs(reqs, neighbor + 1);
233 return rc;
234 }
235
236 for (neighbor = 0 ; neighbor < outdegree ; ++neighbor) {
237
238 rc = MCA_PML_CALL(isend((void *) sbuf, scount, sdtype, outedges[neighbor],
239 MCA_COLL_BASE_TAG_ALLTOALL, MCA_PML_BASE_SEND_STANDARD,
240 comm, preqs++));
241 if (OMPI_SUCCESS != rc) break;
242 sbuf = (char *) sbuf + sdextent * scount;
243 }
244
245 if (OMPI_SUCCESS != rc) {
246 ompi_coll_base_free_reqs(reqs, indegree + neighbor + 1);
247 return rc;
248 }
249
250 rc = ompi_request_wait_all (indegree + outdegree, reqs, MPI_STATUSES_IGNORE);
251 if (OMPI_SUCCESS != rc) {
252 ompi_coll_base_free_reqs(reqs, indegree + outdegree);
253 }
254 return rc;
255 }
256
257 int mca_coll_basic_neighbor_alltoall(const void *sbuf, int scount, struct ompi_datatype_t *sdtype, void *rbuf,
258 int rcount, struct ompi_datatype_t *rdtype, struct ompi_communicator_t *comm,
259 mca_coll_base_module_t *module)
260 {
261 if (OMPI_COMM_IS_INTER(comm)) {
262 return OMPI_ERR_NOT_SUPPORTED;
263 }
264
265 if (OMPI_COMM_IS_CART(comm)) {
266 return mca_coll_basic_neighbor_alltoall_cart (sbuf, scount, sdtype, rbuf,
267 rcount, rdtype, comm, module);
268 } else if (OMPI_COMM_IS_GRAPH(comm)) {
269 return mca_coll_basic_neighbor_alltoall_graph (sbuf, scount, sdtype, rbuf,
270 rcount, rdtype, comm, module);
271 } else if (OMPI_COMM_IS_DIST_GRAPH(comm)) {
272 return mca_coll_basic_neighbor_alltoall_dist_graph (sbuf, scount, sdtype, rbuf,
273 rcount, rdtype, comm, module);
274 }
275
276 return OMPI_ERR_NOT_SUPPORTED;
277 }