new histogram example for MSA
authorAaron Becker <akbecker@gmail.com>
Fri, 20 Jan 2012 05:17:51 +0000 (23:17 -0600)
committerAaron Becker <akbecker@gmail.com>
Fri, 20 Jan 2012 05:17:51 +0000 (23:17 -0600)
examples/multiphaseSharedArrays/Makefile_common
examples/multiphaseSharedArrays/histogram/Makefile [new file with mode: 0644]
examples/multiphaseSharedArrays/histogram/headers [new file with mode: 0644]
examples/multiphaseSharedArrays/histogram/histogram [new file with mode: 0755]
examples/multiphaseSharedArrays/histogram/histogram.C [new file with mode: 0644]
examples/multiphaseSharedArrays/histogram/histogram.ci [new file with mode: 0644]
examples/multiphaseSharedArrays/histogram/run.sh [new file with mode: 0755]

index 95c46b0bc69195b9f75d4ab3ca957abce525c140..a55f5b817f15fd0a4d0fd3e714cf3ebbeb2819db 100644 (file)
@@ -2,7 +2,7 @@
 # needs $(PGM)
 
 OPTS=
 # needs $(PGM)
 
 OPTS=
-CDIR=../../../..
+CDIR=../../..
 CHARMC=$(CDIR)/bin/charmc -language charm++ $(OPTS)
 
 # Rules to convert .ci to .decl.h and .def.h
 CHARMC=$(CDIR)/bin/charmc -language charm++ $(OPTS)
 
 # Rules to convert .ci to .decl.h and .def.h
