Coverage Report

Created: 2026-11-01 12:49

/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.04k
  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.01k
  inline bool& ignoreBgLoad() { return _lb_ignoreBgLoad; }
91
  inline bool& migObjOnly() { return _lb_migObjOnly; }
92
2.39k
  inline bool& syncResume() { return _lb_syncResume; }
93
  inline bool& samePeSpeed() { return _lb_samePeSpeed; }
94
3.89k
  inline bool& testPeSpeed() { return _lb_testPeSpeed; }
95
  inline bool& useCpuTime() { return _lb_useCpuTime; }
96
2.65k
  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.72k
  inline int& maxDistPhases() { return _lb_maxDistPhases; }
102
1.74k
  inline double& targetRatio() { return _lb_targetRatio; }
103
4.08M
  inline bool& metaLbOn() { return _lb_metaLbOn; }
104
2.27k
  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
371
  CkLBOptions() : seqno(-1), legacyName() {}
129
21
  CkLBOptions(int s) : seqno(s), legacyName() {}
130
  CkLBOptions(int s, const char* legacyName) : seqno(s), legacyName(legacyName ? legacyName : "") {}
131
742
  int getSeqNo() const { return seqno; }
132
658
  bool hasLegacyName() const { return !legacyName.empty(); }
133
311
  const char* getLegacyName() const {
134
311
    assert(hasLegacyName());
135
332
    return legacyName.c_str();
136
311
  }
137
138
  void pup(PUP::er& p)
139
598
  {
140
598
    p | seqno;
141
598
    p | legacyName;
142
598
  }
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
109
      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
257
{
163
257
  LBRegisterBalancer(
164
257
      name, [](const CkLBOptions& opts) { T::proxy_t::ckNew(opts); },
165
257
      []() -> BaseLB* { return new T(static_cast<CkMigrateMessage*>(nullptr)); },
166
257
      description, shown);
167
257
}
_Z18LBRegisterBalancerI13DistributedLBEvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_b
Line
Count
Source
162
249
{
163
249
  LBRegisterBalancer(
164
249
      name, [](const CkLBOptions& opts) { T::proxy_t::ckNew(opts); },
165
249
      []() -> BaseLB* { return new T(static_cast<CkMigrateMessage*>(nullptr)); },
166
249
      description, shown);
167
249
}
_Z18LBRegisterBalancerI11RecBipartLBEvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_b
Line
Count
Source
162
249
{
163
249
  LBRegisterBalancer(
164
249
      name, [](const CkLBOptions& opts) { T::proxy_t::ckNew(opts); },
165
249
      []() -> BaseLB* { return new T(static_cast<CkMigrateMessage*>(nullptr)); },
166
249
      description, shown);
167
249
}
_Z18LBRegisterBalancerI7MetisLBEvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_b
Line
Count
Source
162
249
{
163
249
  LBRegisterBalancer(
164
249
      name, [](const CkLBOptions& opts) { T::proxy_t::ckNew(opts); },
165
249
      []() -> BaseLB* { return new T(static_cast<CkMigrateMessage*>(nullptr)); },
166
249
      description, shown);
167
249
}
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.1k
  {
284
56.2k
    return CkpvAccess(lbmanagerInited) ? (LBManager*)CkLocalBranch(_lbmgr) : NULL;
285
56.1k
  }
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.6k
  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
379
  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
101
  void MetaLBCallLBOnChares() { lbdb_obj->MetaLBCallLBOnChares(); }
365
  void MetaLBResumeWaitingChares(int lb_period)
366
107
  {
367
107
    lbdb_obj->MetaLBResumeWaitingChares(lb_period);
368
107
  }
369
4.01k
  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
174
  {
374
174
    lbdb_obj->TotalTime(walltime, cputime);
375
174
  }
376
377
  void GetTime(LBRealType* total_walltime, LBRealType* total_cputime,
378
               LBRealType* idletime, LBRealType* bg_walltime, LBRealType* bg_cputime)
379
3.86k
  {
380
3.86k
    lbdb_obj->GetTime(total_walltime, total_cputime, idletime, bg_walltime, bg_cputime);
381
3.86k
  }
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.45k
  {
397
1.45k
    lbdb_obj->BackgroundLoad(walltime, cputime);
398
1.45k
  }
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
337
  {
437
337
    return AddStartLBFn(std::bind(method, obj));
438
337
  }
_ZN9LBManager12AddStartLBFnI6TreeLBEEiPT_MS2_FvvE
Line
Count
Source
436
321
  {
437
321
    return AddStartLBFn(std::bind(method, obj));
438
321
  }
_ZN9LBManager12AddStartLBFnI10DistBaseLBEEiPT_MS2_FvvE
Line
Count
Source
436
16
  {
437
16
    return AddStartLBFn(std::bind(method, obj));
438
16
  }
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.43k
  inline int step() { return mystep; }
591
4.05k
  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
/*@}*/