package edu.rice.hj.example.comp322.labs.lab8; import edu.rice.hj.runtime.actors.Actor; import static edu.rice.hj.Module1.finish; import static edu.rice.hj.Module1.launchHabaneroApp; /** * This is a actor version of Sieve of Eratosthenes algorithm for generating * prime numbers. */ public class Sieve_Sol { public static void main(final String[] args) { final int limit = 600000; System.out.println("Sieve.main: limit = " + limit); launchHabaneroApp(() -> { for (int iter = 0; iter < 8; iter++) { final long startTime = System.nanoTime(); // 2 is the first prime final SieveActor sieveActor = new SieveActor(0, 2); finish(() -> { sieveActor.start(); // send a request for all the numbers to check for primeness to the first actor for (int i = 3; i <= limit; i += 2) { sieveActor.send(i); } // send termination request sieveActor.send(0); }); // compute number of primes int numPrimes = 0; SieveActor loopActor = sieveActor; while (loopActor != null) { numPrimes += loopActor.numLocalPrimes(); loopActor = loopActor.nextActor(); } final long endTime = System.nanoTime(); final long execTime = (long) ((endTime - startTime) / 1e6); System.out.println("Sieve.main: num primes = " + numPrimes); System.out.println("Iteration-" + iter + " Exec Time = " + execTime + " ms."); } }); } private static class SieveActor extends Actor { private static final int MAX_LOCAL_PRIMES = 2000; private final int id; // counter to keep track of primes stored locally private int numLocalPrimes; // use array to store all local primes private final int localPrimes[]; // use the nextActor to dynamically build the pipeline private SieveActor nextActor; SieveActor(int id, int localPrime) { this.id = id; this.nextActor = null; // initialize localPrimes and store the first entry this.localPrimes = new int[MAX_LOCAL_PRIMES]; localPrimes[0] = localPrime; this.numLocalPrimes = 1; } public SieveActor nextActor() { return nextActor; } public int numLocalPrimes() { return numLocalPrimes; } @Override protected void process(Object theMsg) { int candidate = (Integer) theMsg; if (candidate <= 0) { // pass the termination message along the chain // terminate this actor if (nextActor != null) { nextActor.send(0); } exit(); } else { // determine if candidate is locally prime final boolean locallyPrime = isLocallyPrime(candidate); if (locallyPrime) { // determine whether to store the candidate into the ... // local list of primes or whether to forward it to the ... // next actor in the pipeline. Remember that nextActor was // initialized to null, so might need to create a new // actor and start it. if (numLocalPrimes < MAX_LOCAL_PRIMES) { localPrimes[numLocalPrimes] = candidate; numLocalPrimes += 1; } else { if (nextActor == null) { this.nextActor = new SieveActor(id + 1, candidate); nextActor.start(); } this.nextActor.send(candidate); } } } } private boolean isLocallyPrime(int candidate) { boolean isPrime = true; // code to determine if the candidate is locally prime for (int i = 0; i < numLocalPrimes; i++) { if (candidate % localPrimes[i] == 0) { isPrime = false; break; } } return isPrime; } } }