Advertisement
Guest User

Untitled

a guest
Apr 7th, 2020
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.05 KB | None | 0 0
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<mpi.h>
  4. #include<unistd.h>
  5. #include<math.h>
  6.  
  7. double func(double x) {
  8.     return x*x;
  9. }
  10.  
  11. double integrate(double (*func)(double), double begin, double end, int num_points) {
  12.     double result = 0.0;
  13.     double step = (end - begin) / (double)num_points;
  14.     double y;
  15.     for (int i=1; i<=num_points; i++) {
  16.         y = func(begin + i * step);
  17.         result += y * step;
  18.     }
  19.     return result;
  20. }
  21.  
  22.  
  23. int main(int argc, char **argv) {
  24.     MPI_Init(NULL, NULL);
  25.  
  26.     int world_rank;
  27.     MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
  28.     int world_size;
  29.     MPI_Comm_size(MPI_COMM_WORLD, &world_size);
  30.  
  31.     int tag = 5;
  32.     int destination = world_size-1;  // destination process
  33.  
  34.     if (destination >= world_size) {
  35.         MPI_Abort(MPI_COMM_WORLD, 1); // destination process must be under the number of processes created, otherwise abort
  36.     }
  37.  
  38.     // double *partial_sums = malloc((world_size-1) * sizeof(double) );
  39.     double partial_sums[world_size-1];
  40.  
  41.     double begin = argc > 1 ? atof(argv[1]) : 0;
  42.     double end = argc > 2 ? atof(argv[2]) : 2;
  43.     int num_points = argc > 3 ? atoi(argv[3]) : 10000;
  44.  
  45.     double step = (end - begin) / num_points;
  46.  
  47.     MPI_Request request = MPI_REQUEST_NULL;
  48.     MPI_Status status;
  49.  
  50.     int additional = num_points % world_size;
  51.     int elements_number = (int)floor(num_points / world_size);
  52.  
  53.     double range_begin, partial_sum;
  54.  
  55.     if (world_rank < additional) {
  56.         range_begin = elements_number * world_rank;
  57.         elements_number++;
  58.     } else {
  59.         range_begin = (elements_number + 1) * additional + (world_rank - additional) * elements_number;
  60.     }
  61.     range_begin *= step;
  62.  
  63.     double range_end = range_begin + (elements_number * step);
  64.  
  65.     // printf("rank %d\n", world_rank);
  66.  
  67.     if (world_rank == destination) {
  68.         double result = integrate(func, range_begin, range_end, elements_number);
  69.  
  70.         // odbieramy wyniki
  71.         for (int i = 0; i < world_size; i++) {
  72.         MPI_Wait(&request, &status);
  73.  
  74.             // if(i == destination)
  75.             //     break;
  76.             partial_sum = partial_sums[i-1];
  77.  
  78.             MPI_Irecv(&partial_sum, 1, MPI_DOUBLE, i, tag, MPI_COMM_WORLD, &request);
  79.             result += partial_sum;
  80.  
  81.         }
  82.         // for (int i=0; i<world_size-1; i++)
  83.         //     MPI_Irecv(&partial_sum, 1, MPI_DOUBLE, i, tag, MPI_COMM_WORLD, &request);
  84.         // for (int i=0; i<world_size; i++) result += partial_sums[i];
  85.  
  86.         printf("Wynik całkowania funkcji y = x^2: %g\n", result);
  87.        
  88.     } else {
  89.        // obliczamy wyniki cząstkowe
  90.         partial_sums[world_rank-1] = integrate(func, range_begin, range_end, elements_number);
  91.         MPI_Isend(&partial_sums[world_rank-1], 1, MPI_DOUBLE, destination, tag, MPI_COMM_WORLD, &request);
  92.         printf("part res %g\n", partial_sums[world_rank-1]);
  93.     }
  94.  
  95.  
  96.  
  97.     // if (partial_sums != NULL) {
  98.     //     free(partial_sums);
  99.     //     partial_sums = NULL;
  100.     // }
  101.  
  102.     MPI_Finalize();
  103. }
  104.  
  105. // metoda prostokątów
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement