Advertisement
Guest User

t2.c

a guest
Jun 24th, 2017
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.99 KB | None | 0 0
  1. /*
  2. * The Game of Life
  3. *
  4. * a cell is born, if it has exactly three neighbours
  5. * a cell dies of loneliness, if it has less than two neighbours
  6. * a cell dies of overcrowding, if it has more than three neighbours
  7. * a cell survives to the next generation, if it does not die of loneliness
  8. * or overcrowding
  9. *
  10. * In this version, a 2D array of ints is used.  A 1 cell is on, a 0 cell is off.
  11. * The game plays a number of steps (given by the input), printing to the screen each time.  'x' printed
  12. * means on, space means off.
  13. *
  14. */
  15. #include <pthread.h>
  16. #include <semaphore.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <time.h>
  20. #include <sys/sysinfo.h>
  21. #include <unistd.h>
  22. #include <mpi.h>
  23.  
  24. typedef unsigned char cell_t;
  25. int rank, world_size;
  26. void master();
  27.  
  28. /* ------------------------------------------------------------------------- */
  29.  
  30. cell_t ** allocate_board (int size) {
  31.   cell_t ** board = (cell_t **) malloc(sizeof(cell_t*)*size);
  32.   int   i;
  33.   for (i=0; i<size; i++)
  34.   board[i] = (cell_t *) malloc(sizeof(cell_t)*size);
  35.   return board;
  36. }
  37.  
  38. /* ------------------------------------------------------------------------- */
  39.  
  40. void free_board (cell_t ** board, int size) {
  41.   int     i;
  42.   for (i=0; i<size; i++)
  43.   free(board[i]);
  44.   free(board);
  45. }
  46.  
  47. /* ------------------------------------------------------------------------- */
  48.  
  49. /* return the number of on cells adjacent to the i,j cell */
  50. inline int adjacent_to (cell_t ** board, int size, int i, int j) {
  51.   int count = 0;
  52.   count+=board[i-1][j-1];
  53.   count+=board[i-1][j];
  54.   count+=board[i-1][j+1];
  55.   count+=board[i][j-1];
  56.   count+=board[i][j+1];
  57.   count+=board[i+1][j-1];
  58.   count+=board[i+1][j];
  59.   count+=board[i+1][j+1];
  60.   return count;
  61. }
  62.  
  63. cell_t ** board;
  64. cell_t ** newboard;
  65. sem_t *producer_sem1;
  66. sem_t *producer_sem2;
  67. sem_t *consumer_sem;
  68.  
  69. /* ------------------------------------------------------------------------- */
  70.  
  71. void *play() {
  72.   int i, j, a;
  73.   int play_args[2];
  74.   MPI_Recv(&play_args[0], 2, MPI_INT, 0, 20, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  75.   //int thread_number = *((int *) args);
  76.   //int size = ((int*)args)[1];
  77.   //int steps = ((int*)args)[2];
  78.   //int nprocess = ((int*)args)[3];
  79.   int size = play_args[0];
  80.   int steps = play_args[1];
  81.   cell_t** b = board;
  82.   cell_t** nb = newboard;
  83.   sem_t *temp = producer_sem1;
  84.   /* for each cell, apply the rules of Life */
  85.   int maxi = (int)(size/(double)(world_size-1)*(rank));
  86.   int mini = (int)(size/(double)(world_size-1)*(rank-1));
  87.   //printf("start: %d finish: %d size: %d\n", mini, maxi, size);
  88.   for (int k=0; k<steps; k++) {
  89.     sem_wait(temp);
  90.     b = board;
  91.     nb = newboard;
  92.     for (i = mini+1; i<maxi+1; ++i) {
  93.       for (j= 1; j<size+1; j++) {
  94.         a = adjacent_to(b, size, i, j);
  95.         if (a == 2) {
  96.           nb[i][j] = b[i][j];
  97.         } else if (a == 3) {
  98.           nb[i][j] = 1 ;
  99.         } else {
  100.           nb[i][j] = 0;
  101.         }
  102.       }
  103.     }
  104.     if (temp == producer_sem2){
  105.       temp = producer_sem1;
  106.     } else {
  107.       temp = producer_sem2;
  108.     }
  109.     sem_post(consumer_sem);
  110.   }
  111. }
  112.  
  113. /* ------------------------------------------------------------------------- */
  114.  
  115. /* print the life board */
  116. void print (cell_t ** board, int size) {
  117.   int   i, j;
  118.   /* for each row */
  119.   for (j=1; j<size+1; j++) {
  120.     /* print each column position... */
  121.     for (i=1; i<size+1; i++)
  122.       if(board[i][j]){
  123.           printf ("■ ");
  124.       } else {
  125.         printf ("  ");
  126.       }
  127.     /* followed by a carriage return */
  128.     printf ("\n");
  129.   }
  130. }
  131.  
  132. /* ------------------------------------------------------------------------- */
  133.  
  134. /* read a file into the life board */
  135. void read_file (FILE * f, cell_t ** board, int size) {
  136.   int   i, j;
  137.   char  *s = (char *) malloc(size+10);
  138.  
  139.   /* read the first new line (it will be ignored) */
  140.   fgets (s, size+10,f);
  141.  
  142.   /* read the life board */
  143.   for (j=0; j<size; j++) {
  144.     /* get a string */
  145.     fgets (s, size+10,f);
  146.     /* copy the string to the life board */
  147.     for (i=0; i<size; i++)
  148.     board[i+1][j+1] = s[i] == 'x';
  149.  
  150.   }
  151. }
  152.  
  153. /* ------------------------------------------------------------------------- */
  154.  
  155. void fill_board(cell_t ** board, int size, int percentage_alive) {
  156.   int   i, j;
  157.   srand(time(NULL));
  158.   for (j=1; j<size+1; j++) {
  159.     for (i=1; i<size+1; i++){
  160.         board[i][j] = ((int)(rand()) %percentage_alive == 0? 1 : 0 );
  161.     }
  162.   }
  163. }
  164.  
  165. /* ------------------------------------------------------------------------- */
  166.  
  167. int main(int argc, char**argv){
  168. int size, steps;
  169.   //if (argc<2 || atoi(argv[1])){
  170.     FILE    *f;
  171.     f = stdin;
  172.     fscanf(f,"%d %d", &size, &steps);
  173.     board = allocate_board (size+2);
  174.     read_file (f, board,size);
  175.     fclose(f);
  176.     newboard = allocate_board (size+2);
  177.   /*} else {
  178.     steps = 1000;
  179.     size = 1000;
  180.     board = allocate_board (size+2);
  181.     newboard = allocate_board (size+2);
  182.     fill_board(board, size, 32);
  183.   }
  184.   /**/
  185.   sem_t p_sem1;
  186.   sem_t p_sem2;
  187.   sem_t* prod_sem = &p_sem2;
  188.   sem_t c_sem;
  189.   cell_t ** tmp;
  190.   int i;
  191.   #ifdef DEBUG
  192.     printf("Initial:\n");
  193.     print(board,size);
  194.   #endif
  195.    printf ("You have %d processors.\n", get_nprocs());
  196.   int nprocess = atoi (argv[1]);
  197.   sem_init(&p_sem1, 0, nprocess);
  198.   sem_init(&p_sem2, 0, 0);
  199.   sem_init(&c_sem, 0, 0);
  200.   producer_sem1 = &p_sem1;
  201.   producer_sem2 = &p_sem2;
  202.   consumer_sem = &c_sem;
  203.   MPI_Init(&argc, &argv);
  204.   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  205.   MPI_Comm_size(MPI_COMM_WORLD, &world_size);
  206.   if(rank==0){  // master
  207.       master(size, steps);
  208.   // for (int j = 0; j<nprocess; j++){
  209.   //   int *i = malloc(sizeof(*i)*4);
  210.   //   i[0] = j;  // worker rank
  211.   //   i[1] = size;  // keep
  212.   //   i[2] = steps;  // keep
  213.   //   i[3] = nprocess;  // world_size
  214.   //   pthread_create(&threads[j], NULL, play, (void *)i);
  215.   // }
  216.     for (i=0; i<steps; i++) {
  217.       for (int j = 0; j<nprocess; j++){
  218.         sem_wait(consumer_sem);
  219.       }
  220.       #ifdef DEBUG
  221.         printf("%d ----------\n", i + 1);
  222.         print (newboard,size);
  223.       #endif
  224.       tmp = newboard;
  225.       newboard = board;
  226.       board = tmp;
  227.       for (int j = 0; j<nprocess; j++){
  228.         sem_post(prod_sem);
  229.       }
  230.       if (prod_sem == producer_sem2){
  231.         prod_sem = producer_sem1;
  232.       } else {
  233.         prod_sem = producer_sem2;
  234.       }
  235.     }
  236.  
  237.     #ifdef RESULT
  238.       printf("Final:\n");
  239.       print (board,size);
  240.     #endif
  241.  
  242.     free_board(newboard,size);
  243.     free_board(board,size);
  244.  
  245.   } else {
  246.     play();
  247.   }
  248.   MPI_Barrier(MPI_COMM_WORLD);
  249.   MPI_Finalize();
  250. }
  251.  
  252. /* ------------------------------------------------------------------------- */
  253.  
  254. void master(int boardsize, int steps) {
  255.   int process;
  256.   double play_args[2];
  257.   MPI_Request req;
  258.   //play_args[0] = 0; // rank, adjust
  259.   play_args[0] = boardsize; // boardsize, keep
  260.   play_args[1] = steps; // steps, keep
  261.   //play_args[3] = 0; // world_size, adjust
  262.  
  263.  
  264.   for (process = 1; process < world_size; process++) {
  265.       MPI_Isend(&play_args[0], 2, MPI_INT, process, 20, MPI_COMM_WORLD, &req);
  266.   }
  267. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement