From 06feac3238d4d8d4768416643f1b29722da1b8fa Mon Sep 17 00:00:00 2001 From: Nicole Lemaster Slattengren Date: Tue, 3 May 2022 15:37:42 -0700 Subject: [PATCH] #1129: tests: WIP --- tests/unit/phase/test_subphase_management.cc | 399 +++++++++++++++++++ 1 file changed, 399 insertions(+) create mode 100644 tests/unit/phase/test_subphase_management.cc diff --git a/tests/unit/phase/test_subphase_management.cc b/tests/unit/phase/test_subphase_management.cc new file mode 100644 index 0000000000..76dc9b89dc --- /dev/null +++ b/tests/unit/phase/test_subphase_management.cc @@ -0,0 +1,399 @@ +/* +//@HEADER +// ***************************************************************************** +// +// test_subphase_management.cc +// DARMA/vt => Virtual Transport +// +// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC +// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. +// Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact darma@sandia.gov +// +// ***************************************************************************** +//@HEADER +*/ + +#include + +#include "test_parallel_harness.h" +#include "test_helpers.h" + +#include +#include + +#if vt_check_enabled(lblite) + +namespace vt { namespace tests { namespace unit { namespace subphase { + +static constexpr int const num_elms = 32; +static constexpr int const num_phases = 3; + +// FIXME: the lines below are temporary, to make these tests compile until we +// implement the new functionality +template +void runSubphaseCollective(Callable&& fn) { + runInEpochCollective(std::forward(fn)); +} + +struct MyCol : vt::Collection { + MyCol() = default; + + explicit MyCol(checkpoint::SERIALIZE_CONSTRUCT_TAG) {} + + vt::PhaseType getPhase() { return this->getLBData().getPhase(); } + + vt::PhaseType getSubphase() { return this->getLBData().getSubPhase(); } +}; + +struct MyMsg : vt::CollectionMessage { + explicit MyMsg(vt::PhaseType expected_subphase) { + expected_subphase_ = expected_subphase; + } + + vt::PhaseType expected_subphase_ = vt::no_lb_phase; +}; + +void colHandler(MyMsg* msg, MyCol* col) { + //fmt::print( + // "running colHandler: idx={}, phase={}, subphase={}\n", + // col->getIndex(), col->getPhase(), col->getSubphase() + //); + EXPECT_EQ(col->getSubphase(), msg->expected_subphase_); +} + +struct MyObjgrp { + MyObjgrp() = default; + MyObjgrp(const MyObjgrp& obj) = delete; + MyObjgrp& operator=(const MyObjgrp& obj) = delete; + MyObjgrp(MyObjgrp&&) noexcept = default; + MyObjgrp& operator=(MyObjgrp&& obj) noexcept = default; + ~MyObjgrp() = default; + + void handler(MyMsg* msg) { } +}; + +using TestSubphaseManagement = TestParallelHarness; + +TEST_F(TestSubphaseManagement, test_no_subphases) { + auto range = vt::Index1D(num_elms); + + auto this_node = theContext()->getNode(); + + auto o_proxy = vt::theObjGroup()->makeCollective(); + + auto c_proxy = vt::makeCollection() + .bounds(range) + .bulkInsert() + .wait(); + + PhaseType n_subphases = 0; + for (int phase = 0; phase < num_phases; phase++) { + PhaseType expected_subphase = 0; + + runInEpochCollective([&]{ + if (this_node == 0) { + c_proxy.broadcast(expected_subphase); + o_proxy.broadcast(expected_subphase); + } + }); + + runInEpochCollective([&]{ + if (this_node == 0) { + c_proxy.broadcast(expected_subphase); + o_proxy.broadcast(expected_subphase); + } + }); + + runInEpochCollective([&]{ + if (this_node == 0) { + c_proxy.broadcast(expected_subphase); + o_proxy.broadcast(expected_subphase); + } + }); + + if (phase == 0) { + n_subphases = expected_subphase + 1; + } else { + EXPECT_EQ(n_subphases, expected_subphase + 1); + } + + // Go to the next phase. + vt::thePhase()->nextPhaseCollective(); + + auto lbdh = theNodeLBData()->getLBData(); + ASSERT_TRUE(lbdh->node_data_.find(phase) != lbdh->node_data_.end()); + auto &phase_data = lbdh->node_data_.at(phase); + for (auto &obj_data : phase_data) { + EXPECT_EQ(obj_data.second.subphase_loads.size(), n_subphases); + } + } +} + +TEST_F(TestSubphaseManagement, test_subphase_collective_1) { + auto range = vt::Index1D(num_elms); + + auto this_node = theContext()->getNode(); + + auto o_proxy = vt::theObjGroup()->makeCollective(); + + auto c_proxy = vt::makeCollection() + .bounds(range) + .bulkInsert() + .wait(); + + PhaseType n_subphases = 0; + for (int phase = 0; phase < num_phases; phase++) { + PhaseType expected_subphase = 0; + + runSubphaseCollective([&]{ + if (this_node == 0) { + c_proxy.broadcast(expected_subphase); + o_proxy.broadcast(expected_subphase); + } + }); + ++expected_subphase; + + runSubphaseCollective([&]{ + if (this_node == 0) { + c_proxy.broadcast(expected_subphase); + o_proxy.broadcast(expected_subphase); + c_proxy.broadcast(expected_subphase); + o_proxy.broadcast(expected_subphase); + } + }); + ++expected_subphase; + + runSubphaseCollective([&]{ + if (this_node == 0) { + c_proxy.broadcast(expected_subphase); + o_proxy.broadcast(expected_subphase); + } + }); + ++expected_subphase; + + if (phase == 0) { + n_subphases = expected_subphase; + } else { + EXPECT_EQ(n_subphases, expected_subphase); + } + + // Go to the next phase. + vt::thePhase()->nextPhaseCollective(); + + auto lbdh = theNodeLBData()->getLBData(); + ASSERT_TRUE(lbdh->node_data_.find(phase) != lbdh->node_data_.end()); + auto &phase_data = lbdh->node_data_.at(phase); + for (auto &obj_data : phase_data) { + EXPECT_EQ(obj_data.second.subphase_loads.size(), n_subphases); + } + } +} + +TEST_F(TestSubphaseManagement, test_subphase_collective_mixed_1) { + auto range = vt::Index1D(num_elms); + + auto this_node = theContext()->getNode(); + + auto o_proxy = vt::theObjGroup()->makeCollective(); + + auto c_proxy = vt::makeCollection() + .bounds(range) + .bulkInsert() + .wait(); + + PhaseType n_subphases = 0; + for (int phase = 0; phase < num_phases; phase++) { + PhaseType expected_subphase = 0; + + runSubphaseCollective([&]{ + if (this_node == 0) { + c_proxy.broadcast(expected_subphase); + o_proxy.broadcast(expected_subphase); + } + }); + ++expected_subphase; + + runInEpochCollective([&]{ + if (this_node == 0) { + c_proxy.broadcast(expected_subphase); + o_proxy.broadcast(expected_subphase); + c_proxy.broadcast(expected_subphase); + o_proxy.broadcast(expected_subphase); + } + }); + + runSubphaseCollective([&]{ + if (this_node == 0) { + c_proxy.broadcast(expected_subphase); + o_proxy.broadcast(expected_subphase); + } + }); + ++expected_subphase; + + if (phase == 0) { + n_subphases = expected_subphase; + } else { + EXPECT_EQ(n_subphases, expected_subphase); + } + + // Go to the next phase. + vt::thePhase()->nextPhaseCollective(); + + auto lbdh = theNodeLBData()->getLBData(); + ASSERT_TRUE(lbdh->node_data_.find(phase) != lbdh->node_data_.end()); + auto &phase_data = lbdh->node_data_.at(phase); + for (auto &obj_data : phase_data) { + EXPECT_EQ(obj_data.second.subphase_loads.size(), n_subphases); + } + } +} + +TEST_F(TestSubphaseManagement, test_subphase_collective_nested_1) { + auto range = vt::Index1D(num_elms); + + auto this_node = theContext()->getNode(); + + auto o_proxy = vt::theObjGroup()->makeCollective(); + + auto c_proxy = vt::makeCollection() + .bounds(range) + .bulkInsert() + .wait(); + + PhaseType n_subphases = 0; + for (int phase = 0; phase < num_phases; phase++) { + PhaseType expected_subphase = 0; + + runSubphaseCollective([&]{ + if (this_node == 0) { + c_proxy.broadcast(expected_subphase); + } + }); + ++expected_subphase; + + runInEpochCollective([&]{ + runSubphaseCollective([&]{ + if (this_node == 0) { + c_proxy.broadcast(expected_subphase); + o_proxy.broadcast(expected_subphase); + c_proxy.broadcast(expected_subphase); + o_proxy.broadcast(expected_subphase); + } + }); + ++expected_subphase; + + runSubphaseCollective([&]{ + if (this_node == 0) { + c_proxy.broadcast(expected_subphase); + o_proxy.broadcast(expected_subphase); + } + }); + ++expected_subphase; + }); + + runSubphaseCollective([&]{ + if (this_node == 0) { + c_proxy.broadcast(expected_subphase); + o_proxy.broadcast(expected_subphase); + } + }); + ++expected_subphase; + + if (phase == 0) { + n_subphases = expected_subphase; + } else { + EXPECT_EQ(n_subphases, expected_subphase); + } + + // Go to the next phase. + vt::thePhase()->nextPhaseCollective(); + + auto lbdh = theNodeLBData()->getLBData(); + ASSERT_TRUE(lbdh->node_data_.find(phase) != lbdh->node_data_.end()); + auto &phase_data = lbdh->node_data_.at(phase); + for (auto &obj_data : phase_data) { + EXPECT_EQ(obj_data.second.subphase_loads.size(), n_subphases); + } + } +} + +TEST_F(TestSubphaseManagement, test_chainset_no_subphases) { + auto range = vt::Index1D(num_elms); + + auto c_proxy = vt::makeCollection() + .bounds(range) + .bulkInsert() + .wait(); + + std::unique_ptr> chains + = std::make_unique>(c_proxy); + + PhaseType n_subphases = 0; + for (int phase = 0; phase < num_phases; phase++) { + PhaseType expected_subphase = 0; + + runInEpochCollective([&]{ + chains->nextStepCollective("first", [=](vt::Index1D idx) { + return c_proxy(idx).template send(expected_subphase); + }); + + chains->nextStepCollective("second", [=](vt::Index1D idx) { + return c_proxy(idx).template send(expected_subphase); + }); + + chains->nextStepCollective("third", [=](vt::Index1D idx) { + return c_proxy(idx).template send(expected_subphase); + }); + + chains->phaseDone(); + }); + + if (phase == 0) { + n_subphases = expected_subphase + 1; + } else { + EXPECT_EQ(n_subphases, expected_subphase + 1); + } + + // Go to the next phase. + vt::thePhase()->nextPhaseCollective(); + + auto lbdh = theNodeLBData()->getLBData(); + ASSERT_TRUE(lbdh->node_data_.find(phase) != lbdh->node_data_.end()); + auto &phase_data = lbdh->node_data_.at(phase); + for (auto &obj_data : phase_data) { + EXPECT_EQ(obj_data.second.subphase_loads.size(), n_subphases); + } + } +} + +}}}} // end namespace vt::tests::unit::subphase + +#endif /*vt_check_enabled(lblite)*/