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