Logo AND Algorithmique Numérique Distribuée

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