123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- #include <iostream>
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <mpi.h>
- #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<GSAT*>(_nbThread);
- threads = std::vector<std::thread>(_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<std::mutex> guard(mEnd);
- bEnd = endOrNot;
- }
- bool GSATThreadMPI::isEnd() {
- std::lock_guard<std::mutex> 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);
- }
|