Skip to content

Commit

Permalink
Merge pull request #1001 from DARMA-tasking/959-add-unit-tests-for-lo…
Browse files Browse the repository at this point in the history
…ad-models

959 Add more tests for various load models Part 1
  • Loading branch information
lifflander authored Aug 31, 2020
2 parents 4dff5cc + 1ca4c6b commit 350e064
Show file tree
Hide file tree
Showing 6 changed files with 571 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/vt/vrt/collection/balance/model/composed_model.cc
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ int ComposedModel::getNumObjects() {
}

int ComposedModel::getNumCompletedPhases() {
return base_->getNumSubphases();
return base_->getNumCompletedPhases();
}

int ComposedModel::getNumSubphases() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ TimeType PersistenceMedianLastN::getWork(ElementIDType object, PhaseOffset when)
std::sort(times.begin(), times.end());

if (phases % 2 == 1)
return times[phases / 2 + 1];
return times[phases / 2];
else
return (times[phases / 2] + times[phases / 2 + 1]) / 2;
return (times[phases / 2 - 1] + times[phases / 2]) / 2;
}

}}}}
155 changes: 155 additions & 0 deletions tests/unit/collection/test_model_linear_model.nompi.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/*
//@HEADER
// *****************************************************************************
//
// test_model_linear_model.nompi
// DARMA Toolkit v. 1.0.0
// DARMA/vt => Virtual Transport
//
// Copyright 2019 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 <vt/transport.h>
#include <vt/vrt/collection/balance/model/load_model.h>
#include <vt/vrt/collection/balance/model/linear_model.h>

#include <gtest/gtest.h>

#include "test_harness.h"

#include <memory>

namespace vt { namespace tests { namespace unit {

using TestLinearModel = TestHarness;

static int32_t num_phases = 1;

using vt::vrt::collection::balance::CommMapType;
using vt::vrt::collection::balance::ElementIDType;
using vt::vrt::collection::balance::LinearModel;
using vt::vrt::collection::balance::LoadMapType;
using vt::vrt::collection::balance::LoadModel;
using vt::vrt::collection::balance::ObjectIterator;
using vt::vrt::collection::balance::PhaseOffset;
using vt::vrt::collection::balance::SubphaseLoadMapType;

struct StubModel : LoadModel {

StubModel() = default;
virtual ~StubModel() = default;

void setLoads(
std::vector<LoadMapType> const* proc_load,
std::vector<SubphaseLoadMapType> const*,
std::vector<CommMapType> const*) override {
proc_load_ = proc_load;
}

void updateLoads(PhaseType) override {}

TimeType getWork(ElementIDType id, PhaseOffset phase) override {
// Most recent phase will be at the end of vector
return proc_load_->at(num_phases + phase.phases).at(id);
}

virtual ObjectIterator begin() override {
return ObjectIterator(proc_load_->back().begin());
}
virtual ObjectIterator end() override {
return ObjectIterator(proc_load_->back().end());
}

virtual int getNumObjects() override { return 2; }
virtual int getNumCompletedPhases() override { return num_phases; }
virtual int getNumSubphases() override { return 1; }

private:
std::vector<LoadMapType> const* proc_load_ = nullptr;
};

TEST_F(TestLinearModel, test_model_linear_model_1) {
constexpr int32_t num_test_interations = 6;

auto test_model =
std::make_shared<LinearModel>(std::make_shared<StubModel>(), 4);

// For linear regression there needs to be at least 2 phases completed
// so we begin with 1 phase already done
std::vector<LoadMapType> proc_loads{LoadMapType{
{ElementIDType{1}, TimeType{10}}, {ElementIDType{2}, TimeType{40}}}};
test_model->setLoads(&proc_loads, nullptr, nullptr);

// Work loads to be added in each test iteration
std::vector<LoadMapType> load_holder{
LoadMapType{
{ElementIDType{1}, TimeType{5}}, {ElementIDType{2}, TimeType{10}}},
LoadMapType{
{ElementIDType{1}, TimeType{30}}, {ElementIDType{2}, TimeType{100}}},
LoadMapType{
{ElementIDType{1}, TimeType{50}}, {ElementIDType{2}, TimeType{40}}},
LoadMapType{
{ElementIDType{1}, TimeType{2}}, {ElementIDType{2}, TimeType{50}}},
LoadMapType{
{ElementIDType{1}, TimeType{60}}, {ElementIDType{2}, TimeType{20}}},
LoadMapType{
{ElementIDType{1}, TimeType{100}}, {ElementIDType{2}, TimeType{10}}},
};

std::array<std::pair<TimeType, TimeType>, num_test_interations> expected_data{
std::make_pair(TimeType{0}, TimeType{-20}), // iter 0 results
std::make_pair(TimeType{35}, TimeType{110}), // iter 1 results
std::make_pair(TimeType{60}, TimeType{70}), // iter 2 results
std::make_pair(TimeType{24.5}, TimeType{65}), // iter 3 results
std::make_pair(TimeType{46}, TimeType{-5}), // iter 4 results
std::make_pair(TimeType{105}, TimeType{0}) // iter 5 results
};

for (auto iter = 0; iter < num_test_interations; ++iter) {
proc_loads.push_back(load_holder[iter]);
++num_phases;

for (auto&& obj : *test_model) {
auto work_val = test_model->getWork(obj, PhaseOffset{});
EXPECT_EQ(
work_val,
obj == 1 ? expected_data[iter].first : expected_data[iter].second)
<< fmt::format("Test failed on iteration {}", iter);
}
}
}

}}} // end namespace vt::tests::unit
126 changes: 126 additions & 0 deletions tests/unit/collection/test_model_multiple_phases.nompi.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
//@HEADER
// *****************************************************************************
//
// test_model_multiple_phases.nompi
// DARMA Toolkit v. 1.0.0
// DARMA/vt => Virtual Transport
//
// Copyright 2019 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 <vt/transport.h>
#include <vt/vrt/collection/balance/model/load_model.h>
#include <vt/vrt/collection/balance/model/multiple_phases.h>

#include <gtest/gtest.h>

#include "test_harness.h"

#include <memory>

namespace vt { namespace tests { namespace unit {

using TestModelMultiplePhases = TestHarness;

using vt::vrt::collection::balance::ElementIDType;
using vt::vrt::collection::balance::LoadModel;
using vt::vrt::collection::balance::MultiplePhases;
using vt::vrt::collection::balance::PhaseOffset;
using vt::vrt::collection::balance::LoadMapType;
using vt::vrt::collection::balance::SubphaseLoadMapType;
using vt::vrt::collection::balance::CommMapType;
using vt::vrt::collection::balance::ObjectIterator;

struct StubModel : LoadModel {

StubModel() = default;
virtual ~StubModel() = default;

void setLoads(
std::vector<LoadMapType> const* proc_load,
std::vector<SubphaseLoadMapType> const*,
std::vector<CommMapType> const*) override {
proc_load_ = proc_load;
}

void updateLoads(PhaseType) override {}

TimeType getWork(ElementIDType id, PhaseOffset phase) override {
// Here we return predicted loads for future phases
// For the sake of the test we use values from the past phases
return proc_load_->at(phase.phases).at(id);
}

virtual ObjectIterator begin() override {
return ObjectIterator(proc_load_->back().begin());
}
virtual ObjectIterator end() override {
return ObjectIterator(proc_load_->back().end());
}

// Not used by this test
virtual int getNumObjects() override { return 0; }
virtual int getNumCompletedPhases() override { return 0; }
virtual int getNumSubphases() override { return 0; }

private:
std::vector<LoadMapType> const* proc_load_ = nullptr;
};

TEST_F(TestModelMultiplePhases, test_model_multiple_phases_1) {
std::vector<LoadMapType> proc_loads = {
LoadMapType{
{ElementIDType{1}, TimeType{10}}, {ElementIDType{2}, TimeType{40}}},
LoadMapType{
{ElementIDType{1}, TimeType{20}}, {ElementIDType{2}, TimeType{30}}},
LoadMapType{
{ElementIDType{1}, TimeType{30}}, {ElementIDType{2}, TimeType{10}}},
LoadMapType{
{ElementIDType{1}, TimeType{40}}, {ElementIDType{2}, TimeType{5}}}};

auto test_model =
std::make_shared<MultiplePhases>(std::make_shared<StubModel>(), 4);

test_model->setLoads(&proc_loads, nullptr, nullptr);

for (auto&& obj : *test_model) {
auto work_val = test_model->getWork(obj, PhaseOffset{});
EXPECT_EQ(work_val, obj == 1 ? TimeType{100} : TimeType{85});
}
}

}}} // end namespace vt::tests::unit
Loading

0 comments on commit 350e064

Please sign in to comment.