Added boost header
This commit is contained in:
340
test/external/boost/mpi/group.hpp
vendored
Normal file
340
test/external/boost/mpi/group.hpp
vendored
Normal file
@@ -0,0 +1,340 @@
|
||||
// Copyright (C) 2007 Trustees of Indiana University
|
||||
|
||||
// Authors: Douglas Gregor
|
||||
// Andrew Lumsdaine
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
/** @file group.hpp
|
||||
*
|
||||
* This header defines the @c group class, which allows one to
|
||||
* manipulate and query groups of processes.
|
||||
*/
|
||||
#ifndef BOOST_MPI_GROUP_HPP
|
||||
#define BOOST_MPI_GROUP_HPP
|
||||
|
||||
#include <boost/mpi/exception.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace mpi {
|
||||
|
||||
/**
|
||||
* @brief A @c group is a representation of a subset of the processes
|
||||
* within a @c communicator.
|
||||
*
|
||||
* The @c group class allows one to create arbitrary subsets of the
|
||||
* processes within a communicator. One can compute the union,
|
||||
* intersection, or difference of two groups, or create new groups by
|
||||
* specifically including or excluding certain processes. Given a
|
||||
* group, one can create a new communicator containing only the
|
||||
* processes in that group.
|
||||
*/
|
||||
class BOOST_MPI_DECL group
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructs an empty group.
|
||||
*/
|
||||
group() : group_ptr() { }
|
||||
|
||||
/**
|
||||
* @brief Constructs a group from an @c MPI_Group.
|
||||
*
|
||||
* This routine allows one to construct a Boost.MPI @c group from a
|
||||
* C @c MPI_Group. The @c group object can (optionally) adopt the @c
|
||||
* MPI_Group, after which point the @c group object becomes
|
||||
* responsible for freeing the @c MPI_Group when the last copy of @c
|
||||
* group disappears.
|
||||
*
|
||||
* @param in_group The @c MPI_Group used to construct this @c group.
|
||||
*
|
||||
* @param adopt Whether the @c group should adopt the @c
|
||||
* MPI_Group. When true, the @c group object (or one of its copies)
|
||||
* will free the group (via @c MPI_Comm_free) when the last copy is
|
||||
* destroyed. Otherwise, the user is responsible for calling @c
|
||||
* MPI_Group_free.
|
||||
*/
|
||||
group(const MPI_Group& in_group, bool adopt);
|
||||
|
||||
/**
|
||||
* @brief Determine the rank of the calling process in the group.
|
||||
*
|
||||
* This routine is equivalent to @c MPI_Group_rank.
|
||||
*
|
||||
* @returns The rank of the calling process in the group, which will
|
||||
* be a value in [0, size()). If the calling process is not in the
|
||||
* group, returns an empty value.
|
||||
*/
|
||||
optional<int> rank() const;
|
||||
|
||||
/**
|
||||
* @brief Determine the number of processes in the group.
|
||||
*
|
||||
* This routine is equivalent to @c MPI_Group_size.
|
||||
*
|
||||
* @returns The number of processes in the group.
|
||||
*/
|
||||
int size() const;
|
||||
|
||||
/**
|
||||
* @brief Translates the ranks from one group into the ranks of the
|
||||
* same processes in another group.
|
||||
*
|
||||
* This routine translates each of the integer rank values in the
|
||||
* iterator range @c [first, last) from the current group into rank
|
||||
* values of the corresponding processes in @p to_group. The
|
||||
* corresponding rank values are written via the output iterator @c
|
||||
* out. When there is no correspondence between a rank in the
|
||||
* current group and a rank in @c to_group, the value @c
|
||||
* MPI_UNDEFINED is written to the output iterator.
|
||||
*
|
||||
* @param first Beginning of the iterator range of ranks in the
|
||||
* current group.
|
||||
*
|
||||
* @param last Past the end of the iterator range of ranks in the
|
||||
* current group.
|
||||
*
|
||||
* @param to_group The group that we are translating ranks to.
|
||||
*
|
||||
* @param out The output iterator to which the translated ranks will
|
||||
* be written.
|
||||
*
|
||||
* @returns the output iterator, which points one step past the last
|
||||
* rank written.
|
||||
*/
|
||||
template<typename InputIterator, typename OutputIterator>
|
||||
OutputIterator translate_ranks(InputIterator first, InputIterator last,
|
||||
const group& to_group, OutputIterator out);
|
||||
|
||||
/**
|
||||
* @brief Determines whether the group is non-empty.
|
||||
*
|
||||
* @returns True if the group is not empty, false if it is empty.
|
||||
*/
|
||||
operator bool() const { return (bool)group_ptr; }
|
||||
|
||||
/**
|
||||
* @brief Retrieves the underlying @c MPI_Group associated with this
|
||||
* group.
|
||||
*
|
||||
* @returns The @c MPI_Group handle manipulated by this object. If
|
||||
* this object represents the empty group, returns @c
|
||||
* MPI_GROUP_EMPTY.
|
||||
*/
|
||||
operator MPI_Group() const
|
||||
{
|
||||
if (group_ptr)
|
||||
return *group_ptr;
|
||||
else
|
||||
return MPI_GROUP_EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates a new group including a subset of the processes
|
||||
* in the current group.
|
||||
*
|
||||
* This routine creates a new @c group which includes only those
|
||||
* processes in the current group that are listed in the integer
|
||||
* iterator range @c [first, last). Equivalent to @c
|
||||
* MPI_Group_incl.
|
||||
*
|
||||
* @c first The beginning of the iterator range of ranks to include.
|
||||
*
|
||||
* @c last Past the end of the iterator range of ranks to include.
|
||||
*
|
||||
* @returns A new group containing those processes with ranks @c
|
||||
* [first, last) in the current group.
|
||||
*/
|
||||
template<typename InputIterator>
|
||||
group include(InputIterator first, InputIterator last);
|
||||
|
||||
/**
|
||||
* @brief Creates a new group from all of the processes in the
|
||||
* current group, exluding a specific subset of the processes.
|
||||
*
|
||||
* This routine creates a new @c group which includes all of the
|
||||
* processes in the current group except those whose ranks are
|
||||
* listed in the integer iterator range @c [first,
|
||||
* last). Equivalent to @c MPI_Group_excl.
|
||||
*
|
||||
* @c first The beginning of the iterator range of ranks to exclude.
|
||||
*
|
||||
* @c last Past the end of the iterator range of ranks to exclude.
|
||||
*
|
||||
* @returns A new group containing all of the processes in the
|
||||
* current group except those processes with ranks @c [first, last)
|
||||
* in the current group.
|
||||
*/
|
||||
template<typename InputIterator>
|
||||
group exclude(InputIterator first, InputIterator last);
|
||||
|
||||
|
||||
protected:
|
||||
/**
|
||||
* INTERNAL ONLY
|
||||
*
|
||||
* Function object that frees an MPI group and deletes the
|
||||
* memory associated with it. Intended to be used as a deleter with
|
||||
* shared_ptr.
|
||||
*/
|
||||
struct group_free
|
||||
{
|
||||
void operator()(MPI_Group* comm) const
|
||||
{
|
||||
int finalized;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Finalized, (&finalized));
|
||||
if (!finalized)
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Group_free, (comm));
|
||||
delete comm;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The underlying MPI group. This is a shared pointer, so the actual
|
||||
* MPI group which will be shared among all related instances of the
|
||||
* @c group class. When there are no more such instances, the group
|
||||
* will be automatically freed.
|
||||
*/
|
||||
shared_ptr<MPI_Group> group_ptr;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Determines whether two process groups are identical.
|
||||
*
|
||||
* Equivalent to calling @c MPI_Group_compare and checking whether the
|
||||
* result is @c MPI_IDENT.
|
||||
*
|
||||
* @returns True when the two process groups contain the same
|
||||
* processes in the same order.
|
||||
*/
|
||||
BOOST_MPI_DECL bool operator==(const group& g1, const group& g2);
|
||||
|
||||
/**
|
||||
* @brief Determines whether two process groups are not identical.
|
||||
*
|
||||
* Equivalent to calling @c MPI_Group_compare and checking whether the
|
||||
* result is not @c MPI_IDENT.
|
||||
*
|
||||
* @returns False when the two process groups contain the same
|
||||
* processes in the same order.
|
||||
*/
|
||||
inline bool operator!=(const group& g1, const group& g2)
|
||||
{
|
||||
return !(g1 == g2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Computes the union of two process groups.
|
||||
*
|
||||
* This routine returns a new @c group that contains all processes
|
||||
* that are either in group @c g1 or in group @c g2 (or both). The
|
||||
* processes that are in @c g1 will be first in the resulting group,
|
||||
* followed by the processes from @c g2 (but not also in @c
|
||||
* g1). Equivalent to @c MPI_Group_union.
|
||||
*/
|
||||
BOOST_MPI_DECL group operator|(const group& g1, const group& g2);
|
||||
|
||||
/**
|
||||
* @brief Computes the intersection of two process groups.
|
||||
*
|
||||
* This routine returns a new @c group that contains all processes
|
||||
* that are in group @c g1 and in group @c g2, ordered in the same way
|
||||
* as @c g1. Equivalent to @c MPI_Group_intersection.
|
||||
*/
|
||||
BOOST_MPI_DECL group operator&(const group& g1, const group& g2);
|
||||
|
||||
/**
|
||||
* @brief Computes the difference between two process groups.
|
||||
*
|
||||
* This routine returns a new @c group that contains all processes
|
||||
* that are in group @c g1 but not in group @c g2, ordered in the same way
|
||||
* as @c g1. Equivalent to @c MPI_Group_difference.
|
||||
*/
|
||||
BOOST_MPI_DECL group operator-(const group& g1, const group& g2);
|
||||
|
||||
/************************************************************************
|
||||
* Implementation details *
|
||||
************************************************************************/
|
||||
template<typename InputIterator, typename OutputIterator>
|
||||
OutputIterator
|
||||
group::translate_ranks(InputIterator first, InputIterator last,
|
||||
const group& to_group, OutputIterator out)
|
||||
{
|
||||
std::vector<int> in_array(first, last);
|
||||
if (in_array.empty())
|
||||
return out;
|
||||
|
||||
std::vector<int> out_array(in_array.size());
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Group_translate_ranks,
|
||||
((MPI_Group)*this,
|
||||
in_array.size(),
|
||||
&in_array[0],
|
||||
(MPI_Group)to_group,
|
||||
&out_array[0]));
|
||||
|
||||
for (std::vector<int>::size_type i = 0, n = out_array.size(); i < n; ++i)
|
||||
*out++ = out_array[i];
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL ONLY
|
||||
*
|
||||
* Specialization of translate_ranks that handles the one case where
|
||||
* we can avoid any memory allocation or copying.
|
||||
*/
|
||||
template<>
|
||||
BOOST_MPI_DECL int*
|
||||
group::translate_ranks(int* first, int* last, const group& to_group, int* out);
|
||||
|
||||
template<typename InputIterator>
|
||||
group group::include(InputIterator first, InputIterator last)
|
||||
{
|
||||
if (first == last)
|
||||
return group();
|
||||
|
||||
std::vector<int> ranks(first, last);
|
||||
MPI_Group result;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Group_incl,
|
||||
((MPI_Group)*this, ranks.size(), &ranks[0], &result));
|
||||
return group(result, /*adopt=*/true);
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL ONLY
|
||||
*
|
||||
* Specialization of group::include that handles the one case where we
|
||||
* can avoid any memory allocation or copying before creating the
|
||||
* group.
|
||||
*/
|
||||
template<> BOOST_MPI_DECL group group::include(int* first, int* last);
|
||||
|
||||
template<typename InputIterator>
|
||||
group group::exclude(InputIterator first, InputIterator last)
|
||||
{
|
||||
if (first == last)
|
||||
return group();
|
||||
|
||||
std::vector<int> ranks(first, last);
|
||||
MPI_Group result;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Group_excl,
|
||||
((MPI_Group)*this, ranks.size(), &ranks[0], &result));
|
||||
return group(result, /*adopt=*/true);
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL ONLY
|
||||
*
|
||||
* Specialization of group::exclude that handles the one case where we
|
||||
* can avoid any memory allocation or copying before creating the
|
||||
* group.
|
||||
*/
|
||||
template<> BOOST_MPI_DECL group group::exclude(int* first, int* last);
|
||||
|
||||
} } // end namespace boost::mpi
|
||||
|
||||
#endif // BOOST_MPI_GROUP_HPP
|
||||
Reference in New Issue
Block a user