From cf2a7c6a685a2a56113882f9cf278849e315fd32 Mon Sep 17 00:00:00 2001 From: Martin Quinson Date: Mon, 15 May 2017 00:03:15 +0200 Subject: [PATCH 1/1] tmgr: make a usefull datatype public --- src/surf/cpu_ti.cpp | 26 ++++++------ src/surf/trace_mgr.cpp | 66 ++++++++++++++++++---------- src/surf/trace_mgr.hpp | 33 ++++++++------ src/surf/trace_mgr_test.cpp | 85 +++++++++++++++---------------------- 4 files changed, 112 insertions(+), 98 deletions(-) diff --git a/src/surf/cpu_ti.cpp b/src/surf/cpu_ti.cpp index 21ca9d7ab6..8dc0926b71 100644 --- a/src/surf/cpu_ti.cpp +++ b/src/surf/cpu_ti.cpp @@ -37,8 +37,8 @@ CpuTiTrace::CpuTiTrace(tmgr_trace_t speedTrace) for (auto val : speedTrace->event_list) { timePoints_[i] = time; integral_[i] = integral; - integral += val.delta * val.value; - time += val.delta; + integral += val.date_ * val.value_; + time += val.date_; i++; } timePoints_[i] = time; @@ -237,8 +237,8 @@ double CpuTiTgmr::getPowerScale(double a) { double reduced_a = a - floor(a / lastTime_) * lastTime_; int point = trace_->binarySearch(trace_->timePoints_, reduced_a, 0, trace_->nbPoints_ - 1); - s_tmgr_event_t val = speedTrace_->event_list.at(point); - return val.value; + trace_mgr::DatedValue val = speedTrace_->event_list.at(point); + return val.value_; } /** @@ -264,9 +264,9 @@ CpuTiTgmr::CpuTiTgmr(tmgr_trace_t speedTrace, double value) : /* only one point available, fixed trace */ if (speedTrace->event_list.size() == 1) { - s_tmgr_event_t val = speedTrace->event_list.front(); + trace_mgr::DatedValue val = speedTrace->event_list.front(); type_ = TRACE_FIXED; - value_ = val.value; + value_ = val.value_; return; } @@ -274,7 +274,7 @@ CpuTiTgmr::CpuTiTgmr(tmgr_trace_t speedTrace, double value) : /* count the total time of trace file */ for (auto val : speedTrace->event_list) - total_time += val.delta; + total_time += val.date_; trace_ = new CpuTiTrace(speedTrace); lastTime_ = total_time; @@ -422,8 +422,8 @@ void CpuTi::setSpeedTrace(tmgr_trace_t trace) /* add a fake trace event if periodicity == 0 */ if (trace && trace->event_list.size() > 1) { - s_tmgr_event_t val = trace->event_list.back(); - if (val.delta < 1e-12) + trace_mgr::DatedValue val = trace->event_list.back(); + if (val.date_ < 1e-12) speed_.event = future_evt_set->add_trace(tmgr_empty_trace_new(), this); } } @@ -441,12 +441,12 @@ void CpuTi::apply_event(tmgr_trace_event_t event, double value) modified(true); speedTrace = speedIntegratedTrace_->speedTrace_; - s_tmgr_event_t val = speedTrace->event_list.back(); + trace_mgr::DatedValue val = speedTrace->event_list.back(); delete speedIntegratedTrace_; - speed_.scale = val.value; + speed_.scale = val.value_; - trace = new CpuTiTgmr(TRACE_FIXED, val.value); - XBT_DEBUG("value %f", val.value); + trace = new CpuTiTgmr(TRACE_FIXED, val.value_); + XBT_DEBUG("value %f", val.value_); speedIntegratedTrace_ = trace; diff --git a/src/surf/trace_mgr.cpp b/src/surf/trace_mgr.cpp index 7d8c400278..b9fdbb9796 100644 --- a/src/surf/trace_mgr.cpp +++ b/src/surf/trace_mgr.cpp @@ -23,21 +23,41 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_trace, surf, "Surf trace management"); -static std::unordered_map trace_list; +namespace tmgr = simgrid::trace_mgr; -simgrid::trace_mgr::trace::trace()=default; -simgrid::trace_mgr::trace::~trace()=default; -simgrid::trace_mgr::future_evt_set::future_evt_set()=default; +static std::unordered_map trace_list; +static inline bool doubleEq(double d1, double d2) +{ + return fabs(d1 - d2) < 0.0001; +} +namespace simgrid { +namespace trace_mgr { + +bool DatedValue::operator==(DatedValue e2) +{ + return (doubleEq(date_, e2.date_)) && (doubleEq(value_, e2.value_)); +} +std::ostream& operator<<(std::ostream& out, const DatedValue& e) +{ + out << e.date_ << " " << e.value_; + return out; +} + +trace::trace() = default; +trace::~trace() = default; +future_evt_set::future_evt_set() = default; simgrid::trace_mgr::future_evt_set::~future_evt_set() { xbt_heap_free(p_heap); } +} +} tmgr_trace_t tmgr_trace_new_from_string(const char* name, std::string input, double periodicity) { int linecount = 0; - tmgr_event_t last_event = nullptr; // last event seen + tmgr::DatedValue* last_event; xbt_assert(trace_list.find(name) == trace_list.end(), "Refusing to define trace %s twice", name); @@ -46,7 +66,7 @@ tmgr_trace_t tmgr_trace_new_from_string(const char* name, std::string input, dou std::vector list; boost::split(list, input, boost::is_any_of("\n\r")); for (auto val : list) { - s_tmgr_event_t event; + tmgr::DatedValue event; linecount++; boost::trim(val); if (val[0] == '#' || val[0] == '\0' || val[0] == '%') // pass comments @@ -56,27 +76,29 @@ tmgr_trace_t tmgr_trace_new_from_string(const char* name, std::string input, dou if (sscanf(val.c_str(), "WAITFOR %lg\n", &periodicity) == 1) continue; - xbt_assert(sscanf(val.c_str(), "%lg %lg\n", &event.delta, &event.value) == 2, "%s:%d: Syntax error in trace\n%s", + xbt_assert(sscanf(val.c_str(), "%lg %lg\n", &event.date_, &event.value_) == 2, "%s:%d: Syntax error in trace\n%s", name, linecount, input.c_str()); if (last_event) { - xbt_assert(last_event->delta <= event.delta, + xbt_assert(last_event->date_ <= event.date_, "%s:%d: Invalid trace: Events must be sorted, but time %g > time %g.\n%s", name, linecount, - last_event->delta, event.delta, input.c_str()); + last_event->date_, event.date_, input.c_str()); - last_event->delta = event.delta - last_event->delta; + last_event->date_ = event.date_ - last_event->date_; } else { /* Add the first fake event storing the time at which the trace begins */ - s_tmgr_event_t first_event; - first_event.delta = event.delta; - first_event.value = -1.0; + tmgr::DatedValue first_event(event.date_, -1.0); trace->event_list.push_back(first_event); } trace->event_list.push_back(event); last_event = &(trace->event_list.back()); } if (last_event) { - last_event->delta = periodicity > 0 ? periodicity + trace->event_list.at(0).delta : -1; + if (periodicity > 0) { + last_event->date_ = periodicity + trace->event_list.at(0).date_; + } else { + last_event->date_ = -1; + } } trace_list.insert({xbt_strdup(name), trace}); @@ -104,10 +126,8 @@ tmgr_trace_t tmgr_trace_new_from_file(const char *filename) tmgr_trace_t tmgr_empty_trace_new() { tmgr_trace_t trace = new simgrid::trace_mgr::trace(); - s_tmgr_event_t event; - event.delta = 0.0; - event.value = 0.0; - trace->event_list.push_back(event); + tmgr::DatedValue val(0, 0); + trace->event_list.push_back(val); return trace; } @@ -158,15 +178,15 @@ tmgr_trace_event_t simgrid::trace_mgr::future_evt_set::pop_leq(double date, doub tmgr_trace_t trace = trace_iterator->trace; *resource = trace_iterator->resource; - tmgr_event_t event = &(trace->event_list.at(trace_iterator->idx)); + tmgr::DatedValue dateVal = trace->event_list.at(trace_iterator->idx); - *value = event->value; + *value = dateVal.value_; if (trace_iterator->idx < trace->event_list.size() - 1) { - xbt_heap_push(p_heap, trace_iterator, event_date + event->delta); + xbt_heap_push(p_heap, trace_iterator, event_date + dateVal.date_); trace_iterator->idx++; - } else if (event->delta > 0) { /* Last element. Shall we loop? */ - xbt_heap_push(p_heap, trace_iterator, event_date + event->delta); + } else if (dateVal.date_ > 0) { /* Last element. Shall we loop? */ + xbt_heap_push(p_heap, trace_iterator, event_date + dateVal.date_); trace_iterator->idx = 1; /* idx=0 is a placeholder to store when events really start */ } else { /* If we don't loop, we don't need this trace_event anymore */ trace_iterator->free_me = 1; diff --git a/src/surf/trace_mgr.hpp b/src/surf/trace_mgr.hpp index 902ee0934e..5e19d547ce 100644 --- a/src/surf/trace_mgr.hpp +++ b/src/surf/trace_mgr.hpp @@ -13,11 +13,6 @@ SG_BEGIN_DECL() -typedef struct tmgr_event { - double delta; - double value; -} s_tmgr_event_t, *tmgr_event_t; - /* Iterator within a trace */ typedef struct tmgr_trace_event { tmgr_trace_t trace; @@ -48,17 +43,31 @@ SG_END_DECL() #ifdef __cplusplus namespace simgrid { -/** @brief Modeling of the resource variations, such as those due to an external load +/** @brief Modeling of the availability profile (due to an external load) or the churn * - * There is 3 main concepts in this module: - * - #trace: a set of dated values, ie a list of pair - * - #trace_iterator: links a given trace to a given simgrid resource. A Cpu for example has 2 iterators: state (ie, is it ON/OFF) and speed, while a link has 3 iterators: state, bandwidth and latency. + * There is 4 main concepts in this module: + * - #DatedValue: a pair (both are of type double) + * - #trace: a list of dated values + * - #trace_event: links a given trace to a given SimGrid resource. + * A Cpu for example has 2 kinds of events: state (ie, is it ON/OFF) and speed, + * while a link has 3 iterators: state, bandwidth and latency. * - #future_evt_set: makes it easy to find the next occuring event of all traces */ - namespace trace_mgr { +namespace trace_mgr { +XBT_PUBLIC_CLASS DatedValue +{ +public: + double date_ = 0; + double value_ = 0; + explicit DatedValue() = default; + explicit DatedValue(double d, double v) : date_(d), value_(v) {} + bool operator==(DatedValue e2); + bool operator!=(DatedValue e2) { return !(*this == e2); } +}; +std::ostream& operator<<(std::ostream& out, const DatedValue& e); /** @brief A trace_iterator links a trace to a resource */ -XBT_PUBLIC_CLASS trace_iterator { +XBT_PUBLIC_CLASS trace_event{ }; @@ -73,7 +82,7 @@ public: trace(); virtual ~trace(); //private: - std::vector event_list; + std::vector event_list; }; /** @brief Future Event Set (collection of iterators over the traces) diff --git a/src/surf/trace_mgr_test.cpp b/src/surf/trace_mgr_test.cpp index 81e3a23f39..30c53c6ef8 100644 --- a/src/surf/trace_mgr_test.cpp +++ b/src/surf/trace_mgr_test.cpp @@ -13,6 +13,8 @@ namespace utf = boost::unit_test; #include "src/surf/surf_interface.hpp" #include "src/surf/trace_mgr.hpp" +namespace tmgr = simgrid::trace_mgr; + #include "xbt/log.h" #include "xbt/misc.h" @@ -31,30 +33,13 @@ public: bool isUsed() { return true; } }; -static inline bool doubleEq(double d1, double d2) -{ - return fabs(d1 - d2) < 0.0001; -} -class Evt { -public: - double date; - double value; - explicit Evt(double d, double v) : date(d), value(v) {} - bool operator==(Evt e2) { return (doubleEq(date, e2.date)) && (doubleEq(value, e2.value)); } - bool operator!=(Evt e2) { return !(*this == e2); } -}; -static std::ostream& operator<<(std::ostream& out, const Evt& e) -{ - out << e.date << " " << e.value; - return out; -} - -static void trace2vector(const char* str, std::vector* whereto) +static void trace2vector(const char* str, std::vector* whereto) { simgrid::trace_mgr::trace* trace = tmgr_trace_new_from_string("TheName", str, 0); + XBT_VERB("---------------------------------------------------------"); XBT_VERB("data>>\n%s<event_list) - XBT_VERB("event: d:%lg v:%lg", evt.delta, evt.value); + XBT_VERB("event: d:%lg v:%lg", evt.date_, evt.value_); MockedResource daResource; simgrid::trace_mgr::future_evt_set fes; @@ -71,7 +56,7 @@ static void trace2vector(const char* str, std::vector* whereto) BOOST_CHECK_EQUAL(it, insertedIt); // Check that we find what we've put if (value >= 0) { res->apply_event(it, value); - whereto->push_back(Evt(thedate, value)); + whereto->push_back(tmgr::DatedValue(thedate, value)); } else { XBT_DEBUG("%.1f: ignore an event (idx: %d)\n", thedate, it->idx); } @@ -87,76 +72,76 @@ BOOST_AUTO_TEST_CASE(no_evt_noloop) { }*/ BOOST_AUTO_TEST_CASE(one_evt_noloop) { - std::vector got; + std::vector got; trace2vector("9.0 3.0\n", &got); - std::vector want; - want.push_back(Evt(9, 3)); + std::vector want; + want.push_back(tmgr::DatedValue(9, 3)); BOOST_CHECK_EQUAL_COLLECTIONS(want.begin(), want.end(), got.begin(), got.end()); } BOOST_AUTO_TEST_CASE(two_evt_noloop) { - std::vector got; + std::vector got; trace2vector("3.0 1.0\n" "9.0 3.0\n", &got); - std::vector want; - want.push_back(Evt(3, 1)); - want.push_back(Evt(9, 3)); + std::vector want; + want.push_back(tmgr::DatedValue(3, 1)); + want.push_back(tmgr::DatedValue(9, 3)); BOOST_CHECK_EQUAL_COLLECTIONS(want.begin(), want.end(), got.begin(), got.end()); } BOOST_AUTO_TEST_CASE(three_evt_noloop) { - std::vector got; + std::vector got; trace2vector("3.0 1.0\n" "5.0 2.0\n" "9.0 3.0\n", &got); - std::vector want; - want.push_back(Evt(3, 1)); - want.push_back(Evt(5, 2)); - want.push_back(Evt(9, 3)); + std::vector want; + want.push_back(tmgr::DatedValue(3, 1)); + want.push_back(tmgr::DatedValue(5, 2)); + want.push_back(tmgr::DatedValue(9, 3)); BOOST_CHECK_EQUAL_COLLECTIONS(want.begin(), want.end(), got.begin(), got.end()); } BOOST_AUTO_TEST_CASE(two_evt_loop) { - std::vector got; + std::vector got; trace2vector("1.0 1.0\n" "3.0 3.0\n" "WAITFOR 2\n", &got); - std::vector want; - want.push_back(Evt(1, 1)); - want.push_back(Evt(3, 3)); - want.push_back(Evt(6, 1)); - want.push_back(Evt(8, 3)); - want.push_back(Evt(11, 1)); - want.push_back(Evt(13, 3)); - want.push_back(Evt(16, 1)); - want.push_back(Evt(18, 3)); + std::vector want; + want.push_back(tmgr::DatedValue(1, 1)); + want.push_back(tmgr::DatedValue(3, 3)); + want.push_back(tmgr::DatedValue(6, 1)); + want.push_back(tmgr::DatedValue(8, 3)); + want.push_back(tmgr::DatedValue(11, 1)); + want.push_back(tmgr::DatedValue(13, 3)); + want.push_back(tmgr::DatedValue(16, 1)); + want.push_back(tmgr::DatedValue(18, 3)); BOOST_CHECK_EQUAL_COLLECTIONS(want.begin(), want.end(), got.begin(), got.end()); } BOOST_AUTO_TEST_CASE(two_evt_start0_loop) { - std::vector got; + std::vector got; trace2vector("0.0 1\n" "5.0 2\n" "WAITFOR 5\n", &got); - std::vector want; - want.push_back(Evt(0, 1)); - want.push_back(Evt(5, 2)); - want.push_back(Evt(10, 1)); - want.push_back(Evt(15, 2)); - want.push_back(Evt(20, 1)); + std::vector want; + want.push_back(tmgr::DatedValue(0, 1)); + want.push_back(tmgr::DatedValue(5, 2)); + want.push_back(tmgr::DatedValue(10, 1)); + want.push_back(tmgr::DatedValue(15, 2)); + want.push_back(tmgr::DatedValue(20, 1)); BOOST_CHECK_EQUAL_COLLECTIONS(want.begin(), want.end(), got.begin(), got.end()); } -- 2.20.1