1 /*****************************************************************************
2 * Copyright (c) 2019 FrontISTR Commons
3 * This software is released under the MIT License, see LICENSE.txt
4 *****************************************************************************/
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <assert.h>
10 #include <errno.h>
11
12 #include "hecmw_config.h"
13 #include "hecmw_msgno.h"
14 #include "hecmw_malloc.h"
15 #include "hecmw_error.h"
16 #include "hecmw_comm.h"
17
18 #include "hecmw_couple_define.h"
19 #include "hecmw_couple_struct.h"
20 #include "hecmw_couple_info.h"
21 #include "hecmw_couple_comm.h"
22
HECMW_couple_inter_send_recv(int n_neighbor_pe_send,int * neighbor_pe_send,int * sendbuf_index,void * sendbuf,int n_neighbor_pe_recv,int * neighbor_pe_recv,int * recvbuf_index,void * recvbuf,HECMW_Datatype datatype,HECMW_Comm comm)23 extern int HECMW_couple_inter_send_recv(
24 int n_neighbor_pe_send, int *neighbor_pe_send, int *sendbuf_index,
25 void *sendbuf, int n_neighbor_pe_recv, int *neighbor_pe_recv,
26 int *recvbuf_index, void *recvbuf, HECMW_Datatype datatype,
27 HECMW_Comm comm) {
28 HECMW_Request *request_send = NULL, *request_recv = NULL;
29 HECMW_Status *status_send = NULL, *status_recv = NULL;
30 int rtc, i;
31
32 if (n_neighbor_pe_send > 0) {
33 request_send = (HECMW_Request *)HECMW_calloc(n_neighbor_pe_send,
34 sizeof(HECMW_Request));
35 if (request_send == NULL) {
36 HECMW_set_error(errno, "");
37 goto error;
38 }
39 status_send =
40 (HECMW_Status *)HECMW_calloc(n_neighbor_pe_send, sizeof(HECMW_Status));
41 if (status_send == NULL) {
42 HECMW_set_error(errno, "");
43 goto error;
44 }
45 }
46 if (n_neighbor_pe_recv > 0) {
47 request_recv = (HECMW_Request *)HECMW_calloc(n_neighbor_pe_recv,
48 sizeof(HECMW_Request));
49 if (request_recv == NULL) {
50 HECMW_set_error(errno, "");
51 goto error;
52 }
53 status_recv =
54 (HECMW_Status *)HECMW_calloc(n_neighbor_pe_recv, sizeof(HECMW_Status));
55 if (status_recv == NULL) {
56 HECMW_set_error(errno, "");
57 goto error;
58 }
59 }
60
61 if (datatype == HECMW_INT) {
62 int *_sendbuf = (int *)sendbuf;
63 int *_recvbuf = (int *)recvbuf;
64
65 /* send */
66 for (i = 0; i < n_neighbor_pe_send; i++) {
67 rtc = HECMW_Isend(&_sendbuf[sendbuf_index[i]],
68 sendbuf_index[i + 1] - sendbuf_index[i], HECMW_INT,
69 neighbor_pe_send[i], 0, comm, &request_send[i]);
70 if (rtc != 0) goto error;
71 }
72
73 /* receive */
74 for (i = 0; i < n_neighbor_pe_recv; i++) {
75 rtc = HECMW_Irecv(&_recvbuf[recvbuf_index[i]],
76 recvbuf_index[i + 1] - recvbuf_index[i], HECMW_INT,
77 neighbor_pe_recv[i], 0, comm, &request_recv[i]);
78 if (rtc != 0) goto error;
79 }
80 } else if (datatype == HECMW_DOUBLE) {
81 double *_sendbuf = (double *)sendbuf;
82 double *_recvbuf = (double *)recvbuf;
83
84 /* send */
85 for (i = 0; i < n_neighbor_pe_send; i++) {
86 rtc = HECMW_Isend(&_sendbuf[sendbuf_index[i]],
87 sendbuf_index[i + 1] - sendbuf_index[i], HECMW_DOUBLE,
88 neighbor_pe_send[i], 0, comm, &request_send[i]);
89 if (rtc != 0) goto error;
90 }
91
92 /* receive */
93 for (i = 0; i < n_neighbor_pe_recv; i++) {
94 rtc = HECMW_Irecv(&_recvbuf[recvbuf_index[i]],
95 recvbuf_index[i + 1] - recvbuf_index[i], HECMW_DOUBLE,
96 neighbor_pe_recv[i], 0, comm, &request_recv[i]);
97 if (rtc != 0) goto error;
98 }
99 } else if (datatype == HECMW_CHAR) {
100 char *_sendbuf = (char *)sendbuf;
101 char *_recvbuf = (char *)recvbuf;
102
103 /* send */
104 for (i = 0; i < n_neighbor_pe_send; i++) {
105 rtc = HECMW_Isend(&_sendbuf[sendbuf_index[i]],
106 sendbuf_index[i + 1] - sendbuf_index[i], HECMW_CHAR,
107 neighbor_pe_send[i], 0, comm, &request_send[i]);
108 if (rtc != 0) goto error;
109 }
110
111 /* receive */
112 for (i = 0; i < n_neighbor_pe_recv; i++) {
113 rtc = HECMW_Irecv(&_recvbuf[recvbuf_index[i]],
114 recvbuf_index[i + 1] - recvbuf_index[i], HECMW_CHAR,
115 neighbor_pe_recv[i], 0, comm, &request_recv[i]);
116 if (rtc != 0) goto error;
117 }
118 } else {
119 HECMW_set_error(HECMWCPL_E_MPI_DATATYPE, "");
120 goto error;
121 }
122
123 /* wait */
124 if (n_neighbor_pe_recv > 0) {
125 rtc = HECMW_Waitall(n_neighbor_pe_recv, request_recv, status_recv);
126 if (rtc != 0) goto error;
127 }
128
129 if (n_neighbor_pe_send > 0) {
130 rtc = HECMW_Waitall(n_neighbor_pe_send, request_send, status_send);
131 if (rtc != 0) goto error;
132 }
133
134 HECMW_free(request_send);
135 HECMW_free(request_recv);
136 HECMW_free(status_send);
137 HECMW_free(status_recv);
138
139 return 0;
140
141 error:
142 HECMW_free(request_send);
143 HECMW_free(request_recv);
144 HECMW_free(status_send);
145 HECMW_free(status_recv);
146
147 return -1;
148 }
149
HECMW_couple_intra_send_recv(int n_neighbor_pe,int * neighbor_pe,int * sendbuf_index,void * sendbuf,int * recvbuf_index,void * recvbuf,HECMW_Datatype datatype,HECMW_Comm comm)150 extern int HECMW_couple_intra_send_recv(int n_neighbor_pe, int *neighbor_pe,
151 int *sendbuf_index, void *sendbuf,
152 int *recvbuf_index, void *recvbuf,
153 HECMW_Datatype datatype,
154 HECMW_Comm comm) {
155 HECMW_Request *request_send = NULL, *request_recv = NULL;
156 HECMW_Status *status_send = NULL, *status_recv = NULL;
157 int rtc, i;
158
159 if (n_neighbor_pe > 0) {
160 request_send =
161 (HECMW_Request *)HECMW_calloc(n_neighbor_pe, sizeof(HECMW_Request));
162 if (request_send == NULL) {
163 HECMW_set_error(errno, "");
164 goto error;
165 }
166 status_send =
167 (HECMW_Status *)HECMW_calloc(n_neighbor_pe, sizeof(HECMW_Status));
168 if (status_send == NULL) {
169 HECMW_set_error(errno, "");
170 goto error;
171 }
172 request_recv =
173 (HECMW_Request *)HECMW_calloc(n_neighbor_pe, sizeof(HECMW_Request));
174 if (request_recv == NULL) {
175 HECMW_set_error(errno, "");
176 goto error;
177 }
178 status_recv =
179 (HECMW_Status *)HECMW_calloc(n_neighbor_pe, sizeof(HECMW_Status));
180 if (status_recv == NULL) {
181 HECMW_set_error(errno, "");
182 goto error;
183 }
184 }
185
186 if (datatype == HECMW_INT) {
187 int *_sendbuf = (int *)sendbuf;
188 int *_recvbuf = (int *)recvbuf;
189
190 /* send */
191 for (i = 0; i < n_neighbor_pe; i++) {
192 rtc = HECMW_Isend(&_sendbuf[sendbuf_index[i]],
193 sendbuf_index[i + 1] - sendbuf_index[i], datatype,
194 neighbor_pe[i], 0, comm, &request_send[i]);
195 if (rtc != 0) goto error;
196 }
197
198 /* receive */
199 for (i = 0; i < n_neighbor_pe; i++) {
200 rtc = HECMW_Irecv(&_recvbuf[recvbuf_index[i]],
201 recvbuf_index[i + 1] - recvbuf_index[i], datatype,
202 neighbor_pe[i], 0, comm, &request_recv[i]);
203 if (rtc != 0) goto error;
204 }
205 } else if (datatype == HECMW_DOUBLE) {
206 double *_sendbuf = (double *)sendbuf;
207 double *_recvbuf = (double *)recvbuf;
208
209 /* send */
210 for (i = 0; i < n_neighbor_pe; i++) {
211 rtc = HECMW_Isend(&_sendbuf[sendbuf_index[i]],
212 sendbuf_index[i + 1] - sendbuf_index[i], datatype,
213 neighbor_pe[i], 0, comm, &request_send[i]);
214 if (rtc != 0) goto error;
215 }
216
217 /* receive */
218 for (i = 0; i < n_neighbor_pe; i++) {
219 rtc = HECMW_Irecv(&_recvbuf[recvbuf_index[i]],
220 recvbuf_index[i + 1] - recvbuf_index[i], datatype,
221 neighbor_pe[i], 0, comm, &request_recv[i]);
222 if (rtc != 0) goto error;
223 }
224 } else if (datatype == HECMW_CHAR) {
225 char *_sendbuf = (char *)sendbuf;
226 char *_recvbuf = (char *)recvbuf;
227
228 /* send */
229 for (i = 0; i < n_neighbor_pe; i++) {
230 rtc = HECMW_Isend(&_sendbuf[sendbuf_index[i]],
231 sendbuf_index[i + 1] - sendbuf_index[i], datatype,
232 neighbor_pe[i], 0, comm, &request_send[i]);
233 if (rtc != 0) goto error;
234 }
235
236 /* receive */
237 for (i = 0; i < n_neighbor_pe; i++) {
238 rtc = HECMW_Irecv(&_recvbuf[recvbuf_index[i]],
239 recvbuf_index[i + 1] - recvbuf_index[i], datatype,
240 neighbor_pe[i], 0, comm, &request_recv[i]);
241 if (rtc != 0) goto error;
242 }
243 } else {
244 HECMW_set_error(HECMWCPL_E_MPI_DATATYPE, "");
245 goto error;
246 }
247
248 /* wait */
249 if (n_neighbor_pe > 0) {
250 rtc = HECMW_Waitall(n_neighbor_pe, request_recv, status_recv);
251 if (rtc != 0) goto error;
252 }
253
254 if (n_neighbor_pe > 0) {
255 rtc = HECMW_Waitall(n_neighbor_pe, request_send, status_send);
256 if (rtc != 0) goto error;
257 }
258
259 HECMW_free(request_send);
260 HECMW_free(request_recv);
261 HECMW_free(status_send);
262 HECMW_free(status_recv);
263
264 return 0;
265
266 error:
267 HECMW_free(request_send);
268 HECMW_free(request_recv);
269 HECMW_free(status_send);
270 HECMW_free(status_recv);
271
272 return -1;
273 }
274
HECMW_couple_bcast(int n_neighbor_pe_send,int * neighbor_pe_send,int sendbuf_size,void * sendbuf,int n_neighbor_pe_recv,int * neighbor_pe_recv,int * recvbuf_index,void * recvbuf,HECMW_Datatype datatype,HECMW_Comm comm)275 extern int HECMW_couple_bcast(int n_neighbor_pe_send, int *neighbor_pe_send,
276 int sendbuf_size, void *sendbuf,
277 int n_neighbor_pe_recv, int *neighbor_pe_recv,
278 int *recvbuf_index, void *recvbuf,
279 HECMW_Datatype datatype, HECMW_Comm comm) {
280 HECMW_Request *request_send = NULL, *request_recv = NULL;
281 HECMW_Status *status_send = NULL, *status_recv = NULL;
282 int rtc, i;
283
284 if (n_neighbor_pe_send > 0) {
285 request_send = (HECMW_Request *)HECMW_calloc(n_neighbor_pe_send,
286 sizeof(HECMW_Request));
287 if (request_send == NULL) {
288 HECMW_set_error(errno, "");
289 goto error;
290 }
291 status_send =
292 (HECMW_Status *)HECMW_calloc(n_neighbor_pe_send, sizeof(HECMW_Status));
293 if (status_send == NULL) {
294 HECMW_set_error(errno, "");
295 goto error;
296 }
297 }
298 if (n_neighbor_pe_recv > 0) {
299 request_recv = (HECMW_Request *)HECMW_calloc(n_neighbor_pe_recv,
300 sizeof(HECMW_Request));
301 if (request_recv == NULL) {
302 HECMW_set_error(errno, "");
303 goto error;
304 }
305 status_recv =
306 (HECMW_Status *)HECMW_calloc(n_neighbor_pe_recv, sizeof(HECMW_Status));
307 if (status_recv == NULL) {
308 HECMW_set_error(errno, "");
309 goto error;
310 }
311 }
312
313 if (datatype == HECMW_INT) {
314 int *_sendbuf = (int *)sendbuf;
315 int *_recvbuf = (int *)recvbuf;
316
317 /* send */
318 for (i = 0; i < n_neighbor_pe_send; i++) {
319 rtc = HECMW_Isend(&_sendbuf[0], sendbuf_size, datatype,
320 neighbor_pe_send[i], 0, comm, &request_send[i]);
321 if (rtc != 0) goto error;
322 }
323
324 /* receive */
325 for (i = 0; i < n_neighbor_pe_recv; i++) {
326 rtc = HECMW_Irecv(&_recvbuf[recvbuf_index[i]],
327 recvbuf_index[i + 1] - recvbuf_index[i], datatype,
328 neighbor_pe_recv[i], 0, comm, &request_recv[i]);
329 if (rtc != 0) goto error;
330 }
331 } else if (datatype == HECMW_DOUBLE) {
332 double *_sendbuf = (double *)sendbuf;
333 double *_recvbuf = (double *)recvbuf;
334
335 /* send */
336 for (i = 0; i < n_neighbor_pe_send; i++) {
337 rtc = HECMW_Isend(&_sendbuf[0], sendbuf_size, datatype,
338 neighbor_pe_send[i], 0, comm, &request_send[i]);
339 if (rtc != 0) goto error;
340 }
341
342 /* receive */
343 for (i = 0; i < n_neighbor_pe_recv; i++) {
344 rtc = HECMW_Irecv(&_recvbuf[recvbuf_index[i]],
345 recvbuf_index[i + 1] - recvbuf_index[i], datatype,
346 neighbor_pe_recv[i], 0, comm, &request_recv[i]);
347 if (rtc != 0) goto error;
348 }
349 } else if (datatype == HECMW_CHAR) {
350 char *_sendbuf = (char *)sendbuf;
351 char *_recvbuf = (char *)recvbuf;
352
353 /* send */
354 for (i = 0; i < n_neighbor_pe_send; i++) {
355 rtc = HECMW_Isend(&_sendbuf[0], sendbuf_size, datatype,
356 neighbor_pe_send[i], 0, comm, &request_send[i]);
357 if (rtc != 0) goto error;
358 }
359
360 /* receive */
361 for (i = 0; i < n_neighbor_pe_recv; i++) {
362 rtc = HECMW_Irecv(&_recvbuf[recvbuf_index[i]],
363 recvbuf_index[i + 1] - recvbuf_index[i], datatype,
364 neighbor_pe_recv[i], 0, comm, &request_recv[i]);
365 if (rtc != 0) goto error;
366 }
367 } else {
368 HECMW_set_error(HECMWCPL_E_MPI_DATATYPE, "");
369 goto error;
370 }
371
372 /* wait */
373 if (n_neighbor_pe_recv > 0) {
374 rtc = HECMW_Waitall(n_neighbor_pe_recv, request_recv, status_recv);
375 if (rtc != 0) goto error;
376 }
377 if (n_neighbor_pe_send > 0) {
378 rtc = HECMW_Waitall(n_neighbor_pe_send, request_send, status_send);
379 if (rtc != 0) goto error;
380 }
381
382 HECMW_free(request_send);
383 HECMW_free(request_recv);
384 HECMW_free(status_send);
385 HECMW_free(status_recv);
386
387 return 0;
388
389 error:
390 HECMW_free(request_send);
391 HECMW_free(request_recv);
392 HECMW_free(status_send);
393 HECMW_free(status_recv);
394 return -1;
395 }
396 #if 0
397 /*================================================================================================*/
398
399 static int
400 send_recv_r2r_int(const struct hecmw_couple_comm *comm_src,
401 const struct hecmw_couple_comm *comm_dst, int *buffer, int count)
402 {
403 int n_pe_send = 0, n_pe_recv = 0, *pe_send = NULL, *pe_recv = NULL;
404 int *sendbuf_index = NULL, *recvbuf_index = NULL, *sendbuf = NULL, *recvbuf = NULL;
405 int size, rtc, i;
406
407 if(comm_src->is_root) {
408 n_pe_send = 1;
409
410 pe_send = (int *)HECMW_malloc(sizeof(int)*n_pe_send);
411 if(pe_send == NULL) {
412 HECMW_set_error(errno, "");
413 goto error;
414 }
415 pe_send[0] = comm_dst->root;
416
417 sendbuf_index = (int *)HECMW_calloc(n_pe_send+1, sizeof(int));
418 if(sendbuf_index == NULL) {
419 HECMW_set_error(errno, "");
420 goto error;
421 }
422 sendbuf_index[1] = count;
423
424 sendbuf = (int *)HECMW_malloc(sizeof(int)*sendbuf_index[1]);
425 if(sendbuf == NULL) {
426 HECMW_set_error(errno, "");
427 goto error;
428 }
429 for(i=0; i<sendbuf_index[1]; i++) {
430 sendbuf[i] = buffer[i];
431 }
432 }
433
434 if(comm_dst->is_root) {
435 n_pe_recv = 1;
436
437 pe_recv = (int *)HECMW_malloc(sizeof(int)*n_pe_recv);
438 if(pe_recv == NULL) {
439 HECMW_set_error(errno, "");
440 goto error;
441 }
442 pe_recv[0] = comm_src->root;
443
444 recvbuf_index = (int *)HECMW_calloc(n_pe_recv+1, sizeof(int));
445 if(recvbuf_index == NULL) {
446 HECMW_set_error(errno, "");
447 goto error;
448 }
449 recvbuf_index[1] = count;
450
451 recvbuf = (int *)HECMW_malloc(sizeof(int)*recvbuf_index[1]);
452 if(recvbuf == NULL) {
453 HECMW_set_error(errno, "");
454 goto error;
455 }
456 }
457
458 rtc = HECMW_couple_inter_send_recv(n_pe_send, pe_send, sendbuf_index, sendbuf,
459 n_pe_recv, pe_recv, recvbuf_index, recvbuf, HECMW_INT, HECMW_comm_get_comm());
460 if(rtc) goto error;
461
462 if(comm_dst->is_root) {
463 memcpy(buffer, recvbuf, size);
464 }
465 return 0;
466 HECMW_free(pe_send);
467 HECMW_free(sendbuf_index);
468 HECMW_free(sendbuf);
469 HECMW_free(pe_recv);
470 HECMW_free(recvbuf_index);
471 HECMW_free(recvbuf);
472 return 0;
473
474 error:
475 HECMW_free(pe_send);
476 HECMW_free(sendbuf_index);
477 HECMW_free(sendbuf);
478 HECMW_free(pe_recv);
479 HECMW_free(recvbuf_index);
480 HECMW_free(recvbuf);
481 return -1;
482 }
483 #endif
484 #if 0
485
486 extern int
487 HECMW_couple_inter_bcast(char *boundary_id, void *sendbuf, int sendcount,
488 void **recvbuf, int recvcount, HECMW_Datatype datatype, int direction)
489 {
490 struct hecmw_couple_comm *comm_src = NULL, *comm_dst = NULL, *intercomm = NULL;
491 int rtc, i;
492
493 if((intercomm = HECMW_couple_get_intercomm(boundary_id)) == NULL) goto error;
494
495 if(direction == HECMW_COUPLE_UNIT1_TO_UNIT2) {
496 comm_src = HECMW_couple_get_intracomm(boundary_id, HECMW_COUPLE_UNIT1);
497 comm_dst = HECMW_couple_get_intracomm(boundary_id, HECMW_COUPLE_UNIT2);
498 } else if(direction == HECMW_COUPLE_UNIT2_TO_UNIT1) {
499 comm_src = HECMW_couple_get_intracomm(boundary_id, HECMW_COUPLE_UNIT2);
500 comm_dst = HECMW_couple_get_intracomm(boundary_id, HECMW_COUPLE_UNIT1);
501 } else {
502 HECMW_set_error(HECMWCPL_E_INVALID_DIRECTION, "");
503 goto error;
504 }
505 if(comm_src == NULL || comm_dst == NULL) goto error;
506
507 if(datatype == HECMW_INT) {
508 int n_src = 0, n_dst = 0, *src = NULL, *dst = NULL;
509 int *_sendbuf = (int *)sendbuf;
510 int *sendindex = NULL, *recvindex = NULL;
511 int _recvcount, *_recvbuf = NULL;
512
513 if(comm_src->is_root) {
514 n_dst = 1;
515
516 dst = (int *)HECMW_malloc(sizeof(int)*n_dst);
517 if(dst == NULL) {
518 HECMW_set_error(errno, "");
519 goto error;
520 }
521 dst[0] = comm_dst->root;
522
523 sendindex = (int *)HECMW_calloc(n_dst+1, sizeof(int));
524 if(sendindex == NULL) {
525 HECMW_set_error(errno, "");
526 goto error;
527 }
528 sendindex[0] = 0;
529 sendindex[1] = 1;
530
531 _sendbuf = (int *)HECMW_malloc(sizeof(int)*sendindex[n_dst]);
532 if(_sendbuf == NULL) {
533 HECMW_set_error(errno, "");
534 goto error;
535 }
536 _sendbuf[0] = sendcount;
537 }
538
539 if(comm_dst->is_root) {
540 n_src = 1;
541
542 src = (int *)HECMW_malloc(sizeof(int)*n_src);
543 if(src == NULL) {
544 HECMW_set_error(errno, "");
545 goto error;
546 }
547 src[0] = comm_src->root;
548
549 recvindex = (int *)HECMW_calloc(n_src+1, sizeof(int));
550 if(recvindex == NULL) {
551 HECMW_set_error(errno, "");
552 goto error;
553 }
554 recvindex[0] = 0;
555 recvindex[1] = 1;
556
557 _recvbuf = (int *)HECMW_malloc(sizeof(int)*recvindex[n_src]);
558 if(_recvbuf == NULL) {
559 HECMW_set_error(errno, "");
560 goto error;
561 }
562 }
563
564 rtc = HECMW_couple_inter_send_recv(n_dst, dst, sendindex, _sendbuf,
565 n_src, src, recvindex, _recvbuf, HECMW_INT, intercomm->comm);
566 if(rtc) goto error;
567
568 if(comm_dst->is_root) {
569 recvcount = _recvbuf[0];
570 }
571
572 HECMW_free(_sendbuf);
573 HECMW_free(sendindex);
574 HECMW_free(_recvbuf);
575 HECMW_free(recvindex);
576 _sendbuf = NULL;
577 sendindex = NULL;
578 _recvbuf = NULL;
579 recvindex = NULL;
580
581
582 if(comm_src->is_root) {
583 n_dst = 1;
584
585 dst = (int *)HECMW_malloc(sizeof(int)*n_dst);
586 if(dst == NULL) {
587 HECMW_set_error(errno, "");
588 goto error;
589 }
590 dst[0] = comm_dst->root;
591
592 sendindex = (int *)HECMW_calloc(n_dst+1, sizeof(int));
593 if(sendindex == NULL) {
594 HECMW_set_error(errno, "");
595 goto error;
596 }
597 sendindex[1] = sendcount;
598
599 _sendbuf = (int *)HECMW_malloc(sizeof(int)*sendindex[n_dst]+1);
600 if(_sendbuf == NULL) {
601 HECMW_set_error(errno, "");
602 goto error;
603 }
604 for(i=0; i<sendindex[n_dst]; i++) {
605 _sendbuf[i] = sendbuf[i];
606 }
607 }
608
609 if(comm_dst->is_root) {
610 n_src = 1;
611
612 src = (int *)HECMW_malloc(sizeof(int)*n_src);
613 if(src == NULL) {
614 HECMW_set_error(errno, "");
615 goto error;
616 }
617 src[0] = comm_src->root;
618
619 recvindex = (int *)HECMW_calloc(n_src+1, sizeof(int));
620 if(recvindex == NULL) {
621 HECMW_set_error(errno, "");
622 goto error;
623 }
624 recvindex[1] = recvcount;
625
626 _recvbuf = (int *)HECMW_malloc(sizeof(int)*recvindex[n_src]);
627 if(_recvbuf == NULL) {
628 HECMW_set_error(errno, "");
629 goto error;
630 }
631 }
632
633 rtc = HECMW_couple_inter_send_recv(n_dst, dst, sendindex, _sendbuf,
634 n_src, src, recvindex, _recvbuf, HECMW_INT, intercomm->comm);
635 if(rtc) goto error;
636
637 if(comm_dst->is_member) {
638 if(HECMW_Bcast(recvcount, 1, HECMW_INT, 0, comm_dst->comm)) goto error;
639
640 recvbuf = HECMW_malloc(sizeof(int)*recvcount);
641 if(recvbuf == NULL) {
642 HECMW_set_error(errno, "");
643 goto error;
644 }
645
646 if(comm_dst->is_root) {
647 for(i=0; i<recvcount; i++) {
648 recvbuf[i] = _recvbuf[i];
649 }
650 }
651 if(HECMW_Bcast(recvbuf, recvcount, HECMW_INT, 0, comm_dst->comm)) goto error;
652 }
653 }
654
655 return 0;
656
657 error:
658 HECMW_couple_free_comm(intercomm);
659 HECMW_couple_free_comm(comm_src);
660 HECMW_couple_free_comm(comm_dst);
661 return -1;
662 }
663
664
665
666 extern int
667 HECMW_couple_inter_barrier(const char *boundary_id)
668 {
669 struct hecmw_couple_comm *intercomm = NULL;
670 int rtc;
671
672 if((intercomm = HECMW_couple_get_intercomm(boundary_id)) == NULL) return -1;
673
674 rtc = HECMW_Barrier(intercomm->comm);
675 if(rtc != HECMW_SUCCESS) goto error;
676
677 HECMW_couple_free_comm(intercomm);
678
679 return 0;
680
681 error:
682 HECMW_couple_free_comm(intercomm);
683 return -1;
684 }
685 #endif
686