Monte Carlo

Estimate π using Monte Carlo method (parallelization of workload).

The program picks points at random inside the square. It then checks to see if the point is inside the circle (it knows it's inside the circle if x^2 + y^2 < R^2, where x and y are the coordinates of the point and R is the radius of the circle).

The program keeps track of how many points it's picked (nAll) and how many of those points fell inside the circle (circleCount).

In the parallel version, the work is divided among threads, i.e. each traed is performing nAll / PCJ.threadsCount() attempts. Each thread counts points inside circle.

Finally, the parrial sums are communicated to the procesor 0.

 import java.util.Random;
 import org.pcj.NodesDescription;
 import org.pcj.PCJ;
 import org.pcj.StartPoint;
 import org.pcj.Storage;
 import org.pcj.PcjFuture;
 import org.pcj.RegisterStorage;

 @RegisterStorage(PcjExamplePiMC.Shared.class)
 public class PcjExamplePiMC implements StartPoint {

     @Storage(PcjExamplePiMC.class)
     enum Shared { c }
     long c;

     @Override
     public void main() {
         PCJ.barrier();
         Random r = new Random();

         long nAll = 1000000;
         long n = nAll / PCJ.threadCount();
         double Rsq = 1.0;
         long circleCount;
 //Calculate
         circleCount = 0;
         double time = System.nanoTime();

         for (long i = 0; i < n; i++) {
             double x = 2.0 * r.nextDouble() - 1.0;
             double y = 2.0 * r.nextDouble() - 1.0;
             if ((x * x + y * y) < Rsq) {
                 circleCount++;
             }
         }

         c = circleCount;
         PCJ.barrier();
   // Communicate results
         PcjFuture cL[] = new PcjFuture[PCJ.threadCount()];

         long c0 = c;
         if (PCJ.myId() == 0) {
             for (int p = 1; p < PCJ.threadCount(); p++) {
                 cL[p] = PCJ.asyncGet(p, Shared.c);
             }
             for (int p = 1; p < PCJ.threadCount(); p++) {
                 c0 = c0 + (long) cL[p].get();
             }
         }

         PCJ.barrier();

         double pi = 4.0 * (double) c0 / (double) nAll;
         time = System.nanoTime() - time;
 // Print results
         if (PCJ.myId() == 0) {
             System.out.println(pi + " " + time * 1.0E-9);
         }
     }

     public static void main(String[] args) {
    String nodesFile  = "nodes.txt";
    PCJ.executionBuilder (PcjExample.class)
                .addNodes(new File("nodes.txt"))
                .start();
    }
     }
 }  

The code scales linearly with the numbers of processors.

Last updated