annotate DEPENDENCIES/generic/include/boost/mpi/group.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // Copyright (C) 2007 Trustees of Indiana University
Chris@16 2
Chris@16 3 // Authors: Douglas Gregor
Chris@16 4 // Andrew Lumsdaine
Chris@16 5
Chris@16 6 // Use, modification and distribution is subject to the Boost Software
Chris@16 7 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 8 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 9
Chris@16 10 /** @file group.hpp
Chris@16 11 *
Chris@16 12 * This header defines the @c group class, which allows one to
Chris@16 13 * manipulate and query groups of processes.
Chris@16 14 */
Chris@16 15 #ifndef BOOST_MPI_GROUP_HPP
Chris@16 16 #define BOOST_MPI_GROUP_HPP
Chris@16 17
Chris@16 18 #include <boost/mpi/exception.hpp>
Chris@16 19 #include <boost/shared_ptr.hpp>
Chris@16 20 #include <boost/optional.hpp>
Chris@16 21 #include <vector>
Chris@16 22
Chris@16 23 namespace boost { namespace mpi {
Chris@16 24
Chris@16 25 /**
Chris@16 26 * @brief A @c group is a representation of a subset of the processes
Chris@16 27 * within a @c communicator.
Chris@16 28 *
Chris@16 29 * The @c group class allows one to create arbitrary subsets of the
Chris@16 30 * processes within a communicator. One can compute the union,
Chris@16 31 * intersection, or difference of two groups, or create new groups by
Chris@16 32 * specifically including or excluding certain processes. Given a
Chris@16 33 * group, one can create a new communicator containing only the
Chris@16 34 * processes in that group.
Chris@16 35 */
Chris@16 36 class BOOST_MPI_DECL group
Chris@16 37 {
Chris@16 38 public:
Chris@16 39 /**
Chris@16 40 * @brief Constructs an empty group.
Chris@16 41 */
Chris@16 42 group() : group_ptr() { }
Chris@16 43
Chris@16 44 /**
Chris@16 45 * @brief Constructs a group from an @c MPI_Group.
Chris@16 46 *
Chris@16 47 * This routine allows one to construct a Boost.MPI @c group from a
Chris@16 48 * C @c MPI_Group. The @c group object can (optionally) adopt the @c
Chris@16 49 * MPI_Group, after which point the @c group object becomes
Chris@16 50 * responsible for freeing the @c MPI_Group when the last copy of @c
Chris@16 51 * group disappears.
Chris@16 52 *
Chris@16 53 * @param in_group The @c MPI_Group used to construct this @c group.
Chris@16 54 *
Chris@16 55 * @param adopt Whether the @c group should adopt the @c
Chris@16 56 * MPI_Group. When true, the @c group object (or one of its copies)
Chris@16 57 * will free the group (via @c MPI_Comm_free) when the last copy is
Chris@16 58 * destroyed. Otherwise, the user is responsible for calling @c
Chris@16 59 * MPI_Group_free.
Chris@16 60 */
Chris@16 61 group(const MPI_Group& in_group, bool adopt);
Chris@16 62
Chris@16 63 /**
Chris@16 64 * @brief Determine the rank of the calling process in the group.
Chris@16 65 *
Chris@16 66 * This routine is equivalent to @c MPI_Group_rank.
Chris@16 67 *
Chris@16 68 * @returns The rank of the calling process in the group, which will
Chris@16 69 * be a value in [0, size()). If the calling process is not in the
Chris@16 70 * group, returns an empty value.
Chris@16 71 */
Chris@16 72 optional<int> rank() const;
Chris@16 73
Chris@16 74 /**
Chris@16 75 * @brief Determine the number of processes in the group.
Chris@16 76 *
Chris@16 77 * This routine is equivalent to @c MPI_Group_size.
Chris@16 78 *
Chris@16 79 * @returns The number of processes in the group.
Chris@16 80 */
Chris@16 81 int size() const;
Chris@16 82
Chris@16 83 /**
Chris@16 84 * @brief Translates the ranks from one group into the ranks of the
Chris@16 85 * same processes in another group.
Chris@16 86 *
Chris@16 87 * This routine translates each of the integer rank values in the
Chris@16 88 * iterator range @c [first, last) from the current group into rank
Chris@16 89 * values of the corresponding processes in @p to_group. The
Chris@16 90 * corresponding rank values are written via the output iterator @c
Chris@16 91 * out. When there is no correspondence between a rank in the
Chris@16 92 * current group and a rank in @c to_group, the value @c
Chris@16 93 * MPI_UNDEFINED is written to the output iterator.
Chris@16 94 *
Chris@16 95 * @param first Beginning of the iterator range of ranks in the
Chris@16 96 * current group.
Chris@16 97 *
Chris@16 98 * @param last Past the end of the iterator range of ranks in the
Chris@16 99 * current group.
Chris@16 100 *
Chris@16 101 * @param to_group The group that we are translating ranks to.
Chris@16 102 *
Chris@16 103 * @param out The output iterator to which the translated ranks will
Chris@16 104 * be written.
Chris@16 105 *
Chris@16 106 * @returns the output iterator, which points one step past the last
Chris@16 107 * rank written.
Chris@16 108 */
Chris@16 109 template<typename InputIterator, typename OutputIterator>
Chris@16 110 OutputIterator translate_ranks(InputIterator first, InputIterator last,
Chris@16 111 const group& to_group, OutputIterator out);
Chris@16 112
Chris@16 113 /**
Chris@16 114 * @brief Determines whether the group is non-empty.
Chris@16 115 *
Chris@16 116 * @returns True if the group is not empty, false if it is empty.
Chris@16 117 */
Chris@16 118 operator bool() const { return (bool)group_ptr; }
Chris@16 119
Chris@16 120 /**
Chris@16 121 * @brief Retrieves the underlying @c MPI_Group associated with this
Chris@16 122 * group.
Chris@16 123 *
Chris@16 124 * @returns The @c MPI_Group handle manipulated by this object. If
Chris@16 125 * this object represents the empty group, returns @c
Chris@16 126 * MPI_GROUP_EMPTY.
Chris@16 127 */
Chris@16 128 operator MPI_Group() const
Chris@16 129 {
Chris@16 130 if (group_ptr)
Chris@16 131 return *group_ptr;
Chris@16 132 else
Chris@16 133 return MPI_GROUP_EMPTY;
Chris@16 134 }
Chris@16 135
Chris@16 136 /**
Chris@16 137 * @brief Creates a new group including a subset of the processes
Chris@16 138 * in the current group.
Chris@16 139 *
Chris@16 140 * This routine creates a new @c group which includes only those
Chris@16 141 * processes in the current group that are listed in the integer
Chris@16 142 * iterator range @c [first, last). Equivalent to @c
Chris@16 143 * MPI_Group_incl.
Chris@16 144 *
Chris@16 145 * @c first The beginning of the iterator range of ranks to include.
Chris@16 146 *
Chris@16 147 * @c last Past the end of the iterator range of ranks to include.
Chris@16 148 *
Chris@16 149 * @returns A new group containing those processes with ranks @c
Chris@16 150 * [first, last) in the current group.
Chris@16 151 */
Chris@16 152 template<typename InputIterator>
Chris@16 153 group include(InputIterator first, InputIterator last);
Chris@16 154
Chris@16 155 /**
Chris@16 156 * @brief Creates a new group from all of the processes in the
Chris@16 157 * current group, exluding a specific subset of the processes.
Chris@16 158 *
Chris@16 159 * This routine creates a new @c group which includes all of the
Chris@16 160 * processes in the current group except those whose ranks are
Chris@16 161 * listed in the integer iterator range @c [first,
Chris@16 162 * last). Equivalent to @c MPI_Group_excl.
Chris@16 163 *
Chris@16 164 * @c first The beginning of the iterator range of ranks to exclude.
Chris@16 165 *
Chris@16 166 * @c last Past the end of the iterator range of ranks to exclude.
Chris@16 167 *
Chris@16 168 * @returns A new group containing all of the processes in the
Chris@16 169 * current group except those processes with ranks @c [first, last)
Chris@16 170 * in the current group.
Chris@16 171 */
Chris@16 172 template<typename InputIterator>
Chris@16 173 group exclude(InputIterator first, InputIterator last);
Chris@16 174
Chris@16 175
Chris@16 176 protected:
Chris@16 177 /**
Chris@16 178 * INTERNAL ONLY
Chris@16 179 *
Chris@16 180 * Function object that frees an MPI group and deletes the
Chris@16 181 * memory associated with it. Intended to be used as a deleter with
Chris@16 182 * shared_ptr.
Chris@16 183 */
Chris@16 184 struct group_free
Chris@16 185 {
Chris@16 186 void operator()(MPI_Group* comm) const
Chris@16 187 {
Chris@16 188 int finalized;
Chris@16 189 BOOST_MPI_CHECK_RESULT(MPI_Finalized, (&finalized));
Chris@16 190 if (!finalized)
Chris@16 191 BOOST_MPI_CHECK_RESULT(MPI_Group_free, (comm));
Chris@16 192 delete comm;
Chris@16 193 }
Chris@16 194 };
Chris@16 195
Chris@16 196 /**
Chris@16 197 * The underlying MPI group. This is a shared pointer, so the actual
Chris@16 198 * MPI group which will be shared among all related instances of the
Chris@16 199 * @c group class. When there are no more such instances, the group
Chris@16 200 * will be automatically freed.
Chris@16 201 */
Chris@16 202 shared_ptr<MPI_Group> group_ptr;
Chris@16 203 };
Chris@16 204
Chris@16 205 /**
Chris@16 206 * @brief Determines whether two process groups are identical.
Chris@16 207 *
Chris@16 208 * Equivalent to calling @c MPI_Group_compare and checking whether the
Chris@16 209 * result is @c MPI_IDENT.
Chris@16 210 *
Chris@16 211 * @returns True when the two process groups contain the same
Chris@16 212 * processes in the same order.
Chris@16 213 */
Chris@16 214 BOOST_MPI_DECL bool operator==(const group& g1, const group& g2);
Chris@16 215
Chris@16 216 /**
Chris@16 217 * @brief Determines whether two process groups are not identical.
Chris@16 218 *
Chris@16 219 * Equivalent to calling @c MPI_Group_compare and checking whether the
Chris@16 220 * result is not @c MPI_IDENT.
Chris@16 221 *
Chris@16 222 * @returns False when the two process groups contain the same
Chris@16 223 * processes in the same order.
Chris@16 224 */
Chris@16 225 inline bool operator!=(const group& g1, const group& g2)
Chris@16 226 {
Chris@16 227 return !(g1 == g2);
Chris@16 228 }
Chris@16 229
Chris@16 230 /**
Chris@16 231 * @brief Computes the union of two process groups.
Chris@16 232 *
Chris@16 233 * This routine returns a new @c group that contains all processes
Chris@16 234 * that are either in group @c g1 or in group @c g2 (or both). The
Chris@16 235 * processes that are in @c g1 will be first in the resulting group,
Chris@16 236 * followed by the processes from @c g2 (but not also in @c
Chris@16 237 * g1). Equivalent to @c MPI_Group_union.
Chris@16 238 */
Chris@16 239 BOOST_MPI_DECL group operator|(const group& g1, const group& g2);
Chris@16 240
Chris@16 241 /**
Chris@16 242 * @brief Computes the intersection of two process groups.
Chris@16 243 *
Chris@16 244 * This routine returns a new @c group that contains all processes
Chris@16 245 * that are in group @c g1 and in group @c g2, ordered in the same way
Chris@16 246 * as @c g1. Equivalent to @c MPI_Group_intersection.
Chris@16 247 */
Chris@16 248 BOOST_MPI_DECL group operator&(const group& g1, const group& g2);
Chris@16 249
Chris@16 250 /**
Chris@16 251 * @brief Computes the difference between two process groups.
Chris@16 252 *
Chris@16 253 * This routine returns a new @c group that contains all processes
Chris@16 254 * that are in group @c g1 but not in group @c g2, ordered in the same way
Chris@16 255 * as @c g1. Equivalent to @c MPI_Group_difference.
Chris@16 256 */
Chris@16 257 BOOST_MPI_DECL group operator-(const group& g1, const group& g2);
Chris@16 258
Chris@16 259 /************************************************************************
Chris@16 260 * Implementation details *
Chris@16 261 ************************************************************************/
Chris@16 262 template<typename InputIterator, typename OutputIterator>
Chris@16 263 OutputIterator
Chris@16 264 group::translate_ranks(InputIterator first, InputIterator last,
Chris@16 265 const group& to_group, OutputIterator out)
Chris@16 266 {
Chris@16 267 std::vector<int> in_array(first, last);
Chris@16 268 if (in_array.empty())
Chris@16 269 return out;
Chris@16 270
Chris@16 271 std::vector<int> out_array(in_array.size());
Chris@16 272 BOOST_MPI_CHECK_RESULT(MPI_Group_translate_ranks,
Chris@16 273 ((MPI_Group)*this,
Chris@16 274 in_array.size(),
Chris@16 275 &in_array[0],
Chris@16 276 (MPI_Group)to_group,
Chris@16 277 &out_array[0]));
Chris@16 278
Chris@16 279 for (std::vector<int>::size_type i = 0, n = out_array.size(); i < n; ++i)
Chris@16 280 *out++ = out_array[i];
Chris@16 281 return out;
Chris@16 282 }
Chris@16 283
Chris@16 284 /**
Chris@16 285 * INTERNAL ONLY
Chris@16 286 *
Chris@16 287 * Specialization of translate_ranks that handles the one case where
Chris@16 288 * we can avoid any memory allocation or copying.
Chris@16 289 */
Chris@16 290 template<>
Chris@16 291 BOOST_MPI_DECL int*
Chris@16 292 group::translate_ranks(int* first, int* last, const group& to_group, int* out);
Chris@16 293
Chris@16 294 template<typename InputIterator>
Chris@16 295 group group::include(InputIterator first, InputIterator last)
Chris@16 296 {
Chris@16 297 if (first == last)
Chris@16 298 return group();
Chris@16 299
Chris@16 300 std::vector<int> ranks(first, last);
Chris@16 301 MPI_Group result;
Chris@16 302 BOOST_MPI_CHECK_RESULT(MPI_Group_incl,
Chris@16 303 ((MPI_Group)*this, ranks.size(), &ranks[0], &result));
Chris@16 304 return group(result, /*adopt=*/true);
Chris@16 305 }
Chris@16 306
Chris@16 307 /**
Chris@16 308 * INTERNAL ONLY
Chris@16 309 *
Chris@16 310 * Specialization of group::include that handles the one case where we
Chris@16 311 * can avoid any memory allocation or copying before creating the
Chris@16 312 * group.
Chris@16 313 */
Chris@16 314 template<> BOOST_MPI_DECL group group::include(int* first, int* last);
Chris@16 315
Chris@16 316 template<typename InputIterator>
Chris@16 317 group group::exclude(InputIterator first, InputIterator last)
Chris@16 318 {
Chris@16 319 if (first == last)
Chris@16 320 return group();
Chris@16 321
Chris@16 322 std::vector<int> ranks(first, last);
Chris@16 323 MPI_Group result;
Chris@16 324 BOOST_MPI_CHECK_RESULT(MPI_Group_excl,
Chris@16 325 ((MPI_Group)*this, ranks.size(), &ranks[0], &result));
Chris@16 326 return group(result, /*adopt=*/true);
Chris@16 327 }
Chris@16 328
Chris@16 329 /**
Chris@16 330 * INTERNAL ONLY
Chris@16 331 *
Chris@16 332 * Specialization of group::exclude that handles the one case where we
Chris@16 333 * can avoid any memory allocation or copying before creating the
Chris@16 334 * group.
Chris@16 335 */
Chris@16 336 template<> BOOST_MPI_DECL group group::exclude(int* first, int* last);
Chris@16 337
Chris@16 338 } } // end namespace boost::mpi
Chris@16 339
Chris@16 340 #endif // BOOST_MPI_GROUP_HPP