moving from pgms
authorEric Bohm <ebohm@illinois.edu>
Wed, 29 Sep 2004 19:16:00 +0000 (19:16 +0000)
committerEric Bohm <ebohm@illinois.edu>
Wed, 29 Sep 2004 19:16:00 +0000 (19:16 +0000)
28 files changed:
examples/charm++/integrate/Makefile [new file with mode: 0644]
examples/charm++/integrate/pgm.C [new file with mode: 0644]
examples/charm++/integrate/pgm.ci [new file with mode: 0644]
examples/charm++/integrate/pgm.h [new file with mode: 0644]
examples/charm++/integrate2/Makefile [new file with mode: 0644]
examples/charm++/integrate2/pgm.C [new file with mode: 0644]
examples/charm++/integrate2/pgm.ci [new file with mode: 0644]
examples/charm++/integrate2/pgm.h [new file with mode: 0644]
examples/charm++/integrateArray/Makefile [new file with mode: 0644]
examples/charm++/integrateArray/pgm.C [new file with mode: 0644]
examples/charm++/integrateArray/pgm.ci [new file with mode: 0644]
examples/charm++/integrateArray/pgm.h [new file with mode: 0644]
examples/charm++/piArray/Makefile [new file with mode: 0644]
examples/charm++/piArray/pgm.C [new file with mode: 0644]
examples/charm++/piArray/pgm.ci [new file with mode: 0644]
examples/charm++/piArray/pgm.h [new file with mode: 0644]
examples/charm++/ring/Makefile [new file with mode: 0644]
examples/charm++/ring/ring.C [new file with mode: 0644]
examples/charm++/ring/ring.ci [new file with mode: 0644]
examples/charm++/ring/ring.h [new file with mode: 0644]
examples/charm++/rings/Makefile [new file with mode: 0644]
examples/charm++/rings/rings.C [new file with mode: 0644]
examples/charm++/rings/rings.ci [new file with mode: 0644]
examples/charm++/rings/rings.h [new file with mode: 0644]
examples/charm++/speeds/Makefile [new file with mode: 0644]
examples/charm++/speeds/speed.C [new file with mode: 0644]
examples/charm++/speeds/speed.ci [new file with mode: 0644]
examples/charm++/speeds/speed.h [new file with mode: 0644]

