SHARE
TWEET

Untitled

a guest Feb 27th, 2020 97 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <iostream>
  2. #include <mpi.h>
  3. #include <cmath>
  4.  
  5. // Global variables to store the rank of the process and the size
  6. // of the communicator
  7. int rank, size;
  8.  
  9. // Number of points on one side. The total number of points
  10. // will be p_count*p_count.
  11. constexpr int p_count = 512;
  12.  
  13. // Other global variables. We read them from the command line
  14. // this will be handled by the script running on tech.io, don't
  15. // mind this part.
  16. // The cutoff variable indicates when we decide the series does not converge
  17. // The other variable are just used to center the view and zoom level.
  18. int cutoff;
  19. double min_x, max_x, min_y, max_y, dx, dy;
  20.  
  21. // The modulus of a complex number
  22. double modulus(double x, double y) {
  23.   return sqrt(x*x + y*y);
  24. }
  25.  
  26. // Multiplying a complex number by itself
  27. void self_mul(double &x, double &y) {
  28.   double ox = x*x - y*y;
  29.   double oy = x*y + y*x;
  30.   x = ox;
  31.   y = oy;
  32. }
  33.  
  34. // Computation of the number of iterations on a set of points
  35. // The result is stored in mset.
  36. void compute_mandelbrot(double *points, int npts, int mset[]) {
  37.   // For each point
  38.   for (int i=0; i < npts; ++i) {
  39.     double px, py;
  40.     px = points[i*2];
  41.     py = points[i*2+1];
  42.  
  43.     int iteration = 0;
  44.     double zx = 0;
  45.     double zy = 0;
  46.  
  47.     // We iterate until cutoff or modulus > 2
  48.     while (iteration < cutoff) {
  49.       self_mul(zx, zy);
  50.       zx += px;
  51.       zy += py;
  52.       double mod = modulus(zx, zy);
  53.  
  54.       if (mod > 2.0f)
  55.     break;
  56.  
  57.       iteration++;
  58.     }
  59.  
  60.     // We store the number of iterations, and we use
  61.     // a special value (-1) if we don't converge
  62.     if (iteration == cutoff)
  63.       mset[i] = -1;
  64.     else
  65.     mset[i] = iteration;
  66.   }
  67. }
  68.  
  69. int main(int argc, char **argv) {
  70.   MPI_Init(&argc, &argv);
  71.  
  72.   // Reading the parameters on the command line
  73.   min_x = std::stod(argv[1]);
  74.   max_x = std::stod(argv[2]);
  75.   min_y = std::stod(argv[3]);
  76.   max_y = std::stod(argv[4]);
  77.   dx = max_x - min_x;
  78.   dy = max_y - min_y;
  79.   cutoff = std::stoi(argv[5]);
  80.  
  81.   // Getting rank and size
  82.   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  83.   MPI_Comm_size(MPI_COMM_WORLD, &size);
  84.  
  85.   // Initialisation of the points :
  86.   // The process with rank 0 will hold all the points
  87.   // The others will keep the variable poitns as a null pointer
  88.   MPI_Barrier(MPI_COMM_WORLD);
  89.   double *points = NULL;
  90.  
  91.   if (rank == 0)
  92.   {
  93.     points = new double[p_count * p_count * 2];
  94.     for (int yp=0; yp < p_count; ++yp)
  95.     {
  96.       double py = min_y + dy * yp / p_count;
  97.       for (int xp=0; xp < p_count; ++xp)
  98.       {
  99.         double px = min_x + dx * xp / p_count;
  100.         int lid = yp*p_count*2 + xp*2;
  101.         points[lid]   = px;
  102.         points[lid+1] = py;
  103.       }
  104.     }
  105.   }
  106.  
  107.   MPI_Barrier(MPI_COMM_WORLD);
  108.  
  109.   // The number of points we hold
  110.   int npts = p_count*p_count;
  111.   double *reception = new double[npts * 2 / size];
  112.   MPI_Scatter(points, (npts * 2) / size, MPI_DOUBLE, reception, (npts * 2) / size, MPI_DOUBLE, 0, MPI_COMM_WORLD);
  113.   // Computing the mandelbrot set.
  114.   // This function is already coded and you don't have to worry about it
  115.   int mset[npts / size];
  116.   int mset_gather[npts];
  117.   compute_mandelbrot(reception, npts, mset);
  118.   MPI_Barrier(MPI_COMM_WORLD);
  119.   MPI_Gather(mset, npts / size, MPI_INT, mset_gather, npts, MPI_INT, 0, MPI_COMM_WORLD);
  120.   // Printing only one result that will be used to create the image
  121.   if (rank==0) {
  122.     for (int yp=0; yp < p_count; ++yp) {
  123.       for (int xp=0; xp < p_count; ++xp)
  124.     std::cout << mset_gather[yp*p_count + xp] << " ";
  125.       std::cout << std::endl;
  126.     }
  127.   }
  128.  
  129.   // Cleaning up the mess and exiting properly
  130.   delete [] points;
  131.  
  132.   MPI_Finalize();
  133.   return 0;
  134. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top