Initial checkin of move from pgms
authorEric Bohm <ebohm@illinois.edu>
Wed, 15 Sep 2004 19:43:04 +0000 (19:43 +0000)
committerEric Bohm <ebohm@illinois.edu>
Wed, 15 Sep 2004 19:43:04 +0000 (19:43 +0000)
119 files changed:
tests/charm++/chkpt/Makefile [new file with mode: 0644]
tests/charm++/chkpt/README [new file with mode: 0644]
tests/charm++/chkpt/hello.C [new file with mode: 0644]
tests/charm++/chkpt/hello.ci [new file with mode: 0644]
tests/charm++/commtest/comlib/Makefile [new file with mode: 0644]
tests/charm++/commtest/comlib/hello.C [new file with mode: 0644]
tests/charm++/commtest/comlib/hello.ci [new file with mode: 0644]
tests/charm++/commtest/commlib_stream/Makefile [new file with mode: 0644]
tests/charm++/commtest/commlib_stream/hello.C [new file with mode: 0644]
tests/charm++/commtest/commlib_stream/hello.ci [new file with mode: 0644]
tests/charm++/loadbalancing/lb_test/Makefile [new file with mode: 0644]
tests/charm++/loadbalancing/lb_test/README [new file with mode: 0644]
tests/charm++/loadbalancing/lb_test/Topo.C [new file with mode: 0644]
tests/charm++/loadbalancing/lb_test/Topo.ci [new file with mode: 0644]
tests/charm++/loadbalancing/lb_test/Topo.h [new file with mode: 0644]
tests/charm++/loadbalancing/lb_test/faceoff [new file with mode: 0755]
tests/charm++/loadbalancing/lb_test/lb_test.C [new file with mode: 0644]
tests/charm++/loadbalancing/lb_test/lb_test.ci [new file with mode: 0644]
tests/charm++/loadbalancing/lb_test/predictor/Makefile [new file with mode: 0644]
tests/charm++/loadbalancing/lb_test/predictor/test.C [new file with mode: 0644]
tests/charm++/loadbalancing/lb_test/predictor/test.ci [new file with mode: 0644]
tests/charm++/loadbalancing/lb_test/predictor/test.h [new file with mode: 0644]
tests/charm++/loadbalancing/lb_test/run [new file with mode: 0755]
tests/charm++/loadbalancing/lb_test/sim/Makefile [new file with mode: 0644]
tests/charm++/loadbalancing/lb_test/sim/Topo.C [new file with mode: 0644]
tests/charm++/loadbalancing/lb_test/sim/Topo.ci [new file with mode: 0644]
tests/charm++/loadbalancing/lb_test/sim/Topo.h [new file with mode: 0644]
tests/charm++/loadbalancing/lb_test/sim/sim.C [new file with mode: 0644]
tests/charm++/loadbalancing/lb_test/sim/sim.ci [new file with mode: 0644]
tests/charm++/megatest/Make.depends [new file with mode: 0644]
tests/charm++/megatest/Makefile [new file with mode: 0644]
tests/charm++/megatest/Makefile.win32 [new file with mode: 0644]
tests/charm++/megatest/arrayring.C [new file with mode: 0644]
tests/charm++/megatest/arrayring.ci [new file with mode: 0644]
tests/charm++/megatest/arrayring.h [new file with mode: 0644]
tests/charm++/megatest/bitvector.C [new file with mode: 0644]
tests/charm++/megatest/bitvector.ci [new file with mode: 0644]
tests/charm++/megatest/bitvector.h [new file with mode: 0644]
tests/charm++/megatest/callback.C [new file with mode: 0644]
tests/charm++/megatest/callback.ci [new file with mode: 0644]
tests/charm++/megatest/callback.h [new file with mode: 0644]
tests/charm++/megatest/fib.C [new file with mode: 0644]
tests/charm++/megatest/fib.ci [new file with mode: 0644]
tests/charm++/megatest/fib.h [new file with mode: 0644]
tests/charm++/megatest/groupcast.C [new file with mode: 0644]
tests/charm++/megatest/groupcast.ci [new file with mode: 0644]
tests/charm++/megatest/groupcast.h [new file with mode: 0644]
tests/charm++/megatest/groupring.C [new file with mode: 0644]
tests/charm++/megatest/groupring.ci [new file with mode: 0644]
tests/charm++/megatest/groupring.h [new file with mode: 0644]
tests/charm++/megatest/immediatering.C [new file with mode: 0644]
tests/charm++/megatest/immediatering.ci [new file with mode: 0644]
tests/charm++/megatest/immediatering.h [new file with mode: 0644]
tests/charm++/megatest/inherit.C [new file with mode: 0644]
tests/charm++/megatest/inherit.ci [new file with mode: 0644]
tests/charm++/megatest/inherit.h [new file with mode: 0644]
tests/charm++/megatest/marshall.C [new file with mode: 0644]
tests/charm++/megatest/marshall.ci [new file with mode: 0644]
tests/charm++/megatest/marshall.h [new file with mode: 0644]
tests/charm++/megatest/megatest.C [new file with mode: 0644]
tests/charm++/megatest/megatest.ci [new file with mode: 0644]
tests/charm++/megatest/megatest.h [new file with mode: 0644]
tests/charm++/megatest/migration.C [new file with mode: 0644]
tests/charm++/megatest/migration.ci [new file with mode: 0644]
tests/charm++/megatest/migration.h [new file with mode: 0644]
tests/charm++/megatest/nodecast.C [new file with mode: 0644]
tests/charm++/megatest/nodecast.ci [new file with mode: 0644]
tests/charm++/megatest/nodecast.h [new file with mode: 0644]
tests/charm++/megatest/nodering.C [new file with mode: 0644]
tests/charm++/megatest/nodering.ci [new file with mode: 0644]
tests/charm++/megatest/nodering.h [new file with mode: 0644]
tests/charm++/megatest/packtest.C [new file with mode: 0644]
tests/charm++/megatest/packtest.ci [new file with mode: 0644]
tests/charm++/megatest/packtest.h [new file with mode: 0644]
tests/charm++/megatest/priolongtest.C [new file with mode: 0644]
tests/charm++/megatest/priolongtest.ci [new file with mode: 0644]
tests/charm++/megatest/priolongtest.h [new file with mode: 0644]
tests/charm++/megatest/priomsg.C [new file with mode: 0644]
tests/charm++/megatest/priomsg.ci [new file with mode: 0644]
tests/charm++/megatest/priomsg.h [new file with mode: 0644]
tests/charm++/megatest/priotest.C [new file with mode: 0644]
tests/charm++/megatest/priotest.ci [new file with mode: 0644]
tests/charm++/megatest/priotest.h [new file with mode: 0644]
tests/charm++/megatest/queens.C [new file with mode: 0644]
tests/charm++/megatest/queens.ci [new file with mode: 0644]
tests/charm++/megatest/queens.h [new file with mode: 0644]
tests/charm++/megatest/reduction.C [new file with mode: 0644]
tests/charm++/megatest/reduction.ci [new file with mode: 0644]
tests/charm++/megatest/reduction.h [new file with mode: 0644]
tests/charm++/megatest/rotest.C [new file with mode: 0644]
tests/charm++/megatest/rotest.ci [new file with mode: 0644]
tests/charm++/megatest/rotest.h [new file with mode: 0644]
tests/charm++/megatest/statistics.C [new file with mode: 0644]
tests/charm++/megatest/statistics.h [new file with mode: 0644]
tests/charm++/megatest/synctest.C [new file with mode: 0644]
tests/charm++/megatest/synctest.ci [new file with mode: 0644]
tests/charm++/megatest/synctest.h [new file with mode: 0644]
tests/charm++/megatest/templates.C [new file with mode: 0644]
tests/charm++/megatest/templates.ci [new file with mode: 0644]
tests/charm++/megatest/templates.h [new file with mode: 0644]
tests/charm++/megatest/tempotest.C [new file with mode: 0644]
tests/charm++/megatest/tempotest.ci [new file with mode: 0644]
tests/charm++/megatest/tempotest.h [new file with mode: 0644]
tests/charm++/megatest/varraystest.C [new file with mode: 0644]
tests/charm++/megatest/varraystest.ci [new file with mode: 0644]
tests/charm++/megatest/varraystest.h [new file with mode: 0644]
tests/charm++/megatest/varsizetest.C [new file with mode: 0644]
tests/charm++/megatest/varsizetest.ci [new file with mode: 0644]
tests/charm++/megatest/varsizetest.h [new file with mode: 0644]
tests/charm++/pingpong/Makefile [new file with mode: 0644]
tests/charm++/pingpong/pingpong.C [new file with mode: 0644]
tests/charm++/pingpong/pingpong.ci [new file with mode: 0644]
tests/charm++/simplearrayhello/Makefile [new file with mode: 0644]
tests/charm++/simplearrayhello/hello.C [new file with mode: 0644]
tests/charm++/simplearrayhello/hello.ci [new file with mode: 0644]
tests/charm++/simplearrayhello/msvc_6/README.txt [new file with mode: 0644]
tests/charm++/simplearrayhello/msvc_6/hello.dsp [new file with mode: 0644]
tests/charm++/simplearrayhello/msvc_6/hello.dsw [new file with mode: 0644]
tests/charm++/simplearrayhello/msvc_6/hello.opt [new file with mode: 0644]

