Advertisement
ridjis

multiply_no_comm

Jan 15th, 2018
342
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.95 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <mpi.h>
  4.  
  5. void Check_for_error(int local_ok, char fname[], char message[],
  6.       MPI_Comm comm);
  7. void Get_dims(int* m_p, int* local_m_p, int* n_p, int* local_n_p,
  8.       int my_rank, int comm_sz, MPI_Comm comm);
  9. void Allocate_arrays(double** local_A_pp, double** local_x_pp,
  10.       double** local_y_pp, int local_m, int n, int local_n,
  11.       MPI_Comm comm);
  12. void Read_matrix(char prompt[], double local_A[], int m, int local_m,
  13.       int n, int my_rank, MPI_Comm comm);
  14. void Read_vector(char prompt[], double local_vec[], int n, int local_n,
  15.       int my_rank, MPI_Comm comm);
  16. void Print_matrix(char title[], double local_A[], int m, int local_m,
  17.       int n, int my_rank, MPI_Comm comm);
  18. void Print_vector(char title[], double local_vec[], int n,
  19.       int local_n, int my_rank, MPI_Comm comm);
  20. void Mat_vect_mult(double local_A[], double local_x[],
  21.       double local_y[], int local_m, int n, int local_n,
  22.       MPI_Comm comm);
  23.  
  24. /*-------------------------------------------------------------------*/
  25. int main(void) {
  26.    double* local_A;
  27.    double* local_x; double* local_y;
  28.    int my_rank, comm_sz, m, local_m, n, local_n;
  29.    MPI_Comm comm;
  30.  
  31.    MPI_Init(NULL, NULL);
  32.    comm = MPI_COMM_WORLD;
  33.    MPI_Comm_size(comm, &comm_sz);
  34.    MPI_Comm_rank(comm, &my_rank);
  35.  
  36.    Get_dims(&m, &local_m, &n, &local_n, my_rank, comm_sz, comm);
  37.    Allocate_arrays(&local_A, &local_x, &local_y, local_m, n, local_n, comm);
  38.  
  39.    Read_matrix("A", local_A, m, local_m, n, my_rank, comm);
  40.    Print_matrix("A", local_A, m, local_m, n, my_rank, comm);
  41.  
  42.    Read_vector("x", local_x, n, local_n, my_rank, comm);
  43.    Print_vector("x", local_x, n, local_n, my_rank, comm);
  44.  
  45.    Mat_vect_mult(local_A, local_x, local_y, local_m, n, local_n, comm);
  46.    Print_vector("y", local_y, m, local_m, my_rank, comm);
  47.  
  48.    free(local_A); free(local_x); free(local_y);
  49.    
  50.    MPI_Finalize();
  51.    return 0;
  52. }  /* main */
  53.  
  54. void Check_for_error(
  55.       int       local_ok   /* in */,
  56.       char      fname[]    /* in */,
  57.       char      message[]  /* in */,
  58.       MPI_Comm  comm       /* in */) {
  59.    int ok;
  60.  
  61.    MPI_Allreduce(&local_ok, &ok, 1, MPI_INT, MPI_MIN, comm);
  62.    if (ok == 0) {
  63.       int my_rank;
  64.       MPI_Comm_rank(comm, &my_rank);
  65.       if (my_rank == 0) {
  66.          fprintf(stderr, "Proc %d > In %s, %s\n", my_rank, fname,
  67.                message);
  68.          fflush(stderr);
  69.       }
  70.       MPI_Finalize();
  71.       exit(-1);
  72.    }
  73. }  /* Check_for_error */
  74.  
  75. void Get_dims(
  76.       int*      m_p        /* out */,
  77.       int*      local_m_p  /* out */,
  78.       int*      n_p        /* out */,
  79.       int*      local_n_p  /* out */,
  80.       int       my_rank    /* in  */,
  81.       int       comm_sz    /* in  */,
  82.       MPI_Comm  comm       /* in  */) {
  83.    int local_ok = 1;
  84.  
  85.    if (my_rank == 0) {
  86.       printf("Enter the number of rows\n");
  87.       scanf("%d", m_p);
  88.       printf("Enter the number of columns\n");
  89.       scanf("%d", n_p);
  90.    }
  91.    MPI_Bcast(m_p, 1, MPI_INT, 0, comm);
  92.    MPI_Bcast(n_p, 1, MPI_INT, 0, comm);
  93.    if (*m_p <= 0 || *n_p <= 0 || *m_p % comm_sz != 0
  94.          || *n_p % comm_sz != 0) local_ok = 0;
  95.    Check_for_error(local_ok, "Get_dims",
  96.       "m and n must be positive and evenly divisible by comm_sz",
  97.       comm);
  98.  
  99.    *local_m_p = *m_p/comm_sz;
  100.    *local_n_p = *n_p/comm_sz;
  101. }  /* Get_dims */
  102.  
  103. void Allocate_arrays(
  104.       double**  local_A_pp  /* out */,
  105.       double**  local_x_pp  /* out */,
  106.       double**  local_y_pp  /* out */,
  107.       int       local_m     /* in  */,
  108.       int       n           /* in  */,  
  109.       int       local_n     /* in  */,
  110.       MPI_Comm  comm        /* in  */) {
  111.    int local_ok = 1;
  112.  
  113.    *local_x_pp = malloc(local_n * sizeof(double));
  114.    *local_y_pp = malloc(local_m * sizeof(double));
  115.    *local_A_pp = malloc(local_m * n * sizeof(double));
  116.  
  117.    if (*local_A_pp == NULL || local_x_pp == NULL || local_y_pp == NULL)
  118.       local_ok = 0;
  119.    Check_for_error(local_ok, "Allocate_arrays",
  120.          "Can't allocate local arrays", comm);
  121. }  /* Allocate_arrays */
  122.  
  123. void Read_matrix(
  124.       char      prompt[]   /* in  */,
  125.       double    local_A[]  /* out */,
  126.       int       m          /* in  */,
  127.       int       local_m    /* in  */,
  128.       int       n          /* in  */,
  129.       int       my_rank    /* in  */,
  130.       MPI_Comm  comm       /* in  */) {
  131.    double* A = NULL;
  132.    int local_ok = 1;
  133.  
  134.    if (my_rank == 0) {
  135.       A = malloc(m * n * sizeof(double));
  136.       if (A == NULL) local_ok = 0;
  137.       Check_for_error(local_ok, "Read_matrix",
  138.             "Can't allocate temporary matrix", comm);
  139.       printf("Enter the matrix %s\n", prompt);
  140.       for (int i = 0; i < m; i++)
  141.          for (int j = 0; j < n; j++)
  142.             scanf("%lf", &A[i*n+j]);
  143.       MPI_Scatter(A, local_m*n, MPI_DOUBLE,
  144.             local_A, local_m*n, MPI_DOUBLE, 0, comm);
  145.       free(A);
  146.    } else {
  147.       Check_for_error(local_ok, "Read_matrix",
  148.             "Can't allocate temporary matrix", comm);
  149.       MPI_Scatter(A, local_m*n, MPI_DOUBLE,
  150.             local_A, local_m*n, MPI_DOUBLE, 0, comm);
  151.    }
  152. }  /* Read_matrix */
  153.  
  154. void Read_vector(
  155.       char      prompt[]     /* in  */,
  156.       double    local_vec[]  /* out */,
  157.       int       n            /* in  */,
  158.       int       local_n      /* in  */,
  159.       int       my_rank      /* in  */,
  160.       MPI_Comm  comm         /* in  */) {
  161.    double* vec = NULL;
  162.    int local_ok = 1;
  163.  
  164.    if (my_rank == 0) {
  165.       vec = malloc(n * sizeof(double));
  166.       if (vec == NULL) local_ok = 0;
  167.       Check_for_error(local_ok, "Read_vector",
  168.             "Can't allocate temporary vector", comm);
  169.       printf("Enter the vector %s\n", prompt);
  170.       for (int i = 0; i < n; i++)
  171.          scanf("%lf", &vec[i]);
  172.       MPI_Scatter(vec, local_n, MPI_DOUBLE,
  173.             local_vec, local_n, MPI_DOUBLE, 0, comm);
  174.       free(vec);
  175.    } else {
  176.       Check_for_error(local_ok, "Read_vector",
  177.             "Can't allocate temporary vector", comm);
  178.       MPI_Scatter(vec, local_n, MPI_DOUBLE,
  179.             local_vec, local_n, MPI_DOUBLE, 0, comm);
  180.    }
  181. }  /* Read_vector */
  182.  
  183. void Print_matrix(
  184.       char      title[]    /* in */,
  185.       double    local_A[]  /* in */,
  186.       int       m          /* in */,
  187.       int       local_m    /* in */,
  188.       int       n          /* in */,
  189.       int       my_rank    /* in */,
  190.       MPI_Comm  comm       /* in */) {
  191.    double* A = NULL;
  192.    int i, j, local_ok = 1;
  193.  
  194.    if (my_rank == 0) {
  195.       A = malloc(m * n * sizeof(double));
  196.       if (A == NULL) local_ok = 0;
  197.       Check_for_error(local_ok, "Print_matrix",
  198.             "Can't allocate temporary matrix", comm);
  199.       MPI_Gather(local_A, local_m*n, MPI_DOUBLE,
  200.             A, local_m*n, MPI_DOUBLE, 0, comm);
  201.       printf("\nThe matrix %s\n", title);
  202.       for (i = 0; i < m; i++) {
  203.          for (j = 0; j < n; j++)
  204.             printf("%f ", A[i*n+j]);
  205.          printf("\n");
  206.       }
  207.       printf("\n");
  208.       free(A);
  209.    } else {
  210.       Check_for_error(local_ok, "Print_matrix",
  211.             "Can't allocate temporary matrix", comm);
  212.       MPI_Gather(local_A, local_m*n, MPI_DOUBLE,
  213.             A, local_m*n, MPI_DOUBLE, 0, comm);
  214.    }
  215. }  /* Print_matrix */
  216.  
  217. void Print_vector(
  218.       char      title[]     /* in */,
  219.       double    local_vec[] /* in */,
  220.       int       n           /* in */,
  221.       int       local_n     /* in */,
  222.       int       my_rank     /* in */,
  223.       MPI_Comm  comm        /* in */) {
  224.    double* vec = NULL;
  225.    int local_ok = 1;
  226.  
  227.    if (my_rank == 0) {
  228.       vec = malloc(n * sizeof(double));
  229.       if (vec == NULL) local_ok = 0;
  230.       Check_for_error(local_ok, "Print_vector",
  231.             "Can't allocate temporary vector", comm);
  232.       MPI_Gather(local_vec, local_n, MPI_DOUBLE,
  233.             vec, local_n, MPI_DOUBLE, 0, comm);
  234.       printf("\nThe vector %s\n", title);
  235.       for (int i = 0; i < n; i++)
  236.          printf("%f ", vec[i]);
  237.       printf("\n");
  238.       free(vec);
  239.    }  else {
  240.       Check_for_error(local_ok, "Print_vector",
  241.             "Can't allocate temporary vector", comm);
  242.       MPI_Gather(local_vec, local_n, MPI_DOUBLE,
  243.             vec, local_n, MPI_DOUBLE, 0, comm);
  244.    }
  245. }  /* Print_vector */
  246.  
  247. void Mat_vect_mult(
  248.       double    local_A[]  /* in  */,
  249.       double    local_x[]  /* in  */,
  250.       double    local_y[]  /* out */,
  251.       int       local_m    /* in  */,
  252.       int       n          /* in  */,
  253.       int       local_n    /* in  */,
  254.       MPI_Comm  comm       /* in  */) {
  255.    double* x;
  256.    int local_ok = 1;
  257.  
  258.    x = malloc(n * sizeof(double));
  259.    if (x == NULL) local_ok = 0;
  260.    Check_for_error(local_ok, "Mat_vect_mult",
  261.          "Can't allocate temporary vector", comm);
  262.    MPI_Allgather(local_x, local_n, MPI_DOUBLE,
  263.          x, local_n, MPI_DOUBLE, comm);
  264.  
  265.    for (int local_i = 0; local_i < local_m; local_i++) {
  266.       local_y[local_i] = 0.0;
  267.       for (int j = 0; j < n; j++)
  268.          local_y[local_i] += local_A[local_i*n+j] * x[j];
  269.    }
  270.    free(x);
  271. }  /* Mat_vect_mult */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement