|
15 | 15 | #include "simplex.h" |
16 | 16 |
|
17 | 17 | #include <cassert> |
| 18 | +#include <iostream> |
18 | 19 |
|
19 | 20 | #include "Highs.h" |
20 | 21 | #include "io/HMPSIO.h" |
21 | 22 |
|
22 | 23 | constexpr size_t T_COORD = 2; |
23 | 24 |
|
| 25 | +namespace { |
| 26 | +void highs_log_cb(HighsLogType, const char* msg, void* user_data) { |
| 27 | + CallbackStream* stream = static_cast<CallbackStream*>(user_data); |
| 28 | + (*stream) << msg; |
| 29 | + stream->flush(); |
| 30 | +} |
| 31 | +} // namespace |
| 32 | + |
24 | 33 | std::string SimplexConfig::str() { |
25 | 34 | auto& self = *this; |
26 | 35 | std::stringstream ss; |
27 | 36 | ss << "SimplexConfig("; |
28 | 37 | ss << "dem=" << "DetectorErrorModel_Object" << ", "; |
29 | 38 | ss << "window_length=" << self.window_length << ", "; |
30 | | - ss << "window_slide_length=" << self.window_slide_length << ", "; |
31 | | - ss << "verbose=" << self.verbose << ")"; |
| 39 | + ss << "window_slide_length=" << self.window_slide_length << ")"; |
32 | 40 | return ss.str(); |
33 | 41 | } |
34 | 42 |
|
35 | 43 | SimplexDecoder::SimplexDecoder(SimplexConfig _config) : config(_config) { |
| 44 | + if (!config.verbose_callback) { |
| 45 | + config.verbose_callback = [](const std::string& s) { std::cout << s; }; |
| 46 | + } |
| 47 | + config.log_stream.callback = config.verbose_callback; |
36 | 48 | config.dem = common::remove_zero_probability_errors(config.dem); |
37 | 49 | std::vector<double> detector_t_coords(config.dem.count_detectors()); |
38 | 50 | for (const stim::DemInstruction& instruction : config.dem.flattened().instructions) { |
@@ -152,7 +164,11 @@ void SimplexDecoder::init_ilp() { |
152 | 164 | // Disabled presolve entirely after encountering bugs similar to this one: |
153 | 165 | // https://github.com/ERGO-Code/HiGHS/issues/1273 |
154 | 166 | highs->setOptionValue("presolve", "off"); |
155 | | - highs->setOptionValue("output_flag", config.verbose); |
| 167 | + highs->setOptionValue("output_flag", config.log_stream.active); |
| 168 | + highs->setOptionValue("log_to_console", false); |
| 169 | + if (config.log_stream.active) { |
| 170 | + highs->setLogCallback(highs_log_cb, &config.log_stream); |
| 171 | + } |
156 | 172 | } |
157 | 173 |
|
158 | 174 | void SimplexDecoder::decode_to_errors(const std::vector<uint64_t>& detections) { |
@@ -197,9 +213,7 @@ void SimplexDecoder::decode_to_errors(const std::vector<uint64_t>& detections) { |
197 | 213 | add_costs_for_time(t1); |
198 | 214 | ++t1; |
199 | 215 | } |
200 | | - if (config.verbose) { |
201 | | - std::cout << "t0 = " << t0 << " t1 = " << t1 << std::endl; |
202 | | - } |
| 216 | + config.log_stream << "t0 = " << t0 << " t1 = " << t1 << std::endl; |
203 | 217 |
|
204 | 218 | // Pass the model to HiGHS |
205 | 219 | *return_status = highs->passModel(*model); |
@@ -235,16 +249,20 @@ void SimplexDecoder::decode_to_errors(const std::vector<uint64_t>& detections) { |
235 | 249 | } |
236 | 250 | assert(*return_status == HighsStatus::kOk); |
237 | 251 |
|
238 | | - if (config.verbose) { |
239 | | - // Get the solution information |
| 252 | + if (config.log_stream.active) { |
240 | 253 | const HighsInfo& info = highs->getInfo(); |
241 | | - std::cout << "Simplex iteration count: " << info.simplex_iteration_count << std::endl; |
242 | | - std::cout << "Objective function value: " << info.objective_function_value << std::endl; |
243 | | - std::cout << "Primal solution status: " |
244 | | - << highs->solutionStatusToString(info.primal_solution_status) << std::endl; |
245 | | - std::cout << "Dual solution status: " |
246 | | - << highs->solutionStatusToString(info.dual_solution_status) << std::endl; |
247 | | - std::cout << "Basis: " << highs->basisValidityToString(info.basis_validity) << std::endl; |
| 254 | + config.log_stream << "Simplex iteration count: " << info.simplex_iteration_count |
| 255 | + << std::endl; |
| 256 | + config.log_stream << "Objective function value: " << info.objective_function_value |
| 257 | + << std::endl; |
| 258 | + config.log_stream << "Primal solution status: " |
| 259 | + << highs->solutionStatusToString(info.primal_solution_status) |
| 260 | + << std::endl; |
| 261 | + config.log_stream << "Dual solution status: " |
| 262 | + << highs->solutionStatusToString(info.dual_solution_status) |
| 263 | + << std::endl; |
| 264 | + config.log_stream << "Basis: " |
| 265 | + << highs->basisValidityToString(info.basis_validity) << std::endl; |
248 | 266 | } |
249 | 267 |
|
250 | 268 | // Get the model status |
@@ -286,16 +304,20 @@ void SimplexDecoder::decode_to_errors(const std::vector<uint64_t>& detections) { |
286 | 304 | *return_status = highs->run(); |
287 | 305 | assert(*return_status == HighsStatus::kOk); |
288 | 306 |
|
289 | | - if (config.verbose) { |
290 | | - // Get the solution information |
| 307 | + if (config.log_stream.active) { |
291 | 308 | const HighsInfo& info = highs->getInfo(); |
292 | | - std::cout << "Simplex iteration count: " << info.simplex_iteration_count << std::endl; |
293 | | - std::cout << "Objective function value: " << info.objective_function_value << std::endl; |
294 | | - std::cout << "Primal solution status: " |
295 | | - << highs->solutionStatusToString(info.primal_solution_status) << std::endl; |
296 | | - std::cout << "Dual solution status: " |
297 | | - << highs->solutionStatusToString(info.dual_solution_status) << std::endl; |
298 | | - std::cout << "Basis: " << highs->basisValidityToString(info.basis_validity) << std::endl; |
| 309 | + config.log_stream << "Simplex iteration count: " << info.simplex_iteration_count |
| 310 | + << std::endl; |
| 311 | + config.log_stream << "Objective function value: " << info.objective_function_value |
| 312 | + << std::endl; |
| 313 | + config.log_stream << "Primal solution status: " |
| 314 | + << highs->solutionStatusToString(info.primal_solution_status) |
| 315 | + << std::endl; |
| 316 | + config.log_stream << "Dual solution status: " |
| 317 | + << highs->solutionStatusToString(info.dual_solution_status) |
| 318 | + << std::endl; |
| 319 | + config.log_stream << "Basis: " |
| 320 | + << highs->basisValidityToString(info.basis_validity) << std::endl; |
299 | 321 | } |
300 | 322 |
|
301 | 323 | // Get the model status |
|
0 commit comments