diff --git a/examples/charm++/integrate/Makefile b/examples/charm++/integrate/Makefile
new file mode 100644 (file)
index 0000000..b9c5d64
--- /dev/null
@@ -0,0 +1,10 @@
+CHARMC=../../../../bin/charmc $(OPTS)
+
+pgm: pgm.o
+       $(CHARMC) pgm.o  -o pgm -language charm++
+
+pgm.o : pgm.C pgm.h pgm.ci
+       $(CHARMC) -c pgm.ci pgm.C
+
+clean:
+       rm -f pgm *.o conv-host *.decl.h *.def.h *~ charmrun
diff --git a/examples/charm++/integrate/pgm.C b/examples/charm++/integrate/pgm.C
new file mode 100644 (file)
index 0000000..9298058
--- /dev/null
@@ -0,0 +1,50 @@
+#include "pgm.h"
+
+CProxy_main mainProxy;
+
+main::main(CkArgMsg * m)
+{ 
+  if(m->argc < 3) CmiAbort("./pgm slices numChares.");
+  int slices = atoi(m->argv[1]); 
+  int numChares = atoi(m->argv[2]);
+  mainProxy = thishandle; // readonly initialization
+
+  int slicesPerChare=slices/numChares;
+  slices=slicesPerChare*numChares; //Make slices an even multiple of numChares
+
+  double xLeft=0.0; //Left end of integration domain
+  double xRight=1.0; //Right end of integration domain
+  double dx=(xRight-xLeft)/slices;
+  for (int i=0; i<numChares; i++) {
+    int nSlices=slicesPerChare; // must be a divisor
+    double x=xLeft+i*slicesPerChare*dx; //Chare i takes slices starting at [i*slicesPerChare]
+    CProxy_integrate::ckNew(x,dx,nSlices); 
+  }
+  count = numChares;
+  integral = 0.0;
+}
+
+void main::results(double partialIntegral) 
+{ 
+  integral += partialIntegral;
+  if (0 == --count) {
+    CkPrintf("With all results, integral is: %.15f \n", integral);
+    CkExit();
+  }
+}
+
+integrate::integrate(double xStart,double dx, int nSlices)
+{ 
+  double partialIntegral = 0.0;
+  for (int i=0; i<nSlices; i++) {
+    double x = xStart+(i+0.5)*dx;
+    double f_x=(1.0/(1+x));
+    partialIntegral += f_x*dx;
+  }
+
+  mainProxy.results(partialIntegral);
+
+  delete this; /*this chare has no more work to do.*/
+}
+
+#include "pgm.def.h"
diff --git a/examples/charm++/integrate/pgm.ci b/examples/charm++/integrate/pgm.ci
new file mode 100644 (file)
index 0000000..385a881
--- /dev/null
@@ -0,0 +1,16 @@
+mainmodule pgm {
+
+readonly CProxy_main mainProxy;
+
+mainchare main
+{
+  entry main();
+  entry void results(double partialIntegral);
+};
+
+chare integrate
+{
+  entry integrate(double xStart,double dx, int nSlices);
+};
+
+};
diff --git a/examples/charm++/integrate/pgm.h b/examples/charm++/integrate/pgm.h
new file mode 100644 (file)
index 0000000..13b5589
--- /dev/null
@@ -0,0 +1,22 @@
+#include "pgm.decl.h"
+
+class main : public Chare
+{
+private:
+  int count; //Number of partial results that have not arrived yet
+  double integral; //Partial value of function integral
+public:
+  main(CkMigrateMessage *m) {}
+  main(CkArgMsg *m);
+  void results(double partialIntegral);
+};
+
+class integrate : public Chare 
+{
+private:
+
+public:
+  integrate(CkMigrateMessage *m) {}
+  integrate(double xStart,double dx, int nSlices);
+};
+
diff --git a/examples/charm++/integrate2/Makefile b/examples/charm++/integrate2/Makefile
new file mode 100644 (file)
index 0000000..5940376
--- /dev/null
@@ -0,0 +1,17 @@
+CHARMC=../../../../bin/charmc $(OPTS)
+
+pgm: pgm.o
+       $(CHARMC) pgm.o  -o pgm -language charm++
+
+pgm.o : pgm.C pgm.h pgm.decl.h
+       $(CHARMC) -c pgm.C
+
+pgm.decl.h: pgm.ci
+       $(CHARMC) -c pgm.ci
+
+clean:
+       rm -f pgm *.o conv-host *.decl.h *.def.h *~ charmrun
+
+test: pgm
+       ./charmrun ./pgm +p2 pgm 1000 10
+
diff --git a/examples/charm++/integrate2/pgm.C b/examples/charm++/integrate2/pgm.C
new file mode 100644 (file)
index 0000000..fd390a6
--- /dev/null
@@ -0,0 +1,73 @@
+#include "pgm.h"
+
+CProxy_main mainProxy;
+
+/* 
+  This is the 1D function we want to integrate.
+  Because this class is sent over the network as
+  a pointer to its abstract superclass, we need the 
+  "PUPable" declarations.
+*/
+class myFunction : public function1d {
+       double height;
+public:
+       myFunction(double height_=1.0) :height(height_) {}
+
+       virtual double evaluate(double x) {
+               return height/(1+x);
+       }
+       
+       //PUP::able support:
+       PUPable_decl(myFunction);
+       myFunction(CkMigrateMessage *m=0) {}    
+       virtual void pup(PUP::er &p) {
+               p|height;
+       }
+};
+
+main::main(CkArgMsg * m)
+{ 
+  if(m->argc < 3) CmiAbort("./pgm slices numChares.");
+  int slices = atoi(m->argv[1]); 
+  int numChares = atoi(m->argv[2]);
+  mainProxy = thishandle; // readonly initialization
+
+  int slicesPerChare=slices/numChares;
+  slices=slicesPerChare*numChares; //Make slices an even multiple of numChares
+
+  myFunction *f=new myFunction(2.0);
+  double xLeft=0.0; //Left end of integration domain
+  double xRight=1.0; //Right end of integration domain
+  double dx=(xRight-xLeft)/slices;
+  for (int i=0; i<numChares; i++) {
+    int nSlices=slicesPerChare; // must be a divisor
+    double x=xLeft+i*slicesPerChare*dx; //Chare i takes slices starting at [i*slicesPerChare]
+    CProxy_integrate::ckNew(x,dx,nSlices,*f); 
+  }
+  count = numChares;
+  integral = 0.0;
+}
+
+void main::results(double partialIntegral) 
+{ 
+  integral += partialIntegral;
+  if (0 == --count) {
+    CkPrintf("With all results, integral is: %.15f \n", integral);
+    CkExit();
+  }
+}
+
+integrate::integrate(double xStart,double dx, int nSlices,function1d &f)
+{ 
+  double partialIntegral = 0.0;
+  for (int i=0; i<nSlices; i++) {
+    double x = xStart+(i+0.5)*dx;
+    partialIntegral += f.evaluate(x)*dx;
+  }
+
+  mainProxy.results(partialIntegral);
+
+  delete this; /*this chare has no more work to do.*/
+}
+
+#include "pgm.def.h"
diff --git a/examples/charm++/integrate2/pgm.ci b/examples/charm++/integrate2/pgm.ci
new file mode 100644 (file)
index 0000000..e725216
--- /dev/null
@@ -0,0 +1,18 @@
+mainmodule pgm {
+
+PUPable myFunction;
+
+readonly CProxy_main mainProxy;
+
+mainchare main
+{
+  entry main();
+  entry void results(double partialIntegral);
+};
+
+chare integrate
+{
+  entry integrate(double xStart,double dx, int nSlices, CkReference<function1d> f);
+};
+
+};
diff --git a/examples/charm++/integrate2/pgm.h b/examples/charm++/integrate2/pgm.h
new file mode 100644 (file)
index 0000000..682efdb
--- /dev/null
@@ -0,0 +1,38 @@
+#include "charm++.h"
+
+/* This class is passed as a parameter, so it has to be 
+  declared *before* the .decl header! */
+
+/** 
+ * Abstract 1d real function class.
+ * You inherit from this class to use the numerical integral
+ * class below.
+ */
+class function1d : public PUP::able {
+public:
+       virtual double evaluate(double x) =0;
+       
+       PUPable_abstract(function1d);
+};
+
+#include "pgm.decl.h"
+
+class main : public Chare
+{
+private:
+  int count; //Number of partial results that have not arrived yet
+  double integral; //Partial value of function integral
+public:
+  main(CkMigrateMessage *m) {}
+  main(CkArgMsg *m);
+  void results(double partialIntegral);
+};
+
+class integrate : public Chare 
+{
+private:
+
+public:
+  integrate(CkMigrateMessage *m) {}
+  integrate(double xStart,double dx, int nSlices, function1d &f);
+};
diff --git a/examples/charm++/integrateArray/Makefile b/examples/charm++/integrateArray/Makefile
new file mode 100644 (file)
index 0000000..ae2287a
--- /dev/null
@@ -0,0 +1,18 @@
+# modify the path of CHARMC
+CHARMC=../../../../bin/charmc $(OPTS)
+
+pgm: pgm.o
+       $(CHARMC) pgm.o  -o pgm -language charm++
+
+# compile program with trace projections - performance trace library
+pgm_prof: pgm.o
+       $(CHARMC) pgm.o  -o pgm_prof -language charm++ -tracemode projections
+
+pgm.o : pgm.C pgm.h pgm.def.h
+       $(CHARMC) -c pgm.C
+
+pgm.decl.h pgm.def.h: pgm.ci
+       $(CHARMC)  pgm.ci
+
+clean:
+       rm -f pgm pgm_prof *.o conv-host *.decl.h *.def.h *~ charmrun *.log *.sts core
diff --git a/examples/charm++/integrateArray/pgm.C b/examples/charm++/integrateArray/pgm.C
new file mode 100644 (file)
index 0000000..bc6a03f
--- /dev/null
@@ -0,0 +1,70 @@
+/***************************************************************************
+  This "integration" program calculates the integral value of function
+  f(x)=1.0/x for the range of [1.0, 2.0].
+
+  The idea is to divide the range into "numSlices" of slices, and create 
+  "numChares" of parallel objects, or Chares, each taking care of 
+  numSlices/numChares of slices. 
+  After each chare finishes its portion of computation, a global reduction 
+  is performed to sum up the local values and get the final result.
+***************************************************************************/
+
+#include "pgm.h"
+
+CProxy_main mainProxy;
+
+// program starts from here
+main::main(CkArgMsg *m)
+{ 
+  if(m->argc < 3) CmiAbort("./pgm slices numChares.");
+  int numSlices = atoi(m->argv[1]); 
+  int numChares = atoi(m->argv[2]);
+  mainProxy = thishandle;      // readonly initialization
+
+  // calculate the number of slices for each chare
+  int slicesPerChare=numSlices/numChares;
+  numSlices=slicesPerChare*numChares;   //Make slices an even multiple of numChares
+
+  double xLeft=1.0;                    //Left end of integration domain
+  double xRight=2.0;                   //Right end of integration domain
+  double dx=(xRight-xLeft)/numSlices;  //range between slides
+
+  // create array of chares to do the actual computation
+  CProxy_integrate integrateArray = CProxy_integrate::ckNew();
+  for (int i=0; i<numChares; i++) {
+    int nSlices=slicesPerChare;     // must be a divisor
+    double x=xLeft+i*slicesPerChare*dx; // Chare i takes slices starting at [i*slicesPerChare]
+    // create chare i that takes slices starting from x for nSlices
+    integrateArray[i].insert(x, dx, nSlices); 
+  }
+  integrateArray.doneInserting();      // done with creation
+
+  // set up reduction handler for sum up the integrals across all chares.
+  CkCallback *cb = new CkCallback(CkIndex_main::results(NULL), mainProxy);
+  integrateArray.ckSetReductionClient(cb);
+}
+
+// reduction handler, it prints out the result and exits.
+void main::results(CkReductionMsg *msg) 
+{ 
+  double integral = *(double *)msg->getData();
+  CkPrintf("With all results, integral is: %.15f \n", integral);
+  CkExit();
+}
+
+integrate::integrate(double xStart,double dx, int nSlices)
+{ 
+  // calculate the partialIntegral for this chare for
+  // range of [xStart, xStart+(nSlices-1)*dx]
+  double partialIntegral = 0.0;
+  for (int i=0; i<nSlices; i++) {
+    double x = xStart+(i+0.5)*dx;
+    double f_x=(1.0/x);
+    partialIntegral += f_x*dx;
+  }
+
+  // reduction to sum the partialIntegral across all chares
+  contribute(sizeof(double), &partialIntegral, CkReduction::sum_double);
+}
+
+#include "pgm.def.h"
diff --git a/examples/charm++/integrateArray/pgm.ci b/examples/charm++/integrateArray/pgm.ci
new file mode 100644 (file)
index 0000000..658849e
--- /dev/null
@@ -0,0 +1,19 @@
+// ci file defines the function API's of the parallel objects
+// These remotely invocable functions are called entry functions in Charm++
+
+mainmodule pgm {
+
+readonly CProxy_main mainProxy;
+
+mainchare main
+{
+  entry main();
+  entry void results(CkReductionMsg *msg);
+};
+
+array [1D] integrate
+{
+  entry integrate(double xStart,double dx, int nSlices);
+};
+
+};
diff --git a/examples/charm++/integrateArray/pgm.h b/examples/charm++/integrateArray/pgm.h
new file mode 100644 (file)
index 0000000..bdf3734
--- /dev/null
@@ -0,0 +1,20 @@
+// pgm.decl.h is generated from pgm.ci
+#include "pgm.decl.h"
+
+// define Charm++'s main Chare
+// Main Chare only lives on Processor 0
+class main : public CBase_main
+{
+public:
+  main(CkArgMsg *m);
+  void results(CkReductionMsg *msg);
+};
+
+// define type of an array of Chares
+class integrate : public CBase_integrate 
+{
+public:
+  integrate(CkMigrateMessage *m) {}
+  integrate(double xStart,double dx, int nSlices);
+};
+
diff --git a/examples/charm++/piArray/Makefile b/examples/charm++/piArray/Makefile
new file mode 100644 (file)
index 0000000..216ab19
--- /dev/null
@@ -0,0 +1,13 @@
+CHARMC=../../../../bin/charmc $(OPTS)
+
+pgm: pgm.o
+       $(CHARMC) pgm.o  -o pgm -language charm++
+
+pgm.o : pgm.C pgm.h pgm.decl.h
+       $(CHARMC) -c pgm.C
+
+pgm.decl.h: pgm.ci
+       $(CHARMC) pgm.ci
+
+clean:
+       rm -f pgm *.o conv-host *.decl.h *.def.h *~ charmrun
diff --git a/examples/charm++/piArray/pgm.C b/examples/charm++/piArray/pgm.C
new file mode 100644 (file)
index 0000000..254066a
--- /dev/null
@@ -0,0 +1,81 @@
+#include "pgm.h"
+
+CkChareID mainhandle;
+
+#define USE_REDUCTION 0
+
+void reductionHandler(void *param, int dataSize, void *data)
+{
+  CProxy_main m(mainhandle);
+  int d = *(int*)data;
+  m.results(d);
+}
+
+main::main(CkArgMsg * m)
+{ 
+  if(m->argc != 3)
+  {
+    CkPrintf("Usage: pgm <nsamples> <nchares>\n");
+    CkAbort("");
+  }
+
+  ns = atoi(m->argv[1]);
+  nc = atoi(m->argv[2]);
+  delete m;
+
+  starttime = CmiWallTimer();
+
+  //FIXME
+  //CkGroupID gid = CkCreatePropMap();
+  //CProxy_piPart  arr = CProxy_piPart::ckNew(nc, gid);
+  CProxy_piPart  arr = CProxy_piPart::ckNew(nc);
+
+  CkPrintf("At time %lf, array created.\n", (CmiWallTimer()-starttime));
+
+#if USE_REDUCTION
+  arr.setReductionClient(reductionHandler,(void *)NULL);
+#endif
+  arr.compute(ns);
+  responders = nc;
+  count = 0;
+  mainhandle = thishandle; // readonly initialization
+  CkPrintf("At time %lf, main exits.\n", (CmiWallTimer()-starttime));
+}
+
+void main::results(int cnt) 
+{ 
+  count += cnt;
+#if ! USE_REDUCTION
+  if (0 == --responders) 
+#endif
+  {
+    endtime = CmiWallTimer();
+    CkPrintf("At time %lf, pi=: %f \n", (endtime-starttime), 4.0*count/(ns*nc));
+    CkExit();
+  }
+}
+
+piPart::piPart()
+{ 
+  CrnSrand((int) this);
+}
+
+void
+piPart::compute(int ns)
+{
+  int i;
+  int count=0;
+  for (i= 0; i<ns; i++) {
+    double x = CrnDrand();
+    double y = CrnDrand();
+    if ((x*x + y*y) <= 1.0) count++;
+  }
+#if ! USE_REDUCTION
+  CProxy_main mainproxy(mainhandle);
+  mainproxy.results(count);
+#else
+  contribute(sizeof(int), (void *)&count, CkReduction::sum_int);
+#endif
+}
+
+#include "pgm.def.h"
diff --git a/examples/charm++/piArray/pgm.ci b/examples/charm++/piArray/pgm.ci
new file mode 100644 (file)
index 0000000..af5de8b
--- /dev/null
@@ -0,0 +1,17 @@
+mainmodule pgm {
+
+readonly CkChareID mainhandle;
+
+mainchare main
+{
+  entry main();
+  entry void results(int c);
+};
+
+array [1D] piPart
+{
+  entry piPart(void);
+  entry void compute(int ns);
+};
+
+};
diff --git a/examples/charm++/piArray/pgm.h b/examples/charm++/piArray/pgm.h
new file mode 100644 (file)
index 0000000..71c9634
--- /dev/null
@@ -0,0 +1,22 @@
+#include "pgm.decl.h"
+
+class main : public Chare
+{
+private:
+  int responders;
+  int  count;
+  int ns, nc;
+  double starttime, endtime;
+public:
+  main(CkMigrateMessage *m) {}
+  main(CkArgMsg *m);
+  void results(int c);
+};
+
+class piPart : public ArrayElement1D 
+{
+public:
+  piPart(CkMigrateMessage *m) {}
+  piPart(void);
+  void compute(int ns);
+};
diff --git a/examples/charm++/ring/Makefile b/examples/charm++/ring/Makefile
new file mode 100644 (file)
index 0000000..4b0322d
--- /dev/null
@@ -0,0 +1,10 @@
+CHARMC=../../../../bin/charmc $(OPTS)
+
+pgm:  ring.o
+       $(CHARMC) ring.o  -o pgm -language charm++
+
+ring.o : ring.C ring.h ring.ci
+       $(CHARMC) -c ring.ci ring.C
+
+clean:
+       rm -f conv-host pgm *.def.h *.decl.h *.o *~ charmrun
diff --git a/examples/charm++/ring/ring.C b/examples/charm++/ring/ring.C
new file mode 100644 (file)
index 0000000..d87caca
--- /dev/null
@@ -0,0 +1,98 @@
+#include <string.h>
+#include "ring.h"
+
+void *
+Msg::pack(Msg* m)
+{
+  int *p = (int *) CkAllocBuffer(m, (m->listsize+3)*sizeof(int));  
+  int *t = p;
+
+  *t = m->value; t++;
+  *t = m->hop; t++;
+  *t = m->listsize; t++;
+  for(int i=0;i<m->listsize; i++, t++)
+    *t = m->list1[i];
+  CkFreeMsg(m);
+  return(p);
+}
+
+Msg *
+Msg::unpack(void *buf)
+{
+   int *in = (int *) buf;
+   Msg *t = new (CkAllocBuffer(in, sizeof(Msg))) Msg;
+   t->value = in[0];
+   t->hop = in[1];
+   t->listsize = in[2];
+   t->list1 = new int[t->listsize];
+   for(int i=0;i<t->listsize;i++)
+     t->list1[i] = in[i+3];
+   CkFreeMsg(buf);
+   return t;
+}
+
+Btest::Btest(Msg *m)
+{
+  CkPrintf("branch created on %d\n", CkMyPe());
+
+// Uses the hop information from the message.
+  nexthop=(CkMyPe()+(m->hop)) % CkNumPes();
+
+// Takes care of negative hops
+  if (nexthop < 0) nexthop += CkNumPes();
+
+  if (CkMyPe()==0) {
+    CProxy_Btest btest(thisgroup);
+    btest[nexthop].recv_msg(m);
+  } else  {
+    delete m;
+  }
+}
+
+void 
+Btest::recv_msg(Msg * m)
+{
+  CkPrintf("Message received on  %d for ring %d\n", CkMyPe(), m->value);
+
+// BOC at Processor 0 initiates and terminates a ring.
+  if (CkMyPe() == 0) {
+     CkPrintf("Message got back! %d \n", m->value);
+     CProxy_main mainchare(main::mainhandle);
+     mainchare.quit_when_done(m);
+  } else {
+    CProxy_Btest btest(thisgroup);
+    btest[nexthop].recv_msg(m);
+  }
+}
+
+CkChareID main::mainhandle;
+
+main::main(CkArgMsg* m)
+{
+  Msg *msg1 = new Msg;
+  mainhandle=thishandle;
+
+  msg1->value = 1;
+  msg1->hop=1;
+  msg1->listsize=10;
+  msg1->list1=new int[msg1->listsize];
+  for (int i=0;i<msg1->listsize;i++) 
+    msg1->list1[i]=i;
+  CProxy_Btest::ckNew(msg1);
+  delete m;
+}
+
+// Keeps track of the number of rings that terminated. An alternative 
+// would be to use quiscence detection.
+void 
+main::quit_when_done(Msg *m)
+{
+   CkPrintf("The ring %d terminated\n", m->value);
+   for (int i=0;i<m->listsize;i++)
+     CkPrintf("%d\n", m->list1[i]);
+   delete m;
+   CkExit();
+}
+
+#include "ring.def.h"
+
diff --git a/examples/charm++/ring/ring.ci b/examples/charm++/ring/ring.ci
new file mode 100644 (file)
index 0000000..4bad956
--- /dev/null
@@ -0,0 +1,15 @@
+mainmodule ring {
+  message Msg;
+
+  mainchare main {
+    entry main();
+    entry void quit_when_done(Msg *);
+    readonly CkChareID mainhandle;
+  };
+  
+  group Btest {
+    entry Btest(Msg *);
+    entry void recv_msg(Msg *);
+  };
+}
+
diff --git a/examples/charm++/ring/ring.h b/examples/charm++/ring/ring.h
new file mode 100644 (file)
index 0000000..273df38
--- /dev/null
@@ -0,0 +1,33 @@
+#include "charm++.h"
+#include "ring.decl.h"
+
+class Msg : public CMessage_Msg
+{
+  public:
+    int value;
+    int hop;
+    int *list1;
+    int listsize;
+    static void *pack(Msg *);
+    static Msg  *unpack(void *);
+};
+
+class Btest : public Group
+{
+  private:
+    int nexthop;
+  public:
+    Btest(CkMigrateMessage *m) {}
+    Btest(Msg *);
+    void recv_msg(Msg *);
+};
+
+class main : public Chare
+{
+  public:
+    static CkChareID mainhandle;
+    main(CkMigrateMessage *m) {}
+    main(CkArgMsg *);
+    void quit_when_done(Msg *);
+};
+
diff --git a/examples/charm++/rings/Makefile b/examples/charm++/rings/Makefile
new file mode 100644 (file)
index 0000000..0e8f7de
--- /dev/null
@@ -0,0 +1,10 @@
+CHARMC=../../../../bin/charmc $(OPTS)
+
+pgm:  rings.o
+       $(CHARMC) rings.o  -o pgm -language charm++
+
+rings.o : rings.C rings.h rings.ci
+       $(CHARMC) -c rings.ci rings.C
+
+clean:
+       rm -f conv-host pgm *.o *.decl.h *.def.h *~ charmrun
diff --git a/examples/charm++/rings/rings.C b/examples/charm++/rings/rings.C
new file mode 100644 (file)
index 0000000..6124415
--- /dev/null
@@ -0,0 +1,90 @@
+///////////////////////////////////////////////
+//
+//  rings.C
+//
+//  Definition of chares in rings
+//
+//  Author: Michael Lang
+//  Date: 6/15/99
+//
+///////////////////////////////////////////////
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "charm++.h"
+#include "rings.h"
+#include "rings.def.h"
+
+CkChareID mainhandle;
+
+#define NUMBEROFRINGS 10
+
+main::main(CkArgMsg *m) {
+  
+  int i = 0;
+  count = NUMBEROFRINGS;
+  //  Make several rings of varying hop sizes and repetions
+
+  for (i=0;i<NUMBEROFRINGS;i++) {
+    Token *t = new Token;
+    t->value = i;
+    t->hopSize = (i+1) * (int) pow(-1,i);
+    t->loops = NUMBEROFRINGS - i + 1;
+    CProxy_ring::ckNew(t);
+  }
+
+  mainhandle = thishandle;
+  delete m;
+}
+
+void main::ringDone(NotifyDone *m) {
+  count--;
+  CkPrintf("Ring %d is finished.\n", m->value);
+  if (count == 0)
+    CkExit();
+}
+
+ring::ring(Token *t) {
+
+  //  Calculate next hop
+
+  nextHop = (CkMyPe() + (t->hopSize)) % CkNumPes();
+  
+  if (nextHop < 0) nextHop += CkNumPes();  // For negative hops
+
+  //  Start with the token at Processor 0, and pass it around the ring
+
+  if (CkMyPe() == 0) {
+    CProxy_ring ring(thisgroup);
+    ring[nextHop].passToken(t);
+  } else {
+    delete t;
+  }
+}
+
+void ring::passToken(Token *t) {
+  
+  //  When token returns to processor 0, decrement the count and notify
+  //  main if done
+
+  if (CkMyPe() == 0) {
+    CkPrintf("Loop completed on ring %d\n", t->value);
+    t->loops--;
+    if (t->loops == 0) {
+      NotifyDone *m = new NotifyDone;
+      m->value = t->value;
+      CProxy_main mainchare(mainhandle);
+      mainchare.ringDone(m);
+    } else {
+      CProxy_ring ring(thisgroup);
+      ring[nextHop].passToken(t);
+    }
+  } else {
+    CProxy_ring ring(thisgroup);
+    ring[nextHop].passToken(t);
+  }
+}
+
diff --git a/examples/charm++/rings/rings.ci b/examples/charm++/rings/rings.ci
new file mode 100644 (file)
index 0000000..15b0e26
--- /dev/null
@@ -0,0 +1,40 @@
+////////////////////////////////////////////
+//
+//  rings.ci
+//
+//  Interface file for rings
+//
+//  Author: Michael Lang
+//  Date: 6/15/99
+//
+////////////////////////////////////////////
+//
+//  Rings
+//
+//    Creates several groups of chares ("rings"),
+//  and passes one message around each ring. Each
+//  ring does a different number of repetitions 
+//  going around the loop and different hop
+//  distances.
+//
+//////////////////////////////////////////// 
+mainmodule rings {
+
+  readonly CkChareID mainhandle;
+
+  message Token;
+  message NotifyDone;
+
+  mainchare main {
+    entry main();
+    entry void ringDone(NotifyDone *);
+  };   
+
+  group ring {
+    entry ring(Token *);
+    entry void passToken(Token *);
+  };
+
+};
+
+
diff --git a/examples/charm++/rings/rings.h b/examples/charm++/rings/rings.h
new file mode 100644 (file)
index 0000000..663643e
--- /dev/null
@@ -0,0 +1,45 @@
+//////////////////////////////////////////////
+//
+//  rings.h
+//
+//  Declaration of chares and messages of rings
+//
+//  Author: Michael Lang
+//  Date: 6/15/99
+//
+///////////////////////////////////////////////
+
+#include "rings.decl.h"
+
+class Token : public CMessage_Token {
+public:
+  int value;
+  int hopSize;
+  int loops;
+};
+
+class NotifyDone : public CMessage_NotifyDone {
+public:
+  int value;
+};
+
+class main : public Chare {
+private:
+  int count;
+public:
+  main(CkArgMsg *m);
+  main(CkMigrateMessage *m) {}
+  void ringDone(NotifyDone *m);
+};
+
+class ring : public Group {
+private:
+  int nextHop;
+public:
+  ring(Token *t);
+  ring(CkMigrateMessage *m) {}
+  void passToken(Token *t);
+};
+
+  
+  
diff --git a/examples/charm++/speeds/Makefile b/examples/charm++/speeds/Makefile
new file mode 100644 (file)
index 0000000..5981858
--- /dev/null
@@ -0,0 +1,10 @@
+CHARMC=../../../../bin/charmc $(OPTS)
+
+pgm:  speed.o
+       $(CHARMC) speed.o  -o pgm -language charm++
+
+speed.o : speed.C speed.h speed.ci
+       $(CHARMC) -c speed.ci speed.C
+
+clean:
+       rm -f conv-host pgm *.def.h *.decl.h *.o *~ charmrun
diff --git a/examples/charm++/speeds/speed.C b/examples/charm++/speeds/speed.C
new file mode 100644 (file)
index 0000000..09c5e74
--- /dev/null
@@ -0,0 +1,124 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include "speed.h"
+
+void 
+test::measure(int nc)
+{
+  nchunks = nc;
+  int s = LDProcessorSpeed();
+  CkPrintf("[%d] speed = %d \n", CkMyPe(), s);
+  CProxy_test grp(thisgroup);
+  grp.recv(CkMyPe(), s);
+}
+
+void
+test::recv(int pe, int speed)
+{
+  speeds[pe] = speed;
+  numrecd++;
+  if(numrecd==CkNumPes())
+  {
+    distrib();
+    if(CkMyPe()==0)
+      CkExit();
+  }
+}
+
+double *rem;
+
+int cmp(const void *first, const void *second)
+{
+  int fi = *((const int *)first);
+  int si = *((const int *)second);
+  return ((rem[fi]==rem[si]) ? 0 : ((rem[fi]<rem[si]) ? 1 : (-1)));
+}
+
+void
+test::distrib(void)
+{
+  double total = 0.0;
+  int i;
+  for(i=0;i<numrecd;i++)
+    total += (double) speeds[i];
+  double *nspeeds = new double[numrecd];
+  for(i=0;i<numrecd;i++)
+    nspeeds[i] = (double) speeds[i] / total;
+  int *cp = new int[numrecd];
+  for(i=0;i<numrecd;i++)
+    cp[i] = (int) (nspeeds[i]*nchunks);
+  int nr = 0;
+  for(i=0;i<numrecd;i++)
+    nr += cp[i];
+  nr = nchunks - nr;
+  if(nr != 0)
+  {
+    rem = new double[numrecd];
+    for(i=0;i<numrecd;i++)
+      rem[i] = (double)nchunks*nspeeds[i] - cp[i];
+    int *pes = new int[numrecd];
+    for(i=0;i<numrecd;i++)
+      pes[i] = i;
+    qsort(pes, numrecd, sizeof(int), cmp);
+    for(i=0;i<nr;i++)
+      cp[pes[i]]++;
+  }
+  int minspeed = INT_MAX;
+  for(i=0;i<numrecd;i++)
+    if(minspeed > speeds[i])
+      minspeed = speeds[i];
+  double *rel = new double[numrecd];
+  for(i=0;i<numrecd;i++)
+    rel[i] = (double)speeds[i] /(double)minspeed;
+  int *rr = new int[numrecd];
+  for(i=0;i<numrecd;i++)
+    rr[i] = 0;
+  int j = 0;
+  for(i=0;i<nchunks;i++)
+  {
+    rr[j]++;
+    j = (j+1)%numrecd;
+  }
+  double rrtime = 0.0;
+  double proptime = 0.0;
+  for(i=0;i<numrecd;i++)
+  {
+    double ptime = (double)rr[i]/rel[i];
+    if(rrtime < ptime)
+      rrtime = ptime;
+    ptime = (double)cp[i]/rel[i];
+    if(proptime < ptime)
+      proptime = ptime;
+  }
+  if(CkMyPe()==0)
+  {
+    char *str = new char[1024];
+    char stmp[32];
+    sprintf(str, "Distrib: ");
+    for(i=0;i<numrecd;i++)
+    {
+      sprintf(stmp, "%d=>%d ", i, cp[i]);
+      strcat(str, stmp);
+    }
+    CkPrintf("%s\n", str);
+    CkPrintf("Expected perf improvement using prop map: %lf percent\n",
+              ((rrtime-proptime))*100.0/rrtime);
+  }
+}
+
+main::main(CkArgMsg* m)
+{
+  if(m->argc < 2) {
+    CkPrintf("Usage: charmrun pgm +pN <nchunks>\n");
+    CkAbort("");
+  }
+  int nchunks = atoi(m->argv[1]);
+  CkGroupID gid = CProxy_test::ckNew();
+  CProxy_test grp(gid);
+  grp.measure(nchunks);
+  delete m;
+}
+
+#include "speed.def.h"
+
diff --git a/examples/charm++/speeds/speed.ci b/examples/charm++/speeds/speed.ci
new file mode 100644 (file)
index 0000000..3dd9fff
--- /dev/null
@@ -0,0 +1,13 @@
+mainmodule speed {
+
+  mainchare main {
+    entry main();
+  };
+  
+  group test {
+    entry test(void);
+    entry void measure(int nc);
+    entry void recv(int pe, int speed);
+  };
+}
+
diff --git a/examples/charm++/speeds/speed.h b/examples/charm++/speeds/speed.h
new file mode 100644 (file)
index 0000000..b257b82
--- /dev/null
@@ -0,0 +1,24 @@
+#include "charm++.h"
+#include "speed.decl.h"
+
+class test : public Group
+{
+  private:
+    int nchunks;
+    int numrecd;
+    int *speeds;
+    void distrib(void);
+  public:
+    test(CkMigrateMessage *m) {}
+    test(void) { speeds = new int[CkNumPes()]; numrecd = 0; }
+    void measure(int nc);
+    void recv(int pe, int speed);
+};
+
+class main : public Chare
+{
+  public:
+    main(CkMigrateMessage *m) {}
+    main(CkArgMsg *);
+};
+