From a9ec85f7e77055172f234af80c5cd6c3c717a016 Mon Sep 17 00:00:00 2001 From: Caleb Schilly Date: Fri, 6 Sep 2024 14:05:26 -0400 Subject: [PATCH] #2342: add communications to LBDataHolder test --- .../vrt/collection/balance/lb_data_holder.cc | 62 ++++--- tests/unit/lb/test_lb_data_holder.cc | 173 ++++++++++++------ 2 files changed, 148 insertions(+), 87 deletions(-) diff --git a/src/vt/vrt/collection/balance/lb_data_holder.cc b/src/vt/vrt/collection/balance/lb_data_holder.cc index cfebb9f4a5..9430d84ebb 100644 --- a/src/vt/vrt/collection/balance/lb_data_holder.cc +++ b/src/vt/vrt/collection/balance/lb_data_holder.cc @@ -50,7 +50,8 @@ namespace vt { namespace vrt { namespace collection { namespace balance { void get_object_from_json_field_( - const nlohmann::json& field, nlohmann::json& object, bool& is_bitpacked) { + const nlohmann::json& field, nlohmann::json& object, bool& is_bitpacked, + bool& is_collection) { if (field.find("id") != field.end()) { object = field["id"]; is_bitpacked = true; @@ -58,11 +59,16 @@ void get_object_from_json_field_( object = field["seq_id"]; is_bitpacked = false; } + if (field.find("collection_id") != field.end()) { + is_collection = true; + } else { + is_collection = false; + } } ElementIDStruct get_elm_from_object_info_( const nlohmann::json& object, bool is_bitpacked, bool is_migratable, - const nlohmann::json& home, const nlohmann::json& node) { + const nlohmann::json& home) { using Field = uint64_t; Field object_id; @@ -75,28 +81,25 @@ ElementIDStruct get_elm_from_object_info_( } return elm::ElmIDBits::createCollectionImpl( - is_migratable, object_id, home, node); + is_migratable, object_id, home, theContext()->getNode()); } ElementIDStruct -get_elm_from_comm_object_(const nlohmann::json& field, bool collection) { +get_elm_from_comm_object_(const nlohmann::json& field) { // Get the object's id and determine if it is bit-encoded nlohmann::json object; bool is_bitpacked; - get_object_from_json_field_(field, object, is_bitpacked); + bool is_collection; + get_object_from_json_field_(field, object, is_bitpacked, is_collection); vtAssertExpr(object.is_number()); // Create elm with encoded data ElementIDStruct elm; - - if (collection) { - // TODO: need to get actual object data - int home = 0; - int node = 0; - bool is_migratable = false; - + if (is_collection) { + int home = field["home"]; + bool is_migratable = field["migratable"]; elm = get_elm_from_object_info_( - object, is_bitpacked, is_migratable, home, node); + object, is_bitpacked, is_migratable, home); } else { elm = ElementIDStruct{object, theContext()->getNode()}; } @@ -104,7 +107,6 @@ get_elm_from_comm_object_(const nlohmann::json& field, bool collection) { return elm; } - void LBDataHolder::outputEntity(nlohmann::json& j, ElementIDStruct const& id) const { j["type"] = "object"; j["id"] = id.id; @@ -359,23 +361,23 @@ LBDataHolder::LBDataHolder(nlohmann::json const& j) if (etype == "object") { nlohmann::json object; - bool is_bitpacked; - get_object_from_json_field_(task["entity"], object, is_bitpacked); + bool is_bitpacked, is_collection; + get_object_from_json_field_(task["entity"], object, is_bitpacked, is_collection); vtAssertExpr(object.is_number()); + // Creating elm from `tasks` field ElementIDStruct elm; - - if ( - task["entity"].find("collection_id") != task["entity"].end() and - task["entity"].find("index") != task["entity"].end()) { + if (is_collection) { elm = get_elm_from_object_info_( - object, is_bitpacked, is_migratable, home, node); + object, is_bitpacked, is_migratable, home); auto cid = task["entity"]["collection_id"]; - auto idx = task["entity"]["index"]; - if (cid.is_number() && idx.is_array()) { - std::vector arr = idx; - auto proxy = static_cast(cid); - this->node_idx_[elm] = std::make_tuple(proxy, arr); + if (task["entity"].find("index") != task["entity"].end()) { + auto idx = task["entity"]["index"]; + if (cid.is_number() && idx.is_array()) { + std::vector arr = idx; + auto proxy = static_cast(cid); + this->node_idx_[elm] = std::make_tuple(proxy, arr); + } } } else { elm = ElementIDStruct{object, node}; @@ -449,8 +451,8 @@ LBDataHolder::LBDataHolder(nlohmann::json const& j) // TODO: passing false here (and below) avoids encoding // any information into the obj ids, which preserves // the original behavior - auto from_elm = get_elm_from_comm_object_(comm["from"], false); - auto to_elm = get_elm_from_comm_object_(comm["to"], false); + auto from_elm = get_elm_from_comm_object_(comm["from"]); + auto to_elm = get_elm_from_comm_object_(comm["to"]); CommKey key( CommKey::CollectionTag{}, @@ -467,7 +469,7 @@ LBDataHolder::LBDataHolder(nlohmann::json const& j) auto from_node = comm["from"]["id"]; vtAssertExpr(from_node.is_number()); - auto to_elm = get_elm_from_comm_object_(comm["to"], false); + auto to_elm = get_elm_from_comm_object_(comm["to"]); CommKey key( CommKey::NodeToCollectionTag{}, @@ -482,7 +484,7 @@ LBDataHolder::LBDataHolder(nlohmann::json const& j) vtAssertExpr(comm["from"]["type"] == "object"); vtAssertExpr(comm["to"]["type"] == "node"); - auto from_elm = get_elm_from_comm_object_(comm["from"], false); + auto from_elm = get_elm_from_comm_object_(comm["from"]); auto to_node = comm["to"]["id"]; vtAssertExpr(to_node.is_number()); diff --git a/tests/unit/lb/test_lb_data_holder.cc b/tests/unit/lb/test_lb_data_holder.cc index 4494123ff4..10542714a6 100644 --- a/tests/unit/lb/test_lb_data_holder.cc +++ b/tests/unit/lb/test_lb_data_holder.cc @@ -45,75 +45,134 @@ #include #include -#include "test_harness.h" +#include "test_parallel_harness.h" #include namespace vt { namespace tests { namespace unit { namespace lb { -using TestLBDataHolder = TestHarness; - -nlohmann::json create_basic_json(std::string id_type, int id, - int home, int node, bool is_migratable) { - nlohmann::json j = { - {"metadata", { - {"rank", 0}, - {"type", "LBDatafile"} - }}, - {"phases", { - { - {"id", 0}, - {"tasks", { - { - {"entity", { - {"collection_id", 7}, - {"index", {0}}, - {"home", home}, - {id_type, id}, - {"migratable", is_migratable}, - {"type", "object"} - }}, - {"node", node}, - {"resource", "cpu"}, - {"time", 0.5}, - } - }} - } - }} - }; - - return j; +using TestLBDataHolder = TestParallelHarness; +using LBDataHolder = vt::vrt::collection::balance::LBDataHolder; + +nlohmann::json create_entity_(std::string id_type, int id, int home, bool is_migratable) { + nlohmann::json entity = { + {id_type, id}, + {"type", "object"}, + {"collection_id", 7}, + {"index", {0}}, + {"home", home}, + {"migratable", is_migratable}, + }; + return entity; } -void test_data_holder_elms(int seq_id, int home, int node, bool is_migratable) { - // Determine encoded ID - auto elm = elm::ElmIDBits::createCollectionImpl(is_migratable, seq_id, home, node); - auto encoded_id = elm.id; +nlohmann::json create_json_( + std::string id_type, int id_1, int id_2, int home, int node, + bool is_migratable) { + + auto entity_1 = create_entity_(id_type, id_1, home, is_migratable); + auto entity_2 = create_entity_(id_type, id_2, home, is_migratable); + + // Generate JSON + nlohmann::json j = { + {"metadata", {{"rank", 0}, {"type", "LBDatafile"}}}, + {"phases", + {{{"communications", + {{{"bytes", 2.0}, + {"from", entity_1}, + {"messages", 1}, + {"to", entity_2}, + {"type", "SendRecv"}}}}, + {"id", 0}, + {"tasks", + { + { + {"entity", entity_1}, + {"node", node}, + {"resource", "cpu"}, + {"time", 0.5}, + }, + { + {"entity", entity_2}, + {"node", node}, + {"resource", "cpu"}, + {"time", 0.5}, + } + } + }}} + } + }; + + return j; +} + +void test_data_holder_elms(int seq_id_1, int home, int node, bool is_migratable) { + // Create a second seq_id + auto seq_id_2 = seq_id_1 + 1; + + // Determine encoded ID + auto elm_1 = + elm::ElmIDBits::createCollectionImpl(is_migratable, seq_id_1, home, node); + auto encoded_id_1 = elm_1.id; + + // Create second encoded ID + auto elm_2 = + elm::ElmIDBits::createCollectionImpl(is_migratable, seq_id_2, home, node); + auto encoded_id_2 = elm_2.id; + + // Create DataHolder and get resulting object elm + auto simple_json_id = create_json_( + "id", encoded_id_1, encoded_id_2, home, node, is_migratable); + auto dh_id = LBDataHolder(simple_json_id); + + // Create new DataHolder using "seq_id" and get elm + auto simple_json_seq = + create_json_("seq_id", seq_id_1, seq_id_2, home, node, is_migratable); + auto dh_seq = LBDataHolder(simple_json_seq); + + // Find both elms in each DataHolder + auto it_id_1 = dh_id.node_data_[0].find(elm_1); + auto it_seq_1 = dh_seq.node_data_[0].find(elm_1); + auto it_id_2 = dh_id.node_data_[0].find(elm_2); + auto it_seq_2 = dh_seq.node_data_[0].find(elm_2); + + // Assert that both elms exist + ASSERT_NE(it_id_1, dh_id.node_data_[0].end()); + ASSERT_NE(it_seq_1, dh_seq.node_data_[0].end()); + ASSERT_NE(it_id_2, dh_id.node_data_[0].end()); + ASSERT_NE(it_seq_2, dh_seq.node_data_[0].end()); + + // Compare the the elms in each DataHolder + EXPECT_EQ(it_id_1->first, elm_1); + EXPECT_EQ(it_seq_1->first, elm_1); + EXPECT_EQ(it_id_2->first, elm_2); + EXPECT_EQ(it_seq_2->first, elm_2); - // Create DataHolder and get resulting object elm - auto simple_json_id = create_basic_json("id", encoded_id, home, node, is_migratable); - auto dh_id = vt::vrt::collection::balance::LBDataHolder(simple_json_id); - auto elm_id = dh_id.node_data_[0].begin()->first; + // Check the communication data + auto comm_id = dh_id.node_comm_[0]; + auto comm_key_id = comm_id.begin()->first; + auto comm_seq = dh_seq.node_comm_[0]; + auto comm_key_seq = comm_seq.begin()->first; - // Create new DataHolder using "seq_id" and get elm - auto simple_json_seq = create_basic_json("seq_id", seq_id, home, node, is_migratable); - auto dh_seq = vt::vrt::collection::balance::LBDataHolder(simple_json_seq); - auto elm_seq = dh_seq.node_data_[0].begin()->first; + // Ensure that we get the same CommKey from both id types + EXPECT_EQ(comm_key_id, comm_key_seq); - // Assert that both elms are equal (have the same id) - EXPECT_EQ(elm_id, elm_seq); - EXPECT_EQ(elm_id, elm); + // Assert that both elms are present in the communication data + EXPECT_EQ(comm_key_id.fromObj(), elm_1); + EXPECT_EQ(comm_key_id.toObj(), elm_2); + EXPECT_EQ(comm_key_seq.fromObj(), elm_1); + EXPECT_EQ(comm_key_seq.toObj(), elm_2); } -TEST_F(TestLBDataHolder, test_lb_data_holder_no_comms_object_id) { - // Run a variety of test cases (seq_id, home, node, is_migratable) - test_data_holder_elms(0,0,0,false); - test_data_holder_elms(0,0,0,true); - test_data_holder_elms(0,0,2,false); - test_data_holder_elms(0,0,1,true); - test_data_holder_elms(1,1,0,false); - test_data_holder_elms(2,1,9,true); - test_data_holder_elms(3,0,1,false); +TEST_F(TestLBDataHolder, test_lb_data_holder_object_id) { + // Run a variety of test cases (seq_id, home, node, is_migratable) + test_data_holder_elms(0, 0, 0, false); + test_data_holder_elms(0, 0, 0, true); + test_data_holder_elms(0, 0, 2, false); + test_data_holder_elms(0, 0, 1, true); + test_data_holder_elms(1, 1, 0, false); + test_data_holder_elms(2, 1, 1, true); + test_data_holder_elms(3, 0, 1, false); } }}}} // end namespace vt::tests::unit::lb