added a variable higherLevel and a method deliverer to be used to uniform the
[charm.git] / src / conv-com / convcomlibstrategy.h
1 #ifndef CONVCOMMLIBSTRATEGY_H
2 #define CONVCOMMLIBSTRATEGY_H
3
4 #include "converse.h"
5 #include "pup.h"
6 #include "cklists.h"
7
8 //An abstract data structure that holds a converse message and which
9 //can be buffered by the communication library Message holder is a
10 //wrapper around a message. Has other useful data like destination
11 //processor list for a multicast etc.
12
13 class MessageHolder : public PUP::able {
14  public:
15     int dest_proc;
16     char *data;
17     int size;
18     MessageHolder *next; // also used for the refield at the receiver
19     int isDummy;
20     
21     //For multicast, the user can pass the pelist and list of Pes he
22     //wants to send the data to.
23     int npes;
24     int *pelist;
25     
26     MessageHolder() 
27         {dest_proc = size = isDummy = 0; data = NULL;}    
28
29     MessageHolder(CkMigrateMessage *m) {}
30
31     inline MessageHolder(char * msg, int proc, int sz) {
32         data = msg;
33         dest_proc = proc;
34         size = sz;
35         
36         isDummy = 0;
37         
38         npes = 0;
39         pelist = 0;
40
41     }
42
43     inline ~MessageHolder() {
44         /*
45           if(pelist != NULL && npes > 0)
46           delete[] pelist;
47         */
48     }
49
50     inline char * getMessage() {
51         return data;
52     }
53
54     virtual void pup(PUP::er &p);
55     PUPable_decl(MessageHolder);
56 };
57
58 #define CONVERSE_STRATEGY 0     //The strategy works for converse programs
59 #define NODEGROUP_STRATEGY 1    //Node group level optimizations 
60 #define GROUP_STRATEGY 2        //Charm Processor level optimizations
61 #define ARRAY_STRATEGY 3        //Array level optimizations
62
63 //Class that defines the entry methods that a Converse level strategy
64 //must define. To write a new strategy inherit from this class and
65 //define the virtual methods.  Every strategy can also define its own
66 //constructor and have any number of arguments. Also call the parent
67 //class methods in the virtual methods.
68
69 class Strategy : public PUP::able{
70  protected:
71     int type;
72     int isStrategyBracketed;
73     int myInstanceID;
74
75     //Charm strategies for modularity may have converse strategies in
76     //them.  For the code to work in both Charm and converse, this
77     //variable can be used.    
78     Strategy *converseStrategy;
79     Strategy *higherLevel;
80
81  public:
82     Strategy();
83     Strategy(CkMigrateMessage *m) : PUP::able(m) {
84         converseStrategy = this;
85         higherLevel = this;
86     }
87
88     void setBracketed(){isStrategyBracketed = 1;}
89     int isBracketed(){return isStrategyBracketed;}
90
91     //Called for each message
92     virtual void insertMessage(MessageHolder *msg) {}
93     
94     //Called after all chares and groups have finished depositing their 
95     //messages on that processor.
96     virtual void doneInserting() {}
97
98     void setInstance(int instid){myInstanceID = instid;}
99     int getInstance(){return myInstanceID;}
100     int getType() {return type;}
101     void setType(int t) {type = t;}
102
103     void setConverseStrategy(Strategy *s){
104         converseStrategy = s;
105     }
106
107     Strategy * getConverseStrategy() {
108         return converseStrategy;
109     }
110
111     void setHigherLevel(Strategy *s) {
112       higherLevel = s;
113     }
114
115     Strategy * getHigherLevel() {
116       return higherLevel;
117     }
118
119     //This method can be used to deliver a message through the correct class
120     //when converse does not know if the message was originally sent from
121     //converse itself of from a higher level language like charm
122     virtual void deliverer(char*) {CmiAbort("Strategy::deliverer: If used, should be first redefined\n");};
123
124     //Each strategy must define his own Pup interface.
125     virtual void pup(PUP::er &p);
126     PUPable_decl(Strategy);
127 };
128
129 //Enables a list of strategies to be stored in a message through the
130 //pupable framework
131 class StrategyWrapper  {
132  public:
133     Strategy **s_table;
134     int nstrats;
135
136     void pup(PUP::er &p);
137 };
138 PUPmarshall(StrategyWrapper);
139
140 //Table of strategies. Each entry in the table points to a strategy.
141 //Strategies can change during the execution of the program but the
142 //StrategyTableEntry stores some persistent information for the
143 //strategy. The communication library on receiving a message, calls
144 //the strategy in this table given by the strategy id in the message.
145
146 struct StrategyTableEntry {
147     Strategy *strategy;
148     //A buffer for all strategy messages
149     CkQ<MessageHolder*> tmplist;
150     
151     int numElements;   //used by the array listener, 
152                        //could also be used for other objects
153     int elementCount;  //Count of how many elements have deposited
154                        //their data
155
156     //Used during a fence barrier at the begining or during the
157     //learning phases. Learning is only available for Charm++
158     //programs.
159     int nEndItr;       //#elements that called end iteration
160     int call_doneInserting; //All elements deposited their data
161
162     StrategyTableEntry();
163 };
164
165 typedef CkVec<StrategyTableEntry> StrategyTable;
166
167 #endif