a0dff0eee717b052def5d990ccf259dc904b64ef
[charm.git] / src / ck-core / cknodegroupreduction.h
1 #ifndef _CKNODEGROUPREDUCTION_H
2 #define _CKNODEGROUPREDUCTION_H
3 /** Node Group Reductions added by Sayantan
4     This thing is extremely similar to the guy above****/
5
6
7     /**some data classes used by both ckreductionmgr and cknodereductionmgr**/
8 class contributorInfo {
9         public:
10                 int redNo;//Current reduction number
11                 contributorInfo() {redNo=0;}
12                 //Migration utilities:
13                 void pup(PUP::er &p);
14         };
15
16 class countAdjustment {
17         public:
18                 int gcount;//Adjustment to global count (applied at reduction end)
19                 int lcount;//Adjustment to local count (applied continually)
20                 int mainRecvd;
21                 countAdjustment(int ignored=0) {gcount=lcount=0;mainRecvd=0;}
22                 void pup(PUP::er& p){ p|gcount; p|lcount; p|mainRecvd; }
23 };
24
25 /** @todo: Fwd decl for a temporary class. Remove after
26  * delegated cross-array reductions are implemented more optimally
27  */
28 namespace ck { namespace impl { class XArraySectionReducer; } }
29
30 class CkReductionMsg;
31 //CkReduction is just a "namespace class" for the user-visible
32 // parts of the reduction system.
33 class CkReduction {
34 public:
35         /*These are the reducers you can use,
36           in addition to any user-defined reducers.*/
37         typedef enum {
38         //A placeholder invalid reduction type
39                 invalid=0,
40         //Compute the sum the numbers passed by each element.
41                 sum_int,sum_float,sum_double,
42
43         //Compute the product the numbers passed by each element.
44                 product_int,product_float,product_double,
45
46         //Compute the largest number passed by any element.
47                 max_int,max_float,max_double,
48
49         //Compute the smallest number passed by any element.
50                 min_int,min_float,min_double,
51
52         //Compute the logical AND of the integers passed by each element.
53         // The resulting integer will be zero if any source integer is zero.
54                 logical_and,
55
56         //Compute the logical OR of the integers passed by each element.
57         // The resulting integer will be 1 if any source integer is nonzero.
58                 logical_or,
59
60                 // Compute the logical bitvector AND of the integers passed by each element.
61                 bitvec_and,
62
63                 // Compute the logical bitvector OR of the integers passed by each element.
64                 bitvec_or,
65
66         // Select one message at random to pass on
67                 random,
68
69         //Concatenate the (arbitrary) data passed by each element
70                 concat,
71
72         //Combine the data passed by each element into an list of setElements.
73         // Each element may contribute arbitrary data (with arbitrary length).
74                 set,
75
76         //Last system-defined reducer number (user-defined reducers follow)
77                 lastSystemReducer
78         } reducerType;
79
80         //This structure is used with the set reducer above,
81         // and contains the data from one contribution.
82         class setElement {
83         public:
84                 int dataSize;//The length of the data array below
85                 char data[1];//The (dataSize-long) array of data
86                 //Utility routine: get the next setElement,
87                 // or return NULL if there are none.
88                 setElement *next(void);
89         };
90
91 //Support for adding new reducerTypes:
92         //A reducerFunction is used to combine several contributions
93         //into a single summed contribution:
94         //  nMsg gives the number of messages to reduce.
95         //  msgs[i] contains a contribution or summed contribution.
96         typedef CkReductionMsg *(*reducerFn)(int nMsg,CkReductionMsg **msgs);
97
98         //Add the given reducer to the list.  Returns the new reducer's
99         // reducerType.  Must be called in the same order on every node.
100         static reducerType addReducer(reducerFn fn);
101
102 private:
103         friend class CkReductionMgr;
104         friend class CkNodeReductionMgr;
105         friend class CkArrayReductionMgr;
106         friend class CkMulticastMgr;
107     friend class ck::impl::XArraySectionReducer;
108 //System-level interface
109         //This is the maximum number of possible reducers,
110         // including both builtin and user-defined types
111         enum {MAXREDUCERS=256};
112
113         //Reducer table: maps reducerTypes to reducerFns.
114         static reducerFn reducerTable[MAXREDUCERS];
115         static int nReducers;//Number of reducers currently in table above
116
117         //Don't instantiate a CkReduction object-- it's just a namespace.
118         CkReduction();
119 };
120
121
122
123
124
125 #define CK_REDUCTION_CONTRIBUTE_METHODS_DECL \
126   void contribute(int dataSize,const void *data,CkReduction::reducerType type, \
127         int userFlag=-1); \
128   void contribute(int dataSize,const void *data,CkReduction::reducerType type, \
129         const CkCallback &cb,int userFlag=-1); \
130   void contribute(CkReductionMsg *msg); \
131   void contribute(const CkCallback &cb,int userFlag=-1);\
132   void contribute(int userFlag=-1);\
133
134
135
136
137
138 class CkNodeReductionMgr : public IrrGroup {
139 public:
140         CProxy_CkNodeReductionMgr thisProxy;
141 public:
142         CkNodeReductionMgr(void);
143         CkNodeReductionMgr(CkMigrateMessage *m) : IrrGroup(m) {
144           storedCallback = NULL;
145         }
146
147         typedef CkReductionClientFn clientFn;
148
149         /**
150          * Add the given client function.  Overwrites any previous client.
151          * This manager will dispose of the callback when replaced or done.
152          */
153         void ckSetReductionClient(CkCallback *cb);
154
155 //Contribute-- the given msg can contain any data.  The reducerType
156 // field of the message must be valid.
157 // Each contributor must contribute exactly once to each reduction.
158         void contribute(contributorInfo *ci,CkReductionMsg *msg);
159         void contributeWithCounter(contributorInfo *ci,CkReductionMsg *m,int count);
160 //Communication (library-private)
161         void restartLocalGroupReductions(int number);
162         //Sent down the reduction tree (used by barren PEs)
163         void ReductionStarting(CkReductionNumberMsg *m);
164         //Sent up the reduction tree with reduced data
165         void RecvMsg(CkReductionMsg *m);
166         void doRecvMsg(CkReductionMsg *m);
167         void LateMigrantMsg(CkReductionMsg *m);
168
169         virtual void flushStates();     // flush state varaibles
170         virtual int startLocalGroupReductions(int number){ return 1;} // can be used to start reductions on all the 
171         //CkReductionMgrs on a particular node. It is overwritten by CkArrayReductionMgr to make the actual calls
172         // since it knows the CkReductionMgrs on a node.
173
174         virtual int getTotalGCount(){return 0;};
175
176 private:
177 //Data members
178         //Stored callback function (may be NULL if none has been set)
179         CkCallback *storedCallback;
180
181         int redNo;//Number of current reduction (incremented at end)
182         CmiBool inProgress;//Is a reduction started, but not complete?
183         CmiBool creating;//Are elements still being created?
184         CmiBool startRequested;//Should we start the next reduction when creation finished?
185         int gcount;
186         int lcount;//Number of local contributors
187
188         //Current local and remote contributions
189         int nContrib,nRemote;
190         //Contributions queued for the current reduction
191         CkMsgQ<CkReductionMsg> msgs;
192         //Contributions queued for future reductions (sent to us too early)
193         CkMsgQ<CkReductionMsg> futureMsgs;
194         //Remote messages queued for future reductions (sent to us too early)
195         CkMsgQ<CkReductionMsg> futureRemoteMsgs;
196         //Late migrant messages queued for future reductions
197         CkMsgQ<CkReductionMsg> futureLateMigrantMsgs;
198         
199         //My Big LOCK
200         CmiNodeLock lockEverything;
201
202         int interrupt; /* flag for use in non-smp 0 means interrupt can occur 1 means not (also acts as a lock)*/
203
204         /*vector storing the children of this node*/
205         CkVec<int> kids;
206         
207 //State:
208         void startReduction(int number,int srcPE);
209         void doAddContribution(CkReductionMsg *m);
210         void finishReduction(void);
211 protected:      
212         void addContribution(CkReductionMsg *m);
213
214 private:
215
216 //Reduction tree utilities
217 /* for binomial trees*/
218         unsigned upperSize;
219         unsigned label;
220         int parent;
221         int numKids;
222 //      int *kids;
223         void init_BinomialTree();
224
225         
226         void init_BinaryTree();
227         enum {TREE_WID=2};
228         int treeRoot(void);//Root PE
229         CmiBool hasParent(void);
230         int treeParent(void);//My parent PE
231         int firstKid(void);//My first child PE
232         int treeKids(void);//Number of children in tree
233
234         //Combine (& free) the current message vector.
235         CkReductionMsg *reduceMessages(void);
236
237         //Map reduction number to a time
238         CmiBool isPast(int num) const {return (CmiBool)(num<redNo);}
239         CmiBool isPresent(int num) const {return (CmiBool)(num==redNo);}
240         CmiBool isFuture(int num) const {return (CmiBool)(num>redNo);}
241
242         /*FAULT_EVAC*/
243         bool oldleaf;
244         bool blocked;
245         int newParent;
246         int additionalGCount,newAdditionalGCount; //gcount that gets passed to u from the node u replace
247         CkVec<int> newKids;
248         CkMsgQ<CkReductionMsg> bufferedMsgs;
249         CkMsgQ<CkReductionMsg> bufferedRemoteMsgs;
250         enum {OLDPARENT,OLDCHILDREN,NEWPARENT,LEAFPARENT};
251         int numModificationReplies;
252         int maxModificationRedNo;
253         int tempModificationRedNo;
254         bool readyDeletion;
255         int killed;     
256         
257 //Checkpointing utilities
258  public:
259         virtual void pup(PUP::er &p);
260         /*FAULT_EVAC*/
261         virtual void evacuate();
262         virtual void doneEvacuate();
263         void DeleteChild(int deletedChild);
264         void DeleteNewChild(int deletedChild);
265         void collectMaxRedNo(int maxRedNo);
266         void unblockNode(int maxRedNo);
267         void modifyTree(int code,int size,int *data);
268 private:        
269         int findMaxRedNo();
270         void updateTree();
271         void clearBlockedMsgs();
272 };
273
274
275
276 //A NodeGroup that contribute to reductions
277 class NodeGroup : public CkNodeReductionMgr {
278   protected:
279     contributorInfo reductionInfo;//My reduction information
280   public:
281     CmiNodeLock __nodelock;
282     NodeGroup();
283     NodeGroup(CkMigrateMessage* m):CkNodeReductionMgr(m) { __nodelock=CmiCreateLock(); }
284     
285     ~NodeGroup();
286     inline const CkGroupID &ckGetGroupID(void) const {return thisgroup;}
287     inline CkGroupID CkGetNodeGroupID(void) const {return thisgroup;}
288     virtual int isNodeGroup() { return 1; }
289
290     virtual void pup(PUP::er &p);
291     virtual void flushStates() {
292         CkNodeReductionMgr::flushStates();
293         reductionInfo.redNo = 0;
294     }
295
296     CK_REDUCTION_CONTRIBUTE_METHODS_DECL
297     void contributeWithCounter(CkReductionMsg *msg,int count);
298 };
299
300
301 #endif
302