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