Advertisement
Guest User

Untitled

a guest
Mar 21st, 2018
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.27 KB | None | 0 0
  1. //
  2. // main.cpp
  3. //
  4.  
  5. #include "Matrix.hpp"
  6. #include <mpi.h>
  7.  
  8. #include <cstdlib>
  9. #include <ctime>
  10. #include <iostream>
  11. #include <stdexcept>
  12.  
  13. using namespace std;
  14.  
  15. size_t ROOT_PROCESS_RANK = 0;
  16.  
  17. int ROW_TAG = 1;
  18. int COL_TAG = 2;
  19.  
  20. // Inverser la matrice par la méthode de Gauss-Jordan; implantation séquentielle.
  21. void invertSequential(Matrix& iA) {
  22.  
  23. // vérifier que la matrice est carrée
  24. assert(iA.rows() == iA.cols());
  25. // construire la matrice [A I]
  26. MatrixConcatCols lAI(iA, MatrixIdentity(iA.rows()));
  27.  
  28. // traiter chaque rangée
  29. for (size_t k=0; k<iA.rows(); ++k) {
  30. // trouver l'index p du plus grand pivot de la colonne k en valeur absolue
  31. // (pour une meilleure stabilité numérique).
  32. size_t p = k;
  33. double lMax = fabs(lAI(k,k));
  34. for(size_t i = k; i < lAI.rows(); ++i) {
  35. if(fabs(lAI(i,k)) > lMax) {
  36. lMax = fabs(lAI(i,k));
  37. p = i;
  38. }
  39. }
  40. // vérifier que la matrice n'est pas singulière
  41. if (lAI(p, k) == 0) throw runtime_error("Matrix not invertible");
  42.  
  43. // échanger la ligne courante avec celle du pivot
  44.  
  45. cout << "P = " << p << ", K = " << k << endl;
  46. if (p != k) lAI.swapRows(p, k);
  47.  
  48. double lValue = lAI(k, k);
  49. for (size_t j=0; j<lAI.cols(); ++j) {
  50. // On divise les éléments de la rangée k
  51. // par la valeur du pivot.
  52. // Ainsi, lAI(k,k) deviendra égal à 1.
  53. lAI(k, j) /= lValue;
  54. }
  55.  
  56. // Pour chaque rangée...
  57. for (size_t i=0; i<lAI.rows(); ++i) {
  58. if (i != k) { // ...différente de k
  59. // On soustrait la rangée k
  60. // multipliée par l'élément k de la rangée courante
  61. double lValue = lAI(i, k);
  62. lAI.getRowSlice(i) -= lAI.getRowCopy(k)*lValue;
  63. }
  64. }
  65. cout << lAI.str() <<endl;
  66. }
  67.  
  68. // On copie la partie droite de la matrice AI ainsi transformée
  69. // dans la matrice courante (this).
  70. for (unsigned int i=0; i<iA.rows(); ++i) {
  71. iA.getRowSlice(i) = lAI.getDataArray()[slice(i*lAI.cols()+iA.cols(), iA.cols(), 1)];
  72. }
  73. }
  74.  
  75. // Inverser la matrice par la méthode de Gauss-Jordan; implantation MPI parallèle.
  76. void invertParallel(Matrix& iA, size_t rank, size_t size) {
  77.  
  78. // vérifier que la matrice est carrée
  79. assert(iA.rows() == iA.cols());
  80. // construire la matrice [A I]
  81. MatrixConcatCols lAI(iA, MatrixIdentity(iA.rows()));
  82.  
  83. size_t startRow = rank * lAI.rows() / size;
  84. size_t endRow = (rank + 1) * lAI.rows() / size;
  85. for (size_t currentPivotingRow = 0; currentPivotingRow < lAI.rows(); ++currentPivotingRow) {
  86. double maxAbsValue = 0;
  87. if (startRow <= currentPivotingRow && currentPivotingRow < endRow){
  88. // Find maxValue
  89. // broadcast it
  90. } else {
  91. // get the broadcast from the pivoting row
  92. }
  93.  
  94. if (maxAbsValue == 0) {
  95. // finalize
  96. if (rank == ROOT_PROCESS_RANK) {
  97. //throw runtime_error
  98. } else {
  99. // exit program
  100. }
  101. }
  102.  
  103. if (startRow <= currentPivotingRow && currentPivotingRow < endRow){
  104. // Find maxValue
  105. // broadcast it
  106. } else {
  107. for (size_t currentRow = startRow; currentRow < endRow; ++currentRow) {
  108. for (size_t currentCol = 0; currentCol < lAi.cols(); ++currentCol) {
  109. //lAi(currentRow, currentCol) =
  110. }
  111. }
  112. }
  113.  
  114. }
  115. }
  116.  
  117. // Multiplier deux matrices.
  118. Matrix multiplyMatrix(const Matrix& iMat1, const Matrix& iMat2) {
  119.  
  120. // vérifier la compatibilité des matrices
  121. assert(iMat1.cols() == iMat2.rows());
  122. // effectuer le produit matriciel
  123. Matrix lRes(iMat1.rows(), iMat2.cols());
  124. // traiter chaque rangée
  125. for(size_t i=0; i < lRes.rows(); ++i) {
  126. // traiter chaque colonne
  127. for(size_t j=0; j < lRes.cols(); ++j) {
  128. lRes(i,j) = (iMat1.getRowCopy(i)*iMat2.getColumnCopy(j)).sum();
  129. }
  130. }
  131. return lRes;
  132. }
  133.  
  134. void createSizeAndOffsetBuffers(int* &sizeBuffer, int* &offsetBuffer, size_t rows, size_t cols, size_t size) {
  135. sizeBuffer = new int[size];
  136. offsetBuffer = new int [size];
  137.  
  138. for (int i = 0; i < size; ++i) {
  139. sizeBuffer[i] = cols * ((i + 1) * rows / size - i * rows / size);
  140. offsetBuffer[i] = cols * (i * rows / size);
  141. }
  142. }
  143.  
  144. Matrix broadcastMatrix(size_t rank, size_t size) {
  145. size_t rows, cols;
  146. MPI_Bcast(
  147. &rows,
  148. sizeof(size_t),
  149. MPI_CHAR,
  150. ROOT_PROCESS_RANK,
  151. MPI_COMM_WORLD);
  152. MPI_Bcast(
  153. &cols,
  154. sizeof(size_t),
  155. MPI_CHAR,
  156. ROOT_PROCESS_RANK,
  157. MPI_COMM_WORLD);
  158.  
  159. Matrix broadcastedMatrix(rows, cols);
  160. MPI_Bcast(
  161. &broadcastedMatrix(0, 0),
  162. rows * cols,
  163. MPI_DOUBLE,
  164. ROOT_PROCESS_RANK,
  165. MPI_COMM_WORLD);
  166.  
  167. return broadcastedMatrix;
  168. }
  169.  
  170. void gatherMatrix(Matrix& m, size_t rank, size_t size) {
  171. MPI_Gatherv(&m(rank * m.rows() / size, 0),
  172. m.cols() * ((rank + 1) * m.rows() / size - rank * m.rows() / size),
  173. MPI_DOUBLE,
  174. NULL,
  175. NULL,
  176. NULL,
  177. MPI_DOUBLE,
  178. ROOT_PROCESS_RANK,
  179. MPI_COMM_WORLD);
  180. }
  181.  
  182. Matrix broadcastRootMatrix(Matrix& m, size_t rank, size_t size) {
  183. size_t rows = m.rows();
  184. size_t cols = m.cols();
  185. MPI_Bcast(
  186. &rows,
  187. sizeof(size_t),
  188. MPI_CHAR,
  189. rank,
  190. MPI_COMM_WORLD);
  191. MPI_Bcast(
  192. &rows,
  193. sizeof(size_t),
  194. MPI_CHAR,
  195. rank,
  196. MPI_COMM_WORLD);
  197.  
  198. MPI_Bcast(
  199. &m(0, 0),
  200. rows * cols,
  201. MPI_DOUBLE,
  202. rank,
  203. MPI_COMM_WORLD);
  204.  
  205. return m;
  206. }
  207.  
  208. Matrix gatherRootMatrix(Matrix& m, size_t rank, size_t size) {
  209. int* sizeBuffer;
  210. int* offsetBuffer;
  211.  
  212. createSizeAndOffsetBuffers(sizeBuffer, offsetBuffer, m.rows(), m.cols(), size);
  213.  
  214. Matrix gatheredMatrix(m.rows(), m.cols());
  215. MPI_Gatherv(&m(rank * m.rows() / size, 0),
  216. sizeBuffer[rank],
  217. MPI_DOUBLE,
  218. &gatheredMatrix(0, 0),
  219. sizeBuffer,
  220. offsetBuffer,
  221. MPI_DOUBLE,
  222. ROOT_PROCESS_RANK,
  223. MPI_COMM_WORLD);
  224.  
  225. delete[] sizeBuffer;
  226. delete[] offsetBuffer;
  227.  
  228. return gatheredMatrix;
  229. }
  230.  
  231. void invertParallelChild(size_t rank, size_t size) {
  232. Matrix lB(broadcastMatrix(rank, size));
  233. invertParallel(lB, rank, size);
  234. gatherMatrix(lB, rank, size);
  235. }
  236.  
  237. void invertParallelParent(size_t rank, size_t size, int argc, char** argv) {
  238.  
  239. unsigned int lS = 5;
  240. if (argc == 2) {
  241. lS = atoi(argv[1]);
  242. }
  243.  
  244. MatrixRandom lA(lS, lS);
  245. cout << "Matrice random:\n" << lA.str() << endl;
  246.  
  247. broadcastRootMatrix(lA, rank, size);
  248. invertParallel(lA, rank, size);
  249. Matrix lB(gatherRootMatrix(lA, rank, size));
  250. cout << "Matrice inverse:\n" << lB.str() << endl;
  251.  
  252. Matrix lRes = multiplyMatrix(lA, lB);
  253. cout << "Produit des deux matrices:\n" << lRes.str() << endl;
  254.  
  255. cout << "Erreur: " << lRes.getDataArray().sum() - lS << endl;
  256. }
  257.  
  258. int main(int argc, char** argv) {
  259. MPI_Init(NULL, NULL);
  260.  
  261. srand((unsigned)time(NULL));
  262.  
  263. int worldSize;
  264. MPI_Comm_size(MPI_COMM_WORLD, &worldSize);
  265.  
  266. int worldRank;
  267. MPI_Comm_rank(MPI_COMM_WORLD, &worldRank);
  268.  
  269. if (worldRank == ROOT_PROCESS_RANK) {
  270. invertParallelParent(worldRank, worldSize, argc, argv);
  271. } else {
  272. invertParallelChild(worldRank, worldSize);
  273. }
  274.  
  275. MPI_Finalize();
  276. return 0;
  277. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement