123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 |
- #ifndef BOOST_MPI_IS_MPI_OP_HPP
- #define BOOST_MPI_IS_MPI_OP_HPP
- #include <boost/mpi/config.hpp>
- #include <boost/mpl/bool.hpp>
- #include <boost/mpl/if.hpp>
- #include <boost/mpl/and.hpp>
- #include <boost/mpi/datatype.hpp>
- #include <boost/utility/enable_if.hpp>
- #include <functional>
- namespace boost { namespace mpi {
- template<typename Op, typename T> struct is_mpi_op;
- template<typename Op, typename T>
- struct is_commutative : public mpl::false_ { };
- template<typename T>
- struct maximum : public std::binary_function<T, T, T>
- {
-
- const T& operator()(const T& x, const T& y) const
- {
- return x < y? y : x;
- }
- };
- template<typename T>
- struct minimum : public std::binary_function<T, T, T>
- {
-
- const T& operator()(const T& x, const T& y) const
- {
- return x < y? x : y;
- }
- };
- template<typename T>
- struct bitwise_and : public std::binary_function<T, T, T>
- {
-
- T operator()(const T& x, const T& y) const
- {
- return x & y;
- }
- };
- template<typename T>
- struct bitwise_or : public std::binary_function<T, T, T>
- {
-
- T operator()(const T& x, const T& y) const
- {
- return x | y;
- }
- };
- template<typename T>
- struct logical_xor : public std::binary_function<T, T, T>
- {
-
- T operator()(const T& x, const T& y) const
- {
- return (x || y) && !(x && y);
- }
- };
- template<typename T>
- struct bitwise_xor : public std::binary_function<T, T, T>
- {
-
- T operator()(const T& x, const T& y) const
- {
- return x ^ y;
- }
- };
- template<typename Op, typename T>
- struct is_mpi_op : public mpl::false_ { };
- template<typename T>
- struct is_mpi_op<maximum<T>, T>
- : public boost::mpl::or_<is_mpi_integer_datatype<T>,
- is_mpi_floating_point_datatype<T> >
- {
- static MPI_Op op() { return MPI_MAX; }
- };
- template<typename T>
- struct is_mpi_op<minimum<T>, T>
- : public boost::mpl::or_<is_mpi_integer_datatype<T>,
- is_mpi_floating_point_datatype<T> >
- {
- static MPI_Op op() { return MPI_MIN; }
- };
- template<typename T>
- struct is_mpi_op<std::plus<T>, T>
- : public boost::mpl::or_<is_mpi_integer_datatype<T>,
- is_mpi_floating_point_datatype<T>,
- is_mpi_complex_datatype<T> >
- {
- static MPI_Op op() { return MPI_SUM; }
- };
- template<typename T>
- struct is_mpi_op<std::multiplies<T>, T>
- : public boost::mpl::or_<is_mpi_integer_datatype<T>,
- is_mpi_floating_point_datatype<T>,
- is_mpi_complex_datatype<T> >
- {
- static MPI_Op op() { return MPI_PROD; }
- };
- template<typename T>
- struct is_mpi_op<std::logical_and<T>, T>
- : public boost::mpl::or_<is_mpi_integer_datatype<T>,
- is_mpi_logical_datatype<T> >
- {
- static MPI_Op op() { return MPI_LAND; }
- };
- template<typename T>
- struct is_mpi_op<std::logical_or<T>, T>
- : public boost::mpl::or_<is_mpi_integer_datatype<T>,
- is_mpi_logical_datatype<T> >
- {
- static MPI_Op op() { return MPI_LOR; }
- };
- template<typename T>
- struct is_mpi_op<logical_xor<T>, T>
- : public boost::mpl::or_<is_mpi_integer_datatype<T>,
- is_mpi_logical_datatype<T> >
- {
- static MPI_Op op() { return MPI_LXOR; }
- };
- template<typename T>
- struct is_mpi_op<bitwise_and<T>, T>
- : public boost::mpl::or_<is_mpi_integer_datatype<T>,
- is_mpi_byte_datatype<T> >
- {
- static MPI_Op op() { return MPI_BAND; }
- };
- template<typename T>
- struct is_mpi_op<bitwise_or<T>, T>
- : public boost::mpl::or_<is_mpi_integer_datatype<T>,
- is_mpi_byte_datatype<T> >
- {
- static MPI_Op op() { return MPI_BOR; }
- };
- template<typename T>
- struct is_mpi_op<bitwise_xor<T>, T>
- : public boost::mpl::or_<is_mpi_integer_datatype<T>,
- is_mpi_byte_datatype<T> >
- {
- static MPI_Op op() { return MPI_BXOR; }
- };
- namespace detail {
-
- template<typename Op, typename T>
- class user_op
- {
- public:
- explicit user_op(Op& op)
- {
- BOOST_MPI_CHECK_RESULT(MPI_Op_create,
- (&user_op<Op, T>::perform,
- is_commutative<Op, T>::value,
- &mpi_op));
- op_ptr = &op;
- }
- ~user_op()
- {
- if (std::uncaught_exception()) {
-
-
-
- MPI_Op_free(&mpi_op);
- } else {
- BOOST_MPI_CHECK_RESULT(MPI_Op_free, (&mpi_op));
- }
- }
- MPI_Op& get_mpi_op()
- {
- return mpi_op;
- }
- private:
- MPI_Op mpi_op;
- static Op* op_ptr;
- static void BOOST_MPI_CALLING_CONVENTION perform(void* vinvec, void* voutvec, int* plen, MPI_Datatype*)
- {
- T* invec = static_cast<T*>(vinvec);
- T* outvec = static_cast<T*>(voutvec);
- std::transform(invec, invec + *plen, outvec, outvec, *op_ptr);
- }
- };
- template<typename Op, typename T> Op* user_op<Op, T>::op_ptr = 0;
- }
- } }
- #endif
|