Advertisement
Guest User

Untitled

a guest
Nov 13th, 2018
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 12.92 KB | None | 0 0
  1. package javaapplication1;
  2. import mpi.*;
  3.  
  4. import java.io.FileWriter;
  5. import java.util.Date;
  6. import java.util.Random;
  7.  
  8. public class Laba6 {
  9.     public static void main(String[] args) throws Exception {
  10.         MPI.Init(args);
  11.         int rank = MPI.COMM_WORLD.Rank();
  12.         int size = MPI.COMM_WORLD.Size();
  13.         int[] a = null;
  14.         int[] b = null;
  15.         FileWriter wr = null;
  16.         if (rank == 0) {
  17.             wr = new FileWriter("output" + size + ".csv");
  18.             wr.write("dimension;serial;blocking;" +
  19.                     "non-blocking;deferred;Bcast/Reduce;" +
  20.                     "Scatterv/Gatherv;\n");
  21.         }
  22.         for (int n = 1000; n <= 1000000; n *= 10) {
  23.             double serialTime = 0, blockingTime = 0, nonBlockingTime = 0,
  24.                     deferredTime = 0, bcastReduceTime = 0,
  25.                     scattervGathervTime = 0;
  26.             if (rank == 0)
  27.                 wr.write(n + ";");
  28.             for (int i = 0; i < 50; ++i) {
  29.                 if (rank == 0) {
  30.                     a = new int[n];
  31.                     b = new int[n];
  32.                     Random rnd = new Random();
  33.                     for (int j = 0; j < n; ++j) {
  34.                         a[j] = rnd.nextInt(8) + 1;
  35.                         b[j] = rnd.nextInt(8) + 1;
  36.                     }
  37.                 }
  38.                 // последовательный алгоритм
  39.                 if (rank == 0) {
  40.                     Date time = new Date();
  41.                     long sum = 0;
  42.                     for (int j = 0; j < n; ++j)
  43.                         sum += a[j] * b[j];
  44.                     serialTime += (new Date()).getTime() - time.getTime();
  45.                 }
  46.                 // блокирующий двухточечный обмен
  47.                 if (rank == 0) {
  48.                     Date time = new Date();
  49.                     int div = n / size;
  50.                     int mod = n % size;
  51.                     int next;
  52.                     for (next = 1; next < mod; ++next) {
  53.                         MPI.COMM_WORLD.Send(a, next * (div + 1), div + 1,
  54.                                 MPI.INT, next, 0);
  55.                         MPI.COMM_WORLD.Send(b, next * (div + 1), div + 1,
  56.                                 MPI.INT, next, 1);
  57.                     }
  58.                     for (; next < size; ++next) {
  59.                         MPI.COMM_WORLD.Send(a, next * div + mod, div,
  60.                                 MPI.INT, next, 0);
  61.                         MPI.COMM_WORLD.Send(b, next * div + mod, div,
  62.                                 MPI.INT, next, 1);
  63.                     }
  64.                     long sum = 0;
  65.                     for (int j = 0; j < div + (mod > 0 ? 1 : 0); ++j)
  66.                         sum += a[j] * b[j];
  67.                     for (int prev = 1; prev < size; ++prev) {
  68.                         long[] buf_sum = new long[1];
  69.                         MPI.COMM_WORLD.Recv(buf_sum, 0, 1, MPI.LONG, prev,
  70.                                 2);
  71.                         sum += buf_sum[0];
  72.                     }
  73.                     blockingTime += (new Date()).getTime() - time.getTime();
  74.                 } else {
  75.                     Status st = MPI.COMM_WORLD.Probe(0, 0);
  76.                     int count = st.Get_count(MPI.INT);
  77.                     int[] buf_a = new int[count];
  78.                     int[] buf_b = new int[count];
  79.                     MPI.COMM_WORLD.Recv(buf_a, 0, count, MPI.INT, 0, 0);
  80.                     MPI.COMM_WORLD.Recv(buf_b, 0, count, MPI.INT, 0, 1);
  81.                     long[] sum = {0};
  82.                     for (int j = 0; j < count; ++j)
  83.                         sum[0] += buf_a[j] * buf_b[j];
  84.                     MPI.COMM_WORLD.Send(sum, 0, 1, MPI.LONG, 0, 2);
  85.                 }
  86.                 MPI.COMM_WORLD.Barrier();
  87.                 // использование неблокирующих функций
  88.                 if (rank == 0) {
  89.                     Date time = new Date();
  90.                     int div = n / size;
  91.                     int mod = n % size;
  92.                     int next;
  93.                     for (next = 1; next < mod; ++next) {
  94.                         MPI.COMM_WORLD.Isend(a, next * (div + 1), div + 1,
  95.                                 MPI.INT, next, 0);
  96.                         MPI.COMM_WORLD.Isend(b, next * (div + 1), div + 1,
  97.                                 MPI.INT, next, 1);
  98.                     }
  99.                     for (; next < size; ++next) {
  100.                         MPI.COMM_WORLD.Isend(a, next * div + mod, div,
  101.                                 MPI.INT, next, 0);
  102.                         MPI.COMM_WORLD.Isend(b, next * div + mod, div,
  103.                                 MPI.INT, next, 1);
  104.                     }
  105.                     long sum = 0;
  106.                     for (int j = 0; j < div + (mod > 0 ? 1 : 0); ++j)
  107.                         sum += a[j] * b[j];
  108.                     long[] buf_sum = new long[size - 1];
  109.                     Request[] r = new Request[size - 1];
  110.                     for (int prev = 1; prev < size; ++prev)
  111.                         r[prev - 1] = MPI.COMM_WORLD.Irecv(buf_sum, prev - 1,
  112.                                 1, MPI.LONG, prev, 2);
  113.                     Request.Waitall(r);
  114.                     for (int j = 0; j < size - 1; ++j)
  115.                         sum += buf_sum[j];
  116.                     nonBlockingTime += (new Date()).getTime() -
  117.                             time.getTime();
  118.                 } else {
  119.                     Status st = MPI.COMM_WORLD.Probe(0, 0);
  120.                     int count = st.Get_count(MPI.INT);
  121.                     int[] buf_a = new int[count];
  122.                     int[] buf_b = new int[count];
  123.                     Request[] r = new Request[2];
  124.                     r[0] = MPI.COMM_WORLD.Irecv(buf_a, 0, count, MPI.INT, 0,
  125.                             0);
  126.                     r[1] = MPI.COMM_WORLD.Irecv(buf_b, 0, count, MPI.INT, 0,
  127.                             1);
  128.                     Request.Waitall(r);
  129.                     long[] sum = {0};
  130.                     for (int j = 0; j < count; ++j)
  131.                         sum[0] += buf_a[j] * buf_b[j];
  132.                     MPI.COMM_WORLD.Isend(sum, 0, 1, MPI.LONG, 0, 2);
  133.                 }
  134.                 MPI.COMM_WORLD.Barrier();
  135.                 // отложенные обмены
  136.                 if (rank == 0) {
  137.                     Date time = new Date();
  138.                     int div = n / size;
  139.                     int mod = n % size;
  140.                     int next;
  141.                     Prequest[] pr = new Prequest[2 * (size - 1)];
  142.                     for (next = 1; next < mod; ++next) {
  143.                         pr[2 * (next - 1)] = MPI.COMM_WORLD.Send_init(a,
  144.                                 next * (div + 1), div + 1, MPI.INT, next, 0);
  145.                         pr[2 * next - 1] = MPI.COMM_WORLD.Send_init(b,
  146.                                 next * (div + 1), div + 1, MPI.INT, next, 1);
  147.                     }
  148.                     for (; next < size; ++next) {
  149.                         pr[2 * (next - 1)] = MPI.COMM_WORLD.Send_init(a,
  150.                                 next * div + mod, div, MPI.INT, next, 0);
  151.                         pr[2 * next - 1] = MPI.COMM_WORLD.Send_init(b,
  152.                                 next * div + mod, div, MPI.INT, next, 1);
  153.                     }
  154.                     Prequest.Startall(pr);
  155.                     Prequest.Waitall(pr);
  156.                     long sum = 0;
  157.                     for (int j = 0; j < div + (mod > 0 ? 1 : 0); ++j)
  158.                         sum += a[j] * b[j];
  159.                     long[] buf_sum = new long[size - 1];
  160.                     pr = new Prequest[size - 1];
  161.                     for (int prev = 1; prev < size; ++prev)
  162.                         pr[prev - 1] = MPI.COMM_WORLD.Recv_init(buf_sum,
  163.                                 prev - 1, 1, MPI.LONG, prev, 2);
  164.                     Prequest.Startall(pr);
  165.                     Prequest.Waitall(pr);
  166.                     for (int j = 0; j < size - 1; ++j)
  167.                         sum += buf_sum[j];
  168.                     deferredTime += (new Date()).getTime() - time.getTime();
  169.                 } else {
  170.                     Status st = MPI.COMM_WORLD.Probe(0, 0);
  171.                     int count = st.Get_count(MPI.INT);
  172.                     int[] buf_a = new int[count];
  173.                     int[] buf_b = new int[count];
  174.                     Prequest[] pr = new Prequest[2];
  175.                     pr[0] = MPI.COMM_WORLD.Recv_init(buf_a, 0, count,
  176.                             MPI.INT, 0, 0);
  177.                     pr[1] = MPI.COMM_WORLD.Recv_init(buf_b, 0, count,
  178.                             MPI.INT, 0, 1);
  179.                     Prequest.Startall(pr);
  180.                     Request.Waitall(pr);
  181.                     long[] sum = {0};
  182.                     for (int j = 0; j < count; ++j)
  183.                         sum[0] += buf_a[j] * buf_b[j];
  184.                     MPI.COMM_WORLD.Send(sum, 0, 1, MPI.LONG, 0, 2);
  185.                 }
  186.                 MPI.COMM_WORLD.Barrier();
  187.                 // Bcast/Reduce
  188.                 Date time = null;
  189.                 if (rank == 0)
  190.                     time = new Date();
  191.                 int[] buf_a;
  192.                 int[] buf_b;
  193.                 if (rank == 0) {
  194.                     buf_a = a.clone();
  195.                     buf_b = b.clone();
  196.                 } else {
  197.                     buf_a = new int[n];
  198.                     buf_b = new int[n];
  199.                 }
  200.                 MPI.COMM_WORLD.Bcast(buf_a, 0, n, MPI.INT, 0);
  201.                 MPI.COMM_WORLD.Bcast(buf_b, 0, n, MPI.INT, 0);
  202.                 int div = n / size;
  203.                 int mod = n % size;
  204.                 int first = rank * div + (rank < mod ? rank : mod);
  205.                 int last = first + div + (rank < mod ? 1 : 0);
  206.                 long[] buf_sum = {0};
  207.                 for (int j = first; j < last; ++j)
  208.                     buf_sum[0] += buf_a[j] * buf_b[j];
  209.                 long[] sum = {0};
  210.                 MPI.COMM_WORLD.Reduce(buf_sum, 0, sum, 0, 1, MPI.LONG,
  211.                         MPI.SUM, 0);
  212.                 if (rank == 0)
  213.                     bcastReduceTime += (new Date()).getTime() -
  214.                             time.getTime();
  215.                 MPI.COMM_WORLD.Barrier();
  216.                 // Scatterv/Gatherv
  217.                 if (rank == 0)
  218.                     time = new Date();
  219.                 buf_a = new int[div + (rank < mod ? 1 : 0)];
  220.                 buf_b = new int[div + (rank < mod ? 1 : 0)];
  221.                 if (rank != 0) {
  222.                     a = new int[n];
  223.                     b = new int[n];
  224.                 }
  225.                 if (mod != 0) {
  226.                     int[] displs = new int[size];
  227.                     int[] scounts = new int[size];
  228.                     int next;
  229.                     for (next = 0; next < mod; ++next) {
  230.                         displs[next] = next * (div + 1);
  231.                         scounts[next] = div + 1;
  232.                     }
  233.                     for (; next < size; ++next) {
  234.                         displs[next] = next * div + mod;
  235.                         scounts[next] = div;
  236.                     }
  237.                     MPI.COMM_WORLD.Scatterv(a, 0, scounts, displs, MPI.INT,
  238.                             buf_a, 0, div + (rank < mod ? 1 : 0), MPI.INT,
  239.                             0);
  240.                     MPI.COMM_WORLD.Scatterv(b, 0, scounts, displs, MPI.INT,
  241.                             buf_b, 0, div + (rank < mod ? 1 : 0), MPI.INT,
  242.                             0);
  243.                 } else {
  244.                     MPI.COMM_WORLD.Scatter(a, 0, div, MPI.INT, buf_a, 0,
  245.                             div + (rank < mod ? 1 : 0), MPI.INT, 0);
  246.                     MPI.COMM_WORLD.Scatter(b, 0, div, MPI.INT, buf_b, 0,
  247.                             div + (rank < mod ? 1 : 0), MPI.INT, 0);
  248.                 }
  249.                 sum[0] = 0;
  250.                 for (int j = 0; j < div + (rank < mod ? 1 : 0); ++j)
  251.                     sum[0] += buf_a[j] * buf_b[j];
  252.                 buf_sum = new long[size];
  253.                 MPI.COMM_WORLD.Gather(sum, 0, 1, MPI.LONG, buf_sum, 0, 1,
  254.                         MPI.LONG, 0);
  255.                 if (rank == 0) {
  256.                     for (int j = 1; j < size; ++j)
  257.                         sum[0] += buf_sum[j];
  258.                     scattervGathervTime += (new Date()).getTime() -
  259.                             time.getTime();
  260.                 }
  261.                 MPI.COMM_WORLD.Barrier();
  262.             }
  263.             if (rank == 0) {
  264.                 serialTime /= 50;
  265.                 blockingTime /= 50;
  266.                 nonBlockingTime /= 50;
  267.                 deferredTime /= 50;
  268.                 bcastReduceTime /= 50;
  269.                 scattervGathervTime /= 50;
  270.                 wr.write(serialTime + ";" + blockingTime + ";" +
  271.                         nonBlockingTime + ";" + deferredTime + ";" +
  272.                         bcastReduceTime + ";" + scattervGathervTime + ";\n");
  273.             }
  274.         }
  275.         if (rank == 0) {
  276.             wr.flush();
  277.             wr.close();
  278.         }
  279.         MPI.Finalize();
  280.     }
  281. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement