diff --git a/src/cpp/benders/factories/BendersFactory.cpp b/src/cpp/benders/factories/BendersFactory.cpp index 74dc15046..648c2eadf 100644 --- a/src/cpp/benders/factories/BendersFactory.cpp +++ b/src/cpp/benders/factories/BendersFactory.cpp @@ -32,33 +32,12 @@ BENDERSMETHOD DeduceBendersMethod(size_t coupling_map_size, size_t batch_size, } } -pBendersBase BendersMainFactory::PrepareForExecution(bool external_loop) { - pBendersBase benders; - std::shared_ptr math_log_driver; - +void BendersMainFactory::PrepareForExecution(bool external_loop) { BendersBaseOptions benders_options(options_.get_benders_options()); benders_options.EXTERNAL_LOOP_OPTIONS.DO_OUTER_LOOP = external_loop; + SetupLoggerAndOutputWriter(benders_options); - - auto benders_log_console = benders_options.LOG_LEVEL > 0; - if (pworld_->rank() == 0) { - auto logger_factory = - FileAndStdoutLoggerFactory(LogReportsName(), benders_log_console); - logger_ = logger_factory.get_logger(); - math_log_driver = BuildMathLogger(benders_log_console); - writer_ = build_json_writer(options_.JSON_FILE, options_.RESUME); - if (Benders::StartUp startup; - startup.StudyAlreadyAchievedCriterion(options_, writer_, logger_)) - return nullptr; - } else { - logger_ = build_void_logger(); - writer_ = build_void_writer(); - math_log_driver = MathLoggerFactory::get_void_logger(); - } - - benders_loggers_.AddLogger(logger_); - benders_loggers_.AddLogger(math_log_driver); const auto coupling_map = CouplingMapGenerator::BuildInput( benders_options.STRUCTURE_FILE, std::make_shared(benders_loggers_), "Benders"); @@ -69,49 +48,84 @@ pBendersBase BendersMainFactory::PrepareForExecution(bool external_loop) { criterion_input_holder_ = ProcessCriterionInput(); - if (pworld_->rank() == 0 && !isCriterionListEmpty()) { - AddCriterionOutput(math_log_driver); + if (pworld_->rank() == 0) { + if (Benders::StartUp startup; + startup.StudyAlreadyAchievedCriterion(options_, writer_, logger_)) { + return; + } + if (!isCriterionListEmpty()) { + AddCriterionOutput(); + } } - switch (method_) { - case BENDERSMETHOD::BENDERS: - benders = std::make_shared(benders_options, logger_, writer_, - *penv_, *pworld_, math_log_driver); - break; - case BENDERSMETHOD::BENDERS_OUTERLOOP: - benders = std::make_shared( - benders_options, logger_, writer_, *penv_, *pworld_, math_log_driver); - break; - case BENDERSMETHOD::BENDERS_BY_BATCH: - case BENDERSMETHOD::BENDERS_BY_BATCH_OUTERLOOP: - benders = std::make_shared( - benders_options, logger_, writer_, *penv_, *pworld_, math_log_driver); - break; - } + ConfigureBenders(benders_options, coupling_map); - benders->set_input_map(coupling_map); - std::ostringstream oss_l = start_message(options_, benders->BendersName()); + std::ostringstream oss_l = start_message(options_, benders_->BendersName()); oss_l << std::endl; benders_loggers_.display_message(oss_l.str()); - if (benders_options.LOG_LEVEL > 1) { + ConfigureSolverLog(); +} + +void BendersMainFactory::ConfigureSolverLog() { + if (options_.LOG_LEVEL > 1) { auto solver_log = std::filesystem::path(options_.OUTPUTROOT) / (std::string("solver_log_proc_") + std::to_string(pworld_->rank()) + ".txt"); - benders->set_solver_log_file(solver_log); + benders_->set_solver_log_file(solver_log); } +} - writer_->write_log_level(options_.LOG_LEVEL); - writer_->write_master_name(options_.MASTER_NAME); - writer_->write_solver_name(options_.SOLVER_NAME); - benders->setCriterionComputationInputs(std::visit( +void BendersMainFactory::ConfigureBenders( + const BendersBaseOptions& benders_options, + const CouplingMap& coupling_map) { + switch (method_) { + case BENDERSMETHOD::BENDERS: + benders_ = + std::make_shared(benders_options, logger_, writer_, + *penv_, *pworld_, math_log_driver_); + break; + case BENDERSMETHOD::BENDERS_OUTERLOOP: + benders_ = std::make_shared( + benders_options, logger_, writer_, *penv_, *pworld_, + math_log_driver_); + break; + case BENDERSMETHOD::BENDERS_BY_BATCH: + case BENDERSMETHOD::BENDERS_BY_BATCH_OUTERLOOP: + benders_ = + std::make_shared(benders_options, logger_, writer_, + *penv_, *pworld_, math_log_driver_); + break; + } + + benders_->set_input_map(coupling_map); + benders_->setCriterionComputationInputs(std::visit( [](auto&& the_variant) { return (Benders::Criterion::CriterionInputData)the_variant; }, criterion_input_holder_)); +} - return benders; +void BendersMainFactory::SetupLoggerAndOutputWriter( + const BendersBaseOptions& benders_options) { + auto benders_log_console = benders_options.LOG_LEVEL > 0; + if (pworld_->rank() == 0) { + auto logger_factory = + FileAndStdoutLoggerFactory(LogReportsName(), benders_log_console); + logger_ = logger_factory.get_logger(); + math_log_driver_ = BuildMathLogger(benders_log_console); + writer_ = build_json_writer(options_.JSON_FILE, options_.RESUME); + } else { + logger_ = build_void_logger(); + writer_ = build_void_writer(); + math_log_driver_ = MathLoggerFactory::get_void_logger(); + } + benders_loggers_.AddLogger(logger_); + benders_loggers_.AddLogger(math_log_driver_); + writer_->write_log_level(options_.LOG_LEVEL); + writer_->write_master_name(options_.MASTER_NAME); + writer_->write_solver_name(options_.SOLVER_NAME); } bool BendersMainFactory::isCriterionListEmpty() const { @@ -133,21 +147,20 @@ std::shared_ptr BendersMainFactory::BuildMathLogger( return math_log_driver; } -void BendersMainFactory::AddCriterionOutput( - std::shared_ptr math_log_driver) { +void BendersMainFactory::AddCriterionOutput() { const std::filesystem::path output_root(options_.OUTPUTROOT); const auto& headers = std::visit([](auto&& the_variant) { return the_variant.PatternBodies(); }, criterion_input_holder_); - math_log_driver->add_logger( + math_log_driver_->add_logger( output_root / LOLD_FILE, headers, &OuterLoopCurrentIterationData::outer_loop_criterion); positive_unsupplied_file_ = std::visit( [](auto&& the_variant) { return the_variant.PatternsPrefix() + ".txt"; }, criterion_input_holder_); - math_log_driver->add_logger( + math_log_driver_->add_logger( output_root / positive_unsupplied_file_, headers, &OuterLoopCurrentIterationData::outer_loop_patterns_values); } @@ -155,10 +168,10 @@ void BendersMainFactory::AddCriterionOutput( int BendersMainFactory::RunBenders() { try { - auto benders = PrepareForExecution(false); - if (benders) { - benders->launch(); - EndMessage(benders->execution_time()); + PrepareForExecution(false); + if (benders_) { + benders_->launch(); + EndMessage(benders_->execution_time()); } } catch (std::exception& e) { @@ -244,7 +257,7 @@ std::set BendersMainFactory::ReadAreaFile() { int BendersMainFactory::RunExternalLoop() { try { - auto benders = PrepareForExecution(true); + PrepareForExecution(true); double tau = 0.5; const auto& outer_loop_inputs = @@ -252,12 +265,12 @@ int BendersMainFactory::RunExternalLoop() { criterion_input_holder_); std::shared_ptr master_updater = std::make_shared( - benders, tau, outer_loop_inputs.StoppingThreshold()); + benders_, tau, outer_loop_inputs.StoppingThreshold()); std::shared_ptr cuts_manager = std::make_shared(); Outerloop::OuterLoopBenders ext_loop(outer_loop_inputs.CriterionsData(), - master_updater, cuts_manager, benders, + master_updater, cuts_manager, benders_, *pworld_); ext_loop.Run(); EndMessage(ext_loop.Runtime()); diff --git a/src/cpp/benders/factories/include/antares-xpansion/benders/factories/BendersFactory.h b/src/cpp/benders/factories/include/antares-xpansion/benders/factories/BendersFactory.h index 98362bb46..69dbcaad3 100644 --- a/src/cpp/benders/factories/include/antares-xpansion/benders/factories/BendersFactory.h +++ b/src/cpp/benders/factories/include/antares-xpansion/benders/factories/BendersFactory.h @@ -17,8 +17,10 @@ class BendersMainFactory { std::variant criterion_input_holder_; + pBendersBase benders_ = nullptr; Logger logger_ = nullptr; Writer writer_ = nullptr; + std::shared_ptr math_log_driver_; BENDERSMETHOD method_ = BENDERSMETHOD::BENDERS; std::string context_ = bendersmethod_to_string(BENDERSMETHOD::BENDERS); std::string positive_unsupplied_file_; @@ -28,7 +30,7 @@ class BendersMainFactory { [[nodiscard]] int RunBenders(); [[nodiscard]] std::shared_ptr BuildMathLogger( bool benders_log_console) const; - pBendersBase PrepareForExecution(bool external_loop); + void PrepareForExecution(bool external_loop); [[nodiscard]] std::variant ProcessCriterionInput(); @@ -36,7 +38,12 @@ class BendersMainFactory { Benders::Criterion::CriterionInputData BuildPatternsUsingAreaFile(); std::set ReadAreaFile(); void EndMessage(const double execution_time); - void AddCriterionOutput(std::shared_ptr math_log_driver); + void AddCriterionOutput(); + bool isCriterionListEmpty() const; + void SetupLoggerAndOutputWriter(const BendersBaseOptions& benders_options); + void ConfigureBenders(const BendersBaseOptions& benders_options, + const CouplingMap& coupling_map); + void ConfigureSolverLog(); public: explicit BendersMainFactory(int argc, char** argv, @@ -50,6 +57,5 @@ class BendersMainFactory { const SOLVER& solver); int Run(); std::filesystem::path LogReportsName() const; - bool isCriterionListEmpty() const; }; #endif // ANTARES_XPANSION_SRC_CPP_BENDERS_FACTORIES_INCLUDE_BENDERSFACTORY_H \ No newline at end of file