diff --git a/tests/charm++/chkpt/Makefile b/tests/charm++/chkpt/Makefile
new file mode 100644 (file)
index 0000000..c6cc81c
--- /dev/null
@@ -0,0 +1,27 @@
+CHARMC=../../../bin/charmc $(OPTS)
+
+OBJS = hello.o
+
+all: hello
+       rm -rf log/
+
+hello: $(OBJS)
+       $(CHARMC) -language charm++ -o hello hello.o $(LIBS)
+
+hello.decl.h: hello.ci
+       $(CHARMC)  hello.ci
+
+clean:
+       rm -f *~ *.decl.h *.def.h conv-host *.o hello charmrun
+
+clear: clean
+       rm -rf log/
+
+hello.o: hello.C hello.decl.h
+       $(CHARMC) -c hello.C
+
+test: all
+       -rm -fr log
+       ./charmrun hello +p3
+       ./charmrun hello +p3 +restart log 
+       ./charmrun hello +p4 +restart log 
diff --git a/tests/charm++/chkpt/README b/tests/charm++/chkpt/README
new file mode 100644 (file)
index 0000000..e9ee021
--- /dev/null
@@ -0,0 +1,5 @@
+Example of checkpointable Charm++ program, especially this example
+shows how to checkpoint your mainchare: mark it [migratable], write
+a migrate constructor and pup'er for it. 
+
+Try it out with "make test".
diff --git a/tests/charm++/chkpt/hello.C b/tests/charm++/chkpt/hello.C
new file mode 100644 (file)
index 0000000..8b8b43c
--- /dev/null
@@ -0,0 +1,74 @@
+#include <stdio.h>
+#include "hello.decl.h"
+
+CProxy_Main mainProxy;
+CProxy_Hello helloProxy;
+int nElements;
+
+class Main : public CBase_Main {
+  int step;
+  int a;
+  int b[2];
+public:
+  Main(CkArgMsg* m){
+    step=0;    
+    a=123;b[0]=456;b[1]=789;
+    nElements=8;
+    delete m;
+
+    CkPrintf("Running Hello on %d processors for %d elements\n",CkNumPes(),nElements);
+    mainProxy = thisProxy;
+    helloProxy = CProxy_Hello::ckNew(nElements);
+    helloProxy.SayHi();
+  }
+  
+  Main(CkMigrateMessage *m){ 
+    mainProxy = thisProxy;
+    a=987;b[0]=654;b[1]=321;
+    CkPrintf("Main's MigCtor. a=%d(%p), b[0]=%d(%p), b[1]=%d.\n",a,&a,b[0],b,b[1]);
+  }
+
+  void myClient(CkReductionMsg *m){
+    step = *((int *)m->getData());
+    CkPrintf("myClient. a=%d(%p), b[0]=%d(%p), b[1]=%d.\n",a,&a,b[0],b,b[1]);
+    if(step == 3){
+      CkCallback cb(CkIndex_Hello::SayHi(),helloProxy);
+      CkStartCheckpoint("log",cb);
+    }else{
+      helloProxy.SayHi();
+    }
+    delete m;
+  }
+
+  void pup(PUP::er &p){
+    Chare::pup(p);
+    p|a; p(b,2);
+    CkPrintf("Main's PUPer. a=%d(%p), b[0]=%d(%p), b[1]=%d.\n",a,&a,b[0],b,b[1]);
+  }
+};
+
+class Hello : public ArrayElement1D
+{
+  int step;
+public:
+  Hello(){ step = 0; }
+  Hello(CkMigrateMessage *m) {}
+  
+  void SayHi(){
+    step++;
+    if(step < 6){
+      CkCallback cb(CkIndex_Main::myClient(0),mainProxy);
+      contribute(sizeof(int),(void*)&step,CkReduction::max_int,cb);
+    }else{
+      contribute(sizeof(int),(void*)&step,CkReduction::max_int,CkCallback(CkCallback::ckExit));
+    }
+  }
+  
+  void pup(PUP::er &p){
+    ArrayElement1D::pup(p);
+    p|step;
+  }
+};
+
+#include "hello.def.h"
+
diff --git a/tests/charm++/chkpt/hello.ci b/tests/charm++/chkpt/hello.ci
new file mode 100644 (file)
index 0000000..d8fb9a3
--- /dev/null
@@ -0,0 +1,15 @@
+mainmodule hello {
+  readonly CProxy_Main mainProxy;
+  readonly CProxy_Hello helloProxy;
+  readonly int nElements;
+
+  mainchare [migratable] Main {
+    entry Main(CkArgMsg *m);
+    entry void myClient(CkReductionMsg *);
+  };
+
+  array [1D] Hello {
+    entry Hello(void);
+    entry void SayHi();
+  }; 
+};
diff --git a/tests/charm++/commtest/comlib/Makefile b/tests/charm++/commtest/comlib/Makefile
new file mode 100644 (file)
index 0000000..1820a35
--- /dev/null
@@ -0,0 +1,28 @@
+CHARMC=../../../../bin/charmc $(OPTS)
+
+OBJS = hello.o
+
+all: hello
+
+hello: $(OBJS)
+       $(CHARMC) -module comlib -language charm++ -o hello $(OBJS)
+
+hello.decl.h: hello.ci
+       $(CHARMC)  hello.ci
+
+clean:
+       rm -f *.decl.h *.def.h conv-host *.o hello charmrun *.log *.sum *.sts
+
+hello.o: hello.C hello.decl.h
+       $(CHARMC) -c hello.C
+
+test: all
+       ./charmrun hello +p1 1
+       ./charmrun hello +p1 2
+       ./charmrun hello +p2 2
+       ./charmrun hello +p4 10 2
+       ./charmrun hello +p4 10 3
+       ./charmrun hello +p4 10 4
+       ./charmrun hello +p4 10 5
+       ./charmrun hello +p2 1
+
diff --git a/tests/charm++/commtest/comlib/hello.C b/tests/charm++/commtest/comlib/hello.C
new file mode 100644 (file)
index 0000000..c785145
--- /dev/null
@@ -0,0 +1,238 @@
+/**
+Tiny test program that
+  1.) Creates a simple 1D array
+  2.) Asks the array to do a multicast operation--
+      each element is told what to send, and 
+      what it should expect to receive.
+  3.) Synchronize, and go back to 2.
+
+If SKIP_COMLIB is not set, uses the comlib
+for the multicast operation.
+
+Orion Sky Lawlor, olawlor@acm.org, 2003/7/15
+Migration test in commlib added on 2004/05/12, Sameer Kumar
+*/
+
+#include <stdio.h>
+#include "EachToManyMulticastStrategy.h" /* for ComlibManager Strategy*/
+
+#include "hello.decl.h"
+
+/*readonly*/ CProxy_Main mainProxy;
+/*readonly*/ int nElements;
+
+/*mainchare*/
+class Main : public Chare
+{
+  int **commMatrix; /* commMatrix[s][r]= # messages sent from s to r */
+  int *commSend, *commRecv; /* temporary storage for "send" */
+  CProxy_Hello arr;
+  int nIter; // Iterations remaining
+public:
+  Main(CkArgMsg* m)
+  {
+    //Process command-line arguments
+    nElements=5;
+    int strat=USE_MESH;
+    if(m->argc>1) nElements=atoi(m->argv[1]);
+    if (m->argc>2) strat=atoi(m->argv[2]); /* FIXME: use "+strategy" flag */
+    delete m;
+    
+    // For the first step, use an all-to-all communication pattern.
+    commMatrix=new int*[nElements];
+    for (int i=0;i<nElements;i++) {
+      commMatrix[i]=new int[nElements];
+      for (int j=0;j<nElements;j++)
+        commMatrix[i][j]=1;
+    }
+    commSend=new int[nElements]; 
+    commRecv=new int[nElements];
+
+    //Start the computation
+    CkPrintf("Running Hello on %d processors for %d elements: strategy %d\n",
+            CkNumPes(),nElements, strat);
+    mainProxy = thishandle;
+    
+    ComlibInstanceHandle cinst=CkGetComlibInstance();
+
+    arr = CProxy_Hello::ckNew();
+   
+    EachToManyMulticastStrategy *strategy = new EachToManyMulticastStrategy
+        (strat, arr,arr);
+    cinst.setStrategy(strategy);
+    
+    CProxy_Hello hproxy(arr);
+    for(int count = 0; count < nElements; count++)
+        hproxy[count].insert(cinst);
+
+    hproxy.doneInserting();
+
+    nIter=0;
+    send();
+  };
+  
+  // Tell each element what to send and receive:
+  void send(void) {
+    CkPrintf("-------- starting iteration %d ---------\n",nIter);
+    for (int me=0;me<nElements;me++) {
+      for (int you=0;you<nElements;you++) {
+          commSend[you]=commMatrix[me][you]; //Stuff I send to you
+          commRecv[you]=commMatrix[you][me]; //Stuff you send to me
+      }
+      arr[me].startMcast(nIter,commSend,commRecv);
+    }
+  }
+
+  // This multicast iteration is complete.
+  void done(void)
+  {
+    CkPrintf("-------- finished iteration %d ---------\n",nIter);
+    nIter++;
+    if (nIter == 10) {
+      CkPrintf("All done\n");
+      CkExit();
+    }
+    else {
+      reset();
+      send();
+    }
+  }
+  
+  // Reset the send/recv matrix to random values
+  void reset(void) {
+    for (int i=0;i<nElements;i++)
+      for (int j=0;j<nElements;j++)
+          commMatrix[i][j]=(rand()%3);
+  }
+};
+
+/*array [1D]*/
+class Hello : public CBase_Hello 
+{
+  int curIter; // Current iteration number (only one can be running at a time)
+  int *willRecv; // counts # of message we will recv, per source
+  int *haveRecv; // counts # of messages we have recv'd, per source
+  bool verbose; // generate debugging output for every start/send/recv/end.
+  ComlibInstanceHandle comlib;
+  CProxy_Hello hProxy; // delegated comlib proxy.
+  
+  void reset(void) {
+    int i;
+    for (i=0;i<nElements;i++) haveRecv[i]=0; // Haven't got any yet
+    for (i=0;i<nElements;i++) willRecv[i]=-1; // Don't know how many we will get
+  }
+  // Call endMcast if we have received everything for this iteration.
+  void tryEnd(void) {
+    for (int i=0;i<nElements;i++) 
+      if (willRecv[i]!=haveRecv[i])
+        return;
+    endMcast();
+  }
+  // Verify that we don't have too many messages from "src".
+  void checkOver(int src) {
+    if (willRecv[src]!=-1 && haveRecv[src]>willRecv[src]) {
+      CkError("Element %d received too many messages from %d (expected %d, got %d)\n",
+       thisIndex, src, willRecv[src], haveRecv[src]);
+      CkAbort("Too many multicast messages!\n");
+    }
+  }
+public:
+  Hello(ComlibInstanceHandle comlib_)       
+  {
+    comlib = comlib_;
+
+    verbose=false; // true;
+    if (verbose) CkPrintf("Element %d created\n",thisIndex);
+    willRecv=new int[nElements];
+    haveRecv=new int[nElements];
+    reset();
+    curIter=0;
+    hProxy=thisProxy;
+#ifndef SKIP_COMLIB
+    ComlibDelegateProxy(&hProxy);
+#endif
+  }
+
+  Hello(CkMigrateMessage *m) { 
+  }
+  
+  // Send out the number of messages listed in "send" for each element.
+  //  You'll receive from each element the number of messages listed in "recv".
+  // This routine is called by main, which knows both senders and receivers.
+  void startMcast(int nIter,const int *send,const int *recv)
+  {
+    if (curIter!=nIter) {
+      CkError("Element %d asked to start iter %d, but we're at %d\n",
+           thisIndex, nIter,curIter);
+      CkAbort("Unexpected iteration start message!\n");
+    }
+    
+    if(verbose) CkPrintf("[%d] Element %d iteration %d starting\n",CkMyPe(), thisIndex,curIter);
+    
+    comlib.beginIteration();
+    for (int dest=0;dest<nElements;dest++) {
+      for (int m=0;m<send[dest];m++) {
+          if(verbose) CkPrintf("Element %d iteration %d send to %d\n",thisIndex,curIter,dest);
+          hProxy[dest].midMcast(curIter,thisIndex);
+      }
+    }
+    comlib.endIteration();
+    
+    for (int src=0;src<nElements;src++) {
+       willRecv[src]=recv[src]; 
+       checkOver(src);
+    }
+    tryEnd();
+  }
+  
+  // Receive a multicast from this array element.
+  void midMcast(int nIter,int src) {
+    if (curIter!=nIter) {
+      CkError("Element %d received unexpected message from %d for iter %d (we're at %d)\n",
+           thisIndex,src, nIter,curIter);
+      CkAbort("Unexpected mcast message!\n");
+    }
+    if (verbose) CkPrintf("Element %d iteration %d recv from %d\n",thisIndex,curIter,src);
+    haveRecv[src]++; checkOver(src);
+    tryEnd();
+  }
+  
+  // This is the end of one multicast iteration.
+  //  Update state and contribute to mainchare reduction.
+  void endMcast(void) {
+    if (verbose) CkPrintf("Element %d iteration %d done\n",thisIndex,curIter);
+    curIter++;
+    reset();
+    contribute(0,0,CkReduction::sum_int,CkCallback(
+       CkIndex_Main::done(),mainProxy));
+
+    srandom((CkMyPe()+1) * thisIndex);
+    int dest_proc = random() % CkNumPes();
+
+    if(curIter > 4) {
+        //if (verbose) 
+        if(verbose) CkPrintf("[%d] Migrating to %d\n", CkMyPe(), dest_proc);
+        migrateMe(dest_proc);
+    }
+  }
+
+  void pup(PUP::er &p) {
+      ArrayElement1D::pup(p);
+      p | comlib;
+      p | verbose;
+
+      p | hProxy;
+      p | curIter;
+      p | verbose;        
+
+      if(p.isUnpacking()) {
+          willRecv = new int[nElements];
+          haveRecv = new int[nElements];
+      }
+      
+      p(willRecv, nElements);
+      p(haveRecv, nElements);        
+  }
+};
+
+#include "hello.def.h"
diff --git a/tests/charm++/commtest/comlib/hello.ci b/tests/charm++/commtest/comlib/hello.ci
new file mode 100644 (file)
index 0000000..be61ab7
--- /dev/null
@@ -0,0 +1,15 @@
+mainmodule hello {
+  readonly CProxy_Main mainProxy;
+  readonly int nElements;
+
+  mainchare Main {
+    entry Main(CkArgMsg *m);
+    entry void done(void);
+  };
+
+  array [1D] Hello {
+    entry Hello(ComlibInstanceHandle comlib_);
+    entry void startMcast(int nIter,int send[nElements],int recv[nElements]);
+    entry void midMcast(int nIter,int src);
+  };           
+};
diff --git a/tests/charm++/commtest/commlib_stream/Makefile b/tests/charm++/commtest/commlib_stream/Makefile
new file mode 100644 (file)
index 0000000..9ac80b9
--- /dev/null
@@ -0,0 +1,20 @@
+CHARMC=../../../../bin/charmc $(OPTS)
+
+OBJS = hello.o
+
+all: hello
+
+hello: $(OBJS)
+       $(CHARMC) -language charm++ -o hello $(OBJS) -module comlib
+
+hello.decl.h: hello.ci
+       $(CHARMC)  hello.ci
+
+clean:
+       rm -f *.decl.h *.def.h conv-host *.o hello charmrun *.log *.sum *.sts
+
+hello.o: hello.C hello.decl.h
+       $(CHARMC) -c hello.C
+
+test: all
+       ./charmrun hello +p4 10
diff --git a/tests/charm++/commtest/commlib_stream/hello.C b/tests/charm++/commtest/commlib_stream/hello.C
new file mode 100644 (file)
index 0000000..2c96897
--- /dev/null
@@ -0,0 +1,83 @@
+
+#include <stdio.h>
+#include "hello.decl.h"
+#include "StreamingStrategy.h"
+
+/*readonly*/ CProxy_Main mainProxy;
+/*readonly*/ int nElements;
+
+#define TEST_HI 4001
+
+/*mainchare*/
+class Main : public Chare
+{
+  double startTime;
+public:
+  Main(CkArgMsg* m)
+  {
+    //Process command-line arguments
+    nElements=5;
+    if(m->argc >1 ) nElements=atoi(m->argv[1]);
+    delete m;
+
+    //Start the computation
+    CkPrintf("Running Hello on %d processors for %d elements\n",
+            CkNumPes(),nElements);
+    mainProxy = thishandle;
+
+    CProxy_Hello arr = CProxy_Hello::ckNew(nElements);
+
+    StreamingStrategy *strat=new StreamingStrategy(1,10);
+
+    strat->enableShortArrayMessagePacking();
+    //strat->disableIdleFlush();
+    
+    ComlibInstanceHandle cinst = CkGetComlibInstance();
+    cinst.setStrategy(strat); 
+    
+    startTime=CkWallTimer();
+    CkPrintf("Starting ring...\n");
+    arr.SayHi(TEST_HI);
+  };
+
+  void done(void)
+  {
+    CkPrintf("All done: %d elements in %f seconds\n", nElements,
+       CkWallTimer()-startTime);
+    CkExit();
+  };
+};
+
+/*array [1D]*/
+class Hello : public CBase_Hello 
+{
+public:
+  Hello()
+  {
+
+  }
+
+  Hello(CkMigrateMessage *m) {}
+  
+  void SayHi(int hiNo)
+  {
+      static int recv_count = 0;
+
+      CkAssert(hiNo >= TEST_HI);
+
+      // CkPrintf("Hi[%d] from element %d\n",hiNo,thisIndex);
+      CProxy_Hello array_proxy = thisProxy;
+      ComlibDelegateProxy(&array_proxy);
+      
+      if (thisIndex < nElements-1)
+          //Pass the hello on:
+          array_proxy[thisIndex+1].SayHi(hiNo+1);
+      else if(recv_count == nElements-1)
+          //We've been around once-- we're done.
+          mainProxy.done();    
+      else
+          recv_count ++;
+  }
+};
+
+#include "hello.def.h"
diff --git a/tests/charm++/commtest/commlib_stream/hello.ci b/tests/charm++/commtest/commlib_stream/hello.ci
new file mode 100644 (file)
index 0000000..312b25f
--- /dev/null
@@ -0,0 +1,14 @@
+mainmodule hello {
+  readonly CProxy_Main mainProxy;
+  readonly int nElements;
+
+  mainchare Main {
+    entry Main(CkArgMsg *m);
+    entry void done(void);
+  };
+
+  array [1D] Hello {
+    entry Hello(void);
+    entry void SayHi(int hiNo);
+  };           
+};
diff --git a/tests/charm++/loadbalancing/lb_test/Makefile b/tests/charm++/loadbalancing/lb_test/Makefile
new file mode 100644 (file)
index 0000000..27c9c3c
--- /dev/null
@@ -0,0 +1,31 @@
+# Makefile for load-banacing test program
+
+OPTS=
+LBLIB=-module EveryLB 
+CHARMC=../../../bin/charmc $(OPTS)
+
+OBJS = lb_test.o Topo.o
+
+all:   lb_test
+
+lb_test: $(OBJS)
+       $(CHARMC) -language charm++ -o lb_test $(OBJS) $(LBLIB)
+
+lb_test.decl.h lb_test.def.h: lb_test.ci
+       $(CHARMC)  lb_test.ci 
+
+Topo.decl.h Topo.def.h: Topo.ci
+       $(CHARMC)  Topo.ci 
+
+lb_test.o: lb_test.C lb_test.decl.h Topo.decl.h
+       $(CHARMC) -c lb_test.C
+
+Topo.o: Topo.C Topo.h Topo.decl.h
+       $(CHARMC) -c Topo.C
+
+test:  lb_test
+       ./charmrun +p4 ./lb_test 100 100 10 40 10 1000 comm ring +LBDebug
+
+clean:
+       rm -f *.decl.h *.def.h conv-host *.o lb_test charmrun
+
diff --git a/tests/charm++/loadbalancing/lb_test/README b/tests/charm++/loadbalancing/lb_test/README
new file mode 100644 (file)
index 0000000..4d999c8
--- /dev/null
@@ -0,0 +1,19 @@
+Information on the Load Balancing Framework
+         Test Program
+
+This program tests out the various strategies
+used for load balancing.  The basic configuration
+is a ring of Array elements who do some computation, 
+then send a "compute" message to the next
+element of the ring.  Computation proceeds
+in parallel across all members of the ring
+(main() calls each element's "compute" to
+start everything going).
+
+Note:
+       To compile this program, you'll need
+to link with the Metis library, on NCSA machines
+at ~milind/libmetis.a.  The only way I know
+to do that is to use charmc -verbose to get the
+command line, then paste ~milind/libmetis.a 
+in at the end.
diff --git a/tests/charm++/loadbalancing/lb_test/Topo.C b/tests/charm++/loadbalancing/lb_test/Topo.C
new file mode 100644 (file)
index 0000000..d2530d2
--- /dev/null
@@ -0,0 +1,310 @@
+#include <math.h>
+#include <charm++.h>
+
+#include "Topo.h"
+#include "Topo.def.h"
+
+CkGroupID Topo::Create(const int _elem, const char* _topology, 
+                      const int min_us, const int max_us)
+{
+  int topo = Select(_topology);
+  if (topo == -1)
+    //The user's topology name wasn't in the table-- also bad!
+    CkAbort("ERROR! Topology not found!  \n");
+
+  TopoInitMsg* tmsg = new TopoInitMsg;
+  tmsg->elements = _elem;
+  tmsg->topology = topo;
+  tmsg->seed = 12345;
+  tmsg->min_us = min_us;
+  tmsg->max_us = max_us;
+  CkGroupID topo_id = CProxy_Topo::ckNew(tmsg);
+  return topo_id;
+}
+
+int Topo::Select(const char* _topo)
+{
+  int i=0;
+  while (TopoTable[i].name) {
+    if (strcasecmp(_topo,TopoTable[i].name) == 0) {
+      CkPrintf("Selecting Topology %s\n",TopoTable[i].name);
+      return TopoTable[i].id;
+    }
+    i++;
+  }
+  CkPrintf("Unknown topology %s\n",_topo);
+  return TopoError;
+}
+
+Topo::Topo(TopoInitMsg* _m)
+{
+  elements = _m->elements;
+  topo = TopoType(_m->topology);
+  seed = _m->seed;
+  min_us = _m->min_us;
+  max_us = _m->max_us;
+
+  // Do this first, to make sure everyone gets the same seed
+  srand(seed);
+
+  if (CkMyPe()==0)
+    CkPrintf("Generating topology %d for %d elements\n",topo,elements);
+  elemlist = new Elem[elements];
+
+  FindComputeTimes();
+
+  // Re-seed, so we can change the graph independent of computation
+  srand(seed);
+
+  switch (topo) {
+  case TopoRing:
+    ConstructRing();
+    break;
+  case  TopoMesh2D:
+    ConstructMesh2D();
+    break;
+  case  TopoRandGraph:
+    ConstructRandGraph();
+    break;
+  };
+
+  delete _m;
+}
+
+void Topo::FindComputeTimes()
+{
+  int i;
+  double total_work = 0;
+  const double em1 = exp(1.) - 1;
+  for(i=0; i < elements; i++) {
+    double work;
+    do {  
+      // Gaussian doesn't give a bad enough distribution
+      // work = gasdev() * devms + meanms;
+      //work = (int)(((2.*devms*rand()) / RAND_MAX + meanms - devms) + 0.5);
+      // Randomly select 10% to do 4x more work
+//      if ((10.*rand())/RAND_MAX < 1.)
+//     work *= 4;
+//      work = meanms-devms + 2*devms*(exp((double)rand()/RAND_MAX)-1) / em1;
+      work = min_us + (max_us-min_us)*pow((double)rand()/RAND_MAX,4.);
+    } while (work < 0);
+    elemlist[i].work = work;
+    // CkPrintf("%d work %f\n", i, work);
+    total_work += work;
+  }
+  if (CkMyPe() == 0)
+    CkPrintf("[%d] Total work/step = %f sec\n",CkMyPe(),total_work*1e-6);
+      
+}
+
+float Topo::gasdev()
+{
+  // Based on Numerical Recipes, but throw away extra deviate.
+  float fac,r,v1,v2;
+
+  do {
+    v1 = (rand() * 2.)/RAND_MAX - 1.;
+    v2 = (rand() * 2.)/RAND_MAX - 1.;
+    r = v1*v1 + v2*v2;
+  } while (r >= 1.0);
+  fac = sqrt(-2.0*log(r)/r);
+  return v2 * fac;
+}
+
+void Topo::ConstructRing()
+{
+  int i;
+  for(i=0;i<elements;i++) {
+    elemlist[i].receivefrom = new MsgInfo;
+    elemlist[i].sendto = new MsgInfo;
+    int from = i-1;
+    if (from < 0) from = elements-1;
+    elemlist[i].receivefrom->obj = from;
+    elemlist[i].receivefrom->bytes = N_BYTES;
+    elemlist[i].receiving = 1;
+
+    int to = i+1;
+    if (to == elements) to = 0;
+    elemlist[i].sendto->obj = to;
+    elemlist[i].sendto->bytes = N_BYTES;
+    elemlist[i].sending = 1;
+  }
+}
+
+void Topo::ConstructMesh2D()
+{
+  // How should I build a mesh?  I'll make it close to square, and not
+  // communicate with nonexistent elements
+
+  int nrows = (int)(sqrt(1.0*elements) + 0.5); // Round it
+  if (nrows < 1) nrows = 1;
+  int ncols = elements / nrows;
+  while (nrows * ncols < elements) ncols++;
+
+  if (CkMyPe() == 0)
+    CkPrintf("Building a %d x %d mesh, with %d missing elements\n",
+            nrows,ncols,nrows*ncols-elements);
+
+  int i;
+  for(i=0;i<elements;i++) {
+    elemlist[i].receivefrom = new MsgInfo[4];
+    elemlist[i].sendto = new MsgInfo[4];
+    elemlist[i].receiving = elemlist[i].sending = 0;
+  }
+
+  for(i=0;i<elements;i++) {
+    const int r = i / ncols;
+    const int c = i % ncols;
+
+    const int to_r[4] = { r+1, r,   r-1, r   };
+    const int to_c[4] = { c,   c+1, c,   c-1 };
+
+    for(int nbor = 0; nbor < 4; nbor++) {
+      int dest_r = to_r[nbor];
+      int dest_c = to_c[nbor];
+      if (   dest_r >= nrows || dest_r < 0
+         || dest_c >= ncols || dest_c < 0 )
+       continue;
+
+      int dest = dest_r * ncols + dest_c;
+      if (dest >= elements || dest < 0) 
+       continue;
+
+      // CkPrintf("[%d]Element %d (%d,%d) is sending to element %d(%d,%d)\n",
+      //           CkMyPe(),i,r,c,dest,dest_r,dest_c);
+
+      elemlist[i].sendto[elemlist[i].sending].obj = dest;
+      elemlist[i].sendto[elemlist[i].sending].bytes = N_BYTES;
+      elemlist[i].sending++;
+
+      elemlist[dest].receivefrom[elemlist[dest].receiving].obj = i;
+      elemlist[dest].receivefrom[elemlist[dest].receiving].bytes = N_BYTES;
+      elemlist[dest].receiving++;
+    }
+  }
+}
+
+void Topo::ConstructRandGraph()
+{
+  // First, build a ring.  Then add more random links on top of those
+  // To build the links, we will make a big temporary array for connections
+  const int num_connections = elements * (elements - 1);
+  int connections_made = 0;
+  int connections_tried = 0;
+
+  const double ratio = .01;
+
+  int i;
+  for(i=0;i<elements;i++)
+    elemlist[i].receiving = elemlist[i].sending = 0;
+
+  // To save memory, I will use this slightly more complicated algorithm
+  // A) For each from element
+  //    1) Compute the from links for each processor
+  //    2) Allocate and store enough memory for that list
+  //    3) Keep track of how many each receiver will get
+  // B) For each to element
+  //    1) Allocate enough elements for the to list
+  // C) For each from element
+  //    1) Copy the from list to the to list
+
+  int* receivefrom = new int[elements];
+  for(i=0;i<elements;i++)
+    receivefrom[i] = 0;
+
+  int from;
+  for(from=0; from < elements; from++) {
+    int n_sends = 0;
+    MsgInfo* sendto = new MsgInfo[elements];
+
+    // First, build the ring link
+    int to = (from+1) % elements;
+    receivefrom[to]++;
+    sendto[n_sends].obj = to;
+    sendto[n_sends].bytes = N_BYTES;
+    n_sends++;
+    connections_made++;
+    connections_tried++;
+
+    // Now check out the rest of the links for this processor
+    // Examine each possible destination
+    for(int j=2; j < elements; j++) {
+      const int to = (from + j) % elements;
+      const int to_make = (int)(ratio * num_connections - connections_made);
+      const int to_try = num_connections - connections_tried;
+      const double myrand = ((double) rand() * to_try) / RAND_MAX;
+
+      if (myrand < to_make) {
+       int findx = n_sends++;
+       sendto[findx].obj = to;
+       sendto[findx].bytes = N_BYTES;
+       receivefrom[to]++;
+       connections_made++;
+      }
+      connections_tried++;
+    }
+    // Okay, now we have all of the outgoing links for this processor,
+    // so we just have to copy them into the elemlist
+    if (n_sends > elements)
+      CkPrintf("%s:%d Too many sends attempted %d %d\n",
+              __FILE__,__LINE__,n_sends,elements);
+    elemlist[from].sending = n_sends;
+    elemlist[from].sendto = new MsgInfo[n_sends];
+    int i;
+    for(i=0;i<n_sends;i++)
+      elemlist[from].sendto[i] = sendto[i];
+
+    delete [] sendto;
+  }
+
+  // Now that we've created all of the send lists, and we know how many
+  // elements we will receive, we can create the receivefrom lists
+  for(int to=0; to < elements; to++)
+    elemlist[to].receivefrom = new MsgInfo[receivefrom[to]];
+
+  for(from=0;from<elements;from++) {
+    for(int i=0; i < elemlist[from].sending; i++) {
+      int to = elemlist[from].sendto[i].obj;
+      if (elemlist[to].receiving < receivefrom[to]) {
+       int tindex = elemlist[to].receiving++;
+       elemlist[to].receivefrom[tindex].obj = from;
+       elemlist[to].receivefrom[tindex].bytes = N_BYTES;
+      } else {
+       CkPrintf("%s:%d Too many receives going to %d: %d\n",
+                __FILE__,__LINE__,to,elemlist[to].receiving);
+      }
+    }
+  }
+
+  delete [] receivefrom;
+
+  if (CkMyPe() == 0) {
+    CkPrintf(
+      "Built random graph with %d of %d possible links (%f percent)\n",
+      connections_made,num_connections,
+      (100.0*connections_made)/num_connections);
+  }
+}
+
+int Topo::SendCount(int index)
+{
+  return elemlist[index].sending;
+}
+
+void Topo::SendTo(int index, MsgInfo* who)
+{
+  for(int i=0; i < elemlist[index].sending; i++)
+    who[i] = elemlist[index].sendto[i];
+}
+
+int Topo::RecvCount(int index)
+{
+  return elemlist[index].receiving;
+}
+
+void Topo::RecvFrom(int index, MsgInfo* who)
+{
+  for(int i=0; i < elemlist[index].receiving; i++)
+    who[i] = elemlist[index].receivefrom[i];
+}
diff --git a/tests/charm++/loadbalancing/lb_test/Topo.ci b/tests/charm++/loadbalancing/lb_test/Topo.ci
new file mode 100644 (file)
index 0000000..3bf0c08
--- /dev/null
@@ -0,0 +1,9 @@
+module Topo {
+
+message TopoInitMsg;
+
+group Topo {
+  entry Topo(TopoInitMsg*);  
+};
+
+};
\ No newline at end of file
diff --git a/tests/charm++/loadbalancing/lb_test/Topo.h b/tests/charm++/loadbalancing/lb_test/Topo.h
new file mode 100644 (file)
index 0000000..ef0fb1d
--- /dev/null
@@ -0,0 +1,81 @@
+#ifndef TOPO_H
+#define TOPO_H
+
+#include "Topo.decl.h"
+
+enum { N_BYTES=1000 };
+
+class TopoInitMsg : public CMessage_TopoInitMsg {
+public:
+  int elements;
+  int topology;
+  int seed;
+  int min_us;
+  int max_us;
+};
+
+enum TopoType { TopoRing, TopoMesh2D, TopoRandGraph, TopoError=-1 };
+static const struct { 
+  const char* name;
+  const char* desc;
+  TopoType id;
+} TopoTable[] = {
+  { "Ring",
+    "ring - use ring topology",
+    TopoRing },
+  { "Mesh2D", 
+    "mesh2d - construct a 2D mesh, with holes", 
+    TopoMesh2D },
+  { "RandGraph", 
+    "randgraph - construct a graph, with 25% of links used",
+    TopoRandGraph },
+  { NULL, NULL, TopoError }
+};
+
+
+class Topo : public Group {
+public:
+  struct MsgInfo {
+    int obj;
+    int bytes;
+  };
+
+  Topo(CkMigrateMessage *m) {}
+  Topo(TopoInitMsg*);
+  double Work(int indx) { return elemlist[indx].work; };
+  static CkGroupID Create(const int _elem, const char*_topo, 
+                   const int meanms, const int devms);
+  int SendCount(int index);
+  void SendTo(int index, MsgInfo* who);
+  int RecvCount(int index);
+  void RecvFrom(int index, MsgInfo* who);
+
+private:
+  struct Elem;
+  friend struct Elem;  // Apparently, a private struct can't access another
+                       // private struct without this!
+
+  static int Select(const char*);
+  void FindComputeTimes();
+  void ConstructRing();
+  void ConstructMesh2D();
+  void ConstructRandGraph();
+  float gasdev();
+
+  struct Elem {
+    double work;
+    int receiving;
+    int sending;
+    MsgInfo* receivefrom;
+    MsgInfo* sendto;
+  };
+
+  TopoType topo;
+  int elements;
+  Elem* elemlist;
+  int seed;
+  int min_us;
+  int max_us;
+};
+
+#endif
diff --git a/tests/charm++/loadbalancing/lb_test/faceoff b/tests/charm++/loadbalancing/lb_test/faceoff
new file mode 100755 (executable)
index 0000000..74653fa
--- /dev/null
@@ -0,0 +1,21 @@
+#!/bin/sh
+# A shell script to compare the various load-balancing
+# strategies.
+
+stratList="greedy metis random none"
+
+mkdir out
+processors=8
+lb_arg="1200 32 1 5"
+
+for strategy in `echo $stratList`
+do
+       echo "---- $strategy:---"
+       file1="out/run.$strategy"
+       file2="out/time.$strategy"
+       mpirun -np $processors lb_test $strategy $lb_arg | tee $file1
+       head $file1 > $file2
+       grep GREP00 $file1 >> $file2
+done
+
+echo "Timings in out/"
diff --git a/tests/charm++/loadbalancing/lb_test/lb_test.C b/tests/charm++/loadbalancing/lb_test/lb_test.C
new file mode 100644 (file)
index 0000000..4f9c114
--- /dev/null
@@ -0,0 +1,478 @@
+/*
+Load-balancing test program:
+  Orion Sky Lawlor, 10/19/1999
+
+  Added more complex comm patterns
+  Robert Brunner, 11/3/1999
+
+  updated by
+  Gengbin Zheng
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <math.h>
+#include "charm++.h"
+#include "LBDatabase.h"
+#include "Topo.h"
+#include "CentralLB.h"
+#include "RandCentLB.h"
+#include "RecBisectBfLB.h"
+#include "RefineLB.h"
+#include "RefineCommLB.h"
+#include "GreedyCommLB.h"
+#include "MetisLB.h"
+#include "GreedyLB.h"
+#include "NeighborLB.h"
+#include "WSLB.h"
+#include "GreedyRefLB.h"
+#include "RandRefLB.h"
+#include "OrbLB.h"
+
+#include "lb_test.decl.h"
+
+CkChareID mid;//Main ID
+CkGroupID topoid;
+CProxy_Lb_array hproxy;//Array ID
+int n_loadbalance;
+
+#define N_LOADBALANCE 500 /*Times around ring until we load balance*/
+
+#define DEBUGF(x)       // CmiPrintf x
+int cycle_count,element_count,step_count,print_count;
+int min_us,max_us;
+
+class HiMsg : public CMessage_HiMsg {
+public:
+  int length;
+  int chksum;
+  int refnum;
+  char* data;
+};
+
+class main : public CBase_main {
+public:
+  int nDone;
+
+  main(CkMigrateMessage *m) {}
+  main(CkArgMsg* m);
+
+  void maindone(void) {
+    nDone++;
+    if (nDone==element_count) {
+      CkPrintf("All done\n");
+      CkExit();
+    }
+  };
+
+private:
+  void arg_error(char* argv0);
+};
+
+static const struct {
+  const char *name;//Name of strategy (on command line)
+  const char *description;//Text description of strategy
+  LBCreateFn create;//Strategy routine
+} StratTable[]={
+  {"none",
+   "none - The null load balancer, collect data, do nothing",
+   CreateCentralLB},
+  {"neighbor",
+   "neighbor - The neighborhood load balancer",
+   CreateNeighborLB},
+  {"workstation",
+   "workstation - Like neighbor, but for workstation performance",
+   CreateWSLB},
+  {"random",
+   "random - Assign objects to processors randomly",
+   CreateRandCentLB},
+  {"greedy",
+   "greedy - (Greedy) Use the greedy algorithm to place heaviest object on the "
+   "least-loaded processor until done",
+   CreateGreedyLB},
+  {"metis",
+   "metis - Use Metis(tm) to partition object graph",
+   CreateMetisLB},
+  {"refine",
+   "refine - Move a very few objects away from most heavily-loaded processor",
+   CreateRefineLB},
+  {"refinecomm",
+   "refinecomm - Move a very few objects away from most heavily-loaded processor, taking communicaiton into account",
+   CreateRefineCommLB},
+  {"orb",
+   "orb - Orthogonal Recursive Bisection to partition according to coordinates",
+   CreateOrbLB},
+  {"greedyref",
+   "greedyref - Apply greedy, then refine",
+   CreateGreedyRefLB},
+  {"randref",
+   "randref - Apply random, then refine",
+   CreateRandRefLB},
+  {"comm",
+   "comm - Greedy with communication",
+   CreateGreedyCommLB},
+  {"recbf",
+   "recbf - Recursive partitioning with Breadth first enumeration, with 2 nuclei",
+   CreateRecBisectBfLB},
+
+  {NULL,NULL,NULL}
+};
+
+static void programBegin(void *dummy,int size,void *data)
+{
+  //Start everybody computing
+  for (int i=0;i<element_count;i++)
+    hproxy[i].ForwardMessages();
+}
+
+main::main(CkArgMsg *m) 
+{
+  char *strategy;//String name for strategy routine
+  char *topology;//String name for communication topology
+  int stratNo;
+  nDone=0;
+
+  int cur_arg = 1;
+
+  if (m->argc > cur_arg)
+    element_count=atoi(m->argv[cur_arg++]);
+  else arg_error(m->argv[0]);
+
+  if (m->argc > cur_arg)
+    step_count=atoi(m->argv[cur_arg++]);
+  else arg_error(m->argv[0]);
+  
+  if (m->argc > cur_arg)
+    print_count=atoi(m->argv[cur_arg++]);
+  else arg_error(m->argv[0]);
+  
+  if (m->argc > cur_arg)
+    n_loadbalance=atoi(m->argv[cur_arg++]);
+  else arg_error(m->argv[0]);
+
+  if (m->argc > cur_arg)
+    min_us=atoi(m->argv[cur_arg++]);
+  else arg_error(m->argv[0]);
+
+  if (m->argc > cur_arg)
+    max_us=atoi(m->argv[cur_arg++]);
+  else arg_error(m->argv[0]);
+
+  if (m->argc > cur_arg)
+    strategy=m->argv[cur_arg++];
+  else arg_error(m->argv[0]);
+
+  if (m->argc > cur_arg)
+    topology=m->argv[cur_arg++];
+  else arg_error(m->argv[0]);
+
+  //Look up the user's strategy in table
+  stratNo=0;
+  while (StratTable[stratNo].name!=NULL) {
+    if (0==strcasecmp(strategy,StratTable[stratNo].name)) {
+      //We found the user's chosen strategy!
+      StratTable[stratNo].create();//Create this strategy
+      break;
+    }
+    stratNo++;
+  }
+
+  CkPrintf("%d processors\n",CkNumPes());
+  CkPrintf("%d elements\n",element_count);
+  CkPrintf("Print every %d steps\n",print_count);
+  CkPrintf("Sync every %d steps\n",n_loadbalance);
+  CkPrintf("First node busywaits %d usec; last node busywaits %d usec\n",
+          min_us,max_us);
+
+  mid = thishandle;
+
+
+  if (StratTable[stratNo].name==NULL)
+    //The user's strategy name wasn't in the table-- bad!
+    CkAbort("ERROR! Strategy not found!  \n");
+       
+  topoid = Topo::Create(element_count,topology,min_us,max_us);
+  if (topoid.isZero())
+    CkAbort("ERROR! Topology not found!  \n");
+
+  hproxy = CProxy_Lb_array::ckNew(element_count);
+  hproxy.setReductionClient(programBegin, NULL);
+
+/*
+  //Start everybody computing
+  for (int i=0;i<element_count;i++)
+    hproxy[i].ForwardMessages();
+*/
+};
+
+void main::arg_error(char* argv0)
+{
+  CkPrintf("Usage: %s \n"
+    "<elements> <steps> <print-freq> <lb-freq> <min-dur us> <max-dur us>\n"
+    "<strategy> <topology>\n"
+    "<strategy> is the load-balancing strategy:\n",argv0);
+  int stratNo=0;
+  while (StratTable[stratNo].name!=NULL) {
+    CkPrintf("  %s\n",StratTable[stratNo].description);
+    stratNo++;
+  }
+
+  int topoNo = 0;
+  CkPrintf("<topology> is the object connection topology:\n");
+  while (TopoTable[topoNo].name) {
+    CkPrintf("  %s\n",TopoTable[topoNo].desc);
+    topoNo++;
+  }
+
+  CmiPrintf("\n"
+          " The program creates a ring of element_count array elements,\n"
+          "which all compute and send to their neighbor cycle_count.\n"
+          "Computation proceeds across the entire ring simultaniously.\n"
+          "Orion Sky Lawlor, olawlor@acm.org, PPL, 10/14/1999\n");
+  CmiAbort("Abort!");
+}
+
+class Lb_array : public CBase_Lb_array {
+public:
+  Lb_array(void) {
+    //    CkPrintf("Element %d created\n",thisIndex);
+
+    //Find out who to send to, and how many to receive
+    TopoMap = CProxy_Topo::ckLocalBranch(topoid);
+    send_count = TopoMap->SendCount(thisIndex);
+    send_to = new Topo::MsgInfo[send_count];
+    TopoMap->SendTo(thisIndex,send_to);
+    recv_count = TopoMap->RecvCount(thisIndex)+1;
+    
+    // Benchmark the work function
+    work_per_sec = CalibrateWork();
+
+    //Create massive load imbalance by making load
+    // linear in processor number.
+    usec = (int)TopoMap->Work(thisIndex);
+    DEBUGF(("Element %d working for %d ms\n",thisIndex,usec));
+
+    //msec=meanms+(devms-meanms)*thisIndex/(element_count-1);
+
+    // Initialize some more variables
+    nTimes=0;
+    sendTime=0;
+//    lastTime=CmiWallTimer();
+    n_received = 0;
+    resumed = 1;
+    busywork = (int)(usec*1e-6*work_per_sec);
+    
+    int i;
+    for(i=0; i < future_bufsz; i++)
+      future_receives[i]=0;
+       
+    usesAtSync=CmiTrue;
+
+    contribute(sizeof(i), &i, CkReduction::sum_int);
+  }
+
+  //Packing/migration utilities
+  Lb_array(CkMigrateMessage *m) {
+    DEBUGF(("Migrated element %d to processor %d\n",thisIndex,CkMyPe()));
+    TopoMap = CProxy_Topo::ckLocalBranch(topoid);
+    //Find out who to send to, and how many to receive
+    send_count = TopoMap->SendCount(thisIndex);
+    send_to = new Topo::MsgInfo[send_count];
+    TopoMap->SendTo(thisIndex,send_to);
+    recv_count = TopoMap->RecvCount(thisIndex)+1;
+    resumed = 0;
+    lastTime = CmiWallTimer();
+  }
+
+  virtual void pup(PUP::er &p)
+  {
+       ArrayElement1D::pup(p);//<- pack our superclass
+       p(nTimes);p(sendTime);
+       p(usec);p(lastTime);
+       p(work_per_sec);
+       p(busywork);
+       p(n_received);
+       p(future_receives,future_bufsz);
+  }
+
+  void Compute(HiMsg *m) { 
+    //Perform computation
+    if (m->refnum > nTimes) {
+      // CkPrintf("[%d] Future message received %d %d\n", thisIndex,nTimes,m->refnum);
+      int future_indx = m->refnum - nTimes - 1;
+      if (future_indx >= future_bufsz) {
+       CkPrintf("[%d] future_indx is too far in the future %d, expecting %d, got %d\n",
+                thisIndex,future_indx,nTimes,m->refnum);
+       thisProxy[thisIndex].Compute(m);
+      } else {
+       future_receives[future_indx]++;
+       delete m;
+      }
+    } else if (m->refnum < nTimes) {
+      CkPrintf("[%d] Stale message received %d %d\n",
+              thisIndex,nTimes,m->refnum);
+      delete m;
+    } else {
+      n_received++;
+
+      //      CkPrintf("[%d] %d n_received=%d of %d\n",
+      //              CkMyPe(),thisIndex,n_received,recv_count);
+      if (n_received == recv_count) {
+       //      CkPrintf("[%d] %d computing %d\n",CkMyPe(),thisIndex,nTimes);
+
+       if (nTimes && nTimes % print_count == 0) {
+         //Write out the current time
+         if (thisIndex==1) {
+           double now = CmiWallTimer();
+           CkPrintf("GREP00\t%d\t%lf\t%lf\n",
+                    nTimes,now,now-lastTime);
+           lastTime=now;
+         }
+       }
+
+       n_received = future_receives[0];
+
+       // Move all the future_receives down one slot
+       int i;
+       for(i=1;i<future_bufsz;i++)
+         future_receives[i-1] = future_receives[i];
+       future_receives[future_bufsz-1] = 0;
+
+       nTimes++;//Increment our "times around" 
+
+       double startTime=CmiWallTimer();
+       // First check contents of message
+       //     int chksum = 0;
+       //     for(int i=0; i < m->length; i++)
+       //       chksum += m->data[i];
+      
+       //     if (chksum != m->chksum)
+       //       CkPrintf("Checksum mismatch! %d %d\n",chksum,m->chksum);
+
+       //Do Computation:
+       work(busywork,&result);
+       
+       int loadbalancing = 0;
+       if (nTimes == step_count) {
+         //We're done-- send a message to main telling it to die
+         CProxy_main mproxy(mid);
+         mproxy.maindone();
+       } else if (nTimes % n_loadbalance == 0) {
+         //We're not done yet...
+         //Either load balance, or send a message to the next guy
+         DEBUGF(("Element %d AtSync on PE %d\n",thisIndex,CkMyPe()));
+         AtSync();
+         loadbalancing = 1;
+       } else ForwardMessages();
+      }
+      delete m;
+    }
+  }
+
+  void ResumeFromSync(void) { //Called by Load-balancing framework
+    resumed = 1;
+    DEBUGF(("Element %d resumeFromSync on PE %d\n",thisIndex,CkMyPe()));
+    thisProxy[thisIndex].ForwardMessages();
+  }
+
+  void ForwardMessages(void) { //Pass it on
+    if (sendTime == 0) lastTime = CmiWallTimer();
+
+    if (resumed != 1)
+      CkPrintf("[%d] %d forwarding %d %d %d\n",CkMyPe(),thisIndex,
+              sendTime,nTimes,resumed);
+    for(int s=0; s < send_count; s++) {
+      int msgbytes = send_to[s].bytes;
+      if (msgbytes != 1000)
+       CkPrintf("[%d] %d forwarding %d bytes (%d,%d,%p) obj %p to %d\n",
+                CkMyPe(),thisIndex,msgbytes,s,send_count,send_to,
+                this,send_to[s].obj);
+      HiMsg* msg = new(msgbytes,0) HiMsg;
+      msg->length = msgbytes;
+      //      msg->chksum = 0;
+      //      for(int i=0; i < msgbytes; i++) {
+      //       msg->data[i] = i;
+      //       msg->chksum += msg->data[i];
+      //      }
+      msg->refnum = sendTime;
+
+      //      CkPrintf("[%d] %d sending to %d at %d:%d\n",
+      //              CkMyPe(),thisIndex,send_to[s].obj,nTimes,nCycles);
+      thisProxy[send_to[s].obj].Compute(msg);
+    }
+    int mybytes=1;
+    HiMsg* msg = new(mybytes,0) HiMsg;
+    msg->length = mybytes;
+    msg->refnum = sendTime;
+    thisProxy[thisIndex].Compute(msg);
+
+    sendTime++;
+  }
+
+private:
+  int CalibrateWork() {
+    static int calibrated=-1;
+
+    if (calibrated != -1) return calibrated;
+    const double calTime=0.05; //Time to spend in calibration
+    double wps = 0;
+    // First, count how many iterations for 1 second.
+    // Since we are doing lots of function calls, this will be rough
+    const double end_time = CmiWallTimer()+calTime;
+    wps = 0;
+    while(CmiWallTimer() < end_time) {
+      work(100,&result);
+      wps+=100;
+    }
+
+    // Now we have a rough idea of how many iterations there are per
+    // second, so just perform a few cycles of correction by
+    // running for what we think is 1 second.  Then correct
+    // the number of iterations per second to make it closer
+    // to the correct value
+
+    CkPrintf("[%d] Iter  %.0f per second\n",CmiMyPe(), wps);
+    for(int i=0; i < 2; i++) {
+      const double start_time = CmiWallTimer();
+      work((int)wps,&result);
+      const double end_time = CmiWallTimer();
+      const double correction = calTime / (end_time-start_time);
+      wps *= correction;
+      CkPrintf("Iter %d -> %.0f per second\n",i,wps);
+    }
+    calibrated = (int)(wps/calTime);
+    CkPrintf("calibrated iterations %d\n",calibrated);
+    return calibrated;
+  };
+
+  void work(int iter_block,int* _result) {
+    *_result=0;
+    for(int i=0; i < iter_block; i++) {
+      *_result=(int)(sqrt(1+cos(*_result*1.57)));
+    }
+  };
+
+public:
+  enum { future_bufsz = 50 };
+
+private:
+  int nTimes;//Number of times I've been called
+  int sendTime;//Step number for sending (in case I finish receiving
+               //before sending
+  int usec;//Milliseconds to "compute"
+  double lastTime;//Last time recorded
+  int work_per_sec;
+  int busywork;
+  int result;
+
+  Topo* TopoMap;
+  int send_count;
+  int recv_count;
+  Topo::MsgInfo* send_to;
+  int n_received;
+  int future_receives[future_bufsz];
+  int resumed;
+};
+
+#include "lb_test.def.h"
+
diff --git a/tests/charm++/loadbalancing/lb_test/lb_test.ci b/tests/charm++/loadbalancing/lb_test/lb_test.ci
new file mode 100644 (file)
index 0000000..0526d53
--- /dev/null
@@ -0,0 +1,29 @@
+mainmodule lb_test {
+  extern module Topo;
+
+  readonly CkChareID mid;
+  readonly CkGroupID topoid;
+  readonly CProxy_Lb_array hproxy;
+  readonly int element_count;
+  readonly int step_count;
+  readonly int print_count;
+  readonly int min_us;
+  readonly int max_us;
+  readonly int n_loadbalance;
+
+  message HiMsg {
+   char data[];
+  };
+
+  mainchare main {
+    entry main();
+    entry void maindone(void);
+  };
+
+  array [1D] Lb_array {
+    entry Lb_array();
+    entry void Compute(HiMsg *);
+    entry void ForwardMessages(void);
+  };
+};
+
diff --git a/tests/charm++/loadbalancing/lb_test/predictor/Makefile b/tests/charm++/loadbalancing/lb_test/predictor/Makefile
new file mode 100644 (file)
index 0000000..1cadda9
--- /dev/null
@@ -0,0 +1,15 @@
+CHARMC=/home/net/gioachin/charm/bin/charmc $(OPTS)
+
+test:  test.o
+       $(CHARMC) test.o -o test -language charm++ -module RefineLB
+
+test.o:        test.C test.h test.def.h test.decl.h
+       $(CHARMC) -c test.C
+
+test.def.h test.decl.h: test.ci
+       $(CHARMC) test.ci
+
+clean:
+       rm -f charmrun test test.def.h test.decl.h test.o
+
+new:   clean test
diff --git a/tests/charm++/loadbalancing/lb_test/predictor/test.C b/tests/charm++/loadbalancing/lb_test/predictor/test.C
new file mode 100644 (file)
index 0000000..f7fd986
--- /dev/null
@@ -0,0 +1,71 @@
+#include "test.h"
+
+// routine that updates the length of the work done by the object
+#define MYROUTINE(xxx)    xxx==4000 ? 1000 : 4000
+//#define MYROUTINE(xxx)    xxx
+
+#define MAX_ITER  40
+
+Main::Main(CkArgMsg *m) { // entry point of the program
+
+  el = 12;
+  //if (m->argc > 1) el = atoi(m->argv[1]);
+  delete m;
+
+  mainhandle=thishandle;
+  called = 0;
+
+  CProxy_MyArray arr = CProxy_MyArray::ckNew(el);
+  arr.compute();
+}
+
+void Main::allDone() {
+  if (++called = el) {
+    CkExit();
+  }
+}
+
+MyArray::MyArray() {
+  length = 5000;
+  iterations = 0;
+  usesAtSync = true;
+  for (int i=0; i<length; ++i) {
+    data1[i] = rand();
+    data2[i] = rand();
+  }
+}
+
+void MyArray::compute() {
+  CkPrintf("[%d] computing iteration %d, length %d\n",thisIndex,++iterations,length);
+  for (int j=0; j<2000; ++j) {
+  for (int i=0; i<length; ++i) {
+    a[i] = data1[i] * data2[i];
+    b[i] = data1[i] / data2[i];
+  }
+  }
+  AtSync();
+}
+
+void MyArray::ResumeFromSync(void) {
+  length = MYROUTINE(length);
+
+  // exceptions for the Predictor
+  if (iterations == 1) LBTurnPredictorOff();
+  if (iterations == 3) LBTurnPredictorOn(0, 25);
+  if (iterations == 35) LBChangePredictor(new DefaultFunction());
+  if (iterations == 39) {
+    LBTurnPredictorOff();
+    LBTurnPredictorOn(0,15);
+  }
+
+  if (iterations < MAX_ITER) thisProxy[thisIndex].compute();
+  else mainhandle.allDone();
+};
+
+void MyArray::pup(PUP::er &p) {
+  CBase_MyArray::pup(p);
+  p|length;
+  p|iterations;
+}
+
+#include "test.def.h"
diff --git a/tests/charm++/loadbalancing/lb_test/predictor/test.ci b/tests/charm++/loadbalancing/lb_test/predictor/test.ci
new file mode 100644 (file)
index 0000000..7a24fe1
--- /dev/null
@@ -0,0 +1,14 @@
+mainmodule test {
+
+  readonly CProxy_Main mainhandle;
+
+  mainchare Main {
+    entry Main(CkArgMsg *);
+    entry void allDone();
+  };
+
+  array [1D] MyArray {
+    entry MyArray();
+    entry void compute();
+  };
+}
diff --git a/tests/charm++/loadbalancing/lb_test/predictor/test.h b/tests/charm++/loadbalancing/lb_test/predictor/test.h
new file mode 100644 (file)
index 0000000..db4875b
--- /dev/null
@@ -0,0 +1,25 @@
+#include "test.decl.h"
+
+CProxy_Main mainhandle;
+
+class Main : public Chare {
+  int el, called;
+ public:
+  Main(CkArgMsg *m);
+  void allDone();
+};
+
+class MyArray : public CBase_MyArray {
+  double data1[10000];
+  double data2[10000];
+  double a[10000];
+  double b[10000];
+  int length;
+  int iterations;
+ public:
+  MyArray();
+  MyArray(CkMigrateMessage *m) {}
+  void ResumeFromSync(void);
+  void compute();
+  void pup(PUP::er&);
+};
diff --git a/tests/charm++/loadbalancing/lb_test/run b/tests/charm++/loadbalancing/lb_test/run
new file mode 100755 (executable)
index 0000000..47177c5
--- /dev/null
@@ -0,0 +1,10 @@
+strategies="neighbor random greedy metis refine greedyref randref comm recbf"
+for t in ring mesh2d
+do
+  for i in $strategies
+  do
+   cmd="./charmrun +p4 ./lb_test 4000 100 4 16 1000 10000 $i $t"
+   echo $cmd
+   $cmd > out.$i.$t
+  done
+done 
diff --git a/tests/charm++/loadbalancing/lb_test/sim/Makefile b/tests/charm++/loadbalancing/lb_test/sim/Makefile
new file mode 100644 (file)
index 0000000..37957c9
--- /dev/null
@@ -0,0 +1,22 @@
+# Makefile for load-banacing test program
+
+CHARMC= ../../../../bin/charmc $(OPTS)
+
+OBJS = sim.o Topo.o
+
+all:   cifiles sim 
+
+sim: $(OBJS)
+       $(CHARMC) -language charm++ -o sim $(OBJS)
+
+cifiles: sim.ci Topo.ci
+       $(CHARMC)  sim.ci Topo.ci
+
+clean:
+       rm -f *.decl.h *.def.h conv-host *.o sim charmrun
+
+sim.o: sim.C sim.decl.h
+       $(CHARMC) -c -g sim.C 
+
+Topo.o: Topo.C Topo.decl.h Topo.h
+       $(CHARMC) -c -g Topo.C
diff --git a/tests/charm++/loadbalancing/lb_test/sim/Topo.C b/tests/charm++/loadbalancing/lb_test/sim/Topo.C
new file mode 100644 (file)
index 0000000..5eab728
--- /dev/null
@@ -0,0 +1,310 @@
+#include <math.h>
+#include <charm++.h>
+
+#include "Topo.h"
+#include "Topo.def.h"
+
+Topo* Topo::Create(const int _elem, const char* _topology, 
+                      const int min_us, const int max_us)
+{
+  int topo = Select(_topology);
+  if (topo == -1)
+    //The user's topology name wasn't in the table-- also bad!
+    CkAbort("ERROR! Topology not found!  \n");
+
+  TopoInitMsg* tmsg = new TopoInitMsg;
+  tmsg->elements = _elem;
+  tmsg->topology = topo;
+  tmsg->seed = 12345;
+  tmsg->min_us = min_us;
+  tmsg->max_us = max_us;
+
+  return new Topo(tmsg);
+}
+
+int Topo::Select(const char* _topo)
+{
+  int i=0;
+  while (*TopoTable[i].name) {
+    if (strcasecmp(_topo,TopoTable[i].name) == 0) {
+      CkPrintf("Selecting Topology %s\n",TopoTable[i].name);
+      return TopoTable[i].id;
+    }
+    i++;
+  }
+  CkPrintf("Unknown topology %s\n",_topo);
+  return TopoError;
+}
+
+Topo::Topo(TopoInitMsg* _m)
+{
+  CkPrintf("Topo Constructed\n");
+  elements = _m->elements;
+  topo = TopoType(_m->topology);
+  seed = _m->seed;
+  min_us = _m->min_us;
+  max_us = _m->max_us;
+
+  // Do this first, to make sure everyone gets the same seed
+  CrnSrand(seed);
+
+  if (CkMyPe()==0)
+    CkPrintf("Generating topology %d for %d elements\n",topo,elements);
+  elemlist = new Elem[elements];
+
+  FindComputeTimes();
+
+  // Re-seed, so we can change the graph independent of computation
+  CrnSrand(seed);
+
+  switch (topo) {
+  case TopoRing:
+    ConstructRing();
+    break;
+  case  TopoMesh2D:
+    ConstructMesh2D();
+    break;
+  case  TopoRandGraph:
+    ConstructRandGraph();
+    break;
+  };
+
+  delete _m;
+}
+
+void Topo::FindComputeTimes()
+{
+  int i;
+  int total_work = 0;
+  const double em1 = exp(1.) - 1;
+  for(i=0; i < elements; i++) {
+    double work;
+    do {  
+      // Gaussian doesn't give a bad enough distribution
+      // work = gasdev() * devms + meanms;
+      //work = (int)(((2.*devms*rand()) / RAND_MAX + meanms - devms) + 0.5);
+      // Randomly select 10% to do 4x more work
+//      if ((10.*rand())/RAND_MAX < 1.)
+//     work *= 4;
+//      work = meanms-devms + 2*devms*(exp((double)rand()/RAND_MAX)-1) / em1;
+      work = min_us + (max_us-min_us)*pow((double)CrnRand()/RAND_MAX,4.);
+    } while (work < 0);
+    elemlist[i].work = work;
+    total_work += work;
+  }
+  if (CkMyPe() == 0)
+    CkPrintf("[%d] Total work/step = %f sec\n",CkMyPe(),total_work*1e-6);
+      
+}
+
+float Topo::gasdev()
+{
+  // Based on Numerical Recipes, but throw away extra deviate.
+  float fac,r,v1,v2;
+
+  do {
+    v1 = (CrnRand() * 2.)/RAND_MAX - 1.;
+    v2 = (CrnRand() * 2.)/RAND_MAX - 1.;
+    r = v1*v1 + v2*v2;
+  } while (r >= 1.0);
+  fac = sqrt(-2.0*log(r)/r);
+  return v2 * fac;
+}
+
+void Topo::ConstructRing()
+{
+  int i;
+  for(i=0;i<elements;i++) {
+    elemlist[i].receivefrom = new MsgInfo;
+    elemlist[i].sendto = new MsgInfo;
+    int from = i-1;
+    if (from < 0) from = elements-1;
+    elemlist[i].receivefrom->obj = from;
+    elemlist[i].receivefrom->bytes = N_BYTES;
+    elemlist[i].receiving = 1;
+
+    int to = i+1;
+    if (to == elements) to = 0;
+    elemlist[i].sendto->obj = to;
+    elemlist[i].sendto->bytes = N_BYTES;
+    elemlist[i].sending = 1;
+  }
+}
+
+void Topo::ConstructMesh2D()
+{
+  // How should I build a mesh?  I'll make it close to square, and not
+  // communicate with nonexistent elements
+
+  int nrows = sqrt(elements) + 0.5; // Round it
+  if (nrows < 1) nrows = 1;
+  int ncols = elements / nrows;
+  while (nrows * ncols < elements) ncols++;
+
+  if (CkMyPe() == 0)
+    CkPrintf("Building a %d x %d mesh, with %d missing elements\n",
+            nrows,ncols,nrows*ncols-elements);
+
+  int i;
+  for(i=0;i<elements;i++) {
+    elemlist[i].receivefrom = new MsgInfo[4];
+    elemlist[i].sendto = new MsgInfo[4];
+    elemlist[i].receiving = elemlist[i].sending = 0;
+  }
+
+  for(i=0;i<elements;i++) {
+    const int r = i / ncols;
+    const int c = i % ncols;
+
+    const int to_r[4] = { r+1, r,   r-1, r   };
+    const int to_c[4] = { c,   c+1, c,   c-1 };
+
+    for(int nbor = 0; nbor < 4; nbor++) {
+      int dest_r = to_r[nbor];
+      int dest_c = to_c[nbor];
+      if (   dest_r >= nrows || dest_r < 0
+         || dest_c >= ncols || dest_c < 0 )
+       continue;
+
+      int dest = dest_r * ncols + dest_c;
+      if (dest >= elements || dest < 0) 
+       continue;
+
+      // CkPrintf("[%d]Element %d (%d,%d) is sending to element %d(%d,%d)\n",
+      //           CkMyPe(),i,r,c,dest,dest_r,dest_c);
+
+      elemlist[i].sendto[elemlist[i].sending].obj = dest;
+      elemlist[i].sendto[elemlist[i].sending].bytes = N_BYTES;
+      elemlist[i].sending++;
+
+      elemlist[dest].receivefrom[elemlist[dest].receiving].obj = i;
+      elemlist[dest].receivefrom[elemlist[dest].receiving].bytes = N_BYTES;
+      elemlist[dest].receiving++;
+    }
+  }
+}
+
+void Topo::ConstructRandGraph()
+{
+  // First, build a ring.  Then add more random links on top of those
+  // To build the links, we will make a big temporary array for connections
+  const int num_connections = elements * (elements - 1);
+  int connections_made = 0;
+  int connections_tried = 0;
+
+  const double ratio = .01;
+
+  int i;
+  for(i=0;i<elements;i++)
+    elemlist[i].receiving = elemlist[i].sending = 0;
+
+  // To save memory, I will use this slightly more complicated algorithm
+  // A) For each from element
+  //    1) Compute the from links for each processor
+  //    2) Allocate and store enough memory for that list
+  //    3) Keep track of how many each receiver will get
+  // B) For each to element
+  //    1) Allocate enough elements for the to list
+  // C) For each from element
+  //    1) Copy the from list to the to list
+
+  int* receivefrom = new int[elements];
+  for(i=0;i<elements;i++)
+    receivefrom[i] = 0;
+
+  int from;
+  for(from=0; from < elements; from++) {
+    int n_sends = 0;
+    MsgInfo* sendto = new MsgInfo[elements];
+
+    // First, build the ring link
+    int to = (from+1) % elements;
+    receivefrom[to]++;
+    sendto[n_sends].obj = to;
+    sendto[n_sends].bytes = N_BYTES;
+    n_sends++;
+    connections_made++;
+    connections_tried++;
+
+    // Now check out the rest of the links for this processor
+    // Examine each possible destination
+    for(int j=2; j < elements; j++) {
+      const int to = (from + j) % elements;
+      const int to_make = ratio * num_connections - connections_made;
+      const int to_try = num_connections - connections_tried;
+      const double myrand = ((double) CrnRand() * to_try) / RAND_MAX;
+
+      if (myrand < to_make) {
+       int findx = n_sends++;
+       sendto[findx].obj = to;
+       sendto[findx].bytes = N_BYTES;
+       receivefrom[to]++;
+       connections_made++;
+      }
+      connections_tried++;
+    }
+    // Okay, now we have all of the outgoing links for this processor,
+    // so we just have to copy them into the elemlist
+    if (n_sends > elements)
+      CkPrintf("%s:%d Too many sends attempted %d %d\n",
+              __FILE__,__LINE__,n_sends,elements);
+    elemlist[from].sending = n_sends;
+    elemlist[from].sendto = new MsgInfo[n_sends];
+    int i;
+    for(i=0;i<n_sends;i++)
+      elemlist[from].sendto[i] = sendto[i];
+
+    delete [] sendto;
+  }
+
+  // Now that we've created all of the send lists, and we know how many
+  // elements we will receive, we can create the receivefrom lists
+  for(int to=0; to < elements; to++)
+    elemlist[to].receivefrom = new MsgInfo[receivefrom[to]];
+
+  for(from=0;from<elements;from++) {
+    for(int i=0; i < elemlist[from].sending; i++) {
+      int to = elemlist[from].sendto[i].obj;
+      if (elemlist[to].receiving < receivefrom[to]) {
+       int tindex = elemlist[to].receiving++;
+       elemlist[to].receivefrom[tindex].obj = from;
+       elemlist[to].receivefrom[tindex].bytes = N_BYTES;
+      } else {
+       CkPrintf("%s:%d Too many receives going to %d: %d\n",
+                __FILE__,__LINE__,to,elemlist[to].receiving);
+      }
+    }
+  }
+
+  delete [] receivefrom;
+
+  if (CkMyPe() == 0) {
+    CkPrintf(
+      "Built random graph with %d of %d possible links (%f percent)\n",
+      connections_made,num_connections,
+      (100.0*connections_made)/num_connections);
+  }
+}
+
+int Topo::SendCount(int index)
+{
+  return elemlist[index].sending;
+}
+
+void Topo::SendTo(int index, MsgInfo* who)
+{
+  for(int i=0; i < elemlist[index].sending; i++)
+    who[i] = elemlist[index].sendto[i];
+}
+
+int Topo::RecvCount(int index)
+{
+  return elemlist[index].receiving;
+}
+
+void Topo::RecvFrom(int index, MsgInfo* who)
+{
+  for(int i=0; i < elemlist[index].receiving; i++)
+    who[i] = elemlist[index].receivefrom[i];
+}
diff --git a/tests/charm++/loadbalancing/lb_test/sim/Topo.ci b/tests/charm++/loadbalancing/lb_test/sim/Topo.ci
new file mode 100644 (file)
index 0000000..3bf0c08
--- /dev/null
@@ -0,0 +1,9 @@
+module Topo {
+
+message TopoInitMsg;
+
+group Topo {
+  entry Topo(TopoInitMsg*);  
+};
+
+};
\ No newline at end of file
diff --git a/tests/charm++/loadbalancing/lb_test/sim/Topo.h b/tests/charm++/loadbalancing/lb_test/sim/Topo.h
new file mode 100644 (file)
index 0000000..015bccf
--- /dev/null
@@ -0,0 +1,80 @@
+#ifndef TOPO_H
+#define TOPO_H
+
+#include "Topo.decl.h"
+
+enum { N_BYTES=1000};
+
+class TopoInitMsg : public CMessage_TopoInitMsg {
+public:
+  int elements;
+  int topology;
+  int seed;
+  int min_us;
+  int max_us;
+};
+
+enum TopoType { TopoRing, TopoMesh2D, TopoRandGraph, TopoError=-1 };
+static const struct { 
+  const char* name;
+  const char* desc;
+  TopoType id;
+} TopoTable[] = {
+  { "Ring",
+    "ring - use ring topology",
+    TopoRing },
+  { "Mesh2D", 
+    "mesh2d - construct a 2D mesh, with holes", 
+    TopoMesh2D },
+  { "RandGraph", 
+    "randgraph - construct a graph, with 25% of links used",
+    TopoRandGraph },
+  { "", "", TopoError }
+};
+
+
+class Topo : public Group {
+public:
+  struct MsgInfo {
+    int obj;
+    int bytes;
+  };
+
+  Topo(TopoInitMsg*);
+  double Work(int indx) { return elemlist[indx].work; };
+  static Topo* Create(const int _elem, const char*_topo, 
+                   const int meanms, const int devms);
+  int SendCount(int index);
+  void SendTo(int index, MsgInfo* who);
+  int RecvCount(int index);
+  void RecvFrom(int index, MsgInfo* who);
+
+private:
+  struct Elem;
+  friend struct Elem;  // Apparently, a private struct can't access another
+                       // private struct without this!
+
+  static int Select(const char*);
+  void FindComputeTimes();
+  void ConstructRing();
+  void ConstructMesh2D();
+  void ConstructRandGraph();
+  float gasdev();
+
+  struct Elem {
+    double work;
+    int receiving;
+    int sending;
+    MsgInfo* receivefrom;
+    MsgInfo* sendto;
+  };
+
+  TopoType topo;
+  int elements;
+  Elem* elemlist;
+  int seed;
+  int min_us;
+  int max_us;
+};
+
+#endif
diff --git a/tests/charm++/loadbalancing/lb_test/sim/sim.C b/tests/charm++/loadbalancing/lb_test/sim/sim.C
new file mode 100644 (file)
index 0000000..12c68ac
--- /dev/null
@@ -0,0 +1,397 @@
+/*
+Load-balancing test program:
+  Orion Sky Lawlor, 10/19/1999
+
+  Added more complex comm patterns
+  Robert Brunner, 11/3/1999
+
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <math.h>
+#include "charm++.h"
+#include "LBDatabase.h"
+#include "Topo.h"
+#include "CentralLB.h"
+#include "RandCentLB.h"
+#include "RecBisectBfLB.h"
+#include "RefineLB.h"
+#include "GreedyCommLB.h"
+#ifdef USE_METIS
+#include "MetisLB.h"
+#endif
+#include "GreedyLB.h"
+#include "NeighborLB.h"
+#include "WSLB.h"
+#include "GreedyRefLB.h"
+#include "RandRefLB.h"
+
+#include "sim.decl.h"
+
+CkChareID mid;//Main ID
+CkGroupID topoid;
+
+int n_loadbalance;
+
+#define alpha 35e-6
+#define beeta 8e-9
+
+#define N_LOADBALANCE 500 /*Times around ring until we load balance*/
+
+int cycle_count,element_count,step_count,print_count,processor_count;
+int min_us,max_us;
+
+class main : public Chare {
+public:
+  int nDone;
+
+  main(CkArgMsg* m);
+/*
+  void maindone(void);
+*/
+private:
+  void arg_error(char* argv0);
+};
+
+static const struct {
+  const char *name;//Name of strategy (on command line)
+  const char *description;//Text description of strategy
+} StratTable[]={
+  {"none",
+   "none - The null load balancer, collect data, but do nothing"},
+  {"random",
+   "random - Assign objects to processors randomly"},
+  {"greedy",
+   "greedy - Use the greedy algorithm to place heaviest object on the "
+   "least-loaded processor until done"},
+/*
+#ifdef USE_METIS
+  {"metis",
+   "metis - Use Metis(tm) to partition object graph"},
+#endif
+*/
+  {"refine",
+   "refine - Move a very few objects away from most heavily-loaded processor"},
+  {"greedyref",
+   "greedyref - Apply greedy, then refine"},
+  {"randref",
+   "randref - Apply random, then refine"},
+  {"comm",
+   "comm - Greedy with communication"},
+  {"recbf",
+   "recbf - Recursive partitioning with Breadth first enumeration, with 2 nuclei"},
+
+  {NULL,NULL}
+};
+
+int stratNo = 0;
+
+main::main(CkArgMsg *m) 
+{
+  char *strategy;//String name for strategy routine
+  char *topology;//String name for communication topology
+  nDone=0;
+
+  int cur_arg = 1;
+
+  if (m->argc > cur_arg)
+    processor_count=atoi(m->argv[cur_arg++]);
+
+  if (m->argc > cur_arg)
+    element_count=atoi(m->argv[cur_arg++]);
+  else arg_error(m->argv[0]);
+
+  if (m->argc > cur_arg)
+    step_count=atoi(m->argv[cur_arg++]);
+  else arg_error(m->argv[0]);
+  
+  if (m->argc > cur_arg)
+    print_count=atoi(m->argv[cur_arg++]);
+  else arg_error(m->argv[0]);
+  
+  if (m->argc > cur_arg)
+    n_loadbalance=atoi(m->argv[cur_arg++]);
+  else arg_error(m->argv[0]);
+
+  if (m->argc > cur_arg)
+    min_us=atoi(m->argv[cur_arg++]);
+  else arg_error(m->argv[0]);
+
+  if (m->argc > cur_arg)
+    max_us=atoi(m->argv[cur_arg++]);
+  else arg_error(m->argv[0]);
+
+  if (m->argc > cur_arg)
+    strategy=m->argv[cur_arg++];
+  else arg_error(m->argv[0]);
+
+  if (m->argc > cur_arg)
+    topology=m->argv[cur_arg++];
+  else arg_error(m->argv[0]);
+
+  //Look up the user's strategy in table
+  stratNo=0;
+  while (StratTable[stratNo].name!=NULL) {
+    if (0==strcasecmp(strategy,StratTable[stratNo].name)) {
+      break;
+    }
+    stratNo++;
+  }
+
+  CkPrintf("%d processors\n",CkNumPes());
+  CkPrintf("%d elements\n",element_count);
+  CkPrintf("Print every %d steps\n",print_count);
+  CkPrintf("Sync every %d steps\n",n_loadbalance);
+  CkPrintf("First node busywaits %d usec; last node busywaits %d\n",
+          min_us,max_us);
+
+  mid = thishandle;
+
+  if (StratTable[stratNo].name==NULL)
+    //The user's strategy name wasn't in the table-- bad!
+    CkAbort("ERROR! Strategy not found!  \n");
+
+  CentralLB * lb_ptr;
+
+  switch(stratNo){
+  case 0: lb_ptr = new CentralLB;
+         break;         
+  case 1: lb_ptr = new RandCentLB;
+              break;
+  case 2: lb_ptr = new HeapCentLB;
+              break;
+  case 3: lb_ptr = new RefineLB;
+              break;
+  case 4: lb_ptr = new GreedyRefLB;
+              break;
+  case 5: lb_ptr = new RandRefLB;
+              break;
+  case 6: lb_ptr = new CommLB;
+              break;
+  case 7: lb_ptr = new RecBisectBfLB;
+              break;
+  default: CkPrintf("Error: Strategy not found\n");
+              break;
+  }
+
+  Topo* TopoMap;
+  TopoMap = Topo::Create(element_count,topology,min_us,max_us);
+
+  if (TopoMap == NULL)
+    CkAbort("ERROR! Topology not found!  \n");
+  
+  CentralLB::LDStats *stats = new  CentralLB::LDStats[processor_count];
+  int pe,obj,comm,comm_temp;
+
+  for(pe = 0; pe < processor_count; pe++){
+    stats[pe].total_walltime = 0.0;
+    stats[pe].total_cputime = 0.0;
+    stats[pe].idletime = 0.0;
+    stats[pe].bg_walltime = 0.0;
+    stats[pe].bg_cputime = 0.0;
+    stats[pe].n_objs = 0;
+    stats[pe].n_comm = 0;
+    stats[pe].objData = new LDObjData[element_count/processor_count + 1];
+    stats[pe].commData = NULL;
+  }
+  LDObjData* temp_obj;
+  double total_load = 0.0;
+  for(obj = 0; obj < element_count; obj++){
+    temp_obj = &stats[obj%processor_count].objData[obj/processor_count];
+    
+    temp_obj->id.id[0] = obj;
+    temp_obj->id.id[1] = 0;
+    temp_obj->id.id[2] = 0;
+    temp_obj->id.id[3] = 0;
+    
+    temp_obj->omID.id = 0;
+
+    temp_obj->omHandle.id = temp_obj->omID;
+    temp_obj->handle.omhandle = temp_obj->omHandle;
+    temp_obj->handle.id = temp_obj->id;
+
+    temp_obj->cpuTime = temp_obj->wallTime = (TopoMap->Work(obj) * n_loadbalance)*1e-6;
+    total_load += temp_obj->wallTime;
+    stats[obj%processor_count].n_objs++;
+    stats[obj%processor_count].total_walltime = stats[obj%processor_count].total_cputime = 
+      stats[obj%processor_count].total_walltime + temp_obj->wallTime;
+  }
+
+  for(pe = 0; pe < processor_count; pe++){
+    comm = 0;
+    for(obj = 0; obj < stats[pe].n_objs; obj++)
+      comm += TopoMap->SendCount(stats[pe].objData[obj].id.id[0]);
+    stats[pe].commData = new LDCommData[comm];
+    stats[pe].n_comm = comm;    
+    comm = 0;
+    comm_temp = 0;
+
+    for(obj = 0; obj < stats[pe].n_objs; obj++){
+      comm_temp = TopoMap->SendCount(stats[pe].objData[obj].id.id[0]);
+      Topo::MsgInfo *who_arr = new Topo::MsgInfo[comm_temp];
+      TopoMap->SendTo(stats[pe].objData[obj].id.id[0],who_arr);
+      for(int itr = 0; itr < comm_temp; itr++,comm++){
+       stats[pe].commData[comm].from_proc = 0;
+       stats[pe].commData[comm].to_proc = 0;
+       stats[pe].commData[comm].src_proc = 0;
+       stats[pe].commData[comm].dest_proc = 0;
+       stats[pe].commData[comm].senderOM.id = 0;
+       stats[pe].commData[comm].sender = stats[pe].objData[obj].id;
+       stats[pe].commData[comm].receiverOM.id = 0;
+       stats[pe].commData[comm].receiver = stats[pe].commData[comm].sender;
+       stats[pe].commData[comm].receiver.id[0] = who_arr[itr].obj;
+       stats[pe].commData[comm].messages = n_loadbalance;
+       stats[pe].commData[comm].bytes = n_loadbalance * who_arr[itr].bytes;
+      }
+    }
+  }
+  CLBMigrateMsg* msg = lb_ptr->callStrategy(stats,processor_count);
+  
+  int spe=0,dpe=0,new_obj;
+  LDObjData new_objData;
+  CkPrintf("New length %d\n",msg->n_moves);
+
+  for(int move =0; move < msg->n_moves; move++){
+    spe = msg->moves[move].from_pe;
+    dpe = msg->moves[move].to_pe;
+    
+    LDObjData* temp_obj_arr = new LDObjData[stats[spe].n_objs - 1];
+
+    for(obj =0,new_obj=0; obj < stats[spe].n_objs; obj++)
+      if(stats[spe].objData[obj].id.id[0] != msg->moves[move].obj.id.id[0])
+       temp_obj_arr[new_obj++] = stats[spe].objData[obj];
+      else
+       new_objData = stats[spe].objData[obj];
+
+    delete stats[spe].objData; 
+    stats[spe].objData = temp_obj_arr;
+    stats[spe].n_objs--;
+
+    temp_obj_arr = new LDObjData[stats[dpe].n_objs + 1];
+    for(obj = 0; obj < stats[dpe].n_objs; obj++)
+      temp_obj_arr[obj] = stats[dpe].objData[obj];
+    delete stats[dpe].objData; 
+    temp_obj_arr[obj] = new_objData;
+    stats[dpe].objData = temp_obj_arr;    
+    stats[dpe].n_objs++;
+  }
+
+/*
+  for(int move =0; move < msg->n_moves; move++){
+    spe = msg->moves[move].from_pe;
+    dpe = msg->moves[move].to_pe;
+    for(obj =0,new_obj=0; obj < stats[spe].n_objs; obj++)
+      if(stats[spe].objData[obj].id.id[0] == msg->moves[move].obj.id.id[0]){
+       stats[spe].total_walltime -= stats[spe].objData[obj].wallTime;
+       stats[dpe].total_walltime += stats[spe].objData[obj].wallTime;
+       break;
+      }
+  }
+*/
+  double load=0.0,max_load=0.0;
+  int max_pe=0;
+
+  for(pe = 0; pe < processor_count; pe++){
+    load = 0.0;
+    for(obj = 0; obj < stats[pe].n_objs; obj++)
+      load += stats[pe].objData[obj].wallTime;
+    stats[pe].total_cputime = stats[pe].total_walltime = load;
+/*    if(load > max_load){
+      max_pe = pe;
+      max_load = load;
+    } */
+//    CkPrintf("load on %d = %5.3lf\n",pe,load);
+  }
+
+/*
+  for(pe = 0; pe < processor_count; pe++){
+    load = stats[pe].total_walltime;
+    if(load > max_load){
+      max_pe = pe;
+      max_load = load;
+    }
+//    CkPrintf("load on %d = %5.3lf\n",pe,stats[pe].total_walltime);
+  }
+*/
+
+  for(pe = 0; pe < processor_count; pe++)
+    for(obj = 0; obj < stats[pe].n_objs; obj++){
+      int send_count = TopoMap->SendCount(stats[pe].objData[obj].id.id[0]);
+      int recv_count = TopoMap->RecvCount(stats[pe].objData[obj].id.id[0]);
+      Topo::MsgInfo *send_arr = new Topo::MsgInfo[send_count];
+      TopoMap->SendTo(stats[pe].objData[obj].id.id[0],send_arr);
+      Topo::MsgInfo *recv_arr = new Topo::MsgInfo[recv_count];
+      TopoMap->RecvFrom(stats[pe].objData[obj].id.id[0],recv_arr);
+      int cobj =0;
+      int cdata =0;
+      for(int itr = 0; itr < send_count; itr++){
+       cobj = send_arr[itr].obj;
+       cdata = send_arr[itr].bytes;
+       int found = 0;
+       for(int tempObj = 0; tempObj < stats[pe].n_objs; tempObj++)
+         if(stats[pe].objData[tempObj].id.id[0] == cobj){
+           found = 1;
+           break;
+         }
+       if(!found)
+         stats[pe].total_walltime += (alpha/2)*n_loadbalance + beeta*cdata*n_loadbalance; 
+      }
+
+      for(int itr = 0; itr < recv_count; itr++){
+       cobj = recv_arr[itr].obj;
+       cdata = recv_arr[itr].bytes;
+       int found = 0;
+       for(int tempObj = 0; tempObj < stats[pe].n_objs; tempObj++)
+         if(stats[pe].objData[tempObj].id.id[0] == cobj){
+           found = 1;
+           break;
+         }
+       if(!found)
+         stats[pe].total_walltime += (alpha/2)*n_loadbalance + beeta*cdata*n_loadbalance; 
+    }
+  } 
+
+  for(pe = 0; pe < processor_count; pe++){
+    load = 0.0;
+    load = stats[pe].total_walltime;
+    if(load > max_load){
+      max_pe = pe;
+      max_load = load;
+    }
+  }
+
+  CkPrintf("\nmaximum load = %lf\n",max_load);
+  CkPrintf("speedup = %5.3lf\n",total_load/max_load);
+  CkExit();
+}
+
+void main::arg_error(char* argv0)
+{
+  CkPrintf("Usage: %s \n"
+    "<processors>"    
+    "<elements> <steps> <print-freq> <lb-freq> <min-dur us> <max-dur us>\n"
+    "<strategy> <topology>\n"
+    "<strategy> is the load-balancing strategy:\n",argv0);
+  int stratNo=0;
+  while (StratTable[stratNo].name!=NULL) {
+    CkPrintf("  %s\n",StratTable[stratNo].description);
+    stratNo++;
+  }
+
+  int topoNo = 0;
+  CkPrintf("<topology> is the object connection topology:\n");
+  while (TopoTable[topoNo].name) {
+    CkPrintf("  %s\n",TopoTable[topoNo].desc);
+    topoNo++;
+  }
+
+  CkPrintf("\n"
+          " The program creates a ring of element_count array elements,\n"
+          "which all compute and send to their neighbor cycle_count.\n"
+          "Computation proceeds across the entire ring simultaniously.\n");
+  CkExit();
+}
+
+#include "sim.def.h"
+
diff --git a/tests/charm++/loadbalancing/lb_test/sim/sim.ci b/tests/charm++/loadbalancing/lb_test/sim/sim.ci
new file mode 100644 (file)
index 0000000..bf17d27
--- /dev/null
@@ -0,0 +1,24 @@
+mainmodule sim{
+  extern module Topo;
+  extern module CentralLB;
+  extern module RandCentLB;
+  extern module HeapCentLB;
+  extern module RefineLB;
+  extern module NeighborLB;
+  extern module WSLB;
+/*  extern module MetisLB; */
+  extern module GreedyRefLB;
+  extern module RandRefLB;
+  extern module CommLB;
+  extern module RecBisectBfLB;
+
+  readonly CkChareID mid;
+  readonly CkGroupID topoid;
+
+  mainchare main {
+    entry main();
+/*    entry void maindone(void); */
+  };
+
+};
+
diff --git a/tests/charm++/megatest/Make.depends b/tests/charm++/megatest/Make.depends
new file mode 100644 (file)
index 0000000..8639bcb
--- /dev/null
@@ -0,0 +1,180 @@
+#generated by make depends
+megatest.o: \
+       megatest.C \
+       megatest.h \
+       megatest.decl.h \
+       megatest.def.h
+       $(CHARMC) -o megatest.o megatest.C
+groupring.o: \
+       groupring.C \
+       groupring.h \
+       megatest.h \
+       groupring.decl.h \
+       groupring.def.h
+       $(CHARMC) -o groupring.o groupring.C
+nodering.o: \
+       nodering.C \
+       nodering.h \
+       megatest.h \
+       nodering.decl.h \
+       nodering.def.h
+       $(CHARMC) -o nodering.o nodering.C
+varsizetest.o: \
+       varsizetest.C \
+       varsizetest.h \
+       megatest.h \
+       varsizetest.decl.h \
+       varsizetest.def.h
+       $(CHARMC) -o varsizetest.o varsizetest.C
+varraystest.o: \
+       varraystest.C \
+       varraystest.h \
+       megatest.h \
+       varraystest.decl.h \
+       varraystest.def.h
+       $(CHARMC) -o varraystest.o varraystest.C
+groupcast.o: \
+       groupcast.C \
+       groupcast.h \
+       megatest.h \
+       groupcast.decl.h \
+       groupcast.def.h
+       $(CHARMC) -o groupcast.o groupcast.C
+nodecast.o: \
+       nodecast.C \
+       nodecast.h \
+       megatest.h \
+       nodecast.decl.h \
+       nodecast.def.h
+       $(CHARMC) -o nodecast.o nodecast.C
+synctest.o: \
+       synctest.C \
+       synctest.h \
+       megatest.h \
+       synctest.decl.h \
+       synctest.def.h
+       $(CHARMC) -o synctest.o synctest.C
+fib.o: \
+       fib.C \
+       fib.h \
+       megatest.h \
+       fib.decl.h \
+       fib.def.h
+       $(CHARMC) -o fib.o fib.C
+arrayring.o: \
+       arrayring.C \
+       arrayring.h \
+       arrayring.decl.h \
+       megatest.h \
+       arrayring.def.h
+       $(CHARMC) -o arrayring.o arrayring.C
+tempotest.o: \
+       tempotest.C \
+       tempotest.h \
+       megatest.h \
+       tempotest.decl.h \
+       tempotest.def.h
+       $(CHARMC) -o tempotest.o tempotest.C
+packtest.o: \
+       packtest.C \
+       packtest.h \
+       megatest.h \
+       packtest.decl.h \
+       packtest.def.h
+       $(CHARMC) -o packtest.o packtest.C
+queens.o: \
+       queens.C \
+       queens.h \
+       queens.decl.h \
+       megatest.h \
+       queens.def.h
+       $(CHARMC) -o queens.o queens.C
+migration.o: \
+       migration.C \
+       migration.h \
+       migration.decl.h \
+       megatest.h \
+       migration.def.h
+       $(CHARMC) -o migration.o migration.C
+marshall.o: \
+       marshall.C \
+       marshall.h \
+       marshall.decl.h \
+       megatest.h \
+       marshall.def.h
+       $(CHARMC) -o marshall.o marshall.C
+priomsg.o: \
+       priomsg.C \
+       priomsg.h \
+       megatest.h \
+       priomsg.decl.h \
+       priomsg.def.h
+       $(CHARMC) -o priomsg.o priomsg.C
+priotest.o: \
+       priotest.C \
+       priotest.h \
+       priotest.decl.h \
+       megatest.h \
+       priotest.def.h
+       $(CHARMC) -o priotest.o priotest.C
+priolongtest.o: \
+       priolongtest.C \
+       priolongtest.h \
+       priolongtest.decl.h \
+       megatest.h \
+       priolongtest.def.h
+       $(CHARMC) -o priolongtest.o priolongtest.C
+rotest.o: \
+       rotest.C \
+       rotest.h \
+       megatest.h \
+       rotest.decl.h \
+       rotest.def.h
+       $(CHARMC) -o rotest.o rotest.C
+statistics.o: \
+       statistics.C \
+       statistics.h \
+       megatest.h
+       $(CHARMC) -o statistics.o statistics.C
+templates.o: \
+       templates.C \
+       templates.h \
+       templates.decl.h \
+       megatest.h \
+       templates.def.h
+       $(CHARMC) -o templates.o templates.C
+inherit.o: \
+       inherit.C \
+       inherit.h \
+       inherit.decl.h \
+       megatest.h \
+       inherit.def.h
+       $(CHARMC) -o inherit.o inherit.C
+reduction.o: \
+       reduction.C \
+       reduction.h \
+       reduction.decl.h \
+       megatest.h \
+       reduction.def.h
+       $(CHARMC) -o reduction.o reduction.C
+callback.o: \
+       callback.C \
+       callback.h \
+       callback.decl.h \
+       megatest.h \
+       callback.def.h
+       $(CHARMC) -o callback.o callback.C
+immediatering.o: \
+       immediatering.C \
+       immediatering.h \
+       immediatering.decl.h \
+       megatest.h \
+       immediatering.def.h
+       $(CHARMC) -o immediatering.o immediatering.C
+bitvector.o: \
+       bitvector.C \
+       bitvector.h \
+       bitvector.decl.h \
+       megatest.h \
+       bitvector.def.h
+       $(CHARMC) -o bitvector.o bitvector.C
diff --git a/tests/charm++/megatest/Makefile b/tests/charm++/megatest/Makefile
new file mode 100644 (file)
index 0000000..7806351
--- /dev/null
@@ -0,0 +1,109 @@
+CHARMINC=../../../include
+CHARMBIN=../../../bin
+CHARMC=../../../bin/charmc $(OPTS)
+
+OBJS=megatest.o \
+     groupring.o \
+     nodering.o \
+     varsizetest.o \
+     varraystest.o \
+     groupcast.o \
+     nodecast.o \
+     synctest.o \
+     fib.o \
+     arrayring.o \
+     tempotest.o \
+     packtest.o \
+     queens.o \
+     migration.o \
+     marshall.o \
+     priomsg.o \
+     priotest.o \
+     rotest.o \
+     statistics.o \
+     templates.o \
+     inherit.o \
+     reduction.o \
+     callback.o        \
+     immediatering.o \
+     bitvector.o
+
+#     priolongtest.o \
+
+# reverse order of the above OBJS
+OBJS_REV=megatest.o \
+     bitvector.o       \
+     immediatering.o \
+     callback.o        \
+     reduction.o \
+     inherit.o \
+     templates.o \
+     rotest.o \
+     statistics.o \
+     priotest.o \
+     priomsg.o \
+     marshall.o \
+     migration.o \
+     queens.o \
+     packtest.o \
+     tempotest.o \
+     arrayring.o \
+     fib.o \
+     synctest.o \
+     nodecast.o \
+     groupcast.o \
+     varraystest.o \
+     varsizetest.o \
+     nodering.o \
+     groupring.o
+
+#     priolongtest.o \
+
+CIFILES =  \
+      arrayring.def.h  immediatering.def.h  nodering.def.h   rotest.def.h  \
+      bitvector.def.h  inherit.def.h        packtest.def.h   synctest.def.h  \
+      callback.def.h   marshall.def.h       priomsg.def.h    templates.def.h \
+      fib.def.h        megatest.def.h       priotest.def.h   tempotest.def.h  \
+      groupcast.def.h  migration.def.h      queens.def.h     varraystest.def.h\
+      groupring.def.h  nodecast.def.h       reduction.def.h  varsizetest.def.h\
+#      priolongtest.def.h
+
+.SUFFIXES:
+.SUFFIXES: .o .C .def.h .decl.h .ci .h
+
+pgm: $(OBJS)
+       $(CHARMC) -o pgm  $(OBJS) -language charm++
+
+.ci.decl.h:
+       $(CHARMC) -c $<
+
+.decl.h.def.h:
+       @true
+
+DEPENDFILE = Make.depends
+
+include $(DEPENDFILE)
+
+clean:
+       rm -r -f conv-host pgm *.o *.decl.h *.def.h *.log *.sts *~ *.bak charmrun SunWS_cache
+
+test: pgm
+       ./charmrun ./pgm +p1
+       ./charmrun ./pgm +p2
+       ./charmrun ./pgm +p3
+       ./charmrun ./pgm +p4
+
+depends:  $(CIFILES)
+       echo "Creating " $(DEPENDFILE) " ...";  \
+        if [ -f $(DEPENDFILE) ]; then \
+           /bin/cp -f $(DEPENDFILE) $(DEPENDFILE).old; \
+        fi; \
+        echo '#generated by make depends' > $(DEPENDFILE); \
+        for i in $(OBJS) ; do \
+              SRCFILE=`basename $$i .o`.C ; \
+              echo "checking dependencies for $$SRCFILE" ; \
+              g++ -MM -I$(CHARMINC) $$SRCFILE | \
+              perl $(CHARMBIN)/dep.pl $(CHARMINC) /usr/include /usr/local >> $(DEPENDFILE); \
+              echo '   $$(CHARMC) -o '$$i $$SRCFILE >> $(DEPENDFILE) ; \
+        done;
+
diff --git a/tests/charm++/megatest/Makefile.win32 b/tests/charm++/megatest/Makefile.win32
new file mode 100644 (file)
index 0000000..0e7ad38
--- /dev/null
@@ -0,0 +1,110 @@
+CHARMBIN=..\..\..\bin\r
+CPP = cl.exe\r
+\r
+INC = /I"..\..\..\include"\r
+\r
+CPP_PROJ=/nologo /MT /w /Gm /GX /ZI /Od $(INC)\\r
+ /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX\\r
+ /Fo /c /TP /GZ\r
+\r
+LINK=link.exe\r
+LINK_FLAGS = /nologo /LIBPATH:"..\..\..\lib" /nodefaultlib:"libc"\r
+LINK_OTHER = libldb-rand.o libck.a libconv-core.a \\r
+       libtrace-none.a libconv-cplus-y.a ws2_32.lib kernel32.lib \r
+\r
+\r
+OBJS = megatest.obj groupring.obj nodering.obj varsizetest.obj  groupcast.obj nodecast.obj synctest.obj fib.obj arrayring.obj tempotest.obj packtest.obj queens.obj migration.obj priomsg.obj priotest.obj templates.obj varraystest.obj\r
+\r
+MODULES = megatest groupring nodering varsizetest groupcast nodecast synctest fib arrayring tempotest packtest queens migration priomsg priotest templates varraystest\r
+\r
+DECLS = megatest.decl.h groupring.decl.h nodering.decl.h varsizetest.decl.h  groupcast.decl.h nodecast.decl.h synctest.decl.h fib.decl.h arrayring.decl.h tempotest.decl.h packtest.decl.h queens.decl.h migration.decl.h priomsg.decl.h priotest.decl.h templates.decl.h varraystest.decl.h\r
+\r
+DEFS  = megatest.def.h groupring.def.h nodering.def.h varsizetest.def.h  groupcast.def.h nodecast.def.h synctest.def.h fib.def.h arrayring.def.h tempotest.def.h packtest.def.h queens.def.h migration.def.h priomsg.def.h priotest.def.h templates.def.h varraystest.def.h\r
+\r
+#.SILENT:\r
+\r
+pgm: $(OBJS)\r
+       $(LINK) $(LINK_FLAGS) $(LINK_OTHER) /out:"pgm.exe" $(OBJS)\r
+       copy $(CHARMBIN)\charmrun.exe .\r
+\r
+.c.obj: \r
+       $(CPP) $(CPP_PROJ) $<\r
+\r
+megatest.h: megatest.decl.h\r
+\r
+megatest.C: megatest.h megatest.def.h groupring.h nodering.h varsizetest.h groupcast.h nodecast.h synctest.h fib.h arrayring.h tempotest.h packtest.h queens.h migration.h priomsg.h priotest.h templates.h varraystest.h\r
+\r
+groupring.h: groupring.decl.h\r
+\r
+groupring.C: groupring.h groupring.def.h megatest.h\r
+\r
+nodering.h: nodering.decl.h\r
+\r
+nodering.C: nodering.h nodering.def.h megatest.h\r
+\r
+varsizetest.h: varsizetest.decl.h\r
+\r
+varsizetest.C: varsizetest.h varsizetest.def.h megatest.h\r
+\r
+groupcast.h: groupcast.decl.h\r
+\r
+groupcast.C: groupcast.h groupcast.def.h megatest.h\r
+\r
+nodecast.h: nodecast.decl.h\r
+\r
+nodecast.C: nodecast.h nodecast.def.h megatest.h\r
+\r
+synctest.h: synctest.decl.h\r
+\r
+synctest.C: synctest.h synctest.def.h megatest.h\r
+\r
+fib.h: fib.decl.h\r
+\r
+fib.C: fib.h fib.def.h megatest.h\r
+\r
+arrayring.h: arrayring.decl.h\r
+\r
+arrayring.C: arrayring.h arrayring.def.h megatest.h\r
+\r
+tempotest.h: tempotest.decl.h\r
+\r
+tempotest.C: tempotest.h tempotest.def.h megatest.h\r
+\r
+packtest.h: packtest.decl.h\r
+\r
+packtest.C: packtest.h packtest.def.h megatest.h\r
+\r
+queens.h: queens.decl.h\r
+\r
+queens.C: queens.h queens.def.h megatest.h\r
+\r
+migration.h: migration.decl.h\r
+\r
+migration.C: migration.h migration.def.h megatest.h\r
+\r
+priomsg.h: priomsg.decl.h\r
+\r
+priomsg.C: priomsg.h priomsg.def.h megatest.h\r
+\r
+priotest.h: priotest.decl.h\r
+\r
+priotest.C: priotest.h priotest.def.h megatest.h\r
+\r
+templates.h: templates.decl.h\r
+\r
+templates.C: templates.h templates.def.h megatest.h\r
+\r
+varraystest.C: varraystest.h varraystest.def.h megatest.h\r
+\r
+$(DECLS) $(DEFS) : $(MODULES)\r
+\r
+$(MODULES) : $*.ci\r
+       $(CHARMBIN)\charmxi $*.ci\r
+\r
+clean:\r
+       del *.decl.h\r
+       del *.def.h\r
+       del charmrun.exe\r
+       del *.obj\r
+       del pgm.exe\r
+       del vc60.*\r
diff --git a/tests/charm++/megatest/arrayring.C b/tests/charm++/megatest/arrayring.C
new file mode 100644 (file)
index 0000000..2b00ed7
--- /dev/null
@@ -0,0 +1,39 @@
+#include "arrayring.h"
+
+void arrayring_init(void)
+{ 
+  const int numElements = 50;
+  CProxy_arrayRing_array::ckNew(numElements);
+}
+
+void arrayring_moduleinit(void){}
+
+arrayRing_array::arrayRing_array()
+{
+   if(thisIndex==0) {
+     CProxy_arrayRing_array carr(thisArrayID);
+     carr[0].start(new arrayMessage);
+   }
+}
+
+void arrayRing_array::start(arrayMessage *msg)
+{
+  const int maxRings = 10;
+
+  if(!msg->check()) {
+    CkAbort("Message corrupted!\n");
+  }
+  if(thisIndex==0)
+    msg->iter++;
+  if (msg->iter < maxRings) {
+    CProxy_arrayRing_array hr(thisArrayID);
+    hr[(thisIndex+1) % numElements].start(msg);
+  } else {
+    delete msg;
+    megatest_finish();
+  }
+  return;
+}
+
+MEGATEST_REGISTER_TEST(arrayring,"fang",1)
+#include "arrayring.def.h"
diff --git a/tests/charm++/megatest/arrayring.ci b/tests/charm++/megatest/arrayring.ci
new file mode 100644 (file)
index 0000000..897d768
--- /dev/null
@@ -0,0 +1,8 @@
+module arrayring {
+  message arrayMessage;
+   
+  array [1D] arrayRing_array {
+    entry arrayRing_array();
+    entry void start(arrayMessage *);
+  };
+};
diff --git a/tests/charm++/megatest/arrayring.h b/tests/charm++/megatest/arrayring.h
new file mode 100644 (file)
index 0000000..c9c7207
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef _ARRAYRING_H
+#define _ARRAYRING_H
+
+#include "arrayring.decl.h"
+#include "megatest.h"
+
+class arrayMessage : public CMessage_arrayMessage {
+  char data[7];
+public:
+  int iter;
+  arrayMessage(void) { sprintf(data, "Array!"); iter = 0; };
+  int check(void) { return !strcmp(data, "Array!"); }
+};
+
+class arrayRing_array : public ArrayElement1D
+{
+ public:
+  arrayRing_array();
+  arrayRing_array(CkMigrateMessage *msg) {}
+  void start(arrayMessage *msg);
+};
+
+#endif
diff --git a/tests/charm++/megatest/bitvector.C b/tests/charm++/megatest/bitvector.C
new file mode 100644 (file)
index 0000000..bc22bf2
--- /dev/null
@@ -0,0 +1,150 @@
+#define DEBUGGING
+#include <charm++.h>
+#include "bitvector.h"
+#include "ckbitvector.h"
+#include "megatest.h"
+
+/* This class definition is garbage, to fill the .ci file so it doesn't
+ * complain.
+ */
+class bitvectorMessage : public CMessage_bitvectorMessage {
+};
+
+bool test(bool result, char *what) {
+  if ( result ) {
+//    ckout << what << " passed." << endl;
+  } else {
+    ckerr << what << " failed." << endl;
+    megatest_finish();
+  }
+
+  return result;
+}
+
+void testBitFlipping() {
+  int i;
+  CkBitVector bvOrig(sizeof(unsigned int)*8),
+            bv = bvOrig;
+
+  // Test setting all the bits of bv based on the bits in value
+  for(i=0;i<sizeof(unsigned int)*8;i++) {
+    if ( i >= 16 ) {
+      bv.Set(i);
+    } else {
+      bv.Clear(i);
+    }
+  }
+  test((bv.getData())[0]==0xffff0000, "Set and Clear (low bits)");
+
+  // Do that test again but on high bits.
+  bv = CkBitVector(sizeof(unsigned int)*8*2);
+  for(i=0;i<sizeof(unsigned int)*8;i++) {
+    if ( i>=16 ) {
+      bv.Set(i+sizeof(unsigned int)*8);
+    } else {
+      bv.Clear(i+sizeof(unsigned int)*8);
+    }
+  }
+  test((bv.getData())[1]==0, "Set and Clear (low bits)");
+  test((bv.getData())[0]==0xffff0000, "Set and Clear (high bits)");
+
+  // Comparisons of the first chunk
+  bv.ShiftDown(sizeof(unsigned int)*8);
+  test((bv.getData())[1]==0xffff0000, "Shift Down (low bits)");
+  test((bv.getData())[0]==0, "Shift Down (high bits)");
+
+  // Comparisons of higher chunks
+  bv.ShiftUp(sizeof(unsigned int)*8/2);
+  test((bv.getData())[1]==0, "Shift Up (low bits)");
+  test((bv.getData())[0]==0x0000ffff, "Shift Up (high bits)");
+
+  // Set all bits true
+  bv = bvOrig; bv.Invert();
+  test((bv.getData())[0]==(~(0x0)), "One's compliment, all 0s");
+
+  // Negation
+  bv.Invert();
+  test((bv.getData())[0]==(0x0), "One's compliment, mix");
+}
+
+void testUnion() {
+  unsigned int a = 0x8a82, b=0x8511;
+  CkBitVector bv1(0x8a82, 0x10000),
+              bv2(0x8511, 0x10000);
+
+  // Test the intersection
+  bv1.Union(bv2);
+  a = a | b;
+  a = a << (sizeof(unsigned int)*8/2);
+  test((bv1.getData())[0]==a, "Union in a chunk");
+}
+
+void testInter() {
+  unsigned int a = 0x8a82, b=0x8511;
+  CkBitVector bv1(0x8a82, 0x10000),
+              bv2(0x8511, 0x10000);
+
+  // Test the intersection
+  bv1.Intersection(bv2);
+  a = a & b;
+  a = a << (sizeof(unsigned int)*8/2);
+  test((bv1.getData())[0]==a, "Intersection in a chunk");
+}
+
+void testDiff() {
+  unsigned int a = 0xffff, b=0x8511;
+  CkBitVector bv1(0xffff, 0x10000),
+              bv2(0x8511, 0x10000);
+
+  // Test the difference
+  bv1.Difference(bv2);
+  a = a & ~b;
+  a = a << (sizeof(unsigned int)*8/2);
+  test((bv1.getData())[0]==a, "Difference in a chunk");
+}
+
+void testConcat() {
+  unsigned int a = 0xff0000ff, b=0x00ffff00, c=0xff00ff00;
+  CkBitVector bv1(0xff00,0x10000),
+              bv2(0x00ff,0x10000),
+             t;
+
+  // Test the two ways of concatting them.
+  t = bv1; t.Concat(bv2);
+  test((t.getData())[0]==a, "Concat under a chunk");
+
+  // Now go over a chunk size in concatenation
+  t.Concat(bv2); t.Concat(bv1);
+  test((t.getData())[0]==a, "Concat over a chunk (low)");
+  test((t.getData())[1]==b, "Concat over a chunk (high)");
+
+  // Now try a chunk to itself.
+  t = bv1; t.Concat(t);
+  test((t.getData())[0]==c, "Concat to yourself");
+
+  // Try a bv to itself larger than a single chunk
+  t.Concat(t);
+  test((t.getData())[0]==c, "Concat to yourself (low)");
+  test((t.getData())[1]==c, "Concat to yourself (high)");
+}
+
+void testOps() {
+  testBitFlipping();
+  testUnion();
+  testInter();
+  testDiff();
+  testConcat();
+}
+
+/* ************************************************************************
+ *
+ * ************************************************************************ */
+void bitvector_init(void) {
+  testOps();
+  megatest_finish();
+}
+
+void bitvector_moduleinit(void){}
+
+MEGATEST_REGISTER_TEST(bitvector,"jbooth",0);
+#include "bitvector.def.h"
diff --git a/tests/charm++/megatest/bitvector.ci b/tests/charm++/megatest/bitvector.ci
new file mode 100644 (file)
index 0000000..de46cf1
--- /dev/null
@@ -0,0 +1,3 @@
+module bitvector {
+  message bitvectorMessage;
+};
diff --git a/tests/charm++/megatest/bitvector.h b/tests/charm++/megatest/bitvector.h
new file mode 100644 (file)
index 0000000..abc40b1
--- /dev/null
@@ -0,0 +1,2 @@
+#include "bitvector.decl.h"
+
diff --git a/tests/charm++/megatest/callback.C b/tests/charm++/megatest/callback.C
new file mode 100644 (file)
index 0000000..8a67406
--- /dev/null
@@ -0,0 +1,168 @@
+#include "callback.h"
+#include <stdlib.h>
+
+void callback_moduleinit(void)
+{
+       /*empty*/
+}
+void callback_init(void) 
+{
+       CProxy_callbackCoord::ckNew(0);
+}
+
+class callbackMsg : public CMessage_callbackMsg {
+public:
+       int val;
+       callbackMsg(int v) :val(v) {}
+};
+
+/*This integer lets us tell which method we called,
+so if it's not the method that executes we'll be able to tell.
+*/
+enum {
+  typeChare=1000,
+  typeGroup=2000,
+  typeArray=4000,
+  typeCfn=5000,
+  msgGood=1,
+  msgNull=2
+};
+
+int msg2val(callbackMsg *m) {
+       if (m==NULL) return 0;
+       int ret=m->val;
+       delete m;
+       return ret;
+}
+
+extern "C" void acceptCFnCall(void *param,void *msg) 
+{
+       CProxy_callbackCoord coord=*(CProxy_callbackCoord *)param;
+       coord.done(typeCfn,msg2val((callbackMsg *)msg));
+}
+
+class callbackCoord : public CBase_callbackCoord {
+       CProxy_callbackChare cp;
+       int nArr;
+       CProxy_callbackArray ap;
+       CProxy_callbackGroup gp;
+       int state;
+       int expectType,expectParam;
+       int expectCount;
+
+       //Send this callback off:
+       void send(const CkCallback &c) {
+               if (rand()&0x100) { //Half the time, send the callback ourselves
+                       c.send(new callbackMsg(expectParam));
+               } else //Otherwise, reflect the callback off a random processor:
+                       gp[rand()%CkNumPes()].reflect(c,expectParam);
+       }
+       
+       void next(void) {
+               state++;
+               expectParam=rand();
+               expectCount=1;
+               switch(state) {
+               case 0: //Send to chare
+                       expectType=typeChare;
+                       send(CkCallback(CkIndex_callbackChare::accept(NULL),
+                                       cp));
+                       break;
+               case 1: //Send to array element
+                       expectType=typeArray;
+                       send(CkCallback(CkIndex_callbackArray::accept(NULL),
+                                       CkArrayIndex1D(nArr-1),ap));
+                       break;
+               case 2: //Send to group member 0
+                       expectType=typeGroup;
+                       send(CkCallback(CkIndex_callbackGroup::accept(NULL),
+                                       CkNumPes()-1,gp));
+                       break;
+               case 3: //Send to C function
+                       expectType=typeCfn;
+                       send(CkCallback(acceptCFnCall,&thisProxy));
+                       break;
+               case 4: //Broadcast to array
+                       expectCount=nArr;
+                       expectType=typeArray;
+                       send(CkCallback(CkIndex_callbackArray::accept(NULL),ap));
+                       break;
+               case 5: //Broadcast to group
+                       expectCount=CkNumPes();
+                       expectType=typeGroup;
+                       send(CkCallback(CkIndex_callbackGroup::accept(NULL),gp));
+                       break;
+               case 6: //That's it
+                       expectType=-1;
+                       expectParam=-1;
+                       thisProxy.threadedTest();
+                       break;
+               };
+       }
+public:
+       callbackCoord(void) {
+               cp=CProxy_callbackChare::ckNew(thisProxy);
+               nArr=CkNumPes()*2+1;
+               ap=CProxy_callbackArray::ckNew(thisProxy,nArr);
+               gp=CProxy_callbackGroup::ckNew(thisProxy);
+               state=-1;
+               next();
+       }
+       void done(int objectType,int paramVal) {
+               if (objectType!=expectType || paramVal!=expectParam) {
+                       CkError("Callback step %d: expected object %d, got %d; expected param %d, got %d\n",
+                               state,expectType,objectType, expectParam,paramVal);
+                       CkAbort("Unexpected callback object or parameter");
+               }
+               expectCount--;
+               if (expectCount==0)
+                       next();
+       }
+       void threadedTest(void) {
+               //Reflect a value off each processor:
+               for (int pe=0;pe<CkNumPes();pe+=2) {
+                       CkCallback cb(CkCallback::resumeThread);
+                       int expectedVal=237+13*pe;
+                       gp[pe].reflect(cb,expectedVal);
+                       callbackMsg *m=(callbackMsg *)(cb.thread_delay());
+                       int gotVal=msg2val(m);
+                       if (gotVal!=expectedVal) CkAbort("Threaded callback returned wrong value");
+               }
+               megatest_finish();
+       }
+};
+
+class callbackChare : public CBase_callbackChare {
+       CProxy_callbackCoord coord;
+public:
+       callbackChare(CProxy_callbackCoord coord_) :coord(coord_) {}
+       void accept(callbackMsg *m) {
+               coord.done(typeChare,msg2val(m));
+       }
+};
+class callbackArray : public CBase_callbackArray {
+       CProxy_callbackCoord coord;
+public:
+       callbackArray(CProxy_callbackCoord coord_) :coord(coord_) {}
+       callbackArray(CkMigrateMessage *) {}
+       void accept(callbackMsg *m) {
+               coord.done(typeArray,msg2val(m));
+       }
+};
+class callbackGroup : public CBase_callbackGroup {
+       CProxy_callbackCoord coord;
+public:
+       callbackGroup(CProxy_callbackCoord coord_) :coord(coord_) {}
+       void accept(callbackMsg *m) {
+               coord.done(typeGroup,msg2val(m));
+       }
+       void reflect(CkCallback cb,int val) {
+               cb.send(new callbackMsg(val));
+       }
+};
+
+
+MEGATEST_REGISTER_TEST(callback,"olawlor",1)
+#include "callback.def.h"
+
+
diff --git a/tests/charm++/megatest/callback.ci b/tests/charm++/megatest/callback.ci
new file mode 100644 (file)
index 0000000..219b363
--- /dev/null
@@ -0,0 +1,22 @@
+module callback {
+  message callbackMsg;
+  chare callbackCoord {
+    entry callbackCoord(void);
+    entry void done(int objectType,int paramVal); 
+    entry [threaded] void threadedTest(void);
+  };
+
+  chare callbackChare {
+    entry callbackChare(CProxy_callbackCoord coord);
+    entry void accept(callbackMsg *m);
+  };
+  array[1D] callbackArray {
+    entry callbackArray(CProxy_callbackCoord coord);
+    entry void accept(callbackMsg *m);
+  };
+  group callbackGroup {
+    entry callbackGroup(CProxy_callbackCoord coord);
+    entry void accept(callbackMsg *m);
+    entry void reflect(CkCallback cb,int paramVal);
+  };
+};
diff --git a/tests/charm++/megatest/callback.h b/tests/charm++/megatest/callback.h
new file mode 100644 (file)
index 0000000..71d0032
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _CALLBACK_H
+#define _CALLBACK_H
+
+#include "callback.decl.h"
+#include "megatest.h"
+
+#endif
diff --git a/tests/charm++/megatest/fib.C b/tests/charm++/megatest/fib.C
new file mode 100644 (file)
index 0000000..bd207be
--- /dev/null
@@ -0,0 +1,93 @@
+#include "fib.h"
+
+#define NUMCHARES 20
+#define GRAIN 10
+void fib_init(void){
+  CProxy_fib_main::ckNew(0);
+}
+
+void fib_moduleinit(void){} 
+
+fib_main::fib_main (void)
+{
+  fib_Range *pMsg;
+  
+  result = 0;
+  pMsg = new fib_Range;
+  pMsg->n = NUMCHARES;
+  pMsg->parent = thishandle;
+  CProxy_fib_fibFunction::ckNew(pMsg);
+}  
+
+void fib_main::results(fib_DataMsg *msg)
+{
+  result = msg->x;
+  delete msg;
+  if (result != 6765)
+    CkAbort("fib test failed! \n");
+  megatest_finish();
+}      
+
+                                                                                   
+fib_fibFunction::fib_fibFunction(fib_Range *m)
+{
+  sum = 0;
+  count = 0;
+  parent = m->parent;
+  root = m->n;
+  if (m->n <= GRAIN){ 
+    fib_DataMsg *sub = new fib_DataMsg;
+    sub->x = sequent(m->n); 
+    CProxy_fib_fibFunction fibproxy(parent);
+    fibproxy.sendParent (sub);
+  } else {
+    //if not then recursively call for f(n-1) and f(n-2) 
+    
+    fib_Range *pMsg1 = new fib_Range; //create two new chares
+    fib_Range *pMsg2 = new fib_Range;
+
+    pMsg1->n = m->n - 1;
+    pMsg1->parent = thishandle;
+   
+    pMsg2->n = m->n - 2;
+    pMsg2->parent = thishandle;
+   
+    CProxy_fib_fibFunction::ckNew(pMsg1);
+    CProxy_fib_fibFunction::ckNew(pMsg2);
+  }
+  delete m;
+}
+
+void fib_fibFunction::sendParent(fib_DataMsg *msg){
+  sum += msg->x;
+  delete msg;
+  count++;
+  if (count == 2) {
+    fib_DataMsg *subtotal = new fib_DataMsg;
+    subtotal->x = sum;
+    count = 0;
+    if (root == NUMCHARES){
+      CProxy_fib_main mainproxy (parent);
+      mainproxy.results(subtotal);
+    } else {
+      CProxy_fib_fibFunction fibproxy(parent);
+      fibproxy.sendParent (subtotal);
+    }
+    delete this;
+  }
+} 
+
+int fib_fibFunction::sequent(int i)
+{
+  int sum1 = 0;
+  if (i == 0 || i == 1) {
+      return i;
+  } else {
+    sum1 = sequent(i-1) + sequent(i-2);
+    return sum1;
+  }
+}
+
+MEGATEST_REGISTER_TEST(fib,"jackie",1)
+#include "fib.def.h"
diff --git a/tests/charm++/megatest/fib.ci b/tests/charm++/megatest/fib.ci
new file mode 100644 (file)
index 0000000..e604980
--- /dev/null
@@ -0,0 +1,15 @@
+module fib {
+  message fib_DataMsg;
+  message fib_Range;
+
+  chare fib_main {
+    entry fib_main(void);
+    entry void results(fib_DataMsg *);
+  };
+
+  chare fib_fibFunction {
+    entry fib_fibFunction(fib_Range *);
+    entry void sendParent(fib_DataMsg *);
+  };
+
+};
diff --git a/tests/charm++/megatest/fib.h b/tests/charm++/megatest/fib.h
new file mode 100644 (file)
index 0000000..70dbc7e
--- /dev/null
@@ -0,0 +1,38 @@
+# include "megatest.h"
+# include "fib.decl.h"
+
+#define NUMCHARES 20
+#define GRAIN 10
+
+class fib_DataMsg: public CMessage_fib_DataMsg { 
+ public:
+    int x;
+};
+
+class fib_Range :public CMessage_fib_Range{
+ public:
+  int n;
+  CkChareID parent;
+};
+
+class fib_main : public Chare {
+ private:
+  int result;
+ public:
+  fib_main(void);
+  fib_main(CkMigrateMessage *m) {}
+  void results(fib_DataMsg * msg);
+};
+
+class fib_fibFunction: public Chare {
+ private:
+  int sum;
+  CkChareID parent;
+  int count;
+  int root;
+  int sequent(int i);
+ public:
+  fib_fibFunction(fib_Range * m);
+  fib_fibFunction(CkMigrateMessage *m) {}
+  void sendParent(fib_DataMsg * msg);
+};
diff --git a/tests/charm++/megatest/groupcast.C b/tests/charm++/megatest/groupcast.C
new file mode 100644 (file)
index 0000000..14b1b6a
--- /dev/null
@@ -0,0 +1,46 @@
+#include "groupcast.h"
+
+void groupcast_moduleinit(void) {}
+
+void groupcast_init(void) 
+{
+  CProxy_groupcast_main::ckNew(0);
+}
+
+groupcast_main::groupcast_main(void) 
+{
+  count = 0;
+  groupcast_SimpleMsg *sm = new groupcast_SimpleMsg;
+  sm->mainhandle = thishandle;
+  gid=CProxy_groupcast_group::ckNew(sm);
+}
+
+void groupcast_main::groupReady() {
+  count++;
+  if (count < 3) {
+    CProxy_groupcast_group groupproxy(gid);
+    groupcast_BCMsg *g_bcm = new groupcast_BCMsg;
+    groupproxy.doBroadcast(g_bcm);
+  } else {
+      delete this;
+      megatest_finish();
+  }
+}
+
+groupcast_group::groupcast_group(groupcast_SimpleMsg *sm) {
+  myMain = sm->mainhandle;
+  CkCallback cb(CkIndex_groupcast_main::groupReady(),myMain);
+  contribute(0,0,CkReduction::sum_int,cb);
+}
+
+void groupcast_group::doBroadcast(groupcast_BCMsg *bcm) {
+  if (!bcm->check()) {
+    CkAbort("Broadcasted message fails check.\n");
+  }
+  delete bcm;
+  CkCallback cb(CkIndex_groupcast_main::groupReady(),myMain);
+  contribute(0,0,CkReduction::sum_int,cb);
+}
+
+MEGATEST_REGISTER_TEST(groupcast,"mjlang",1)
+#include "groupcast.def.h"
diff --git a/tests/charm++/megatest/groupcast.ci b/tests/charm++/megatest/groupcast.ci
new file mode 100644 (file)
index 0000000..cacfc8e
--- /dev/null
@@ -0,0 +1,14 @@
+module groupcast {
+  message groupcast_SimpleMsg;
+  message groupcast_BCMsg;
+
+  chare groupcast_main {
+    entry groupcast_main(void);
+    entry void groupReady(void);
+  };
+
+  group groupcast_group {
+    entry groupcast_group(groupcast_SimpleMsg *);
+    entry void doBroadcast(groupcast_BCMsg *);
+  };
+};
diff --git a/tests/charm++/megatest/groupcast.h b/tests/charm++/megatest/groupcast.h
new file mode 100644 (file)
index 0000000..e5e5468
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef _GROUPCAST_H
+#define _GROUPCAST_H
+
+#include "megatest.h"
+#include "groupcast.decl.h"
+
+class groupcast_SimpleMsg : public CMessage_groupcast_SimpleMsg {
+public:
+  CkGroupID gid;
+  CkChareID mainhandle;
+};
+
+class groupcast_BCMsg : public CMessage_groupcast_BCMsg {
+private:
+  double dval;
+  char checkString[11];
+public:
+  groupcast_BCMsg(void) { dval = 3.145; sprintf(checkString, "Broadcast!");} 
+  groupcast_BCMsg(CkMigrateMessage *m) {}
+  int check(void) { 
+    if (strcmp("Broadcast!", checkString) == 0 && dval == 3.145)
+      return 1;
+    else
+      return 0;
+  }
+};
+
+class groupcast_main : public Chare {
+private:
+  CkGroupID gid;
+  int count;
+public:
+  groupcast_main(void);
+  groupcast_main(CkMigrateMessage *m) {}
+  void groupReady(void);
+};
+
+class groupcast_group : public Group {
+private:
+  CkChareID myMain;
+public:
+  groupcast_group(groupcast_SimpleMsg *sm);
+  groupcast_group(CkMigrateMessage *m) {}
+  void doBroadcast(groupcast_BCMsg *bcm);
+};
+
+#endif
diff --git a/tests/charm++/megatest/groupring.C b/tests/charm++/megatest/groupring.C
new file mode 100644 (file)
index 0000000..2a46b24
--- /dev/null
@@ -0,0 +1,30 @@
+#include "groupring.h"
+
+static int nextseq = 0;
+
+void groupring_init(void)
+{
+  CkGroupID groupring_thisgroup = CProxy_groupring_group::ckNew();
+  CProxy_groupring_group pgg(groupring_thisgroup);
+  groupring_message *msg = new groupring_message(nextseq++,0);
+  pgg[0].start(msg);
+}
+
+void groupring_moduleinit(void) {}
+
+void groupring_group::start(groupring_message *msg)
+{
+  CProxyElement_groupring_group pgg(thisgroup,(CkMyPe()+1)%CkNumPes());
+  if(CkMyPe()==0 && msg->iter==NITER) {
+    delete msg;
+    megatest_finish();
+  } else if(CkMyPe()==0) {
+    msg->iter++;
+    pgg.start(msg);
+  } else {
+    pgg.start(msg);
+  }
+}
+
+MEGATEST_REGISTER_TEST(groupring,"milind",1)
+#include "groupring.def.h"
diff --git a/tests/charm++/megatest/groupring.ci b/tests/charm++/megatest/groupring.ci
new file mode 100644 (file)
index 0000000..9aae02a
--- /dev/null
@@ -0,0 +1,11 @@
+module groupring {
+  message groupring_message;
+  mainchare groupring_main {
+    entry groupring_main();
+  };
+  group groupring_group {
+    entry groupring_group(void);
+    entry void start(groupring_message *);
+  };
+};
+
diff --git a/tests/charm++/megatest/groupring.h b/tests/charm++/megatest/groupring.h
new file mode 100644 (file)
index 0000000..ac91ec5
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef GROUPRING_H
+#define GROUPRING_H
+
+#include "megatest.h"
+#include "groupring.decl.h"
+
+#define NITER 100
+
+class groupring_message : public CMessage_groupring_message {
+ public:
+  int seqnum;
+  int iter;
+  groupring_message(int s, int i) : seqnum(s), iter(i) {}
+  groupring_message(CkMigrateMessage *m) {}
+};
+
+class groupring_main : public Chare {
+  public:
+    groupring_main(CkArgMsg *m) {
+      delete m;
+    }
+    groupring_main(CkMigrateMessage *m) {}
+};
+
+class groupring_group : public Group {
+  public:
+    groupring_group(void) {}
+    groupring_group(CkMigrateMessage *m) {}
+    void start(groupring_message *msg);
+};
+
+#endif 
diff --git a/tests/charm++/megatest/immediatering.C b/tests/charm++/megatest/immediatering.C
new file mode 100644 (file)
index 0000000..265790d
--- /dev/null
@@ -0,0 +1,142 @@
+#include "immediatering.h"
+
+static CProxy_immRing_nodegroup immring_nodegrp;
+static CProxy_immRing_group     immring_grp;
+
+// testing Converse immeidate message
+int immediatering_startHandlerIdx=0;
+int immediatering_finishHandlerIdx=0;
+
+static int numTests = 0;
+
+// testing Converse message
+static void sendImmediate(int destNode,int iter) {
+  immediateMsg *msg=(immediateMsg *)CmiAlloc(sizeof(immediateMsg));
+  msg->iter=iter;
+  sprintf(msg->data, "Array!");
+  CmiSetHandler(msg, immediatering_startHandlerIdx);
+#if 1 /* Use immediate converse message */
+  CmiBecomeImmediate(msg);
+#endif
+  CmiSyncNodeSendAndFree(destNode,sizeof(immediateMsg),(char *)msg);
+}
+
+// Converse immediate handler
+void immediatering_startHandler(void *vmsg)
+{
+  const int maxRings = 1000;
+  immediateMsg *msg=(immediateMsg *)vmsg;
+
+  if(0!=strcmp(msg->data,"Array!")) {
+    CkAbort("Message corrupted");
+  }
+  if(CkMyNode()==0)
+    msg->iter++;
+  if (msg->iter < maxRings) { /* Keep passing message around the ring */
+    /* This is questionable: */
+    sendImmediate((CkMyNode()+1) % CkNumNodes(),msg->iter);
+  } else /* msg->iter>=maxRings, so stop: */ { 
+    /* megatest_finish isn't safe from an immediate, so send a 
+       regular non-immediate message out: */
+    int size=CmiMsgHeaderSizeBytes;
+    void *msg=CmiAlloc(size);
+    CmiSetHandler(msg,immediatering_finishHandlerIdx);
+    CmiSyncSendAndFree(0,size,(char *)msg);
+  }
+  CmiFree(msg);
+}
+
+// on node 0
+static int waitFor = 0;
+
+extern "C" void immediatering_finishHandler(void *msg) {
+  CmiFree(msg);
+  waitFor ++;
+  // only send one megatest_finish when all tests finish
+  if (waitFor%numTests == 0) {
+    megatest_finish(); // Not safe from inside immediate
+  }
+}
+
+// testing Charm immediate handler
+
+void immRing_nodegroup::start(immMessage *msg)
+{
+  const int maxRings = 50;
+
+//CkPrintf("[%d] start %d\n", thisIndex, msg->iter);
+
+  if(!msg->check()) {
+    CkError("Message corrupted!\n");
+    megatest_finish();
+    return;
+  }
+  if(CkMyNode()==0)
+    msg->iter++;
+  if (msg->iter < maxRings) {
+    thisProxy[(CkMyNode()+1) % CkNumNodes()].start(msg);
+  } else {
+    delete msg;
+    //megatest_finish();
+    int size=CmiMsgHeaderSizeBytes;
+    void *msg=CmiAlloc(size);
+    CmiSetHandler(msg,immediatering_finishHandlerIdx);
+    CmiSyncSendAndFree(0,size,(char *)msg);
+  }
+}
+
+void immRing_group::start(immMessage *msg)
+{
+  const int maxRings = 50;
+
+//CkPrintf("[%d] start %d\n", thisIndex, msg->iter);
+
+  if(!msg->check()) {
+    CkError("Message corrupted!\n");
+    megatest_finish();
+    return;
+  }
+  if(CkMyPe()==0)
+    msg->iter++;
+  if (msg->iter < maxRings) {
+    thisProxy[(CkMyPe()+1) % CkNumPes()].start(msg);
+  } else {
+    delete msg;
+    //megatest_finish();
+    int size=CmiMsgHeaderSizeBytes;
+    void *msg=CmiAlloc(size);
+    CmiSetHandler(msg,immediatering_finishHandlerIdx);
+    CmiSyncSendAndFree(0,size,(char *)msg);
+  }
+}
+
+void immediatering_init(void)
+{ 
+  int setNum = 0;
+  if (CkMyRank()==0 && numTests==0) setNum = 1;
+#if 1
+  // test Charm immediate messages
+  if (setNum) numTests +=2;
+  immring_nodegrp[0].start(new immMessage);
+  immring_grp[0].start(new immMessage);
+#endif
+#if 1
+  if (setNum) numTests ++;
+  sendImmediate(0,0);
+#endif
+}
+
+void immediatering_moduleinit(void)
+{
+  immring_nodegrp = CProxy_immRing_nodegroup::ckNew();
+  immring_grp = CProxy_immRing_group::ckNew();
+}
+
+void immediatering_initcall(void) {
+  // Register converse handlers
+  immediatering_startHandlerIdx=CmiRegisterHandler(immediatering_startHandler);
+  immediatering_finishHandlerIdx=CmiRegisterHandler(immediatering_finishHandler);
+}
+
+MEGATEST_REGISTER_TEST(immediatering,"gengbin",1)
+#include "immediatering.def.h"
diff --git a/tests/charm++/megatest/immediatering.ci b/tests/charm++/megatest/immediatering.ci
new file mode 100644 (file)
index 0000000..5ff724a
--- /dev/null
@@ -0,0 +1,15 @@
+module immediatering {
+  message immMessage;
+   
+  initproc void immediatering_initcall(void);
+
+  nodegroup immRing_nodegroup {
+    entry immRing_nodegroup();
+    entry [immediate] void start(immMessage *);
+  };
+
+  group immRing_group {
+    entry immRing_group();
+    entry [expedited] void start(immMessage *);
+  };
+};
diff --git a/tests/charm++/megatest/immediatering.h b/tests/charm++/megatest/immediatering.h
new file mode 100644 (file)
index 0000000..299687f
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef _IMMEDIATERING_H
+#define _IMMEDIATERING_H
+
+#include "immediatering.decl.h"
+#include "megatest.h"
+
+struct immediateMsg {
+        char converseHeader[CmiMsgHeaderSizeBytes];
+        int iter; /* number of times we've been around the ring. */
+        char data[7];
+};
+
+// charm immeidate message
+class immMessage : public CMessage_immMessage {
+  char data[7];
+public:
+  int iter;
+  immMessage(void) { sprintf(data, "Array!"); iter = 0; };
+  int check(void) { return !strcmp(data, "Array!"); }
+};
+
+class immRing_nodegroup : public CBase_immRing_nodegroup
+{
+ public:
+  immRing_nodegroup() {}
+  immRing_nodegroup(CkMigrateMessage *msg) {}
+  void start(immMessage *msg);
+};
+
+class immRing_group : public CBase_immRing_group
+{
+ public:
+  immRing_group() {}
+  immRing_group(CkMigrateMessage *msg) {}
+  void start(immMessage *msg);
+};
+
+#endif
diff --git a/tests/charm++/megatest/inherit.C b/tests/charm++/megatest/inherit.C
new file mode 100644 (file)
index 0000000..7b3d981
--- /dev/null
@@ -0,0 +1,248 @@
+#include "inherit.h"
+#include <stdlib.h>
+
+
+readonly<CProxy_inhCoord> coordinator;
+readonly<CkGroupID> id_gp,id_g1,id_g2,id_g3,id_g13;
+readonly<CkArrayID> id_ap,id_a1,id_a2,id_a3,id_a13;
+
+void inherit_moduleinit(void)
+{
+  coordinator=CProxy_inhCoord::ckNew();
+  id_gp=CProxy_gp::ckNew(); 
+  id_g1=CProxy_g1::ckNew(); 
+  id_g2=CProxy_g2::ckNew(); 
+  id_g3=CProxy_g3::ckNew(); 
+  id_g13=CProxy_g13::ckNew();
+  id_ap=CProxy_ap::ckNew(1); 
+  id_a1=CProxy_a1::ckNew(1); 
+  id_a2=CProxy_a2::ckNew(1); 
+  id_a3=CProxy_a3::ckNew(1); 
+  id_a13=CProxy_a13::ckNew(1);
+}
+
+void inherit_init(void) 
+{
+  ((CProxy_inhCoord)coordinator).startTest();
+}
+
+/*This integer lets us tell which method we called,
+so if it's not the method that executes we'll be able to tell.
+*/
+enum {
+  typeChare=1000,
+  typeGroup=2000,
+  typeArray=4000,
+  genParent= 100,
+  genChild1= 300,
+  genChild2= 700,
+  genChild3= 900,
+  genChild13=390,
+  methParent=  1,
+  methLex   =  5,
+  methInh   =  7
+};
+
+class inhCoord : public CBase_inhCoord {
+  int sendCount;
+  int doneCount;
+  
+  //Chare tests:
+  void as_cp(CProxy_cp &p,int gen) {
+    p.parent(typeChare+genParent+methParent);sendCount++;
+    p.inhLexical(typeChare+genParent+methLex);sendCount++;
+    p.inhVirtual(typeChare+gen+methInh);sendCount++;  
+  }
+  void as_c1(CProxy_c1 &p,int gen) {
+    as_cp(p,gen);
+    p.parent(typeChare+genParent+methParent);sendCount++;
+    p.inhLexical(typeChare+genChild1+methLex);sendCount++;
+    p.inhVirtual(typeChare+gen+methInh);sendCount++;  
+  }
+  void as_c2(CProxy_c2 &p,int gen) {
+    as_c1(p,gen);
+    p.parent(typeChare+genParent+methParent);sendCount++;
+    p.inhLexical(typeChare+genChild2+methLex);sendCount++;
+    p.inhVirtual(typeChare+gen+methInh);sendCount++;  
+  }
+  void as_c3(CProxy_c3 &p,int gen) {
+    as_cp(p,gen);    
+    p.parent(typeChare+genParent+methParent);sendCount++;
+    p.inhLexical(typeChare+genChild3+methLex);sendCount++;
+    p.inhVirtual(typeChare+gen+methInh);sendCount++;  
+  }
+  void as_c13(CProxy_c13 &p,int gen) {
+    as_c1(p,gen); 
+    as_c3(p,gen); 
+    p.inhLexical(typeChare+genChild13+methLex);sendCount++;
+    p.inhVirtual(typeChare+gen+methInh);sendCount++;  
+  }
+
+  //Group tests: (copy-and-paste programming at its worst!)
+  int groupDest;
+  void as_gp(CProxy_gp &p,int gen) {
+    p[groupDest].parent(typeGroup+genParent+methParent);sendCount++;
+    p[groupDest].inhLexical(typeGroup+genParent+methLex);sendCount++;
+    p[groupDest].inhVirtual(typeGroup+gen+methInh);sendCount++;  
+  }
+  void as_g1(CProxy_g1 &p,int gen) {
+    as_gp(p,gen);
+    p[groupDest].parent(typeGroup+genParent+methParent);sendCount++;
+    p[groupDest].inhLexical(typeGroup+genChild1+methLex);sendCount++;
+    p[groupDest].inhVirtual(typeGroup+gen+methInh);sendCount++;  
+  }
+  void as_g2(CProxy_g2 &p,int gen) {
+    as_g1(p,gen);
+    p[groupDest].parent(typeGroup+genParent+methParent);sendCount++;
+    p[groupDest].inhLexical(typeGroup+genChild2+methLex);sendCount++;
+    p[groupDest].inhVirtual(typeGroup+gen+methInh);sendCount++;  
+  }
+  void as_g3(CProxy_g3 &p,int gen) {
+    as_gp(p,gen);    
+    p[groupDest].parent(typeGroup+genParent+methParent);sendCount++;
+    p[groupDest].inhLexical(typeGroup+genChild3+methLex);sendCount++;
+    p[groupDest].inhVirtual(typeGroup+gen+methInh);sendCount++;  
+  }
+  void as_g13(CProxy_g13 &p,int gen) {
+    as_g1(p,gen); 
+    as_g3(p,gen); 
+    p[groupDest].inhLexical(typeGroup+genChild13+methLex);sendCount++;
+    p[groupDest].inhVirtual(typeGroup+gen+methInh);sendCount++;  
+  }
+
+  //Array tests:
+  void as_ap(CProxy_ap &p,int gen) {
+    p[0].parent(typeArray+genParent+methParent);sendCount++;
+    p[0].inhLexical(typeArray+genParent+methLex);sendCount++;
+    p[0].inhVirtual(typeArray+gen+methInh);sendCount++;  
+  }
+  void as_a1(CProxy_a1 &p,int gen) {
+    as_ap(p,gen);
+    p[0].parent(typeArray+genParent+methParent);sendCount++;
+    p[0].inhLexical(typeArray+genChild1+methLex);sendCount++;
+    p[0].inhVirtual(typeArray+gen+methInh);sendCount++;  
+  }
+  void as_a2(CProxy_a2 &p,int gen) {
+    as_a1(p,gen);
+    p[0].parent(typeArray+genParent+methParent);sendCount++;
+    p[0].inhLexical(typeArray+genChild2+methLex);sendCount++;
+    p[0].inhVirtual(typeArray+gen+methInh);sendCount++;  
+  }
+  void as_a3(CProxy_a3 &p,int gen) {
+    as_ap(p,gen);    
+    p[0].parent(typeArray+genParent+methParent);sendCount++;
+    p[0].inhLexical(typeArray+genChild3+methLex);sendCount++;
+    p[0].inhVirtual(typeArray+gen+methInh);sendCount++;  
+  }
+  void as_a13(CProxy_a13 &p,int gen) {
+    as_a1(p,gen); 
+    as_a3(p,gen); 
+    p[0].inhLexical(typeArray+genChild13+methLex);sendCount++;
+    p[0].inhVirtual(typeArray+gen+methInh);sendCount++;  
+  }
+  
+public:
+  inhCoord() { groupDest=0; }
+  void startTest(void) {
+    sendCount=0;
+    doneCount=0;  
+    groupDest=(1+groupDest)%(CkNumPes());
+    
+    {CProxy_cp p=CProxy_cp::ckNew(); as_cp(p,genParent);}
+    {CProxy_c1 p=CProxy_c1::ckNew(); as_c1(p,genChild1);}
+    {CProxy_c2 p=CProxy_c2::ckNew(); as_c2(p,genChild2);}
+    {CProxy_c3 p=CProxy_c3::ckNew(); as_c3(p,genChild3);}
+    {CProxy_c13 p=CProxy_c13::ckNew(); as_c13(p,genChild13);}
+
+    {CProxy_gp p(id_gp); as_gp(p,genParent);}
+    {CProxy_g1 p(id_g1); as_g1(p,genChild1);}
+    {CProxy_g2 p(id_g2); as_g2(p,genChild2);}
+    {CProxy_g3 p(id_g3); as_g3(p,genChild3);}
+    {CProxy_g13 p(id_g13); as_g13(p,genChild13);}
+
+    {CProxy_ap p(id_ap); as_ap(p,genParent);}
+    {CProxy_a1 p(id_a1); as_a1(p,genChild1);}
+    {CProxy_a2 p(id_a2); as_a2(p,genChild2);}
+    {CProxy_a3 p(id_a3); as_a3(p,genChild3);}
+    {CProxy_a13 p(id_a13); as_a13(p,genChild13);}
+  }
+  void done(void) {
+    if (++doneCount==sendCount)
+      megatest_finish();
+  }
+};
+
+/************ Called if an incorrect method is executed *********/
+void badMeth(const char *cls,const char *meth,int t)
+{
+  CkError("ERROR! Incorrect method %s::%s called instead of %d!\n",
+         cls,meth,t);
+  CkAbort("Incorrect method executed");
+}
+
+/************ Class definitions ***********/
+//Declares the constructor and normal methods
+#define BASIC(className,parentName,type,gen) \
+public: \
+       className() : parentName() {} \
+       className(CkMigrateMessage *m) : parentName(m) {} \
+       void inhLexical(int t) { \
+               if (t!=type+gen+methLex) badMeth(#className,"inhLexical",t); \
+               ((CProxy_inhCoord)coordinator).done();\
+       }\
+       virtual void inhVirtual(int t) { \
+               if (t!=type+gen+methInh) badMeth(#className,"inhVirtual",t); \
+               ((CProxy_inhCoord)coordinator).done();\
+        }\
+       virtual void pup(PUP::er &p) {\
+               parentName::pup(p);\
+       }\
+
+//Declares the parent method
+#define PARENT(className,type) \
+public: \
+       void parent(int t) { \
+               if (t!=type+genParent+methParent) badMeth(#className,"parent",t); \
+               ((CProxy_inhCoord)coordinator).done();\
+       }\
+
+//Declares a complete child class
+#define CHILD(className,type,gen) \
+class className : public CBase_##className { \
+       BASIC(className,CBase_##className,type,gen) \
+};\
+
+//----- chares ------
+class cp : public CBase_cp { 
+  BASIC(cp,CBase_cp,typeChare,genParent) 
+  PARENT(cp,typeChare) 
+};
+CHILD(c1,typeChare,genChild1)
+CHILD(c2,typeChare,genChild2)
+CHILD(c3,typeChare,genChild3)
+CHILD(c13,typeChare,genChild13)
+
+//------ groups ------
+class gp : public CBase_gp { 
+  BASIC(gp,CBase_gp,typeGroup,genParent) 
+  PARENT(gp,typeGroup) 
+};
+CHILD(g1,typeGroup,genChild1)
+CHILD(g2,typeGroup,genChild2)
+CHILD(g3,typeGroup,genChild3)
+CHILD(g13,typeGroup,genChild13)
+
+//------ arrays ------
+class ap : public CBase_ap { 
+  BASIC(ap,CBase_ap,typeArray,genParent) 
+  PARENT(ap,typeArray) 
+};
+CHILD(a1,typeArray,genChild1)
+CHILD(a2,typeArray,genChild2)
+CHILD(a3,typeArray,genChild3)
+CHILD(a13,typeArray,genChild13)
+
+MEGATEST_REGISTER_TEST(inherit,"olawlor",0)
+#include "inherit.def.h"
+
+
diff --git a/tests/charm++/megatest/inherit.ci b/tests/charm++/megatest/inherit.ci
new file mode 100644 (file)
index 0000000..b87f346
--- /dev/null
@@ -0,0 +1,90 @@
+module inherit {
+  chare inhCoord {
+    entry inhCoord(void);
+    entry void startTest(void);
+    entry void done(void);
+  };
+
+  chare cp {
+    entry cp();
+    entry void parent(int);
+    entry void inhLexical(int);
+    entry void inhVirtual(int);
+  };
+  chare c1 : cp {
+    entry c1();
+    entry void inhLexical(int);
+    entry void inhVirtual(int);
+  };
+  chare c2 : c1 {
+    entry c2();
+    entry void inhLexical(int);
+    entry void inhVirtual(int);
+  };
+  chare c3 : cp {
+    entry c3();
+    entry void inhLexical(int);
+    entry void inhVirtual(int);
+  };
+  chare c13 : c1, c3 {
+    entry c13();
+    entry void inhLexical(int);
+    entry void inhVirtual(int);
+  };
+
+  group gp {
+    entry gp();
+    entry void parent(int);
+    entry void inhLexical(int);
+    entry void inhVirtual(int);
+  };
+  group g1 : gp {
+    entry g1();
+    entry void inhLexical(int);
+    entry void inhVirtual(int);
+  };
+  group g2 : g1 {
+    entry g2();
+    entry void inhLexical(int);
+    entry void inhVirtual(int);
+  };
+  group g3 : gp {
+    entry g3();
+    entry void inhLexical(int);
+    entry void inhVirtual(int);
+  };
+  group g13 : g1, g3 {
+    entry g13();
+    entry void inhLexical(int);
+    entry void inhVirtual(int);
+  };
+
+  array [1D]  ap {
+    entry ap();
+    entry void parent(int);
+    entry void inhLexical(int);
+    entry void inhVirtual(int);
+  };
+  array [1D]  a1 : ap {
+    entry a1();
+    entry void inhLexical(int);
+    entry void inhVirtual(int);
+  };
+  array [1D]  a2 : a1 {
+    entry a2();
+    entry void inhLexical(int);
+    entry void inhVirtual(int);
+  };
+  array [1D]  a3 : ap {
+    entry a3();
+    entry void inhLexical(int);
+    entry void inhVirtual(int);
+  };
+  array [1D]  a13 : a1, a3 {
+    entry a13();
+    entry void inhLexical(int);
+    entry void inhVirtual(int);
+  };
+
+
+};
diff --git a/tests/charm++/megatest/inherit.h b/tests/charm++/megatest/inherit.h
new file mode 100644 (file)
index 0000000..59123b0
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _INHERIT_H
+#define _INHERIT_H
+
+#include "inherit.decl.h"
+#include "megatest.h"
+
+#endif
diff --git a/tests/charm++/megatest/marshall.C b/tests/charm++/megatest/marshall.C
new file mode 100644 (file)
index 0000000..3c908aa
--- /dev/null
@@ -0,0 +1,309 @@
+/*
+ Parameter marshalling test program
+  Orion Sky Lawlor, olawlor@acm.org, 4/6/2001
+ Creates an array, and invokes a variety of
+different marshalled entry methds.
+*/
+class flatStruct; class pupStruct; class parent;
+#include "marshall.h"
+#include <string.h>
+
+class flatStruct {
+       int x;
+       char str[10];
+public:
+       void init(void) {
+               x=1234;
+               strcpy(str,"foo");
+       }
+       void check(void) {
+               if (x!=1234 || 0!=strcmp(str,"foo"))
+                       CkAbort("flatStruct corrupted during marshalling\n");
+       }
+};
+PUPbytes(flatStruct)
+
+static int *makeArr(int tryNo,int n,int extra);
+static void checkArr(int *arr,int tryNo,int n);
+
+class parent : public PUP::able {
+public:
+       parent() {}
+       virtual const char * getSignature() {return "parent";}
+       
+       //PUP::able support:
+       PUPable_decl(parent);
+       parent(CkMigrateMessage *) {}
+       // no data fields, so no pup routine
+};
+class child : public parent {
+public:
+       child() {}
+       virtual const char * getSignature() {return "childe";}
+       
+       //PUP::able support:
+       PUPable_decl(child);
+       child(CkMigrateMessage *m):parent(m) {}
+       // no data fields, so no pup routine
+};
+
+class pupStruct {
+       int len1;
+       int *arr1;
+       int len2; 
+       int *arr2;
+       parent *subclass;
+public:
+       pupStruct() {arr1=NULL;arr2=NULL; subclass=NULL;}
+       ~pupStruct() {delete[] arr1;delete[] arr2;delete subclass;}
+       void init(parent *sub=new parent()) {
+               static int lenCount=0;
+               len1=lenCount*5+3;
+               arr1=makeArr(17,len1,0);        
+               len2=lenCount*3+7;
+               arr2=makeArr(18,len2,0);
+               subclass=sub;
+       }
+       parent *getSubclass(void) {return subclass;}
+       void check(void) {
+               checkArr(arr1,17,len1);
+               checkArr(arr2,18,len2);
+       }
+       void pup(PUP::er &p) {
+               p|len1;
+               if (p.isUnpacking()) arr1=new int[len1];
+               PUParray(p,arr1,len1);
+               p|len2;
+               if (p.isUnpacking()) arr2=new int[len2];
+               PUParray(p,arr2,len2);
+               p|subclass;
+       }
+};
+
+
+const static double basicData[10]={
+       247,'v',
+       -31000,65000,
+       -2000000000.0,4000000000.0,
+       -2000000001.0,4000000001.0,
+       12.75,4123.0e23 
+};
+
+
+class randGen {
+       unsigned int state;
+public:
+       randGen(unsigned int seed) {
+               state=(unsigned int)(0xffffu&(seed%1280107u));
+       }
+       unsigned int next(void) {
+               unsigned int val=(state<<16)+state;
+               state=(unsigned int)(0xffffu&(val%1280107u));
+               return (unsigned int)(0xffffu&val);
+       }
+};
+
+static void fillArr(int tryNo,int n,int *dest) {
+       randGen g(tryNo+257*n);
+       for (int i=0;i<n;i++)
+               dest[i]=(int)g.next();
+}
+
+static int *makeArr(int tryNo,int n,int extra)
+{
+       int *ret=new int[extra+n];
+       fillArr(tryNo,n,&ret[extra]);
+       return ret;
+}
+static void checkArr(int *arr,int tryNo,int n)
+{
+       randGen g(tryNo+257*n);
+       for (int i=0;i<n;i++) {
+               int expected=(int)g.next();
+               if (arr[i]!=expected)
+               {
+                        CkError("Array marshalling error: try %d,"
+                                        " index %d of %d (got 0x%08x; should be 0x%08x) \n",
+                                       tryNo,i,n,arr[i],expected);
+                        CkAbort("Marshalling error");
+               }
+       }
+}
+static CkMarshallMsg *makeMsg(int tryNo,int n) {
+       int len=n*sizeof(int);
+       CkMarshallMsg *msg=new (&len,0) CkMarshallMsg;
+       fillArr(tryNo,n,(int *)msg->msgBuf);
+       return msg;
+}
+static void checkMsg(CkMarshallMsg *msg,int tryNo,int n) {
+       checkArr((int *)msg->msgBuf,tryNo,n);
+       delete msg;
+}
+
+
+
+static const int numElements=20;
+static CProxy_marshallElt arrayProxy;
+static int marshallInitVal=0,eltInitVal=0;
+static void marshallInit(void) 
+{
+       marshallInitVal=0x1234567;
+}
+
+static int reflector=0;
+void marshall_init(void)
+{
+  if (marshallInitVal!=0x1234567)
+       CkAbort("initcall marshallInit never got called!\n");
+  if (eltInitVal!=0x54321)
+       CkAbort("initcall marshallElt::eltInit never got called!\n");
+  reflector++;
+  for (int i=0;i<numElements;i++)
+       arrayProxy[(i+reflector)%numElements].reflectMarshall(i);
+  arrayProxy[0].done();
+}
+
+
+void marshall_moduleinit(void){
+       if (CkMyPe()==0) {
+               arrayProxy=CProxy_marshallElt::ckNew(); 
+               for (int i=0;i<numElements;i++) arrayProxy[i].insert();
+               arrayProxy.doneInserting();
+       }
+}
+
+
+/// Send the array element ap[i] a whole set of marshalled messages.
+static void callMarshallElt(const CProxy_marshallElt &ap,int i) {
+     ap[i].basic((unsigned char)basicData[0],(char)basicData[1],
+                                (short)basicData[2],(unsigned short)basicData[3],
+                                (int)basicData[4],(unsigned int)basicData[5],
+                                (long)basicData[6],(unsigned long)basicData[7],
+                                (float)basicData[8],(double)basicData[9]);
+
+     flatStruct f; f.init();
+     ap[i].flatRef(f);
+     pupStruct p; 
+     p.init();
+     ap[i].pupped(p);
+     pupStruct p2; 
+     p2.init(new child);
+     ap[i].puppedSubclass(p2);
+     
+     parent *sub=new child;
+     ap[i].PUPableReference(*sub);
+     ap[i].PUPablePointer(sub);
+     delete sub;
+
+     int n=0+13*i*i;
+     int *arr=makeArr(1,n,0);
+     ap[i].simpleArray(n,arr);
+     delete[] arr;
+
+     int m=1+i;
+     int *arr2=makeArr(2,n*m,0);
+     ap[i].fancyArray(arr2,n,m);
+     delete[] arr2;
+
+     int n1=2+7*i*i,n2=4+i;
+     int *a1=makeArr(3,n1,1);
+     int *a2=makeArr(4,n2+n,1);
+     a1[0]=n2+1; a2[0]=n1+1;
+     ap[i].crazyArray(a1,a2,n);
+     delete[] a1;
+     delete[] a2;
+     
+     int j;
+     msgQ_t q;
+     ap[i].msgQ(0,q);
+     const int nQ=2;
+     for (j=0;j<nQ;j++)
+       q.enq(makeMsg(5,13+2*j));
+     ap[i].msgQ(nQ,q);
+     for (j=0;j<nQ;j++)
+       delete q.deq();
+}
+
+class marshallElt: public CBase_marshallElt
+{
+    int count;
+    void next(void) {
+//CkPrintf("Marshall, pe %d> element %d at %d\n",CkMyPe(),thisIndex,count);
+       const int numTests=11; /* number of tests listed in callMarshallElt */
+       if (++count == numTests+1)  /* all tests plus done() message */
+       {//All tests passed for this element
+         count=0;
+          if (thisIndex==(::numElements-1)) megatest_finish();
+          else  {
+           thisProxy[thisIndex+1].done();
+         }
+       }
+    }
+    void checkChild(parent *p) {
+       if (0!=strcmp("childe",p->getSignature()))
+               CkAbort("Subclass not pup'ed properly");
+    }
+public:
+    marshallElt() { 
+      count=0; 
+//      CkPrintf("Created marshalling object %d\n",thisIndex);
+    }
+    marshallElt(CkMigrateMessage *) {}
+    void done(void) {next();}
+    void reflectMarshall(int forElt) {
+       callMarshallElt(thisProxy,forElt);
+    }
+
+    void basic(unsigned char b,char c,
+                short i,unsigned short j,
+                int k,unsigned int l,
+                long m,unsigned long n,
+                float f,double d)
+    {
+       if (b!=basicData[0] || c!=basicData[1] ||
+           i!=basicData[2] || j!=basicData[3] ||
+           k!=basicData[4] || l!=basicData[5] ||
+           m!=basicData[6] || n!=basicData[7] ||
+           f!=basicData[8] || d!=basicData[9])
+               CkAbort("Basic data marshalling test failed\n");
+       next();
+    }
+    void flatRef(flatStruct &s) {s.check(); next();}
+    void pupped(pupStruct &s) {s.check(); next();}
+    void puppedSubclass(pupStruct &s) {
+       s.check(); 
+       checkChild(s.getSubclass());
+       next();
+    }
+    void PUPableReference(parent &p) {
+       checkChild(&p);
+       next();
+    }
+    void PUPablePointer(parent *p) {
+       checkChild(p);
+       delete p;
+       next();
+    }
+    void simpleArray(int n,int *arr) {checkArr(arr,1,n); next();}
+    void fancyArray(int *arr2,int n,int m) {checkArr(arr2,2,n*m); next();}
+    void crazyArray(int *arr1,int *arr2,int n)
+    {
+        checkArr(&arr1[1],3,arr2[0]-1);
+        checkArr(&arr2[1],4,arr1[0]-1+n);
+        next();
+    }
+    void msgQ(int n,msgQ_t &q) {
+       if (n!=q.length()) CkAbort("Message queue length corrupted during marshalling");
+       for (int i=0;i<n;i++)
+               checkMsg(q.deq(),5,13+2*i);
+       next();
+    }
+    static void eltInit(void) {
+       eltInitVal=0x54321;
+    }
+};
+
+MEGATEST_REGISTER_TEST(marshall,"olawlor",1);
+#include "marshall.def.h"
+
diff --git a/tests/charm++/megatest/marshall.ci b/tests/charm++/megatest/marshall.ci
new file mode 100644 (file)
index 0000000..f0685aa
--- /dev/null
@@ -0,0 +1,25 @@
+module marshall {
+ PUPable parent, child;
+ initnode void marshallInit(void);
+ array [1D] marshallElt {
+    entry marshallElt();
+    entry void basic(unsigned char b,char c,
+               short i,unsigned short j,
+               int k,unsigned int l,
+               long m,unsigned long n,
+               float f,double d);
+    entry void flatRef(flatStruct &s);
+    entry void pupped(pupStruct &s);
+    entry void puppedSubclass(pupStruct &s);
+    entry void PUPableReference(CkReference<parent> p);
+    entry void PUPablePointer(CkPointer<parent> p);
+    entry void simpleArray(int n,int arr[n]);
+    entry void fancyArray(int arr2[n*m],int n,int m);
+    entry void crazyArray(int arr1[arr2[0]],int arr2[arr1[0]+n],int n);
+    entry void msgQ(int nMsgs,msgQ_t q);
+
+    entry void reflectMarshall(int forElt);
+    entry void done(void);
+    initnode void eltInit(void);
+  };
+};
diff --git a/tests/charm++/megatest/marshall.h b/tests/charm++/megatest/marshall.h
new file mode 100644 (file)
index 0000000..460d3e5
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef _MARSHALL_H
+#define _MARSHALL_H
+
+#include "charm++.h"
+typedef CkMsgQ<CkMarshallMsg> msgQ_t;
+
+#include "marshall.decl.h"
+#include "megatest.h"
+
+#endif
diff --git a/tests/charm++/megatest/megatest.C b/tests/charm++/megatest/megatest.C
new file mode 100644 (file)
index 0000000..c9adf87
--- /dev/null
@@ -0,0 +1,220 @@
+ /**************************************************************************
+ * DESCRIPTION:
+ *
+ * To add a test to megatest, you have to:
+ *
+ *   1. write a testname_moduleinit function that initializes the module.
+ *   2. write a testname_init function that starts the test.
+ *   3. declare the testname_init function inside this module.
+ *   4. extend the tests[] table in this module to include the new test.
+ *   5. add extern module statement to megatest.ci
+ *
+ **************************************************************************/
+
+#include <stdio.h>
+#include "megatest.h"
+
+/******************************************************************************
+ *
+ * Test Configuration Section
+ *
+ *****************************************************************************/
+
+struct testinfo
+{
+  const char *name;
+  const char *author;
+  megatest_init_fn initiator;
+  megatest_moduleinit_fn initializer;
+  int reentrant;
+  megatest_register_fn regfn;
+} tests[100]={0};
+int nTests=0;
+
+/**
+ This routine is called from MEGATEST_REGISTER_TEST, which 
+ means it may be called before global variable initialization is complete.
+*/
+void megatest_register(const char *moduleName,const char *author,
+       megatest_init_fn init, megatest_moduleinit_fn moduleinit,
+       int reentrant, megatest_register_fn regfn)
+{
+       // printf("Registering module %s \n",moduleName);
+       tests[nTests].name=moduleName;
+       tests[nTests].author=author;
+       tests[nTests].initiator=init;
+       tests[nTests].initializer=moduleinit;
+       tests[nTests].reentrant=reentrant;
+       tests[nTests].regfn=regfn;
+       nTests++;
+}
+
+/******************************************************************************
+ *
+ * Central Control Section
+ *
+ *****************************************************************************/
+#include "megatest.decl.h"
+
+CkChareID mainhandle;
+
+class main : public Chare {
+ private:
+  int test_bank_size;
+  double test_start_time;
+  int next_test_index;
+  int next_test_number;
+  int acks_expected;
+  int acks_received;
+  
+// Command line arguments:
+  int test_negate_skip; // boolean: *only* run listed tests
+  int test_repeat;      // boolean: keep running tests
+  char **tests_to_skip; // argv
+  int num_tests_to_skip; // argc
+  int megatest_skip(const char *);
+  
+  void megatest_next(void);
+ public:
+
+  main(CkArgMsg *);
+  main(CkMigrateMessage *m) {}
+  void start(void);
+  void finish(void);
+};
+
+void megatest_finish(void)
+{
+  CProxy_main mainproxy(mainhandle);
+  mainproxy.finish();
+}
+
+int main::megatest_skip(const char *test)
+{
+  int i;
+  int num_skip = num_tests_to_skip;
+  char **skip;
+  skip = tests_to_skip;
+  for (i=0; i<num_skip; i++) {
+    if ((skip[i][0]=='-')&&(strcmp(skip[i]+1, test)==0))
+      return 1 - test_negate_skip;
+  }
+  return test_negate_skip;
+}
+
+void main::megatest_next(void)
+{
+  int i, pos, idx, num, bank;
+
+  bank = test_bank_size;
+  num = next_test_number;
+
+nextidx:
+  idx = next_test_index;
+  if (idx < bank) {
+    if (megatest_skip(tests[idx].name)) {
+      next_test_index++;
+      goto nextidx;
+    }
+    test_start_time = CkWallTimer();
+    CkPrintf("test %d: initiated [%s (%s)]\n", num, tests[idx].name, 
+                                               tests[idx].author);
+    acks_expected = 1;
+    acks_received = 0;
+    (tests[idx].initiator)();
+    return; 
+  }
+  if (idx < (2*bank)) {
+    pos = idx - bank;
+    if (!tests[pos].reentrant||(megatest_skip(tests[pos].name))||
+        test_negate_skip) {
+      next_test_index++;
+      goto nextidx;
+    }
+    acks_expected = 5;
+    acks_received = 0;
+    test_start_time = CkWallTimer();
+    CmiPrintf("test %d: initiated [multi %s (%s)]\n", num, tests[pos].name,
+                                                      tests[pos].author);
+    for (i=0; i<5; i++) (tests[pos].initiator)();
+    return;
+  }
+  if (idx== (2*bank)) {
+    acks_expected = 1;
+    acks_received = 0;
+    test_start_time = CkWallTimer();
+    CmiPrintf("test %d: initiated [all-at-once]\n", num);
+    for (i=0; i<bank; i++) {
+      if (!megatest_skip(tests[i].name)) {
+       acks_expected++;
+       (tests[i].initiator)();
+      }
+    }
+    megatest_finish();
+    return;
+  }
+  if (idx== ((2*bank)+1)) {
+    if (test_repeat) { 
+      next_test_index=0;
+      goto nextidx;
+    } else { /* no repeat, normal exit */
+      CkPrintf("All tests completed, exiting\n");
+      CkExit();
+    }
+  }
+}
+
+void main::finish(void)
+{
+    acks_received++;
+    if(acks_expected != acks_received)
+      return;
+    CkPrintf("test %d: completed (%1.2f sec)\n",
+             next_test_number,
+             CkWallTimer() - test_start_time);
+    next_test_number++;
+    next_test_index++;
+    megatest_next();
+}
+
+main::main(CkArgMsg *msg)
+{
+  CmiPrintf("Megatest is running on %d processors. \n", CkNumPes());
+  int argc = msg->argc;
+  char **argv = msg->argv;
+  int numtests, i;
+  delete msg;
+  mainhandle = thishandle;
+  if (nTests<=0)
+    CkAbort("Megatest: No tests registered-- is MEGATEST_REGISTER_TEST malfunctioning?");
+  for (i=0; i<nTests; i++)
+    (tests[i].initializer)();
+  test_bank_size = nTests;
+  next_test_index = 0;
+  next_test_number = 0;
+  test_negate_skip=0;
+  test_repeat = 0;
+  for (i=1; i<argc; i++) {
+    if (strcmp(argv[i],"-only")==0)
+      test_negate_skip = 1;
+    if (strcmp(argv[i],"-repeat")==0)
+      test_repeat = 1;
+  }
+  num_tests_to_skip = argc;
+  tests_to_skip = argv;
+  CProxy_main(thishandle).start();
+}
+
+void main::start()
+{
+  megatest_next();
+}
+
+void megatest_initnode(void)
+{
+       for (int i=0; i<nTests; i++)
+                if (tests[i].regfn)
+                       tests[i].regfn();
+}
+
+#include "megatest.def.h"
diff --git a/tests/charm++/megatest/megatest.ci b/tests/charm++/megatest/megatest.ci
new file mode 100644 (file)
index 0000000..508b6ae
--- /dev/null
@@ -0,0 +1,10 @@
+mainmodule megatest {
+  readonly CkChareID  mainhandle;
+  mainchare main {
+    entry main();
+    entry void start();
+    entry void finish(void);
+  };
+  initnode void megatest_initnode(void);
+};
+
diff --git a/tests/charm++/megatest/megatest.h b/tests/charm++/megatest/megatest.h
new file mode 100644 (file)
index 0000000..6761840
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef MEGATEST_H
+#define MEGATEST_H
+
+#include "charm++.h"
+
+/**
+  Start running this test.  
+  This routine is called from processor 0 (from a mainchare).
+  If the test is reentrant, this function may be called
+  multiple times.
+  The test finishes successfully with "megatest_finish".
+*/
+typedef void (*megatest_init_fn)(void);
+
+/// Indicate to megatest that this test finished successfully.
+void megatest_finish(void);
+
+
+/// Do any one-time initialization for this test, like in a main routine.
+typedef void (*megatest_moduleinit_fn)(void);
+/// Perform Charm++ registration for this test.
+typedef void (*megatest_register_fn)(void);
+
+/// Register this new test with megatest.  Must be called 
+///  before the mainchare executes; normally via MEGATEST_REGISTER_TEST.
+void megatest_register(const char *moduleName,const char *author,
+       megatest_init_fn init, megatest_moduleinit_fn moduleinit,
+       int reentrant, megatest_register_fn regfn);
+
+/** 
+  Use this macro to register your test with megatest.
+  
+  Place this macro at the bottom of your .C file--
+  it uses a global variable class constructor to register
+  itself with megatest.
+
+  You must provide:
+    - A Charm module called mymod
+    - A one-time (mainchare) initialization routine called mymod_moduleinit
+    - A per-test initialization routine called mymod_init
+*/
+#define MEGATEST_REGISTER_TEST(mymod,author,reentrant) \
+class mymod##_init_class_t {\
+public:\
+       mymod##_init_class_t() {\
+               megatest_register(#mymod,author,\
+                       mymod##_init,mymod##_moduleinit,\
+                       reentrant, _register##mymod); \
+       }\
+};\
+mymod##_init_class_t mymod##_init_class;\
+
+
+#endif
diff --git a/tests/charm++/megatest/migration.C b/tests/charm++/megatest/migration.C
new file mode 100644 (file)
index 0000000..acca294
--- /dev/null
@@ -0,0 +1,62 @@
+#include "migration.h"
+
+void migration_init(void)
+{
+  const int numElements = 10;
+  if(CkNumPes() < 2) {
+    CkError("migration: requires at least 2 processors.\n");
+    megatest_finish();
+  } else
+    CProxy_mig_Element::ckNew(numElements);
+}
+
+void migration_moduleinit(void){}
+
+mig_Element::mig_Element()
+{
+  origPE = -1;
+  sum = 0;
+  index = thisIndex;
+  numDone = 0;
+  CProxy_mig_Element self(thisArrayID);
+  self[thisIndex].arrive();
+}
+
+void mig_Element::pup(PUP::er &p)
+{
+  ArrayElement1D::pup(p);//Call superclass
+  p(origPE);
+  p(sum);
+  p(numDone);
+  p(index);
+}
+
+void 
+mig_Element::arrive(void)
+{
+  if (thisIndex != index) 
+    CkAbort("migration: chare-data corrupted!\n");
+  CProxy_mig_Element self(thisArrayID);
+  if(CkMyPe() == origPE) {
+    if(sum != ((CkNumPes()+1)*CkNumPes())/2)
+      CkAbort("migrate: Element did not migrate to all the processors!\n");
+    self[0].done();
+  } else {
+    if(origPE==(-1)) origPE = CkMyPe();
+    sum += CkMyPe() + 1;
+    self[thisIndex].arrive();
+    int nextPE = (CkMyPe()+1)%CkNumPes();
+    migrateMe(nextPE);
+  }  
+}
+
+void
+mig_Element::done(void)
+{
+  numDone++;
+  if(numDone==numElements)
+    megatest_finish();
+}
+
+MEGATEST_REGISTER_TEST(migration,"jackie",1)
+#include "migration.def.h"
diff --git a/tests/charm++/megatest/migration.ci b/tests/charm++/megatest/migration.ci
new file mode 100644 (file)
index 0000000..c873459
--- /dev/null
@@ -0,0 +1,7 @@
+module migration {
+ array [1D] mig_Element {
+    entry mig_Element();
+    entry void arrive(void);
+    entry void done(void);
+  };
+};
diff --git a/tests/charm++/megatest/migration.h b/tests/charm++/megatest/migration.h
new file mode 100644 (file)
index 0000000..3900874
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef _MIGRATION_H
+#define _MIGRATION_H
+
+#include "migration.decl.h"
+#include "megatest.h"
+
+class mig_Element : public ArrayElement1D
+{
+ public:
+  mig_Element();
+  mig_Element(CkMigrateMessage *msg){}
+  void done(void);
+  void arrive(void);
+  void pup(PUP::er &p);
+ private:
+  int origPE, index, numDone, sum;
+};
+
+#endif
diff --git a/tests/charm++/megatest/nodecast.C b/tests/charm++/megatest/nodecast.C
new file mode 100644 (file)
index 0000000..db332ba
--- /dev/null
@@ -0,0 +1,50 @@
+#include "nodecast.h"
+
+void nodecast_moduleinit(void) {}
+
+void nodecast_init(void) 
+{
+  CProxy_nodecast_main::ckNew();
+}
+
+nodecast_main::nodecast_main(void) 
+{
+  count = 0;
+  nodecast_SimpleMsg *sm = new nodecast_SimpleMsg;
+  sm->mainhandle = thishandle;
+  CProxy_nodecast_group::ckNew(sm);
+}
+
+void nodecast_main::reply(nodecast_SimpleMsg *em) {
+  gid = em->gid;
+  delete em;
+  count++;
+  if (count == CkNumNodes()) {
+    CProxy_nodecast_group groupproxy(gid);
+    nodecast_BCMsg *g_bcm = new nodecast_BCMsg;
+    groupproxy.doBroadcast(g_bcm);
+  } else if (count == CkNumNodes()*2) {
+      delete this;
+      megatest_finish();
+  }
+}
+
+nodecast_group::nodecast_group(nodecast_SimpleMsg *sm) {
+  myMain = sm->mainhandle;
+  sm->gid = thisgroup;
+  CProxy_nodecast_main mainproxy(myMain);
+  mainproxy.reply(sm);
+}
+
+void nodecast_group::doBroadcast(nodecast_BCMsg *bcm) {
+  if (!bcm->check()) {
+    CkAbort("nodecast: broadcast message is corrupted!\n");
+  }
+  delete bcm;
+  CProxy_nodecast_main mainproxy(myMain);
+  nodecast_SimpleMsg *g_em = new nodecast_SimpleMsg;
+  mainproxy.reply(g_em);
+}
+
+MEGATEST_REGISTER_TEST(nodecast,"milind",1)
+#include "nodecast.def.h"
diff --git a/tests/charm++/megatest/nodecast.ci b/tests/charm++/megatest/nodecast.ci
new file mode 100644 (file)
index 0000000..d0a8afd
--- /dev/null
@@ -0,0 +1,14 @@
+module nodecast {
+  message nodecast_SimpleMsg;
+  message nodecast_BCMsg;
+
+  chare nodecast_main {
+    entry nodecast_main(void);
+    entry void reply(nodecast_SimpleMsg *);
+  };
+
+  nodegroup nodecast_group {
+    entry nodecast_group(nodecast_SimpleMsg *);
+    entry void doBroadcast(nodecast_BCMsg *);
+  };
+};
diff --git a/tests/charm++/megatest/nodecast.h b/tests/charm++/megatest/nodecast.h
new file mode 100644 (file)
index 0000000..5406839
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef _GROUPCAST_H
+#define _GROUPCAST_H
+
+#include "megatest.h"
+#include "nodecast.decl.h"
+
+class nodecast_SimpleMsg : public CMessage_nodecast_SimpleMsg {
+public:
+  CkGroupID gid;
+  CkChareID mainhandle;
+};
+
+class nodecast_BCMsg : public CMessage_nodecast_BCMsg {
+private:
+  char checkString[11];
+public:
+  nodecast_BCMsg(void) { sprintf(checkString, "Broadcast!");} 
+  int check(void) { 
+    if (strcmp("Broadcast!", checkString) == 0)
+      return 1;
+    else
+      return 0;
+  }
+};
+
+class nodecast_main : public Chare {
+private:
+  CkGroupID gid;
+  int count;
+public:
+  nodecast_main(void);
+  nodecast_main(CkMigrateMessage *m) {}
+  void reply(nodecast_SimpleMsg *em);
+};
+
+class nodecast_group : public NodeGroup {
+private:
+  CkChareID myMain;
+public:
+  nodecast_group(nodecast_SimpleMsg *sm);
+  nodecast_group(CkMigrateMessage *m) {}
+  void doBroadcast(nodecast_BCMsg *bcm);
+};
+
+#endif
diff --git a/tests/charm++/megatest/nodering.C b/tests/charm++/megatest/nodering.C
new file mode 100644 (file)
index 0000000..9a9cba1
--- /dev/null
@@ -0,0 +1,31 @@
+#include "nodering.h"
+
+readonly<CkGroupID> nodering_thisgroup;
+static int nextseq = 0;
+
+void nodering_init(void)
+{
+  nodering_message *msg = new nodering_message(nextseq++,0);
+  CProxy_nodering_group pgg(nodering_thisgroup);
+  pgg[0].start(msg);
+}
+
+void nodering_moduleinit(void) {}
+
+void nodering_group::start(nodering_message *msg)
+{
+  CProxyElement_nodering_group pgg(
+    nodering_thisgroup, (CkMyNode()+1)%CkNumNodes());
+  if(CkMyNode()==0 && msg->iter==NITER) {
+    delete msg;
+    megatest_finish();
+  } else if(CkMyNode()==0) {
+    msg->iter++;
+    pgg.start(msg);
+  } else {
+    pgg.start(msg);
+  }
+}
+
+MEGATEST_REGISTER_TEST(nodering,"milind",1)
+#include "nodering.def.h"
diff --git a/tests/charm++/megatest/nodering.ci b/tests/charm++/megatest/nodering.ci
new file mode 100644 (file)
index 0000000..b023069
--- /dev/null
@@ -0,0 +1,11 @@
+module nodering {
+  message nodering_message;
+  mainchare nodering_main {
+    entry nodering_main();
+  };
+  nodegroup nodering_group {
+    entry nodering_group(void);
+    entry void start(nodering_message *);
+  };
+};
+
diff --git a/tests/charm++/megatest/nodering.h b/tests/charm++/megatest/nodering.h
new file mode 100644 (file)
index 0000000..2c4c5fa
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef GROUPRING_H
+#define GROUPRING_H
+
+#include "megatest.h"
+#include "nodering.decl.h"
+
+#define NITER 100
+
+extern readonly<CkGroupID> nodering_thisgroup;
+
+class nodering_message : public CMessage_nodering_message {
+ public:
+  int seqnum;
+  int iter;
+  nodering_message(int s, int i) : seqnum(s), iter(i) {}
+};
+
+class nodering_main : public Chare {
+  public:
+    nodering_main(CkArgMsg *m) {
+      delete m;
+      nodering_thisgroup = CProxy_nodering_group::ckNew();
+    }
+    nodering_main(CkMigrateMessage *m) {}
+};
+
+class nodering_group : public NodeGroup {
+  public:
+    nodering_group(void) {}
+    nodering_group(CkMigrateMessage *m) {}
+    void start(nodering_message *msg);
+};
+
+#endif 
diff --git a/tests/charm++/megatest/packtest.C b/tests/charm++/megatest/packtest.C
new file mode 100644 (file)
index 0000000..f9425a7
--- /dev/null
@@ -0,0 +1,85 @@
+#include "converse.h"
+#include "packtest.h"
+
+void packtest_init(void)
+{ 
+  CProxy_packtest_Btest::ckNew();
+}
+
+void packtest_moduleinit(void) {}
+
+void *packtest_Msg::pack(packtest_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];
+  delete m;
+  return(p);
+}
+
+packtest_Msg * packtest_Msg::unpack(void *buf)
+{
+   int *in = (int *) buf;
+   packtest_Msg *t = new (CkAllocBuffer(in, sizeof(packtest_Msg)))packtest_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;
+}
+
+packtest_Btest::packtest_Btest(void)
+{
+/*
+  static CrnStream str;
+  static int flag = 0;
+  if (0 == flag) {
+    CrnInitStream(&str, (int)this, 0);
+    flag = 1;
+  }
+  // seed needs to be set only once
+*/
+
+  if(CkMyPe()==0) {
+    packtest_Msg *msg = new packtest_Msg;
+
+    // msg->value = sentval = CrnInt(&str);
+    msg->value = sentval = CrnRand();
+    msg->hop=1;
+    msg->listsize=10;
+    msg->list1=new int[msg->listsize];
+    for (int i=0;i<msg->listsize;i++) 
+      msg->list1[i]=i;
+
+    CProxy_packtest_Btest btest(thisgroup);
+    btest[(CkMyPe()+1)%CkNumPes()].recv_msg(msg);
+  }
+}
+
+void 
+packtest_Btest::recv_msg(packtest_Msg * m)
+{
+  if (CkMyPe() == 0) {
+    for (int i=0;i<m->listsize;i++)
+      if(m->list1[i]!=i)
+        CkAbort("packtest: message corrupted!\n");
+    if(sentval != m->value)
+      CkAbort("packtest: message corrupted!\n");
+    delete m;
+    megatest_finish();
+  } else {
+    CProxy_packtest_Btest btest(thisgroup);
+    btest[(CkMyPe()+1)%CkNumPes()].recv_msg(m);
+  }
+}
+
+MEGATEST_REGISTER_TEST(packtest,"fang",1)
+#include "packtest.def.h"
diff --git a/tests/charm++/megatest/packtest.ci b/tests/charm++/megatest/packtest.ci
new file mode 100644 (file)
index 0000000..adb4ecc
--- /dev/null
@@ -0,0 +1,9 @@
+module packtest {
+  message packtest_Msg;
+
+  group packtest_Btest {
+    entry packtest_Btest(void);
+    entry void recv_msg(packtest_Msg *);
+  };
+}
+
diff --git a/tests/charm++/megatest/packtest.h b/tests/charm++/megatest/packtest.h
new file mode 100644 (file)
index 0000000..ecf472f
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef _PACKTEST_H
+#define _PACKTEST_H
+
+#include "megatest.h"
+#include "packtest.decl.h"
+
+class packtest_Msg : public CMessage_packtest_Msg
+{
+  public:
+    int value;
+    int hop;
+    int *list1;
+    int listsize;
+    static void *pack(packtest_Msg *);
+    static packtest_Msg  *unpack(void *);
+    packtest_Msg(void) { list1=0; }
+    ~packtest_Msg(void) { if(list1) delete[] list1; }
+};
+
+class packtest_Btest : public Group
+{
+  private:
+    int sentval;
+  public:
+    packtest_Btest(void);
+    packtest_Btest(CkMigrateMessage *m) {}
+    void recv_msg(packtest_Msg *);
+};
+
+#endif
diff --git a/tests/charm++/megatest/priolongtest.C b/tests/charm++/megatest/priolongtest.C
new file mode 100644 (file)
index 0000000..d79916d
--- /dev/null
@@ -0,0 +1,47 @@
+#include "priolongtest.h"
+
+void priolongtest_init(void)
+{
+  CProxy_priolongtest_chare::ckNew();
+}
+
+void priolongtest_moduleinit(void) {}
+
+priolongtest_chare::priolongtest_chare(void)
+{
+  CProxy_priolongtest_chare self(thishandle);
+  // max is 9223372036854775807LL
+  lastprio = -922337203685477550LL;
+  CmiInt8 lastsend=lastprio+NMSG+1;
+  for(CmiInt8 i=lastprio; i<lastsend; i++) {
+    priolongtest_msg *m = new (8*sizeof(CmiInt8)) priolongtest_msg(i);
+    memcpy((CmiInt8 *) CkPriorityPtr(m), &i,sizeof(CmiInt8));
+    CkSetQueueing(m, CK_QUEUEING_LFIFO);
+    self.recv(m);
+  }
+  for(CmiInt8 i=NMSG-1; i>=0LL; i--) {
+    priolongtest_msg *m = new (8*sizeof(CmiInt8)) priolongtest_msg(i);
+    memcpy((CmiInt8 *) CkPriorityPtr(m), &i,sizeof(CmiInt8));
+    CkSetQueueing(m, CK_QUEUEING_LFIFO);
+    self.recv(m);
+  }
+
+}
+
+void
+priolongtest_chare::recv(priolongtest_msg *m)
+{
+  if(m->prio < lastprio)
+    {
+      CkPrintf("priolongtest: message %lld after %lld \n",m->prio, lastprio);
+      CkAbort("priolongtest: message received out of order\n");
+    }
+  //  CkPrintf("priolongtest: got %lld prev was %lld \n",m->prio, lastprio);
+  lastprio = m->prio;
+  delete m;
+  if(lastprio == NMSG-1)
+    megatest_finish();
+}
+
+MEGATEST_REGISTER_TEST(priolongtest,"ebohm",1)
+#include "priolongtest.def.h"
diff --git a/tests/charm++/megatest/priolongtest.ci b/tests/charm++/megatest/priolongtest.ci
new file mode 100644 (file)
index 0000000..01a85ed
--- /dev/null
@@ -0,0 +1,7 @@
+module priolongtest {
+  message priolongtest_msg;
+  chare priolongtest_chare {
+    entry priolongtest_chare(void);
+    entry void recv(priolongtest_msg *);
+  };
+}
diff --git a/tests/charm++/megatest/priolongtest.h b/tests/charm++/megatest/priolongtest.h
new file mode 100644 (file)
index 0000000..a3c7c85
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef _PRIOLONGTEST_H
+#define _PRIOLONGTEST_H
+
+#include "priolongtest.decl.h"
+#include "megatest.h"
+
+#define NMSG 100
+
+/* slightly hacked up version of milind's priotest */
+
+class priolongtest_msg : public CMessage_priolongtest_msg
+{
+  public:
+    CmiInt8 prio;
+    priolongtest_msg(CmiInt8 p) : prio(p) {}
+};
+
+class priolongtest_chare : public Chare
+{
+  private:
+    CmiInt8 lastprio;
+  public:
+    priolongtest_chare(void);
+    priolongtest_chare(CkMigrateMessage *m) {}
+    void recv(priolongtest_msg *);
+};
+
+#endif
diff --git a/tests/charm++/megatest/priomsg.C b/tests/charm++/megatest/priomsg.C
new file mode 100644 (file)
index 0000000..737267f
--- /dev/null
@@ -0,0 +1,38 @@
+#include "priomsg.h"
+
+void priomsg_init(void)
+{ 
+  priomsg_Msg *m = new (8*sizeof(int)) priomsg_Msg;
+  *((int *)CkPriorityPtr(m)) = 100;
+  CkSetQueueing(m, CK_QUEUEING_IFIFO);
+  CProxy_priomsg_test pri=CProxy_priomsg_test::ckNew();
+  pri.donow(m);
+}
+
+void priomsg_moduleinit (void) {}
+
+void priomsg_test::donow(priomsg_Msg *m)
+{
+  if(!m->check()) 
+    CkAbort("priomsg: message corrupted!\n");
+  delete m;
+  megatest_finish();   
+}
+
+priomsg_Msg::priomsg_Msg(void)
+{
+  for(int i=0; i<10; i++)
+    data[i] = i*i;
+}
+
+int priomsg_Msg::check(void)
+{
+  for(int i=0; i<10; i++)
+    if(data[i] != i*i)
+      return 0;
+  return 1;
+}
+
+
+MEGATEST_REGISTER_TEST(priomsg,"fang",1)
+#include "priomsg.def.h"
diff --git a/tests/charm++/megatest/priomsg.ci b/tests/charm++/megatest/priomsg.ci
new file mode 100644 (file)
index 0000000..5f06d7f
--- /dev/null
@@ -0,0 +1,7 @@
+module priomsg {
+  message priomsg_Msg;
+  chare priomsg_test {
+    entry priomsg_test(void);
+    entry void donow(priomsg_Msg *);
+  };
+}
diff --git a/tests/charm++/megatest/priomsg.h b/tests/charm++/megatest/priomsg.h
new file mode 100644 (file)
index 0000000..d531c10
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _PRIOMSG_H
+#define _PRIOMSG_H
+
+#include "megatest.h"
+#include "priomsg.decl.h"
+
+class priomsg_Msg : public CMessage_priomsg_Msg {
+ public:
+  priomsg_Msg(void);
+  int check(void);
+  int data[10];
+}; 
+
+class priomsg_test : public Chare {
+ public:
+  priomsg_test(void) {};
+  priomsg_test(CkMigrateMessage *m) {}
+  void donow(priomsg_Msg *m);
+};
+
+#endif
diff --git a/tests/charm++/megatest/priotest.C b/tests/charm++/megatest/priotest.C
new file mode 100644 (file)
index 0000000..f210083
--- /dev/null
@@ -0,0 +1,34 @@
+#include "priotest.h"
+
+void priotest_init(void)
+{
+  CProxy_priotest_chare::ckNew();
+}
+
+void priotest_moduleinit(void) {}
+
+priotest_chare::priotest_chare(void)
+{
+  CProxy_priotest_chare self(thishandle);
+  lastprio = -1;
+  for(int i=NMSG-1; i>=0; i--) {
+    priotest_msg *m = new (8*sizeof(int)) priotest_msg(i);
+    *((int *)CkPriorityPtr(m)) = i;
+    CkSetQueueing(m, CK_QUEUEING_IFIFO);
+    self.recv(m);
+  }
+}
+
+void
+priotest_chare::recv(priotest_msg *m)
+{
+  if(m->prio < lastprio)
+    CkAbort("priotest: message received out of order\n");
+  lastprio = m->prio;
+  delete m;
+  if(lastprio == NMSG-1)
+    megatest_finish();
+}
+
+MEGATEST_REGISTER_TEST(priotest,"mlind",1)
+#include "priotest.def.h"
diff --git a/tests/charm++/megatest/priotest.ci b/tests/charm++/megatest/priotest.ci
new file mode 100644 (file)
index 0000000..9a5e776
--- /dev/null
@@ -0,0 +1,7 @@
+module priotest {
+  message priotest_msg;
+  chare priotest_chare {
+    entry priotest_chare(void);
+    entry void recv(priotest_msg *);
+  };
+}
diff --git a/tests/charm++/megatest/priotest.h b/tests/charm++/megatest/priotest.h
new file mode 100644 (file)
index 0000000..20815a0
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef _PRIOTEST_H
+#define _PRIOTEST_H
+
+#include "priotest.decl.h"
+#include "megatest.h"
+
+#define NMSG 100
+
+class priotest_msg : public CMessage_priotest_msg
+{
+  public:
+    int prio;
+    priotest_msg(int p) : prio(p) {}
+};
+
+class priotest_chare : public Chare
+{
+  private:
+    int lastprio;
+  public:
+    priotest_chare(void);
+    priotest_chare(CkMigrateMessage *m) {}
+    void recv(priotest_msg *);
+};
+
+#endif
diff --git a/tests/charm++/megatest/queens.C b/tests/charm++/megatest/queens.C
new file mode 100644 (file)
index 0000000..50037f7
--- /dev/null
@@ -0,0 +1,164 @@
+#include "queens.h"
+
+readonly<CkGroupID> queens_counterGroup;
+
+void queens_init(void)
+{
+  queens_DMSG *dmsg = new queens_DMSG;
+  dmsg->counterGroup = queens_counterGroup; 
+  CProxy_queens_main::ckNew(dmsg, 0);
+}
+
+void queens_moduleinit(void)
+{
+  queens_counterGroup = CProxy_queens_counter::ckNew(); 
+}
+
+queens_main::queens_main(queens_DMSG * dmsg)
+{ 
+  // CkPrintf("[%d] queens_main created\n", CkMyPe());
+  counterGroup = dmsg->counterGroup;
+  queens_PartialBoard *pMsg = new queens_PartialBoard ;
+
+  pMsg->nextRow = 0;
+  pMsg->counterGroup = counterGroup;
+  CProxy_queens_queens::ckNew(pMsg);
+
+  CkStartQD(CkIndex_queens_main::Quiescence1((CkQdMsg *)0), 
+            &thishandle);
+}
+
+void 
+queens_main::Quiescence1(CkQdMsg *msg) 
+{ 
+  // CkPrintf("QD reached\n");
+  int ns = CProxy_queens_counter(counterGroup).ckLocalBranch()->getTotalCount();
+
+  if (ns != EXPECTNUM){
+    CkError("queens: expected solutions = %d, got=%d\n", EXPECTNUM, ns);
+    CkAbort("queens: unexpected number of solutions\n");
+  }
+  delete msg;
+  megatest_finish();
+}
+
+queens_queens::queens_queens(queens_PartialBoard *m)
+{ 
+  int col,i, row;
+  queens_PartialBoard *newMsg;
+  
+  row = m->nextRow;  
+  counterGroup = m->counterGroup;
+  if (row == NUMQUEENS) 
+    solutionFound();
+  else if ( (NUMQUEENS - row) < Q_GRAIN) 
+    seqQueens(m->Queens, row); 
+  else
+  {
+    for (col = 0; col<NUMQUEENS; col++) 
+      if (consistent(m->Queens, row, col))
+      {
+       newMsg = new  queens_PartialBoard;
+       newMsg->nextRow = row + 1;
+       newMsg->counterGroup = counterGroup;
+       for (i=0; i< NUMQUEENS; i++)
+         newMsg->Queens[i] = m->Queens[i];
+       newMsg->Queens[row] = col;
+       CProxy_queens_queens::ckNew(newMsg);  
+      }
+  }
+  delete m;
+  delete this;
+}
+
+
+void 
+queens_queens::solutionFound(void)
+{ 
+  CProxy_queens_counter(counterGroup).ckLocalBranch()->increment();
+}
+
+void 
+queens_queens::seqQueens(int kqueens[], int nextRow)
+{ 
+  int col;
+
+  if (nextRow == NUMQUEENS) { 
+    solutionFound();
+    return; 
+  }
+  for (col = 0; col < NUMQUEENS; col++) 
+    if (consistent(kqueens, nextRow, col)) {
+      kqueens[nextRow] = col;
+      seqQueens(kqueens, nextRow+1);
+    }
+}
+
+int 
+queens_queens::consistent(int kqueens[], int lastRow, int col)
+{ 
+  for (int x=0; x<lastRow; x++)
+  { 
+    int y = kqueens[x];
+    if ((y==col)  || ((lastRow-x) == (col-y)) || ((lastRow-x) == (y-col)) ) {
+      return(0);
+    }
+  }
+  return(1);
+}
+
+queens_counter::queens_counter(void)
+{ 
+  myCount = 0;
+  waitFor = CkNumPes(); // wait for all processors to report
+  threadId = 0;
+}
+
+void 
+queens_counter::increment(void)
+{
+  myCount++;
+}
+
+void 
+queens_counter::sendCounts(void)
+{
+  // CkPrintf("[%d] sending counts\n", CkMyPe());
+  CProxy_queens_counter grp(thisgroup);
+  grp[0].childCount(new queens_countMsg(myCount));
+  myCount = 0;
+}
+
+void 
+queens_counter::childCount(queens_countMsg *m)
+{
+  totalCount += m->count;
+  delete m;
+  waitFor--;
+  // CkPrintf("[%d] received count. Remaining = %d\n", CkMyPe(), waitFor);
+  if (waitFor == 0) {
+    CthAwaken(threadId);
+    waitFor = CkNumPes();
+  }
+}
+
+int 
+queens_counter::getTotalCount(void)
+{
+  if(CkMyPe() != 0) {
+    CkAbort("queens: queens_main not created on processor 0 ?\n");
+    megatest_finish();
+  }
+  totalCount = 0;
+  CProxy_queens_counter grp(thisgroup);
+  grp.sendCounts();
+  threadId = CthSelf(); 
+  // CkPrintf("[%d] suspending\n", CkMyPe());
+  CthSuspend();
+  // CkPrintf("[%d] awakened\n", CkMyPe());
+  threadId = 0;
+  return totalCount;
+}
+
+MEGATEST_REGISTER_TEST(queens,"jackie",0)
+#include "queens.def.h"
diff --git a/tests/charm++/megatest/queens.ci b/tests/charm++/megatest/queens.ci
new file mode 100644 (file)
index 0000000..54442ea
--- /dev/null
@@ -0,0 +1,22 @@
+module queens {
+  message queens_PartialBoard;
+  message queens_DMSG;
+  message queens_countMsg;
+  
+  chare queens_main {
+    entry queens_main(queens_DMSG *);
+    entry [threaded] void Quiescence1(CkQdMsg *);
+  };
+  
+  chare queens_queens {
+    entry queens_queens(queens_PartialBoard *);
+  };
+
+  
+  group queens_counter {
+    entry queens_counter(void);
+    entry void sendCounts(void);
+    entry void childCount(queens_countMsg *);
+  };
+};
diff --git a/tests/charm++/megatest/queens.h b/tests/charm++/megatest/queens.h
new file mode 100644 (file)
index 0000000..4f9fc3a
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef _QUEENS_H
+#define _QUEENS_H
+
+#include "queens.decl.h"
+#include "megatest.h"
+
+#define NUMQUEENS  9
+#define Q_GRAIN 6
+#define EXPECTNUM  352
+
+
+extern readonly<CkGroupID> queens_counterGroup;
+
+class queens_PartialBoard : public CMessage_queens_PartialBoard { 
+ public:
+  int nextRow;
+  int Queens[NUMQUEENS];
+  CkGroupID counterGroup;
+};
+
+class queens_DMSG: public CMessage_queens_DMSG {
+ public:
+  CkGroupID counterGroup;
+};
+
+class queens_countMsg : public CMessage_queens_countMsg {
+ public:
+  int count;
+  queens_countMsg(int c) : count(c) {};
+};
+
+class queens_main : public Chare {
+ public:
+  CkGroupID counterGroup;
+  queens_main(queens_DMSG * dmsg);
+  queens_main(CkMigrateMessage *m) {}
+  void Quiescence1(CkQdMsg *);
+};
+
+class queens_queens : public Chare {
+ private:
+  void seqQueens(int queens[], int nextRow);
+  int consistent(int queens[], int lastRow, int col);
+  void solutionFound(void);
+
+ public:
+  CkGroupID counterGroup;
+  queens_queens(queens_PartialBoard *m);
+  queens_queens(CkMigrateMessage *m) {}
+};
+
+class queens_counter: public Group {
+ private:
+  int myCount;
+  int totalCount;
+  int waitFor;
+  CthThread threadId;
+ public:
+  queens_counter(void);
+  queens_counter(CkMigrateMessage *m) {}
+  void childCount(queens_countMsg *);
+  void increment(void);
+  void sendCounts(void);
+  int  getTotalCount(void);
+};
+
+#endif
diff --git a/tests/charm++/megatest/reduction.C b/tests/charm++/megatest/reduction.C
new file mode 100644 (file)
index 0000000..2e528bf
--- /dev/null
@@ -0,0 +1,65 @@
+#include "reduction.h"
+
+/*These aren't readonlies, because they're only used on PE 0*/
+static CProxy_reductionArray redArr;
+static CProxy_reductionGroup redGrp;
+static int nFinished;
+
+class reductionInfo {
+public:
+       int properValue;
+       reductionInfo(int v) :properValue(v) {}
+       void check(void *data,int size) {
+               int *v=(int *)data;
+               if (size!=2*sizeof(int))
+                       CkAbort("Unexpected-size reduction result!");
+               if (v[0]!=properValue)
+                       CkAbort("Corrupted first field!");
+               if (v[1]!=0 && v[1]!=(2*properValue))
+                       CkAbort("Corrupted second field!");
+       }
+};
+
+static void reductionClient(void *redInfo,int size,void *data) {
+       reductionInfo *info=(reductionInfo *)redInfo;
+       info->check(data,size);
+       nFinished++;
+       if (nFinished%4 == 0) megatest_finish();
+}
+
+void reduction_moduleinit(void) {
+       nFinished=0;
+       const int numElements = 5;
+       redArr=CProxy_reductionArray::ckNew(numElements);
+       redArr.setReductionClient(reductionClient,new reductionInfo(numElements));
+       redGrp=CProxy_reductionGroup::ckNew();
+       redGrp.setReductionClient(reductionClient,new reductionInfo(CkNumPes()));
+}
+
+void reduction_init(void)
+{
+       redArr.start();
+       redGrp.start();
+}
+
+void reductionArray::start(void) {
+       int i[2];
+       i[0]=1; //Sum=numElements
+       i[1]=0; //Sum=0
+       contribute(sizeof(i),&i,CkReduction::sum_int);
+       i[1]=2; //Sum=2*numElements
+       contribute(sizeof(i),&i,CkReduction::sum_int);
+       if (1) //Migrate to the next processor
+               ckMigrate((CkMyPe()+1)%CkNumPes());
+}
+void reductionGroup::start(void) {
+       int i[2];
+       i[0]=1;
+       i[1]=0;
+       contribute(sizeof(i),&i,CkReduction::sum_int);  
+       i[1]=2; 
+       contribute(sizeof(i),&i,CkReduction::sum_int);
+}
+
+MEGATEST_REGISTER_TEST(reduction,"olawlor",1)
+#include "reduction.def.h"
diff --git a/tests/charm++/megatest/reduction.ci b/tests/charm++/megatest/reduction.ci
new file mode 100644 (file)
index 0000000..53051f5
--- /dev/null
@@ -0,0 +1,10 @@
+module reduction {
+  array [1D] reductionArray {
+    entry reductionArray();
+    entry void start(void);
+  };
+  group reductionGroup {
+    entry reductionGroup();
+    entry void start(void);
+  };
+};
diff --git a/tests/charm++/megatest/reduction.h b/tests/charm++/megatest/reduction.h
new file mode 100644 (file)
index 0000000..6949063
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _REDUCTION_H
+#define _REDUCTION_H
+
+#include "reduction.decl.h"
+#include "megatest.h"
+
+class reductionArray : public CBase_reductionArray {
+ public:
+       reductionArray() {}
+       reductionArray(CkMigrateMessage *msg) {}
+       void start(void);
+};
+
+class reductionGroup : public CBase_reductionGroup {
+ public:
+       reductionGroup() {}
+       reductionGroup(CkMigrateMessage *msg) {}
+       void start(void);
+};
+
+#endif
diff --git a/tests/charm++/megatest/rotest.C b/tests/charm++/megatest/rotest.C
new file mode 100644 (file)
index 0000000..46f05e4
--- /dev/null
@@ -0,0 +1,59 @@
+#include "rotest.h"
+
+readonly<CkGroupID> rotest_groupid;
+roarray<int,10> rotest_iarray_num;
+roarray<int,ROTEST_SIZE> rotest_iarray_sz;
+romsg<rotest_msg> rmsg;
+
+void rotest_init(void)
+{
+  CProxy_rotest_group pgg(rotest_groupid);
+  pgg.start();
+}
+
+void rotest_moduleinit(void) 
+{
+  int i;
+  for(i=0;i<10;i++) {
+    rotest_iarray_num[i] = i*i+1023;
+  }
+  for(i=0;i<ROTEST_SIZE;i++) {
+    rotest_iarray_sz[i] = i*i+511;
+  }
+  rmsg = new rotest_msg(1024);
+  rotest_groupid = CProxy_rotest_group::ckNew();
+}
+
+static int rotest_check(void)
+{
+  int i;
+  for(i=0;i<10;i++) {
+    if(rotest_iarray_num[i] != i*i+1023)
+      return 1;
+  }
+  for(i=0;i<ROTEST_SIZE;i++) {
+    if(rotest_iarray_sz[i] != i*i+511)
+      return 1;
+  }
+  return rmsg->check();
+}
+
+void rotest_group::start(void)
+{
+  if(rotest_check())
+    CkAbort("rotest failed");
+  CProxy_rotest_group rog(rotest_groupid);
+  rog[0].done();
+}
+
+void rotest_group::done(void)
+{
+  numdone++;
+  if(numdone == CkNumPes()) {
+    numdone = 0;
+    megatest_finish();
+  }
+}
+
+MEGATEST_REGISTER_TEST(rotest,"milind",0)
+#include "rotest.def.h"
diff --git a/tests/charm++/megatest/rotest.ci b/tests/charm++/megatest/rotest.ci
new file mode 100644 (file)
index 0000000..02e78a2
--- /dev/null
@@ -0,0 +1,9 @@
+module rotest {
+  message rotest_msg;
+  group rotest_group {
+    entry rotest_group(void);
+    entry void start(void);
+    entry void done(void);
+  };
+};
+
diff --git a/tests/charm++/megatest/rotest.h b/tests/charm++/megatest/rotest.h
new file mode 100644 (file)
index 0000000..89030a6
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef ROTEST_H
+#define ROTEST_H
+
+#include "megatest.h"
+#include "rotest.decl.h"
+
+#define ROTEST_SIZE 100
+
+extern roarray<int,10> rotest_iarray_num;
+extern roarray<int,ROTEST_SIZE> rotest_iarray_sz;
+
+class rotest_msg : public CMessage_rotest_msg
+{
+    int datasz;
+    int *data;
+  public:
+    rotest_msg(void *m)
+    {
+      int *im = (int*) m;
+      datasz = im[0];
+      data = new int[datasz];
+      for(int i=0;i<datasz;i++)
+        data[i] = im[i+1];
+    }
+    rotest_msg(int sz)
+    {
+      data = new int[datasz=sz];
+      for(int i=0; i<datasz; i++)
+        data[i] = i*32-1;
+    }
+    ~rotest_msg()
+    {
+      delete[] data;
+    }
+    int check(void)
+    {
+      for(int i=0; i<datasz; i++)
+        if(data[i] != (i*32-1))
+          return 1;
+      return 0;
+    }
+    static void *pack(rotest_msg *m)
+    {
+      char *pbuf = (char*) CkAllocBuffer(m, (m->datasz+1)*sizeof(int));
+      *((int*)pbuf) = m->datasz;
+      memcpy((void*)(pbuf+sizeof(int)), m->data, m->datasz*sizeof(int));
+      return (void*) pbuf;
+    }
+    static rotest_msg *unpack(void *m)
+    {
+      rotest_msg *msg = (rotest_msg*) CkAllocBuffer(m, sizeof(rotest_msg));
+      msg = new ((void*) msg) rotest_msg(m);
+      CkFreeMsg(m);
+      return msg;
+    }
+};
+
+class rotest_group : public Group {
+  int numdone;
+  public:
+    rotest_group(void){ numdone = 0; }
+    void start(void);
+    void done(void);
+    rotest_group(CkMigrateMessage *m) {}
+};
+
+#endif 
diff --git a/tests/charm++/megatest/statistics.C b/tests/charm++/megatest/statistics.C
new file mode 100644 (file)
index 0000000..69c95de
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ Statistics and random number test program
+  Orion Sky Lawlor, olawlor@acm.org, 11/26/2002
+*/
+#include "statistics.h"
+#include "ckstatistics.h"
+
+void checkRange(double v,double lo,double hi,const char *desc) {
+       if (v<lo || v>hi) {
+               CkError("Error: expected %s %g to be between %g and %g!\n",
+                       desc,v,lo,hi);
+               CkAbort("Statistic out of range!");
+       }
+}
+
+void statistics_init(void) {
+       //Try out the Converse random number generator
+       CkSample s;
+       for (int i=0;i<10000;i++) s+=CrnDrand();
+       checkRange(s.getMean(),0.4,0.6,"mean"); //Theory: 0.5
+       checkRange(s.getStddev(),0.2,0.4,"stddev"); //Theory: 0.2887=sqrt(1/12)
+       checkRange(s.getMin(),0.0,0.1,"min"); //Theory: 0
+       checkRange(s.getMax(),0.9,1.0,"max"); //Theory: 1
+       
+       megatest_finish();
+}
+void statistics_moduleinit(void) {}
+
+// Need a fake "_register" routine because we don't have a .ci file...
+void _registerstatistics(void) {}
+MEGATEST_REGISTER_TEST(statistics,"olawlor",1)
diff --git a/tests/charm++/megatest/statistics.h b/tests/charm++/megatest/statistics.h
new file mode 100644 (file)
index 0000000..bf8918d
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _STATISTICS_H
+#define _STATISTICS_H
+
+#include "charm++.h"
+#include "megatest.h"
+
+#endif
diff --git a/tests/charm++/megatest/synctest.C b/tests/charm++/megatest/synctest.C
new file mode 100644 (file)
index 0000000..4045a18
--- /dev/null
@@ -0,0 +1,98 @@
+#include "synctest.h"
+
+void synctest_moduleinit(void) {}
+
+void synctest_init(void) 
+{
+  CProxy_synctest_main::ckNew();
+}
+
+synctest_main::synctest_main(void) 
+{
+  count = 0;
+  for (int i=0;i<NUMCHILDREN;i++) {
+    synctest_InitMsg *s_im = new synctest_InitMsg;
+    s_im->initValue = i+1;
+    s_im->myMain = thishandle;
+    CProxy_synctest_chare::ckNew(s_im);
+  }
+    synctest_InitMsg *s_im = new synctest_InitMsg;
+    s_im->initValue = 23;
+    s_im->myMain = thishandle;
+    arr=CProxy_synctest_arr::ckNew(s_im,NUMCHILDREN);
+}
+
+void synctest_main::reply(synctest_ReplyMsg *s_rm) 
+{
+  children[count] = s_rm->childID;
+  delete s_rm;
+  count++;
+  if (count == NUMCHILDREN) {
+    CProxy_synctest_main mainproxy(thishandle);
+    mainproxy.doTest();
+  } 
+}
+
+void synctest_main::doTest(void)
+{
+  int i,sum = 0;
+  synctest_SyncRecvMsg *childValue;
+
+  for (i=0;i<NUMCHILDREN;i++) {
+    CProxy_synctest_chare childproxy(children[i]);
+    childValue = childproxy.test(new synctest_SyncSendMsg);
+    sum = sum + childValue->value;
+    delete childValue;
+  }
+  if (sum != (NUMCHILDREN * (NUMCHILDREN + 1))/2) {
+    CkAbort("chare synctest failed!\n");
+  }
+  for (i=0;i<NUMCHILDREN;i++) {
+    childValue = arr[i].test(new synctest_SyncSendMsg);
+    if (childValue->value!=23) CkAbort("array synctest failed!\n");
+    delete childValue;
+  }
+  delete this;
+  megatest_finish();
+}
+
+synctest_chare::synctest_chare(synctest_InitMsg *s_im)
+{
+  value = s_im->initValue;
+  myMain = s_im->myMain;
+  delete s_im;
+  CProxy_synctest_main mainproxy(myMain);
+  synctest_ReplyMsg *myReply = new synctest_ReplyMsg;
+  myReply->childID = thishandle;
+  mainproxy.reply(myReply);
+}
+
+synctest_SyncRecvMsg *synctest_chare::test(synctest_SyncSendMsg *s_ssm)
+{
+  if (s_ssm->check() == 0)
+    CkAbort("Message to chare sync method corrupted!");
+  delete s_ssm;
+  synctest_SyncRecvMsg *returnMsg = new synctest_SyncRecvMsg;
+  returnMsg->value = value;
+  return returnMsg;
+}
+
+synctest_arr::synctest_arr(synctest_InitMsg *s_im)
+{
+  value = s_im->initValue;
+  myMain = s_im->myMain;
+  delete s_im;
+}
+
+synctest_SyncRecvMsg *synctest_arr::test(synctest_SyncSendMsg *s_ssm)
+{
+  if (s_ssm->check() == 0)
+    CkAbort("Message to array sync method corrupted!");
+  delete s_ssm;
+  synctest_SyncRecvMsg *returnMsg = new synctest_SyncRecvMsg;
+  returnMsg->value = value;
+  return returnMsg;
+}
+
+MEGATEST_REGISTER_TEST(synctest,"mjlang",1)  
+#include "synctest.def.h"
diff --git a/tests/charm++/megatest/synctest.ci b/tests/charm++/megatest/synctest.ci
new file mode 100644 (file)
index 0000000..1783024
--- /dev/null
@@ -0,0 +1,23 @@
+module synctest {
+  
+  message synctest_InitMsg;
+  message synctest_ReplyMsg;
+  message synctest_SyncSendMsg;
+  message synctest_SyncRecvMsg;
+  chare synctest_main {
+    entry synctest_main(void);
+    entry void reply(synctest_ReplyMsg *);
+    entry [threaded] void doTest(void) stacksize=65536;
+  };
+
+  chare synctest_chare {
+    entry synctest_chare(synctest_InitMsg *);
+    entry [sync] synctest_SyncRecvMsg *test(synctest_SyncSendMsg *);
+  };
+
+  array[1D] synctest_arr {
+    entry synctest_arr(synctest_InitMsg *);
+    entry [sync] synctest_SyncRecvMsg *test(synctest_SyncSendMsg *);
+  };
+};
diff --git a/tests/charm++/megatest/synctest.h b/tests/charm++/megatest/synctest.h
new file mode 100644 (file)
index 0000000..e870240
--- /dev/null
@@ -0,0 +1,71 @@
+#ifndef _SYNCTEST_H
+#define _SYNCTEST_H
+
+#include "megatest.h"
+#include "synctest.decl.h"
+
+#define NUMCHILDREN 100
+
+
+class synctest_InitMsg : public CMessage_synctest_InitMsg {
+public:
+  CkChareID myMain;
+  int initValue;
+};
+
+class synctest_ReplyMsg : public CMessage_synctest_ReplyMsg {
+public:
+  CkChareID childID;
+};
+
+class synctest_SyncSendMsg : public CMessage_synctest_SyncSendMsg {
+private:
+  char checkString[6];
+public:
+  synctest_SyncSendMsg(void) { sprintf(checkString, "Sync!");} 
+  int check(void) { 
+    if (strcmp("Sync!", checkString) == 0)
+      return 1;
+    else
+      return 0;
+  }
+};
+
+class synctest_SyncRecvMsg : public CMessage_synctest_SyncRecvMsg {
+public:
+  int value;
+};
+
+class synctest_main : public Chare {
+private:
+  int count;
+  CkChareID children[NUMCHILDREN];
+  CProxy_synctest_arr arr;
+public:
+  synctest_main(void);
+  synctest_main(CkMigrateMessage *m) {}
+  void reply(synctest_ReplyMsg *s_rm);
+  void doTest(void);
+};
+
+class synctest_chare : public Chare {
+private:
+  int value;
+  CkChareID myMain;
+public:
+  synctest_chare(synctest_InitMsg *s_im);
+  synctest_chare(CkMigrateMessage *m) {}
+  synctest_SyncRecvMsg *test(synctest_SyncSendMsg *s_ssm);
+};
+
+class synctest_arr : public ArrayElement1D {
+private:
+  int value;
+  CkChareID myMain;
+public:
+  synctest_arr(synctest_InitMsg *s_im);
+  synctest_arr(CkMigrateMessage *m) {}
+  synctest_SyncRecvMsg *test(synctest_SyncSendMsg *s_ssm);
+};
+
+#endif
diff --git a/tests/charm++/megatest/templates.C b/tests/charm++/megatest/templates.C
new file mode 100644 (file)
index 0000000..3ca51b1
--- /dev/null
@@ -0,0 +1,92 @@
+#include "templates.h"
+#include "templates.def.h"
+
+readonly<CkGroupID> templates_redid;
+CProxy_templates_Array<int> templatesArray;
+
+int BINSIZE;
+
+void templates_init(void) 
+{
+  int i;
+  for(i=0;i<CkNumPes();i++) {
+    CProxy_templates_Collector<int>::ckNew(i);
+  }
+  templatesArray[1].remoteRecv(new templates_Single<int>(7));
+  int arr[3]; arr[0]=123; arr[1]=234; arr[2]=345;
+  templatesArray[0].marshalled(3,arr);
+}
+
+void templates_moduleinit(void)
+{
+  templates_redid = CProxy_templates_Reduction<int>::ckNew();
+  templatesArray = CProxy_templates_Array<int>::ckNew(2);
+}
+
+template <class dtype> void 
+templates_Reduction<dtype>::submit(templates_Single<dtype> *msg)
+{
+  CProxy_templates_Reduction<dtype> red(thisgroup);
+  red[0].remoteRecv(msg);
+}
+
+template <class dtype> void
+templates_Reduction<dtype>::Register(templates_ClientMsg *msg)
+{
+  cid = msg->cid;
+  delete msg;
+}
+
+template <class dtype> void
+templates_Reduction<dtype>::remoteRecv(templates_Single<dtype> *msg)
+{
+  data += msg->data;
+  nreported++;
+  if(nreported == CkNumPes()) {
+    msg->data = data;
+    CProxy_templates_Collector<dtype> col(cid);
+    col.collect(msg);
+    nreported = 0; data = 0;
+  } else {
+    delete msg;
+  }
+}
+
+template <class dtype> 
+templates_Collector<dtype>::templates_Collector(void)
+{
+  CProxy_templates_Reduction<dtype> red(templates_redid);
+  if(CkMyPe()==0) {
+    templates_ClientMsg *cmsg = new templates_ClientMsg(thishandle);
+    red[0].Register(cmsg);
+  }
+  templates_Single<dtype> *m = new templates_Single<dtype>((dtype)(CkMyPe()+1));
+  red[CkMyPe()].submit(m);
+}
+
+template <class dtype> void
+templates_Collector<dtype>::collect(templates_Single<dtype> *msg)
+{
+  dtype data = msg->data;
+  delete msg;
+  if(data != (dtype) ((CkNumPes()*(CkNumPes()+1))/2)) {
+    CkAbort("templates: test failed!\n");
+  }
+  megatest_finish();
+}
+
+
+template <class dtype> void
+templates_Array<dtype>::remoteRecv(templates_Single<dtype> *msg) 
+{
+       data+= msg->data;
+       delete msg;
+}
+
+template <class dtype> void 
+templates_Array<dtype>::marshalled(int len,dtype *arr)
+{
+       for (int i=0;i<len;i++) data+=arr[i];
+}
+
+MEGATEST_REGISTER_TEST(templates,"milind",0)
diff --git a/tests/charm++/megatest/templates.ci b/tests/charm++/megatest/templates.ci
new file mode 100644 (file)
index 0000000..a4be537
--- /dev/null
@@ -0,0 +1,29 @@
+module templates {
+  readonly int BINSIZE;
+
+  message templates_ClientMsg;
+  template<class dtype> message templates_Single;
+  message templates_Single<int>;
+
+  template<class dtype> array[1D] templates_Array {
+    entry templates_Array(void);
+    entry void remoteRecv(templates_Single<dtype> *);
+    entry void marshalled(int len,dtype arr[len]);
+  };
+  
+  template<class dtype> group templates_Reduction {
+    entry templates_Reduction(void);
+    entry void submit(templates_Single<dtype> *);
+    entry void Register(templates_ClientMsg *);
+    entry void remoteRecv(templates_Single<dtype> *);
+  };
+
+  template<class dtype> chare templates_Collector {
+    entry void templates_Collector(void);
+    entry void collect(templates_Single<dtype> *);
+  };
+
+  group templates_Reduction<int>;
+  chare templates_Collector<int>;
+  array [1D] templates_Array<int>;
+};
diff --git a/tests/charm++/megatest/templates.h b/tests/charm++/megatest/templates.h
new file mode 100644 (file)
index 0000000..1434293
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef _TEMPLATES_H
+#define _TEMPLATES_H
+
+#include "templates.decl.h"
+#include "megatest.h"
+
+extern readonly<CkGroupID> templates_redid;
+
+extern int BINSIZE;
+
+template <class dtype>
+class templates_Single : public CMessage_templates_Single<dtype> {
+  public:
+    dtype data;
+    templates_Single() { data = 0; }
+    templates_Single(dtype _data) { data = _data; }
+};
+
+class templates_ClientMsg: public CMessage_templates_ClientMsg {
+  public:
+    CkChareID cid;
+    templates_ClientMsg(CkChareID _cid) : cid(_cid) {}
+};
+
+template <class dtype>
+class templates_Array : public ArrayElement1D {
+  private:
+    dtype data;
+  public:
+    templates_Array(void) { data = 0; }
+    templates_Array(CkMigrateMessage *m) {}
+    void remoteRecv(templates_Single<dtype> *);
+    void marshalled(int len,dtype *arr);
+};
+
+template <class dtype>
+class templates_Reduction : public Group {
+  private:
+    dtype data;
+    int nreported;
+    CkChareID cid;
+  public:
+    templates_Reduction(void) { nreported = 0; data = 0; }
+    templates_Reduction(CkMigrateMessage *m) {}
+    void submit(templates_Single<dtype> *msg);
+    void Register(templates_ClientMsg *msg);
+    void remoteRecv(templates_Single<dtype> *msg);
+};
+
+template <class dtype>
+class templates_Collector : public Chare {
+  public:
+    templates_Collector(void);
+    templates_Collector(CkMigrateMessage *m) {}
+    void collect(templates_Single<dtype> *msg);
+};
+
+#define CK_TEMPLATES_ONLY
+#include "templates.def.h"
+#undef CK_TEMPLATES_ONLY
+
+#endif
diff --git a/tests/charm++/megatest/tempotest.C b/tests/charm++/megatest/tempotest.C
new file mode 100644 (file)
index 0000000..cb42cd4
--- /dev/null
@@ -0,0 +1,104 @@
+#include "tempotest.h"
+
+void tempotest_init(void)
+{
+  CProxy_tempotest_main::ckNew(0);
+}
+
+void tempotest_moduleinit(void) {}
+
+tempotest_UserClass::tempotest_UserClass(IdMsg *msg)
+{
+  mainid = msg->id;
+  delete msg;
+  CProxy_tempotest_UserClass uc(thishandle);
+  uc.doSendRecv();
+}
+
+void
+tempotest_UserClass::doSendRecv(void)
+{
+  CkChareID otherid;
+  char inbuf[11], outbuf[11];
+  
+  IdMsg *idmsg = new IdMsg(thishandle);
+  CProxy_tempotest_main mainproxy(mainid);
+  mainproxy.getid(idmsg);
+
+  ckTempoRecv(1, &otherid, sizeof(CkChareID));
+  
+  for (int i=0; i<10; i++) {
+    sprintf(outbuf, "UserClass!");
+    sprintf(inbuf, "");
+    ckTempoSend(i+2, outbuf, strlen(outbuf)+1, otherid);
+    ckTempoRecv(i+2, inbuf, 11);
+    if(strcmp(inbuf, "UserClass!")) {
+      CkAbort("tempotest: Message corrupted!\n");
+      mainproxy.Finish();
+      return;
+    }
+  }
+  mainproxy.Finish();
+  delete this;
+}
+
+tempotest_UserGroup::tempotest_UserGroup(IdMsg *msg)
+{
+  mainid = msg->id;
+  CProxy_tempotest_UserGroup ug(thisgroup);
+  ug[CkMyPe()].doSendRecv();
+  delete msg;
+}
+
+void
+tempotest_UserGroup::doSendRecv(void)
+{
+  char *outbuf = new char[1024000];
+  if(CkMyPe()==0)
+    sprintf(outbuf, "UserGroup!");
+  ckTempoBcast(CkMyPe()==0, 1001, outbuf, 11);
+  if(strcmp(outbuf, "UserGroup!"))
+    CkAbort("tempotest: Message corrupted!\n");
+  CProxy_tempotest_main mainproxy(mainid);
+  mainproxy.Finish();
+  delete [] outbuf;
+  delete this;
+}
+
+void 
+tempotest_main::sendids(void)
+{
+  TempoChare::ckTempoSend(1, &(id2->id), sizeof(CkChareID), id1->id); 
+  TempoChare::ckTempoSend(1, &(id1->id), sizeof(CkChareID), id2->id); 
+  delete id1;
+  delete id2;
+}
+
+tempotest_main::tempotest_main(void)
+{
+  id1 = id2 = 0;
+  recvd = 0;
+  CProxy_tempotest_UserGroup::ckNew(new IdMsg(thishandle));
+  CProxy_tempotest_UserClass::ckNew(new IdMsg(thishandle));
+  CProxy_tempotest_UserClass::ckNew(new IdMsg(thishandle));
+}
+
+void tempotest_main::Finish(void)
+{
+  recvd++;
+  if(recvd==(CkNumPes()+2))
+    megatest_finish();
+}
+
+void tempotest_main::getid(IdMsg *idmsg)
+{
+  if (id1 == 0)
+    id1 = idmsg;
+  else {
+    id2 = idmsg;
+    sendids();
+  }
+}
+
+MEGATEST_REGISTER_TEST(tempotest,"fang",1)
+#include "tempotest.def.h"
diff --git a/tests/charm++/megatest/tempotest.ci b/tests/charm++/megatest/tempotest.ci
new file mode 100644 (file)
index 0000000..8447619
--- /dev/null
@@ -0,0 +1,20 @@
+module tempotest {
+
+  message IdMsg;
+
+  chare tempotest_main {
+    entry tempotest_main(void);
+    entry void getid(IdMsg *);
+    entry void Finish(void);
+  };
+  
+  chare tempotest_UserClass : TempoChare {
+    entry tempotest_UserClass(IdMsg *);
+    entry [threaded] void doSendRecv(void);
+  };
+  
+  group tempotest_UserGroup : TempoGroup {
+    entry tempotest_UserGroup(IdMsg *);
+    entry [threaded] void doSendRecv(void);
+  };
+};
diff --git a/tests/charm++/megatest/tempotest.h b/tests/charm++/megatest/tempotest.h
new file mode 100644 (file)
index 0000000..7c981b9
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef _TEMPOTEST_H
+#define _TEMPOTEST_H
+
+#include "megatest.h"
+#include "tempotest.decl.h"
+#include "tempo.h"
+
+class IdMsg : public CMessage_IdMsg
+{
+  public :
+    CkChareID id;
+    IdMsg(CkChareID _id) : id(_id) {}
+};
+
+class tempotest_UserClass : public TempoChare
+{
+  CkChareID mainid;
+  public :
+    tempotest_UserClass(IdMsg *);
+    tempotest_UserClass(CkMigrateMessage *m) {}
+    void doSendRecv(void);
+};
+
+class tempotest_UserGroup : public TempoGroup
+{
+  CkChareID mainid;
+  public :
+    tempotest_UserGroup(IdMsg *);
+    tempotest_UserGroup(CkMigrateMessage *m) {}
+    void doSendRecv(void);
+};
+class tempotest_main : public Chare
+{
+  IdMsg *id1, *id2;
+  void sendids(void);
+  int recvd;
+
+  public :
+    tempotest_main(void);
+    tempotest_main(CkMigrateMessage *m) {}
+    void Finish(void);
+    void getid(IdMsg *);
+};
+
+#endif
diff --git a/tests/charm++/megatest/varraystest.C b/tests/charm++/megatest/varraystest.C
new file mode 100644 (file)
index 0000000..933c8e9
--- /dev/null
@@ -0,0 +1,75 @@
+#include "varraystest.h"
+
+static int nextseq = 0;
+
+void varraystest_init(void) 
+{
+  if(CkNumPes()<2) {
+    CkError("varraystest: requires at least 2 processors\n");
+    megatest_finish();
+  } else
+    CProxy_varraystest_main::ckNew(0);
+}
+
+void varraystest_moduleinit(void) {}
+
+varraystest_main::varraystest_main(void)
+{
+  varraystest_Msg *m = new (100, 300, 0) varraystest_Msg(100, 300, nextseq++);
+  m->myMain = thishandle;
+  CProxy_varraystest_test::ckNew(m, 1);
+}
+
+void varraystest_main::exit(varraystest_Msg *m)
+{
+  if(!m->check())
+    CkAbort("varraystest failed!\n");
+  delete m;
+  delete this;
+  megatest_finish();
+}
+
+varraystest_Msg::varraystest_Msg(int is, int fs, int s)
+{
+  isize = is;
+  fsize = fs;
+  seqnum = s;
+  int i;
+  for(i=0; i<isize; i++)
+    iarray[i] = i*i*seqnum;
+  for(i=0; i<fsize;i++)
+    farray[i] = 2.0*i*i*seqnum;
+}
+
+int varraystest_Msg::check(void)
+{
+  int i;
+  for(i=0; i<isize; i++)
+    if(iarray[i] != i*i*seqnum) {
+      return 0;
+    }
+  for(i=0; i<fsize; i++)
+    if(farray[i] != 2.0*i*i*seqnum) {
+      return 0;
+    }
+  return 1;
+}
+
+varraystest_test::varraystest_test(varraystest_Msg *m)
+{
+  CkChareID mhandle = m->myMain;
+  int currentSeqnum = m->seqnum;
+  if(!m->check()) {
+    CkAbort("varraystest failed!\n");
+    megatest_finish();
+    return;
+  }
+  delete m;
+  m = new (300, 100, 0) varraystest_Msg(300, 100, currentSeqnum);
+  CProxy_varraystest_main mainproxy(mhandle);
+  mainproxy.exit(m); 
+  delete this;
+}
+
+MEGATEST_REGISTER_TEST(varraystest,"milind",1)
+#include "varraystest.def.h"
diff --git a/tests/charm++/megatest/varraystest.ci b/tests/charm++/megatest/varraystest.ci
new file mode 100644 (file)
index 0000000..0cdc475
--- /dev/null
@@ -0,0 +1,15 @@
+module varraystest {
+  message varraystest_Msg {
+    int iarray[];
+    float farray[];
+  };
+
+  chare varraystest_main {
+    entry varraystest_main(void);
+    entry void exit(varraystest_Msg *);
+  };
+
+  chare varraystest_test {
+    entry varraystest_test(varraystest_Msg *);
+  };
+};
diff --git a/tests/charm++/megatest/varraystest.h b/tests/charm++/megatest/varraystest.h
new file mode 100644 (file)
index 0000000..600f412
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef _VARSIZETEST_H
+#define _VARSIZETEST_H
+
+#include "megatest.h"
+#include "varraystest.decl.h"
+
+
+class varraystest_Msg : public CMessage_varraystest_Msg {
+ public:
+  varraystest_Msg(int, int, int s);
+  int check(void);
+  int isize;
+  int fsize;
+  int *iarray;
+  float *farray;
+  int seqnum;
+  CkChareID myMain;
+}; 
+
+class varraystest_main : public Chare {
+ public:
+  varraystest_main(void);
+  varraystest_main(CkMigrateMessage *m) {}
+  void exit(varraystest_Msg *m);
+};
+
+class varraystest_test : public Chare {
+ public:
+  varraystest_test(varraystest_Msg *m);
+  varraystest_test(CkMigrateMessage *m) {}
+};
+
+#endif
diff --git a/tests/charm++/megatest/varsizetest.C b/tests/charm++/megatest/varsizetest.C
new file mode 100644 (file)
index 0000000..943299f
--- /dev/null
@@ -0,0 +1,106 @@
+#include "varsizetest.h"
+
+static int nextseq = 0;
+
+void varsizetest_init(void) 
+{
+  if(CkNumPes()<2) {
+    CkError("varsize: requires at least 2 processors\n");
+    megatest_finish();
+  } else
+    CProxy_varsizetest_main::ckNew(0);
+}
+
+void varsizetest_moduleinit(void) {}
+
+void *varsizetest_Msg::alloc(int mnum, size_t size, int *sizes, int pbits)
+{
+  // CkPrintf("Msg::alloc called with size=%d, sizes[0]=%d, sizes[1]=%d\n",
+  //         size, sizes[0], sizes[1]);
+  int stmp = sizes[0]*sizeof(int)+sizes[1]*sizeof(float);
+  varsizetest_Msg *m = (varsizetest_Msg *) CkAllocMsg(mnum, size+stmp, pbits);
+  m->isize = sizes[0];
+  m->fsize = sizes[1];
+  m->iarray = (int *)((char *)m+size);
+  m->farray = (float *)((char *)m+size+sizes[0]*sizeof(int));
+  return (void *) m;
+}
+
+void *varsizetest_Msg::pack(varsizetest_Msg *m)
+{
+  // CkPrintf("M::pack called\n");
+  return (void *) m;
+}
+
+varsizetest_Msg *varsizetest_Msg::unpack(void *buf)
+{
+  //CkPrintf("M::unpack called\n");
+  varsizetest_Msg *m = (varsizetest_Msg *) buf;
+  m->iarray = (int *)((char *)m+sizeof(varsizetest_Msg));
+  m->farray = (float *)((char *)m+sizeof(varsizetest_Msg)+(m->isize*sizeof(int)));
+  return m;
+}
+
+varsizetest_main::varsizetest_main(void)
+{
+  int sizes[2];
+  sizes[0] = 100; sizes[1] = 300;
+  varsizetest_Msg *m = new (sizes,0) varsizetest_Msg(nextseq++);
+  m->myMain = thishandle;
+  CProxy_varsizetest_test::ckNew(m, 1);
+}
+
+void varsizetest_main::exit(varsizetest_Msg *m)
+{
+  if(!m->check())
+    CkAbort("varsizetest failed!\n");
+  delete m;
+  delete this;
+  megatest_finish();
+}
+
+varsizetest_Msg::varsizetest_Msg(int s)
+{
+  seqnum = s;
+  int i;
+  for(i=0; i<isize; i++)
+    iarray[i] = i*i*seqnum;
+  for(i=0; i<fsize;i++)
+    farray[i] = 2.0*i*i*seqnum;
+}
+
+int varsizetest_Msg::check(void)
+{
+  int i;
+  for(i=0; i<isize; i++)
+    if(iarray[i] != i*i*seqnum) {
+      return 0;
+    }
+  for(i=0; i<fsize; i++)
+    if(farray[i] != 2.0*i*i*seqnum) {
+      return 0;
+    }
+  return 1;
+}
+
+varsizetest_test::varsizetest_test(varsizetest_Msg *m)
+{
+  CkChareID mhandle = m->myMain;
+  int currentSeqnum = m->seqnum;
+  if(!m->check()) {
+    CkAbort("varsizetest failed!\n");
+    megatest_finish();
+    return;
+  }
+  delete m;
+  int sizes[2];
+  sizes[0] = 300;
+  sizes[1] = 100;
+  m = new (sizes,0) varsizetest_Msg(currentSeqnum);
+  CProxy_varsizetest_main mainproxy(mhandle);
+  mainproxy.exit(m); 
+  delete this;
+}
+
+MEGATEST_REGISTER_TEST(varsizetest,"mjlang",1)
+#include "varsizetest.def.h"
diff --git a/tests/charm++/megatest/varsizetest.ci b/tests/charm++/megatest/varsizetest.ci
new file mode 100644 (file)
index 0000000..85bc0a4
--- /dev/null
@@ -0,0 +1,12 @@
+module varsizetest {
+  message varsizetest_Msg;
+
+  chare varsizetest_main {
+    entry varsizetest_main(void);
+    entry void exit(varsizetest_Msg *);
+  };
+
+  chare varsizetest_test {
+    entry varsizetest_test(varsizetest_Msg *);
+  };
+};
diff --git a/tests/charm++/megatest/varsizetest.h b/tests/charm++/megatest/varsizetest.h
new file mode 100644 (file)
index 0000000..4dd0891
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef _VARSIZETEST_H
+#define _VARSIZETEST_H
+
+#include "megatest.h"
+#include "varsizetest.decl.h"
+
+
+class varsizetest_Msg : public CMessage_varsizetest_Msg {
+ public:
+  static void *alloc(int mnum, size_t size, int *sizes, int priobits);
+  static void *pack(varsizetest_Msg *msg);
+  static varsizetest_Msg *unpack(void *buf);
+  varsizetest_Msg(int s);
+  int check(void);
+  int isize;
+  int fsize;
+  int *iarray;
+  float *farray;
+  int seqnum;
+  CkChareID myMain;
+}; 
+
+class varsizetest_main : public Chare {
+ public:
+  varsizetest_main(void);
+  varsizetest_main(CkMigrateMessage *m) {}
+  void exit(varsizetest_Msg *m);
+};
+
+class varsizetest_test : public Chare {
+ public:
+  varsizetest_test(varsizetest_Msg *m);
+  varsizetest_test(CkMigrateMessage *m) {}
+};
+
+#endif
diff --git a/tests/charm++/pingpong/Makefile b/tests/charm++/pingpong/Makefile
new file mode 100644 (file)
index 0000000..30fd730
--- /dev/null
@@ -0,0 +1,23 @@
+CHARMC=../../../bin/charmc $(OPTS)
+
+OBJS = pingpong.o
+
+all:   cifiles pgm
+
+pgm: $(OBJS)
+       $(CHARMC) -language charm++ -o pgm $(OBJS)
+
+cifiles: pingpong.ci
+       $(CHARMC)  pingpong.ci
+
+clean:
+       rm -f *.decl.h *.def.h conv-host *.o pgm charmrun
+
+pingpong.o: pingpong.C
+       $(CHARMC) -c pingpong.C
+
+test: all
+       @echo "Intra-processor Pingpong.."
+       ./charmrun ./pgm +p1
+       @echo "Inter-processor Pingpong.."
+       ./charmrun ./pgm +p2
diff --git a/tests/charm++/pingpong/pingpong.C b/tests/charm++/pingpong/pingpong.C
new file mode 100644 (file)
index 0000000..292849c
--- /dev/null
@@ -0,0 +1,381 @@
+#include <string.h> // for strlen, and strcmp
+#include <charm++.h>
+
+#define NITER 10000
+
+class Fancy
+{
+  char _str[12];
+  public:
+    Fancy() { _str[0] = '\0'; }
+    Fancy(char *str) {
+      strncpy(_str, str, 12);
+    }
+    int equals(char *str) { return !strcmp(str, _str); }
+};
+
+class CkArrayIndexFancy : public CkArrayIndex {
+  Fancy f;
+  public:
+    CkArrayIndexFancy(char *str) : f(str) {nInts=3;}
+};
+
+#include "pingpong.decl.h"
+
+class PingMsg : public CMessage_PingMsg
+{
+  public:
+    char x[100];
+};
+
+class IdMsg : public CMessage_IdMsg
+{
+  public:
+    CkChareID cid;
+    IdMsg(CkChareID _cid) : cid(_cid) {}
+};
+
+CProxy_main mainProxy;
+
+#define P1 0
+#define P2 1%CkNumPes()
+
+class main : public Chare
+{
+  int phase;
+  CProxy_Ping1 arr1;
+  CProxy_Ping2 arr2;
+  CProxy_Ping3 arr3;
+  CProxy_PingF arrF;
+  CProxy_PingC cid;
+  CProxy_PingG gid;
+public:
+  main(CkMigrateMessage *m) {}
+  main(CkArgMsg* m)
+  {
+    delete m;
+    if(CkNumPes()>2) {
+      CkAbort("Run this program on 1 or 2 processors only.\n");
+    }
+    mainProxy = thishandle;
+    phase = 0;
+    gid = CProxy_PingG::ckNew();
+    cid=CProxy_PingC::ckNew(1%CkNumPes());
+    cid=CProxy_PingC::ckNew(new IdMsg(cid.ckGetChareID()),0);
+    arr1 = CProxy_Ping1::ckNew(2);
+    arr2 = CProxy_Ping2::ckNew();
+    arr3 = CProxy_Ping3::ckNew();
+    arrF = CProxy_PingF::ckNew();
+    arr2(0,0).insert(P1);
+    arr2(0,1).insert(P2);
+    arr2.doneInserting();
+    arr3(0,0,0).insert(P1);
+    arr3(0,0,1).insert(P2);
+    arr3.doneInserting();
+    arrF[CkArrayIndexFancy("first")].insert(P1);
+    arrF[CkArrayIndexFancy("second")].insert(P2);
+    arrF.doneInserting();
+    phase=0;
+    mainProxy.maindone();
+  };
+
+  void maindone(void)
+  {
+    switch(phase++) {
+      case 0:
+       arr1[0].start();
+       break;
+      case 1:
+        arr2(0,0).start();
+        break;
+      case 2:
+        arr3(0,0,0).start();
+        break;
+      case 3:
+        arrF[CkArrayIndexFancy("first")].start();
+        break;
+      case 4:
+        cid.start();
+        break;
+      case 5:
+        gid[0].start();
+        break;
+      default:
+        CkExit();
+    }
+  };
+};
+
+class PingG : public Group
+{
+  CProxyElement_PingG *pp;
+  int niter;
+  int me, nbr;
+  double start_time, end_time;
+public:
+  PingG()
+  {
+    me = CkMyPe();    
+    nbr = (me+1)%CkNumPes();
+    pp = new CProxyElement_PingG(thisgroup,nbr);
+    niter = 0;
+  }
+  PingG(CkMigrateMessage *m) {}
+  void start(void)
+  {
+    (*pp).recv();
+    start_time = CkWallTimer();
+  }
+  void recv(void)
+  {
+    if(me==0) {
+      niter++;
+      if(niter==NITER) {
+        end_time = CkWallTimer();
+        int titer = (CkNumPes()==1)?(NITER/2) : NITER;
+        CkPrintf("Roundtrip time for Groups is %lf us\n",
+                 1.0e6*(end_time-start_time)/titer);
+        mainProxy.maindone();
+      } else {
+        (*pp).recv();
+      }
+    } else {
+      (*pp).recv();
+    }
+  }
+};
+
+class Ping1 : public ArrayElement1D
+{
+  CProxy_Ping1 *pp;
+  int niter;
+  double start_time, end_time;
+public:
+  Ping1()
+  {
+    pp = new CProxy_Ping1(thisArrayID);
+    niter = 0;
+  }
+  Ping1(CkMigrateMessage *m) {}
+  void start(void)
+  {
+    (*pp)[1].recv(new PingMsg);
+    start_time = CkWallTimer();
+  }
+  void recv(PingMsg *msg)
+  {
+    if(thisIndex==0) {
+      niter++;
+      if(niter==NITER) {
+        end_time = CkWallTimer();
+        CkPrintf("Roundtrip time for 1D Arrays is %lf us\n",
+                 1.0e6*(end_time-start_time)/NITER);
+        mainProxy.maindone();
+      } else {
+        (*pp)[1].recv(msg);
+      }
+    } else {
+      (*pp)[0].recv(msg);
+    }
+  }
+};
+
+class Ping2 : public ArrayElement2D
+{
+  CProxy_Ping2 *pp;
+  int niter;
+  double start_time, end_time;
+public:
+  Ping2()
+  {
+    pp = new CProxy_Ping2(thisArrayID);
+    niter = 0;
+  }
+  Ping2(CkMigrateMessage *m) {}
+  void start(void)
+  {
+    (*pp)(0,1).recv(new PingMsg);
+    start_time = CkWallTimer();
+  }
+  void recv(PingMsg *msg)
+  {
+    if(thisIndex.y==0) {
+      niter++;
+      if(niter==NITER) {
+        end_time = CkWallTimer();
+        CkPrintf("Roundtrip time for 2D Arrays is %lf us\n",
+                 1.0e6*(end_time-start_time)/NITER);
+        mainProxy.maindone();
+      } else {
+        (*pp)(0,1).recv(msg);
+      }
+    } else {
+      (*pp)(0,0).recv(msg);
+    }
+  }
+};
+
+class Ping3 : public ArrayElement3D
+{
+  CProxy_Ping3 *pp;
+  int niter;
+  double start_time, end_time;
+public:
+  Ping3()
+  {
+    pp = new CProxy_Ping3(thisArrayID);
+    niter = 0;
+  }
+  Ping3(CkMigrateMessage *m) {}
+  void start(void)
+  {
+    (*pp)(0,0,1).recv(new PingMsg);
+    start_time = CkWallTimer();
+  }
+  void recv(PingMsg *msg)
+  {
+    if(thisIndex.z==0) {
+      niter++;
+      if(niter==NITER) {
+        end_time = CkWallTimer();
+        CkPrintf("Roundtrip time for 3D Arrays is %lf us\n",
+                 1.0e6*(end_time-start_time)/NITER);
+        mainProxy.maindone();
+      } else {
+        (*pp)(0,0,1).recv(msg);
+      }
+    } else {
+      (*pp)(0,0,0).recv(msg);
+    }
+  }
+};
+
+class PingF : public CBase_PingF
+{
+  CProxy_PingF *pp;
+  int niter;
+  double start_time, end_time;
+  int first;
+public:
+  PingF()
+  {
+    pp = new CProxy_PingF(thisArrayID);
+    niter = 0;
+    first = thisIndex.equals("first") ? 1 : 0;
+  }
+  PingF(CkMigrateMessage *m) {}
+  void start(void)
+  {
+    (*pp)[CkArrayIndexFancy("second")].recv();
+    start_time = CkWallTimer();
+  }
+  void recv(void)
+  {
+    CkArrayIndexFancy partner((char *)(first?"second" : "first"));
+    if(first) {
+      niter++;
+      if(niter==NITER) {
+        end_time = CkWallTimer();
+        CkPrintf("Roundtrip time for Fancy Arrays is %lf us\n",
+                 1.0e6*(end_time-start_time)/NITER);
+        mainProxy.maindone();
+      } else {
+        (*pp)[partner].recv();
+      }
+    } else {
+      (*pp)[partner].recv();
+    }
+  }
+};
+
+class PingC : public Chare
+{
+  CProxy_PingC *pp;
+  int niter;
+  double start_time, end_time;
+  int first;
+ public:
+  PingC(void)
+  {
+    first = 0;
+  }
+  PingC(IdMsg *msg)
+  {
+    first = 1;
+    CProxy_PingC pc(msg->cid);
+    msg->cid = thishandle;
+    pc.exchange(msg);
+  }
+  PingC(CkMigrateMessage *m) {}
+  void start(void)
+  {
+    niter = 0;
+    pp->recv();
+    start_time = CkWallTimer();
+  }
+  void exchange(IdMsg *msg)
+  {
+    if(first) {
+      pp = new CProxy_PingC(msg->cid);
+      delete msg;
+    } else {
+      pp = new CProxy_PingC(msg->cid);
+      msg->cid = thishandle;
+      pp->exchange(msg);
+    }
+  }
+  void recv(void)
+  {
+    if(first) {
+      niter++;
+      if(niter==NITER) {
+        end_time = CkWallTimer();
+        CkPrintf("Roundtrip time for Chares (reuse msgs) is %lf us\n",
+                 1.0e6*(end_time-start_time)/NITER);
+        niter = 0;
+        pp->recv(new PingMsg);
+        start_time = CkWallTimer();
+      } else {
+        pp->recv();
+      }
+    } else {
+      pp->recv();
+    }
+  }
+  void recv(PingMsg *msg)
+  {
+    delete msg;
+    if(first) {
+      niter++;
+      if(niter==NITER) {
+        end_time = CkWallTimer();
+        CkPrintf("Roundtrip time for Chares (new/del msgs) is %lf us\n",
+                 1.0e6*(end_time-start_time)/NITER);
+        niter = 0;
+        pp->trecv();
+        start_time = CkWallTimer();
+      } else {
+        pp->recv(new PingMsg);
+      }
+    } else {
+      pp->recv(new PingMsg);
+    }
+  }
+  void trecv(void)
+  {
+    if(first) {
+      niter++;
+      if(niter==NITER) {
+        end_time = CkWallTimer();
+        CkPrintf("Roundtrip time for threaded Chares is %lf us\n",
+                 1.0e6*(end_time-start_time)/NITER);
+        mainProxy.maindone();
+      } else {
+        pp->trecv();
+      }
+    } else {
+      pp->trecv();
+    }
+  }
+};
+#include "pingpong.def.h"
diff --git a/tests/charm++/pingpong/pingpong.ci b/tests/charm++/pingpong/pingpong.ci
new file mode 100644 (file)
index 0000000..dd6374d
--- /dev/null
@@ -0,0 +1,43 @@
+mainmodule pingpong {
+  readonly CProxy_main mainProxy;
+  mainchare main {
+    entry main();
+    entry void maindone(void);
+  };
+  message PingMsg;
+  message IdMsg;
+  array [1D] Ping1 {
+    entry Ping1();
+    entry void start(void);
+    entry void recv(PingMsg *);
+  };           
+  array [2D] Ping2 {
+    entry Ping2();
+    entry void start(void);
+    entry void recv(PingMsg *);
+  };           
+  array [3D] Ping3 {
+    entry Ping3();
+    entry void start(void);
+    entry void recv(PingMsg *);
+  };           
+  chare PingC {
+    entry PingC(void);
+    entry PingC(IdMsg *);
+    entry void start(void);
+    entry void exchange(IdMsg *);
+    entry void recv(void);
+    entry void recv(PingMsg *);
+    entry [threaded] void trecv(void);
+  };
+  group PingG {
+    entry PingG(void);
+    entry void start(void);
+    entry void recv(void);
+  }
+  array [Fancy] PingF {
+    entry PingF();
+    entry void start(void);
+    entry void recv(void);
+  };           
+};
diff --git a/tests/charm++/simplearrayhello/Makefile b/tests/charm++/simplearrayhello/Makefile
new file mode 100644 (file)
index 0000000..86fae73
--- /dev/null
@@ -0,0 +1,20 @@
+CHARMC=../../../bin/charmc $(OPTS)
+
+OBJS = hello.o
+
+all: hello
+
+hello: $(OBJS)
+       $(CHARMC) -language charm++ -o hello $(OBJS)
+
+hello.decl.h: hello.ci
+       $(CHARMC)  hello.ci
+
+clean:
+       rm -f *.decl.h *.def.h conv-host *.o hello charmrun *.log *.sum *.sts
+
+hello.o: hello.C hello.decl.h
+       $(CHARMC) -c hello.C
+
+test: all
+       ./charmrun ./hello +p4 10
diff --git a/tests/charm++/simplearrayhello/hello.C b/tests/charm++/simplearrayhello/hello.C
new file mode 100644 (file)
index 0000000..f11727a
--- /dev/null
@@ -0,0 +1,58 @@
+#include <stdio.h>
+#include "hello.decl.h"
+
+/*readonly*/ CProxy_Main mainProxy;
+/*readonly*/ int nElements;
+
+/*mainchare*/
+class Main : public Chare
+{
+public:
+  Main(CkArgMsg* m)
+  {
+    //Process command-line arguments
+    nElements=5;
+    if(m->argc >1 ) nElements=atoi(m->argv[1]);
+    delete m;
+
+    //Start the computation
+    CkPrintf("Running Hello on %d processors for %d elements\n",
+            CkNumPes(),nElements);
+    mainProxy = thishandle;
+
+    CProxy_Hello arr = CProxy_Hello::ckNew(nElements);
+
+    arr[0].SayHi(17);
+  };
+
+  void done(void)
+  {
+    CkPrintf("All done\n");
+    CkExit();
+  };
+};
+
+/*array [1D]*/
+class Hello : public CBase_Hello 
+{
+public:
+  Hello()
+  {
+    CkPrintf("Hello %d created\n",thisIndex);
+  }
+
+  Hello(CkMigrateMessage *m) {}
+  
+  void SayHi(int hiNo)
+  {
+    CkPrintf("Hi[%d] from element %d\n",hiNo,thisIndex);
+    if (thisIndex < nElements-1)
+      //Pass the hello on:
+      thisProxy[thisIndex+1].SayHi(hiNo+1);
+    else 
+      //We've been around once-- we're done.
+      mainProxy.done();
+  }
+};
+
+#include "hello.def.h"
diff --git a/tests/charm++/simplearrayhello/hello.ci b/tests/charm++/simplearrayhello/hello.ci
new file mode 100644 (file)
index 0000000..312b25f
--- /dev/null
@@ -0,0 +1,14 @@
+mainmodule hello {
+  readonly CProxy_Main mainProxy;
+  readonly int nElements;
+
+  mainchare Main {
+    entry Main(CkArgMsg *m);
+    entry void done(void);
+  };
+
+  array [1D] Hello {
+    entry Hello(void);
+    entry void SayHi(int hiNo);
+  };           
+};
diff --git a/tests/charm++/simplearrayhello/msvc_6/README.txt b/tests/charm++/simplearrayhello/msvc_6/README.txt
new file mode 100644 (file)
index 0000000..276ae67
--- /dev/null
@@ -0,0 +1,14 @@
+This directory contains a Microsoft Visual Studio
+6.0 project file for a simple Charm++ application.
+
+To use it, first build Charm++, then translate the hello.ci
+interface file into the hello.decl.h and hello.def.h headers
+manually.  To do this, open a DOS prompt and type:
+
+       cd net-win32\pgms\charm++\simplearrayhello
+       ..\..\..\bin\charmxi.exe hello.ci
+
+You should now be able to open hello.dsw in Visual Studio
+by double-clicking on the hello.dsw icon.  Build the 
+executable under the Build menu, and then execute it.
+
diff --git a/tests/charm++/simplearrayhello/msvc_6/hello.dsp b/tests/charm++/simplearrayhello/msvc_6/hello.dsp
new file mode 100644 (file)
index 0000000..c0415a0
--- /dev/null
@@ -0,0 +1,141 @@
+# Microsoft Developer Studio Project File - Name="hello" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
+\r
+CFG=hello - Win32 Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "hello.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "hello.mak" CFG="hello - Win32 Debug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "hello - Win32 Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "hello - Win32 Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "hello - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Release"\r
+# PROP Intermediate_Dir "Release"\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+\r
+!ELSEIF  "$(CFG)" == "hello - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Debug"\r
+# PROP Intermediate_Dir "Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ  /c\r
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c /Tp\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 libck.a libconv-core.a libconv-cplus-y.a libconv-util.a libldb-rand.o libmemory-default.o libtrace-none.a kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"../../../../lib"\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "hello - Win32 Release"\r
+# Name "hello - Win32 Debug"\r
+# Begin Group "Source Files"\r
+\r
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+# Begin Source File\r
+\r
+SOURCE=..\hello.C\r
+# End Source File\r
+# End Group\r
+# Begin Group "Header Files"\r
+\r
+# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
+# Begin Source File\r
+\r
+SOURCE=..\hello.decl.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\hello.def.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Resource Files"\r
+\r
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"\r
+# End Group\r
+# Begin Group "Charm++ Libraries"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\lib\libck.a\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE="..\..\..\..\lib\libconv-core.a"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE="..\..\..\..\lib\libconv-cplus-y.a"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE="..\..\..\..\lib\libconv-util.a"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE="..\..\..\..\lib\libldb-rand.o"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE="..\..\..\..\lib\libmemory-default.o"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE="..\..\..\..\lib\libtrace-none.a"\r
+# End Source File\r
+# End Group\r
+# End Target\r
+# End Project\r
diff --git a/tests/charm++/simplearrayhello/msvc_6/hello.dsw b/tests/charm++/simplearrayhello/msvc_6/hello.dsw
new file mode 100644 (file)
index 0000000..07550fe
--- /dev/null
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00\r
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r
+\r
+###############################################################################\r
+\r
+Project: "hello"=".\hello.dsp" - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Global:\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<3>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
diff --git a/tests/charm++/simplearrayhello/msvc_6/hello.opt b/tests/charm++/simplearrayhello/msvc_6/hello.opt
new file mode 100644 (file)
index 0000000..81f5a46
Binary files /dev/null and b/tests/charm++/simplearrayhello/msvc_6/hello.opt differ