Advertisement
Guest User

Mx=b.c

a guest
Nov 24th, 2014
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.82 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <mpi.h>
  4.  
  5. #define N 10000
  6. #define NITER 50
  7.  
  8. /* Valor double aleatorio entre 0 y 1 */
  9. #define D01  (rand() / (double)RAND_MAX)
  10.  
  11. /* NOTA: Se trabaja con matrices almacenadas por columnas */
  12. #define M(i,j) M[(i) + (j)*n]
  13. #define Mloc(i,j) Mloc[(i) + (j)*n]
  14.  
  15. void inventa(int m, int n, double *A)
  16. {
  17.   for (m *= n; m > 0; m--)
  18.     *A++ = D01;
  19. }
  20. /* Se asume que todos los elementos son no negativos,
  21.  * lo que es cierto si se ha generado con la función inventa */
  22. double uno_norma(int m, int n, double *A)
  23. {
  24.   double max, aux;
  25.   int i;
  26.  
  27.   max = 0;
  28.   for (; n > 0; n--) {
  29.     aux = 0;
  30.     for (i = 0; i < m; i++)
  31.       aux += *A++;
  32.     if (aux > max) max = aux;
  33.   }
  34.   return max;
  35. }
  36. void escala(int m, int n, double *A, double e)
  37. {
  38.   for (m *= n; m > 0; m--)
  39.     *A++ *= e;
  40. }
  41.  
  42. /*
  43.  * (Resolución de un sistema de ecuaciones por un método iterativo)
  44.  * Dadas una matriz de iteración M de nxn y dos vectores x,v de nx1, calcular:
  45.  * Repetir num_iteraciones veces:
  46.  *   x <- M * x + v
  47.  * Al final, se tendrá en x una aproximación a la solución del sistema.
  48.  * Se desea visualizar su 1-norma.
  49.  * (La 1-norma de un vector es la suma de los valores absolutos de sus elementos)
  50.  */
  51. int main(int argc, char *argv[])
  52. {
  53.   int num_iter = NITER, semilla = 0, n = N, n2,
  54.       ncolus, ncoluscalculo, tama;
  55.   char opcion;
  56.   double t;
  57.   int yo, num_procs, proc;
  58.   double *M, *Mloc, *x, *xloc1, *xloc2, *v, norma, aux;
  59.   int i, j, iter;
  60.  
  61.   MPI_Init(&argc, &argv);
  62.   MPI_Comm_rank(MPI_COMM_WORLD, &yo);
  63.   MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
  64.  
  65.   while (argc > 1) {
  66.     argc--; argv++;
  67.     if (argv[0][0] != '-') {
  68.       opcion = '?';
  69.     } else {
  70.       opcion = *++argv[0];
  71.       if (opcion != '\0' && *++argv[0] == '\0' && argc > 1) {
  72.         argc--; argv++;
  73.       }
  74.     }
  75.     switch (opcion) {
  76.     case 's':
  77.       semilla = atoi(argv[0]);
  78.       break;
  79.     case 'n':
  80.       n = atoi(argv[0]); if (n < 0) n = N;
  81.       break;
  82.     case 'i':
  83.       num_iter = atoi(argv[0]); if (num_iter < 0) num_iter = NITER;
  84.       break;
  85.     default:
  86.       fprintf(stderr, "Uso: mxv2 [-s semilla] [-n tamanyo] [-i iteraciones]\n");
  87.       return 1;
  88.     }
  89.   }
  90.  
  91.   /* Calculamos n2, un tamaño múltiplo de num_procs en el que quepa n */
  92.   ncolus = n / num_procs;
  93.   if (num_procs * ncolus < n) ncolus++;
  94.   n2 = num_procs * ncolus;
  95.  
  96.   /* Todos los procesos almacenarán unas columnas de M (Mloc), las mismas filas
  97.    * de x de la iteración anterior (xloc1) y toda x recién calculada (xloc2)
  98.    * (cada uno tiene una parte de la x, la global se obtiene sumando todas) */
  99.   if (yo == 0)   /* El proceso 0 almacenará toda la M, toda la x y toda la v */
  100.     tama = n * n2 + n2 + n;
  101.   else
  102.     tama = 0;
  103.   tama += n * ncolus + ncolus + n; /* Mloc, xloc1, xloc2 */
  104.  
  105.   M = malloc(tama*sizeof(double));
  106.   if (M == NULL) {
  107.     fprintf(stderr, "ERROR: Falta memoria\n");
  108.     return 1;
  109.   }
  110.  
  111.   tama = n * ncolus;
  112.   if (yo == 0) {
  113.     x = M + n * n2;
  114.     v = x + n2;
  115.     Mloc = v + n;
  116.   } else {
  117.     Mloc = M;
  118.   }
  119.   xloc1 = Mloc + tama;
  120.   xloc2 = xloc1 + ncolus;
  121.  
  122.   if (yo == 0) {
  123.     srand(semilla);
  124.     inventa(n, n, M);
  125.     inventa(n, 1, v);
  126.     inventa(n, 1, x);
  127.     /* Ya que es inventado, hacer que el sistema sea convergente
  128.      * (la norma de la matriz de iteración M debe ser menor que 1) */
  129.     escala(n, n, M, 0.9 / uno_norma(n, n, M));
  130.   }
  131.  
  132.   t = MPI_Wtime();
  133.  
  134.   /* COMUNICACIONES */
  135.  
  136.     /* Para el resto, enviamos */
  137.     MPI_Scatter(M,tama,MPI_DOUBLE,Mloc,tama,MPI_DOUBLE,0,MPI_COMM_WORLD);
  138.     MPI_Scatter(x,ncolus,MPI_DOUBLE,xloc1,ncolus,MPI_DOUBLE,0,MPI_COMM_WORLD);
  139.  
  140.  
  141.   ncoluscalculo = n - yo * ncolus;
  142.   if (ncoluscalculo > ncolus)
  143.     ncoluscalculo = ncolus;
  144.  
  145.   for (iter = 1; iter <= num_iter; iter++) {
  146.     /* Calcular Mloc*xloc1 en xloc2 */
  147.     for (i = 0; i < n; i++) {
  148.       aux = 0;
  149.       for (j = 0; j < ncoluscalculo; j++)
  150.         aux += Mloc(i, j) * xloc1[j];
  151.       xloc2[i] = aux;
  152.     }
  153.  
  154.     /* COMUNICACIONES */
  155.        MPI_Reduce(xloc2,x,n,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
  156.        if (yo == 0) {
  157.         /* La xloc2 que tiene el 0 no hay que recibirla sino operar con ella */
  158.         for (i = 0; i < n; i++)
  159.         x[i] += v[i];
  160.        }
  161.        MPI_Scatter(x,ncolus,MPI_DOUBLE,xloc1,ncolus,MPI_DOUBLE,0,MPI_COMM_WORLD);
  162.  
  163.  
  164. #define ABS(a) ((a) >= 0 ? (a) : -(a))
  165.   /* Calcular la 1-norma de la parte de x que tiene cada uno (xloc1) */
  166.   norma = 0;
  167.   for (i = 0; i < ncoluscalculo; i++)
  168.     norma += ABS(xloc1[i]);
  169.  
  170.   /* COMUNICACIONES */
  171.   MPI_Reduce(&norma,&aux,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
  172.   norma = aux;
  173.  
  174.   t = MPI_Wtime() - t;
  175.  
  176.   if (yo == 0) {
  177.     printf("1-norma (%d iteraciones): %.10g\n", num_iter, norma);
  178.     printf("Tiempo con %d procesos: %.2f\n", num_procs, t);
  179.   }
  180.  
  181.   free(M);
  182.  
  183.   MPI_Finalize();
  184.  
  185.   return 0;
  186. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement