Bug #757: disable unnecassary network polling in multicore build
[charm.git] / doc / charm++ / advancedlb.tex
blob2fe7e683749a5eb1c7874290d201b0e243a1fb46
1 \section{Load Balancing Simulation}
3 The simulation feature of the load balancing framework allows the users to collect information
4 about the compute WALL/CPU time and communication of the chares during a particular run of
5 the program and use this information later to test the different load balancing strategies to
6 see which one is suitable for the program behavior. Currently, this feature is supported only for
7 the centralized load balancing strategies. For this, the load balancing framework
8 accepts the following command line options:
9 \begin{enumerate}
10 \item {\em +LBDump StepStart}\\
11 This will dump the compute and the communication data collected by the load balancing framework
12 starting from the load balancing step {\em StepStart} into a file on the disk. The name of the file
13 is given by the {\em +LBDumpFile} option. The load balancing step in the
14 program is numbered starting from 0. Negative value for {\em StepStart} will be converted to 0.
15 \item {\em +LBDumpSteps StepsNo}\\
16 This option specifies the number of load balancing steps for which data will be dumped to disk.
17 If omitted, its default value is 1. The program will exit after {\em StepsNo} files are created.
18 \item {\em +LBDumpFile FileName}\\
19 This option specifies the base name of the file created with the load balancing data. If this
20 option is not specified, the framework uses the default file {\tt lbdata.dat}. Since multiple steps are allowed,
21 a number correspoding to the step number is appended to the filename in the form {\tt Filename.\#};
22 this applies to both dump and simulation.
23 \item {\em +LBSim StepStart}\\
24 This option instructs the framework to do the simulation starting from {\em StepStart} step.
25 When this option is specified, the load balancing data along with the step
26 number will be read from the file specified in the {\em +LBDumpFile}
27 option. The program will print the results of the balancing for a number of steps given
28 by the {\em +LBSimSteps} option, and then will exit.
29 \item {\em +LBSimSteps StepsNo}\\
30 This option is applicable only to the simulation mode. It specifies the number of
31 load balancing steps for which the data will be dumped. The default value is 1.
32 \item {\em +LBSimProcs}\\
33 With this option, the user can change the number of processors
34 specified to the load balancing strategy. It may be used to test
35 the strategy in the cases where some processor crashes or a new processor becomes available. If this number is not
36 changed since the original run, starting from the second step file, the program will print other additional
37 information about how the simulated load differs from the real load during the run (considering all
38 strategies that were applied while running). This may be used to test the validity of a load balancer
39 prediction over the reality. If the strategies used during run and simulation differ, the additional data
40 printed may not be useful.
41 \end{enumerate}
42 Here is an example which collects the data for a 1000 processor run of a program
43 \begin{alltt}
44 ./charmrun pgm +p1000 +balancer RandCentLB +LBDump 2 +LBDumpSteps 4 +LBDumpFile lbsim.dat
45 \end{alltt}
46 This will collect data on files lbsim.dat.{2,3,4,5}. We can use this data to
47 analyze the performance of various centralized strategies using:
48 \begin{alltt}
49 ./charmrun pgm +balancer <Strategy to test> +LBSim 2 +LBSimSteps 4 +LBDumpFile lbsim.dat
50 [+LBSimProcs 900]
51 \end{alltt}
52 Please note that this does not invoke the real application. In fact,
53 ''pgm'' can be replaced with any generic application which calls centralized load balancer.
54 An example can be found in \testrefdir{load\_balancing/lb\_test}.
56 \section{Future load predictor}
58 When objects do not follow the assumption that the future workload will be the
59 same as the past, the load balancer might not have the right information to do
60 a good rebalancing job. To prevent this, the user can provide a transition
61 function to the load balancer to predict what will be the future workload, given
62 the past instrumented one. For this, the user can provide a specific class
63 which inherits from {\tt LBPredictorFunction} and implement the appropriate functions.
64 Here is the abstract class:
65 \begin{alltt}
66 class LBPredictorFunction \{
67 public:
68 int num_params;
70 virtual void initialize_params(double *x);
72 virtual double predict(double x, double *params) =0;
73 virtual void print(double *params) {PredictorPrintf("LB: unknown model");};
74 virtual void function(double x, double *param, double &y, double *dyda) =0;
75 \};
76 \end{alltt}
77 \begin{itemize}
78 \item {\tt initialize\_params} by default initializes the parameters randomly. If the user
79 knows how they should be, this function can be re-implemented.
80 \item {\tt predict} is the function that predicts the future load based on the function parameters.
81 An example for the {\em predict} function is given below.
82 \begin{verbatim}
83 double predict(double x, double *param) {return (param[0]*x + param[1]);}
84 \end{verbatim}
85 \item {\tt print} is useful for debugging and it can be re-implemented to have a meaningful
86 print of the learnt model
87 \item {\tt function} is a function internally needed to learn the parameters, {\tt x} and
88 {\tt param} are input, {\tt y} and {\tt dyda} are output (the computed function and
89 all its derivatives with respect to the parameters, respectively).
90 For the function in the example should look like:
91 \begin{verbatim}
92 void function(double x, double *param, double &y, double *dyda) {
93 y = predict(x, param);
94 dyda[0] = x;
95 dyda[1] = 1;
97 \end{verbatim}
98 \end{itemize}
99 Other than these functions, the user should provide a constructor which must initialize
100 {\tt num\_params} to the number of parameters the model has to learn. This number is
101 the dimension of {\tt param} and {\tt dyda} in the previous functions. For the given
102 example, the constructor is {\tt \{num\_params = 2;\}}.
104 If the model for computation is not known, the user can leave the system to
105 use the default function.
107 As seen, the function can have several parameters which will be learned during
108 the execution of the program. For this, user can be add the following command
109 line arguments to specify the learning behavior:
110 \begin{enumerate}
111 \item {\em +LBPredictorWindow size}\\
112 This parameter specifies the number of statistics steps the load balancer will
113 store. The greater this number is, the better the
114 approximation of the workload will be, but more memory is required to store
115 the intermediate information. The default is 20.
116 \item {\em +LBPredictorDelay steps}\\
117 This will tell how many load balancer steps to wait before considering the
118 function parameters learnt and starting to use the mode. The load balancer will
119 collect statistics for a {\em +LBPredictorWindow} steps, but it will start using
120 the model as soon as {\em +LBPredictorDelay} information are collected. The
121 default is 10.
122 \end{enumerate}
123 Moreover, another flag can be set to enable the predictor from command line: {\em
124 +LBPredictor}.\\
125 Other than the command line options, there are some methods
126 which can be called from the user program to modify the predictor. These methods are:
127 \begin{itemize}
128 \item {\tt void PredictorOn(LBPredictorFunction *model);}
129 \item {\tt void PredictorOn(LBPredictorFunction *model,int window);}
130 \item {\tt void PredictorOff();}
131 \item {\tt void ChangePredictor(LBPredictorFunction *model);}
132 \end{itemize}
134 An example can be found in \testrefdir{load\_balancing/lb\_test/predictor}.
135 \section{Control CPU Load Statistics}
137 \charmpp{} programmers can modify the CPU load data in the load balancing database
138 before a load balancing phase starts (which is the time when load balancing
139 database is collected and used by load balancing strategies).
141 In an array element, the following function can be invoked to overwrite the
142 CPU load that is measured by the load balancing framework.
144 \begin{alltt}
145 double newTiming;
146 setObjTime(newTiming);
147 \end{alltt}
149 {\em setObjTime()} is defined as a method of class {\em CkMigratable}, which is
150 the superclass of all array elements.
152 The users can also retrieve the current timing that the load balancing runtime
153 has measured for the current array element using {\em getObjTime()}.
155 \begin{alltt}
156 double measuredTiming;
157 measuredTiming = getObjTime();
158 \end{alltt}
160 This is useful when the users want to derive a new CPU load based on the
161 existing one.
163 \section{Model-based Load Balancing}
165 The user can choose to feed load balancer with their own CPU
166 timing for each Chare based on certain computational model of the applications.
168 To do so, in the array element's constructor, the user first needs to turn off
169 automatic CPU load measurement completely by setting
171 \begin{alltt}
172 usesAutoMeasure = false;
173 \end{alltt}
175 The user must also implement the following function to the chare array
176 classes:
178 \begin{alltt}
179 virtual void CkMigratable::UserSetLBLoad(); // defined in base class
180 \end{alltt}
182 This function serves as a callback that is called on each chare object when
183 {\em AtSync()} is called and ready to do load balancing. The implementation of
184 {\em UserSetLBLoad()} is simply to set the current chare object's CPU load in
185 load balancing framework. {\em setObjTime()} described above can be used for
186 this.
188 \section{Writing a new load balancing strategy}
189 \label{lbWriteNewLB}
191 \charmpp{} programmers can choose an existing load balancing strategy from
192 \charmpp{}'s built-in strategies(see ~\ref{lbStrategy}) for the best performance
193 based on the characteristics of their applications. However, they can also
194 choose to write their own load balancing strategies.
196 The \charmpp{} load balancing framework provides a simple scheme to incorporate
197 new load balancing strategies. The programmer needs to write their strategy for
198 load balancing based on the instrumented ProcArray and ObjGraph provided by the
199 load balancing framework. This strategy is implemented within this
200 function:
202 \begin{alltt}
203 void FooLB::work(LDStats *stats) \{
204 /** ========================== INITIALIZATION ============================= */
205 ProcArray *parr = new ProcArray(stats);
206 ObjGraph *ogr = new ObjGraph(stats);
208 /** ============================= STRATEGY ================================ */
209 /// The strategy goes here
210 /// The strategy goes here
211 /// The strategy goes here
212 /// The strategy goes here
213 /// The strategy goes here
215 /** ============================== CLEANUP ================================ */
216 ogr->convertDecisions(stats);
218 \end{alltt}
220 Figure~\ref{fig:ckgraph} explains the two data structures available to the
221 strategy: ProcArray and ObjGraph. Using them, the strategy should assign objects
222 to new processors where it wants to be migrated through the setNewPe() method.
223 {\tt src/ck-ldb/GreedyLB.C} can be referred.
224 \begin{figure}[h]
225 \centering
226 \includegraphics[width=6.0in]{fig/ckgraph.png}
227 \caption{ProcArray and ObjGraph data structures to be used when writing a load
228 balancing strategy}
229 \label{fig:ckgraph}
230 \end{figure}
232 Incorporating this strategy into the \charmpp{} build framework is explained in
233 the next section.
235 \section{Adding a load balancer to \charmpp{}}
237 Let us assume that we are writing a new centralized load balancer called FooLB.
238 The next few steps explain the steps of adding the load balancer to the \charmpp{}
239 build system:
241 \begin{enumerate}
242 \item Create files named {\em FooLB.ci, FooLB.h and FooLB.C} in directory of {\tt src/ck-ldb}.
243 One can choose to copy and rename the files GraphPartLB.* and rename the class name in those
244 files.
246 \item Implement the strategy in the {\em FooLB} class method --- {\bf
247 FooLB::work(LDStats* stats)} as described in the previous section.
248 %This method takes the load balancing database ({\em stats}) as an input, and
249 %output the new mapping of objects to processors in {\em stats->to\_proc}
250 %array.
252 \item Build charm for your platform (This will create the required links in the
253 tmp directory).
255 \item To compile the strategy files, first add {\em FooLB} in the ALL\_LDBS
256 list in charm/tmp/Makefile\_lb.sh. Also comment out the line containing
257 UNCOMMON\_LDBS in Makefile\_lb.sh. If FooLB will require some libraries at
258 link time, you also need to create the dependency file called
259 libmoduleFooLB.dep. Run the script in charm/tmp, which creates the new Makefile
260 named ``Make.lb''.
262 \item Run ``make depends'' to update dependence rule of \charmpp{} files. And run
263 ``make charm++'' to compile \charmpp{} which includes the new load balancing
264 strategy files.
265 \end{enumerate}
268 \section{Understand Load Balancing Database Data Structure}
269 \label{lbdatabase}
271 To write a load balancing strategy, you need to know
272 what information is measured during the runtime and how it is represented in
273 the load balancing database data structure.
275 There are mainly 3 categories of information: a) processor information including processor speed, background load; b) object information including per object
276 CPU/WallClock compute time and c) communication information .
278 The database data structure named {\kw LDStats} is defined in {\em CentralLB.h}:
280 \begin{verbatim}
282 struct ProcStats { // per processor
283 LBRealType total_walltime;
284 LBRealType total_cputime;
285 LBRealType idletime;
286 LBRealType bg_walltime;
287 LBRealType bg_cputime;
288 int pe_speed;
289 double utilization;
290 bool available;
291 int n_objs;
294 struct LDStats { // load balancing database
295 ProcStats *procs;
296 int count;
298 int n_objs;
299 int n_migrateobjs;
300 LDObjData* objData;
302 int n_comm;
303 LDCommData* commData;
305 int *from_proc, *to_proc;
308 \end{verbatim}
310 \begin{enumerate}
311 \item {\em LBRealType} is the data type for load balancer measured time. It is "double" by default. User can specify the type to float at \charmpp{} compile time if want. For example, ./build charm++ net-linux-x86\_64 {-}{-}with-lbtime-type=float;
312 \item {\em procs} array defines processor attributes and usage data for each
313 processor;
314 \item {\em objData} array records per object information, {\em LDObjData} is defined in {\em lbdb.h};
315 \item {\em commData} array records per communication information. {\em LDCommData} is defined in {\em lbdb.h}.
316 \end{enumerate}