/home/runner/work/charm/charm/src/ck-ldb/LBManager.h
Line | Count | Source (jump to first uncovered line) |
1 | | /** |
2 | | * \addtogroup CkLdb |
3 | | */ |
4 | | /*@{*/ |
5 | | |
6 | | #ifndef LBMANAGER_H |
7 | | #define LBMANAGER_H |
8 | | |
9 | | #include <cassert> |
10 | | |
11 | | #include "LBDatabase.h" |
12 | | #include "conv-ccs.h" // CcsDelayedReply |
13 | | #include <deque> |
14 | | #include "json_fwd.hpp" |
15 | | using json = nlohmann::json; |
16 | | |
17 | | #define LB_FORMAT_VERSION 3 |
18 | | |
19 | | #define LB_MANAGER_VERSION 1 |
20 | | |
21 | | class MetaBalancer; |
22 | | extern int _lb_version; |
23 | | |
24 | | // command line options |
25 | | class CkLBArgs |
26 | | { |
27 | | private: |
28 | | double _autoLbPeriod; // in seconds |
29 | | double _lb_alpha; // per message send overhead |
30 | | double _lb_beta; // per byte send overhead |
31 | | int _lb_debug; // 1 or greater |
32 | | bool _lb_printsummary; // print summary |
33 | | bool _lb_loop; // use multiple load balancers in loop |
34 | | bool _lb_ignoreBgLoad; |
35 | | bool _lb_migObjOnly; // only consider migratable objs |
36 | | bool _lb_syncResume; |
37 | | bool _lb_samePeSpeed; // ignore cpu speed |
38 | | bool _lb_testPeSpeed; // test cpu speed |
39 | | bool _lb_useCpuTime; // use cpu instead of wallclock time |
40 | | bool _lb_statson; // stats collection |
41 | | bool _lb_traceComm; // stats collection for comm |
42 | | int _lb_central_pe; // processor number for centralized strategy |
43 | | int _lb_maxDistPhases; // Specifies the max number of LB phases in DistributedLB |
44 | | double _lb_targetRatio; // Specifies the target load ratio for LBs that aim for a |
45 | | // particular load ratio |
46 | | bool _lb_metaLbOn; |
47 | | char* _lb_metaLbModelDir; |
48 | | char* _lb_treeLBFile = (char*)"treelb.json"; |
49 | | int _lb_percentMovesAllowed; // for the greedy-refine balancers, as a |
50 | | // percentage of chares that may be moved |
51 | | // For the greedy-refine balancers: how far above the max load plain greedy |
52 | | // achieves this balancer may go, in exchange for migrating less. 1.1 allows |
53 | | // a 10% higher max load. It is the "tolerance" the manual documents. |
54 | | // |
55 | | // Defaults to 1.1: allow a max load 10% above what plain greedy achieves, and |
56 | | // spend that slack on not migrating. Measured on jacobi2d-imbalance, 256 |
57 | | // chares on 32 PEs, that is 26 moves against 366 for the parameter search it |
58 | | // replaces as the default, and less than half the time. |
59 | | // |
60 | | // 0 or below asks for that search instead: every PE builds a candidate from a |
61 | | // different (A,B) pair and the best is chosen. It costs a reduction per |
62 | | // balancing step and is bounded by the PE count, which is why it is no longer |
63 | | // the default -- but it stays reachable with +LBGreedyRefineTolerance 0. |
64 | | double _lb_greedyRefineTolerance; |
65 | | |
66 | | public: |
67 | | CkLBArgs() |
68 | | { |
69 | | _autoLbPeriod = -1.0; // off by default |
70 | | _lb_debug = 0; |
71 | | _lb_ignoreBgLoad = _lb_syncResume = _lb_useCpuTime = false; |
72 | | _lb_printsummary = _lb_migObjOnly = false; |
73 | | _lb_statson = true; |
74 | | _lb_traceComm = false; |
75 | | _lb_loop = false; |
76 | | _lb_central_pe = 0; |
77 | | _lb_maxDistPhases = 10; |
78 | | _lb_targetRatio = 1.05; |
79 | | _lb_metaLbOn = false; |
80 | | _lb_metaLbModelDir = nullptr; |
81 | | _lb_percentMovesAllowed = 100; |
82 | | _lb_greedyRefineTolerance = 1.1; // 10% over greedy; <=0 searches instead |
83 | | } |
84 | 2.09k | inline char*& treeLBFile() { return _lb_treeLBFile; } |
85 | | inline double& lbperiod() { return _autoLbPeriod; } |
86 | 14.0k | inline int& debug() { return _lb_debug; } |
87 | | inline bool& printSummary() { return _lb_printsummary; } |
88 | | inline int& lbversion() { return _lb_version; } |
89 | | inline bool& loop() { return _lb_loop; } |
90 | 6.04k | inline bool& ignoreBgLoad() { return _lb_ignoreBgLoad; } |
91 | | inline bool& migObjOnly() { return _lb_migObjOnly; } |
92 | 2.43k | inline bool& syncResume() { return _lb_syncResume; } |
93 | | inline bool& samePeSpeed() { return _lb_samePeSpeed; } |
94 | 3.86k | inline bool& testPeSpeed() { return _lb_testPeSpeed; } |
95 | | inline bool& useCpuTime() { return _lb_useCpuTime; } |
96 | 2.69k | inline bool& statsOn() { return _lb_statson; } |
97 | | inline bool& traceComm() { return _lb_traceComm; } |
98 | | inline int& central_pe() { return _lb_central_pe; } |
99 | | inline double& alpha() { return _lb_alpha; } |
100 | | inline double& beta() { return _lb_beta; } |
101 | 1.70k | inline int& maxDistPhases() { return _lb_maxDistPhases; } |
102 | 1.75k | inline double& targetRatio() { return _lb_targetRatio; } |
103 | 4.10M | inline bool& metaLbOn() { return _lb_metaLbOn; } |
104 | 2.31k | inline char*& metaLbModelDir() { return _lb_metaLbModelDir; } |
105 | | inline int& percentMovesAllowed() { return _lb_percentMovesAllowed; } |
106 | | inline double& greedyRefineTolerance() { return _lb_greedyRefineTolerance; } |
107 | | }; |
108 | | |
109 | | extern CkLBArgs _lb_args; |
110 | | |
111 | | extern bool _lb_predict; |
112 | | extern int _lb_predict_delay; |
113 | | extern int _lb_predict_window; |
114 | | extern bool _lb_psizer_on; |
115 | | #ifndef PREDICT_DEBUG |
116 | | #define PREDICT_DEBUG 0 // 0 = No debug, 1 = Debug info on |
117 | | #endif |
118 | | #define PredictorPrintf \ |
119 | | if (PREDICT_DEBUG) CmiPrintf |
120 | | |
121 | | // used in constructor of all load balancers |
122 | | class CkLBOptions |
123 | | { |
124 | | private: |
125 | | int seqno; // for centralized lb, the seqno |
126 | | std::string legacyName; |
127 | | public: |
128 | 387 | CkLBOptions() : seqno(-1), legacyName() {} |
129 | 24 | CkLBOptions(int s) : seqno(s), legacyName() {} |
130 | | CkLBOptions(int s, const char* legacyName) : seqno(s), legacyName(legacyName ? legacyName : "") {} |
131 | 803 | int getSeqNo() const { return seqno; } |
132 | 689 | bool hasLegacyName() const { return !legacyName.empty(); } |
133 | 340 | const char* getLegacyName() const { |
134 | 340 | assert(hasLegacyName()); |
135 | 334 | return legacyName.c_str(); |
136 | 340 | } |
137 | | |
138 | | void pup(PUP::er& p) |
139 | 620 | { |
140 | 620 | p | seqno; |
141 | 620 | p | legacyName; |
142 | 620 | } |
143 | | }; |
144 | | |
145 | | #include "LBManager.decl.h" |
146 | | |
147 | | extern CkGroupID _lbmgr; |
148 | | |
149 | | CkpvExtern(bool, lbmanagerInited); |
150 | | |
151 | | // LB options, mostly controled by user parameter |
152 | | extern char* _lbtopo; |
153 | | |
154 | | typedef void (*LBCreateFn)(const CkLBOptions&); |
155 | | typedef BaseLB* (*LBAllocFn)(); |
156 | | void LBDefaultCreate(LBCreateFn f); |
157 | | |
158 | | void LBRegisterBalancer(std::string, LBCreateFn, LBAllocFn, std::string, bool shown = true); |
159 | | |
160 | | template <typename T> |
161 | | void LBRegisterBalancer(std::string name, std::string description, bool shown = true) |
162 | 1.00k | { |
163 | 1.00k | LBRegisterBalancer( |
164 | 1.00k | name, [](const CkLBOptions& opts) { T::proxy_t::ckNew(opts); },_ZZ18LBRegisterBalancerI6TreeLBEvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_bENKUlRK11CkLBOptionsE_clES9_ Line | Count | Source | 164 | 108 | name, [](const CkLBOptions& opts) { T::proxy_t::ckNew(opts); }, |
_ZZ18LBRegisterBalancerI13DistributedLBEvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_bENKUlRK11CkLBOptionsE_clES9_ Line | Count | Source | 164 | 4 | name, [](const CkLBOptions& opts) { T::proxy_t::ckNew(opts); }, |
Unexecuted instantiation: _ZZ18LBRegisterBalancerI11RecBipartLBEvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_bENKUlRK11CkLBOptionsE_clES9_ _ZZ18LBRegisterBalancerI7MetisLBEvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_bENKUlRK11CkLBOptionsE_clES9_ Line | Count | Source | 164 | 4 | name, [](const CkLBOptions& opts) { T::proxy_t::ckNew(opts); }, |
|
165 | 1.00k | []() -> BaseLB* { return new T(static_cast<CkMigrateMessage*>(nullptr)); },Unexecuted instantiation: _ZZ18LBRegisterBalancerI6TreeLBEvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_bENKUlvE_clEv Unexecuted instantiation: _ZZ18LBRegisterBalancerI13DistributedLBEvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_bENKUlvE_clEv Unexecuted instantiation: _ZZ18LBRegisterBalancerI11RecBipartLBEvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_bENKUlvE_clEv Unexecuted instantiation: _ZZ18LBRegisterBalancerI7MetisLBEvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_bENKUlvE_clEv |
166 | 1.00k | description, shown); |
167 | 1.00k | } _Z18LBRegisterBalancerI6TreeLBEvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_b Line | Count | Source | 162 | 256 | { | 163 | 256 | LBRegisterBalancer( | 164 | 256 | name, [](const CkLBOptions& opts) { T::proxy_t::ckNew(opts); }, | 165 | 256 | []() -> BaseLB* { return new T(static_cast<CkMigrateMessage*>(nullptr)); }, | 166 | 256 | description, shown); | 167 | 256 | } |
_Z18LBRegisterBalancerI13DistributedLBEvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_b Line | Count | Source | 162 | 248 | { | 163 | 248 | LBRegisterBalancer( | 164 | 248 | name, [](const CkLBOptions& opts) { T::proxy_t::ckNew(opts); }, | 165 | 248 | []() -> BaseLB* { return new T(static_cast<CkMigrateMessage*>(nullptr)); }, | 166 | 248 | description, shown); | 167 | 248 | } |
_Z18LBRegisterBalancerI11RecBipartLBEvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_b Line | Count | Source | 162 | 248 | { | 163 | 248 | LBRegisterBalancer( | 164 | 248 | name, [](const CkLBOptions& opts) { T::proxy_t::ckNew(opts); }, | 165 | 248 | []() -> BaseLB* { return new T(static_cast<CkMigrateMessage*>(nullptr)); }, | 166 | 248 | description, shown); | 167 | 248 | } |
_Z18LBRegisterBalancerI7MetisLBEvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_b Line | Count | Source | 162 | 248 | { | 163 | 248 | LBRegisterBalancer( | 164 | 248 | name, [](const CkLBOptions& opts) { T::proxy_t::ckNew(opts); }, | 165 | 248 | []() -> BaseLB* { return new T(static_cast<CkMigrateMessage*>(nullptr)); }, | 166 | 248 | description, shown); | 167 | 248 | } |
|
168 | | |
169 | | void _LBMgrInit(); |
170 | | |
171 | | // main chare |
172 | | class LBMgrInit : public Chare |
173 | | { |
174 | | public: |
175 | | LBMgrInit(CkArgMsg*); |
176 | | LBMgrInit(CkMigrateMessage* m) : Chare(m) {} |
177 | | }; |
178 | | |
179 | | // class which implement a virtual function for the FuturePredictor |
180 | | class LBPredictorFunction |
181 | | { |
182 | | public: |
183 | | virtual ~LBPredictorFunction() {} |
184 | | int num_params; |
185 | | |
186 | | virtual void initialize_params(double* x) |
187 | | { |
188 | | double normall = 1.0 / pow((double)2, (double)31); |
189 | | for (int i = 0; i < num_params; ++i) x[i] = rand() * normall; |
190 | | } |
191 | | |
192 | | virtual double predict(double x, double* params) = 0; |
193 | | virtual void print(double* params) { PredictorPrintf("LB: unknown model\n"); }; |
194 | | virtual void function(double x, double* param, double& y, double* dyda) = 0; |
195 | | }; |
196 | | |
197 | | // a default implementation for a FuturePredictor function |
198 | | class DefaultFunction : public LBPredictorFunction |
199 | | { |
200 | | public: |
201 | | // constructor |
202 | | DefaultFunction() { num_params = 6; }; |
203 | | |
204 | | // compute the prediction function for the variable x with parameters param |
205 | | double predict(double x, double* param) |
206 | | { |
207 | | return (param[0] + param[1] * x + param[2] * x * x + |
208 | | param[3] * sin(param[4] * (x + param[5]))); |
209 | | } |
210 | | |
211 | | void print(double* param) |
212 | | { |
213 | | PredictorPrintf("LB: %f + %fx + %fx^2 + %fsin%f(x+%f)\n", param[0], param[1], |
214 | | param[2], param[3], param[4], param[5]); |
215 | | } |
216 | | |
217 | | // compute the prediction function and its derivatives respect to the parameters |
218 | | void function(double x, double* param, double& y, double* dyda) |
219 | | { |
220 | | double tmp; |
221 | | |
222 | | y = predict(x, param); |
223 | | |
224 | | dyda[0] = 1; |
225 | | dyda[1] = x; |
226 | | dyda[2] = x * x; |
227 | | tmp = param[4] * (x + param[5]); |
228 | | dyda[3] = sin(tmp); |
229 | | dyda[4] = param[3] * (x + param[5]) * cos(tmp); |
230 | | dyda[5] = param[3] * param[4] * cos(tmp); |
231 | | } |
232 | | }; |
233 | | |
234 | | class LBManager : public CBase_LBManager |
235 | | { |
236 | | private: |
237 | | struct StartLBCB |
238 | | { |
239 | | std::function<void()> fn; |
240 | | bool on; |
241 | | }; |
242 | | |
243 | | struct MigrationDoneCB |
244 | | { |
245 | | std::function<void()> fn; |
246 | | }; |
247 | | |
248 | | struct PredictCB |
249 | | { |
250 | | std::function<void(LBPredictorFunction* model)> on; |
251 | | std::function<void(LBPredictorFunction* model, int win)> onWin; |
252 | | std::function<void()> off; |
253 | | std::function<void(LBPredictorFunction* model)> change; |
254 | | }; |
255 | | |
256 | | LBDatabase* lbdb_obj; |
257 | | |
258 | | // CCS handler "LBObjLoads": pending reply tokens and whether a collection |
259 | | // round is in flight (one round serves every request that arrived meanwhile) |
260 | | std::deque<CcsDelayedReply> objLoadsReplies; |
261 | | bool objLoadsCollecting; |
262 | | |
263 | | bool useBarrier; // use barrier or not |
264 | | |
265 | | PredictCB* predictCBFn; |
266 | | |
267 | | int startLBFn_count; |
268 | | |
269 | | public: |
270 | | int chare_count; |
271 | | |
272 | | LBManager(void) { init(); } |
273 | | LBManager(CkMigrateMessage* m) : CBase_LBManager(m) { init(); } |
274 | | ~LBManager() { delete lbdb_obj; } |
275 | | |
276 | | private: |
277 | | void init(); |
278 | | void InvokeLB(); |
279 | | |
280 | | public: |
281 | | LBDatabase* getLBDB() { return lbdb_obj; } |
282 | | inline static LBManager* Object() |
283 | 56.3k | { |
284 | 56.3k | return CkpvAccess(lbmanagerInited) ? (LBManager*)CkLocalBranch(_lbmgr) : NULL; |
285 | 56.3k | } |
286 | | |
287 | | static void initnodeFn(void); |
288 | | |
289 | | void pup(PUP::er& p); |
290 | | |
291 | | void configureTreeLB(const char* json_str); |
292 | | void configureTreeLB(json& config); |
293 | | |
294 | | /* |
295 | | * Calls from object managers to load database |
296 | | */ |
297 | | // LDOMHandle RegisterOM(LDOMid userID, void *userptr, LDCallbacks cb); |
298 | | |
299 | | static void periodicLB(void*); |
300 | | void setTimer(); |
301 | | |
302 | | LDOMHandle RegisterOM(LDOMid userID, void* userptr, LDCallbacks cb) |
303 | | { |
304 | | return lbdb_obj->RegisterOM(userID, userptr, cb); |
305 | | } |
306 | 50.0k | int Migrate(LDObjHandle h, int dest) { return lbdb_obj->Migrate(h, dest); } |
307 | | void UnregisterOM(LDOMHandle omh) { lbdb_obj->UnregisterOM(omh); } |
308 | | void RegisteringObjects(LDOMHandle omh) { lbdb_obj->RegisteringObjects(omh); } |
309 | | void DoneRegisteringObjects(LDOMHandle omh) |
310 | | { |
311 | | lbdb_obj->DoneRegisteringObjects(omh); |
312 | | } |
313 | | void ObjectStart(const LDObjHandle& h) { lbdb_obj->ObjectStart(h); } |
314 | | void ObjectStop(const LDObjHandle& h) { lbdb_obj->ObjectStop(h); } |
315 | | void NonMigratable(LDObjHandle h) { lbdb_obj->NonMigratable(h); } |
316 | | void Migratable(LDObjHandle h) { lbdb_obj->Migratable(h); } |
317 | | void setPupSize(LDObjHandle h, size_t pup_size) { lbdb_obj->setPupSize(h, pup_size); } |
318 | | void setGPUPupSize(LDObjHandle h, size_t gpu_pup_size) |
319 | | { |
320 | | lbdb_obj->setGPUPupSize(h, gpu_pup_size); |
321 | | } |
322 | | void UseAsyncMigrate(LDObjHandle h, bool flag) { lbdb_obj->UseAsyncMigrate(h, flag); }; |
323 | | // Live per-object load snapshot over CCS (handler "LBObjLoads" on PE 0): |
324 | | // every PE appends one record, the reply is int32 numPes followed by the |
325 | | // concatenated records; see collectObjLoads for the layout. |
326 | | void objLoadsRequest(const CcsDelayedReply& token); |
327 | | void collectObjLoads(); |
328 | | void objLoadsCollected(CkReductionMsg* m); |
329 | | |
330 | 40.8k | int GetObjDataSz(void) { return lbdb_obj->GetObjDataSz(); } |
331 | | int GetCommDataSz(void) { return lbdb_obj->GetCommDataSz(); } |
332 | 3.91k | void GetObjData(LDObjData* data) { lbdb_obj->GetObjData(data); } |
333 | | void GetCommData(LDCommData* data) { lbdb_obj->GetCommData(data); } |
334 | | void GetCommInfo(int& bytes, int& msgs, int& withinbytes, int& outsidebytes, |
335 | | int& num_nghbors, int& hops, int& hopbytes) |
336 | 0 | { |
337 | 0 | lbdb_obj->GetCommInfo(bytes, msgs, withinbytes, outsidebytes, num_nghbors, hops, |
338 | 0 | hopbytes); |
339 | 0 | } |
340 | 368 | void CollectStatsOn(void) { lbdb_obj->CollectStatsOn(); } |
341 | | void CollectStatsOff(void) { lbdb_obj->CollectStatsOff(); } |
342 | | bool StatsOn(void) { return lbdb_obj->StatsOn(); } |
343 | | void ObjTime(LDObjHandle h, double walltime, double cputime) |
344 | | { |
345 | | lbdb_obj->ObjTime(h, walltime, cputime); |
346 | | } |
347 | | void GetObjLoad(LDObjHandle& h, LBRealType& walltime, LBRealType& cputime) |
348 | | { |
349 | | lbdb_obj->GetObjLoad(h, walltime, cputime); |
350 | | }; |
351 | | void GetObjGPULoad(LDObjHandle& h, LBRealType& gputime) |
352 | | { |
353 | | lbdb_obj->GetObjGPULoad(h, gputime); |
354 | | }; |
355 | | // Copy a round's normalized per-object GPU loads (built by |
356 | | // hapiPrepareCuptiLoads) into this PE's LB objects, just before its stats |
357 | | // are sent. |
358 | | void SetObjGPULoad( |
359 | | const std::unordered_map<LDObjKey, double, LDObjKeyHash>& id_loadMap) |
360 | | { |
361 | | lbdb_obj->SetObjGPULoad(id_loadMap); |
362 | | } |
363 | | void* GetObjUserData(LDObjHandle& h) { return lbdb_obj->GetObjUserData(h); } |
364 | 106 | void MetaLBCallLBOnChares() { lbdb_obj->MetaLBCallLBOnChares(); } |
365 | | void MetaLBResumeWaitingChares(int lb_period) |
366 | 106 | { |
367 | 106 | lbdb_obj->MetaLBResumeWaitingChares(lb_period); |
368 | 106 | } |
369 | 4.06k | void ClearLoads(void) { lbdb_obj->ClearLoads(); } |
370 | | const LDObjHandle& GetObjHandle(int idx) { return lbdb_obj->GetObjHandle(idx); } |
371 | 1.45k | void IdleTime(LBRealType* walltime) { lbdb_obj->IdleTime(walltime); } |
372 | | void TotalTime(LBRealType* walltime, LBRealType* cputime) |
373 | 184 | { |
374 | 184 | lbdb_obj->TotalTime(walltime, cputime); |
375 | 184 | } |
376 | | |
377 | | void GetTime(LBRealType* total_walltime, LBRealType* total_cputime, |
378 | | LBRealType* idletime, LBRealType* bg_walltime, LBRealType* bg_cputime) |
379 | 3.89k | { |
380 | 3.89k | lbdb_obj->GetTime(total_walltime, total_cputime, idletime, bg_walltime, bg_cputime); |
381 | 3.89k | } |
382 | | LDObjHandle RegisterObj(LDOMHandle omh, CmiUInt8 id, void* userPtr, int migratable) |
383 | | { |
384 | | return lbdb_obj->RegisterObj(omh, id, userPtr, migratable); |
385 | | } |
386 | | void UnregisterObj(LDObjHandle h) { lbdb_obj->UnregisterObj(h); } |
387 | | void EstObjLoad(const LDObjHandle& h, double cpuload) |
388 | | { |
389 | | lbdb_obj->EstObjLoad(h, cpuload); |
390 | | } |
391 | | void EstObjGPULoad(const LDObjHandle& h, double gpuload) |
392 | | { |
393 | | lbdb_obj->EstObjGPULoad(h, gpuload); |
394 | | } |
395 | | void BackgroundLoad(LBRealType* walltime, LBRealType* cputime) |
396 | 1.46k | { |
397 | 1.46k | lbdb_obj->BackgroundLoad(walltime, cputime); |
398 | 1.46k | } |
399 | | void Send(const LDOMHandle& destOM, const CmiUInt8& destID, unsigned int bytes, |
400 | | int destObjProc, int force = 0) |
401 | | { |
402 | | lbdb_obj->Send(destOM, destID, bytes, destObjProc, force); |
403 | | } |
404 | | void MulticastSend(const LDOMHandle& _om, CmiUInt8* _ids, int _n, unsigned int _b, |
405 | | int _nMsgs = 1) |
406 | | { |
407 | | lbdb_obj->MulticastSend(_om, _ids, _n, _b, _nMsgs); |
408 | | } |
409 | | int useMem() |
410 | | { |
411 | | int size = sizeof(LBManager); |
412 | | size += startLBFnList.size() * sizeof(StartLBCB); |
413 | | size += migrationDoneCBList.size() * sizeof(MigrationDoneCB); |
414 | | size += lbdb_obj->useMem(); |
415 | | return size; |
416 | | } |
417 | | |
418 | | #if CMK_LB_USER_DATA |
419 | | inline void* GetDBObjUserData(LDObjHandle& h, int idx) |
420 | | { |
421 | | return lbdb_obj->LbObj(h)->getDBUserData(idx); |
422 | | } |
423 | | #endif |
424 | | |
425 | | void ResetAdaptive(); |
426 | | |
427 | | void DumpDatabase(void); |
428 | | |
429 | | void reset(); |
430 | | |
431 | | /* |
432 | | * Calls from load balancer to load database |
433 | | */ |
434 | | template <typename T> |
435 | | inline int AddStartLBFn(T* obj, void (T::*method)(void)) |
436 | 359 | { |
437 | 359 | return AddStartLBFn(std::bind(method, obj)); |
438 | 359 | } _ZN9LBManager12AddStartLBFnI6TreeLBEEiPT_MS2_FvvE Line | Count | Source | 436 | 345 | { | 437 | 345 | return AddStartLBFn(std::bind(method, obj)); | 438 | 345 | } |
_ZN9LBManager12AddStartLBFnI10DistBaseLBEEiPT_MS2_FvvE Line | Count | Source | 436 | 14 | { | 437 | 14 | return AddStartLBFn(std::bind(method, obj)); | 438 | 14 | } |
|
439 | | int AddStartLBFn(std::function<void()> fn); |
440 | | void TurnOnStartLBFn(int handle) { startLBFnList[handle]->on = 1; } |
441 | | void TurnOffStartLBFn(int handle) { startLBFnList[handle]->on = 0; } |
442 | | void RemoveStartLBFn(int handle); |
443 | | |
444 | | void StartLB(); |
445 | | |
446 | | template <typename T> |
447 | | inline int AddMigrationDoneFn(T* obj, void (T::*method)(void)) |
448 | | { |
449 | | return AddMigrationDoneFn(std::bind(method, obj)); |
450 | | } |
451 | | int AddMigrationDoneFn(std::function<void()> fn); |
452 | | void RemoveMigrationDoneFn(int handle); |
453 | | void MigrationDone(); |
454 | | |
455 | | public: |
456 | | inline void TurnManualLBOn() { useBarrier = false; } |
457 | | inline void TurnManualLBOff() { useBarrier = true; } |
458 | | |
459 | | inline void PredictorOn(LBPredictorFunction* model) |
460 | | { |
461 | | if (predictCBFn != NULL) |
462 | | predictCBFn->on(model); |
463 | | else |
464 | | CmiPrintf("Predictor not supported in this load balancer\n"); |
465 | | } |
466 | | inline void PredictorOn(LBPredictorFunction* model, int wind) |
467 | | { |
468 | | if (predictCBFn != NULL) |
469 | | predictCBFn->onWin(model, wind); |
470 | | else |
471 | | CmiPrintf("Predictor not supported in this load balancer\n"); |
472 | | } |
473 | | inline void PredictorOff() |
474 | | { |
475 | | if (predictCBFn != NULL) |
476 | | predictCBFn->off(); |
477 | | else |
478 | | CmiPrintf("Predictor not supported in this load balancer\n"); |
479 | | } |
480 | | inline void ChangePredictor(LBPredictorFunction* model) |
481 | | { |
482 | | if (predictCBFn != NULL) |
483 | | predictCBFn->change(model); |
484 | | else |
485 | | CmiPrintf("Predictor not supported in this load balancer"); |
486 | | } |
487 | | |
488 | | template <typename T> |
489 | | void SetupPredictor(T* data, |
490 | | void (T::*on)(LBPredictorFunction*), |
491 | | void (T::*onWin)(LBPredictorFunction*, int), |
492 | | void (T::*off)(void), |
493 | | void (T::*change)(LBPredictorFunction*)) |
494 | | { |
495 | | if (predictCBFn == nullptr) predictCBFn = new PredictCB; |
496 | | predictCBFn->on = [=](LBPredictorFunction* fn) { (data->*on)(fn); }; |
497 | | predictCBFn->onWin = [=](LBPredictorFunction* fn, int win) { (data->*onWin)(fn, win); }; |
498 | | predictCBFn->off = [=]() { (data->*off)(); }; |
499 | | predictCBFn->change = [=](LBPredictorFunction* fn) { (data->*change)(fn); }; |
500 | | } |
501 | | |
502 | | inline int CollectingCommStats(void) |
503 | | { |
504 | | return lbdb_obj->CollectingStats() && _lb_args.traceComm(); |
505 | | }; |
506 | | |
507 | | void Migrated(LDObjHandle h, int waitBarrier = 1); |
508 | | |
509 | | LDBarrierClient AddLocalBarrierClient(Chare* obj, std::function<void()> fn); |
510 | | template <typename T> |
511 | | inline LDBarrierClient AddLocalBarrierClient(T* obj, void (T::*method)(void)) |
512 | | { |
513 | | return AddLocalBarrierClient((Chare*)obj, std::bind(method, obj)); |
514 | | } |
515 | | |
516 | | void RemoveLocalBarrierClient(LDBarrierClient h); |
517 | | |
518 | | LDBarrierReceiver AddLocalBarrierReceiver(std::function<void()> fn); |
519 | | template <typename T> |
520 | | inline LDBarrierReceiver AddLocalBarrierReceiver(T* obj, void (T::*method)(void)) |
521 | | { |
522 | | return AddLocalBarrierReceiver(std::bind(method, obj)); |
523 | | } |
524 | | void RemoveLocalBarrierReceiver(LDBarrierReceiver h); |
525 | | void AtLocalBarrier(LDBarrierClient _n_c); |
526 | | void TurnOnBarrierReceiver(LDBarrierReceiver h); |
527 | | void TurnOffBarrierReceiver(LDBarrierReceiver h); |
528 | | |
529 | | void LocalBarrierOn(void); |
530 | | void LocalBarrierOff(void); |
531 | | void ResumeClients(); |
532 | | static int ProcessorSpeed(); |
533 | | static void SetLBPeriod(double period) |
534 | | { |
535 | | _lb_args.lbperiod() = period; |
536 | | // If the manager has been initialized, then start the timer |
537 | | if (auto* const obj = LBManager::Object()) obj->setTimer(); |
538 | | } |
539 | | static double GetLBPeriod() { return _lb_args.lbperiod(); } |
540 | | |
541 | | void SetMigrationCost(double cost); |
542 | | void SetStrategyCost(double cost); |
543 | | void UpdateDataAfterLB(double mLoad, double mCpuLoad, double avgLoad); |
544 | | |
545 | | private: |
546 | | int mystep; |
547 | | static std::vector<char> avail_vector; // processor bit vector |
548 | | static bool avail_vector_set; |
549 | | int new_ld_balancer; // for Node 0 |
550 | | MetaBalancer* metabalancer; |
551 | | int currentLBIndex; |
552 | | bool isPeriodicQueued = false; |
553 | | |
554 | | public: |
555 | | std::vector<BaseLB*> loadbalancers; |
556 | | |
557 | | std::vector<StartLBCB*> startLBFnList; |
558 | | std::vector<MigrationDoneCB*> migrationDoneCBList; |
559 | | |
560 | | public: |
561 | | BaseLB** getLoadBalancers() { return loadbalancers.data(); } |
562 | | int getNLoadBalancers() { return loadbalancers.size(); } |
563 | | |
564 | | public: |
565 | | static bool manualOn; |
566 | | |
567 | | public: |
568 | | const char *availVector() const { return avail_vector.data(); } |
569 | | void get_avail_vector(char * bitmap) const; |
570 | | void get_avail_vector(std::vector<char> & bitmap) const { bitmap = avail_vector; } |
571 | | void set_avail_vector(const char * bitmap, int new_ld = -1); |
572 | | void set_avail_vector(const std::vector<char> & bitmap, int new_ld = -1); |
573 | | int& new_lbbalancer() { return new_ld_balancer; } |
574 | | |
575 | | struct LastLBInfo |
576 | | { |
577 | | LBRealType* expectedLoad; |
578 | | LastLBInfo(); |
579 | | }; |
580 | | LastLBInfo lastLBInfo; |
581 | | inline LBRealType myExpectedLoad() { return lastLBInfo.expectedLoad[CkMyPe()]; } |
582 | | inline LBRealType* expectedLoad() { return lastLBInfo.expectedLoad; } |
583 | | |
584 | | int getLoadbalancerTicket(); |
585 | | void addLoadbalancer(BaseLB* lb, int seq); |
586 | | void nextLoadbalancer(int seq); |
587 | | void switchLoadbalancer(int switchFrom, int switchTo); |
588 | | const char* loadbalancer(int seq); |
589 | | |
590 | 4.47k | inline int step() { return mystep; } |
591 | 4.07k | inline void incStep() { mystep++; } |
592 | | }; |
593 | | |
594 | | void TurnManualLBOn(); |
595 | | void TurnManualLBOff(); |
596 | | |
597 | | void LBTurnPredictorOn(LBPredictorFunction* model); |
598 | | void LBTurnPredictorOn(LBPredictorFunction* model, int wind); |
599 | | void LBTurnPredictorOff(); |
600 | | void LBChangePredictor(LBPredictorFunction* model); |
601 | | |
602 | | // This alias remains for backwards compatibility |
603 | | CMK_DEPRECATED_MSG("Use LBManager::SetLBPeriod instead of LBSetPeriod") |
604 | | void LBSetPeriod(double period); |
605 | | |
606 | | #if CMK_LB_USER_DATA |
607 | | int LBRegisterObjUserData(int size); |
608 | | #endif |
609 | | |
610 | | CLINKAGE void LBTurnInstrumentOn(); |
611 | | CLINKAGE void LBTurnInstrumentOff(); |
612 | | void LBTurnCommOn(); |
613 | | void LBTurnCommOff(); |
614 | | void LBClearLoads(); |
615 | | |
616 | | inline LBManager* LBManagerObj() { return LBManager::Object(); } |
617 | | |
618 | | inline void CkStartLB() { LBManager::Object()->StartLB(); } |
619 | | |
620 | | inline void get_avail_vector(std::vector<char> & bitmap) { LBManagerObj()->get_avail_vector(bitmap); } |
621 | | |
622 | | inline void set_avail_vector(const std::vector<char> & bitmap) { LBManagerObj()->set_avail_vector(bitmap); } |
623 | | |
624 | | // a helper class to suspend/resume load instrumentation when calling into |
625 | | // runtime apis |
626 | | |
627 | | class SystemLoad |
628 | | { |
629 | | const LDObjHandle* objHandle; |
630 | | LBManager* lbmgr; |
631 | | |
632 | | public: |
633 | | SystemLoad(); |
634 | | |
635 | | ~SystemLoad() |
636 | | { |
637 | | if (objHandle) lbmgr->ObjectStart(*objHandle); |
638 | | } |
639 | | }; |
640 | | |
641 | | #define CK_RUNTIME_API SystemLoad load_entry; |
642 | | |
643 | | #endif /* LDATABASE_H */ |
644 | | |
645 | | /*@}*/ |