This source file includes following definitions.
- mca_coll_basic_neighbor_alltoallv_cart
- mca_coll_basic_neighbor_alltoallv_graph
- mca_coll_basic_neighbor_alltoallv_dist_graph
- mca_coll_basic_neighbor_alltoallv
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_alltoallv_cart(const void *sbuf, const int scounts[], const int sdisps[],
41 struct ompi_datatype_t *sdtype, void *rbuf, const int rcounts[],
42 const int rdisps[], struct ompi_datatype_t *rdtype,
43 struct ompi_communicator_t *comm, mca_coll_base_module_t *module)
44 {
45 const mca_topo_base_comm_cart_2_2_0_t *cart = comm->c_topo->mtc.cart;
46 const int rank = ompi_comm_rank (comm);
47 int rc = MPI_SUCCESS, dim, i, nreqs;
48 ptrdiff_t lb, rdextent, sdextent;
49 ompi_request_t **reqs, **preqs;
50
51 if( 0 == cart->ndims ) return OMPI_SUCCESS;
52
53 ompi_datatype_get_extent(rdtype, &lb, &rdextent);
54 ompi_datatype_get_extent(sdtype, &lb, &sdextent);
55 reqs = preqs = ompi_coll_base_comm_get_reqs( module->base_data, 4 * cart->ndims );
56 if( NULL == reqs ) { return OMPI_ERR_OUT_OF_RESOURCE; }
57
58
59 for (dim = 0, nreqs = 0, i = 0; dim < cart->ndims ; ++dim, i += 2) {
60 int srank = MPI_PROC_NULL, drank = MPI_PROC_NULL;
61
62 if (cart->dims[dim] > 1) {
63 mca_topo_base_cart_shift (comm, dim, 1, &srank, &drank);
64 } else if (1 == cart->dims[dim] && cart->periods[dim]) {
65 srank = drank = rank;
66 }
67
68 if (MPI_PROC_NULL != srank) {
69 nreqs++;
70 rc = MCA_PML_CALL(irecv((char *) rbuf + rdisps[i] * rdextent, rcounts[i], rdtype, srank,
71 MCA_COLL_BASE_TAG_ALLTOALL, comm, preqs++));
72 if (OMPI_SUCCESS != rc) break;
73 }
74
75 if (MPI_PROC_NULL != drank) {
76 nreqs++;
77 rc = MCA_PML_CALL(irecv((char *) rbuf + rdisps[i+1] * rdextent, rcounts[i+1], rdtype, drank,
78 MCA_COLL_BASE_TAG_ALLTOALL, comm, preqs++));
79 if (OMPI_SUCCESS != rc) break;
80 }
81 }
82
83 if (OMPI_SUCCESS != rc) {
84 ompi_coll_base_free_reqs( reqs, nreqs );
85 return rc;
86 }
87
88 for (dim = 0, i = 0 ; dim < cart->ndims ; ++dim, i += 2) {
89 int srank = MPI_PROC_NULL, drank = MPI_PROC_NULL;
90
91 if (cart->dims[dim] > 1) {
92 mca_topo_base_cart_shift (comm, dim, 1, &srank, &drank);
93 } else if (1 == cart->dims[dim] && cart->periods[dim]) {
94 srank = drank = rank;
95 }
96
97 if (MPI_PROC_NULL != srank) {
98 nreqs++;
99
100 rc = MCA_PML_CALL(isend((char *) sbuf + sdisps[i] * sdextent, scounts[i], sdtype, srank,
101 MCA_COLL_BASE_TAG_ALLTOALL, MCA_PML_BASE_SEND_STANDARD, comm, preqs++));
102 if (OMPI_SUCCESS != rc) break;
103 }
104
105 if (MPI_PROC_NULL != drank) {
106 nreqs++;
107 rc = MCA_PML_CALL(isend((char *) sbuf + sdisps[i+1] * sdextent, scounts[i+1], sdtype, drank,
108 MCA_COLL_BASE_TAG_ALLTOALL, MCA_PML_BASE_SEND_STANDARD, comm, preqs++));
109 if (OMPI_SUCCESS != rc) break;
110 }
111 }
112
113 if (OMPI_SUCCESS != rc) {
114 ompi_coll_base_free_reqs( reqs, nreqs );
115 return rc;
116 }
117
118 rc = ompi_request_wait_all (nreqs, reqs, MPI_STATUSES_IGNORE);
119 if (OMPI_SUCCESS != rc) {
120 ompi_coll_base_free_reqs( reqs, nreqs );
121 }
122 return rc;
123 }
124
125 static int
126 mca_coll_basic_neighbor_alltoallv_graph(const void *sbuf, const int scounts[], const int sdisps[],
127 struct ompi_datatype_t *sdtype, void *rbuf, const int rcounts[],
128 const int rdisps[], struct ompi_datatype_t *rdtype,
129 struct ompi_communicator_t *comm, mca_coll_base_module_t *module)
130 {
131 const mca_topo_base_comm_graph_2_2_0_t *graph = comm->c_topo->mtc.graph;
132 int rc = MPI_SUCCESS, neighbor, degree;
133 const int rank = ompi_comm_rank (comm);
134 ptrdiff_t lb, rdextent, sdextent;
135 ompi_request_t **reqs, **preqs;
136 const int *edges;
137
138 mca_topo_base_graph_neighbors_count (comm, rank, °ree);
139 if( 0 == degree ) return OMPI_SUCCESS;
140
141 edges = graph->edges;
142 if (rank > 0) {
143 edges += graph->index[rank - 1];
144 }
145
146 ompi_datatype_get_extent(rdtype, &lb, &rdextent);
147 ompi_datatype_get_extent(sdtype, &lb, &sdextent);
148 reqs = preqs = ompi_coll_base_comm_get_reqs( module->base_data, 2 * degree );
149 if( NULL == reqs ) { return OMPI_ERR_OUT_OF_RESOURCE; }
150
151
152 for (neighbor = 0; neighbor < degree ; ++neighbor) {
153 rc = MCA_PML_CALL(irecv((char *) rbuf + rdisps[neighbor] * rdextent, rcounts[neighbor], rdtype,
154 edges[neighbor], MCA_COLL_BASE_TAG_ALLTOALL, comm, preqs++));
155 if (OMPI_SUCCESS != rc) break;
156 }
157
158 if (OMPI_SUCCESS != rc) {
159 ompi_coll_base_free_reqs( reqs, neighbor + 1);
160 return rc;
161 }
162
163 for (neighbor = 0 ; neighbor < degree ; ++neighbor) {
164
165 rc = MCA_PML_CALL(isend((char *) sbuf + sdisps[neighbor] * sdextent, scounts[neighbor], sdtype,
166 edges[neighbor], MCA_COLL_BASE_TAG_ALLTOALL, MCA_PML_BASE_SEND_STANDARD,
167 comm, preqs++));
168 if (OMPI_SUCCESS != rc) break;
169 }
170
171 if (OMPI_SUCCESS != rc) {
172 ompi_coll_base_free_reqs( reqs, degree + neighbor + 1);
173 return rc;
174 }
175
176 rc = ompi_request_wait_all (degree * 2, reqs, MPI_STATUSES_IGNORE);
177 if (OMPI_SUCCESS != rc) {
178 ompi_coll_base_free_reqs( reqs, degree * 2);
179 }
180 return rc;
181 }
182
183 static int
184 mca_coll_basic_neighbor_alltoallv_dist_graph(const void *sbuf, const int scounts[], const int sdisps[],
185 struct ompi_datatype_t *sdtype, void *rbuf, const int rcounts[],
186 const int rdisps[], struct ompi_datatype_t *rdtype,
187 struct ompi_communicator_t *comm, mca_coll_base_module_t *module)
188 {
189 const mca_topo_base_comm_dist_graph_2_2_0_t *dist_graph = comm->c_topo->mtc.dist_graph;
190 ptrdiff_t lb, rdextent, sdextent;
191 int rc = MPI_SUCCESS, neighbor;
192 const int *inedges, *outedges;
193 int indegree, outdegree;
194 ompi_request_t **reqs, **preqs;
195
196 indegree = dist_graph->indegree;
197 outdegree = dist_graph->outdegree;
198 if( 0 == (indegree + outdegree) ) return OMPI_SUCCESS;
199
200 inedges = dist_graph->in;
201 outedges = dist_graph->out;
202
203 ompi_datatype_get_extent(rdtype, &lb, &rdextent);
204 ompi_datatype_get_extent(sdtype, &lb, &sdextent);
205 reqs = preqs = ompi_coll_base_comm_get_reqs( module->base_data, indegree + outdegree);
206 if( NULL == reqs ) { return OMPI_ERR_OUT_OF_RESOURCE; }
207
208
209 for (neighbor = 0; neighbor < indegree ; ++neighbor) {
210 rc = MCA_PML_CALL(irecv((char *) rbuf + rdisps[neighbor] * rdextent, rcounts[neighbor], rdtype,
211 inedges[neighbor], MCA_COLL_BASE_TAG_ALLTOALL, comm, preqs++));
212 if (OMPI_SUCCESS != rc) break;
213 }
214
215 if (OMPI_SUCCESS != rc) {
216 ompi_coll_base_free_reqs(reqs, neighbor + 1);
217 return rc;
218 }
219
220 for (neighbor = 0 ; neighbor < outdegree ; ++neighbor) {
221
222 rc = MCA_PML_CALL(isend((char *) sbuf + sdisps[neighbor] * sdextent, scounts[neighbor], sdtype,
223 outedges[neighbor], MCA_COLL_BASE_TAG_ALLTOALL, MCA_PML_BASE_SEND_STANDARD,
224 comm, preqs++));
225 if (OMPI_SUCCESS != rc) break;
226 }
227
228 if (OMPI_SUCCESS != rc) {
229 ompi_coll_base_free_reqs(reqs, indegree + neighbor + 1);
230 return rc;
231 }
232
233 rc = ompi_request_wait_all (indegree + outdegree, reqs, MPI_STATUSES_IGNORE);
234 if (OMPI_SUCCESS != rc) {
235 ompi_coll_base_free_reqs( reqs, indegree + outdegree );
236 }
237 return rc;
238 }
239
240 int mca_coll_basic_neighbor_alltoallv(const void *sbuf, const int scounts[], const int sdisps[],
241 struct ompi_datatype_t *sdtype, void *rbuf, const int rcounts[],
242 const int rdisps[], struct ompi_datatype_t *rdtype,
243 struct ompi_communicator_t *comm, mca_coll_base_module_t *module)
244 {
245 if (OMPI_COMM_IS_INTER(comm)) {
246 return OMPI_ERR_NOT_SUPPORTED;
247 }
248
249 if (OMPI_COMM_IS_CART(comm)) {
250 return mca_coll_basic_neighbor_alltoallv_cart (sbuf, scounts, sdisps, sdtype, rbuf,
251 rcounts, rdisps, rdtype, comm, module);
252 } else if (OMPI_COMM_IS_GRAPH(comm)) {
253 return mca_coll_basic_neighbor_alltoallv_graph (sbuf, scounts, sdisps, sdtype, rbuf,
254 rcounts, rdisps, rdtype, comm, module);
255 } else if (OMPI_COMM_IS_DIST_GRAPH(comm)) {
256 return mca_coll_basic_neighbor_alltoallv_dist_graph (sbuf, scounts, sdisps, sdtype, rbuf,
257 rcounts, rdisps, rdtype, comm, module);
258 }
259
260 return OMPI_ERR_NOT_SUPPORTED;
261 }