#include #include #include #include #include #include "Main.hpp" #include "GSATHybride.hpp" #include "color.h" extern int world_rank; extern int world_size; /* --- Public --- */ GSATThreadMPI::GSATThreadMPI(int _nbThread, int argc, char** argv) { nbThread = _nbThread; gsat = std::vector(_nbThread); threads = std::vector(_nbThread); for(int i = 0; i < _nbThread; i++) { gsat[i] = new GSAT(); gsat[i]->setParameters(argc,argv); gsat[i]->initialize(); } srand(getpid()); } GSATThreadMPI::~GSATThreadMPI() { for(int i = 0; i < nbThread; i++) { delete gsat[i]; } } bool GSATThreadMPI::solve() { threads.clear(); this->end(false); find = false; //Lance thread for(int i = 0; i < nbThread; i++) { threads[i] = std::thread(&GSATThreadMPI::solverThread, this, i); } //Lance thread de synchronisation MPI mpiSync = std::thread(&GSATThreadMPI::mpiWait, this, this); //Attend resultat for(int i = 0; i < nbThread; i++){ threads[i].join(); } mpiSync.join(); //Si c'est le proc qui à trouvé if(find) { this->mpiSendResult(DISPLAY_RANK); } return find; } void GSATThreadMPI::end() { this->end(true); } void GSATThreadMPI::end(bool endOrNot) { std::lock_guard guard(mEnd); bEnd = endOrNot; } bool GSATThreadMPI::isEnd() { std::lock_guard guard(mEnd); return bEnd; } void GSATThreadMPI::printResult() { printf(GREEN); printf("s %s\n",find?"SATISFIABLE":"NOT FOUND"); printf(YELLOW); printf("c real time : %.4f seconds\n", result.calcTime); printf("c [pid:%6d][process:%2d][thread:%2d][iteration:%4d][fill:%d][heuristic:%d]Satisfied clauses (begin: %d)(end:%d)\n", result.pid, result.rank, result.threadId, result.nbIteration, result.heuristicFill, result.heuristicSolve, result.nbSatisfiedClausesFill, result.nbSatisfiedClausesSolve); printf(RESET); fflush(stdout); } 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) { find = isFind; result.pid = pid; result.rank = rank; result.threadId = thread; result.calcTime = time; result.nbIteration = nbIte; result.heuristicFill = heuriFill; result.heuristicSolve = heuriSolve; result.nbSatisfiedClausesFill = satisfFill; result.nbSatisfiedClausesSolve = satisfSolve; } /* --- Private --- */ void GSATThreadMPI::solverThread(int id) { //Resolution double startTime = gsat[id]->realTime(); bool solve = false; int cpt = 0; while(!this->isEnd() && !solve){ //Pour eviter que les processeurs effectue tous les meme calculs int fill = rand() % 4 + 2; int h = rand() % 7; solve = gsat[id]->start(fill, h); if(solve) { printf(CYAN); } printf("c [pid:%6d][process:%2d][thread:%2d][iteration:%4d][fill:%d][heuristic:%d]Satisfied clauses (begin: %d)(end:%d)\n", getpid(), world_rank, id, gsat[id]->getNbIterations(), gsat[id]->getHeuristicFill(), gsat[id]->getHeuristicSolve(), gsat[id]->getNbSatisfiedClausesFill(), gsat[id]->getNbSatisfiedClausesSolve()); if(solve) { printf(RESET); } cpt++; } //Si 1er arreter if(!this->isEnd() && solve) { this->mpiNotify(world_rank); this->end(); find = true; this->setResult( true, getpid(), world_rank, id, gsat[id]->realTime() - startTime, gsat[id]->getNbIterations(), gsat[id]->getHeuristicFill(), gsat[id]->getHeuristicSolve(), gsat[id]->getNbSatisfiedClausesFill(), gsat[id]->getNbSatisfiedClausesSolve() ); } } void GSATThreadMPI::mpiWait(GSATThreadMPI* gsat) { int buff; MPI_Recv(&buff, 1, MPI_INT, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); if(buff != world_rank) { gsat->end(); } } void GSATThreadMPI::mpiNotify(int rank) { MPI_Request request; for(int i = 0; i < world_size; i++) { MPI_Isend(&rank, 1, MPI_INT, i, 0, MPI_COMM_WORLD, &request); } } void GSATThreadMPI::mpiSendResult(int rankTo) { MPI_Request request; //Envoi des infos au rank determiné MPI_Isend(&result.pid, 1, MPI_INT, rankTo, 0, MPI_COMM_WORLD, &request); MPI_Isend(&result.rank, 1, MPI_INT, rankTo, 0, MPI_COMM_WORLD, &request); MPI_Isend(&result.threadId, 1, MPI_INT, rankTo, 0, MPI_COMM_WORLD, &request); MPI_Isend(&result.calcTime, 1, MPI_DOUBLE, rankTo, 0, MPI_COMM_WORLD, &request); MPI_Isend(&result.nbIteration, 1, MPI_UNSIGNED, rankTo, 0, MPI_COMM_WORLD, &request); MPI_Isend(&result.heuristicFill, 1, MPI_UNSIGNED, rankTo, 0, MPI_COMM_WORLD, &request); MPI_Isend(&result.heuristicSolve, 1, MPI_UNSIGNED, rankTo, 0, MPI_COMM_WORLD, &request); MPI_Isend(&result.nbSatisfiedClausesFill, 1, MPI_UNSIGNED, rankTo, 0, MPI_COMM_WORLD, &request); MPI_Isend(&result.nbSatisfiedClausesSolve, 1, MPI_UNSIGNED, rankTo, 0, MPI_COMM_WORLD, &request); }