diff --git a/src/cpp/benders/benders_core/BendersBase.cpp b/src/cpp/benders/benders_core/BendersBase.cpp index 5f8f3b51e..311c10aff 100644 --- a/src/cpp/benders/benders_core/BendersBase.cpp +++ b/src/cpp/benders/benders_core/BendersBase.cpp @@ -1,4 +1,5 @@ #include "antares-xpansion/benders/benders_core/BendersBase.h" +#include #include #include @@ -8,6 +9,7 @@ #include "antares-xpansion/benders/benders_core/LastIterationPrinter.h" #include "antares-xpansion/benders/benders_core/LastIterationReader.h" #include "antares-xpansion/benders/benders_core/LastIterationWriter.h" +#include "antares-xpansion/benders/benders_core/ProblemFormatStream.h" #include "antares-xpansion/xpansion_interfaces/LogUtils.h" #include "antares-xpansion/helpers/solver_utils.h" diff --git a/src/cpp/benders/benders_core/ProblemFormatStream.cpp b/src/cpp/benders/benders_core/ProblemFormatStream.cpp index 30429b828..d7579bf52 100644 --- a/src/cpp/benders/benders_core/ProblemFormatStream.cpp +++ b/src/cpp/benders/benders_core/ProblemFormatStream.cpp @@ -6,10 +6,10 @@ auto fmt::formatter::format(ProblemsFormat problems_format, string_view result = "Unknown"; switch (problems_format) { case ProblemsFormat::MPS_FILE: - result = "MPS_FILE"; + result = "MPS"; break; case ProblemsFormat::SAVED_FILE: - result = "SAVED_FILE"; + result = "SAVED"; break; default: result = "Unknown"; diff --git a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersBase.h b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersBase.h index 3a8c90da8..e814c7386 100644 --- a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersBase.h +++ b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersBase.h @@ -16,7 +16,6 @@ #include "WorkerMaster.h" #include "antares-xpansion/helpers/Timer.h" #include "antares-xpansion/xpansion_interfaces/ILogger.h" -#include "antares-xpansion/xpansion_interfaces/OutputWriter.h" #include "common.h" /** * std execution policies don't share a base type so we can't just select diff --git a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/ProblemFormatStream.h b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/ProblemFormatStream.h index 401593c63..2e4d12831 100644 --- a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/ProblemFormatStream.h +++ b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/ProblemFormatStream.h @@ -10,10 +10,10 @@ inline std::ostream &operator<<(std::ostream &stream, ProblemsFormat const &rhs) { switch (rhs) { case ProblemsFormat::MPS_FILE: - stream << "MPS_FILE"; + stream << "MPS"; break; case ProblemsFormat::SAVED_FILE: - stream << "SAVED_FILE"; + stream << "SAVED"; break; default: stream << "Unknown"; diff --git a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/StartUp.h b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/StartUp.h index 9eaa69eb5..48726359b 100644 --- a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/StartUp.h +++ b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/StartUp.h @@ -4,9 +4,9 @@ #pragma once -#include "antares-xpansion/xpansion_interfaces/ILogger.h" -#include "antares-xpansion/xpansion_interfaces/OutputWriter.h" #include "SimulationOptions.h" +#include "antares-xpansion/benders/output/OutputWriter.h" +#include "antares-xpansion/xpansion_interfaces/ILogger.h" namespace Benders { class StartUp { diff --git a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/Worker.h b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/Worker.h index 7bdf3e432..4c016d512 100644 --- a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/Worker.h +++ b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/Worker.h @@ -3,9 +3,9 @@ #include #include "SolverIO.h" +#include "antares-xpansion/benders/output/OutputWriter.h" #include "antares-xpansion/multisolver_interface/Solver.h" #include "antares-xpansion/xpansion_interfaces/ILogger.h" -#include "antares-xpansion/xpansion_interfaces/OutputWriter.h" #include "common.h" /*! diff --git a/src/cpp/benders/factories/BendersFactory.cpp b/src/cpp/benders/factories/BendersFactory.cpp index 17f00b5c8..4c08b6365 100644 --- a/src/cpp/benders/factories/BendersFactory.cpp +++ b/src/cpp/benders/factories/BendersFactory.cpp @@ -1,12 +1,15 @@ #include "antares-xpansion/benders/factories/BendersFactory.h" +#include + #include #include "antares-xpansion/benders/benders_by_batch/BendersByBatch.h" #include "antares-xpansion/benders/benders_core/CouplingMapGenerator.h" #include "antares-xpansion/benders/benders_core/MasterUpdate.h" #include "antares-xpansion/benders/benders_core/StartUp.h" +#include "antares-xpansion/benders/benders_core/ProblemFormatStream.h" #include "antares-xpansion/benders/benders_mpi/BendersMpiOuterLoop.h" #include "antares-xpansion/benders/benders_mpi/OuterLoopBenders.h" #include "antares-xpansion/benders/factories/LoggerFactories.h" @@ -121,6 +124,7 @@ void BendersMainFactory::SetupLoggerAndOutputWriter( writer_->write_log_level(options_.LOG_LEVEL); writer_->write_master_name(options_.MASTER_NAME); writer_->write_solver_name(options_.SOLVER_NAME); + writer_->WriteProblemFormat(fmt::format("{}", options_.PROBLEMS_FORMAT)); } bool BendersMainFactory::isCriterionListEmpty() const { diff --git a/src/cpp/benders/factories/WriterFactories.cpp b/src/cpp/benders/factories/WriterFactories.cpp index 054adcf69..dd2ed5916 100644 --- a/src/cpp/benders/factories/WriterFactories.cpp +++ b/src/cpp/benders/factories/WriterFactories.cpp @@ -3,7 +3,6 @@ #include "antares-xpansion/benders/factories/WriterFactories.h" #include "antares-xpansion/benders/output/JsonWriter.h" -#include "antares-xpansion/xpansion_interfaces/OutputWriter.h" #include "antares-xpansion/benders/output/VoidWriter.h" #include "antares-xpansion/benders/benders_core/common.h" diff --git a/src/cpp/benders/factories/include/antares-xpansion/benders/factories/WriterFactories.h b/src/cpp/benders/factories/include/antares-xpansion/benders/factories/WriterFactories.h index 16778630e..3c3ba0c35 100644 --- a/src/cpp/benders/factories/include/antares-xpansion/benders/factories/WriterFactories.h +++ b/src/cpp/benders/factories/include/antares-xpansion/benders/factories/WriterFactories.h @@ -5,7 +5,7 @@ #include #include -#include "antares-xpansion/xpansion_interfaces/OutputWriter.h" +#include "antares-xpansion/benders/output/OutputWriter.h" Writer build_void_writer(); diff --git a/src/cpp/benders/output/CMakeLists.txt b/src/cpp/benders/output/CMakeLists.txt index 3c5daff0f..24c52a2bf 100644 --- a/src/cpp/benders/output/CMakeLists.txt +++ b/src/cpp/benders/output/CMakeLists.txt @@ -13,6 +13,7 @@ target_sources(output_core PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/JsonWriter.cpp include/antares-xpansion/benders/output/VoidWriter.h include/antares-xpansion/benders/output/JsonWriter.h + include/antares-xpansion/benders/output/OutputWriter.h ) target_include_directories(output_core diff --git a/src/cpp/benders/output/JsonWriter.cpp b/src/cpp/benders/output/JsonWriter.cpp index 5ef774afc..fb331bb95 100644 --- a/src/cpp/benders/output/JsonWriter.cpp +++ b/src/cpp/benders/output/JsonWriter.cpp @@ -170,4 +170,7 @@ void JsonWriter::WriteProblem(const ProblemData &problem_data) { _output[ERROR_C][PROBLEMPATH_C] = problem_data.path.string(); _output[ERROR_C][PROBLEM_STATUS_C] = problem_data.status; } +void JsonWriter::WriteProblemFormat(const std::string format) { + _output[OPTIONS_C][PROBLEM_FORMAT_C] = format; +} } // namespace Output \ No newline at end of file diff --git a/src/cpp/benders/output/VoidWriter.cpp b/src/cpp/benders/output/VoidWriter.cpp index ec694fe0a..1931ee70c 100644 --- a/src/cpp/benders/output/VoidWriter.cpp +++ b/src/cpp/benders/output/VoidWriter.cpp @@ -68,5 +68,6 @@ std::string VoidWriter::solution_status() const { return ""; } void VoidWriter::WriteProblem(const ProblemData &problem_data) { // keep this method empty } +void VoidWriter::WriteProblemFormat(const std::string format) {} } // namespace Output \ No newline at end of file diff --git a/src/cpp/benders/output/include/antares-xpansion/benders/output/JsonWriter.h b/src/cpp/benders/output/include/antares-xpansion/benders/output/JsonWriter.h index 7bc84169a..911f480cc 100644 --- a/src/cpp/benders/output/include/antares-xpansion/benders/output/JsonWriter.h +++ b/src/cpp/benders/output/include/antares-xpansion/benders/output/JsonWriter.h @@ -6,8 +6,8 @@ #include #include +#include "antares-xpansion/benders/output/OutputWriter.h" #include "antares-xpansion/xpansion_interfaces/Clock.h" -#include "antares-xpansion/xpansion_interfaces/OutputWriter.h" namespace Output { @@ -79,5 +79,6 @@ class JsonWriter : public OutputWriter { void write_duration(const double duration) override; std::string solution_status() const override; void WriteProblem(const ProblemData &problem_data) override; + void WriteProblemFormat(const std::string format) override; }; } // namespace Output \ No newline at end of file diff --git a/src/cpp/xpansion_interfaces/include/antares-xpansion/xpansion_interfaces/OutputWriter.h b/src/cpp/benders/output/include/antares-xpansion/benders/output/OutputWriter.h similarity index 96% rename from src/cpp/xpansion_interfaces/include/antares-xpansion/xpansion_interfaces/OutputWriter.h rename to src/cpp/benders/output/include/antares-xpansion/benders/output/OutputWriter.h index c474496a0..9e7ccb8d1 100644 --- a/src/cpp/xpansion_interfaces/include/antares-xpansion/xpansion_interfaces/OutputWriter.h +++ b/src/cpp/benders/output/include/antares-xpansion/benders/output/OutputWriter.h @@ -26,7 +26,9 @@ const std::string ANTARES_C("antares"), VERSION_C("version"), SOLVER_NAME_C("SOLVER_NAME"), PROBLEMNAME_C("problem_name"), PROBLEMPATH_C("problem_path"), CUMULATIVE_NUMBER_OF_SUBPROBLEM_RESOLVED_C( - "cumulative_number_of_subproblem_resolutions"); + "cumulative_number_of_subproblem_resolutions"), + PROBLEM_FORMAT_C{"PROBLEM_FORMAT"} +; struct CandidateData { std::string name; double invest; @@ -126,6 +128,7 @@ class OutputWriter { virtual void write_duration(const double duration) = 0; virtual std::string solution_status() const = 0; virtual void WriteProblem(const ProblemData &problem_data) = 0; + virtual void WriteProblemFormat(const std::string format) = 0; }; } // namespace Output using Writer = std::shared_ptr; \ No newline at end of file diff --git a/src/cpp/benders/output/include/antares-xpansion/benders/output/VoidWriter.h b/src/cpp/benders/output/include/antares-xpansion/benders/output/VoidWriter.h index 08c170cb8..861a1b3fc 100644 --- a/src/cpp/benders/output/include/antares-xpansion/benders/output/VoidWriter.h +++ b/src/cpp/benders/output/include/antares-xpansion/benders/output/VoidWriter.h @@ -1,8 +1,7 @@ #pragma once -#include "antares-xpansion/xpansion_interfaces/OutputWriter.h" - +#include "antares-xpansion/benders/output/OutputWriter.h" namespace Output { /*! * \class VoidWriter @@ -71,5 +70,6 @@ class VoidWriter : public OutputWriter { void write_duration(const double duration) override; std::string solution_status() const override; void WriteProblem(const ProblemData &problem_data) override; + void WriteProblemFormat(const std::string format) override; }; } // namespace Output \ No newline at end of file diff --git a/src/cpp/sensitivity/CMakeLists.txt b/src/cpp/sensitivity/CMakeLists.txt index a5b3c5b5a..502dcb0a6 100644 --- a/src/cpp/sensitivity/CMakeLists.txt +++ b/src/cpp/sensitivity/CMakeLists.txt @@ -30,9 +30,12 @@ target_include_directories(sensitivity_core $ ) +find_package(fmt REQUIRED) target_link_libraries(sensitivity_core PUBLIC antaresXpansion::logger_lib + PRIVATE + fmt::fmt ) add_library(${PROJECT_NAME}::sensitivity_core ALIAS sensitivity_core) \ No newline at end of file diff --git a/src/cpp/sensitivity/SensitivityInputReader.cpp b/src/cpp/sensitivity/SensitivityInputReader.cpp index e70f0a485..0596cee55 100644 --- a/src/cpp/sensitivity/SensitivityInputReader.cpp +++ b/src/cpp/sensitivity/SensitivityInputReader.cpp @@ -1,13 +1,16 @@ #include "antares-xpansion/sensitivity/SensitivityInputReader.h" +#include + #include #include #include -#include "antares-xpansion/xpansion_interfaces/LogUtils.h" -#include "antares-xpansion/xpansion_interfaces/OutputWriter.h" -#include "antares-xpansion/benders/benders_core/common.h" +#include "antares-xpansion/benders/benders_core/ProblemFormat.h" +#include "antares-xpansion/benders/benders_core/ProblemFormatStream.h" +#include "antares-xpansion/benders/output/OutputWriter.h" #include "antares-xpansion/multisolver_interface/SolverFactory.h" +#include "antares-xpansion/xpansion_interfaces/LogUtils.h" const std::string EPSILON_C("epsilon"); const std::string CAPEX_C("capex"); @@ -19,8 +22,8 @@ Json::Value read_json(const std::filesystem::path &json_file_path) { if (json_file.good()) { json_file >> json_data; } else { - throw std::runtime_error(LOGLOCATION + - "unable to open : " + json_file_path.string()); + throw std::runtime_error(fmt::format("{}: unable to open : {}", + LOGLOCATION, json_file_path.string())); } return json_data; } @@ -45,9 +48,9 @@ std::vector SensitivityInputReader::get_projection() const { return projection; } -SolverAbstract::Ptr SensitivityInputReader::get_last_master() const { +std::shared_ptr SensitivityInputReader::get_last_master() const { SolverFactory factory; - SolverAbstract::Ptr last_master; + std::shared_ptr last_master; if (_benders_data[Output::OPTIONS_C]["SOLVER_NAME"].asString() == "COIN") { last_master = factory.create_solver("CBC"); @@ -58,13 +61,25 @@ SolverAbstract::Ptr SensitivityInputReader::get_last_master() const { last_master->set_threads(1); last_master->set_output_log_level( _benders_data[Output::OPTIONS_C]["LOG_LEVEL"].asInt()); - last_master->read_prob_mps(_last_master_path); + auto problem_format = _benders_data[Output::OPTIONS_C][Output::PROBLEM_FORMAT_C].asString(); + auto format = problem_format.empty() ? ProblemsFormat::MPS_FILE : problemsFormatFromString(problem_format); + switch (format) { + case ProblemsFormat::MPS_FILE: + last_master->read_prob_mps(_last_master_path); + break; + case ProblemsFormat::SAVED_FILE: + last_master->restore_prob(_last_master_path); + break; + default: + throw std::runtime_error(fmt::format("{}: unsupported format : {}", + LOGLOCATION, format)); + } return last_master; } std::map> SensitivityInputReader::get_candidates_bounds( - SolverAbstract::Ptr last_master, + SolverAbstract *last_master, const std::map &name_to_id) const { std::map> candidates_bounds; @@ -145,7 +160,7 @@ SensitivityInputData SensitivityInputReader::get_input_data() const { input_data.last_master = get_last_master(); input_data.basis_file_path = _basis_file_path; input_data.candidates_bounds = - get_candidates_bounds(input_data.last_master, input_data.name_to_id); + get_candidates_bounds(input_data.last_master.get(), input_data.name_to_id); input_data.capex = _json_data[CAPEX_C].asBool(); input_data.projection = get_projection(); return input_data; diff --git a/src/cpp/sensitivity/include/antares-xpansion/sensitivity/SensitivityInputReader.h b/src/cpp/sensitivity/include/antares-xpansion/sensitivity/SensitivityInputReader.h index df9235260..8d2b47b30 100644 --- a/src/cpp/sensitivity/include/antares-xpansion/sensitivity/SensitivityInputReader.h +++ b/src/cpp/sensitivity/include/antares-xpansion/sensitivity/SensitivityInputReader.h @@ -11,7 +11,7 @@ struct SensitivityInputData { double benders_capex; std::map benders_solution; std::map name_to_id; - SolverAbstract::Ptr last_master; + std::shared_ptr last_master; std::filesystem::path basis_file_path; std::map> candidates_bounds; bool capex; @@ -37,13 +37,13 @@ class SensitivityInputReader { std::filesystem::path _basis_file_path; std::filesystem::path _structure_file_path; - SolverAbstract::Ptr get_last_master() const; + std::shared_ptr get_last_master() const; double get_best_ub() const; double get_benders_capex() const; std::map get_benders_solution() const; std::map get_name_to_id() const; std::vector get_projection() const; std::map> get_candidates_bounds( - SolverAbstract::Ptr last_master, + SolverAbstract *last_master, const std::map &name_to_id) const; }; diff --git a/src/cpp/xpansion_interfaces/CMakeLists.txt b/src/cpp/xpansion_interfaces/CMakeLists.txt index 7e3a0744e..c668b524c 100644 --- a/src/cpp/xpansion_interfaces/CMakeLists.txt +++ b/src/cpp/xpansion_interfaces/CMakeLists.txt @@ -12,7 +12,6 @@ target_sources(xpansion_interfaces ${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/xpansion_interfaces/ILogger.h ${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/xpansion_interfaces/IWriterLogger.h ${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/xpansion_interfaces/LogUtils.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/xpansion_interfaces/OutputWriter.h ${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/xpansion_interfaces/StringManip.h ${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/xpansion_interfaces/Clock.h ) diff --git a/src/python/antares_xpansion/config_loader.py b/src/python/antares_xpansion/config_loader.py index c2759c15c..46c9086eb 100644 --- a/src/python/antares_xpansion/config_loader.py +++ b/src/python/antares_xpansion/config_loader.py @@ -694,11 +694,16 @@ def structure_file_path(self): def last_master_file_path(self): # The 'last_iteration' literal is only hard-coded in Worker.cpp, should we introduce a new variable in _config.options_default ? - return os.path.join( + use_xpress = str(self.options["solver"]).upper() == "XPRESS" + base_path = os.path.join( self.simulation_lp_path(), self._config.options_default["MASTER_NAME"] + - "_last_iteration.mps", - ) + "_last_iteration") + if use_xpress: + base_path += ".svf" + else: + base_path += ".mps" + return base_path def last_master_basis_path(self): return os.path.join( diff --git a/src/python/antares_xpansion/sensitivity_driver.py b/src/python/antares_xpansion/sensitivity_driver.py index 8a729f352..8199d4c96 100644 --- a/src/python/antares_xpansion/sensitivity_driver.py +++ b/src/python/antares_xpansion/sensitivity_driver.py @@ -2,12 +2,9 @@ Class to control the sensitivity analysis """ -import glob import os -import shutil import subprocess import sys -import zipfile from pathlib import Path from antares_xpansion.logger import step_logger @@ -52,7 +49,7 @@ def launch( old_cwd = os.getcwd() os.chdir(xpansion_simulation_output) self.logger.info(f"Current directory is now {os.getcwd()}") - + self.logger.info(f"Launching sensitivity analysis : {self._get_sensitivity_cmd()}") returned_l = subprocess.run( self._get_sensitivity_cmd(), shell=False, diff --git a/tests/cpp/TestDoubles/WriterStub.h b/tests/cpp/TestDoubles/WriterStub.h index d34182449..d35003ed7 100644 --- a/tests/cpp/TestDoubles/WriterStub.h +++ b/tests/cpp/TestDoubles/WriterStub.h @@ -3,7 +3,6 @@ // #pragma once -#include "antares-xpansion/xpansion_interfaces/OutputWriter.h" class WriterNOOPStub : public Output::OutputWriter { public: @@ -24,4 +23,5 @@ class WriterNOOPStub : public Output::OutputWriter { void write_duration(const double duration) override {} std::string solution_status() const override { return std::string(); } void WriteProblem(const Output::ProblemData& problem_data) override {} + void WriteProblemFormat(const std::string format) override {} }; \ No newline at end of file