Skip to content

Commit

Permalink
Merge pull request #2137 from DARMA-tasking/2130-spec-for-skipped-pha…
Browse files Browse the repository at this point in the history
…ses-2

#2130: Add spec for skipped and identical phases
  • Loading branch information
nlslatt authored May 16, 2023
2 parents fd7501a + 526a6ed commit 522945b
Show file tree
Hide file tree
Showing 5 changed files with 346 additions and 1 deletion.
11 changes: 11 additions & 0 deletions scripts/JSON_data_files_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ def _get_valid_schema(self) -> Schema:
'rank': int,
'num_nodes': int,
},
Optional('phases'): {
'count': int,
'skipped': {
'list': [int],
'range': [[int]],
},
'identical_to_previous': {
'list': [int],
'range': [[int]],
},
},
},
'phases': [
{
Expand Down
113 changes: 112 additions & 1 deletion src/vt/vrt/collection/balance/lb_data_holder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,63 @@ void LBDataHolder::outputEntity(nlohmann::json& j, ElementIDStruct const& id) co
}
}

std::unique_ptr<nlohmann::json> LBDataHolder::metadataToJson() const {
// Find last element of a range for which it's values are incremented by 1
auto find_last_of_range = [](
const std::set<PhaseType>& notEmptySet,
std::set<PhaseType>::iterator fromIt) {
vtAssert(!notEmptySet.empty(), "Input Set must be not empty");

do {
auto next = std::next(fromIt);
// end of a set or range
if (next == notEmptySet.end() || *fromIt + 1 != *next) {
break;
}
++fromIt;
} while (fromIt != notEmptySet.end());

return fromIt;
};

nlohmann::json j;
j["count"] = count_;

// Generate list and ranges of skipped phases
std::set<PhaseType> skipped_list;
std::vector<std::pair<PhaseType, PhaseType>> skipped_ranges;
for (auto it = skipped_phases_.begin(); it != skipped_phases_.end(); it++) {
auto endOfRange = find_last_of_range(skipped_phases_, it);
if (it == endOfRange) {
skipped_list.insert(*it);
} else {
skipped_ranges.emplace_back(*it, *endOfRange);
it = endOfRange;
}
}

// Generate list and ranges of identical phases
std::set<PhaseType> identical_list;
std::vector<std::pair<PhaseType, PhaseType>> identical_ranges;
for (auto it = identical_phases_.begin(); it != identical_phases_.end();
it++) {
auto endOfRange = find_last_of_range(identical_phases_, it);
if (it == endOfRange) {
identical_list.insert(*it);
} else {
identical_ranges.emplace_back(*it, *endOfRange);
it = endOfRange;
}
}

// Save metadata
j["skipped"]["list"] = skipped_list;
j["skipped"]["range"] = skipped_ranges;
j["identical_to_previous"]["list"] = identical_list;
j["identical_to_previous"]["range"] = identical_ranges;
return std::make_unique<nlohmann::json>(std::move(j));
}

