Coverage Report

Created: 2026-10-28 17:42

/home/runner/work/charm/charm/src/ck-ldb/LBDatabase.h
Line
Count
Source (jump to first uncovered line)
1
#ifndef LBDATABASE_H
2
#define LBDATABASE_H
3
4
#include "lbdb.h"
5
6
#include "LBObj.h"
7
#include "LBOM.h"
8
#include "LBComm.h"
9
#include "LBMachineUtil.h"
10
11
#if CMK_CUDA && CMK_LBDB_ON
12
// For hapiCuptiStartTracing/hapiCuptiStopTracing, called from TurnStatsOn/Off.
13
// Declared here rather than by including hapi.h, which drags the CUDA runtime
14
// headers into every consumer of LBDatabase.h.
15
void hapiCuptiStartTracing();
16
void hapiCuptiStopTracing();
17
#endif
18
19
#include <unordered_map>
20
#include <vector>
21
22
class CkSyncBarrier;
23
24
class LBDatabase {
25
friend class LBManager;
26
private:
27
  LBDatabase();
28
  struct LBObjEntry {
29
    static const LDObjIndex DEFAULT_NEXT = -1;
30
    LBObj* obj;
31
    LDObjIndex nextEmpty;
32
33
1.09M
    LBObjEntry(LBObj* obj, LDObjIndex nextEmpty = DEFAULT_NEXT) : obj(obj), nextEmpty(nextEmpty) {}
34
  };
35
36
  std::vector<LBObjEntry> objs;
37
  std::vector<LBOM*> oms;
38
  LDObjIndex objsEmptyHead;
39
  int omCount;
40
  int omsRegistering;
41
  LBCommTable* commTable;
42
  bool statsAreOn;
43
  double obj_walltime;
44
  LBMachineUtil machineUtil;
45
  CkSyncBarrier* syncBarrier;
46
47
#if CMK_LB_CPUTIMER
48
  double obj_cputime;
49
#endif
50
51
public:
52
  inline void MeasuredObjTime(double wtime, double ctime) {
53
    if (statsAreOn) {
54
      obj_walltime += wtime;
55
#if CMK_LB_CPUTIMER
56
      obj_cputime += ctime;
57
#endif
58
    }
59
  }
60
  inline LBOM* LbOM(LDOMHandle h) {
61
    return oms[h.handle];
62
  }
63
10.0M
  inline LBObj *LbObj(const LDObjHandle &h) const {
64
10.0M
    return objs[h.handle].obj;
65
10.0M
  }
66
  inline LBObj *LbObjIdx(int h) const {
67
    return objs[h].obj;
68
  }
69
70
  inline void ObjTime(LDObjHandle h, double walltime, double cputime) {
71
    LbObj(h)->IncrementTime(walltime, cputime);
72
    MeasuredObjTime(walltime, cputime);
73
  };
74
75
  inline void GetObjLoad(LDObjHandle &h, LBRealType &walltime, LBRealType &cputime) {
76
    LbObj(h)->getTime(&walltime, &cputime);
77
  };
78
79
  inline void GetObjGPULoad(LDObjHandle &h, LBRealType &gputime) {
80
    LbObj(h)->getGPUTime(&gputime);
81
  };
82
83
  // Copy the per-object normalized GPU loads computed by
84
  // hapiNormalizeCuptiLoads into this PE's LB objects. The map is shared
85
  // per-process and every PE reads it concurrently, so this must not mutate it.
86
  inline void SetObjGPULoad(
87
      const std::unordered_map<LDObjKey, double, LDObjKeyHash> &id_loadMap)
88
  {
89
    for (size_t i = 0; i < objs.size(); i++) {
90
      if (objs[i].obj == nullptr)
91
        continue;
92
      const LDObjHandle &handle = objs[i].obj->GetLDObjHandle();
93
      LDObjKey key;
94
      key.omID() = handle.omID();
95
      key.objID() = handle.objID();
96
      auto it = id_loadMap.find(key);
97
      if (it == id_loadMap.end())
98
        continue;
99
      objs[i].obj->setGPUTiming(it->second);
100
    }
101
  }
102
103
  inline void* GetObjUserData(LDObjHandle &h) {
104
    return LbObj(h)->getLocalUserData();
105
  }
106
  // GPU activity tracing follows the same switch as CPU instrumentation, so an
107
  // application that calls LBTurnInstrumentOn()/LBTurnInstrumentOff() around
108
  // its own AtSync schedule controls both with one call. Tracing is by far the
109
  // more expensive of the two, so leaving it off between load-balancing steps
110
  // is what makes instrumented runs affordable.
111
  inline void TurnStatsOn(void)
112
382
       {statsAreOn = true; machineUtil.StatsOn();
113
#if CMK_CUDA && CMK_LBDB_ON
114
        hapiCuptiStartTracing();
115
#endif
116
382
       }
117
  inline void TurnStatsOff(void)
118
       {statsAreOn = false; machineUtil.StatsOff();
119
#if CMK_CUDA && CMK_LBDB_ON
120
        hapiCuptiStopTracing();
121
#endif
122
       }
123
  inline bool StatsOn(void) const
124
21.9M
       { return statsAreOn; };
125
6.77k
  inline void IdleTime(LBRealType *walltime) {
126
6.77k
    machineUtil.IdleTime(walltime);
127
6.77k
  }
128
5.52k
  inline void TotalTime(LBRealType *walltime, LBRealType *cputime) {
129
5.52k
    machineUtil.TotalTime(walltime, cputime);
130
5.52k
  }
131
132
  inline void QueryKnownObjLoad(LDObjHandle &h, LBRealType &walltime, LBRealType &cputime) {
133
    LbObj(h)->lastKnownLoad(&walltime, &cputime);
134
  };
135
  inline void NonMigratable(LDObjHandle h) { LbObj(h)->SetMigratable(false); };
136
  inline void Migratable(LDObjHandle h) { LbObj(h)->SetMigratable(true); };
137
  inline void setPupSize(LDObjHandle h, size_t pup_size) { LbObj(h)->setPupSize(pup_size);};
138
  inline void setGPUPupSize(LDObjHandle h, size_t gpu_pup_size) { LbObj(h)->setGPUPupSize(gpu_pup_size);};
139
  inline void UseAsyncMigrate(LDObjHandle h, bool flag) { LbObj(h)->UseAsyncMigrate(flag); };
140
  inline int GetCommDataSz(void) {
141
    if (commTable)
142
      return commTable->CommCount();
143
    else return 0;
144
  }
145
146
  inline void GetCommData(LDCommData *data) {
147
    if (commTable) commTable->GetCommData(data);
148
  }
149
150
0
  inline void GetCommInfo(int& bytes, int& msgs, int& withinbytes, int& outsidebytes, int& num_nghbors, int& hops, int& hopbytes) {
151
0
    if (commTable)
152
0
      commTable->GetCommInfo(bytes, msgs, withinbytes, outsidebytes, num_nghbors, hops, hopbytes);
153
0
  }
154
155
156
  LDOMHandle RegisterOM(LDOMid userID, void *userptr, LDCallbacks cb);
157
  int Migrate(LDObjHandle h, int dest);
158
  void UnregisterOM(LDOMHandle omh);
159
  void RegisteringObjects(LDOMHandle omh);
160
  void DoneRegisteringObjects(LDOMHandle omh);
161
  int GetObjDataSz(void);
162
  void GetObjData(LDObjData *data);
163
  void MetaLBCallLBOnChares();
164
  void MetaLBResumeWaitingChares(int lb_period);
165
  void ClearLoads(void);
166
  int useMem(void);
167
  LDObjHandle RegisterObj(LDOMHandle omh, CmiUInt8 id, void* userPtr,
168
                          int migratable);
169
  void UnregisterObj(LDObjHandle h);
170
  void EstObjLoad(const LDObjHandle &h, double cpuload);
171
  void EstObjGPULoad(const LDObjHandle &h, double gpuload);
172
  void BackgroundLoad(LBRealType *walltime, LBRealType *cputime);
173
  void Send(const LDOMHandle &destOM, const CmiUInt8 &destID, unsigned int bytes, int destObjProc, int force = 0);
174
  void MulticastSend(const LDOMHandle &_om, CmiUInt8 *_ids, int _n, unsigned int _b, int _nMsgs=1);
175
  void GetTime(LBRealType *total_walltime, LBRealType *total_cputime,
176
               LBRealType *idletime, LBRealType *bg_walltime,
177
               LBRealType *bg_cputime);
178
  const std::vector<LBObjEntry>& getObjs() {return objs;}
179
180
  inline void ObjectStart(const LDObjHandle &h) {
181
    if (StatsOn()) {
182
      LbObj(h)->StartTimer();
183
    }
184
  };
185
186
  inline void ObjectStop(const LDObjHandle &h) {
187
    LBObj* const obj = LbObj(h);
188
189
    if (StatsOn()) {
190
      LBRealType walltime, cputime;
191
      obj->StopTimer(&walltime, &cputime);
192
      obj->IncrementTime(walltime, cputime);
193
      MeasuredObjTime(walltime, cputime);
194
    }
195
  };
196
  inline const LDObjHandle &GetObjHandle(int idx) {
197
    return LbObjIdx(idx)->GetLDObjHandle();
198
  }
199
  void CollectStatsOn(void);
200
  inline void CollectStatsOff(void) { TurnStatsOff(); };
201
  inline int  CollectingStats(void) {
202
  #if CMK_LBDB_ON
203
    return StatsOn();
204
  #else
205
    return 0;
206
  #endif
207
  };
208
};
209
210
#endif /* LBDATABASE_H */