package edu.rice.comp322;
import edu.rice.hj.api.HjFuture;
import edu.rice.hj.api.HjProcedure;
import edu.rice.hj.api.SuspendableException;
import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
import static edu.rice.hj.Module0.finish;
import static edu.rice.hj.Module0.launchHabaneroApp;
import static edu.rice.hj.Module1.future;
/**
* Two-way Array sum example.
*/
public class ArraySum {
/**
* Constant ERROR_MSG="Incorrect argument for array size"
.
*/
public static final String ERROR_MSG = "Incorrect argument for array size (should be > 0), assuming default n";
/**
* Constant DEFAULT_N=20_000_000
.
*/
public static final int DEFAULT_N = 20_000_000;
/**
* Constant THRESHOLD=1_000_000
.
*/
public static final int THRESHOLD = 1_000_000;
/**
*
main.
* * @param args an array of {@link String} objects. */ public static void main(final String[] args) throws Exception { // Initialization int n = parseLengthArgument(args); final double[] X = initializeArray(n); System.out.println("ReciprocalArraySum.main: starting..."); for (int numRun = 0; numRun < 5; numRun++) { System.out.printf(" Run %d\n", numRun); timeExecution(() -> seqArraySum(X, 0, X.length), (p) -> printResults("seqArraySum", p)); timeExecution(() -> parArraySumHabaneroJava(X, 0, X.length), (p) -> printResults("parArraySumHabaneroJava", p)); timeExecution(() -> parArraySumForkJoin(X, 0, X.length), (p) -> printResults("parArraySumForkJoin", p)); timeExecution(() -> parArraySumForkJoin2(X, 0, X.length), (p) -> printResults("parArraySumForkJoin2", p)); } System.out.println("ReciprocalArraySum.main: ended."); } protected static int parseLengthArgument(final String[] argv) { int n; if (argv.length != 0) { try { n = Integer.parseInt(argv[0]); if (n <= 0) { // Bad value of n System.out.println(ERROR_MSG); n = DEFAULT_N; } } catch (Throwable e) { System.out.println(ERROR_MSG); n = DEFAULT_N; } } else { // argv.length == 0 n = DEFAULT_N; } return n; } protected static double[] initializeArray(final int n) { final double[] X = new double[n]; final Random myRand = new Random(n); for (int i = 0; i < n; i++) { X[i] = myRand.nextInt(n); if (X[i] == 0.0) { i--; } } return X; } protected static void timeExecution( final Runnable body, final HjProcedureseqArraySum.
* * @param xArray an array of double. * @return a double. */ protected static double seqArraySum(final double[] xArray, final int start, final int end) { double sum = 0; // Compute sum of array elements doing some work (square the root) for (int i = start; i < end; i++) { sum += Math.pow(2, Math.sqrt(xArray[i])) / (i + 1); } return sum; } /** *parArraySumHabaneroJava.
** NOTE: you will need to add a "throws SuspendableException" clause to this method signature when it contains a * finish or any other blocking API. *
* * @param xArray an array of double. * @return a double. */ protected static double parArraySumHabaneroJavaHelper( final double[] xArray, final int start, final int end) throws SuspendableException { final int fragmentSize = end - start; if (fragmentSize < THRESHOLD) { // sequential threshold cutoff return seqArraySum(xArray, start, end); } else { final int mid = (end + start) / 2; final HjFutureparArraySumHabaneroJava.
** NOTE: you will need to add a "throws SuspendableException" clause to this method signature when it contains a * finish or any other blocking API. *
* * @param xArray an array of double. * @return a double. */ protected static double parArraySumHabaneroJava( final double[] xArray, final int start, final int end) { final double[] sum = {0.0}; launchHabaneroApp(() -> { finish(() -> { sum[0] = parArraySumHabaneroJavaHelper(xArray, start, end); }); }); return sum[0]; } protected static class ArraySumForkJoinTask extends RecursiveTaskparArraySumHabaneroJava.
** NOTE: you will need to add a "throws SuspendableException" clause to this method signature when it contains a * finish or any other blocking API. *
* * @param xArray an array of double. * @return a double. */ protected static double parArraySumForkJoin(final double[] xArray, final int start, final int end) { final ForkJoinPool commonPool = ForkJoinPool.commonPool(); final ArraySumForkJoinTask task = new ArraySumForkJoinTask(xArray, start, end); return commonPool.invoke(task); } protected static class ArraySumForkJoinTask2 extends RecursiveTaskparArraySumHabaneroJava.
** NOTE: you will need to add a "throws SuspendableException" clause to this method signature when it contains a * finish or any other blocking API. *
* * @param xArray an array of double. * @return a double. */ protected static double parArraySumForkJoin2(final double[] xArray, final int start, final int end) { final ForkJoinPool commonPool = ForkJoinPool.commonPool(); final ArraySumForkJoinTask2 task = new ArraySumForkJoinTask2(xArray, start, end); return commonPool.invoke(task); } }