d68cc420e016c6dc6967ce0830aaa02d3b34ee82
[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     inline int getSize() {
55       return size;
56     }
57
58     virtual void pup(PUP::er &p);
59     PUPable_decl(MessageHolder);
60 };
61
62 #define CONVERSE_STRATEGY 0     //The strategy works for converse programs
63 #define NODEGROUP_STRATEGY 1    //Node group level optimizations 
64 #define GROUP_STRATEGY 2        //Charm Processor level optimizations
65 #define ARRAY_STRATEGY 3        //Array level optimizations
66
67 //Class that defines the entry methods that a Converse level strategy
68 //must define. To write a new strategy inherit from this class and
69 //define the virtual methods.  Every strategy can also define its own
70 //constructor and have any number of arguments. Also call the parent
71 //class methods in the virtual methods.
72
73 class Strategy : public PUP::able{
74  protected:
75     int type;
76     int isStrategyBracketed;
77     int myInstanceID;
78     int destinationHandler;
79
80     //Charm strategies for modularity may have converse strategies in
81     //them.  For the code to work in both Charm and converse, this
82     //variable can be used.    
83     Strategy *converseStrategy;
84     Strategy *higherLevel;
85
86  public:
87     Strategy();
88     Strategy(CkMigrateMessage *m) : PUP::able(m) {
89         converseStrategy = this;
90         higherLevel = this;
91     }
92
93     void setBracketed(){isStrategyBracketed = 1;}
94     int isBracketed(){return isStrategyBracketed;}
95
96     //Called for each message
97     virtual void insertMessage(MessageHolder *msg) {}
98     
99     //Called after all chares and groups have finished depositing their 
100     //messages on that processor.
101     virtual void doneInserting() {}
102
103     void setInstance(int instid){myInstanceID = instid;}
104     int getInstance(){return myInstanceID;}
105     int getType() {return type;}
106     void setType(int t) {type = t;}
107
108     void setDestination(int handler) {destinationHandler = handler;}
109     int getDestination() {return destinationHandler;}
110
111     void setConverseStrategy(Strategy *s){
112         converseStrategy = s;
113     }
114
115     Strategy * getConverseStrategy() {
116         return converseStrategy;
117     }
118
119     void setHigherLevel(Strategy *s) {
120       higherLevel = s;
121     }
122
123     Strategy * getHigherLevel() {
124       return higherLevel;
125     }
126
127     //This method can be used to deliver a message through the correct class
128     //when converse does not know if the message was originally sent from
129     //converse itself of from a higher level language like charm
130     virtual void deliverer(char*, int) {CmiAbort("Strategy::deliverer: If used, should be first redefined\n");};
131
132     //Each strategy must define his own Pup interface.
133     virtual void pup(PUP::er &p);
134     PUPable_decl(Strategy);
135 };
136
137 //Enables a list of strategies to be stored in a message through the
138 //pupable framework
139 class StrategyWrapper  {
140  public:
141     Strategy **s_table;
142     int nstrats;
143
144     void pup(PUP::er &p);
145 };
146 PUPmarshall(StrategyWrapper);
147
148 //Table of strategies. Each entry in the table points to a strategy.
149 //Strategies can change during the execution of the program but the
150 //StrategyTableEntry stores some persistent information for the
151 //strategy. The communication library on receiving a message, calls
152 //the strategy in this table given by the strategy id in the message.
153
154 struct StrategyTableEntry {
155     Strategy *strategy;
156     //A buffer for all strategy messages
157     CkQ<MessageHolder*> tmplist;
158     
159     int numElements;   //used by the array listener, 
160                        //could also be used for other objects
161     int elementCount;  //Count of how many elements have deposited
162                        //their data
163
164     //Used during a fence barrier at the begining or during the
165     //learning phases. Learning is only available for Charm++
166     //programs.
167     int nEndItr;       //#elements that called end iteration
168     int call_doneInserting; //All elements deposited their data
169
170     StrategyTableEntry();
171 };
172
173 typedef CkVec<StrategyTableEntry> StrategyTable;
174
175 #endif