GSATThreadMPI.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #include <iostream>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <unistd.h>
  5. #include <mpi.h>
  6. #include "Main.hpp"
  7. #include "GSATThreadMPI.hpp"
  8. #include "color.h"
  9. extern int world_rank;
  10. extern int world_size;
  11. /* --- Public --- */
  12. GSATThreadMPI::GSATThreadMPI(int _nbThread, int argc, char** argv) {
  13. nbThread = _nbThread;
  14. gsat = std::vector<GSAT*>(_nbThread);
  15. threads = std::vector<std::thread>(_nbThread);
  16. for(int i = 0; i < _nbThread; i++) {
  17. gsat[i] = new GSAT();
  18. gsat[i]->setParameters(argc,argv);
  19. gsat[i]->initialize();
  20. }
  21. srand(getpid());
  22. }
  23. GSATThreadMPI::~GSATThreadMPI() {
  24. for(int i = 0; i < nbThread; i++) {
  25. delete gsat[i];
  26. }
  27. }
  28. bool GSATThreadMPI::solve() {
  29. threads.clear();
  30. end = false;
  31. find = false;
  32. //Lance thread
  33. for(int i = 0; i < nbThread; i++) {
  34. threads[i] = std::thread(&GSATThreadMPI::solverThread, this, i);
  35. }
  36. //Lance thread de synchronisation MPI
  37. mpiSync = std::thread(&GSATThreadMPI::mpiWait, this, this);
  38. //Attend resultat
  39. for(int i = 0; i < nbThread; i++){
  40. threads[i].join();
  41. }
  42. mpiSync.join();
  43. //Si c'est le proc qui à trouvé
  44. if(find) {
  45. //Affiche resultat
  46. sleep(1); //Attend la fin des autres processus
  47. printf("-----------------------------------------------------------------------------------------------------------------\n");
  48. this->printResult();
  49. }
  50. return find;
  51. }
  52. void GSATThreadMPI::isEnd() {
  53. end = true;
  54. }
  55. void GSATThreadMPI::printResult() {
  56. printf(GREEN);
  57. printf("s %s\n",find?"SATISFIABLE":"NOT FOUND");
  58. printf(YELLOW);
  59. printf("c real time : %.4f seconds\n", result.calcTime);
  60. printf("c [pid:%6d][process:%2d][thread:%2d][iteration:%4d][fill:%d][heuristic:%d]Satisfied clauses (begin: %d)(end:%d)\n",
  61. getpid(),
  62. world_rank,
  63. result.threadId,
  64. result.nbIteration,
  65. result.heuristicFill,
  66. result.heuristicSolve,
  67. result.nbSatisfiedClausesFill,
  68. result.nbSatisfiedClausesSolve);
  69. printf(RESET);
  70. fflush(stdout);
  71. }
  72. /* --- Private --- */
  73. void GSATThreadMPI::solverThread(int id) {
  74. //Resolution
  75. double startTime = gsat[id]->realTime();
  76. bool solve = false;
  77. int cpt = 0;
  78. while(!end && !solve){
  79. //Pour eviter que les processeurs effectue tous les meme calculs
  80. int fill = rand() % 4 + 2;
  81. int h = rand() % 7;
  82. solve = gsat[id]->start(fill, h);
  83. if(solve) {
  84. printf(CYAN);
  85. }
  86. printf("c [pid:%6d][process:%2d][thread:%2d][iteration:%4d][fill:%d][heuristic:%d]Satisfied clauses (begin: %d)(end:%d)\n",
  87. getpid(),
  88. world_rank,
  89. id,
  90. gsat[id]->getNbIterations(),
  91. gsat[id]->getHeuristicFill(),
  92. gsat[id]->getHeuristicSolve(),
  93. gsat[id]->getNbSatisfiedClausesFill(),
  94. gsat[id]->getNbSatisfiedClausesSolve());
  95. if(solve) {
  96. printf(RESET);
  97. }
  98. cpt++;
  99. }
  100. //Si 1er arreter
  101. if(!end && solve) {
  102. this->mpiNotify(world_rank);
  103. end = true;
  104. find = true;
  105. result.threadId = id;
  106. result.calcTime = gsat[id]->realTime() - startTime;
  107. result.nbIteration = gsat[id]->getNbIterations();
  108. result.heuristicFill = gsat[id]->getHeuristicFill();
  109. result.heuristicSolve = gsat[id]->getHeuristicSolve();
  110. result.nbSatisfiedClausesFill = gsat[id]->getNbSatisfiedClausesFill();
  111. result.nbSatisfiedClausesSolve = gsat[id]->getNbSatisfiedClausesSolve();
  112. }
  113. }
  114. void GSATThreadMPI::mpiWait(GSATThreadMPI* gsat) {
  115. int buff;
  116. MPI_Recv(&buff, 1, MPI_INT, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  117. if(buff != world_rank) {
  118. gsat->isEnd();
  119. }
  120. }
  121. void GSATThreadMPI::mpiNotify(int rank) {
  122. for(int i = 0; i < world_size; i++) {
  123. MPI_Send(&rank, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
  124. }
  125. }