File indexing completed on 2025-01-30 09:46:55
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #ifndef BOOST_MPI_IS_MPI_OP_HPP
0019 #define BOOST_MPI_IS_MPI_OP_HPP
0020
0021 #include <boost/mpi/config.hpp>
0022 #include <boost/mpl/bool.hpp>
0023 #include <boost/mpl/if.hpp>
0024 #include <boost/mpl/and.hpp>
0025 #include <boost/mpi/datatype.hpp>
0026 #include <boost/core/enable_if.hpp>
0027 #include <boost/core/uncaught_exceptions.hpp>
0028 #include <functional>
0029
0030 namespace boost { namespace mpi {
0031
0032 template<typename Op, typename T> struct is_mpi_op;
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 template<typename Op, typename T>
0045 struct is_commutative : public mpl::false_ { };
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058 template<typename T>
0059 struct maximum
0060 {
0061 typedef T first_argument_type;
0062 typedef T second_argument_type;
0063 typedef T result_type;
0064
0065 const T& operator()(const T& x, const T& y) const
0066 {
0067 return x < y? y : x;
0068 }
0069 };
0070
0071
0072
0073
0074
0075
0076
0077
0078 template<typename T>
0079 struct minimum
0080 {
0081 typedef T first_argument_type;
0082 typedef T second_argument_type;
0083 typedef T result_type;
0084
0085 const T& operator()(const T& x, const T& y) const
0086 {
0087 return x < y? x : y;
0088 }
0089 };
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099 template<typename T>
0100 struct bitwise_and
0101 {
0102 typedef T first_argument_type;
0103 typedef T second_argument_type;
0104 typedef T result_type;
0105
0106 T operator()(const T& x, const T& y) const
0107 {
0108 return x & y;
0109 }
0110 };
0111
0112
0113
0114
0115
0116
0117
0118
0119 template<typename T>
0120 struct bitwise_or
0121 {
0122 typedef T first_argument_type;
0123 typedef T second_argument_type;
0124 typedef T result_type;
0125
0126 T operator()(const T& x, const T& y) const
0127 {
0128 return x | y;
0129 }
0130 };
0131
0132
0133
0134
0135
0136
0137
0138
0139 template<typename T>
0140 struct logical_xor
0141 {
0142 typedef T first_argument_type;
0143 typedef T second_argument_type;
0144 typedef T result_type;
0145
0146 T operator()(const T& x, const T& y) const
0147 {
0148 return (x || y) && !(x && y);
0149 }
0150 };
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160 template<typename T>
0161 struct bitwise_xor
0162 {
0163 typedef T first_argument_type;
0164 typedef T second_argument_type;
0165 typedef T result_type;
0166
0167 T operator()(const T& x, const T& y) const
0168 {
0169 return x ^ y;
0170 }
0171 };
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195 template<typename Op, typename T>
0196 struct is_mpi_op : public mpl::false_ { };
0197
0198
0199 template<typename T>
0200 struct is_mpi_op<maximum<T>, T>
0201 : public boost::mpl::or_<is_mpi_integer_datatype<T>,
0202 is_mpi_floating_point_datatype<T> >
0203 {
0204 static MPI_Op op() { return MPI_MAX; }
0205 };
0206
0207
0208 template<typename T>
0209 struct is_mpi_op<minimum<T>, T>
0210 : public boost::mpl::or_<is_mpi_integer_datatype<T>,
0211 is_mpi_floating_point_datatype<T> >
0212 {
0213 static MPI_Op op() { return MPI_MIN; }
0214 };
0215
0216
0217 template<typename T>
0218 struct is_mpi_op<std::plus<T>, T>
0219 : public boost::mpl::or_<is_mpi_integer_datatype<T>,
0220 is_mpi_floating_point_datatype<T>,
0221 is_mpi_complex_datatype<T> >
0222 {
0223 static MPI_Op op() { return MPI_SUM; }
0224 };
0225
0226
0227 template<typename T>
0228 struct is_mpi_op<std::multiplies<T>, T>
0229 : public boost::mpl::or_<is_mpi_integer_datatype<T>,
0230 is_mpi_floating_point_datatype<T>,
0231 is_mpi_complex_datatype<T> >
0232 {
0233 static MPI_Op op() { return MPI_PROD; }
0234 };
0235
0236
0237 template<typename T>
0238 struct is_mpi_op<std::logical_and<T>, T>
0239 : public boost::mpl::or_<is_mpi_integer_datatype<T>,
0240 is_mpi_logical_datatype<T> >
0241 {
0242 static MPI_Op op() { return MPI_LAND; }
0243 };
0244
0245
0246 template<typename T>
0247 struct is_mpi_op<std::logical_or<T>, T>
0248 : public boost::mpl::or_<is_mpi_integer_datatype<T>,
0249 is_mpi_logical_datatype<T> >
0250 {
0251 static MPI_Op op() { return MPI_LOR; }
0252 };
0253
0254
0255 template<typename T>
0256 struct is_mpi_op<logical_xor<T>, T>
0257 : public boost::mpl::or_<is_mpi_integer_datatype<T>,
0258 is_mpi_logical_datatype<T> >
0259 {
0260 static MPI_Op op() { return MPI_LXOR; }
0261 };
0262
0263
0264 template<typename T>
0265 struct is_mpi_op<bitwise_and<T>, T>
0266 : public boost::mpl::or_<is_mpi_integer_datatype<T>,
0267 is_mpi_byte_datatype<T> >
0268 {
0269 static MPI_Op op() { return MPI_BAND; }
0270 };
0271
0272
0273 template<typename T>
0274 struct is_mpi_op<bitwise_or<T>, T>
0275 : public boost::mpl::or_<is_mpi_integer_datatype<T>,
0276 is_mpi_byte_datatype<T> >
0277 {
0278 static MPI_Op op() { return MPI_BOR; }
0279 };
0280
0281
0282 template<typename T>
0283 struct is_mpi_op<bitwise_xor<T>, T>
0284 : public boost::mpl::or_<is_mpi_integer_datatype<T>,
0285 is_mpi_byte_datatype<T> >
0286 {
0287 static MPI_Op op() { return MPI_BXOR; }
0288 };
0289
0290 namespace detail {
0291
0292 template<typename Op, typename T>
0293 class user_op
0294 {
0295 public:
0296 user_op()
0297 {
0298 BOOST_MPI_CHECK_RESULT(MPI_Op_create,
0299 (&user_op<Op, T>::perform,
0300 is_commutative<Op, T>::value,
0301 &mpi_op));
0302 }
0303
0304 ~user_op()
0305 {
0306 if (boost::core::uncaught_exceptions() > 0) {
0307
0308
0309
0310 MPI_Op_free(&mpi_op);
0311 } else {
0312 BOOST_MPI_CHECK_RESULT(MPI_Op_free, (&mpi_op));
0313 }
0314 }
0315
0316 MPI_Op& get_mpi_op()
0317 {
0318 return mpi_op;
0319 }
0320
0321 private:
0322 MPI_Op mpi_op;
0323
0324 static void BOOST_MPI_CALLING_CONVENTION perform(void* vinvec, void* voutvec, int* plen, MPI_Datatype*)
0325 {
0326 T* invec = static_cast<T*>(vinvec);
0327 T* outvec = static_cast<T*>(voutvec);
0328 Op op;
0329 std::transform(invec, invec + *plen, outvec, outvec, op);
0330 }
0331 };
0332
0333 }
0334
0335 } }
0336
0337 #endif