Advertisement
Guest User

Untitled

a guest
May 10th, 2023
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.28 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, int sizeX, int sizeY) {
  12. for (int i = 0; i < sizeX; i++) {
  13. for (int j = 0; j < sizeY; j++) {
  14. printf("%d ", matrix[i * sizeX + 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, int sizeX, int sizeY) {
  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 + sizeX) % sizeX;
  42. int neighbor_col = (j + sizeY) % sizeY;
  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 * sizeX + 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 = (int *)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. int size_x_small = SIZE_X;
  149. int size_y_small = height;
  150.  
  151. for (int iter = 0; iter < MAX_ITERATIONS; iter++) {
  152. all_states[iter] = curr_state;
  153. all_states[iter+1] = (int *) malloc(send_counts[rank] * sizeof(int));
  154.  
  155. MPI_Request send_top, receive_bottom, send_bottom, receive_top;
  156.  
  157. MPI_Isend(&all_states[iter][0], size_x_small, MPI_INT, (rank + size - 1) % size, 1, MPI_COMM_WORLD, &send_top);
  158. MPI_Isend(&all_states[iter][send_counts[rank] - size_x_small], size_x_small, MPI_INT, (rank + 1) % size, 2, MPI_COMM_WORLD, &send_bottom);
  159. MPI_Irecv(bottom_line, size_x_small, MPI_INT, (rank + 1 ) % size, 1, MPI_COMM_WORLD, &receive_bottom);
  160. MPI_Irecv(top_line, size_x_small, MPI_INT, (rank - 1 + size) % size, 2, MPI_COMM_WORLD, &receive_top);
  161. for (int i = 1; i < size_y_small - 1; i++) {
  162. for (int j = 0; j < size_x_small; j++) {
  163. int neighbors = count_neighbors(all_states[iter], i, j, size_x_small, size_y_small);
  164.  
  165. if (all_states[iter][i* size_x_small + j] == 1 && (neighbors < 2 || neighbors > 3)) {
  166. all_states[iter+1][i * size_x_small + j] = false;
  167. }
  168. else if (all_states[iter][i * size_x_small + j] == 0 && neighbors == 3) {
  169. all_states[iter+1][i * size_x_small + j] = true;
  170. }
  171. else {
  172. all_states[iter+1][i * size_x_small + j] = all_states[iter][i * size_x_small + j];
  173. }
  174. }
  175. }
  176.  
  177. MPI_Wait(&send_top, MPI_STATUS_IGNORE);
  178. MPI_Wait(&receive_top, MPI_STATUS_IGNORE);
  179. for(size_t i = 0; i < size_x_small; i++){
  180. int neighbors = count_top_neighbors(all_states[iter], top_line, 0, (int)i);
  181.  
  182. if (all_states[iter][ i] == 1 && (neighbors < 2 || neighbors > 3)) {
  183. all_states[iter+1][ i] = false;
  184. }
  185. else if (all_states[iter][i] == 0 && neighbors == 3) {
  186. all_states[iter+1][i] = true;
  187. }
  188. else {
  189. all_states[iter+1][i] = all_states[iter][i];
  190. }
  191. }
  192.  
  193. MPI_Wait(&send_bottom, MPI_STATUS_IGNORE);
  194. MPI_Wait(&receive_bottom, MPI_STATUS_IGNORE);
  195.  
  196. for(size_t i = 0; i < size_x_small; i++){
  197. int neighbors = count_bottom_neighbors(all_states[iter], bottom_line, size_y_small-1, (int)i);
  198.  
  199. if (all_states[iter][(size_y_small-1)* SIZE_X + i] == 1 && (neighbors < 2 || neighbors > 3)) {
  200. all_states[iter+1][(size_y_small-1) * SIZE_X + i] = false;
  201. }
  202. else if (all_states[iter][(size_y_small-1) * SIZE_X + i] == 0 && neighbors == 3) {
  203. all_states[iter+1][(size_y_small-1) * SIZE_X + i] = true;
  204. }
  205. else {
  206. all_states[iter+1][(size_y_small-1) * SIZE_X + i] = all_states[iter][(size_y_small-1) * SIZE_X + i];
  207. }
  208. }
  209.  
  210. for (int back_step = iter; back_step >= 0; back_step--)
  211. {
  212. flags[back_step] = 1;
  213. for (int i = 0; i < SIZE_X; i++)
  214. {
  215. for (int j = 0; j < size_y_small; j++)
  216. {
  217. if (curr_state[i * SIZE_X + j] != all_states[back_step][i * SIZE_X + j])
  218. {
  219. flags[back_step] = 0;
  220. break;
  221. }
  222. }
  223. if (flags[back_step] == 0)
  224. break;
  225. }
  226. }
  227.  
  228. MPI_Allreduce(MPI_IN_PLACE, flags, MAX_ITERATIONS, MPI_INT, MPI_LAND, MPI_COMM_WORLD);
  229.  
  230. int check = 0;
  231. for (int i = 0; i < iter; i++){
  232. if (flags[i] == 1){
  233. check = 1;
  234. break;
  235. }
  236. }
  237.  
  238. if (check == 1){
  239. printf("SOLVED %d \n", iter);
  240. break;
  241. }
  242.  
  243. curr_state = all_states[iter+1];
  244. }
  245.  
  246.  
  247. if(rank == 0){
  248. for(size_t i = 0; i < size; i++){
  249. printf("%zu %d %d\n", i, displs[i], send_counts[i]);
  250. }
  251.  
  252. }
  253.  
  254. for (int i = 0; i < MAX_ITERATIONS; ++i) {
  255. if (all_states[i] != NULL)
  256. free(all_states[i]);
  257. }
  258.  
  259. free(all_states);
  260. free(curr_state);
  261.  
  262. MPI_Finalize();
  263. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement