Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' into stoprofiles
[simgrid.git] / src / kernel / resource / profile / Profile_test.cpp
1 /* Copyright (c) 2017-2019. The SimGrid Team. All rights reserved.               */
2
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. */
5
6 #include "catch.hpp"
7
8 #include "simgrid/kernel/resource/Resource.hpp"
9 #include "src/kernel/resource/profile/DatedValue.hpp"
10 #include "src/kernel/resource/profile/Event.hpp"
11 #include "src/kernel/resource/profile/Profile.hpp"
12 #include "src/kernel/resource/profile/StochasticDatedValue.hpp"
13 #include "src/surf/surf_interface.hpp"
14
15 #include "xbt/log.h"
16 #include "xbt/misc.h"
17 #include "xbt/random.hpp"
18
19 #include <cmath>
20
21 XBT_LOG_NEW_DEFAULT_CATEGORY(unit, "Unit tests of the Trace Manager");
22
23 double thedate;
24 class MockedResource : public simgrid::kernel::resource::Resource {
25 public:
26   explicit MockedResource() : simgrid::kernel::resource::Resource(nullptr, "fake", nullptr) {}
27   void apply_event(simgrid::kernel::profile::Event* event, double value) override
28   {
29     XBT_VERB("t=%.1f: Change value to %lg (idx: %u)", thedate, value, event->idx);
30     tmgr_trace_event_unref(&event);
31   }
32   bool is_used() override { return true; }
33 };
34
35 static std::vector<simgrid::kernel::profile::DatedValue> trace2vector(const char* str)
36 {
37   std::vector<simgrid::kernel::profile::DatedValue> res;
38   simgrid::kernel::profile::Profile* trace = simgrid::kernel::profile::Profile::from_string("TheName", str, 0);
39   XBT_VERB("---------------------------------------------------------");
40   XBT_VERB("data>>\n%s<<data\n", str);
41   for (auto const& evt : trace->event_list)
42     XBT_VERB("event: d:%lg v:%lg", evt.date_, evt.value_);
43
44   MockedResource daResource;
45   simgrid::kernel::profile::FutureEvtSet fes;
46   simgrid::kernel::profile::Event* insertedIt = trace->schedule(&fes, &daResource);
47
48   while (fes.next_date() <= 20.0 && fes.next_date() >= 0) {
49     thedate = fes.next_date();
50     double value;
51     simgrid::kernel::resource::Resource* resource;
52     simgrid::kernel::profile::Event* it = fes.pop_leq(thedate, &value, &resource);
53     if (it == nullptr)
54       continue;
55
56     REQUIRE(it == insertedIt); // Check that we find what we've put
57     if (value >= 0) {
58       res.push_back(simgrid::kernel::profile::DatedValue(thedate, value));
59     } else {
60       XBT_DEBUG("%.1f: ignore an event (idx: %u)\n", thedate, it->idx);
61     }
62     resource->apply_event(it, value);
63   }
64   tmgr_finalize();
65   return res;
66 }
67
68 static std::vector<simgrid::kernel::profile::StochasticDatedValue> trace2selist(const char* str)
69 {
70   simgrid::kernel::profile::Profile* trace = simgrid::kernel::profile::Profile::from_string("TheName", str, 0);
71   std::vector<simgrid::kernel::profile::StochasticDatedValue> stocevlist = trace->stochastic_event_list;
72   tmgr_finalize();
73   return stocevlist;
74 }
75
76 TEST_CASE("kernel::profile: Resource profiles, defining the external load", "kernel::profile")
77 {
78
79   SECTION("No event, no loop")
80   {
81     std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("");
82     std::vector<simgrid::kernel::profile::DatedValue> want;
83     REQUIRE(want == got);
84   }
85
86   SECTION("One event no loop")
87   {
88     std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("9.0 3.0\n");
89
90     std::vector<simgrid::kernel::profile::DatedValue> want;
91     want.push_back(simgrid::kernel::profile::DatedValue(9, 3));
92     REQUIRE(want == got);
93   }
94
95   SECTION("Two events, no loop")
96   {
97     std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("3.0 1.0\n"
98                                                                          "9.0 3.0\n");
99
100     std::vector<simgrid::kernel::profile::DatedValue> want;
101     want.push_back(simgrid::kernel::profile::DatedValue(3, 1));
102     want.push_back(simgrid::kernel::profile::DatedValue(9, 3));
103
104     REQUIRE(want == got);
105   }
106
107   SECTION("Three events, no loop")
108   {
109
110     std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("3.0 1.0\n"
111                                                                          "5.0 2.0\n"
112                                                                          "9.0 3.0\n");
113
114     std::vector<simgrid::kernel::profile::DatedValue> want;
115     want.push_back(simgrid::kernel::profile::DatedValue(3, 1));
116     want.push_back(simgrid::kernel::profile::DatedValue(5, 2));
117     want.push_back(simgrid::kernel::profile::DatedValue(9, 3));
118
119     REQUIRE(want == got);
120   }
121
122   SECTION("Two events, looping")
123   {
124     std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("1.0 1.0\n"
125                                                                          "3.0 3.0\n"
126                                                                          "LOOPAFTER 2\n");
127
128     std::vector<simgrid::kernel::profile::DatedValue> want;
129     want.push_back(simgrid::kernel::profile::DatedValue(1, 1));
130     want.push_back(simgrid::kernel::profile::DatedValue(3, 3));
131     want.push_back(simgrid::kernel::profile::DatedValue(6, 1));
132     want.push_back(simgrid::kernel::profile::DatedValue(8, 3));
133     want.push_back(simgrid::kernel::profile::DatedValue(11, 1));
134     want.push_back(simgrid::kernel::profile::DatedValue(13, 3));
135     want.push_back(simgrid::kernel::profile::DatedValue(16, 1));
136     want.push_back(simgrid::kernel::profile::DatedValue(18, 3));
137
138     REQUIRE(want == got);
139   }
140
141   SECTION("Two events, looping, start at 0")
142   {
143     std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("0.0 1\n"
144                                                                          "5.0 2\n"
145                                                                          "LOOPAFTER 5\n");
146
147     std::vector<simgrid::kernel::profile::DatedValue> want;
148     want.push_back(simgrid::kernel::profile::DatedValue(0, 1));
149     want.push_back(simgrid::kernel::profile::DatedValue(5, 2));
150     want.push_back(simgrid::kernel::profile::DatedValue(10, 1));
151     want.push_back(simgrid::kernel::profile::DatedValue(15, 2));
152     want.push_back(simgrid::kernel::profile::DatedValue(20, 1));
153
154     REQUIRE(want == got);
155   }
156
157   SECTION("One stochastic event (parsing)")
158   {
159     std::vector<simgrid::kernel::profile::StochasticDatedValue> got = trace2selist("STOCHASTIC\n"
160                                                                                    "DET 0 UNIF 10 20");
161
162     std::vector<simgrid::kernel::profile::StochasticDatedValue> want;
163     want.push_back(simgrid::kernel::profile::StochasticDatedValue(0, -1)); // The initial fake event
164     want.push_back(simgrid::kernel::profile::StochasticDatedValue(simgrid::kernel::profile::Dist_Det, {0},
165                                                                   simgrid::kernel::profile::Dist_Unif, {10, 20}));
166
167     REQUIRE(want == got);
168   }
169
170   SECTION("Several stochastic events (all possible parsing forms)")
171   {
172     std::vector<simgrid::kernel::profile::StochasticDatedValue> got = trace2selist("STOCHASTIC\n"
173                                                                                    "DET 0 DET 4\n"
174                                                                                    "NORMAL 25 10 DET 3\n"
175                                                                                    "UNIF 10 20 NORMAL 25 10\n"
176                                                                                    "DET 5 UNIF 5 25");
177
178     std::vector<simgrid::kernel::profile::StochasticDatedValue> want;
179     want.push_back(simgrid::kernel::profile::StochasticDatedValue(0, -1));
180     want.push_back(simgrid::kernel::profile::StochasticDatedValue(simgrid::kernel::profile::Dist_Det, {0},
181                                                                   simgrid::kernel::profile::Dist_Det, {4}));
182     want.push_back(simgrid::kernel::profile::StochasticDatedValue(simgrid::kernel::profile::Dist_Norm, {25, 10},
183                                                                   simgrid::kernel::profile::Dist_Det, {3}));
184     want.push_back(simgrid::kernel::profile::StochasticDatedValue(simgrid::kernel::profile::Dist_Unif, {10, 20},
185                                                                   simgrid::kernel::profile::Dist_Norm, {25, 10}));
186     want.push_back(simgrid::kernel::profile::StochasticDatedValue(simgrid::kernel::profile::Dist_Det, {5},
187                                                                   simgrid::kernel::profile::Dist_Unif, {5, 25}));
188
189     REQUIRE(want == got);
190   }
191
192   SECTION("Two stochastic events (drawing each distribution)")
193   {
194     simgrid::xbt::random::set_mersenne_seed(12345);
195     std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("STOCHASTIC\n"
196                                                                          "DET 0 UNIF 10 20\n"
197                                                                          "EXP 0.05 NORMAL 15 5");
198
199     std::vector<simgrid::kernel::profile::DatedValue> want;
200     // The following values were drawn using the XBT_RNG_xbt method /outside/ the testcase.
201     want.push_back(simgrid::kernel::profile::DatedValue(0, 19.29616086867082813683));
202     want.push_back(simgrid::kernel::profile::DatedValue(2.32719992449416279712, 20.16807234800742065772));
203
204     REQUIRE(want == got);
205   }
206
207   SECTION("Two stochastic events, with a loop")
208   {
209     simgrid::xbt::random::set_mersenne_seed(12345);
210     std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("STOCHASTIC LOOP\n"
211                                                                          "DET 0 UNIF 10 20\n"
212                                                                          "EXP 0.05 NORMAL 15 5\n"
213                                                                          "UNIF 1 2 DET 0");
214
215     // In this case, the main use of the last stochastic event is to set when the first event takes place.
216
217     std::vector<simgrid::kernel::profile::DatedValue> want;
218     want.push_back(simgrid::kernel::profile::DatedValue(0, 19.29616086867082813683));
219     want.push_back(simgrid::kernel::profile::DatedValue(2.32719992449416279712, 20.16807234800742065772));
220     want.push_back(simgrid::kernel::profile::DatedValue(3.51111873684917075167, 0));
221     want.push_back(simgrid::kernel::profile::DatedValue(3.51111873684917075167, 10.39759496468994726115));
222
223     REQUIRE(want == got);
224   }
225 }