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