diff --git a/examples/multiphaseSharedArrays/histogram/Makefile b/examples/multiphaseSharedArrays/histogram/Makefile
new file mode 100644 (file)
index 0000000..5c7f5c4
--- /dev/null
@@ -0,0 +1,3 @@
+
+PGM=histogram
+include ../Makefile_common
diff --git a/examples/multiphaseSharedArrays/histogram/headers b/examples/multiphaseSharedArrays/histogram/headers
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/examples/multiphaseSharedArrays/histogram/histogram b/examples/multiphaseSharedArrays/histogram/histogram
new file mode 100755 (executable)
index 0000000..b914917
Binary files /dev/null and b/examples/multiphaseSharedArrays/histogram/histogram differ
diff --git a/examples/multiphaseSharedArrays/histogram/histogram.C b/examples/multiphaseSharedArrays/histogram/histogram.C
new file mode 100644 (file)
index 0000000..000038b
--- /dev/null
@@ -0,0 +1,125 @@
+// -*- mode: c++; tab-width: 4 -*-
+//
+#include "msa/msa.h"
+
+typedef MSA::MSA2D<int, DefaultEntry<int>,
+        MSA_DEFAULT_ENTRIES_PER_PAGE, MSA_ROW_MAJOR> MSA2D;
+typedef MSA::MSA1D<int, DefaultEntry<int>, MSA_DEFAULT_ENTRIES_PER_PAGE> MSA1D;
+
+#include "histogram.decl.h"
+
+
+const unsigned int ROWS = 2000;
+const unsigned int COLS = 2000;
+const unsigned int BINS = 10;
+const unsigned int MAX_ENTRY = 1000;
+unsigned int WORKERS = 10;
+
+
+class Driver : public CBase_Driver
+{
+public:
+    Driver(CkArgMsg* m)
+    {
+        // Usage: histogram [number_of_worker_threads]
+        if (m->argc > 1) WORKERS=atoi(m->argv[1]);
+        delete m;
+
+        // Actually build the shared arrays: a 2d array to hold arbitrary
+        // data, and a 1d histogram array.
+        MSA2D data(ROWS, COLS, WORKERS);
+        MSA1D bins(BINS, WORKERS);
+        // Create worker threads and start them off.
+        workers = CProxy_Histogram::ckNew(data, bins, WORKERS);
+        workers.ckSetReductionClient(
+            new CkCallback(CkIndex_Driver::done(NULL), thisProxy));
+        workers.start();
+    }
+
+    void done(CkReductionMsg* m)
+    {
+        // When the reduction is complete, everything is ready to exit.
+        CkExit();
+    }
+};
+
+
+class Histogram: public CBase_Histogram
+{
+public:
+    MSA2D data;
+    MSA1D bins;
+
+    Histogram(const MSA2D& data_, const MSA1D& bins_)
+    : data(data_), bins(bins_)
+    {}
+
+    Histogram(CkMigrateMessage* m)
+    {}
+
+    ~Histogram()
+    {}
+
+    // Note: it's important that start is a threaded entry method
+    // so that the blocking MSA calls work as intended.
+    void start()
+    {
+        data.enroll(WORKERS);
+        bins.enroll(WORKERS);
+        
+        // Fill the data array with random numbers.
+               MSA2D::Write wd = data.getInitialWrite();
+        if (thisIndex == 0) fill_array(wd);
+
+        // Fill the histogram bins: read from the data array and
+        // accumulate to the histogram array.
+               MSA2D::Read rd = wd.syncToRead();
+        MSA1D::Accum ab = bins.getInitialAccum();
+        fill_bins(ab, rd);
+
+        // Print the histogram.
+        MSA1D::Read rb = ab.syncToRead();
+        if (thisIndex == 0) print_array(rb);
+
+        // Contribute to Driver::done to terminate the program.
+        contribute();
+    }
+
+    void fill_array(MSA2D::Write& w)
+    {
+        // Just let one thread fill the whole data array
+        // with random entries to be histogrammed.
+        for (unsigned int r = 0; r < data.getRows(); r++) {
+            for (unsigned int c = 0; c < data.getCols(); c++) {
+                w.set(r, c) = random() % MAX_ENTRY;
+            }
+        }
+    }
+
+    void fill_bins(MSA1D::Accum& b, MSA2D::Read& d)
+    {
+        // Determine the range of the data array that this
+        // worker should read from.
+        unsigned int range = ROWS / WORKERS;
+        unsigned int min_row = thisIndex * range;
+        unsigned int max_row = (thisIndex + 1) * range;
+        
+        // Count the entries that belong to each bin.
+        for (unsigned int r = 0; r < data.getRows(); r++) {
+            for (unsigned int c = 0; c < data.getCols(); c++) {
+                unsigned int bin = d.get(r, c) / (MAX_ENTRY / BINS);
+                b(bin) += 1;
+            }
+        }
+    }
+
+    void print_array(MSA1D::Read& b)
+    {
+        for (unsigned int i=0; i<BINS; ++i) {
+            CkPrintf("%d ", b.get(i)); 
+        }
+    }
+};
+
+#include "histogram.def.h"
diff --git a/examples/multiphaseSharedArrays/histogram/histogram.ci b/examples/multiphaseSharedArrays/histogram/histogram.ci
new file mode 100644 (file)
index 0000000..e0dd682
--- /dev/null
@@ -0,0 +1,23 @@
+// -*- mode: c++; tab-width: 4 -*-
+mainmodule histogram
+{
+    mainchare Driver
+    {
+        entry void Driver(CkArgMsg*);
+        entry void done(CkReductionMsg*);
+    };
+
+    array[1D] Histogram
+    {
+        entry void Histogram(MSA2D data_, MSA1D bins_);
+        entry [threaded] void start();
+    };
+
+    
+    /* Currently, you must explicitly instantiate any
+       MSA templates that you use. */
+    group MSA_CacheGroup<int, DefaultEntry<int>,
+                         MSA_DEFAULT_ENTRIES_PER_PAGE>;
+    array [1D] MSA_PageArray<int, DefaultEntry<int>,
+                             MSA_DEFAULT_ENTRIES_PER_PAGE>;
+};
diff --git a/examples/multiphaseSharedArrays/histogram/run.sh b/examples/multiphaseSharedArrays/histogram/run.sh
new file mode 100755 (executable)
index 0000000..3cfcad3
--- /dev/null
@@ -0,0 +1,29 @@
+#!/bin/sh
+# Shell script to test for multiple test cases
+
+touch outputs
+for rows1 in 1000 5000 10000; do
+  for cols1 in 500 750 1000; do
+    for cols2 in 1000 5000 10000; do
+      for mbytes in 128 64 32 16 8 4 2 1; do
+       for num_workers in 1 2 4 8 16 32; do
+          rm -rf params.h
+          printf "const unsigned int bytes = %d*1024*1024;\n" $mbytes >> params.h
+          printf "const unsigned int ROWS1 = %d;\n" $rows1 >> params.h
+          printf "const unsigned int COLS1 = %d;\n" $cols1 >> params.h
+          printf "const unsigned int COLS2 = %d;\n" $cols2 >> params.h
+          printf "const unsigned int ROWS2 = COLS1;\n" >> params.h
+          printf "const unsigned int NUM_WORKERS = %d;\n" $num_workers >> params.h
+          printf "\n" >> params.h
+  
+          rm -f t3
+          make OPTS=-O3 -s
+          for num_pes in 4 8 16 32; do
+            ./charmrun transpose +p$num_pes >> outputs
+          done
+        done
+      done
+    done
+  done
+done