Commit 75d7679e authored by Gaurav Kukreja's avatar Gaurav Kukreja

Parallel-Minimax Working Code

Signed-off-by: 's avatarGaurav Kukreja <mailme.gaurav@gmail.com>
parent 44c58013
This diff is collapsed.
...@@ -21,6 +21,12 @@ ...@@ -21,6 +21,12 @@
#include "eval.h" #include "eval.h"
#include "network.h" #include "network.h"
#define pretty_print(name, val) printf("%s = %d: %s: %s: %d\n", name, val, __FILE__,__FUNCTION__,__LINE__);
int thread_rank;
int num_threads;
/* Global, static vars */ /* Global, static vars */
NetworkLoop l; NetworkLoop l;
...@@ -47,7 +53,7 @@ char* host = 0; /* not used on default */ ...@@ -47,7 +53,7 @@ char* host = 0; /* not used on default */
int rport = 23412; int rport = 23412;
/* local channel */ /* local channel */
int lport = 23412; int lport = 13375;
/* change evaluation after move? */ /* change evaluation after move? */
bool changeEval = true; bool changeEval = true;
...@@ -83,6 +89,11 @@ void MyDomain::sendBoard() ...@@ -83,6 +89,11 @@ void MyDomain::sendBoard()
void MyDomain::received(char* str) void MyDomain::received(char* str)
{ {
for(int i=1;i<num_threads;i++)
MPI_Send (str, 1024, MPI_CHAR, i, 10,
MPI_COMM_WORLD);
if (strncmp(str, "quit", 4)==0) { if (strncmp(str, "quit", 4)==0) {
l.exit(); l.exit();
return; return;
...@@ -265,17 +276,14 @@ void parseArgs(int argc, char* argv[]) ...@@ -265,17 +276,14 @@ void parseArgs(int argc, char* argv[])
int strength = atoi(argv[arg]); int strength = atoi(argv[arg]);
if (strength == 0) { if (strength == 0) {
printf("ERROR - Unknown option %s\n", argv[arg]); printf("ERROR - Unknown option %s\n", argv[arg]);
printHelp(argv[0], false); printHelp(argv[0], false);
} }
maxDepth = strength; maxDepth = strength;
} }
} }
int thread_rank;
int num_threads;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
...@@ -284,9 +292,15 @@ int main(int argc, char* argv[]) ...@@ -284,9 +292,15 @@ int main(int argc, char* argv[])
MPI_Comm_size(MPI_COMM_WORLD, &num_threads); MPI_Comm_size(MPI_COMM_WORLD, &num_threads);
MPI_Comm_rank(MPI_COMM_WORLD, &thread_rank); MPI_Comm_rank(MPI_COMM_WORLD, &thread_rank);
if(thread_rank == 0) parseArgs(argc, argv);
parseArgs(argc, argv); #if 0
if(thread_rank < 4)
myColor = Board::color1;
else {
myColor = Board::color2;
thread_rank = thread_rank - 4;
}
#endif
SearchStrategy* ss = SearchStrategy::create(strategyNo); SearchStrategy* ss = SearchStrategy::create(strategyNo);
if (verbose) if (verbose)
printf("Using strategy '%s' ...\n", ss->name()); printf("Using strategy '%s' ...\n", ss->name());
...@@ -296,12 +310,115 @@ int main(int argc, char* argv[]) ...@@ -296,12 +310,115 @@ int main(int argc, char* argv[])
ss->setEvaluator(&ev); ss->setEvaluator(&ev);
ss->registerCallbacks(new SearchCallbacks(verbose)); ss->registerCallbacks(new SearchCallbacks(verbose));
MyDomain d(lport); if(thread_rank == 0) {
if (host) d.addConnection(host, rport);
l.install(&d); MyDomain d(lport);
l.run(); if (host) d.addConnection(host, rport);
l.install(&d);
l.run();
}
else
{
bool exit_loop = false;
while(!exit_loop)
{
char state_str[1024];
MPI_Status mpi_st;
pretty_print("thread_rank", thread_rank);
MPI_Recv (state_str, 1024, MPI_CHAR, 0, 10, MPI_COMM_WORLD, &mpi_st);
pretty_print("thread_rank", thread_rank);
if (strncmp(state_str, "quit", 4)==0) {
l.exit();
return 0;
}
if (strncmp(state_str, "pos ", 4)!=0) return 0;
b.setState(state_str+4);
if (verbose) {
printf("\n\n==========================================\n");
printf(state_str+4);
}
int state = b.validState();
if ((state == Board::empty))
continue;
if ((state != Board::valid1) &&
(state != Board::valid2)) {
printf("%s\n", Board::stateDescription(state));
switch(state) {
case Board::timeout1:
case Board::timeout2:
case Board::win1:
case Board::win2:
// l.exit();
exit_loop = true;
default:
break;
}
return 0;
}
if (b.actColor() & myColor) {
struct timeval t1, t2;
gettimeofday(&t1,0);
Move m = b.bestMove();
gettimeofday(&t2,0);
int msecsPassed =
(1000* t2.tv_sec + t2.tv_usec / 1000) -
(1000* t1.tv_sec + t1.tv_usec / 1000);
printf("%s ", (myColor == Board::color1) ? "O":"X");
if (m.type == Move::none) {
printf(" can not draw any move ?! Sorry.\n");
return 0;
}
printf("draws '%s' (after %d.%03d secs)...\n",
m.name(), msecsPassed/1000, msecsPassed%1000);
b.playMove(m, msecsPassed);
// sendBoard();
if (changeEval)
ev.changeEvaluation();
/* stop player at win position */
int state = b.validState();
if ((state != Board::valid1) &&
(state != Board::valid2)) {
printf("%s\n", Board::stateDescription(state));
switch(state) {
case Board::timeout1:
case Board::timeout2:
case Board::win1:
case Board::win2:
// l.exit();
exit_loop = true;
default:
break;
}
}
maxMoves--;
if (maxMoves == 0) {
printf("Terminating because given number of moves drawn.\n");
// broadcast("quit\n");
// l.exit();
exit_loop = true;
}
}
pretty_print("*********** Exit_loop", exit_loop);
}
}
MPI_Finalize(); MPI_Finalize();
} }
...@@ -45,7 +45,7 @@ static int msecsToPlay[3] = {0,0,0}; ...@@ -45,7 +45,7 @@ static int msecsToPlay[3] = {0,0,0};
/* to set verbosity of NetworkLoop implementation */ /* to set verbosity of NetworkLoop implementation */
extern int verbose; extern int verbose;
#define DEFAULT_DOMAIN_PORT 23412 #define DEFAULT_DOMAIN_PORT 13375
#define DEFAULT_DOMAIN_DIFF 50 #define DEFAULT_DOMAIN_DIFF 50
/* remote channel */ /* remote channel */
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#define likely(x) __builtin_expect((x),1) #define likely(x) __builtin_expect((x),1)
#define unlikely(x) __builtin_expect((x),0) #define unlikely(x) __builtin_expect((x),0)
extern int maxDepth;
extern int thread_rank; extern int thread_rank;
extern int num_threads; extern int num_threads;
...@@ -54,7 +56,7 @@ class MinimaxStrategy: public SearchStrategy ...@@ -54,7 +56,7 @@ class MinimaxStrategy: public SearchStrategy
}; };
int current_depth=0; int current_depth=0;
#define MAX_DEPTH 3 #define MAX_DEPTH maxDepth
int MinimaxStrategy::minimax() int MinimaxStrategy::minimax()
{ {
...@@ -121,65 +123,77 @@ int MinimaxStrategy::minimax() ...@@ -121,65 +123,77 @@ int MinimaxStrategy::minimax()
} }
bestEval = sign*bestEval; bestEval = sign*bestEval;
// if(thread_rank==0) if(current_depth == 0)
// {
Move *moves=NULL;
int *eval_results;
moves=(Move*)malloc((num_threads -1)*sizeof(Move));
eval_results=(int*)malloc((num_threads - 1)*sizeof(int));
// }
//all threads send value to thread 0
MPI_Gather (&_bestMove, sizeof(Move), MPI_BYTE,
moves, sizeof(Move), MPI_BYTE, 0, MPI_COMM_WORLD);
MPI_Gather (&bestEval, 1, MPI_INT,
eval_results, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
if(thread_rank == 0)
{ {
for(i=0;i<num_threads-1;i++) if(thread_rank==0)
{ {
if(sign*eval_results[i] > sign*bestEval) Move *moves=NULL;
int *eval_results;
moves=(Move*)malloc((num_threads -1)*sizeof(Move));
eval_results=(int*)malloc((num_threads - 1)*sizeof(int));
//all threads send value to thread 0
for(int i=1;i<num_threads;i++)
{ {
bestEval = eval_results[i]; MPI_Status status;
bestestMove=moves[i]; MPI_Recv((void*)&moves[i-1], sizeof(Move), MPI_BYTE, i, 10,
MPI_COMM_WORLD, &status);
MPI_Recv(&eval_results[i-1], 1, MPI_INT, i, 10,
MPI_COMM_WORLD, &status);
} }
}
}
MPI_Barrier(MPI_COMM_WORLD); bestestMove=_bestMove;
for(int i=0;i<num_threads-1;i++)
MPI_Bcast (&bestestMove, sizeof(Move), MPI_BYTE, 0, {
MPI_COMM_WORLD); if(sign*eval_results[i] > sign*bestEval)
MPI_Bcast (&bestEval, 1, MPI_INT, 0, {
MPI_COMM_WORLD); bestEval = eval_results[i];
bestestMove=moves[i];
MPI_Barrier(MPI_COMM_WORLD); }
}
foundBestMove(0, bestestMove, bestEval); for(int i=1;i<num_threads;i++)
{
MPI_Send (&bestestMove, sizeof(Move), MPI_BYTE, i, 10,
MPI_COMM_WORLD);
MPI_Send (&bestEval, 1, MPI_INT, i, 10,
MPI_COMM_WORLD);
}
if(current_depth == 0) }
else
{
MPI_Send (&_bestMove, sizeof(Move), MPI_BYTE, 0, 10,
MPI_COMM_WORLD);
MPI_Send (&bestEval, 1, MPI_INT, 0, 10,
MPI_COMM_WORLD);
MPI_Status status;
MPI_Recv(&bestestMove, sizeof(Move), MPI_BYTE, 0, 10,
MPI_COMM_WORLD, &status);
MPI_Recv(&bestEval, 1, MPI_INT, 0, 10,
MPI_COMM_WORLD, &status);
}
foundBestMove(0, bestestMove, bestEval);
finishedNode(0,0); finishedNode(0,0);
}
return bestEval; return bestEval;
} }
void MinimaxStrategy::searchBestMove() void MinimaxStrategy::searchBestMove()
{ {
// KUKU : Here we have to implement the minimax strategy // KUKU : Here we have to implement the minimax strategy
// Minimax strategy tries to minimize the maximum possible outcome of opponent. // Minimax strategy tries to minimize the maximum possible outcome of opponent.
// At each turn, we check for each move the max positive outcome for opponent. // At each turn, we check for each move the max positive outcome for opponent.
// We choose the move for which the max is least. // We choose the move for which the max is least.
// To check this, we look at more than one levels in the Game Tree. // To check this, we look at more than one levels in the Game Tree.
// we try to maximize bestEvaluation // we try to maximize bestEvaluation
/* int bestEval = minEvaluation(); /* int bestEval = minEvaluation();
int eval; int eval;
Move m; Move m;
MoveList list; MoveList list;
// generate list of allowed moves, put them into <list> // generate list of allowed moves, put them into <list>
generateMoves(list); generateMoves(list);
...@@ -187,19 +201,19 @@ void MinimaxStrategy::searchBestMove() ...@@ -187,19 +201,19 @@ void MinimaxStrategy::searchBestMove()
// loop over all moves // loop over all moves
while(list.getNext(m)) { while(list.getNext(m)) {
// draw move, evalute, and restore position // draw move, evalute, and restore position
playMove(m); playMove(m);
eval = evaluate(); eval = evaluate();
takeBack(); takeBack();
if (eval > bestEval) { if (eval > bestEval) {
bestEval = eval; bestEval = eval;
foundBestMove(0, m, eval); foundBestMove(0, m, eval);
} }
} }
finishedNode(0,0); finishedNode(0,0);
*/ */
minimax(); minimax();
} }
......
...@@ -29,7 +29,7 @@ static int secsToPlay = -1; ...@@ -29,7 +29,7 @@ static int secsToPlay = -1;
/* to set verbosity of NetworkLoop implementation */ /* to set verbosity of NetworkLoop implementation */
extern int verbose; extern int verbose;
#define DEFAULT_DOMAIN_PORT 23412 #define DEFAULT_DOMAIN_PORT 13375
/* remote channel */ /* remote channel */
static char* host = 0; /* not used on default */ static char* host = 0; /* not used on default */
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment