FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
hecmw_couple_comm.c
Go to the documentation of this file.
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 
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 if (datatype == HECMW_LONG_LONG) {
119  long long *_sendbuf = (long long *)sendbuf;
120  long long *_recvbuf = (long long *)recvbuf;
121 
122  /* send */
123  for (i = 0; i < n_neighbor_pe_send; i++) {
124  rtc = HECMW_Isend(&_sendbuf[sendbuf_index[i]],
125  sendbuf_index[i + 1] - sendbuf_index[i], HECMW_LONG_LONG,
126  neighbor_pe_send[i], 0, comm, &request_send[i]);
127  if (rtc != 0) goto error;
128  }
129 
130  /* receive */
131  for (i = 0; i < n_neighbor_pe_recv; i++) {
132  rtc = HECMW_Irecv(&_recvbuf[recvbuf_index[i]],
133  recvbuf_index[i + 1] - recvbuf_index[i], HECMW_LONG_LONG,
134  neighbor_pe_recv[i], 0, comm, &request_recv[i]);
135  if (rtc != 0) goto error;
136  }
137  } else {
139  goto error;
140  }
141 
142  /* wait */
143  if (n_neighbor_pe_recv > 0) {
144  rtc = HECMW_Waitall(n_neighbor_pe_recv, request_recv, status_recv);
145  if (rtc != 0) goto error;
146  }
147 
148  if (n_neighbor_pe_send > 0) {
149  rtc = HECMW_Waitall(n_neighbor_pe_send, request_send, status_send);
150  if (rtc != 0) goto error;
151  }
152 
153  HECMW_free(request_send);
154  HECMW_free(request_recv);
155  HECMW_free(status_send);
156  HECMW_free(status_recv);
157 
158  return 0;
159 
160 error:
161  HECMW_free(request_send);
162  HECMW_free(request_recv);
163  HECMW_free(status_send);
164  HECMW_free(status_recv);
165 
166  return -1;
167 }
168 
169 extern int HECMW_couple_intra_send_recv(int n_neighbor_pe, int *neighbor_pe,
170  int *sendbuf_index, void *sendbuf,
171  int *recvbuf_index, void *recvbuf,
172  HECMW_Datatype datatype,
173  HECMW_Comm comm) {
174  HECMW_Request *request_send = NULL, *request_recv = NULL;
175  HECMW_Status *status_send = NULL, *status_recv = NULL;
176  int rtc, i;
177 
178  if (n_neighbor_pe > 0) {
179  request_send =
180  (HECMW_Request *)HECMW_calloc(n_neighbor_pe, sizeof(HECMW_Request));
181  if (request_send == NULL) {
182  HECMW_set_error(errno, "");
183  goto error;
184  }
185  status_send =
186  (HECMW_Status *)HECMW_calloc(n_neighbor_pe, sizeof(HECMW_Status));
187  if (status_send == NULL) {
188  HECMW_set_error(errno, "");
189  goto error;
190  }
191  request_recv =
192  (HECMW_Request *)HECMW_calloc(n_neighbor_pe, sizeof(HECMW_Request));
193  if (request_recv == NULL) {
194  HECMW_set_error(errno, "");
195  goto error;
196  }
197  status_recv =
198  (HECMW_Status *)HECMW_calloc(n_neighbor_pe, sizeof(HECMW_Status));
199  if (status_recv == NULL) {
200  HECMW_set_error(errno, "");
201  goto error;
202  }
203  }
204 
205  if (datatype == HECMW_INT) {
206  int *_sendbuf = (int *)sendbuf;
207  int *_recvbuf = (int *)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_DOUBLE) {
225  double *_sendbuf = (double *)sendbuf;
226  double *_recvbuf = (double *)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 if (datatype == HECMW_CHAR) {
244  char *_sendbuf = (char *)sendbuf;
245  char *_recvbuf = (char *)recvbuf;
246 
247  /* send */
248  for (i = 0; i < n_neighbor_pe; i++) {
249  rtc = HECMW_Isend(&_sendbuf[sendbuf_index[i]],
250  sendbuf_index[i + 1] - sendbuf_index[i], datatype,
251  neighbor_pe[i], 0, comm, &request_send[i]);
252  if (rtc != 0) goto error;
253  }
254 
255  /* receive */
256  for (i = 0; i < n_neighbor_pe; i++) {
257  rtc = HECMW_Irecv(&_recvbuf[recvbuf_index[i]],
258  recvbuf_index[i + 1] - recvbuf_index[i], datatype,
259  neighbor_pe[i], 0, comm, &request_recv[i]);
260  if (rtc != 0) goto error;
261  }
262  } else if (datatype == HECMW_LONG_LONG) {
263  long long *_sendbuf = (long long *)sendbuf;
264  long long *_recvbuf = (long long *)recvbuf;
265 
266  /* send */
267  for (i = 0; i < n_neighbor_pe; i++) {
268  rtc = HECMW_Isend(&_sendbuf[sendbuf_index[i]],
269  sendbuf_index[i + 1] - sendbuf_index[i], datatype,
270  neighbor_pe[i], 0, comm, &request_send[i]);
271  if (rtc != 0) goto error;
272  }
273 
274  /* receive */
275  for (i = 0; i < n_neighbor_pe; i++) {
276  rtc = HECMW_Irecv(&_recvbuf[recvbuf_index[i]],
277  recvbuf_index[i + 1] - recvbuf_index[i], datatype,
278  neighbor_pe[i], 0, comm, &request_recv[i]);
279  if (rtc != 0) goto error;
280  }
281  } else {
283  goto error;
284  }
285 
286  /* wait */
287  if (n_neighbor_pe > 0) {
288  rtc = HECMW_Waitall(n_neighbor_pe, request_recv, status_recv);
289  if (rtc != 0) goto error;
290  }
291 
292  if (n_neighbor_pe > 0) {
293  rtc = HECMW_Waitall(n_neighbor_pe, request_send, status_send);
294  if (rtc != 0) goto error;
295  }
296 
297  HECMW_free(request_send);
298  HECMW_free(request_recv);
299  HECMW_free(status_send);
300  HECMW_free(status_recv);
301 
302  return 0;
303 
304 error:
305  HECMW_free(request_send);
306  HECMW_free(request_recv);
307  HECMW_free(status_send);
308  HECMW_free(status_recv);
309 
310  return -1;
311 }
312 
313 extern int HECMW_couple_bcast(int n_neighbor_pe_send, int *neighbor_pe_send,
314  int sendbuf_size, void *sendbuf,
315  int n_neighbor_pe_recv, int *neighbor_pe_recv,
316  int *recvbuf_index, void *recvbuf,
317  HECMW_Datatype datatype, HECMW_Comm comm) {
318  HECMW_Request *request_send = NULL, *request_recv = NULL;
319  HECMW_Status *status_send = NULL, *status_recv = NULL;
320  int rtc, i;
321 
322  if (n_neighbor_pe_send > 0) {
323  request_send = (HECMW_Request *)HECMW_calloc(n_neighbor_pe_send,
324  sizeof(HECMW_Request));
325  if (request_send == NULL) {
326  HECMW_set_error(errno, "");
327  goto error;
328  }
329  status_send =
330  (HECMW_Status *)HECMW_calloc(n_neighbor_pe_send, sizeof(HECMW_Status));
331  if (status_send == NULL) {
332  HECMW_set_error(errno, "");
333  goto error;
334  }
335  }
336  if (n_neighbor_pe_recv > 0) {
337  request_recv = (HECMW_Request *)HECMW_calloc(n_neighbor_pe_recv,
338  sizeof(HECMW_Request));
339  if (request_recv == NULL) {
340  HECMW_set_error(errno, "");
341  goto error;
342  }
343  status_recv =
344  (HECMW_Status *)HECMW_calloc(n_neighbor_pe_recv, sizeof(HECMW_Status));
345  if (status_recv == NULL) {
346  HECMW_set_error(errno, "");
347  goto error;
348  }
349  }
350 
351  if (datatype == HECMW_INT) {
352  int *_sendbuf = (int *)sendbuf;
353  int *_recvbuf = (int *)recvbuf;
354 
355  /* send */
356  for (i = 0; i < n_neighbor_pe_send; i++) {
357  rtc = HECMW_Isend(&_sendbuf[0], sendbuf_size, datatype,
358  neighbor_pe_send[i], 0, comm, &request_send[i]);
359  if (rtc != 0) goto error;
360  }
361 
362  /* receive */
363  for (i = 0; i < n_neighbor_pe_recv; i++) {
364  rtc = HECMW_Irecv(&_recvbuf[recvbuf_index[i]],
365  recvbuf_index[i + 1] - recvbuf_index[i], datatype,
366  neighbor_pe_recv[i], 0, comm, &request_recv[i]);
367  if (rtc != 0) goto error;
368  }
369  } else if (datatype == HECMW_DOUBLE) {
370  double *_sendbuf = (double *)sendbuf;
371  double *_recvbuf = (double *)recvbuf;
372 
373  /* send */
374  for (i = 0; i < n_neighbor_pe_send; i++) {
375  rtc = HECMW_Isend(&_sendbuf[0], sendbuf_size, datatype,
376  neighbor_pe_send[i], 0, comm, &request_send[i]);
377  if (rtc != 0) goto error;
378  }
379 
380  /* receive */
381  for (i = 0; i < n_neighbor_pe_recv; i++) {
382  rtc = HECMW_Irecv(&_recvbuf[recvbuf_index[i]],
383  recvbuf_index[i + 1] - recvbuf_index[i], datatype,
384  neighbor_pe_recv[i], 0, comm, &request_recv[i]);
385  if (rtc != 0) goto error;
386  }
387  } else if (datatype == HECMW_CHAR) {
388  char *_sendbuf = (char *)sendbuf;
389  char *_recvbuf = (char *)recvbuf;
390 
391  /* send */
392  for (i = 0; i < n_neighbor_pe_send; i++) {
393  rtc = HECMW_Isend(&_sendbuf[0], sendbuf_size, datatype,
394  neighbor_pe_send[i], 0, comm, &request_send[i]);
395  if (rtc != 0) goto error;
396  }
397 
398  /* receive */
399  for (i = 0; i < n_neighbor_pe_recv; i++) {
400  rtc = HECMW_Irecv(&_recvbuf[recvbuf_index[i]],
401  recvbuf_index[i + 1] - recvbuf_index[i], datatype,
402  neighbor_pe_recv[i], 0, comm, &request_recv[i]);
403  if (rtc != 0) goto error;
404  }
405  } else if (datatype == HECMW_LONG_LONG) {
406  long long *_sendbuf = (long long *)sendbuf;
407  long long *_recvbuf = (long long *)recvbuf;
408 
409  /* send */
410  for (i = 0; i < n_neighbor_pe_send; i++) {
411  rtc = HECMW_Isend(&_sendbuf[0], sendbuf_size, datatype,
412  neighbor_pe_send[i], 0, comm, &request_send[i]);
413  if (rtc != 0) goto error;
414  }
415 
416  /* receive */
417  for (i = 0; i < n_neighbor_pe_recv; i++) {
418  rtc = HECMW_Irecv(&_recvbuf[recvbuf_index[i]],
419  recvbuf_index[i + 1] - recvbuf_index[i], datatype,
420  neighbor_pe_recv[i], 0, comm, &request_recv[i]);
421  if (rtc != 0) goto error;
422  }
423  } else {
425  goto error;
426  }
427 
428  /* wait */
429  if (n_neighbor_pe_recv > 0) {
430  rtc = HECMW_Waitall(n_neighbor_pe_recv, request_recv, status_recv);
431  if (rtc != 0) goto error;
432  }
433  if (n_neighbor_pe_send > 0) {
434  rtc = HECMW_Waitall(n_neighbor_pe_send, request_send, status_send);
435  if (rtc != 0) goto error;
436  }
437 
438  HECMW_free(request_send);
439  HECMW_free(request_recv);
440  HECMW_free(status_send);
441  HECMW_free(status_recv);
442 
443  return 0;
444 
445 error:
446  HECMW_free(request_send);
447  HECMW_free(request_recv);
448  HECMW_free(status_send);
449  HECMW_free(status_recv);
450  return -1;
451 }
452 #if 0
453 /*================================================================================================*/
454 
455 static int
456 send_recv_r2r_int(const struct hecmw_couple_comm *comm_src,
457  const struct hecmw_couple_comm *comm_dst, int *buffer, int count)
458 {
459  int n_pe_send = 0, n_pe_recv = 0, *pe_send = NULL, *pe_recv = NULL;
460  int *sendbuf_index = NULL, *recvbuf_index = NULL, *sendbuf = NULL, *recvbuf = NULL;
461  int size, rtc, i;
462 
463  if(comm_src->is_root) {
464  n_pe_send = 1;
465 
466  pe_send = (int *)HECMW_malloc(sizeof(int)*n_pe_send);
467  if(pe_send == NULL) {
468  HECMW_set_error(errno, "");
469  goto error;
470  }
471  pe_send[0] = comm_dst->root;
472 
473  sendbuf_index = (int *)HECMW_calloc(n_pe_send+1, sizeof(int));
474  if(sendbuf_index == NULL) {
475  HECMW_set_error(errno, "");
476  goto error;
477  }
478  sendbuf_index[1] = count;
479 
480  sendbuf = (int *)HECMW_malloc(sizeof(int)*sendbuf_index[1]);
481  if(sendbuf == NULL) {
482  HECMW_set_error(errno, "");
483  goto error;
484  }
485  for(i=0; i<sendbuf_index[1]; i++) {
486  sendbuf[i] = buffer[i];
487  }
488  }
489 
490  if(comm_dst->is_root) {
491  n_pe_recv = 1;
492 
493  pe_recv = (int *)HECMW_malloc(sizeof(int)*n_pe_recv);
494  if(pe_recv == NULL) {
495  HECMW_set_error(errno, "");
496  goto error;
497  }
498  pe_recv[0] = comm_src->root;
499 
500  recvbuf_index = (int *)HECMW_calloc(n_pe_recv+1, sizeof(int));
501  if(recvbuf_index == NULL) {
502  HECMW_set_error(errno, "");
503  goto error;
504  }
505  recvbuf_index[1] = count;
506 
507  recvbuf = (int *)HECMW_malloc(sizeof(int)*recvbuf_index[1]);
508  if(recvbuf == NULL) {
509  HECMW_set_error(errno, "");
510  goto error;
511  }
512  }
513 
514  rtc = HECMW_couple_inter_send_recv(n_pe_send, pe_send, sendbuf_index, sendbuf,
515  n_pe_recv, pe_recv, recvbuf_index, recvbuf, HECMW_INT, HECMW_comm_get_comm());
516  if(rtc) goto error;
517 
518  if(comm_dst->is_root) {
519  memcpy(buffer, recvbuf, size);
520  }
521 return 0;
522  HECMW_free(pe_send);
523  HECMW_free(sendbuf_index);
524  HECMW_free(sendbuf);
525  HECMW_free(pe_recv);
526  HECMW_free(recvbuf_index);
527  HECMW_free(recvbuf);
528  return 0;
529 
530 error:
531  HECMW_free(pe_send);
532  HECMW_free(sendbuf_index);
533  HECMW_free(sendbuf);
534  HECMW_free(pe_recv);
535  HECMW_free(recvbuf_index);
536  HECMW_free(recvbuf);
537  return -1;
538 }
539 #endif
540 #if 0
541 
542 extern int
543 HECMW_couple_inter_bcast(char *boundary_id, void *sendbuf, int sendcount,
544  void **recvbuf, int recvcount, HECMW_Datatype datatype, int direction)
545 {
546  struct hecmw_couple_comm *comm_src = NULL, *comm_dst = NULL, *intercomm = NULL;
547  int rtc, i;
548 
549  if((intercomm = HECMW_couple_get_intercomm(boundary_id)) == NULL) goto error;
550 
551  if(direction == HECMW_COUPLE_UNIT1_TO_UNIT2) {
552  comm_src = HECMW_couple_get_intracomm(boundary_id, HECMW_COUPLE_UNIT1);
553  comm_dst = HECMW_couple_get_intracomm(boundary_id, HECMW_COUPLE_UNIT2);
554  } else if(direction == HECMW_COUPLE_UNIT2_TO_UNIT1) {
555  comm_src = HECMW_couple_get_intracomm(boundary_id, HECMW_COUPLE_UNIT2);
556  comm_dst = HECMW_couple_get_intracomm(boundary_id, HECMW_COUPLE_UNIT1);
557  } else {
559  goto error;
560  }
561  if(comm_src == NULL || comm_dst == NULL) goto error;
562 
563  if(datatype == HECMW_INT) {
564  int n_src = 0, n_dst = 0, *src = NULL, *dst = NULL;
565  int *_sendbuf = (int *)sendbuf;
566  int *sendindex = NULL, *recvindex = NULL;
567  int _recvcount, *_recvbuf = NULL;
568 
569  if(comm_src->is_root) {
570  n_dst = 1;
571 
572  dst = (int *)HECMW_malloc(sizeof(int)*n_dst);
573  if(dst == NULL) {
574  HECMW_set_error(errno, "");
575  goto error;
576  }
577  dst[0] = comm_dst->root;
578 
579  sendindex = (int *)HECMW_calloc(n_dst+1, sizeof(int));
580  if(sendindex == NULL) {
581  HECMW_set_error(errno, "");
582  goto error;
583  }
584  sendindex[0] = 0;
585  sendindex[1] = 1;
586 
587  _sendbuf = (int *)HECMW_malloc(sizeof(int)*sendindex[n_dst]);
588  if(_sendbuf == NULL) {
589  HECMW_set_error(errno, "");
590  goto error;
591  }
592  _sendbuf[0] = sendcount;
593  }
594 
595  if(comm_dst->is_root) {
596  n_src = 1;
597 
598  src = (int *)HECMW_malloc(sizeof(int)*n_src);
599  if(src == NULL) {
600  HECMW_set_error(errno, "");
601  goto error;
602  }
603  src[0] = comm_src->root;
604 
605  recvindex = (int *)HECMW_calloc(n_src+1, sizeof(int));
606  if(recvindex == NULL) {
607  HECMW_set_error(errno, "");
608  goto error;
609  }
610  recvindex[0] = 0;
611  recvindex[1] = 1;
612 
613  _recvbuf = (int *)HECMW_malloc(sizeof(int)*recvindex[n_src]);
614  if(_recvbuf == NULL) {
615  HECMW_set_error(errno, "");
616  goto error;
617  }
618  }
619 
620  rtc = HECMW_couple_inter_send_recv(n_dst, dst, sendindex, _sendbuf,
621  n_src, src, recvindex, _recvbuf, HECMW_INT, intercomm->comm);
622  if(rtc) goto error;
623 
624  if(comm_dst->is_root) {
625  recvcount = _recvbuf[0];
626  }
627 
628  HECMW_free(_sendbuf);
629  HECMW_free(sendindex);
630  HECMW_free(_recvbuf);
631  HECMW_free(recvindex);
632  _sendbuf = NULL;
633  sendindex = NULL;
634  _recvbuf = NULL;
635  recvindex = NULL;
636 
637 
638  if(comm_src->is_root) {
639  n_dst = 1;
640 
641  dst = (int *)HECMW_malloc(sizeof(int)*n_dst);
642  if(dst == NULL) {
643  HECMW_set_error(errno, "");
644  goto error;
645  }
646  dst[0] = comm_dst->root;
647 
648  sendindex = (int *)HECMW_calloc(n_dst+1, sizeof(int));
649  if(sendindex == NULL) {
650  HECMW_set_error(errno, "");
651  goto error;
652  }
653  sendindex[1] = sendcount;
654 
655  _sendbuf = (int *)HECMW_malloc(sizeof(int)*sendindex[n_dst]+1);
656  if(_sendbuf == NULL) {
657  HECMW_set_error(errno, "");
658  goto error;
659  }
660  for(i=0; i<sendindex[n_dst]; i++) {
661  _sendbuf[i] = sendbuf[i];
662  }
663  }
664 
665  if(comm_dst->is_root) {
666  n_src = 1;
667 
668  src = (int *)HECMW_malloc(sizeof(int)*n_src);
669  if(src == NULL) {
670  HECMW_set_error(errno, "");
671  goto error;
672  }
673  src[0] = comm_src->root;
674 
675  recvindex = (int *)HECMW_calloc(n_src+1, sizeof(int));
676  if(recvindex == NULL) {
677  HECMW_set_error(errno, "");
678  goto error;
679  }
680  recvindex[1] = recvcount;
681 
682  _recvbuf = (int *)HECMW_malloc(sizeof(int)*recvindex[n_src]);
683  if(_recvbuf == NULL) {
684  HECMW_set_error(errno, "");
685  goto error;
686  }
687  }
688 
689  rtc = HECMW_couple_inter_send_recv(n_dst, dst, sendindex, _sendbuf,
690  n_src, src, recvindex, _recvbuf, HECMW_INT, intercomm->comm);
691  if(rtc) goto error;
692 
693  if(comm_dst->is_member) {
694  if(HECMW_Bcast(recvcount, 1, HECMW_INT, 0, comm_dst->comm)) goto error;
695 
696  recvbuf = HECMW_malloc(sizeof(int)*recvcount);
697  if(recvbuf == NULL) {
698  HECMW_set_error(errno, "");
699  goto error;
700  }
701 
702  if(comm_dst->is_root) {
703  for(i=0; i<recvcount; i++) {
704  recvbuf[i] = _recvbuf[i];
705  }
706  }
707  if(HECMW_Bcast(recvbuf, recvcount, HECMW_INT, 0, comm_dst->comm)) goto error;
708  }
709  }
710 
711  return 0;
712 
713 error:
714  HECMW_couple_free_comm(intercomm);
715  HECMW_couple_free_comm(comm_src);
716  HECMW_couple_free_comm(comm_dst);
717  return -1;
718 }
719 
720 
721 
722 extern int
723 HECMW_couple_inter_barrier(const char *boundary_id)
724 {
725  struct hecmw_couple_comm *intercomm = NULL;
726  int rtc;
727 
728  if((intercomm = HECMW_couple_get_intercomm(boundary_id)) == NULL) return -1;
729 
730  rtc = HECMW_Barrier(intercomm->comm);
731  if(rtc != HECMW_SUCCESS) goto error;
732 
733  HECMW_couple_free_comm(intercomm);
734 
735  return 0;
736 
737 error:
738  HECMW_couple_free_comm(intercomm);
739  return -1;
740 }
741 #endif
int HECMW_Irecv(void *buffer, int count, HECMW_Datatype datatype, int source, int tag, HECMW_Comm comm, HECMW_Request *request)
Definition: hecmw_comm.c:353
int HECMW_Isend(void *buffer, int count, HECMW_Datatype datatype, int dest, int tag, HECMW_Comm comm, HECMW_Request *request)
Definition: hecmw_comm.c:302
int HECMW_Waitall(int count, HECMW_Request *array_of_requests, HECMW_Status *array_of_statuses)
Definition: hecmw_comm.c:132
HECMW_Comm HECMW_comm_get_comm(void)
Definition: hecmw_comm.c:751
int HECMW_Barrier(HECMW_Comm comm)
Definition: hecmw_comm.c:95
int HECMW_Bcast(void *buffer, int count, HECMW_Datatype datatype, int root, HECMW_Comm comm)
Definition: hecmw_comm.c:151
#define HECMW_INT
Definition: hecmw_config.h:48
MPI_Datatype HECMW_Datatype
Definition: hecmw_config.h:38
MPI_Status HECMW_Status
Definition: hecmw_config.h:36
#define HECMW_DOUBLE
Definition: hecmw_config.h:50
MPI_Comm HECMW_Comm
Definition: hecmw_config.h:30
MPI_Request HECMW_Request
Definition: hecmw_config.h:34
#define HECMW_LONG_LONG
Definition: hecmw_config.h:54
#define HECMW_SUCCESS
Definition: hecmw_config.h:66
#define HECMW_CHAR
Definition: hecmw_config.h:52
int 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)
int 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)
int 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)
int HECMW_couple_inter_barrier(const char *boundary_id)
int HECMW_couple_inter_bcast(const char *boundary_id, void *buffer, int count, HECMW_Datatype datatype, int direction)
#define HECMWCPL_E_MPI_DATATYPE
#define HECMW_COUPLE_UNIT1
#define HECMW_COUPLE_UNIT2_TO_UNIT1
#define HECMW_COUPLE_UNIT1_TO_UNIT2
#define HECMW_COUPLE_UNIT2
#define HECMWCPL_E_INVALID_DIRECTION
void HECMW_couple_free_comm(struct hecmw_couple_comm *comm)
struct hecmw_couple_comm * HECMW_couple_get_intracomm(const char *boundary_id, int unit_specifier)
struct hecmw_couple_comm * HECMW_couple_get_intercomm(const char *boundary_id)
int HECMW_set_error(int errorno, const char *fmt,...)
Definition: hecmw_error.c:37
#define NULL
#define HECMW_calloc(nmemb, size)
Definition: hecmw_malloc.h:21
#define HECMW_free(ptr)
Definition: hecmw_malloc.h:24
#define HECMW_malloc(size)
Definition: hecmw_malloc.h:20