00001 #ifndef INDII_ML_AUX_PARALLEL_HPP
00002 #define INDII_ML_AUX_PARALLEL_HPP
00003
00004 #include "vector.hpp"
00005 #include "matrix.hpp"
00006
00007 #include "boost/mpi.hpp"
00008
00009 #include <functional>
00010
00011 namespace boost {
00012 namespace mpi {
00013
00014
00015
00016
00017 template<>
00018 struct is_commutative<std::plus<unsigned int>, unsigned int> : mpl::true_ {
00019
00020 };
00021
00022 template<>
00023 struct is_commutative<std::plus<double>, double> : mpl::true_ {
00024
00025 };
00026
00027 template<>
00028 struct is_commutative<std::plus<indii::ml::aux::vector>,
00029 indii::ml::aux::vector> : mpl::true_ {
00030
00031 };
00032
00033 template<>
00034 struct is_commutative<std::plus<indii::ml::aux::matrix>,
00035 indii::ml::aux::matrix> : mpl::true_ {
00036
00037 };
00038
00039 template<>
00040 struct is_commutative<std::plus<indii::ml::aux::symmetric_matrix>,
00041 indii::ml::aux::symmetric_matrix> : mpl::true_ {
00042
00043 };
00044
00045 template<>
00046 struct is_commutative<std::plus<indii::ml::aux::lower_triangular_matrix>,
00047 indii::ml::aux::lower_triangular_matrix> : mpl::true_ {
00048
00049 };
00050
00051 template<>
00052 struct is_commutative<std::plus<indii::ml::aux::upper_triangular_matrix>,
00053 indii::ml::aux::upper_triangular_matrix> : mpl::true_ {
00054
00055 };
00056
00057 template<>
00058 struct is_commutative<std::plus<indii::ml::aux::identity_matrix>,
00059 indii::ml::aux::identity_matrix> : mpl::true_ {
00060
00061 };
00062
00063 template<>
00064 struct is_commutative<std::plus<indii::ml::aux::zero_matrix>,
00065 indii::ml::aux::zero_matrix> : mpl::true_ {
00066
00067 };
00068
00069 template<>
00070 struct is_commutative<std::plus<indii::ml::aux::scalar_matrix>,
00071 indii::ml::aux::scalar_matrix> : mpl::true_ {
00072
00073 };
00074
00075 template<>
00076 struct is_commutative<std::plus<indii::ml::aux::sparse_matrix>,
00077 indii::ml::aux::sparse_matrix> : mpl::true_ {
00078
00079 };
00080
00081
00082
00083 }
00084 }
00085
00086 namespace indii {
00087 namespace ml {
00088 namespace aux {
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 unsigned int shareOf(const unsigned int P);
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 template <class T>
00113 void rotate(T& x, const unsigned int num = 1);
00114
00115 }
00116 }
00117 }
00118
00119 inline unsigned int indii::ml::aux::shareOf(const unsigned int P) {
00120 boost::mpi::communicator world;
00121 const unsigned int rank = world.rank();
00122 const unsigned int size = world.size();
00123 unsigned int P_local = P / size;
00124 if (rank < P % size) {
00125 P_local++;
00126 }
00127
00128 return P_local;
00129 }
00130
00131 template <class T>
00132 void indii::ml::aux::rotate(T& x, const unsigned int num = 1) {
00133 boost::mpi::communicator world;
00134 boost::mpi::request reqSend, reqRecv;
00135 const unsigned int rank = world.rank();
00136 const unsigned int size = world.size();
00137
00138 if (size > 1 && num > 0) {
00139
00140
00141
00142
00143
00144
00145 reqSend = world.isend((rank+size-num) % size, 0, x);
00146 reqRecv = world.irecv((rank+num) % size, 0, x);
00147 reqRecv.wait();
00148 reqSend.wait();
00149 }
00150 }
00151
00152 #endif