Advertisement
lOOigi

mpi

Jan 28th, 2016
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 21.68 KB | None | 0 0
  1. #include <sched.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <stdlib.h>
  7. #include <pthread.h>
  8. #include <sys/time.h>
  9. #include <time.h>
  10. #include <math.h>
  11. #include <mpi.h>
  12. #define _REENTRANT
  13.  
  14. //mpicxx -o flab4_itog flab4_itog.cpp
  15. //mpiexec -np 2 ./flab4_itog 205 (1029) 2 100
  16.  
  17. int t;
  18. int N;//размер матрицы
  19. int n_blocks;//число потоков (число блоков)
  20. int block_size;//размер блока
  21. int edging_size;//размер окаймления
  22. int M;
  23. int n; int m; int _time_;
  24. int intBuf[3];
  25.  
  26. double *A;
  27. double *B;
  28. double *X;
  29. double *b;
  30. double *x;
  31. double *A_block;
  32. double *A_ver;
  33. double *A_gor;
  34. double *A_koef;
  35. double *a_block;
  36. double *a_ver;
  37. double *a_gor;
  38. double *a_koef;
  39.  
  40. double *A2;
  41. double *B2;
  42. double *X2;
  43. double *x2;
  44.  
  45. double *A1;
  46. double *B1;
  47. double *X1;
  48.  
  49. FILE *f;
  50. struct timeval tv1, tv2;
  51. double t_posl,t_par;
  52.  
  53. //lab.c
  54. int Length;
  55. int Lambda;
  56. int Ct;
  57. int p;
  58. double material;
  59. double k1;
  60. double k2;
  61. double k3;
  62. double dt;
  63. double dx;
  64. int tLayers;
  65. int nodesNum;//число узлов
  66. int threadsNum;//число потоков (число блоков)
  67. double simulationTime;
  68. int nodesInBlock;//размер блока
  69. int edgingSize;//размер окаймления
  70. double maxT = 0;
  71. double minT = 100;
  72.  
  73.  
  74. struct arg_fwd_struct //структура для прямого хода Гаусса
  75. {
  76.    int topleft;
  77.    int downright;
  78.    int dim;
  79.    double *matr;
  80.    double *vec;
  81.    bool *result;
  82. };
  83.  
  84. struct arg_bwd_struct //структура для обратного хода Гаусса
  85. {
  86.    int topleft;
  87.    int downright;
  88.    int dim;
  89.    double *matr;
  90.    double *vec;
  91.    double *res;
  92. };
  93.  
  94. //lab.c
  95. //get variable index in matrix by node index
  96. int getIndexVar(int node){
  97.     if(node == 0)
  98.         return nodesNum  - edgingSize;
  99.     if(node == nodesNum - 1)
  100.         return nodesNum - 1;
  101.     if(node % (nodesInBlock + 1) == 0)
  102.         return nodesInBlock * threadsNum + node / (nodesInBlock + 1);
  103.     return node - 1 - (int) (node / (nodesInBlock + 1));
  104. }
  105.  
  106. //get node index by variable index from matrix
  107. int getIndexNode(int var){
  108.     if(var == 0)
  109.         return 1;
  110.     if(var < nodesInBlock * threadsNum){
  111.         return var + 1 + (int) (var / nodesInBlock);
  112.     } else {
  113.         return (nodesInBlock + 1) * (var - nodesInBlock * threadsNum);
  114.     }
  115. }
  116.  
  117. void initConditions(){
  118.     int i;
  119.     //X =  (double *) calloc(nodesNum, sizeof(double));
  120.     for(i = 0; i < nodesNum; i++)
  121.         X[i] = 0;
  122. }
  123.  
  124. void boundConditions1(int node, double T){
  125.     A[getIndexVar(node) * nodesNum + getIndexVar(node)] = 1;
  126.     B[getIndexVar(node)] = T;
  127. }
  128.  
  129. void boundConditions2(){
  130.     double dT = 50;
  131.     //////// left border
  132.     /* -->[########] */
  133.     //A[getIndexVar(0) * nodesNum + getIndexVar(0)] = (double) 1/dx;
  134.     //A[getIndexVar(0) * nodesNum + getIndexVar(1)] = -(double) 1/dx;
  135.     //B[getIndexVar(0)] = dT;
  136.  
  137.     /* <--[########]*/
  138.     /*A[getIndexVar(0) * nodesNum + getIndexVar(0)] = -(double) 1/dx;
  139.     A[getIndexVar(0) * nodesNum + getIndexVar(1)] = (double) 1/dx;
  140.     B[getIndexVar(0)] = dT;*/
  141.  
  142.     ////////right border
  143.     /* [########]<-- */
  144.     A[getIndexVar(nodesNum - 1) * nodesNum + getIndexVar(nodesNum - 1)] = (double) 1/dx;
  145.     A[getIndexVar(nodesNum - 1) * nodesNum + getIndexVar(nodesNum - 2)] = -(double) 1/dx;
  146.     B[getIndexVar(nodesNum - 1)] = dT;
  147.  
  148.     /* [########]--> */
  149.     //A[getIndexVar(nodesNum - 1) * nodesNum + getIndexVar(nodesNum - 1)] = -(double) 1/dx;
  150.     //A[getIndexVar(nodesNum - 1) * nodesNum + getIndexVar(nodesNum - 2)] = (double) 1/dx;
  151.     //B[getIndexVar(nodesNum - 1)] = dT;
  152. }
  153.  
  154. void checkMaxMin(){
  155.     int i;
  156.     for(i = 0; i < nodesNum; i++){
  157.         if(X[i] > maxT){
  158.             maxT = X[i];
  159.             continue;
  160.         }
  161.         if(X[i] < minT){
  162.             minT = X[i];
  163.             continue;
  164.         }
  165.     }
  166. }
  167.  
  168. void printToGNU(int Tag){
  169.     int i,j,t;
  170.     int node;
  171.    
  172.     if(Tag == 0) {
  173.         fprintf(f, "%s\n", "clear");
  174.         fprintf(f, "%s\n", "plot 2 with lines");
  175.         fprintf(f, "%s\n", "set size ratio -1");
  176.         fprintf(f, "%s\n", "set nokey");
  177.  
  178.         fprintf(f, "%s%d%s\n","set xrange [-1:", nodesNum,"]");
  179.         fprintf(f, "%s%d%s%d%s\n","set yrange [", -(int) nodesNum/4, ":", (int) nodesNum/2,"]");
  180.  
  181.         fprintf(f, "                                                                                                                 \n");
  182.         fprintf(f, "%s\n", "set palette defined (0 \"#6699FF\", 100 \"#FF0000\")");
  183.         return;
  184.     }
  185.  
  186.     if(Tag == 1){
  187.         fprintf(f, "%s\n", "plot \"-\" using 2:1:3 with image");
  188.         for(j = 0; j < nodesNum; j++){
  189.             for(i = 0; i < (int) (Length/(4*dx)); i++){
  190.                 fprintf(f, "%d\t%d\t%f\n", i, j, X[getIndexVar(j)]);
  191.             }
  192.         }
  193.         fprintf(f, "%s\n", "EOF");
  194.         //fprintf(f, "%s\n", "pause 0.0001");
  195.     }
  196.  
  197.     if(Tag == 2){
  198.         fseek(f, 100, SEEK_SET);
  199.         fprintf(f, "%s%f%s%f%s\n", "set cbrange [", minT , ":", maxT , "]");
  200.         return;
  201.     }
  202. }
  203.  
  204. void fillSLAU(){
  205.     int i, j;
  206.  
  207.     //memset(A, 0, sizeof(A));
  208.     for(i = 0; i < nodesNum; i++)
  209.         for(j = 0; j < nodesNum; j++)
  210.             A[i * nodesNum + j] = 0;
  211.  
  212.  
  213.     for(i = 0; i < nodesNum; i++){
  214.         if(i == 0){
  215.             boundConditions1(i, 50);
  216.             continue;
  217.         }
  218.         if(i == nodesNum - 1){
  219.             boundConditions1(i, 100);
  220.             continue;
  221.         }
  222.         /*if(i == (int) (nodesNum / 2)){
  223.             boundConditions1(i, 200);
  224.             continue;
  225.         }*/
  226.  
  227.         //insert if here to add conditions 1st type
  228.  
  229.         A[getIndexVar(i) * nodesNum + getIndexVar(i)] = k1;
  230.         A[getIndexVar(i) * nodesNum + getIndexVar(i + 1)] = k2;
  231.         A[getIndexVar(i) * nodesNum + getIndexVar(i - 1)] = k2;
  232.         B[getIndexVar(i)] = k3 * X[getIndexVar(i)];
  233.        
  234.     }
  235.     //boundConditions2();
  236. }
  237.  
  238. void prepare(){
  239.     int i;
  240.  
  241.     printf("\n");
  242.     material = (double) Lambda/(Ct * p);
  243.     printf("material koefficient = %.10f\n", material);
  244.  
  245.     //A = (double *) calloc(nodesNum*nodesNum, sizeof(double));
  246.     //B = (double *) calloc(nodesNum, sizeof(double));
  247.  
  248.     nodesInBlock = (nodesNum - 2 - (threadsNum - 1)) / threadsNum;
  249.     printf("nodes to block = %d\n", nodesInBlock);
  250.     edgingSize = nodesNum - nodesInBlock * threadsNum;
  251.     printf("edging size = %d\n", edgingSize);
  252.  
  253.     dx = (double) Length/(nodesNum - 1);
  254.     tLayers = (int) simulationTime/ dt;
  255.  
  256.     k1 = ((double) 1/dt + (double) (2*material/(dx*dx)));
  257.     k2 = - (double) material/(dx*dx);
  258.     k3 = (double) 1/dt;
  259.  
  260.     printf("dx = %f\n", dx);
  261.     printf("number of t calculations = %d\n", tLayers);
  262.     printf("k1 = %f\n", k1);
  263.     printf("k2 = %f\n", k2);
  264.     printf("k3 = %f\n", k3);
  265.  
  266.     //initConditions();
  267. }
  268. //lab.c
  269.  
  270.  
  271. void print_matrix(double *A,double *B,int N) //вывод матриц A и B
  272. {
  273.    for (int i = 0; i < N; i++)
  274.    {
  275.       for (int j = 0; j < N; j++)
  276.       printf ("%.3f\t",A[N*i+j]);
  277.       printf ("\t\t%.3f\n",B[i]);
  278.    }  
  279. }
  280.  
  281. void print_result(double *X,int N) //вывод результата X
  282. {
  283.    for (int i = 0; i < N; i++)
  284.    printf ("x[%d]=%.3f",i,X[i]);  
  285. }
  286.  
  287. void* gauss_forward(void *argument)
  288. {//метод Гаусса - прямой ход для послед. вычислений
  289.    int i, j, k;
  290.    int tl, nonzero;
  291.    double c, aa;
  292.    double *swap_row;
  293.    double swap_b;    
  294.  
  295.    arg_fwd_struct *arg = (arg_fwd_struct *)argument;
  296.  
  297.    for (tl = arg->topleft; tl < arg->downright; tl++)
  298.    {
  299.       if (!arg->matr[arg->dim*tl+tl]){
  300.          if (tl == arg->downright - 1){
  301.             *(arg->result) = false;          
  302.            pthread_exit(0);}
  303.  
  304.          for (k = tl + 1, nonzero = 0; k < arg->downright; k++)
  305.             if (arg->matr[arg->dim*k+tl]){
  306.                nonzero = k;
  307.                break;}
  308.  
  309.          if (!nonzero){
  310.             *(arg->result) = false;            
  311.             pthread_exit(0);}
  312.            
  313.          swap_row=(double *)calloc(arg->dim, sizeof(double));
  314.          for(int j=0;j<arg->dim;j++)
  315.          swap_row[j] = arg->matr[arg->dim*tl+j];                
  316.          for(int j=0;j<arg->dim;j++)
  317.          arg->matr[arg->dim*tl+j] = arg->matr[arg->dim*nonzero+j];        
  318.          for(int j=0;j<arg->dim;j++)
  319.          arg->matr[arg->dim*nonzero+j] = swap_row[j];
  320.  
  321.          swap_b = arg->vec[tl];
  322.          arg->vec[tl] = arg->vec[nonzero];
  323.          arg->vec[nonzero] = swap_b;
  324.          delete [] swap_row;        
  325.       }
  326.      
  327.       c = arg->matr[arg->dim*tl+tl];
  328.       for (j = tl; j < arg->downright; j++) arg->matr[arg->dim*tl+j] /= c;    
  329.       arg->vec[tl] /= c;
  330.  
  331.       for (i = tl + 1; i < arg->downright; i++)
  332.       {
  333.          c = arg->matr[arg->dim*i+tl];
  334.          for (j = tl; j < arg->downright; j++) arg->matr[arg->dim*i+j] -= c * arg->matr[arg->dim*tl+j];  
  335.          arg->vec[i] -= c * arg->vec[tl];
  336.       }
  337.    }
  338.    *(arg->result) = true;  
  339. }
  340.  
  341. void* gauss_backward(void *argument)
  342. { //Обратный ход метода Гаусса для послед. вычислений
  343.    int i, j;
  344.    double res1;
  345.  
  346.    arg_bwd_struct *arg = (arg_bwd_struct *)argument;
  347.  
  348.    for (i = arg->downright - 1; i >= arg->topleft; i--)
  349.    {
  350.       arg->res[i] = arg->vec[i];    
  351.       for (j = arg->downright - 1; j > i; j--)
  352.       {
  353.          res1 = arg->res[j];
  354.          arg->res[i] -= res1 * arg->matr[(arg->dim)*i+j];
  355.       }
  356.    }  
  357. }
  358.  
  359. void* gauss_forward_par()
  360. {//метод Гаусса - прямой ход для парал. вычислений
  361.  
  362.    int i, k;
  363.    int tl, nonzero;
  364.    double c, aa;
  365.    double *swap_row;
  366.    double *swap_row_v;
  367.    double swap_b;    
  368.  
  369.    for (tl = 0; tl < n; tl++)
  370.    {
  371.          if (!a_block[n*tl+tl]){
  372.          if (tl == n - 1){exit(1);}
  373.  
  374.          for (k = tl + 1, nonzero = 0; k < n; k++)
  375.             if (a_block[n*k+tl]){
  376.                nonzero = k;
  377.                break;}
  378.  
  379.          if (!nonzero){exit(1);}
  380.            
  381.          swap_row=(double *)calloc(n, sizeof(double));
  382.      swap_row_v=(double *)calloc(n, sizeof(double));
  383.          for(int j=0;j<n;j++)
  384.          swap_row[j] = a_block[n*tl+j];                
  385.          for(int j=0;j<n;j++)
  386.          a_block[n*tl+j] = a_block[n*nonzero+j];        
  387.          for(int j=0;j<n;j++)
  388.          a_block[n*nonzero+j] = swap_row[j];
  389.  
  390.          for(int j=0;j<m;j++)
  391.          swap_row_v[j] = a_ver[m*tl+j];                
  392.          for(int j=0;j<m;j++)
  393.          a_ver[m*tl+j] = a_ver[m*nonzero+j];        
  394.          for(int j=0;j<m;j++)
  395.          a_ver[m*nonzero+j] = swap_row_v[j];
  396.  
  397.          swap_b = b[tl];
  398.          b[tl] = b[nonzero];
  399.          b[nonzero] = swap_b;
  400.          delete [] swap_row;        
  401.       }
  402.      
  403.       c = a_block[n*tl+tl];
  404.       for (int j = tl; j < n; j++) a_block[n*tl+j] /= c;    
  405.       for (int j = 0; j < m; j++) a_ver[m*tl+j] /= c;      
  406.       b[tl] /= c;
  407.  
  408.       for (i = tl + 1; i < n; i++)
  409.       {
  410.          c = a_block[n*i+tl];
  411.          for (int j = tl; j < n; j++) a_block[n*i+j] -= c * a_block[n*tl+j];     
  412.          for (int j=0;j<m;j++) a_ver[m*i+j] -= c * a_ver[m*tl+j];        
  413.          b[i] -= c * b[tl];
  414.       }
  415.  
  416.       for(i=0;i<m;i++)
  417.       {
  418.     a_koef[n*i+tl] = a_gor[n*i+tl];
  419.     aa=a_gor[n*i+tl];
  420.     for (int j = tl; j < n; j++) a_gor[n*i+j] -= aa * a_block[n*tl+j];
  421.       }
  422.   }
  423. }
  424.  
  425. void* gauss_backward_par()
  426. {//Обратный ход метода Гаусса для парал. вычислений
  427.    int i;
  428.    double res1;
  429.  
  430.    for (i = n - 1; i >=0; i--)
  431.    {
  432.       x[i] = b[i];      
  433.       for (int j=0;j<m;j++)
  434.       {
  435.         res1 = x2[j];
  436.         x[i] -= a_ver[m*i+j] * res1;
  437.       }
  438.      
  439.       for (int j = n - 1; j > i; j--)
  440.       {
  441.          res1 = x[j];
  442.          x[i] -= res1 * a_block[n*i+j];
  443.       }
  444.    }
  445. }
  446.  
  447. int main (int argc, char **argv)
  448. {
  449.    
  450. int myrank;
  451. int total;
  452. MPI_Init (&argc,&argv);
  453. MPI_Comm_size (MPI_COMM_WORLD,&total);
  454. MPI_Comm_rank (MPI_COMM_WORLD,&myrank);
  455.  
  456. if (!myrank){
  457.     if (argc<4) {printf("Input Error!\n");exit(1);}
  458.    
  459. //lab.c
  460.         Length = 1;
  461.     dt = 1;
  462.     //material
  463.     p = 10000;//8900;//7800
  464.     Ct = 235;//390;//460
  465.     Lambda = 420;//390;//45
  466.     //nodesNum - threadsNum - 3 % threadsNum == 0
  467.     nodesNum = atoi(argv[1]);//151;//9;//13;
  468.     threadsNum = atoi(argv[2]);//2;//2;//4;
  469.     simulationTime = atoi(argv[3]);//100;
  470.     if((nodesNum - 2 - (threadsNum - 1)) % threadsNum != 0) {
  471.         printf("\nwrong number of nodes and threads!\n");
  472.         return 1;
  473.     }
  474.     prepare();
  475. //lab.c      
  476.    
  477.     block_size = nodesInBlock;
  478.     edging_size = edgingSize;
  479.     n_blocks = threadsNum;
  480.     M=block_size* n_blocks;
  481.     N = (block_size* n_blocks)+edging_size;
  482.  
  483.    
  484.     A=(double *)calloc(N*N, sizeof(double));
  485.     B=(double *)calloc(N, sizeof(double));
  486.     X=(double *)calloc(N, sizeof(double));
  487.     initConditions();
  488.     A1=(double *)calloc(N*N, sizeof(double));
  489.     B1=(double *)calloc(N, sizeof(double));
  490.     X1=(double *)calloc(N, sizeof(double));
  491.     A_koef=(double *)calloc(n_blocks*block_size*edging_size, sizeof(double));
  492.     A_block=(double *)calloc(n_blocks*block_size*block_size, sizeof(double));
  493.     A_ver=(double *)calloc(n_blocks*block_size*edging_size, sizeof(double));
  494.     A_gor=(double *)calloc(n_blocks*block_size*edging_size, sizeof(double));    
  495.     A2=(double *)calloc(edging_size*edging_size, sizeof(double));
  496.     B2=(double *)calloc(edging_size, sizeof(double));
  497.     X2=(double *)calloc(edging_size, sizeof(double));  
  498.  
  499.     //Заполнение intBuf
  500.     intBuf[0]=block_size;
  501.     intBuf[1]=edging_size;
  502.     intBuf[2]=tLayers;
  503.    
  504. //lab.c
  505.     f = fopen("gnu", "w");
  506.     printToGNU(0);
  507. //lab.c    
  508. }//myrank
  509.  
  510.     MPI_Bcast((void *)intBuf,3,MPI_INT,0,MPI_COMM_WORLD);
  511.     n=intBuf[0];
  512.     m=intBuf[1];
  513.     _time_=intBuf[2];
  514.    
  515. for(t = 0; t < _time_; t++){ //главный цикл  
  516.  
  517.  
  518.  if (!myrank){
  519.                  
  520.         fillSLAU(); //lab.c
  521.         //print_matrix(A,B,N);
  522.         //printf("\n");
  523.        
  524.     for (int i=0; i<N; i++){//заполнение матриц A1 и B1
  525.         for (int j=0; j<N; j++){A1[i*N+j]=A[i*N+j];}
  526.         B1[i]=B[i];
  527.     }
  528.  
  529.    //заполнение матрицы A_block
  530.     int k=0; int shift=0; int count=0;
  531.     for (int i=0; i<n_blocks*block_size;i++)
  532.     {
  533.     for (int j=0+shift; j<block_size+shift;j++)
  534.     {A_block[k]=A[N*i+j];k+=1;}
  535.     count+=1;
  536.     if (count==block_size)
  537.     {shift+=block_size;count=0;}
  538.     }
  539.      //printf("\n");
  540.      //print_result(A_block,n_blocks*block_size*block_size);
  541.  
  542.  
  543.    //заполнение матрицы A_ver
  544.     k=0;
  545.     for (int i=0; i<N-edging_size; i++){        
  546.         for (int j=N-edging_size; j<N; j++)
  547.         {A_ver[k]=A[N*i+j];k+=1;}
  548.     }
  549.      //printf("\n");
  550.      //print_result(A_ver,n_blocks*block_size*edging_size);
  551.  
  552.    //заполнение матрицы A_gor
  553.     k=0;shift=0;count=0;
  554.     for (int l=0;l<n_blocks;l++)
  555.     {
  556.     for (int i=N-edging_size; i<N;i++)
  557.     {
  558.     for (int j=0+shift; j<block_size+shift;j++)
  559.     {A_gor[k]=A[N*i+j];k+=1;}
  560.     count+=1;
  561.     if (count==edging_size)
  562.     {shift+=block_size;count=0;}
  563.     }
  564.     }
  565.      //printf("\n");
  566.      //print_result(A_gor,n_blocks*block_size*edging_size);
  567.  
  568.  
  569.  //Последовательный расчет    
  570.     arg_fwd_struct *arg_fwd_posl;
  571.     arg_fwd_posl = new arg_fwd_struct[1];
  572.     bool *status_posl;
  573.     status_posl = new bool[1];
  574.  
  575.        arg_fwd_posl[0].topleft = 0; // индекс левого верхнего угла текущего блока
  576.        arg_fwd_posl[0].downright = N;// индекс ниж. прав. угла тек. блока +1(индекс лев. верх. угла след.бл.)
  577.        arg_fwd_posl[0].dim = N;// размер всей матрицы
  578.        arg_fwd_posl[0].matr = A1;// указатель на матрицу
  579.        arg_fwd_posl[0].vec = B1;// указатель на вектор правых частей
  580.        arg_fwd_posl[0].result = &status_posl[0];// указатель на переменную, в которой будет содержаться исход прямого прохода (удача или нет)
  581. gettimeofday(&tv1, NULL);
  582.     gauss_forward((void*)&arg_fwd_posl[0]);  
  583.     X1[N-1] = B1[N-1];
  584. gettimeofday(&tv2, NULL);
  585. t_posl+=(tv2.tv_sec-tv1.tv_sec)+(tv2.tv_usec-tv1.tv_usec)/1000000.0;  
  586.     //print_matrix(A1,B1,N);    
  587.  
  588.     arg_bwd_struct *arg_bwd_posl;
  589.     arg_bwd_posl = new arg_bwd_struct[1];
  590.  
  591.       arg_bwd_posl[0].topleft = 0;
  592.       arg_bwd_posl[0].downright = N;
  593.       arg_bwd_posl[0].dim = N;
  594.       arg_bwd_posl[0].matr = A1;
  595.       arg_bwd_posl[0].vec = B1;
  596.       arg_bwd_posl[0].res = X1;
  597. gettimeofday(&tv1, NULL);  
  598.     gauss_backward((void*)&arg_bwd_posl[0]);
  599. gettimeofday(&tv2, NULL);
  600. t_posl +=(tv2.tv_sec-tv1.tv_sec)+(tv2.tv_usec-tv1.tv_usec)/1000000.0;
  601.     //printf("\n");print_result(X1,N);
  602.    delete [] arg_fwd_posl;  
  603.    delete [] arg_bwd_posl;
  604.    delete [] status_posl;
  605. //printf("\ntime_posl = %f\n",t_posl);
  606.  
  607. } //myrank
  608.    
  609.  
  610. //Параллельный расчет
  611.  
  612. /*MPI_Bcast((void *)intBuf,3,MPI_INT,0,MPI_COMM_WORLD);
  613. n=intBuf[0];
  614. m=intBuf[1];
  615. _time_=intBuf[2];*/
  616.  
  617. a_block =(double *)calloc(n*n, sizeof(double));
  618. a_ver=(double *)calloc(n*m, sizeof(double));
  619. a_gor=(double *)calloc(m*n, sizeof(double));
  620. a_koef=(double *)calloc(m*n, sizeof(double));
  621. b=(double *)calloc(n, sizeof(double));
  622. x=(double *)calloc(n, sizeof(double));
  623. x2=(double *)calloc(m, sizeof(double));
  624.  
  625. if (!myrank){gettimeofday(&tv1, NULL);}
  626.  
  627. MPI_Scatter((void *)A_block,n*n,MPI_DOUBLE,(void *)a_block,n*n,MPI_DOUBLE,0,MPI_COMM_WORLD);
  628. MPI_Scatter((void *)A_ver,n*m,MPI_DOUBLE,(void *)a_ver,n*m,MPI_DOUBLE,0,MPI_COMM_WORLD);
  629. MPI_Scatter((void *)A_gor,m*n,MPI_DOUBLE,(void *)a_gor,m*n,MPI_DOUBLE,0,MPI_COMM_WORLD);
  630. MPI_Scatter((void *)B,n,MPI_DOUBLE,(void *)b,n,MPI_DOUBLE,0,MPI_COMM_WORLD);
  631.  
  632. gauss_forward_par();
  633.  
  634. MPI_Gather((void *)a_block,n*n,MPI_DOUBLE,(void *)A_block,n*n,MPI_DOUBLE,0,MPI_COMM_WORLD);
  635. MPI_Gather((void *)a_ver,n*m,MPI_DOUBLE,(void *)A_ver,n*m,MPI_DOUBLE,0,MPI_COMM_WORLD);
  636. MPI_Gather((void *)a_gor,m*n,MPI_DOUBLE,(void *)A_gor,m*n,MPI_DOUBLE,0,MPI_COMM_WORLD);
  637. MPI_Gather((void *)b,n,MPI_DOUBLE,(void *)B,n,MPI_DOUBLE,0,MPI_COMM_WORLD);
  638. MPI_Gather((void *)a_koef,m*n,MPI_DOUBLE,(void *)A_koef,m*n,MPI_DOUBLE,0,MPI_COMM_WORLD);
  639.  
  640. if (!myrank){gettimeofday(&tv2, NULL);
  641. t_par +=(tv2.tv_sec-tv1.tv_sec)+(tv2.tv_usec-tv1.tv_usec)/1000000.0;  
  642. /*printf("\n");print_result(A_block,n_blocks*block_size*block_size);
  643.  
  644. printf("\n");print_result(A_ver,n_blocks*block_size*edging_size);
  645.  
  646. printf("\n");print_result(A_gor,n_blocks*block_size*edging_size);
  647.  
  648. printf("\n");print_result(A_koef,n_blocks*block_size*edging_size);
  649.  
  650. printf("\n");print_result(B,N);*/
  651. }//myrank
  652.  
  653. //Обработка Аnn
  654. if (!myrank){ gettimeofday(&tv1, NULL);
  655.  
  656.    //Заполняем матрицу A2 и B2
  657.    for (int i = N-edging_size; i < N; i++){
  658.     for (int k=0;k<edging_size;k++) {
  659.         A2[edging_size*(i-N+edging_size)+k]=A[N*i+(M+k)];
  660.         B2[i-N+edging_size]=B[i];
  661.     }
  662.     }
  663.    
  664.     //Преобразуем матрицу B2
  665.     for (int i = 0; i < edging_size; i++){
  666.     int shift=0; int count=0;
  667.     for (int j=0;j<M;j++)
  668.     {
  669.         B2[i] -= A_koef[block_size*i+j+shift] * B[j];
  670.         count+=1;
  671.         if (count==block_size)
  672.         {count=0; shift+=block_size*(edging_size-1);}
  673.     }
  674.     }
  675.  
  676.     //Преобразуем матрицу A2
  677.     for (int i = 0; i < edging_size; i++){
  678.     for (int k=0;k<edging_size;k++){
  679.         int shift=0; int count=0;
  680.         for (int j=0;j<M;j++)
  681.         {
  682.             A2[edging_size*i+k] -= A_koef[block_size*i+j+shift] * A_ver[edging_size*j+k];
  683.             count+=1;
  684.             if (count==block_size)
  685.             {count=0; shift+=block_size*(edging_size-1);}
  686.         }
  687.     }
  688.     }
  689.  
  690. gettimeofday(&tv2, NULL);
  691. t_par +=(tv2.tv_sec-tv1.tv_sec)+(tv2.tv_usec-tv1.tv_usec)/1000000.0;    
  692.  
  693. //Прямой ход для Ann
  694.     arg_fwd_struct *arg_fwd;
  695.     arg_fwd = new arg_fwd_struct[1];
  696.     bool *status;
  697.     status = new bool[1];
  698.  
  699.        arg_fwd[0].topleft =0;        
  700.        arg_fwd[0].downright =edging_size;      
  701.        arg_fwd[0].dim = edging_size;            
  702.        arg_fwd[0].matr = A2;          
  703.        arg_fwd[0].vec = B2;            
  704.        arg_fwd[0].result = &status[0];
  705. gettimeofday(&tv1, NULL);    
  706.     gauss_forward((void*)&arg_fwd[0]);
  707.     X2[edging_size-1] = B2[edging_size-1];
  708. gettimeofday(&tv2, NULL);
  709. t_par +=(tv2.tv_sec-tv1.tv_sec)+(tv2.tv_usec-tv1.tv_usec)/1000000.0;
  710.  
  711. //Обратный ход для Ann        
  712.     arg_bwd_struct *arg_bwd;
  713.     arg_bwd = new arg_bwd_struct[1];
  714.  
  715.       arg_bwd[0].topleft = 0;
  716.       arg_bwd[0].downright = edging_size;
  717.       arg_bwd[0].dim = edging_size;
  718.       arg_bwd[0].matr = A2;
  719.       arg_bwd[0].vec = B2;
  720.       arg_bwd[0].res = X2;
  721. gettimeofday(&tv1, NULL);  
  722.     gauss_backward((void*)&arg_bwd[0]);
  723.     for (int i=N-1,j=edging_size-1;j>=0;j--){X[i]=X2[j];i--;}
  724. gettimeofday(&tv2, NULL);
  725. t_par +=(tv2.tv_sec-tv1.tv_sec)+(tv2.tv_usec-tv1.tv_usec)/1000000.0;
  726.    delete [] arg_fwd;
  727.    delete [] arg_bwd;
  728.    delete [] status;
  729. } //myrank
  730.  
  731. if (!myrank){gettimeofday(&tv1, NULL);
  732. memcpy(x2,X2,sizeof(double)*m);}
  733.  
  734. MPI_Bcast((void *)x2,m,MPI_DOUBLE,0,MPI_COMM_WORLD);
  735. gauss_backward_par();
  736. MPI_Gather((void *)x,n,MPI_DOUBLE,(void *)X,n,MPI_DOUBLE,0,MPI_COMM_WORLD);
  737.  
  738. if (!myrank){gettimeofday(&tv2, NULL);
  739. t_par +=(tv2.tv_sec-tv1.tv_sec)+(tv2.tv_usec-tv1.tv_usec)/1000000.0;
  740. //printf("\n");    
  741. //print_result(X,N);
  742.  
  743. //lab.c
  744.         checkMaxMin();
  745.         if(maxT > 10000){
  746.             printf("errr\n");
  747.             exit(1);//return;
  748.         }
  749.  
  750.         //printNodesFromMatrix(OldResult);
  751.         if(t % (int)( _time_*0.01) == 0)
  752.             printToGNU(1);
  753.         //getchar();
  754. //lab.c
  755. }//myrank
  756. }// all end
  757.  
  758. if (!myrank){
  759. //lab.c            
  760.     printToGNU(2);
  761.     printf("max T = %f\n", maxT);
  762.     printf("min T = %f\n", minT);
  763. //lab.c                
  764. printf("\ntime_posl = %f\n",t_posl);
  765. printf("\ntime_par = %f\n",t_par);
  766. double t= t_posl/t_par;
  767. printf("speed = %f\n",t);
  768. }//myrank
  769.  
  770. if(!myrank){
  771.    delete [] X;
  772.    delete [] B;
  773.    delete [] A;
  774.    delete [] X1;
  775.    delete [] B1;
  776.    delete [] A1;
  777.    delete [] A_koef;
  778.    delete [] A_block;
  779.    delete [] A_ver;
  780.    delete [] A_gor;
  781.    delete [] a_koef;
  782.    delete [] a_block;
  783.    delete [] a_ver;
  784.    delete [] a_gor;
  785.    delete [] b;
  786.    delete [] x;
  787.    delete [] A2;
  788.    delete [] B2;
  789.    delete [] X2;
  790.    printf("\nENDL\n");  
  791.  }
  792.     MPI_Finalize();
  793.     exit(0);
  794. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement