new test to demonstrate a race condition
authorEric Bohm <ebohm@illinois.edu>
Fri, 27 May 2011 03:10:45 +0000 (22:10 -0500)
committerEric Bohm <ebohm@illinois.edu>
Fri, 27 May 2011 03:10:45 +0000 (22:10 -0500)
tests/charm++/ckAllocSysMsgTest/Makefile [new file with mode: 0644]
tests/charm++/ckAllocSysMsgTest/README [new file with mode: 0644]
tests/charm++/ckAllocSysMsgTest/ckAllocSysMsgTest.C [new file with mode: 0644]
tests/charm++/ckAllocSysMsgTest/ckAllocSysMsgTest.ci [new file with mode: 0644]
tests/charm++/ckAllocSysMsgTest/ckAllocSysMsgTest.h [new file with mode: 0644]

diff --git a/tests/charm++/ckAllocSysMsgTest/Makefile b/tests/charm++/ckAllocSysMsgTest/Makefile
new file mode 100644 (file)
index 0000000..ad9fa16
--- /dev/null
@@ -0,0 +1,29 @@
+CHARMC=../../../bin/charmc $(OPTS) $(MOPTS) 
+#CHARMC=$(HOME)/charm/bin/charmc $(OPTS) $(MOPTS) 
+
+
+OBJS = ckAllocSysMsgTest.o
+
+
+all: ckAllocSysMsgTest
+
+ckAllocSysMsgTest: $(OBJS)
+       $(CHARMC) -language charm++ -o ckAllocSysMsgTest $(OBJS)
+
+ckAllocSysMsgTest.decl.h: ckAllocSysMsgTest.ci
+       $(CHARMC)  ckAllocSysMsgTest.ci
+
+clean:
+       rm -f *.decl.h *.def.h conv-host *.o ckAllocSysMsgTest charmrun *.log *.sum *.sts
+
+ckAllocSysMsgTest.o: ckAllocSysMsgTest.C ckAllocSysMsgTest.decl.h ckAllocSysMsgTest.h
+       $(CHARMC) -c ckAllocSysMsgTest.C
+
+test: all
+       ./charmrun ./ckAllocSysMsgTest 10 10 10 1 $(TESTOPTS) 
+       ./charmrun ./ckAllocSysMsgTest 30 10 10 1 $(TESTOPTS) +p2 
+       ./charmrun ./ckAllocSysMsgTest 30 10 10 1 $(TESTOPTS) +p4
+
+
+bgtest: all
+       ./charmrun ./ckAllocSysMsgTest 30 10 10 1 $(TESTOPTS) +p4 +x2 +y2 +z2
diff --git a/tests/charm++/ckAllocSysMsgTest/README b/tests/charm++/ckAllocSysMsgTest/README
new file mode 100644 (file)
index 0000000..cf85228
--- /dev/null
@@ -0,0 +1,22 @@
+   This test is to demonstrate a race condition in the SMP build of
+   charm++.
+
+   Main launches a batch of Array and Group in a loop.
+   
+   The Array and group each engage in a ring and complete by reporting
+   to main.  Main will not start on the new batch until all elements
+   of the previous batch complete.
+   
+   This test is expected to hang in SMP mode if the bug is present.
+
+   By default a periodic timeout is registered which will trigger an abort
+   if the number of batches doesn't progress between periods. 
+
+   We do not construct the group or array inside main because the
+   CkAllocSysMsg race condition only affects group construction in
+   parallel execution.
+
+   The array must be multidimensional so that its indices will have
+   non zero values 
+
+   For sample usage, see make test.
diff --git a/tests/charm++/ckAllocSysMsgTest/ckAllocSysMsgTest.C b/tests/charm++/ckAllocSysMsgTest/ckAllocSysMsgTest.C
new file mode 100644 (file)
index 0000000..9607a64
--- /dev/null
@@ -0,0 +1,150 @@
+#include "charm++.h"
+#include "ckAllocSysMsgTest.decl.h"
+#include <stdio.h>
+#include <math.h>
+
+#include "ckAllocSysMsgTest.h"
+
+/* This test is to demonstrate a race condition in the SMP build of
+   charm++.
+
+   Main launches a batch of Array and Group in a loop.
+   
+   The Array and group each engage in a ring and complete by reporting
+   to main.  Main will not start on the new batch until all elements
+   of the previous batch complete.
+   
+   This test is expected to hang in SMP mode if the bug is present.
+
+   By default a periodic timeout is registered which will trigger an abort
+   if the number of batches doesn't progress between periods. 
+
+   We do not construct the group or array inside main because the
+   CkAllocSysMsg race condition only affects group construction in
+   parallel execution.
+
+   The array must be multidimensional so that its indices will have
+   non zero values 
+*/
+
+
+CProxy_main mainProxy;         
+int period;
+void timeout(void *, double thing)
+{
+  if(--period>0)
+    CcdCallOnCondition(CcdPERIODIC_1minute,timeout,NULL);
+  else
+    CkAbort("hung job failure");
+}
+
+
+main::main(CkArgMsg *msg)
+{
+  reportedArr=0;
+  reportedGrp=0;
+  completeBatches=0;
+  if(msg->argc>5)
+    CkAbort("Usage: ckAllocSysMsgTest arrSize nBatches batchSize timeout\n Where arrSize, nBatches, batchSize are int >0 \n and period is minutes, a timeout of zero disables the default 1 minute timer\n");
+  //get arrsize and wastetime from cmd line
+  arrSize= 30;
+  nBatches =6;
+  batchSize=10;
+  period=1;
+  if(msg->argc>1)
+    arrSize =atoi(msg->argv[1]);
+  if(msg->argc>2)
+    nBatches =atoi(msg->argv[2]);
+  if(msg->argc>3)
+    batchSize =atoi(msg->argv[3]);
+  if(msg->argc>4)
+    period=atoi(msg->argv[4]);
+  if(arrSize<=0 || nBatches <= 0 || batchSize <= 0)
+    CkAbort("Usage: ckAllocSysMsgTest arrSize nBatches batchSize period\n Where arrSize, nBatches, batchSize are int >0  and period is timeout in seconds, a timeout of zero disables the timer\n");
+  mainProxy=thisProxy;
+  if(period>0)
+    CcdCallOnCondition(CcdPERIODIC_1minute,timeout,NULL);
+  mainProxy.startBatching();
+}
+
+void main::startBatching()
+{
+  CkPrintf("batch %d\n",completeBatches);
+  for(int i=0;i<batchSize;i++)
+    {
+      CProxy_RaceMeArr arrProxy=CProxy_RaceMeArr::ckNew(arrSize,arrSize,arrSize, arrSize);
+      arrProxy.doneInserting();
+      CProxy_RaceMeGrp grpProxy=CProxy_RaceMeGrp::ckNew();
+      arrProxy(0,0,0).recvMsg();
+      grpProxy[0].recvMsg();
+      
+    }
+}
+
+
+
+void main::reportInArr()
+{
+  ++reportedArr;
+  if(reportedArr==batchSize)
+    nextBatch();
+}
+
+void main::reportInGrp()
+{
+ ++reportedGrp;
+  if(reportedGrp==batchSize)
+    nextBatch();
+
+}
+
+void main::nextBatch()
+{
+
+  if(reportedGrp==batchSize && reportedArr ==batchSize)
+    {
+      completeBatches++;
+      if(completeBatches==nBatches)
+       mainProxy.done();
+      else
+       {
+         reportedArr=reportedGrp=0;
+         startBatching();
+       }
+    }
+}
+
+void main::done()
+{
+  CkExit();
+}
+
+void RaceMeGrp::recvMsg()
+{
+  if(CkMyPe()==CkNumPes()-1)
+    mainProxy.reportInGrp();
+  else
+    {
+      CProxy_RaceMeGrp rtest(thisgroup);
+      rtest[CkMyPe()+1].recvMsg();
+    }
+}
+
+void RaceMeArr::recvMsg()
+{
+  if(thisIndex.x==nElements-1)
+    {
+      if(thisIndex.y==nElements-1)
+      {
+       if(thisIndex.z==nElements-1)
+         mainProxy.reportInArr();
+       else
+         thisProxy(thisIndex.x, thisIndex.y, thisIndex.z+1).recvMsg();
+      }
+      else
+       thisProxy(thisIndex.x, thisIndex.y+1, thisIndex.z).recvMsg();
+    }
+  else
+    thisProxy(thisIndex.x+1, thisIndex.y, thisIndex.z).recvMsg();
+}
+#include "ckAllocSysMsgTest.def.h"
diff --git a/tests/charm++/ckAllocSysMsgTest/ckAllocSysMsgTest.ci b/tests/charm++/ckAllocSysMsgTest/ckAllocSysMsgTest.ci
new file mode 100644 (file)
index 0000000..c0728aa
--- /dev/null
@@ -0,0 +1,20 @@
+mainmodule ckAllocSysMsgTest {
+    readonly CProxy_main mainProxy;            
+    readonly int period;
+  mainchare main {
+    entry main(CkArgMsg *m);              
+    entry void startBatching();
+    entry void reportInArr();
+    entry void reportInGrp();
+    entry void nextBatch();
+    entry void done();
+    };
+  group RaceMeGrp {
+    entry RaceMeGrp();
+    entry void recvMsg();
+  };
+  array [3D] RaceMeArr{
+    entry RaceMeArr(int nElements);
+    entry void recvMsg();
+ };
+};
diff --git a/tests/charm++/ckAllocSysMsgTest/ckAllocSysMsgTest.h b/tests/charm++/ckAllocSysMsgTest/ckAllocSysMsgTest.h
new file mode 100644 (file)
index 0000000..d687ba8
--- /dev/null
@@ -0,0 +1,30 @@
+class main : public CBase_main
+{
+ public:
+  main(CkArgMsg *msg);
+  void startBatching();
+  void reportInArr();
+  void reportInGrp();
+  void nextBatch();
+  void done();
+ private:
+  int reportedArr,reportedGrp, completeBatches, arrSize, nBatches, batchSize;
+
+};
+
+class RaceMeArr : public CBase_RaceMeArr
+{
+ public:
+ RaceMeArr(int nElements_):nElements(nElements_){}
+  void recvMsg();
+  RaceMeArr(CkMigrateMessage *m) {};
+ private:
+  int nElements;
+};
+
+class RaceMeGrp : public Group
+{
+ public:
+  RaceMeGrp(){}
+  void recvMsg();
+};