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