Advertisement
ridjis

mat_vect

Jan 15th, 2018
266
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.44 KB | None | 0 0
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<mpi.h>
  4.  
  5. void get_dims(int *m_p, int *n_p, int *local_m_p, int my_rank, int comm_sz, MPI_Comm comm);
  6. void allocate(double **local_A_pp, double **v_pp, double **local_r_pp, int m, int local_m, int n, MPI_Comm comm);
  7. void read_matrix(double local_A[], int m, int local_m, int n, int my_rank, MPI_Comm comm);
  8. void read_vector(double v[], int n, int my_rank, MPI_Comm comm);
  9. void print_matrix(double local_A[], int m, int local_m, int n, int my_rank, MPI_Comm comm);
  10. void print_vector(double v[], int n, int my_rank);
  11. void gather_and_print_vector(double local_r[], int local_m, int m, int my_rank, MPI_Comm comm);
  12. void multiply(double local_A[], double v[], double local_r[], int local_m, int n, int my_rank);
  13.  
  14. int main(void) {
  15.     int comm_sz, my_rank, m, n, local_m;
  16.     double* local_A;
  17.     double* v; double* local_r;
  18.     MPI_Comm comm;
  19.  
  20.     MPI_Init(NULL, NULL);
  21.     comm = MPI_COMM_WORLD;
  22.     MPI_Comm_size(comm, &comm_sz);
  23.     MPI_Comm_rank(comm, &my_rank);
  24.  
  25.     get_dims(&m, &n, &local_m, my_rank, comm_sz, comm);
  26.     allocate(&local_A, &v, &local_r, m, local_m, n, comm);
  27.    
  28.     read_matrix(local_A, m, local_m, n, my_rank, comm);
  29.     print_matrix(local_A, m, local_m, n, my_rank, comm);
  30.  
  31.     read_vector(v, n, my_rank, comm);
  32.     print_vector(v, n, my_rank);
  33.  
  34.     multiply(local_A, v, local_r, local_m, n, my_rank);
  35.     gather_and_print_vector(local_r, local_m, m, my_rank, comm);
  36.  
  37.     free(local_A); free(v); free(local_r);
  38.     MPI_Finalize();
  39.  
  40.     return 0;
  41. }
  42.  
  43. void get_dims(int *m_p, int *n_p, int *local_m_p, int my_rank, int comm_sz, MPI_Comm comm) {
  44.     if (my_rank == 0) {
  45.         printf("Unesite broj redova - m: \n");
  46.         scanf("%d", m_p);
  47.         printf("Unesite broj kolona - n: \n");
  48.         scanf("%d", n_p);
  49.  
  50.         if (*m_p <= 0 || *n_p <= 0 || *m_p % comm_sz != 0) {
  51.             fprintf(stderr, "Proc %d > In %s, %s\n", my_rank, "get_dims", "input invalid.");
  52.             fflush(stderr);
  53.             MPI_Finalize();
  54.             exit(-1);
  55.         }
  56.     }
  57.     MPI_Bcast(m_p, 1, MPI_INT, 0, comm);
  58.     MPI_Bcast(n_p, 1, MPI_INT, 0, comm);
  59.  
  60.     *local_m_p = *m_p / comm_sz;
  61. }
  62.  
  63. void allocate(double **local_A_pp, double **v_pp, double **local_r_pp, int m, int local_m, int n, MPI_Comm comm) {
  64.     *v_pp       = calloc(n, sizeof(double));
  65.     *local_r_pp = calloc(local_m, sizeof(double));
  66.     *local_A_pp = calloc(local_m * n, sizeof(double));
  67. }
  68.  
  69. void read_matrix(double local_A[], int m, int local_m, int n, int my_rank, MPI_Comm comm) {
  70.     double* A = NULL;
  71.     if (my_rank == 0) {
  72.         A = calloc(m * n, sizeof(double));
  73.         printf("Enter the matrix:\n");
  74.         for (int i = 0; i < m; i++)
  75.             for (int j = 0; j < n; j++)
  76.                 scanf("%lf", &A[i*n+j]);
  77.        
  78.         MPI_Scatter(A, local_m*n, MPI_DOUBLE, local_A, local_m*n, MPI_DOUBLE, 0, comm);
  79.         free(A);
  80.     } else {
  81.         MPI_Scatter(A, local_m*n, MPI_DOUBLE, local_A, local_m*n, MPI_DOUBLE, 0, comm);
  82.     }
  83. }
  84.  
  85. void print_matrix(double local_A[], int m, int local_m, int n, int my_rank, MPI_Comm comm) {
  86.     double* A = NULL;
  87.     if (my_rank == 0) {
  88.         A = calloc(m * n, sizeof(double));
  89.         MPI_Gather(local_A, local_m*n, MPI_DOUBLE, A, local_m*n, MPI_DOUBLE, 0, comm);
  90.         printf("\nThe matrix:\n");
  91.         for (int i = 0; i < m; i++) {
  92.             for (int j = 0; j < n; j++) {
  93.                 printf("%.2lf ", A[i*n+j]);
  94.             }
  95.             printf("\n");
  96.         }
  97.         printf("\n");
  98.         free(A);
  99.     } else {
  100.         MPI_Gather(local_A, local_m*n, MPI_DOUBLE, A, local_m*n, MPI_DOUBLE, 0, comm);
  101.     }
  102. }
  103.  
  104. void read_vector(double v[], int n, int my_rank, MPI_Comm comm) {
  105.     if (my_rank == 0) {
  106.         printf("Enter the vector:\n");
  107.         for (int i = 0; i < n; i++)
  108.             scanf("%lf", &v[i]);
  109.     }
  110.     MPI_Bcast(v, n, MPI_DOUBLE, 0, comm);
  111. }
  112.  
  113. void print_vector(double v[], int n, int my_rank) {
  114.     if (my_rank == 0) {
  115.         printf("\nVector: [ ");
  116.         for (int i = 0; i < n; i++)
  117.             printf("%.2lf ", v[i]);
  118.        
  119.         printf("]\n");
  120.     }
  121. }
  122.  
  123. void gather_and_print_vector(double local_r[], int local_m, int m, int my_rank, MPI_Comm comm) {
  124.     double* r = NULL;
  125.     if (my_rank == 0) {
  126.         r = calloc(m, sizeof(double));
  127.         MPI_Gather(local_r, local_m, MPI_DOUBLE, r, local_m, MPI_DOUBLE, 0, comm);
  128.  
  129.         printf("\nVector: [ ");
  130.         for (int i = 0; i < m; i++)
  131.             printf("%.2lf ", r[i]);
  132.        
  133.         printf("]\n");
  134.  
  135.         free(r);
  136.     } else {
  137.         MPI_Gather(local_r, local_m, MPI_DOUBLE, r, local_m, MPI_DOUBLE, 0, comm);
  138.     }
  139. }
  140.  
  141. void multiply(double local_A[], double v[], double local_r[], int local_m, int n, int my_rank) {
  142.     for (int local_i = 0; local_i < local_m; local_i++) {
  143.         local_r[local_i] = 0;
  144.         for (int j = 0; j < n; j++) {
  145.             local_r[local_i] += local_A[local_i*n+j] * v[j];
  146.         }
  147.     }
  148. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement