fork download
  1. #include<stdio.h>
  2. #include<mpi.h>
  3. #include<stdlib.h>
  4. #include<math.h>
  5. #define N 8
  6. #define MASTER 0
  7. #define DEFAULT_TAG 0
  8.  
  9. //za N = 8 program se startuje za 16 procesa
  10. //za N = 4 program se startuje za 4 procesa
  11.  
  12. void printMatrix(int* mat, int rows, int cols, const char* msg);
  13. void printVector(int arr[], int len, const char* msg);
  14.  
  15. int main(int argc, char** argv) {
  16. int rank, size;
  17.  
  18. MPI_Init(&argc, &argv);
  19. MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  20. MPI_Comm_size(MPI_COMM_WORLD, &size);
  21.  
  22. int a[N][N], b[N], c[N];
  23. const int q = (int)sqrt(size), // q predstavlja red velicine matrice procesa
  24. l = N / q,// l predstavlja broj redova u podmatrici A kao i broj elemenata podvektora B
  25. k = q + 1; // k predstavlja broj kolona u podmatrici A
  26.  
  27. int* locA = calloc(l * k, sizeof(int)),
  28. * locB = calloc(l, sizeof(int)),
  29. * tmp = calloc(l, sizeof(int)),
  30. * rowsTmp = calloc(l, sizeof(int));
  31.  
  32. MPI_Datatype submatrixType;
  33. MPI_Type_vector(l, k, N, MPI_INT, &submatrixType);
  34. MPI_Type_commit(&submatrixType);
  35.  
  36. if (rank == MASTER) {
  37. int cnt = 0;
  38. for (int i = 0; i < N; i++) {
  39. b[i] = i;
  40. for (int j = 0; j < N; j++)
  41. a[i][j] = cnt++;
  42. }
  43.  
  44. printMatrix(&a[0][0], N, N, "\nMatrica A:\n");
  45. printVector(b, N, "Vektor B: ");
  46.  
  47. int proc = 0;
  48. for (int i = 0; i < q; i++)
  49. for (int j = 0; j < q; j++) {
  50. if (proc == MASTER) {
  51. for (int i = 0; i < l; i++)
  52. for (int j = 0; j < k; j++)
  53. locA[i * k + j] = a[i][j];
  54. proc++;
  55. }
  56. else
  57. MPI_Send(&a[i * l][j], 1, submatrixType, proc++, DEFAULT_TAG, MPI_COMM_WORLD);
  58. }
  59. }
  60. else
  61. MPI_Recv(locA, l * k, MPI_INT, MASTER, DEFAULT_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  62.  
  63. MPI_Datatype subvectorType, resizedSubvectorType;
  64. MPI_Type_vector(l, 1, q, MPI_INT, &subvectorType);
  65. MPI_Type_create_resized(subvectorType, 0, 1 * sizeof(int), &resizedSubvectorType);
  66. MPI_Type_commit(&resizedSubvectorType);
  67.  
  68. MPI_Comm rowsComm, colsComm;
  69. MPI_Comm_split(MPI_COMM_WORLD, rank / q, rank % q, &rowsComm);
  70. MPI_Comm_split(MPI_COMM_WORLD, rank % q, rank / q, &colsComm);
  71.  
  72. int rowsRank, colsRank;
  73. MPI_Comm_rank(rowsComm, &rowsRank);
  74. MPI_Comm_rank(colsComm, &colsRank);
  75.  
  76. if (colsRank == MASTER)
  77. MPI_Scatter(&b, 1, resizedSubvectorType, locB, l, MPI_INT, MASTER, rowsComm);
  78. MPI_Bcast(locB, l, MPI_INT, MASTER, colsComm);
  79.  
  80. struct {
  81. int val;
  82. int rank;
  83. } locMin = { INT32_MAX, rank }, min = { INT32_MAX, -1 };
  84.  
  85. for (int i = 0; i < l; i++)
  86. for (int j = 0; j < k; j++)
  87. if (locMin.val > locA[i * k + j])
  88. locMin.val = locA[i * k + j];
  89.  
  90. MPI_Reduce(&locMin, &min, 1, MPI_2INT, MPI_MINLOC, MASTER, MPI_COMM_WORLD);
  91. MPI_Bcast(&min, 1, MPI_2INT, MASTER, MPI_COMM_WORLD);
  92.  
  93. //Mnoze se samo elementi nulte i poslednje kolone iz locA sa elementima iz locB
  94. for (int i = 0; i < l; i++)
  95. for (int j = 0; j < l; j++) {
  96. tmp[i] += locA[i * k + j * (k - 1)] * locB[j]; //Nacrtaj si
  97. }
  98.  
  99. //U nultoj koloni matrice procesa su svi medjurezultati
  100. MPI_Reduce(tmp, rowsTmp, l, MPI_INT, MPI_SUM, MASTER, rowsComm);
  101. //skupljamo u master proces nulte kolone koji je i globalni.
  102. if (rowsRank == MASTER)
  103. MPI_Gather(rowsTmp, l, MPI_INT, &c[0], l, MPI_INT, min.rank, colsComm);
  104.  
  105. printf("\n[Process %d]-----------------------\n", rank);
  106. printMatrix(locA, l, k, "locA:\n");
  107. printVector(locB, l, "locB: ");
  108.  
  109. if (rank == min.rank) {
  110. printf("Ja, proces %d, sadrzim najmanji element matrice A.\n", rank);
  111. printVector(c, N, "Rezultujuci vektor C: ");
  112. }
  113.  
  114. free(locA);
  115. free(locB);
  116. free(tmp);
  117. free(rowsTmp);
  118.  
  119. MPI_Finalize();
  120. return 0;
  121. }
  122.  
  123. void printMatrix(int* mat, int rows, int cols, const char* msg) {
  124. msg&& printf(msg);
  125.  
  126. for (int i = 0; i < rows; i++) {
  127. for (int j = 0; j < cols; j++)
  128. printf("%d\t", mat[i * cols + j]);
  129. printf("\n");
  130. }
  131. }
  132.  
  133. void printVector(int arr[], int len, const char* msg) {
  134. msg&& printf(msg);
  135.  
  136. printf("[");
  137. for (int i = 0; i < len; i++)
  138. printf(i < len - 1 ? "%d, " : "%d]", arr[i]);
  139. printf("\n");
  140. }
  141.  
  142.  
Success #stdin #stdout #stderr 0.25s 40232KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
Error: unexpected '/' in "/"
Execution halted