This source file includes following definitions.
- nbc_alltoallw_init
- ompi_coll_libnbc_ialltoallw
- nbc_alltoallw_inter_init
- ompi_coll_libnbc_ialltoallw_inter
- a2aw_sched_linear
- a2aw_sched_pairwise
- a2aw_sched_inplace
- ompi_coll_libnbc_alltoallw_init
- ompi_coll_libnbc_alltoallw_inter_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include "nbc_internal.h"
22
23 static inline int a2aw_sched_linear(int rank, int p, NBC_Schedule *schedule,
24 const void *sendbuf, const int *sendcounts, const int *sdispls,
25 struct ompi_datatype_t * const * sendtypes,
26 void *recvbuf, const int *recvcounts, const int *rdispls,
27 struct ompi_datatype_t * const * recvtypes);
28
29 static inline int a2aw_sched_pairwise(int rank, int p, NBC_Schedule *schedule,
30 const void *sendbuf, const int *sendcounts, const int *sdispls,
31 struct ompi_datatype_t * const * sendtypes,
32 void *recvbuf, const int *recvcounts, const int *rdispls,
33 struct ompi_datatype_t * const * recvtypes);
34
35 static inline int a2aw_sched_inplace(int rank, int p, NBC_Schedule *schedule,
36 void *buf, const int *counts, const int *displs,
37 struct ompi_datatype_t * const * types);
38
39
40
41
42
43
44 static int nbc_alltoallw_init(const void* sendbuf, const int *sendcounts, const int *sdispls,
45 struct ompi_datatype_t * const *sendtypes, void* recvbuf, const int *recvcounts, const int *rdispls,
46 struct ompi_datatype_t * const *recvtypes, struct ompi_communicator_t *comm, ompi_request_t ** request,
47 struct mca_coll_base_module_2_3_0_t *module, bool persistent)
48 {
49 int rank, p, res;
50 NBC_Schedule *schedule;
51 char *rbuf, *sbuf, inplace;
52 ptrdiff_t span=0;
53 void *tmpbuf = NULL;
54 ompi_coll_libnbc_module_t *libnbc_module = (ompi_coll_libnbc_module_t*) module;
55
56 NBC_IN_PLACE(sendbuf, recvbuf, inplace);
57
58 rank = ompi_comm_rank (comm);
59 p = ompi_comm_size (comm);
60
61
62 if (inplace) {
63 ptrdiff_t lgap, lspan;
64 for (int i = 0; i < p; i++) {
65 lspan = opal_datatype_span(&recvtypes[i]->super, recvcounts[i], &lgap);
66 if (lspan > span) {
67 span = lspan;
68 }
69 }
70 if (OPAL_UNLIKELY(0 == span)) {
71 return nbc_get_noop_request(persistent, request);
72 }
73 tmpbuf = malloc(span);
74 if (OPAL_UNLIKELY(NULL == tmpbuf)) {
75 return OMPI_ERR_OUT_OF_RESOURCE;
76 }
77 sendcounts = recvcounts;
78 sdispls = rdispls;
79 sendtypes = recvtypes;
80 }
81
82 schedule = OBJ_NEW(NBC_Schedule);
83 if (OPAL_UNLIKELY(NULL == schedule)) {
84 free(tmpbuf);
85 return OMPI_ERR_OUT_OF_RESOURCE;
86 }
87
88 if (!inplace && sendcounts[rank] != 0) {
89 rbuf = (char *) recvbuf + rdispls[rank];
90 sbuf = (char *) sendbuf + sdispls[rank];
91 res = NBC_Sched_copy(sbuf, false, sendcounts[rank], sendtypes[rank],
92 rbuf, false, recvcounts[rank], recvtypes[rank], schedule, false);
93 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
94 return res;
95 }
96 }
97
98 if (inplace) {
99 res = a2aw_sched_inplace(rank, p, schedule, recvbuf,
100 recvcounts, rdispls, recvtypes);
101 } else {
102 res = a2aw_sched_linear(rank, p, schedule,
103 sendbuf, sendcounts, sdispls, sendtypes,
104 recvbuf, recvcounts, rdispls, recvtypes);
105 }
106 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
107 OBJ_RELEASE(schedule);
108 free(tmpbuf);
109 return res;
110 }
111
112 res = NBC_Sched_commit (schedule);
113 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
114 OBJ_RELEASE(schedule);
115 free(tmpbuf);
116 return res;
117 }
118
119 res = NBC_Schedule_request(schedule, comm, libnbc_module, persistent, request, tmpbuf);
120 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
121 OBJ_RELEASE(schedule);
122 free(tmpbuf);
123 return res;
124 }
125
126 return OMPI_SUCCESS;
127 }
128
129 int ompi_coll_libnbc_ialltoallw(const void* sendbuf, const int *sendcounts, const int *sdispls,
130 struct ompi_datatype_t * const *sendtypes, void* recvbuf, const int *recvcounts, const int *rdispls,
131 struct ompi_datatype_t * const *recvtypes, struct ompi_communicator_t *comm, ompi_request_t ** request,
132 struct mca_coll_base_module_2_3_0_t *module) {
133 int res = nbc_alltoallw_init(sendbuf, sendcounts, sdispls, sendtypes,
134 recvbuf, recvcounts, rdispls, recvtypes,
135 comm, request, module, false);
136 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
137 return res;
138 }
139
140 res = NBC_Start(*(ompi_coll_libnbc_request_t **)request);
141 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
142 NBC_Return_handle (*(ompi_coll_libnbc_request_t **)request);
143 *request = &ompi_request_null.request;
144 return res;
145 }
146
147 return OMPI_SUCCESS;
148 }
149
150
151 static int nbc_alltoallw_inter_init (const void* sendbuf, const int *sendcounts, const int *sdispls,
152 struct ompi_datatype_t * const *sendtypes, void* recvbuf, const int *recvcounts, const int *rdispls,
153 struct ompi_datatype_t * const *recvtypes, struct ompi_communicator_t *comm, ompi_request_t ** request,
154 struct mca_coll_base_module_2_3_0_t *module, bool persistent)
155 {
156 int res, rsize;
157 NBC_Schedule *schedule;
158 char *rbuf, *sbuf;
159 ompi_coll_libnbc_module_t *libnbc_module = (ompi_coll_libnbc_module_t*) module;
160
161 rsize = ompi_comm_remote_size (comm);
162
163 schedule = OBJ_NEW(NBC_Schedule);
164 if (OPAL_UNLIKELY(NULL == schedule)) {
165 return OMPI_ERR_OUT_OF_RESOURCE;
166 }
167
168 for (int i = 0 ; i < rsize ; ++i) {
169
170 if (sendcounts[i] != 0) {
171 sbuf = (char *) sendbuf + sdispls[i];
172 res = NBC_Sched_send (sbuf, false, sendcounts[i], sendtypes[i], i, schedule, false);
173 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
174 OBJ_RELEASE(schedule);
175 return res;
176 }
177 }
178
179 if (recvcounts[i] != 0) {
180 rbuf = (char *) recvbuf + rdispls[i];
181 res = NBC_Sched_recv (rbuf, false, recvcounts[i], recvtypes[i], i, schedule, false);
182 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
183 OBJ_RELEASE(schedule);
184 return res;
185 }
186 }
187 }
188
189 res = NBC_Sched_commit (schedule);
190 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
191 OBJ_RELEASE(schedule);
192 return res;
193 }
194
195 res = NBC_Schedule_request(schedule, comm, libnbc_module, persistent, request, NULL);
196 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
197 OBJ_RELEASE(schedule);
198 return res;
199 }
200
201 return OMPI_SUCCESS;
202 }
203
204 int ompi_coll_libnbc_ialltoallw_inter(const void* sendbuf, const int *sendcounts, const int *sdispls,
205 struct ompi_datatype_t * const *sendtypes, void* recvbuf, const int *recvcounts, const int *rdispls,
206 struct ompi_datatype_t * const *recvtypes, struct ompi_communicator_t *comm, ompi_request_t ** request,
207 struct mca_coll_base_module_2_3_0_t *module) {
208 int res = nbc_alltoallw_inter_init(sendbuf, sendcounts, sdispls, sendtypes,
209 recvbuf, recvcounts, rdispls, recvtypes,
210 comm, request, module, false);
211 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
212 return res;
213 }
214
215 res = NBC_Start(*(ompi_coll_libnbc_request_t **)request);
216 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
217 NBC_Return_handle (*(ompi_coll_libnbc_request_t **)request);
218 *request = &ompi_request_null.request;
219 return res;
220 }
221
222 return OMPI_SUCCESS;
223 }
224
225 static inline int a2aw_sched_linear(int rank, int p, NBC_Schedule *schedule,
226 const void *sendbuf, const int *sendcounts, const int *sdispls,
227 struct ompi_datatype_t * const * sendtypes,
228 void *recvbuf, const int *recvcounts, const int *rdispls,
229 struct ompi_datatype_t * const * recvtypes) {
230 int res;
231
232 for (int i = 0; i < p; i++) {
233 ptrdiff_t gap, span;
234 if (i == rank) {
235 continue;
236 }
237
238
239 span = opal_datatype_span(&sendtypes[i]->super, sendcounts[i], &gap);
240 if (OPAL_LIKELY(0 < span)) {
241 char *sbuf = (char *) sendbuf + sdispls[i];
242 res = NBC_Sched_send (sbuf, false, sendcounts[i], sendtypes[i], i, schedule, false);
243 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
244 return res;
245 }
246 }
247
248 span = opal_datatype_span(&recvtypes[i]->super, recvcounts[i], &gap);
249 if (OPAL_LIKELY(0 < span)) {
250 char *rbuf = (char *) recvbuf + rdispls[i];
251 res = NBC_Sched_recv (rbuf, false, recvcounts[i], recvtypes[i], i, schedule, false);
252 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
253 return res;
254 }
255 }
256 }
257
258 return OMPI_SUCCESS;
259 }
260
261 __opal_attribute_unused__
262 static inline int a2aw_sched_pairwise(int rank, int p, NBC_Schedule *schedule,
263 const void *sendbuf, const int *sendcounts, const int *sdispls,
264 struct ompi_datatype_t * const * sendtypes,
265 void *recvbuf, const int *recvcounts, const int *rdispls,
266 struct ompi_datatype_t * const * recvtypes) {
267 int res;
268
269 for (int i = 1; i < p; i++) {
270 int sndpeer = (rank + i) % p;
271 int rcvpeer = (rank + p - i) % p;
272
273
274 if (sendcounts[sndpeer] != 0) {
275 char *sbuf = (char *) sendbuf + sdispls[sndpeer];
276 res = NBC_Sched_send (sbuf, false, sendcounts[sndpeer], sendtypes[sndpeer], sndpeer, schedule, false);
277 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
278 return res;
279 }
280 }
281
282 if (recvcounts[rcvpeer] != 0) {
283 char *rbuf = (char *) recvbuf + rdispls[rcvpeer];
284 res = NBC_Sched_recv (rbuf, false, recvcounts[rcvpeer], recvtypes[rcvpeer], rcvpeer, schedule, true);
285 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
286 return res;
287 }
288 }
289 }
290
291 return OMPI_SUCCESS;
292 }
293
294 static inline int a2aw_sched_inplace(int rank, int p, NBC_Schedule *schedule,
295 void *buf, const int *counts, const int *displs,
296 struct ompi_datatype_t * const * types) {
297 ptrdiff_t gap = 0;
298 int res;
299
300 for (int i = 1; i < (p+1)/2; i++) {
301 int speer = (rank + i) % p;
302 int rpeer = (rank + p - i) % p;
303 char *sbuf = (char *) buf + displs[speer];
304 char *rbuf = (char *) buf + displs[rpeer];
305
306 if (0 != counts[rpeer]) {
307 (void)opal_datatype_span(&types[rpeer]->super, counts[rpeer], &gap);
308 res = NBC_Sched_copy (rbuf, false, counts[rpeer], types[rpeer],
309 (void *)(-gap), true, counts[rpeer], types[rpeer],
310 schedule, true);
311 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
312 return res;
313 }
314 }
315 if (0 != counts[speer]) {
316 res = NBC_Sched_send (sbuf, false , counts[speer], types[speer], speer, schedule, false);
317 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
318 return res;
319 }
320 }
321 if (0 != counts[rpeer]) {
322 res = NBC_Sched_recv (rbuf, false , counts[rpeer], types[rpeer], rpeer, schedule, true);
323 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
324 return res;
325 }
326 }
327
328 if (0 != counts[rpeer]) {
329 res = NBC_Sched_send ((void *)(-gap), true, counts[rpeer], types[rpeer], rpeer, schedule, false);
330 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
331 return res;
332 }
333 }
334 if (0 != counts[speer]) {
335 res = NBC_Sched_recv (sbuf, false, counts[speer], types[speer], speer, schedule, true);
336 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
337 return res;
338 }
339 }
340 }
341 if (0 == (p%2)) {
342 int peer = (rank + p/2) % p;
343
344 char *tbuf = (char *) buf + displs[peer];
345 (void)opal_datatype_span(&types[peer]->super, counts[peer], &gap);
346 res = NBC_Sched_copy (tbuf, false, counts[peer], types[peer],
347 (void *)(-gap), true, counts[peer], types[peer],
348 schedule, true);
349 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
350 return res;
351 }
352 res = NBC_Sched_send ((void *)(-gap), true , counts[peer], types[peer], peer, schedule, false);
353 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
354 return res;
355 }
356 res = NBC_Sched_recv (tbuf, false , counts[peer], types[peer], peer, schedule, true);
357 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
358 return res;
359 }
360 }
361
362 return OMPI_SUCCESS;
363 }
364
365 int ompi_coll_libnbc_alltoallw_init(const void* sendbuf, const int *sendcounts, const int *sdispls,
366 struct ompi_datatype_t * const *sendtypes, void* recvbuf, const int *recvcounts, const int *rdispls,
367 struct ompi_datatype_t * const *recvtypes, struct ompi_communicator_t *comm, MPI_Info info, ompi_request_t ** request,
368 struct mca_coll_base_module_2_3_0_t *module) {
369 int res = nbc_alltoallw_init(sendbuf, sendcounts, sdispls, sendtypes, recvbuf, recvcounts, rdispls, recvtypes,
370 comm, request, module, true);
371 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
372 return res;
373 }
374
375 return OMPI_SUCCESS;
376 }
377
378 int ompi_coll_libnbc_alltoallw_inter_init(const void* sendbuf, const int *sendcounts, const int *sdispls,
379 struct ompi_datatype_t * const *sendtypes, void* recvbuf, const int *recvcounts, const int *rdispls,
380 struct ompi_datatype_t * const *recvtypes, struct ompi_communicator_t *comm, MPI_Info info, ompi_request_t ** request,
381 struct mca_coll_base_module_2_3_0_t *module) {
382 int res = nbc_alltoallw_inter_init(sendbuf, sendcounts, sdispls, sendtypes, recvbuf, recvcounts, rdispls, recvtypes,
383 comm, request, module, true);
384 if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
385 return res;
386 }
387
388 return OMPI_SUCCESS;
389 }