std::unique_ptr<nlohmann::json> LBDataHolder::toJson(PhaseType phase) const {
using json = nlohmann::json;

Expand Down Expand Up @@ -164,9 +221,14 @@ std::unique_ptr<nlohmann::json> LBDataHolder::toJson(PhaseType phase) const {
return std::make_unique<json>(std::move(j));
}

LBDataHolder::LBDataHolder(nlohmann::json const& j) {
LBDataHolder::LBDataHolder(nlohmann::json const& j)
: count_(0)
{
auto this_node = theContext()->getNode();

// read metadata for skipped and identical phases
readMetadata(j);

auto phases = j["phases"];
if (phases.is_array()) {
for (auto const& phase : phases) {
Expand Down Expand Up @@ -303,15 +365,64 @@ LBDataHolder::LBDataHolder(nlohmann::json const& j) {
}
}

if (!count_) {
count_ = node_data_.size();
}

// @todo: implement subphase communication de-serialization, no use for it
// right now, so it will be ignored
}

void LBDataHolder::readMetadata(nlohmann::json const& j) {
auto metadata = j["metadata"];
if (metadata.find("phases") != metadata.end()) {
auto phases = metadata["phases"];
// load count
vtAssertExpr(phases["count"].is_number());
count_ = phases["count"];
// load all skipped phases
auto sl = phases["skipped"]["list"];
if(sl.is_array()) {
for(PhaseType skipped : sl) {
skipped_phases_.insert(skipped);
}
}
auto sr = phases["skipped"]["range"];
if(sr.is_array()) {
for(auto const& pair : sr) {
vtAssertExpr(pair.is_array());
for(PhaseType i = pair[0]; i <= pair[1]; i++){
skipped_phases_.insert(i);
}
}
}
// load all identical phases
auto il = phases["identical_to_previous"]["list"];
if(il.is_array()) {
for(PhaseType identical : il) {
identical_phases_.insert(identical);
}
}
auto ir = phases["identical_to_previous"]["range"];
if(ir.is_array()) {
for(auto const& pair : ir) {
vtAssertExpr(pair.is_array());
for(PhaseType i = pair[0]; i <= pair[1]; i++){
identical_phases_.insert(i);
}
}
}
}
}

void LBDataHolder::clear() {
node_comm_.clear();
node_data_.clear();
node_subphase_comm_.clear();
node_idx_.clear();
count_ = 0;
skipped_phases_.clear();
identical_phases_.clear();
}

}}}} /* end namespace vt::vrt::collection::balance */
23 changes: 23 additions & 0 deletions src/vt/vrt/collection/balance/lb_data_holder.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ struct LBDataHolder {
s | node_subphase_comm_;
s | user_defined_json_;
s | node_idx_;
s | count_;
s | skipped_phases_;
s | identical_phases_;
}

/**
Expand All @@ -89,6 +92,13 @@ struct LBDataHolder {
*/
std::unique_ptr<nlohmann::json> toJson(PhaseType phase) const;

/**
* \brief Output a LB phase's metdadata to JSON
*
* \return the json data structure
*/
std::unique_ptr<nlohmann::json> metadataToJson() const;

/**
* \brief Clear all LB data
*/
Expand All @@ -103,6 +113,13 @@ struct LBDataHolder {
*/
void outputEntity(nlohmann::json& j, ElementIDStruct const& elm_id) const;

/**
* \brief Read the LB phase's metadata
*
* \param[in] j the json
*/
void readMetadata(nlohmann::json const& j);

public:
/// Node timings for each local object
std::unordered_map<PhaseType, LoadMapType> node_data_;
Expand All @@ -118,6 +135,12 @@ struct LBDataHolder {
std::unordered_map<ElementIDStruct, std::tuple<VirtualProxyType, std::vector<uint64_t>>> node_idx_;
/// Map from id to objgroup proxy
std::unordered_map<ElementIDStruct, ObjGroupProxyType> node_objgroup_;
// Number of all phases including skipped and identical
PhaseType count_;
// Set of phases that are skipped
std::set<PhaseType> skipped_phases_;
// Set of phases which are identical to previous
std::set<PhaseType> identical_phases_;
};

}}}} /* end namespace vt::vrt::collection::balance */
Expand Down
4 changes: 4 additions & 0 deletions src/vt/vrt/collection/balance/node_lb_data.cc
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,10 @@ void NodeLBData::createLBDataFile() {
}
metadata["type"] = "LBDatafile";
metadata["rank"] = theContext()->getNode();
auto phasesMetadata = lb_data_->metadataToJson();
if(phasesMetadata) {
metadata["phases"] = *phasesMetadata;
}
lb_data_writer_ = std::make_unique<JSONAppender>(
"phases", metadata, file_name, compress
);
Expand Down
Loading

0 comments on commit 522945b

Please sign in to comment.