Skip to content

Commit 30b05f5

Browse files
committed
engine: Extract SimulationProgress into simulation_progress.hpp
1 parent 5e3d4ef commit 30b05f5

File tree

3 files changed

+171
-136
lines changed

3 files changed

+171
-136
lines changed

engine/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ add_executable(cloe-engine
8585
src/coordinator.cpp
8686
src/simulation.cpp
8787
src/simulation_context.cpp
88+
src/simulation_context.hpp
89+
src/simulation_progress.hpp
8890
src/utility/command.cpp
8991
)
9092
set_target_properties(cloe-engine PROPERTIES

engine/src/simulation_context.hpp

+1-136
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@
4545
#include "registrar.hpp" // for Registrar
4646
#include "server.hpp" // for Server
4747
#include "stack.hpp" // for Stack
48+
#include "simulation_progress.hpp" // for SimulationProgress
4849
#include "utility/command.hpp" // for CommandExecuter
49-
#include "utility/progress.hpp" // for Progress
5050
#include "utility/time_event.hpp" // for TimeCallback
5151

5252
namespace engine {
@@ -120,141 +120,6 @@ class SimulationSync : public cloe::Sync {
120120
cloe::Duration step_width_{20'000'000}; // should be 20ms
121121
};
122122

123-
/**
124-
* SimulationProgress represents the progress of the simulation, split into
125-
* initialization and execution phases.
126-
*/
127-
class SimulationProgress {
128-
using TimePoint = std::chrono::steady_clock::time_point;
129-
130-
public:
131-
std::string stage{""};
132-
std::string message{"initializing engine"};
133-
134-
Progress initialization;
135-
size_t initialization_n;
136-
size_t initialization_k;
137-
138-
Progress execution;
139-
cloe::Duration execution_eta{0};
140-
141-
// Reporting:
142-
double report_granularity_p{0.1};
143-
cloe::Duration report_granularity_d{10'000'000'000};
144-
double execution_report_p;
145-
TimePoint execution_report_t;
146-
147-
public:
148-
void init_begin(size_t n) {
149-
message = "initializing";
150-
initialization.begin();
151-
initialization_n = n;
152-
initialization_k = 0;
153-
}
154-
155-
void init(const std::string& what) {
156-
stage = what;
157-
message = "initializing " + what;
158-
initialization_k++;
159-
double p = static_cast<double>(initialization_k) / static_cast<double>(initialization_n);
160-
initialization.update(p);
161-
}
162-
163-
void init_end() {
164-
initialization_k++;
165-
assert(initialization_k == initialization_n);
166-
initialization.end();
167-
stage = "";
168-
message = "initialization done";
169-
}
170-
171-
bool is_init_ended() const { return initialization.is_ended(); }
172-
173-
cloe::Duration elapsed() const {
174-
if (is_init_ended()) {
175-
return initialization.elapsed() + execution.elapsed();
176-
} else {
177-
return initialization.elapsed();
178-
}
179-
}
180-
181-
void exec_begin() {
182-
stage = "simulation";
183-
message = "executing simulation";
184-
execution_report_p = 0;
185-
execution_report_t = std::chrono::steady_clock::now();
186-
execution.begin();
187-
}
188-
189-
void exec_update(double p) { execution.update_safe(p); }
190-
191-
void exec_update(cloe::Duration now) {
192-
if (execution_eta != cloe::Duration(0)) {
193-
double now_d = static_cast<double>(now.count());
194-
double eta_d = static_cast<double>(execution_eta.count());
195-
exec_update(now_d / eta_d);
196-
}
197-
}
198-
199-
void exec_end() {
200-
stage = "";
201-
message = "simulation done";
202-
execution.end();
203-
}
204-
205-
bool is_exec_ended() const { return execution.is_ended(); }
206-
207-
/**
208-
* Return true and store the current progress percentage and time if the
209-
* current percentage is granularity_p ahead or at least granularity_d has
210-
* elapsed since the last report.
211-
*/
212-
bool exec_report() {
213-
// We should not report 100% more than once.
214-
if (execution_report_p == 1.0) {
215-
return false;
216-
}
217-
218-
// If there is no execution ETA, also don't report.
219-
if (execution_eta == cloe::Duration(0)) {
220-
return false;
221-
}
222-
223-
// Certain minimum percentage has passed.
224-
auto now = std::chrono::steady_clock::now();
225-
if (execution.is_ended()) {
226-
// We should report 100% at least once.
227-
execution_report_p = 1.0;
228-
execution_report_t = now;
229-
return true;
230-
} else if (execution.percent() - execution_report_p > report_granularity_p) {
231-
// We should report at least every report_granularity_p (percent).
232-
execution_report_p = execution.percent();
233-
execution_report_t = now;
234-
return true;
235-
} else if (cast_duration(now - execution_report_t) > report_granularity_d) {
236-
// We should report at least every report_granularity_d (duration).
237-
execution_report_p = execution.percent();
238-
execution_report_t = now;
239-
return true;
240-
} else {
241-
return false;
242-
}
243-
}
244-
245-
friend void to_json(cloe::Json& j, const SimulationProgress& p) {
246-
j = cloe::Json{
247-
{"message", p.message},
248-
{"initialization", p.initialization},
249-
};
250-
if (p.execution_eta > cloe::Duration(0)) {
251-
j["execution"] = p.execution;
252-
} else {
253-
j["execution"] = nullptr;
254-
}
255-
}
256-
};
257-
258123
struct SimulationStatistics {
259124
cloe::utility::Accumulator engine_time_ms;
260125
cloe::utility::Accumulator cycle_time_ms;

engine/src/simulation_progress.hpp

+168
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/*
2+
* Copyright 2020 Robert Bosch GmbH
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
*/
18+
/**
19+
* \file simulation_progress.hpp
20+
*/
21+
22+
#pragma once
23+
24+
#include <string>
25+
#include <chrono>
26+
27+
#include <cloe/core.hpp>
28+
29+
#include "utility/progress.hpp" // for Progress
30+
31+
namespace engine {
32+
33+
/**
34+
* SimulationProgress represents the progress of the simulation, split into
35+
* initialization and execution phases.
36+
*/
37+
class SimulationProgress {
38+
using TimePoint = std::chrono::steady_clock::time_point;
39+
40+
public:
41+
std::string stage{""};
42+
std::string message{"initializing engine"};
43+
44+
Progress initialization;
45+
size_t initialization_n;
46+
size_t initialization_k;
47+
48+
Progress execution;
49+
cloe::Duration execution_eta{0};
50+
51+
// Reporting:
52+
double report_granularity_p{0.1};
53+
cloe::Duration report_granularity_d{10'000'000'000};
54+
double execution_report_p;
55+
TimePoint execution_report_t;
56+
57+
public:
58+
void init_begin(size_t n) {
59+
message = "initializing";
60+
initialization.begin();
61+
initialization_n = n;
62+
initialization_k = 0;
63+
}
64+
65+
void init(const std::string& what) {
66+
stage = what;
67+
message = "initializing " + what;
68+
initialization_k++;
69+
double p = static_cast<double>(initialization_k) / static_cast<double>(initialization_n);
70+
initialization.update(p);
71+
}
72+
73+
void init_end() {
74+
initialization_k++;
75+
assert(initialization_k == initialization_n);
76+
initialization.end();
77+
stage = "";
78+
message = "initialization done";
79+
}
80+
81+
bool is_init_ended() const { return initialization.is_ended(); }
82+
83+
cloe::Duration elapsed() const {
84+
if (is_init_ended()) {
85+
return initialization.elapsed() + execution.elapsed();
86+
} else {
87+
return initialization.elapsed();
88+
}
89+
}
90+
91+
void exec_begin() {
92+
stage = "simulation";
93+
message = "executing simulation";
94+
execution_report_p = 0;
95+
execution_report_t = std::chrono::steady_clock::now();
96+
execution.begin();
97+
}
98+
99+
void exec_update(double p) { execution.update_safe(p); }
100+
101+
void exec_update(cloe::Duration now) {
102+
if (execution_eta != cloe::Duration(0)) {
103+
double now_d = static_cast<double>(now.count());
104+
double eta_d = static_cast<double>(execution_eta.count());
105+
exec_update(now_d / eta_d);
106+
}
107+
}
108+
109+
void exec_end() {
110+
stage = "";
111+
message = "simulation done";
112+
execution.end();
113+
}
114+
115+
bool is_exec_ended() const { return execution.is_ended(); }
116+
117+
/**
118+
* Return true and store the current progress percentage and time if the
119+
* current percentage is granularity_p ahead or at least granularity_d has
120+
* elapsed since the last report.
121+
*/
122+
bool exec_report() {
123+
// We should not report 100% more than once.
124+
if (execution_report_p == 1.0) {
125+
return false;
126+
}
127+
128+
// If there is no execution ETA, also don't report.
129+
if (execution_eta == cloe::Duration(0)) {
130+
return false;
131+
}
132+
133+
// Certain minimum percentage has passed.
134+
auto now = std::chrono::steady_clock::now();
135+
if (execution.is_ended()) {
136+
// We should report 100% at least once.
137+
execution_report_p = 1.0;
138+
execution_report_t = now;
139+
return true;
140+
} else if (execution.percent() - execution_report_p > report_granularity_p) {
141+
// We should report at least every report_granularity_p (percent).
142+
execution_report_p = execution.percent();
143+
execution_report_t = now;
144+
return true;
145+
} else if (cast_duration(now - execution_report_t) > report_granularity_d) {
146+
// We should report at least every report_granularity_d (duration).
147+
execution_report_p = execution.percent();
148+
execution_report_t = now;
149+
return true;
150+
} else {
151+
return false;
152+
}
153+
}
154+
155+
friend void to_json(cloe::Json& j, const SimulationProgress& p) {
156+
j = cloe::Json{
157+
{"message", p.message},
158+
{"initialization", p.initialization},
159+
};
160+
if (p.execution_eta > cloe::Duration(0)) {
161+
j["execution"] = p.execution;
162+
} else {
163+
j["execution"] = nullptr;
164+
}
165+
}
166+
};
167+
168+
} // namespace engine

0 commit comments

Comments
 (0)