OpenMPI  0.1.1
comm_inln.h
1 // -*- c++ -*-
2 //
3 // Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
4 // University Research and Technology
5 // Corporation. All rights reserved.
6 // Copyright (c) 2004-2005 The University of Tennessee and The University
7 // of Tennessee Research Foundation. All rights
8 // reserved.
9 // Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
10 // University of Stuttgart. All rights reserved.
11 // Copyright (c) 2004-2005 The Regents of the University of California.
12 // All rights reserved.
13 // Copyright (c) 2007-2012 Cisco Systems, Inc. All rights reserved.
14 // Copyright (c) 2011 FUJITSU LIMITED. All rights reserved.
15 // $COPYRIGHT$
16 //
17 // Additional copyrights may follow
18 //
19 // $HEADER$
20 //
21 
22 //
23 // Point-to-Point
24 //
25 
26 inline void
27 MPI::Comm::Send(const void *buf, int count,
28  const MPI::Datatype & datatype, int dest, int tag) const
29 {
30  (void)MPI_Send(const_cast<void *>(buf), count, datatype, dest, tag, mpi_comm);
31 }
32 
33 inline void
34 MPI::Comm::Recv(void *buf, int count, const MPI::Datatype & datatype,
35  int source, int tag, MPI::Status & status) const
36 {
37  (void)MPI_Recv(buf, count, datatype, source, tag, mpi_comm, &status.mpi_status);
38 }
39 
40 inline void
41 MPI::Comm::Recv(void *buf, int count, const MPI::Datatype & datatype,
42  int source, int tag) const
43 {
44  (void)MPI_Recv(buf, count, datatype, source,
45  tag, mpi_comm, MPI_STATUS_IGNORE);
46 }
47 
48 inline void
49 MPI::Comm::Bsend(const void *buf, int count,
50  const MPI::Datatype & datatype, int dest, int tag) const
51 {
52  (void)MPI_Bsend(const_cast<void *>(buf), count, datatype,
53  dest, tag, mpi_comm);
54 }
55 
56 inline void
57 MPI::Comm::Ssend(const void *buf, int count,
58  const MPI::Datatype & datatype, int dest, int tag) const
59 {
60  (void)MPI_Ssend(const_cast<void *>(buf), count, datatype, dest,
61  tag, mpi_comm);
62 }
63 
64 inline void
65 MPI::Comm::Rsend(const void *buf, int count,
66  const MPI::Datatype & datatype, int dest, int tag) const
67 {
68  (void)MPI_Rsend(const_cast<void *>(buf), count, datatype,
69  dest, tag, mpi_comm);
70 }
71 
72 inline MPI::Request
73 MPI::Comm::Isend(const void *buf, int count,
74  const MPI::Datatype & datatype, int dest, int tag) const
75 {
77  (void)MPI_Isend(const_cast<void *>(buf), count, datatype,
78  dest, tag, mpi_comm, &request);
79  return request;
80 }
81 
82 inline MPI::Request
83 MPI::Comm::Ibsend(const void *buf, int count,
84  const MPI::Datatype & datatype, int dest, int tag) const
85 {
86  MPI_Request request;
87  (void)MPI_Ibsend(const_cast<void *>(buf), count, datatype,
88  dest, tag, mpi_comm, &request);
89  return request;
90 }
91 
92 inline MPI::Request
93 MPI::Comm::Issend(const void *buf, int count,
94  const MPI::Datatype & datatype, int dest, int tag) const
95 {
96  MPI_Request request;
97  (void)MPI_Issend(const_cast<void *>(buf), count, datatype,
98  dest, tag, mpi_comm, &request);
99  return request;
100 }
101 
102 inline MPI::Request
103 MPI::Comm::Irsend(const void *buf, int count,
104  const MPI::Datatype & datatype, int dest, int tag) const
105 {
106  MPI_Request request;
107  (void)MPI_Irsend(const_cast<void *>(buf), count, datatype,
108  dest, tag, mpi_comm, &request);
109  return request;
110 }
111 
112 inline MPI::Request
113 MPI::Comm::Irecv(void *buf, int count,
114  const MPI::Datatype & datatype, int source, int tag) const
115 {
116  MPI_Request request;
117  (void)MPI_Irecv(buf, count, datatype, source,
118  tag, mpi_comm, &request);
119  return request;
120 }
121 
122 
123 inline bool
124 MPI::Comm::Iprobe(int source, int tag, MPI::Status & status) const
125 {
126  int t;
127  (void)MPI_Iprobe(source, tag, mpi_comm, &t, &status.mpi_status);
128  return OPAL_INT_TO_BOOL(t);
129 }
130 
131 inline bool
132 MPI::Comm::Iprobe(int source, int tag) const
133 {
134  int t;
135  (void)MPI_Iprobe(source, tag, mpi_comm, &t, MPI_STATUS_IGNORE);
136  return OPAL_INT_TO_BOOL(t);
137 }
138 
139 inline void
140 MPI::Comm::Probe(int source, int tag, MPI::Status & status) const
141 {
142  (void)MPI_Probe(source, tag, mpi_comm, &status.mpi_status);
143 }
144 
145 inline void
146 MPI::Comm::Probe(int source, int tag) const
147 {
148  (void)MPI_Probe(source, tag, mpi_comm, MPI_STATUS_IGNORE);
149 }
150 
151 inline MPI::Prequest
152 MPI::Comm::Send_init(const void *buf, int count,
153  const MPI::Datatype & datatype, int dest, int tag) const
154 {
155  MPI_Request request;
156  (void)MPI_Send_init(const_cast<void *>(buf), count, datatype,
157  dest, tag, mpi_comm, &request);
158  return request;
159 }
160 
161 inline MPI::Prequest
162 MPI::Comm::Bsend_init(const void *buf, int count,
163  const MPI::Datatype & datatype, int dest, int tag) const
164 {
165  MPI_Request request;
166  (void)MPI_Bsend_init(const_cast<void *>(buf), count, datatype,
167  dest, tag, mpi_comm, &request);
168  return request;
169 }
170 
171 inline MPI::Prequest
172 MPI::Comm::Ssend_init(const void *buf, int count,
173  const MPI::Datatype & datatype, int dest, int tag) const
174 {
175  MPI_Request request;
176  (void)MPI_Ssend_init(const_cast<void *>(buf), count, datatype,
177  dest, tag, mpi_comm, &request);
178  return request;
179 }
180 
181 inline MPI::Prequest
182 MPI::Comm::Rsend_init(const void *buf, int count,
183  const MPI::Datatype & datatype, int dest, int tag) const
184 {
185  MPI_Request request;
186  (void)MPI_Rsend_init(const_cast<void *>(buf), count, datatype,
187  dest, tag, mpi_comm, &request);
188  return request;
189 }
190 
191 inline MPI::Prequest
192 MPI::Comm::Recv_init(void *buf, int count,
193  const MPI::Datatype & datatype, int source, int tag) const
194 {
195  MPI_Request request;
196  (void)MPI_Recv_init(buf, count, datatype, source,
197  tag, mpi_comm, &request);
198  return request;
199 }
200 
201 inline void
202 MPI::Comm::Sendrecv(const void *sendbuf, int sendcount,
203  const MPI::Datatype & sendtype, int dest, int sendtag,
204  void *recvbuf, int recvcount,
205  const MPI::Datatype & recvtype, int source,
206  int recvtag, MPI::Status & status) const
207 {
208  (void)MPI_Sendrecv(const_cast<void *>(sendbuf), sendcount,
209  sendtype,
210  dest, sendtag, recvbuf, recvcount,
211  recvtype,
212  source, recvtag, mpi_comm, &status.mpi_status);
213 }
214 
215 inline void
216 MPI::Comm::Sendrecv(const void *sendbuf, int sendcount,
217  const MPI::Datatype & sendtype, int dest, int sendtag,
218  void *recvbuf, int recvcount,
219  const MPI::Datatype & recvtype, int source,
220  int recvtag) const
221 {
222  (void)MPI_Sendrecv(const_cast<void *>(sendbuf), sendcount,
223  sendtype,
224  dest, sendtag, recvbuf, recvcount,
225  recvtype,
226  source, recvtag, mpi_comm, MPI_STATUS_IGNORE);
227 }
228 
229 inline void
230 MPI::Comm::Sendrecv_replace(void *buf, int count,
231  const MPI::Datatype & datatype, int dest,
232  int sendtag, int source,
233  int recvtag, MPI::Status & status) const
234 {
235  (void)MPI_Sendrecv_replace(buf, count, datatype, dest,
236  sendtag, source, recvtag, mpi_comm,
237  &status.mpi_status);
238 }
239 
240 inline void
241 MPI::Comm::Sendrecv_replace(void *buf, int count,
242  const MPI::Datatype & datatype, int dest,
243  int sendtag, int source,
244  int recvtag) const
245 {
246  (void)MPI_Sendrecv_replace(buf, count, datatype, dest,
247  sendtag, source, recvtag, mpi_comm,
248  MPI_STATUS_IGNORE);
249 }
250 
251 //
252 // Groups, Contexts, and Communicators
253 //
254 
255 inline MPI::Group
256 MPI::Comm::Get_group() const
257 {
258  MPI_Group group;
259  (void)MPI_Comm_group(mpi_comm, &group);
260  return group;
261 }
262 
263 inline int
264 MPI::Comm::Get_size() const
265 {
266  int size;
267  (void)MPI_Comm_size (mpi_comm, &size);
268  return size;
269 }
270 
271 inline int
272 MPI::Comm::Get_rank() const
273 {
274  int rank;
275  (void)MPI_Comm_rank (mpi_comm, &rank);
276  return rank;
277 }
278 
279 inline int
280 MPI::Comm::Compare(const MPI::Comm & comm1,
281  const MPI::Comm & comm2)
282 {
283  int result;
284  (void)MPI_Comm_compare(comm1, comm2, &result);
285  return result;
286 }
287 
288 inline void
289 MPI::Comm::Free(void)
290 {
291  (void)MPI_Comm_free(&mpi_comm);
292 }
293 
294 inline bool
295 MPI::Comm::Is_inter() const
296 {
297  int t;
298  (void)MPI_Comm_test_inter(mpi_comm, &t);
299  return OPAL_INT_TO_BOOL(t);
300 }
301 
302 
303 //
304 // Collective Communication
305 //
306 
307 inline void
308 MPI::Comm::Barrier() const
309 {
310  (void)MPI_Barrier(mpi_comm);
311 }
312 
313 inline void
314 MPI::Comm::Bcast(void *buffer, int count,
315  const MPI::Datatype& datatype, int root) const
316 {
317  (void)MPI_Bcast(buffer, count, datatype, root, mpi_comm);
318 }
319 
320 inline void
321 MPI::Comm::Gather(const void *sendbuf, int sendcount,
322  const MPI::Datatype & sendtype,
323  void *recvbuf, int recvcount,
324  const MPI::Datatype & recvtype, int root) const
325 {
326  (void)MPI_Gather(const_cast<void *>(sendbuf), sendcount, sendtype,
327  recvbuf, recvcount, recvtype, root, mpi_comm);
328 }
329 
330 inline void
331 MPI::Comm::Gatherv(const void *sendbuf, int sendcount,
332  const MPI::Datatype & sendtype, void *recvbuf,
333  const int recvcounts[], const int displs[],
334  const MPI::Datatype & recvtype, int root) const
335 {
336  (void)MPI_Gatherv(const_cast<void *>(sendbuf), sendcount, sendtype,
337  recvbuf, const_cast<int *>(recvcounts),
338  const_cast<int *>(displs),
339  recvtype, root, mpi_comm);
340 }
341 
342 inline void
343 MPI::Comm::Scatter(const void *sendbuf, int sendcount,
344  const MPI::Datatype & sendtype,
345  void *recvbuf, int recvcount,
346  const MPI::Datatype & recvtype, int root) const
347 {
348  (void)MPI_Scatter(const_cast<void *>(sendbuf), sendcount, sendtype,
349  recvbuf, recvcount, recvtype, root, mpi_comm);
350 }
351 
352 inline void
353 MPI::Comm::Scatterv(const void *sendbuf, const int sendcounts[],
354  const int displs[], const MPI::Datatype & sendtype,
355  void *recvbuf, int recvcount,
356  const MPI::Datatype & recvtype, int root) const
357 {
358  (void)MPI_Scatterv(const_cast<void *>(sendbuf),
359  const_cast<int *>(sendcounts),
360  const_cast<int *>(displs), sendtype,
361  recvbuf, recvcount, recvtype,
362  root, mpi_comm);
363 }
364 
365 inline void
366 MPI::Comm::Allgather(const void *sendbuf, int sendcount,
367  const MPI::Datatype & sendtype, void *recvbuf,
368  int recvcount, const MPI::Datatype & recvtype) const
369 {
370  (void)MPI_Allgather(const_cast<void *>(sendbuf), sendcount,
371  sendtype, recvbuf, recvcount,
372  recvtype, mpi_comm);
373 }
374 
375 inline void
376 MPI::Comm::Allgatherv(const void *sendbuf, int sendcount,
377  const MPI::Datatype & sendtype, void *recvbuf,
378  const int recvcounts[], const int displs[],
379  const MPI::Datatype & recvtype) const
380 {
381  (void)MPI_Allgatherv(const_cast<void *>(sendbuf), sendcount,
382  sendtype, recvbuf,
383  const_cast<int *>(recvcounts),
384  const_cast<int *>(displs),
385  recvtype, mpi_comm);
386 }
387 
388 inline void
389 MPI::Comm::Alltoall(const void *sendbuf, int sendcount,
390  const MPI::Datatype & sendtype, void *recvbuf,
391  int recvcount, const MPI::Datatype & recvtype) const
392 {
393  (void)MPI_Alltoall(const_cast<void *>(sendbuf), sendcount,
394  sendtype, recvbuf, recvcount,
395  recvtype, mpi_comm);
396 }
397 
398 inline void
399 MPI::Comm::Alltoallv(const void *sendbuf, const int sendcounts[],
400  const int sdispls[], const MPI::Datatype & sendtype,
401  void *recvbuf, const int recvcounts[],
402  const int rdispls[],
403  const MPI::Datatype & recvtype) const
404 {
405  (void)MPI_Alltoallv(const_cast<void *>(sendbuf),
406  const_cast<int *>(sendcounts),
407  const_cast<int *>(sdispls), sendtype, recvbuf,
408  const_cast<int *>(recvcounts),
409  const_cast<int *>(rdispls),
410  recvtype,mpi_comm);
411 }
412 
413 inline void
414 MPI::Comm::Alltoallw(const void *sendbuf, const int sendcounts[],
415  const int sdispls[], const MPI::Datatype sendtypes[],
416  void *recvbuf, const int recvcounts[],
417  const int rdispls[],
418  const MPI::Datatype recvtypes[]) const
419 {
420  const int comm_size = Get_size();
421  MPI_Datatype *const data_type_tbl = new MPI_Datatype [2*comm_size];
422 
423  // This must be done because MPI::Datatype arrays cannot be
424  // converted directly into MPI_Datatype arrays.
425  for (int i_rank=0; i_rank < comm_size; i_rank++) {
426  data_type_tbl[i_rank] = sendtypes[i_rank];
427  data_type_tbl[i_rank + comm_size] = recvtypes[i_rank];
428  }
429 
430  (void)MPI_Alltoallw(const_cast<void *>(sendbuf),
431  const_cast<int *>(sendcounts),
432  const_cast<int *>(sdispls),
433  data_type_tbl, recvbuf,
434  const_cast<int *>(recvcounts),
435  const_cast<int *>(rdispls),
436  &data_type_tbl[comm_size], mpi_comm);
437 
438  delete[] data_type_tbl;
439 }
440 
441 inline void
442 MPI::Comm::Reduce(const void *sendbuf, void *recvbuf, int count,
443  const MPI::Datatype & datatype, const MPI::Op& op,
444  int root) const
445 {
446  (void)MPI_Reduce(const_cast<void *>(sendbuf), recvbuf, count, datatype, op, root, mpi_comm);
447 }
448 
449 inline void
450 MPI::Comm::Allreduce(const void *sendbuf, void *recvbuf, int count,
451  const MPI::Datatype & datatype, const MPI::Op& op) const
452 {
453  (void)MPI_Allreduce (const_cast<void *>(sendbuf), recvbuf, count, datatype, op, mpi_comm);
454 }
455 
456 inline void
457 MPI::Comm::Reduce_scatter(const void *sendbuf, void *recvbuf,
458  int recvcounts[],
459  const MPI::Datatype & datatype,
460  const MPI::Op& op) const
461 {
462  (void)MPI_Reduce_scatter(const_cast<void *>(sendbuf), recvbuf, recvcounts,
463  datatype, op, mpi_comm);
464 }
465 
466 //
467 // Process Creation and Managemnt
468 //
469 
470 inline void
471 MPI::Comm::Disconnect()
472 {
473  (void) MPI_Comm_disconnect(&mpi_comm);
474 }
475 
476 
477 inline MPI::Intercomm
478 MPI::Comm::Get_parent()
479 {
480  MPI_Comm parent;
481  MPI_Comm_get_parent(&parent);
482  return parent;
483 }
484 
485 
486 inline MPI::Intercomm
487 MPI::Comm::Join(const int fd)
488 {
489  MPI_Comm newcomm;
490  (void) MPI_Comm_join((int) fd, &newcomm);
491  return newcomm;
492 }
493 
494 //
495 // External Interfaces
496 //
497 
498 inline void
499 MPI::Comm::Get_name(char* comm_name, int& resultlen) const
500 {
501  (void) MPI_Comm_get_name(mpi_comm, comm_name, &resultlen);
502 }
503 
504 inline void
505 MPI::Comm::Set_name(const char* comm_name)
506 {
507  (void) MPI_Comm_set_name(mpi_comm, const_cast<char *>(comm_name));
508 }
509 
510 //
511 //Process Topologies
512 //
513 
514 inline int
515 MPI::Comm::Get_topology() const
516 {
517  int status;
518  (void)MPI_Topo_test(mpi_comm, &status);
519  return status;
520 }
521 
522 //
523 // Environmental Inquiry
524 //
525 
526 inline void
527 MPI::Comm::Abort(int errorcode)
528 {
529  (void)MPI_Abort(mpi_comm, errorcode);
530 }
531 
532 //
533 // These C++ bindings are for MPI-2.
534 // The MPI-1.2 functions called below are all
535 // going to be deprecated and replaced in MPI-2.
536 //
537 
538 inline MPI::Errhandler
539 MPI::Comm::Get_errhandler() const
540 {
541  MPI_Errhandler errhandler;
542  MPI_Comm_get_errhandler(mpi_comm, &errhandler);
543  return errhandler;
544 }
545 
546 inline void
547 MPI::Comm::Set_errhandler(const MPI::Errhandler& errhandler)
548 {
549  (void)MPI_Comm_set_errhandler(mpi_comm, errhandler);
550 }
551 
552 inline void
553 MPI::Comm::Call_errhandler(int errorcode) const
554 {
555  (void) MPI_Comm_call_errhandler(mpi_comm, errorcode);
556 }
557 
558 // 1) original Create_keyval that takes the first 2 arguments as C++
559 // functions
560 inline int
561 MPI::Comm::Create_keyval(MPI::Comm::Copy_attr_function* comm_copy_attr_fn,
562  MPI::Comm::Delete_attr_function* comm_delete_attr_fn,
563  void* extra_state)
564 {
565  // Back-end function does the heavy lifting
566  int ret, keyval;
567  ret = do_create_keyval(NULL, NULL,
568  comm_copy_attr_fn, comm_delete_attr_fn,
569  extra_state, keyval);
570  return (MPI_SUCCESS == ret) ? keyval : ret;
571 }
572 
573 // 2) overload Create_keyval to take the first 2 arguments as C
574 // functions
575 inline int
576 MPI::Comm::Create_keyval(MPI_Comm_copy_attr_function* comm_copy_attr_fn,
577  MPI_Comm_delete_attr_function* comm_delete_attr_fn,
578  void* extra_state)
579 {
580  // Back-end function does the heavy lifting
581  int ret, keyval;
582  ret = do_create_keyval(comm_copy_attr_fn, comm_delete_attr_fn,
583  NULL, NULL,
584  extra_state, keyval);
585  return (MPI_SUCCESS == ret) ? keyval : ret;
586 }
587 
588 // 3) overload Create_keyval to take the first 2 arguments as C++ & C
589 // functions
590 inline int
591 MPI::Comm::Create_keyval(MPI::Comm::Copy_attr_function* comm_copy_attr_fn,
592  MPI_Comm_delete_attr_function* comm_delete_attr_fn,
593  void* extra_state)
594 {
595  // Back-end function does the heavy lifting
596  int ret, keyval;
597  ret = do_create_keyval(NULL, comm_delete_attr_fn,
598  comm_copy_attr_fn, NULL,
599  extra_state, keyval);
600  return (MPI_SUCCESS == ret) ? keyval : ret;
601 }
602 
603 // 4) overload Create_keyval to take the first 2 arguments as C & C++
604 // functions
605 inline int
606 MPI::Comm::Create_keyval(MPI_Comm_copy_attr_function* comm_copy_attr_fn,
607  MPI::Comm::Delete_attr_function* comm_delete_attr_fn,
608  void* extra_state)
609 {
610  // Back-end function does the heavy lifting
611  int ret, keyval;
612  ret = do_create_keyval(comm_copy_attr_fn, NULL,
613  NULL, comm_delete_attr_fn,
614  extra_state, keyval);
615  return (MPI_SUCCESS == ret) ? keyval : ret;
616 }
617 
618 inline void
619 MPI::Comm::Free_keyval(int& comm_keyval)
620 {
621  (void) MPI_Comm_free_keyval(&comm_keyval);
622 }
623 
624 inline void
625 MPI::Comm::Set_attr(int comm_keyval, const void* attribute_val) const
626 {
627  (void)MPI_Comm_set_attr(mpi_comm, comm_keyval, const_cast<void*>(attribute_val));
628 }
629 
630 inline bool
631 MPI::Comm::Get_attr(int comm_keyval, void* attribute_val) const
632 {
633  int flag;
634  (void)MPI_Comm_get_attr(mpi_comm, comm_keyval, attribute_val, &flag);
635  return OPAL_INT_TO_BOOL(flag);
636 }
637 
638 inline void
639 MPI::Comm::Delete_attr(int comm_keyval)
640 {
641  (void)MPI_Comm_delete_attr(mpi_comm, comm_keyval);
642 }
643 
644 // Comment out the unused parameters so that compilers don't warn
645 // about them. Use comments instead of just deleting the param names
646 // outright so that we know/remember what they are.
647 inline int
648 MPI::Comm::NULL_COPY_FN(const MPI::Comm& /* oldcomm */,
649  int /* comm_keyval */,
650  void* /* extra_state */,
651  void* /* attribute_val_in */,
652  void* /* attribute_val_out */,
653  bool& flag)
654 {
655  flag = false;
656  return MPI_SUCCESS;
657 }
658 
659 inline int
660 MPI::Comm::DUP_FN(const MPI::Comm& oldcomm, int comm_keyval,
661  void* extra_state, void* attribute_val_in,
662  void* attribute_val_out, bool& flag)
663 {
664  if (sizeof(bool) != sizeof(int)) {
665  int f = (int)flag;
666  int ret;
667  ret = MPI_COMM_DUP_FN(oldcomm, comm_keyval, extra_state,
668  attribute_val_in, attribute_val_out, &f);
669  flag = OPAL_INT_TO_BOOL(f);
670  return ret;
671  } else {
672  return MPI_COMM_DUP_FN(oldcomm, comm_keyval, extra_state,
673  attribute_val_in, attribute_val_out,
674  (int*)&flag);
675  }
676 }
677 
678 // Comment out the unused parameters so that compilers don't warn
679 // about them. Use comments instead of just deleting the param names
680 // outright so that we know/remember what they are.
681 inline int
682 MPI::Comm::NULL_DELETE_FN(MPI::Comm& /* comm */,
683  int /* comm_keyval */,
684  void* /* attribute_val */,
685  void* /* extra_state */)
686 {
687  return MPI_SUCCESS;
688 }
689 
Definition: ompi_datatype.h:68
Back-end type for MPI_Errorhandler.
Definition: errhandler.h:108
Group structure Currently we have four formats for storing the process pointers that are members of t...
Definition: group.h:79
Definition: evdns.c:158
Definition: communicator.h:118
Main top-level request struct definition.
Definition: request.h:100