Coverage Report

Created: 2026-10-29 22:51

/home/runner/work/charm/charm/src/ck-ldb/GreedyRefineCentralGPULB.h
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * \addtogroup CkLdb
3
*/
4
/*@{*/
5
6
/**
7
 * Two-level GPU-aware variant of GreedyRefineCentralLB.
8
 *
9
 * Objects are balanced at two granularities:
10
 *   - Across GPU groups (the set of PEs that share a gpu_device_id, i.e. the
11
 *     PEs of a process bound to one GPU): balanced by GPU load (gpuTime).
12
 *   - Within a GPU group, across that group's PEs: balanced by CPU load
13
 *     (wallTime).
14
 *
15
 * This matches a setup where each process owns a GPU. The coarse decision of
16
 * which GPU/process an object lands on is driven by the object's GPU work; the
17
 * fine decision of which PE inside that process runs the object's host-side
18
 * code is driven by its CPU work.
19
 *
20
 * Inherits the greedy-refine migration-minimization machinery and the
21
 * concurrent multi-parameter solution search from GreedyRefineCentralLB.
22
 *
23
 * supports processor avail bitvector
24
 * supports nonmigratable attrib
25
*/
26
27
#ifndef _GREEDY_REFINE_GPU_LB_H_
28
#define _GREEDY_REFINE_GPU_LB_H_
29
30
#include "CentralLB.h"
31
#include "GreedyRefineCentralGPULB.decl.h"
32
33
#include <algorithm>
34
35
void CreateGreedyRefineCentralGPULB();
36
BaseLB *AllocateGreedyRefineCentralGPULB();
37
38
#define __DEBUG_GREEDY_REFINE_GPU_ 0
39
40
class GreedyRefineCentralGPULB : public CBase_GreedyRefineCentralGPULB {
41
public:
42
  GreedyRefineCentralGPULB(const CkLBOptions &);
43
  GreedyRefineCentralGPULB(CkMigrateMessage *m);
44
  void work(LDStats* stats);
45
  void receiveSolutions(CkReductionMsg *msg);
46
  void receiveTotalTime(double time);
47
0
  void setMigrationTolerance(float tol) { migrationTolerance = tol; }
48
49
private:
50
0
  bool QueryBalanceNow(int step) { return true; }
51
52
  class GProc {
53
  public:
54
0
    GProc() : available(true), load(0), bgload(0), cpuLoad(0), bg_walltime(0) {}
55
    int id;
56
    bool available;
57
    int pos;    // position in min heap
58
    double load;       // GPU load accumulator (used by non-CUDA PE-level path)
59
    double bgload;     // background GPU load (group level under CUDA)
60
    double cpuLoad;    // CPU/wall load accumulator for within-group balancing
61
    double bg_walltime;
62
    float speed;
63
  };
64
65
  class GObj {
66
  public:
67
    int id;
68
    double load;     // GPU load (gpuTime) — drives cross-group assignment
69
    double cpuLoad;  // CPU load (wallTime) — drives within-group PE assignment
70
    int oldPE;
71
  };
72
73
  class ObjLoadGreater {
74
  public:
75
0
    inline bool operator() (const GObj *o1, const GObj *o2) const {
76
#if CMK_CUDA
77
      // Greedy packing is only as good as its ordering: placing the largest
78
      // items first is what keeps the bins even. Placement here is scored on
79
      // both dimensions, so order by whichever one binds for each object.
80
      // Ordering on GPU time alone leaves the CPU dimension in essentially
81
      // arbitrary order, which packs it worse than not moving anything at all.
82
      return std::max(o1->load, o1->cpuLoad) > std::max(o2->load, o2->cpuLoad);
83
#else
84
0
      return (o1->load > o2->load);
85
0
#endif
86
0
    }
87
  };
88
89
  class PHeap;
90
  class Solution;
91
92
  double fillData(LDStats *stats,
93
                  std::vector<GObj> &objs,
94
                  std::vector<GObj*> &pobjs,
95
                  std::vector<GProc> &procs,
96
                  PHeap &procHeap);
97
98
  double greedyLB(const std::vector<GObj*> &pobjs, PHeap &procHeap, const BaseLB::LDStats *stats) const;
99
  void sendSolution(double maxLoad, int migrations);
100
101
  double strategyStartTime;
102
  double totalObjLoad;
103
  int availablePes;
104
  float migrationTolerance;
105
  int totalObjs;
106
107
#if __DEBUG_GREEDY_REFINE_GPU_
108
  void dumpObjLoads(std::vector<GObj> &objs);
109
  void dumpProcLoads(std::vector<GProc> &procs);
110
#endif
111
};
112
113
#endif
114
115
/*@}*/