Skip to content

Commit 558ee7d

Browse files
committed
#5: LB: add work model calculations
1 parent 13218b8 commit 558ee7d

File tree

3 files changed

+216
-59
lines changed

3 files changed

+216
-59
lines changed

src/vt-lb/algo/temperedlb/temperedlb.h

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#include <random>
5656
#include <ostream>
5757
#include <fstream>
58+
#include <cassert>
5859

5960
#include <mpi.h>
6061

@@ -70,6 +71,17 @@ struct WorkModel {
7071
/// @brief Coefficient for shared-memory communication component
7172
double delta = 0.0;
7273

74+
/// @brief Whether memory information is available
75+
bool has_memory_info = true;
76+
/// @brief Has task serialized memory info
77+
bool has_task_serialized_memory_info = true;
78+
/// @brief Has task working memory info
79+
bool has_task_working_memory_info = true;
80+
/// @brief Has task footprint memory info
81+
bool has_task_footprint_memory_info = true;
82+
/// @brief Has shared block memory info
83+
bool has_shared_block_memory_info = true;
84+
7385
double applyWorkFormula(
7486
double compute, double inter_comm_bytes, double intra_comm_bytes,
7587
double shared_comm_bytes
@@ -90,6 +102,20 @@ struct Configuration {
90102
k_max_ = std::ceil(std::sqrt(std::log(num_ranks)/std::log(2.0)));
91103
}
92104

105+
bool hasMemoryInfo() const { return work_model_.has_memory_info; }
106+
bool hasTaskSerializedMemoryInfo() const {
107+
return hasMemoryInfo() && work_model_.has_task_serialized_memory_info;
108+
}
109+
bool hasTaskWorkingMemoryInfo() const {
110+
return hasMemoryInfo() && work_model_.has_task_working_memory_info;
111+
}
112+
bool hasTaskFootprintMemoryInfo() const {
113+
return hasMemoryInfo() && work_model_.has_task_footprint_memory_info;
114+
}
115+
bool hasSharedBlockMemoryInfo() const {
116+
return hasMemoryInfo() && work_model_.has_shared_block_memory_info;
117+
}
118+
93119
/// @brief Number of trials to perform
94120
int num_trials_ = 1;
95121
/// @brief Number of iterations per trial
@@ -249,6 +275,31 @@ struct TaskClusterSummaryInfo {
249275
model::BytesType max_object_serialized_bytes = 0;
250276
model::BytesType max_object_serialized_bytes_outside = 0;
251277
model::BytesType cluster_footprint = 0;
278+
279+
template <typename SerializerT>
280+
void serializer(SerializerT& s) {
281+
s | cluster_id;
282+
s | num_tasks_;
283+
s | cluster_load;
284+
s | cluster_intra_send_bytes;
285+
s | cluster_intra_recv_bytes;
286+
s | inter_edges_;
287+
s | shared_block_bytes_;
288+
s | max_object_working_bytes;
289+
s | max_object_working_bytes_outside;
290+
s | max_object_serialized_bytes;
291+
s | max_object_serialized_bytes_outside;
292+
s | cluster_footprint;
293+
}
294+
};
295+
296+
struct WorkBreakdown {
297+
double compute = 0.0;
298+
double inter_node_recv_comm = 0.0;
299+
double inter_node_send_comm = 0.0;
300+
double intra_node_recv_comm = 0.0;
301+
double intra_node_send_comm = 0.0;
302+
double shared_mem_comm = 0.0;
252303
};
253304

254305
template <typename CommT>
@@ -347,6 +398,102 @@ struct TemperedLB : baselb::BaseLB {
347398

348399
Clusterer const* getClusterer() const { return clusterer_.get(); }
349400

401+
private:
402+
WorkBreakdown computeWorkBreakdown() const {
403+
WorkBreakdown breakdown;
404+
std::unordered_set<model::SharedBlockType> shared_blocks_here;
405+
406+
// Rank-alpha term
407+
for (auto const& [id, task] : this->getPhaseData().getTasksMap()) {
408+
breakdown.compute += task.getLoad();
409+
for (auto const& sb : task.getSharedBlocks()) {
410+
shared_blocks_here.insert(sb);
411+
}
412+
}
413+
414+
// Communication terms
415+
for (auto const& e : this->getPhaseData().getCommunications()) {
416+
assert(
417+
(e.getFromRank() == comm_.getRank() || e.getToRank() == comm_.getRank()) &&
418+
"Edge does not belong to this rank"
419+
);
420+
if (e.getFromRank() != e.getToRank()) {
421+
if (e.getToRank() == comm_.getRank()) {
422+
breakdown.inter_node_recv_comm += e.getVolume();
423+
} else {
424+
breakdown.inter_node_send_comm += e.getVolume();
425+
}
426+
} else {
427+
if (e.getToRank() == comm_.getRank()) {
428+
breakdown.intra_node_recv_comm += e.getVolume();
429+
} else {
430+
breakdown.intra_node_send_comm += e.getVolume();
431+
}
432+
}
433+
}
434+
435+
// Shared-memory communication term
436+
for (auto const& sb : shared_blocks_here) {
437+
assert(getPhaseData().hasSharedBlock(sb) && "Shared block information missing");
438+
auto info = getPhaseData().getSharedBlock(sb);
439+
if (info->getHome() != comm_.getRank()) {
440+
breakdown.shared_mem_comm += info->getSize();
441+
}
442+
}
443+
444+
return breakdown;
445+
}
446+
447+
double computeWork(WorkBreakdown breakdown) const {
448+
return config_.work_model_.applyWorkFormula(
449+
breakdown.compute,
450+
std::max(breakdown.inter_node_recv_comm, breakdown.inter_node_send_comm),
451+
std::max(breakdown.intra_node_recv_comm, breakdown.intra_node_send_comm),
452+
breakdown.shared_mem_comm
453+
);
454+
}
455+
456+
double computeMemoryUsage() const {
457+
if (!config_.hasMemoryInfo()) {
458+
return 0.0;
459+
}
460+
461+
double task_footprint_bytes_ = 0.0;
462+
double task_max_working_bytes_ = 0.0;
463+
double task_max_serialized_bytes_ = 0.0;
464+
double shared_blocks_bytes_ = 0.0;
465+
std::unordered_set<model::SharedBlockType> shared_blocks_here;
466+
for (auto const& [id, task] : this->getPhaseData().getTasksMap()) {
467+
if (config_.hasTaskFootprintMemoryInfo()) {
468+
task_footprint_bytes_ += task.getMemory().footprint_bytes;
469+
}
470+
if (config_.hasTaskWorkingMemoryInfo()) {
471+
task_max_working_bytes_ = std::max(
472+
task_max_working_bytes_, task.getMemory().working_bytes
473+
);
474+
}
475+
if (config_.hasTaskSerializedMemoryInfo()) {
476+
task_max_serialized_bytes_ = std::max(
477+
task_max_serialized_bytes_, task.getMemory().serialized_bytes
478+
);
479+
}
480+
if (config_.hasSharedBlockMemoryInfo()) {
481+
for (auto const& sb : task.getSharedBlocks()) {
482+
shared_blocks_here.insert(sb);
483+
}
484+
}
485+
}
486+
for (auto const& sb : shared_blocks_here) {
487+
assert(getPhaseData().hasSharedBlock(sb) && "Shared block information missing");
488+
auto info = getPhaseData().getSharedBlock(sb);
489+
shared_blocks_bytes_ += info->getSize();
490+
}
491+
return this->getPhaseData().getRankFootprintBytes() +
492+
task_footprint_bytes_ +
493+
task_max_working_bytes_ +
494+
shared_blocks_bytes_;
495+
}
496+
350497
private:
351498
void computeGlobalMaxClusters() {
352499
// compute max number of clusters on any rank

src/vt-lb/model/PhaseData.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ struct PhaseData {
8282
std::vector<Edge> const& getCommunications() const { return communications_; }
8383
std::unordered_map<SharedBlockType, SharedBlock> const& getSharedBlocksMap() const { return shared_blocks_; }
8484

85+
BytesType getRankFootprintBytes() const { return rank_footprint_bytes_; }
86+
void setRankFootprintBytes(BytesType bytes) { rank_footprint_bytes_ = bytes; }
87+
88+
BytesType getRankMaxMemoryAvailable() const { return rank_max_memory_available_; }
89+
void setRankMaxMemoryAvailable(BytesType bytes) { rank_max_memory_available_ = bytes; }
90+
8591
void clear() {
8692
tasks_.clear();
8793
communications_.clear();
@@ -94,13 +100,17 @@ struct PhaseData {
94100
s | tasks_;
95101
s | communications_;
96102
s | shared_blocks_;
103+
s | rank_footprint_bytes_;
104+
s | rank_max_memory_available_;
97105
}
98106

99107
private:
100108
RankType rank_ = invalid_node;
101109
std::unordered_map<TaskType, Task> tasks_;
102110
std::vector<Edge> communications_;
103111
std::unordered_map<SharedBlockType, SharedBlock> shared_blocks_;
112+
BytesType rank_footprint_bytes_ = 0.0;
113+
BytesType rank_max_memory_available_ = 0.0;
104114
};
105115

106116
} /* end namespace vt_lb::model */

src/vt-lb/model/Task.h

Lines changed: 59 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -51,74 +51,74 @@
5151
namespace vt_lb::model {
5252

5353
struct TaskMemory {
54-
TaskMemory() = default;
55-
TaskMemory(BytesType working, BytesType footprint, BytesType serialized)
56-
: working_(working), footprint_(footprint), serialized_(serialized)
57-
{}
58-
59-
BytesType getWorking() const { return working_; }
60-
BytesType getFootprint() const { return footprint_; }
61-
BytesType getSerialized() const { return serialized_; }
62-
63-
template <typename Serializer>
64-
void serialize(Serializer& s) {
65-
s | working_;
66-
s | footprint_;
67-
s | serialized_;
68-
}
54+
TaskMemory() = default;
55+
TaskMemory(BytesType working, BytesType footprint, BytesType serialized)
56+
: working_(working), footprint_(footprint), serialized_(serialized)
57+
{}
58+
59+
BytesType getWorking() const { return working_; }
60+
BytesType getFootprint() const { return footprint_; }
61+
BytesType getSerialized() const { return serialized_; }
62+
63+
template <typename Serializer>
64+
void serialize(Serializer& s) {
65+
s | working_;
66+
s | footprint_;
67+
s | serialized_;
68+
}
6969

7070
private:
71-
BytesType working_ = 0.0;
72-
BytesType footprint_ = 0.0;
73-
BytesType serialized_ = 0.0;
71+
BytesType working_ = 0.0;
72+
BytesType footprint_ = 0.0;
73+
BytesType serialized_ = 0.0;
7474
};
7575

7676
struct Task {
77-
Task() = default;
78-
Task(TaskType id, RankType home, RankType current, bool migratable,
79-
TaskMemory const& memory, LoadType load)
80-
: id_(id),
81-
home_(home),
82-
current_(current),
83-
migratable_(migratable),
84-
memory_(memory),
85-
load_(load)
86-
{}
87-
88-
TaskType getId() const { return id_; }
89-
RankType getHome() const { return home_; }
90-
RankType getCurrent() const { return current_; }
91-
bool isMigratable() const { return migratable_; }
92-
TaskMemory const& getMemory() const { return memory_; }
93-
LoadType getLoad() const { return load_; }
94-
95-
// Add accessors for shared blocks
96-
void addSharedBlock(SharedBlockType sb) { shared_blocks_.insert(sb); }
97-
std::unordered_set<SharedBlockType> const& getSharedBlocks() const { return shared_blocks_; }
98-
99-
template <typename Serializer>
100-
void serialize(Serializer& s) {
101-
s | id_;
102-
s | home_;
103-
s | current_;
104-
s | migratable_;
105-
s | memory_;
106-
s | load_;
107-
s | shared_blocks_;
108-
}
77+
Task() = default;
78+
Task(TaskType id, RankType home, RankType current, bool migratable,
79+
TaskMemory const& memory, LoadType load)
80+
: id_(id),
81+
home_(home),
82+
current_(current),
83+
migratable_(migratable),
84+
memory_(memory),
85+
load_(load)
86+
{}
87+
88+
TaskType getId() const { return id_; }
89+
RankType getHome() const { return home_; }
90+
RankType getCurrent() const { return current_; }
91+
bool isMigratable() const { return migratable_; }
92+
TaskMemory const& getMemory() const { return memory_; }
93+
LoadType getLoad() const { return load_; }
94+
95+
// Add accessors for shared blocks
96+
void addSharedBlock(SharedBlockType sb) { shared_blocks_.insert(sb); }
97+
std::unordered_set<SharedBlockType> const& getSharedBlocks() const { return shared_blocks_; }
98+
99+
template <typename Serializer>
100+
void serialize(Serializer& s) {
101+
s | id_;
102+
s | home_;
103+
s | current_;
104+
s | migratable_;
105+
s | memory_;
106+
s | load_;
107+
s | shared_blocks_;
108+
}
109109

110110
private:
111-
TaskType id_ = invalid_task;
112-
int home_ = invalid_node;
113-
int current_ = invalid_node;
114-
bool migratable_ = true;
115-
TaskMemory memory_;
116-
LoadType load_ = 0.0;
117-
std::unordered_set<SharedBlockType> shared_blocks_;
111+
TaskType id_ = invalid_task;
112+
int home_ = invalid_node;
113+
int current_ = invalid_node;
114+
bool migratable_ = true;
115+
TaskMemory memory_;
116+
LoadType load_ = 0.0;
117+
std::unordered_set<SharedBlockType> shared_blocks_;
118118

119119
public:
120-
bool operator==(const Task& other) const { return id_ == other.id_; }
121-
bool operator!=(const Task& other) const { return !(*this == other); }
120+
bool operator==(const Task& other) const { return id_ == other.id_; }
121+
bool operator!=(const Task& other) const { return !(*this == other); }
122122
};
123123

124124
} /* end namespace vt_lb::model */

0 commit comments

Comments
 (0)