/* par.ex8.36.c SJ */ /* 31) Write a "game" where all processes generate a random number 0..9, compare the numbers, and the one(s) with largest number is (are) the winner(s). After someone has 5 wins, all quit. Here, if there are several processes with the same number, all get the winning point. Hint: MPI_Allreduce, MPI_MAX. 36) Modify the game of exercise 31 solving draws by new numbers. Only those processes that had the largest number will generate a new numbers, and if there was a sole winner, it wins. If even the new numbers generated a draw, the procedure is repeated among remaining processing until the winner if found. */ #include #include #include #include /* maximum number */ #ifndef NMAX #define NMAX 4 #endif /* number of rounds */ #ifndef WINS #define WINS 3 #endif /* how much to print */ #ifndef PRINT #define PRINT 2 #endif static int P, PID; /* used in prints in fucntins */ int playround(MPI_Comm comm); int main(int argc, char **argv) { int wins = 0, maxwins, round = 0; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &PID); MPI_Comm_size(MPI_COMM_WORLD, &P); srand(getpid()); do { round++; wins += playround(MPI_COMM_WORLD); /* find maximum of wins */ MPI_Allreduce(&wins, &maxwins, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD); if (PRINT && !PID) { printf("After round %d: maximum: %d wins\n", round, maxwins); } fflush(stdout); MPI_Barrier(MPI_COMM_WORLD); } while (maxwins < WINS); MPI_Finalize(); exit(0); } int playround(MPI_Comm comm) { int num, max, mebest, numbests; MPI_Comm newcomm; /* get a number */ num = rand()%NMAX; if (PRINT > 1) printf("%d gets %d\n", PID, num); /* find maximum */ MPI_Allreduce(&num, &max, 1, MPI_INT, MPI_MAX, comm); /* check for draws */ /* did I possibly win */ if (num == max) mebest = 1; else mebest = 0; MPI_Allreduce(&mebest, &numbests, 1, MPI_INT, MPI_SUM, comm); if (numbests == 1) { if (PRINT && mebest) printf("%d wins by %d\n", PID, num); return mebest; } else { /* regame, just best participate in new group */ MPI_Comm_split(comm, mebest, 0, &newcomm); if (mebest) { if (PRINT) printf("%d has draw %d (%d same)\n", PID, num, numbests); mebest = playround(newcomm); } MPI_Comm_free(&newcomm); } return mebest; } /* playround() */