jacobi-mpi3.c
上传用户:sun780518
上传日期:2022-02-08
资源大小:2k
文件大小:6k
源码类别:

并行计算

开发平台:

C/C++

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include<stdlib.h>
  4. #include<malloc.h>
  5. #include<math.h>
  6. #include "mpi.h"
  7. double max(double a, double b) {
  8. if(a > b) return a; else return b;
  9. }
  10. int main(int argc,char *argv[]) {
  11. int myId;
  12. int numWorkers;
  13. int gridSize;
  14. int stripSize;
  15. int numIter;
  16. double maxdiff = 0.0, globalmaxdiff = 0.0;
  17. MPI_Status status;
  18. int i, j, iter;
  19. double tipmatriz, //tempo inicio preenchimento matriz
  20. tfpmatriz, //tempo final preenchimento matriz 
  21. tlpmatriz, //tempo local preenchimento matriz
  22. tgpmatriz, //tempo global preenchimento matriz 
  23. tienmatriz, //tempo inicio enviar matriz 
  24. tfenmatriz, //tempo final enviar matriz
  25. tlenmatriz, //tempo local enviar matriz
  26. tgenmatriz, //tempo global enviar matriz
  27. tirematriz, //tempo inicio receber matriz 
  28. tfrematriz, //tempo final receber matriz
  29. tlrematriz, //tempo local receber matriz
  30. tgrematriz, //tempo global receber matriz
  31. tigmatriz, //tempo inicio calcular grid
  32. tfgmatriz, //tempo final calcular grid
  33. tlgmatriz, //tempo local calcular grid
  34. tggmatriz, //tempo global calcular grid
  35. tinmatriz, //tempo inicio calcular novo
  36. tfnmatriz, //tempo final calcular novo
  37. tlnmatriz, //tempo local calcular novo
  38. tgnmatriz, //tempo global calcular novo
  39. timmatriz, //tempo inicio calcular diff
  40. tfmmatriz, //tempo final calcular diff
  41. tlmmatriz, //tempo local calcular diff
  42. tgmmatriz; //tempo global calcular diff
  43. if ((argc <= 1) || (argc != 3)) {
  44. printf("nn");
  45. printf("Jacobi Iteration Versao Sequencialn");
  46. printf("Desenvolvido por Robertino Mendes Santiago Jrn");
  47. printf("Mestrado em Ciencia da Computacaon");
  48. printf("Universidade Estadual de Maringan");
  49. printf("Maringa - Parana - Brasilnn");
  50. printf("Syntax:n");
  51. printf("jacobi-serial [gridSize] [numWorkers] [numIter]n");
  52. printf("gridSize: tamanho da matrizn");
  53. printf("numIter: numero de iteracoesnn");
  54. return 0;
  55. MPI_Init(&argc, &argv);
  56. MPI_Comm_rank(MPI_COMM_WORLD, &myId);
  57. MPI_Comm_size(MPI_COMM_WORLD, &numWorkers);
  58.    
  59. /*
  60. Pega os argumentos da linha de comando
  61. */
  62. gridSize = atoi(argv[1]);
  63. numIter = atoi(argv[2]);
  64. stripSize = gridSize/numWorkers;
  65. if (gridSize % numWorkers != 0) {
  66. printf("O tamanho do grid deve ser multiplo do numero de processos!n");
  67. MPI_Abort(MPI_COMM_WORLD, 1);
  68. return 0;
  69. }
  70.   
  71. if(myId == 0) {
  72. /*
  73.     Imprime informacoes na tela
  74.     */
  75.     printf("----------------n");
  76.     printf("Tamanho Grid.: %dn", gridSize);
  77.     printf("Trabalhadores: %dn", numWorkers);
  78.     printf("Iteracoes....: %dn", numIter);
  79.     printf("StripSize: %dn", stripSize);
  80.     printf("----------------n");
  81. }
  82. double** grid = (double **)malloc((stripSize+1) * sizeof(double *));
  83.    double** novo = (double **)malloc((stripSize+1) * sizeof(double *));
  84.    for(i=0;i< gridSize+1;i++) {
  85.       grid[i] = (double *)malloc((gridSize+1) * sizeof(double));
  86.       novo[i] = (double *)malloc((gridSize+1) * sizeof(double));
  87.     }
  88. tipmatriz = MPI_Wtime();
  89. for (i=0; i<stripSize; i++) 
  90. for (j=0; j<gridSize; j++) {
  91. grid[i][j] = 1.0;
  92. novo[i][j] = 1.0+j;
  93. }
  94. tfpmatriz = MPI_Wtime();
  95. tlpmatriz = tfpmatriz - tipmatriz;
  96. MPI_Allreduce(&tlpmatriz, &tgpmatriz, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
  97. tlenmatriz = 0.0;
  98. tlrematriz = 0.0;
  99. tlgmatriz = 0.0;
  100. tlnmatriz = 0.0;
  101. tlmmatriz = 0.0;
  102. for (iter=0; iter < (numIter/2); iter++) {
  103. if (myId < numWorkers -1) {
  104. tienmatriz = MPI_Wtime();
  105. MPI_Send(grid[stripSize], gridSize, MPI_DOUBLE, myId+1 , 0, MPI_COMM_WORLD);
  106. MPI_Send(novo[stripSize], gridSize, MPI_DOUBLE, myId+1 , 0, MPI_COMM_WORLD);
  107. tfenmatriz = MPI_Wtime();
  108. tlenmatriz += (tfenmatriz-tienmatriz);
  109. }
  110. if (myId > 0) {
  111. tirematriz = MPI_Wtime();
  112. MPI_Recv(grid[0], gridSize, MPI_DOUBLE, myId -1, 0, MPI_COMM_WORLD, &status);
  113. MPI_Recv(novo[0], gridSize, MPI_DOUBLE, myId -1, 0, MPI_COMM_WORLD, &status);
  114. tfrematriz = MPI_Wtime();
  115. tlrematriz += (tfrematriz-tirematriz);
  116. }
  117. if (myId > 0) {
  118. tienmatriz = MPI_Wtime();
  119. MPI_Send(grid[1], gridSize, MPI_DOUBLE, myId-1 , 1, MPI_COMM_WORLD);
  120. MPI_Send(novo[1], gridSize, MPI_DOUBLE, myId-1 , 1, MPI_COMM_WORLD);
  121. tfenmatriz = MPI_Wtime();
  122. tlenmatriz += (tfenmatriz-tienmatriz);
  123. }
  124. if (myId < numWorkers -1) {
  125. tienmatriz = MPI_Wtime();
  126. MPI_Recv(grid[stripSize+1], gridSize, MPI_DOUBLE, myId+1, 1, MPI_COMM_WORLD, &status);
  127. MPI_Recv(novo[stripSize+1], gridSize, MPI_DOUBLE, myId+1, 1, MPI_COMM_WORLD, &status);
  128. tfenmatriz = MPI_Wtime();
  129. tlenmatriz += (tfenmatriz-tienmatriz);
  130. }
  131. maxdiff = 0.0;
  132. tinmatriz = MPI_Wtime();
  133. for (i=1; i<stripSize-1; i++) {
  134. for (j=1; j<gridSize-1; j++) {
  135. novo[i][j] = (grid[i-1][j] + grid[i+1][j] + grid[i][j-1] + grid[i][j+1]) * 0.25;
  136. }
  137. }
  138. tfnmatriz = MPI_Wtime();
  139. tlnmatriz += (tfnmatriz-tinmatriz);
  140. tigmatriz = MPI_Wtime();
  141. for (i=1; i<stripSize-1; i++) {
  142. for (j=1; j<gridSize-1; j++) {
  143. grid[i][j] = (novo[i-1][j] + novo[i+1][j] + novo[i][j-1] + novo[i][j+1]) * 0.25;
  144. }
  145. }
  146. tfgmatriz = MPI_Wtime();
  147. tlgmatriz += (tfgmatriz-tigmatriz);
  148. timmatriz = MPI_Wtime();
  149. for (i=1; i < stripSize-1; i++) {
  150. for (j=1; j < gridSize-1; j++) {
  151. maxdiff = max(maxdiff, abs(grid[i][j] - novo[i][j]));
  152. }
  153. }
  154. tfmmatriz = MPI_Wtime();
  155. tlmmatriz += (tfmmatriz-timmatriz);
  156. MPI_Allreduce(&maxdiff, &globalmaxdiff, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
  157. MPI_Allreduce(&tlenmatriz, &tgenmatriz, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
  158. MPI_Allreduce(&tlrematriz, &tgrematriz, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
  159. MPI_Allreduce(&tlgmatriz, &tggmatriz, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
  160. MPI_Allreduce(&tlnmatriz, &tgnmatriz, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
  161. MPI_Allreduce(&tlmmatriz, &tgmmatriz, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
  162. }
  163. if (myId == 0) {
  164. printf("Maxdiff...................: [%.2f]n", globalmaxdiff);
  165. printf("Tempo preenchimento matriz: [%.2f]n", tgpmatriz);
  166. printf("Tempo enviar matriz.......: [%.2f]n", tgenmatriz);
  167. printf("Tempo receber matriz......: [%.2f]n", tgrematriz);
  168. printf("Tempo calcular grid.......: [%.2f]n", tggmatriz);
  169. printf("Tempo calcular novo.......: [%.2f]n", tgnmatriz);
  170. printf("Tempo calcular diff.......: [%.2f]n", tgmmatriz);
  171. printf("tempo:[%.2f]n ", (tgpmatriz+tgenmatriz+tgrematriz+tggmatriz+tgnmatriz+tgmmatriz));
  172. }
  173. MPI_Finalize();
  174. return 0;
  175. }