import edu.rice.hj.api.HjMetrics; import edu.rice.hj.runtime.config.HjSystemProperty; import edu.rice.hj.runtime.metrics.AbstractMetricsManager; import java.util.Random; import static edu.rice.hj.Module1.*; /** * ArraySum1.hj --- Parallel iterative example program for computing the sum of an array * * This example program creates an array of n random int's, and computes their sum in parallel. * The default value of n is 8, but any array size can be provided as argv[0] * by going into the run configuration and putting it in the program arguments field on * intelliJ, or by typing java ArraySum1 n on the command line * * To obtain abstract performance metrics, select the appropriate compiler option. * * NOTE: this example program is for illustrative purposes, and is not intended to be used as a performance benchmark. * * @author Vivek Sarkar (vsarkar@rice.edu) */ public class ArraySum1 { static final int default_n = 8; static final String err = "Incorrect argument for array size (should be > 0), assuming n = " + default_n; /** * Main method, runs the ArraySum * @param argv - the input parameters */ public static void main(String[] argv) { // Setup metrics initializeHabanero(); // Initialization int n; int[] X; if (argv.length != 0) { try { n = Integer.parseInt(argv[0]); if (n <= 0) { // Bad value of n System.out.println(err); n = default_n; } } catch (Throwable e) { System.out.println(err); n = default_n; } } else { // argv.length == 0 n = default_n; } X = new int[n]; Random myRand = new Random(n); for (int i = 0; i < n; i++) { X[i] = myRand.nextInt(n); } // Parallel reduction for (int step = 1; step < n; step *= 2) { int size = ceilDiv(n, 2 * step); final int sstep = step; finish(() -> { for (int i = 0; i < size; i++) { final int ii = i; async(() -> { // if condition ensures that algorithm works correctly when X.length is not a power of 2 if ((2 * ii + 1) * sstep < X.length) { doWork(1); // count each + operator as 1 unit of work in the abstract performance metrics // local variables X, step, size are copied on entry to the async, analogous to method call parameters X[2 * ii * sstep] += X[(2 * ii + 1) * sstep]; } }); } }); // finish-for-async } // Output System.out.println("Sum of " + n + " elements = " + X[0] + " (should be 27 for n = 8)"); // Print out the metrics data finalizeHabanero(); final HjMetrics actualMetrics = abstractMetrics(); AbstractMetricsManager.dumpStatistics(actualMetrics); System.out.println(actualMetrics); } /** * Divide x by y, and round up to next largest int * @param x - dividend * @param y - divisor * @return quotient rounded to the up to an integer */ static int ceilDiv(int x, int y) { return (x + y - 1) / y; } }