1 /* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */
3 /* This program is free software; you can redistribute it and/or modify it
4 * under the terms of the license (GNU LGPL) which comes with this package. */
6 #include "src/3rd-party/catch.hpp"
8 #include "simgrid/kernel/ProfileBuilder.hpp"
9 #include "src/kernel/resource/Resource.hpp"
10 #include "src/kernel/resource/profile/Event.hpp"
11 #include "src/kernel/resource/profile/StochasticDatedValue.hpp"
15 #include "xbt/random.hpp"
19 XBT_LOG_NEW_DEFAULT_CATEGORY(unit, "Unit tests of the Trace Manager");
21 class MockedResource : public simgrid::kernel::resource::Resource {
23 static double the_date;
25 explicit MockedResource() : Resource("fake"){}
26 void apply_event(simgrid::kernel::profile::Event* event, double value) override
28 XBT_VERB("t=%.1f: Change value to %lg (idx: %u)", the_date, value, event->idx);
29 tmgr_trace_event_unref(&event);
31 bool is_used() const override { return true; }
34 double MockedResource::the_date;
36 static std::vector<simgrid::kernel::profile::DatedValue> trace2vector(const char* str)
38 std::vector<simgrid::kernel::profile::DatedValue> res;
39 simgrid::kernel::profile::Profile* trace = simgrid::kernel::profile::ProfileBuilder::from_string("TheName", str, 0);
40 XBT_VERB("---------------------------------------------------------");
41 XBT_VERB("data>>\n%s<<data\n", str);
42 for (auto const& evt : trace->get_event_list())
43 XBT_VERB("event: d:%lg v:%lg", evt.date_, evt.value_);
45 MockedResource daResource;
46 simgrid::kernel::profile::FutureEvtSet fes;
47 simgrid::kernel::profile::Event* insertedIt = trace->schedule(&fes, &daResource);
49 while (fes.next_date() <= 20.0 && fes.next_date() >= 0) {
50 MockedResource::the_date = fes.next_date();
52 simgrid::kernel::resource::Resource* resource;
53 simgrid::kernel::profile::Event* it = fes.pop_leq(MockedResource::the_date, &value, &resource);
57 REQUIRE(it == insertedIt); // Check that we find what we've put
59 res.emplace_back(MockedResource::the_date, value);
61 XBT_DEBUG("%.1f: ignore an event (idx: %u)\n", MockedResource::the_date, it->idx);
63 resource->apply_event(it, value);
69 TEST_CASE("kernel::profile: Resource profiles, defining the external load", "kernel::profile")
71 SECTION("No event, no loop")
73 std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("");
74 std::vector<simgrid::kernel::profile::DatedValue> want;
78 SECTION("One event no loop")
80 std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("9.0 3.0\n");
82 std::vector<simgrid::kernel::profile::DatedValue> want;
83 want.emplace_back(9, 3);
87 SECTION("Two events, no loop")
89 std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("3.0 1.0\n"
92 std::vector<simgrid::kernel::profile::DatedValue> want;
93 want.emplace_back(3, 1);
94 want.emplace_back(9, 3);
99 SECTION("Three events, no loop")
101 std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("3.0 1.0\n"
105 std::vector<simgrid::kernel::profile::DatedValue> want;
106 want.emplace_back(3, 1);
107 want.emplace_back(5, 2);
108 want.emplace_back(9, 3);
110 REQUIRE(want == got);
113 SECTION("Two events, looping")
115 std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("1.0 1.0\n"
119 std::vector<simgrid::kernel::profile::DatedValue> want;
120 want.emplace_back(1, 1);
121 want.emplace_back(3, 3);
122 want.emplace_back(6, 1);
123 want.emplace_back(8, 3);
124 want.emplace_back(11, 1);
125 want.emplace_back(13, 3);
126 want.emplace_back(16, 1);
127 want.emplace_back(18, 3);
129 REQUIRE(want == got);
132 SECTION("Two events, looping, start at 0")
134 std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("0.0 1\n"
138 std::vector<simgrid::kernel::profile::DatedValue> want;
139 want.emplace_back(0, 1);
140 want.emplace_back(5, 2);
141 want.emplace_back(10, 1);
142 want.emplace_back(15, 2);
143 want.emplace_back(20, 1);
145 REQUIRE(want == got);
148 SECTION("One stochastic event (parsing)")
150 using simgrid::kernel::profile::Distribution;
151 std::vector<simgrid::kernel::profile::StochasticDatedValue> got = trace2selist("STOCHASTIC\n"
154 std::vector<simgrid::kernel::profile::StochasticDatedValue> want;
155 want.emplace_back(Distribution::DET, std::vector<double>{0}, Distribution::UNIF, std::vector<double>{10, 20});
157 REQUIRE(want == got);
160 SECTION("Several stochastic events (all possible parsing forms)")
162 using simgrid::kernel::profile::Distribution;
163 std::vector<simgrid::kernel::profile::StochasticDatedValue> got = trace2selist("STOCHASTIC\n"
165 "NORMAL 25 10 DET 3\n"
166 "UNIF 10 20 NORMAL 25 10\n"
169 std::vector<simgrid::kernel::profile::StochasticDatedValue> want;
170 want.emplace_back(Distribution::DET, std::vector<double>{0}, Distribution::DET, std::vector<double>{4});
171 want.emplace_back(Distribution::NORM, std::vector<double>{25, 10}, Distribution::DET, std::vector<double>{3});
172 want.emplace_back(Distribution::UNIF, std::vector<double>{10, 20}, Distribution::NORM, std::vector<double>{25, 10});
173 want.emplace_back(Distribution::DET, std::vector<double>{5}, Distribution::UNIF, std::vector<double>{5, 25});
175 REQUIRE(want == got);
178 SECTION("Two stochastic events (drawing each distribution)")
180 simgrid::xbt::random::set_implem_xbt();
181 simgrid::xbt::random::set_mersenne_seed(12345);
182 std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("STOCHASTIC\n"
184 "EXP 0.05 NORMAL 15 5");
186 std::vector<simgrid::kernel::profile::DatedValue> want;
187 // The following values were drawn using the XBT_RNG_xbt method /outside/ the testcase.
188 want.emplace_back(0, 19.29616086867082813683);
189 want.emplace_back(2.32719992449416279712, 20.16807234800742065772);
191 REQUIRE(want == got);
194 SECTION("Two stochastic events, with a loop")
196 simgrid::xbt::random::set_implem_xbt();
197 simgrid::xbt::random::set_mersenne_seed(12345);
198 std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("STOCHASTIC LOOP\n"
200 "EXP 0.05 NORMAL 15 5\n"
203 // In this case, the main use of the last stochastic event is to set when the first event takes place.
205 std::vector<simgrid::kernel::profile::DatedValue> want;
206 want.emplace_back(0, 19.29616086867082813683);
207 want.emplace_back(2.32719992449416279712, 20.16807234800742065772);
208 want.emplace_back(3.51111873684917075167, 0);
209 want.emplace_back(3.51111873684917075167, 10.39759496468994726115);
211 REQUIRE(want == got);