x-array sections: Update example code to use x-array section reductions too
[charm.git] / examples / charm++ / hello / xarraySection / hello.C
1 #include "hello.decl.h"
2 #include "ckmulticast.h"
3 #include <stdio.h>
4
5 class pingMsg: public CkMcastBaseMsg, public CMessage_pingMsg
6 {
7     public:
8         pingMsg(int num=0): hiNo(num) {}
9         int hiNo;
10 };
11
12
13 /// Test controller. Main chare
14 class Main : public CBase_Main
15 {
16 public:
17   Main(CkArgMsg* m): numArrays(2), numElements(5), sectionSize(numElements), maxIter(3), numIter(0)
18   {
19     //Process command-line arguments
20     if (m->argc > 1) numElements = atoi(m->argv[1]);
21     if (m->argc > 2) numArrays   = atoi(m->argv[2]);
22     if (m->argc > 3) sectionSize = atoi(m->argv[3]); else sectionSize = numElements;
23     if (m->argc > 4) maxIter     = atoi(m->argv[4]);
24     if (m->argc > 5)
25     { CkPrintf("Syntax: %s [numElements numArrays sectionSize maxIter]",m->argv[0]); CkAbort("Wrong Usage\n"); }
26     delete m;
27
28     CkPrintf("Running a cross-array section demo.\n");
29     CkPrintf("\tnum PEs = %d\n\tnum arrays = %d\n\tnum elements = %d\n\tsection size = %d\n\tnum iterations = %d\n",
30              CkNumPes(), numArrays, numElements, sectionSize, maxIter);
31
32     // Create a multicast manager group
33     CkGroupID mcastMgrGID = CProxy_CkMulticastMgr::ckNew();
34     CkMulticastMgr *mcastMgr = CProxy_CkMulticastMgr(mcastMgrGID).ckLocalBranch();
35
36     // Setup section member index bounds
37     int afloor = 0, aceiling = sectionSize-1;
38
39     // Allocate space
40     CProxy_Hello *arrayOfArrays = new CProxy_Hello[numArrays];
41     CkArrayID *arrID            = new CkArrayID[numArrays];
42     int *nelems                 = new int[numArrays];
43     CkArrayIndexMax **elems     = new CkArrayIndexMax*[numArrays];
44
45     // Create a list of array section members
46     for(int k=0; k < numArrays; k++)
47     {
48         // Create the array
49         arrayOfArrays[k] = CProxy_Hello::ckNew(k, mcastMgrGID, numElements);
50         // Store the AID
51         arrID[k]  = arrayOfArrays[k].ckGetArrayID();
52         // Create a list of section member indices in this array
53         nelems[k] = sectionSize;
54         elems[k]  = new CkArrayIndexMax[sectionSize];
55         for(int i=afloor,j=0; i <= aceiling; i++,j++)
56             elems[k][j] = CkArrayIndex1D(i);
57     }
58     // Create the x-array-section
59     sectionProxy = CProxySection_Hello(numArrays, arrID, elems, nelems);
60
61     // Delegate the section comm to the CkMulticast library
62     sectionProxy.ckSectionDelegate(mcastMgr);
63     // Configure the client of the section reduction
64     CkCallback *rednCB = new CkCallback(CkIndex_Main::rednPong(NULL), thisProxy); 
65     mcastMgr->setReductionClient(sectionProxy, rednCB);
66
67     // Start the test by pinging the section
68     pingMsg *msg = new pingMsg(numIter);
69     sectionProxy.mcastPing(msg);
70   }
71
72   /// Test controller method
73   void rednPong(CkReductionMsg *msg)
74   {
75       CkPrintf("----------------- testController: Received pong via reduction msg for iter %d\n", numIter+1);
76       CkAssert( msg->getSize() == sizeof(int) );
77       CkAssert( *( reinterpret_cast<int*>(msg->getData()) ) == numIter * numArrays * sectionSize);
78
79       if (++numIter == maxIter) {
80           CkPrintf("----------------- testController: All %d iterations done\n", numIter);
81           CkExit();
82       }
83       else
84       {
85           // Ping the section
86           CkPrintf("----------------- testController: Iteration %d done\n", numIter);
87           pingMsg *nextPing = new pingMsg(numIter);
88           sectionProxy.mcastPing(nextPing);
89       }
90
91       delete msg;
92   }
93
94 private:
95   /// Input parameters
96   int numArrays, numElements, sectionSize, maxIter;
97   /// Counters
98   int numIter;
99   /// The cross-array section proxy
100   CProxySection_Hello sectionProxy;
101 };
102
103
104
105 /** 1D chare array.
106  *
107  * Sections of multiple instances of this array participate in a cross-array section reduction
108  */
109 class Hello : public CBase_Hello
110 {
111 public:
112   Hello(int _aNum, CkGroupID mcastMgrGID): aNum(_aNum), mcastMgr(NULL), isCookieSet(false)
113   {
114     CkPrintf("Array %d, Element %d created on PE %d\n", aNum, thisIndex, CkMyPe());
115     mcastMgr = CProxy_CkMulticastMgr(mcastMgrGID).ckLocalBranch();
116   }
117
118   Hello(CkMigrateMessage *m) {}
119
120   void mcastPing(pingMsg *msg)
121   {
122     // Say hello world
123     CkPrintf("Array %d, Element %d received ping number %d\n", aNum, thisIndex, msg->hiNo);
124     // Save the section cookie, the first time you get it
125     if (! isCookieSet)
126     {
127         sectionCookie = msg->_cookie;
128         isCookieSet = true;
129     }
130     // Contribute to the section reduction
131     mcastMgr->contribute(sizeof(int), &(msg->hiNo), CkReduction::sum_int, sectionCookie);
132     delete msg;
133   }
134
135 private:
136   int aNum;
137   CkMulticastMgr *mcastMgr;
138   CkSectionInfo sectionCookie;
139   bool isCookieSet;
140 };
141
142 #include "hello.def.h"
143