GSATHybride.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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 "GSATHybride.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. this->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. this->mpiSendResult(DISPLAY_RANK);
  46. }
  47. return find;
  48. }
  49. void GSATThreadMPI::end() {
  50. this->end(true);
  51. }
  52. void GSATThreadMPI::end(bool endOrNot) {
  53. std::lock_guard<std::mutex> guard(mEnd);
  54. bEnd = endOrNot;
  55. }
  56. bool GSATThreadMPI::isEnd() {
  57. std::lock_guard<std::mutex> guard(mEnd);
  58. return bEnd;
  59. }
  60. void GSATThreadMPI::printResult() {
  61. printf(GREEN);
  62. printf("s %s\n",find?"SATISFIABLE":"NOT FOUND");
  63. printf(YELLOW);
  64. printf("c real time : %.4f seconds\n", result.calcTime);
  65. printf("c [pid:%6d][process:%2d][thread:%2d][iteration:%4d][fill:%d][heuristic:%d]Satisfied clauses (begin: %d)(end:%d)\n",
  66. result.pid,
  67. result.rank,
  68. result.threadId,
  69. result.nbIteration,
  70. result.heuristicFill,
  71. result.heuristicSolve,
  72. result.nbSatisfiedClausesFill,
  73. result.nbSatisfiedClausesSolve);
  74. printf(RESET);
  75. fflush(stdout);
  76. }
  77. void GSATThreadMPI::setResult(bool isFind, int pid, int rank, int thread, double time, unsigned int nbIte, unsigned int heuriFill, unsigned int heuriSolve, unsigned int satisfFill, unsigned int satisfSolve) {
  78. find = isFind;
  79. result.pid = pid;
  80. result.rank = rank;
  81. result.threadId = thread;
  82. result.calcTime = time;
  83. result.nbIteration = nbIte;
  84. result.heuristicFill = heuriFill;
  85. result.heuristicSolve = heuriSolve;
  86. result.nbSatisfiedClausesFill = satisfFill;
  87. result.nbSatisfiedClausesSolve = satisfSolve;
  88. }
  89. /* --- Private --- */
  90. void GSATThreadMPI::solverThread(int id) {
  91. //Resolution
  92. double startTime = gsat[id]->realTime();
  93. bool solve = false;
  94. int cpt = 0;
  95. while(!this->isEnd() && !solve){
  96. //Pour eviter que les processeurs effectue tous les meme calculs
  97. int fill = rand() % 4 + 2;
  98. int h = rand() % 7;
  99. solve = gsat[id]->start(fill, h);
  100. if(solve) {
  101. printf(CYAN);
  102. }
  103. printf("c [pid:%6d][process:%2d][thread:%2d][iteration:%4d][fill:%d][heuristic:%d]Satisfied clauses (begin: %d)(end:%d)\n",
  104. getpid(),
  105. world_rank,
  106. id,
  107. gsat[id]->getNbIterations(),
  108. gsat[id]->getHeuristicFill(),
  109. gsat[id]->getHeuristicSolve(),
  110. gsat[id]->getNbSatisfiedClausesFill(),
  111. gsat[id]->getNbSatisfiedClausesSolve());
  112. if(solve) {
  113. printf(RESET);
  114. }
  115. cpt++;
  116. }
  117. //Si 1er arreter
  118. if(!this->isEnd() && solve) {
  119. this->mpiNotify(world_rank);
  120. this->end();
  121. find = true;
  122. this->setResult(
  123. true,
  124. getpid(),
  125. world_rank,
  126. id, gsat[id]->realTime() - startTime,
  127. gsat[id]->getNbIterations(),
  128. gsat[id]->getHeuristicFill(),
  129. gsat[id]->getHeuristicSolve(),
  130. gsat[id]->getNbSatisfiedClausesFill(),
  131. gsat[id]->getNbSatisfiedClausesSolve()
  132. );
  133. }
  134. }
  135. void GSATThreadMPI::mpiWait(GSATThreadMPI* gsat) {
  136. int buff;
  137. MPI_Recv(&buff, 1, MPI_INT, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  138. if(buff != world_rank) {
  139. gsat->end();
  140. }
  141. }
  142. void GSATThreadMPI::mpiNotify(int rank) {
  143. MPI_Request request;
  144. for(int i = 0; i < world_size; i++) {
  145. MPI_Isend(&rank, 1, MPI_INT, i, 0, MPI_COMM_WORLD, &request);
  146. }
  147. }
  148. void GSATThreadMPI::mpiSendResult(int rankTo) {
  149. MPI_Request request;
  150. //Envoi des infos au rank determiné
  151. MPI_Isend(&result.pid, 1, MPI_INT, rankTo, 0, MPI_COMM_WORLD, &request);
  152. MPI_Isend(&result.rank, 1, MPI_INT, rankTo, 0, MPI_COMM_WORLD, &request);
  153. MPI_Isend(&result.threadId, 1, MPI_INT, rankTo, 0, MPI_COMM_WORLD, &request);
  154. MPI_Isend(&result.calcTime, 1, MPI_DOUBLE, rankTo, 0, MPI_COMM_WORLD, &request);
  155. MPI_Isend(&result.nbIteration, 1, MPI_UNSIGNED, rankTo, 0, MPI_COMM_WORLD, &request);
  156. MPI_Isend(&result.heuristicFill, 1, MPI_UNSIGNED, rankTo, 0, MPI_COMM_WORLD, &request);
  157. MPI_Isend(&result.heuristicSolve, 1, MPI_UNSIGNED, rankTo, 0, MPI_COMM_WORLD, &request);
  158. MPI_Isend(&result.nbSatisfiedClausesFill, 1, MPI_UNSIGNED, rankTo, 0, MPI_COMM_WORLD, &request);
  159. MPI_Isend(&result.nbSatisfiedClausesSolve, 1, MPI_UNSIGNED, rankTo, 0, MPI_COMM_WORLD, &request);
  160. }