1 // Copyright (C) 2007 Trustees of Indiana University
2 
3 // Authors: Douglas Gregor
4 //          Andrew Lumsdaine
5 
6 // Use, modification and distribution is subject to the Boost Software
7 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9 #include <boost/mpi/group.hpp>
10 #include <boost/mpi/communicator.hpp>
11 
12 namespace boost { namespace mpi {
13 
group(const MPI_Group & in_group,bool adopt)14 group::group(const MPI_Group& in_group, bool adopt)
15 {
16   if (in_group != MPI_GROUP_EMPTY) {
17     if (adopt) group_ptr.reset(new MPI_Group(in_group), group_free());
18     else       group_ptr.reset(new MPI_Group(in_group));
19   }
20 }
21 
rank() const22 optional<int> group::rank() const
23 {
24   if (!group_ptr)
25     return optional<int>();
26 
27   int rank;
28   BOOST_MPI_CHECK_RESULT(MPI_Group_rank, (*group_ptr, &rank));
29   if (rank == MPI_UNDEFINED)
30     return optional<int>();
31   else
32     return rank;
33 }
34 
size() const35 int group::size() const
36 {
37   if (!group_ptr)
38     return 0;
39 
40   int size;
41   BOOST_MPI_CHECK_RESULT(MPI_Group_size, (*group_ptr, &size));
42   return size;
43 }
44 
operator ==(const group & g1,const group & g2)45 bool operator==(const group& g1, const group& g2)
46 {
47   int result;
48   BOOST_MPI_CHECK_RESULT(MPI_Group_compare,
49                          ((MPI_Group)g1, (MPI_Group)g2, &result));
50   return result == MPI_IDENT;
51 }
52 
operator |(const group & g1,const group & g2)53 group operator|(const group& g1, const group& g2)
54 {
55   MPI_Group result;
56   BOOST_MPI_CHECK_RESULT(MPI_Group_union,
57                          ((MPI_Group)g1, (MPI_Group)g2, &result));
58   return group(result, /*adopt=*/true);
59 }
60 
operator &(const group & g1,const group & g2)61 group operator&(const group& g1, const group& g2)
62 {
63   MPI_Group result;
64   BOOST_MPI_CHECK_RESULT(MPI_Group_intersection,
65                          ((MPI_Group)g1, (MPI_Group)g2, &result));
66   return group(result, /*adopt=*/true);
67 }
68 
operator -(const group & g1,const group & g2)69 group operator-(const group& g1, const group& g2)
70 {
71   MPI_Group result;
72   BOOST_MPI_CHECK_RESULT(MPI_Group_difference,
73                          ((MPI_Group)g1, (MPI_Group)g2, &result));
74   return group(result, /*adopt=*/true);
75 }
76 
77 template<>
78 int*
translate_ranks(int * first,int * last,const group & to_group,int * out)79 group::translate_ranks(int* first, int* last, const group& to_group, int* out)
80 {
81   BOOST_MPI_CHECK_RESULT(MPI_Group_translate_ranks,
82                          ((MPI_Group)*this,
83                           last-first,
84                           first,
85                           (MPI_Group)to_group,
86                           out));
87   return out + (last - first);
88 }
89 
include(int * first,int * last)90 template<> group group::include(int* first, int* last)
91 {
92   MPI_Group result;
93   BOOST_MPI_CHECK_RESULT(MPI_Group_incl,
94                          ((MPI_Group)*this, last - first, first, &result));
95   return group(result, /*adopt=*/true);
96 }
97 
exclude(int * first,int * last)98 template<> group group::exclude(int* first, int* last)
99 {
100   MPI_Group result;
101   BOOST_MPI_CHECK_RESULT(MPI_Group_excl,
102                          ((MPI_Group)*this, last - first, first, &result));
103   return group(result, /*adopt=*/true);
104 }
105 
106 } } // end namespace boost::mpi
107