Advertisement
Guest User

Untitled

a guest
May 10th, 2023
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.95 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <stdbool.h>
  5. #include "mpi/mpi.h"
  6.  
  7. #define SIZE_X 10
  8. #define SIZE_Y 15
  9. #define MAX_ITERATIONS 10
  10.  
  11. void print_state(int *matrix) {
  12.     for (int i = 0; i < SIZE_X; i++) {
  13.         for (int j = 0; j < SIZE_Y; j++) {
  14.             printf("%d ", matrix[i * SIZE_X + j]);
  15.         }
  16.         printf("\n");
  17.     }
  18.     printf("\n");
  19. }
  20.  
  21. void generate_glider(int *cur_state) {//Making first state called "Glider"
  22.     for (int i = 0; i < SIZE_X * SIZE_Y; i++) {
  23.         cur_state[i] = 0;
  24.     }
  25.  
  26.     cur_state[0 * SIZE_X + 1] = true;
  27.     cur_state[1 * SIZE_X + 2] = true;
  28.     cur_state[2 * SIZE_X + 0] = true;
  29.     cur_state[2 * SIZE_X + 1] = true;
  30.     cur_state[2 * SIZE_X + 2] = true;
  31. }
  32.  
  33. int count_neighbors(const int *board, int row, int col) {
  34.     int count = 0;
  35.  
  36.     // Iterate through all the neighbors
  37.     for (int i = row-1; i <= row+1; i++) {
  38.         for (int j = col-1; j <= col+1; j++) {
  39.             // Calculate the row and column indices of the current neighbor,
  40.             // taking into account the toroidal nature of the grid
  41.             int neighbor_row = (i + SIZE_X) % SIZE_X;
  42.             int neighbor_col = (j + SIZE_Y) % SIZE_Y;
  43.  
  44.             // Check if the current neighbor is not the same as the given cell
  45.             if (!(neighbor_row == row && neighbor_col == col)) {
  46.                 // If the neighbor is alive, increment the count
  47.                 if (board[neighbor_row * SIZE_X + neighbor_col] == 1) {
  48.                     count++;
  49.                 }
  50.             }
  51.         }
  52.     }
  53.  
  54.     return count;
  55. }
  56.  
  57. int count_top_neighbors(const int *board, const int *top, int row, int col) {
  58.     int count = 0;
  59.     int top_row = (row - 1 + SIZE_X) % SIZE_X;
  60.  
  61.     // Iterate through all the neighbors
  62.     for (int i = top_row; i <= row+1; i++) {
  63.         for (int j = col-1; j <= col+1; j++) {
  64.             // Calculate the row and column indices of the current neighbor,
  65.             // taking into account the toroidal nature of the grid
  66.             int neighbor_row = (i + SIZE_X) % SIZE_X;
  67.             int neighbor_col = (j + SIZE_Y) % SIZE_Y;
  68.  
  69.             // Check if the current neighbor is not the same as the given cell
  70.             if (!(neighbor_row == row && neighbor_col == col)) {
  71.                 // If the neighbor is alive, increment the count
  72.                 if (i == top_row) {
  73.                     if (top[neighbor_col] == 1) {
  74.                         count++;
  75.                     }
  76.                 } else if (board[neighbor_row * SIZE_X + neighbor_col] == 1) {
  77.                     count++;
  78.                 }
  79.             }
  80.         }
  81.     }
  82.  
  83.     return count;
  84. }
  85.  
  86. int count_bottom_neighbors(const int *board, const int *bottom, int row, int col) {
  87.     int count = 0;
  88.     int bottom_row = (row + 1) % SIZE_X;
  89.  
  90.     // Iterate through all the neighbors
  91.     for (int i = row-1; i <= bottom_row; i++) {
  92.         for (int j = col-1; j <= col+1; j++) {
  93.             // Calculate the row and column indices of the current neighbor,
  94.             // taking into account the toroidal nature of the grid
  95.             int neighbor_row = (i + SIZE_X) % SIZE_X;
  96.             int neighbor_col = (j + SIZE_Y) % SIZE_Y;
  97.  
  98.             // Check if the current neighbor is not the same as the given cell
  99.             if (!(neighbor_row == row && neighbor_col == col)) {
  100.                 // If the neighbor is alive, increment the count
  101.                 if (i == bottom_row) {
  102.                     if (bottom[neighbor_col] == 1) {
  103.                         count++;
  104.                     }
  105.                 } else if (board[neighbor_row * SIZE_X + neighbor_col] == 1) {
  106.                     count++;
  107.                 }
  108.             }
  109.         }
  110.     }
  111.  
  112.     return count;
  113. }
  114.  
  115. int main() {
  116.     int rank, size;
  117.     MPI_Init(NULL, NULL);
  118.     MPI_Comm_size(MPI_COMM_WORLD, &size);
  119.     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  120.     int** all_states = (int**)malloc(MAX_ITERATIONS * sizeof(int*));
  121.     int* flags = (int*)malloc(MAX_ITERATIONS * sizeof(int));
  122.     int* initial_state = (int*)malloc(SIZE_X * SIZE_Y * sizeof(int));
  123.  
  124.  
  125.     int rows_per_proc = SIZE_X / size;
  126.     int remaining_rows = SIZE_X % size;
  127.     int* send_counts = (int*)malloc(size * sizeof(int));
  128.     int* displs = (int*)malloc(size * sizeof(int));
  129.  
  130.     int offset = 0;
  131.     for (int i = 0; i < size; i++) {
  132.         send_counts[i] = rows_per_proc * SIZE_Y;
  133.         if (remaining_rows > 0) {
  134.             send_counts[i] += SIZE_Y; // add an extra row to the first few processes
  135.             remaining_rows--;
  136.         }
  137.         displs[i] = offset;
  138.         offset += send_counts[i];
  139.     }
  140.  
  141.     int *curr_state = malloc(send_counts[rank] * sizeof(int));
  142.  
  143.     MPI_Scatterv(initial_state, send_counts, displs, MPI_INT, curr_state, send_counts[rank], MPI_INT, 0, MPI_COMM_WORLD);
  144.     int* top_line = (int*)malloc(SIZE_Y * sizeof(int));
  145.     int* bottom_line = (int*)malloc(SIZE_Y * sizeof(int));
  146.     int height = send_counts[rank] / SIZE_X;
  147.  
  148.     for (int iter = 0; iter < MAX_ITERATIONS; iter++) {
  149.         all_states[iter] = curr_state;
  150.         all_states[iter+1] = (int *) malloc(SIZE_X * SIZE_Y * sizeof(int));
  151.  
  152.         MPI_Request send_top, receive_bottom, send_bottom, receive_top;
  153.  
  154.         MPI_Isend(&all_states[iter][0], SIZE_Y, MPI_INT, (rank + size - 1) % size, 1, MPI_COMM_WORLD, &send_top);
  155.         MPI_Isend(&all_states[iter][SIZE_Y * (SIZE_X - 1)], SIZE_Y, MPI_INT, (rank + 1) % size, 2, MPI_COMM_WORLD, &send_bottom);
  156.         MPI_Irecv(bottom_line, SIZE_Y, MPI_INT, (rank + 1 ) % size, 1, MPI_COMM_WORLD, &receive_bottom);
  157.         MPI_Irecv(top_line, SIZE_Y, MPI_INT, (rank - 1 + size) % size, 2, MPI_COMM_WORLD, &receive_top);
  158.         for (int i = 1; i < height - 1; i++) {
  159.             for (int j = 0; j < SIZE_Y; j++) {
  160.                 int neighbors = count_neighbors(all_states[iter], i, j);
  161.  
  162.                 if (all_states[iter][i* SIZE_X + j] == 1 && (neighbors < 2 || neighbors > 3)) {
  163.                     all_states[iter+1][i * SIZE_X + j] = false;
  164.                 }
  165.                 else if (all_states[iter][i * SIZE_X + j] == 0 && neighbors == 3) {
  166.                     all_states[iter+1][i * SIZE_X + j] = true;
  167.                 }
  168.                 else {
  169.                     all_states[iter+1][i * SIZE_X + j] = all_states[iter][i * SIZE_X + j];
  170.                 }
  171.             }
  172.         }
  173.  
  174.         MPI_Wait(&send_top, MPI_STATUS_IGNORE);
  175.         MPI_Wait(&receive_top, MPI_STATUS_IGNORE);
  176.         for(size_t i = 0; i < SIZE_Y; i++){
  177.             int neighbors = count_top_neighbors(all_states[iter], top_line, 0, (int)i);
  178.  
  179.             if (all_states[iter][0* SIZE_X + i] == 1 && (neighbors < 2 || neighbors > 3)) {
  180.                 all_states[iter+1][0 * SIZE_X + i] = false;
  181.             }
  182.             else if (all_states[iter][0 * SIZE_X + i] == 0 && neighbors == 3) {
  183.                 all_states[iter+1][0 * SIZE_X + i] = true;
  184.             }
  185.             else {
  186.                 all_states[iter+1][0 * SIZE_X + i] = all_states[iter][0 * SIZE_X + i];
  187.             }
  188.         }
  189.  
  190.         MPI_Wait(&send_bottom, MPI_STATUS_IGNORE);
  191.         MPI_Wait(&receive_bottom, MPI_STATUS_IGNORE);
  192.  
  193.         for(size_t i = 0; i < SIZE_Y; i++){
  194.             int neighbors = count_bottom_neighbors(all_states[iter], bottom_line, SIZE_Y-1, (int)i);
  195.  
  196.             if (all_states[iter][(SIZE_Y-1)* SIZE_X + i] == 1 && (neighbors < 2 || neighbors > 3)) {
  197.                 all_states[iter+1][(SIZE_Y-1) * SIZE_X + i] = false;
  198.             }
  199.             else if (all_states[iter][(SIZE_Y-1) * SIZE_X + i] == 0 && neighbors == 3) {
  200.                 all_states[iter+1][(SIZE_Y-1) * SIZE_X + i] = true;
  201.             }
  202.             else {
  203.                 all_states[iter+1][(SIZE_Y-1) * SIZE_X + i] = all_states[iter][(SIZE_Y-1) * SIZE_X + i];
  204.             }
  205.         }
  206.  
  207.         for (int back_step = iter; back_step >= 0; back_step--)
  208.         {
  209.             flags[back_step] = 1;
  210.             for (int i = 0; i < SIZE_X; i++)
  211.             {
  212.                 for (int j = 0; j < SIZE_Y; j++)
  213.                 {
  214.                     if (curr_state[i * SIZE_X + j] != all_states[back_step][i * SIZE_X + j])
  215.                     {
  216.                         flags[back_step] = 0;
  217.                         break;
  218.                     }
  219.                 }
  220.                 if (flags[back_step] == 0)
  221.                     break;
  222.             }
  223.         }
  224.  
  225.         MPI_Allreduce(MPI_IN_PLACE, flags, MAX_ITERATIONS, MPI_INT, MPI_LAND, MPI_COMM_WORLD);
  226.  
  227.         int check = 0;
  228.         for (int i = 0; i < iter; i++){
  229.             if (flags[i] == 1){
  230.                 check = 1;
  231.                 break;
  232.             }
  233.         }
  234.  
  235.         if (check == 1){
  236.             printf("SOLVED %d \n", iter);
  237.             break;
  238.         }
  239.  
  240.         curr_state = all_states[iter+1];
  241.     }
  242.  
  243.  
  244.     if(rank == 0){
  245.         for(size_t i = 0; i < size; i++){
  246.             printf("%zu %d %d\n", i, displs[i], send_counts[i]);
  247.         }
  248.  
  249.     }
  250.  
  251.     free(all_states);
  252.     free(curr_state);
  253.    
  254.     MPI_Finalize();
  255. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement