package edu.rice.hj.example.comp322.labs.lab2; import edu.rice.hj.api.HjMetrics; import edu.rice.hj.api.SuspendableException; import edu.rice.hj.runtime.config.HjSystemProperty; import edu.rice.hj.runtime.metrics.AbstractMetricsManager; 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 ArraySumLoop 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 ArraySumLoop { /** * Main method, runs the ArraySum * * @param args - the input parameters */ public static void main(final String[] args) { // Setup metrics HjSystemProperty.abstractMetrics.set(true); launchHabaneroApp(() -> { final String strategyStr = System.getProperty("arraysum.work.strategy"); System.out.println("Strategy: " + strategyStr); final int n = ArraySumUtil.readLengthArgument(args); final int[] X = ArraySumUtil.initialize(n); final int expectedResult = ArraySumUtil.expectedResult(X); computeSumReduction(n, X); // Output System.out.println("Sum of " + n + " elements = " + X[0] + " (should be " + expectedResult + ")"); }, () -> { // Print out the metrics data final HjMetrics actualMetrics = abstractMetrics(); AbstractMetricsManager.dumpStatistics(actualMetrics); }); } /** * Reduces the array down into a single sum, mutating input array with partial sums. The final result is stored in * the first element of the array * * @param n - the number of elements in the array * @param x - the array to sum (is mutated in the function) */ protected static void computeSumReduction(final int n, final int[] x) throws SuspendableException { // Parallel reduction for (int step = 1; step < n; step *= 2) { int size = ArraySumUtil.ceilDiv(n, 2 * step); final int sstep = step; finish(() -> { for (int i = 0; i < size; i++) { final int ii = i; asyncNb(() -> { // if condition ensures that algorithm works correctly when X.length is not a power of 2 final int rightIndex = (2 * ii + 1) * sstep; final int leftIndex = 2 * ii * sstep; if (rightIndex < x.length) { // local variables X, step, size are copied on entry to the async, analogous to method call parameters x[leftIndex] = ArraySumUtil.doOperation(x, leftIndex, rightIndex); } }); } }); // finish-for-async } } }