Skip to content

Commit

Permalink
Cohérence des solver E2E
Browse files Browse the repository at this point in the history
  • Loading branch information
JasonMarechal25 committed Nov 8, 2024
1 parent 48e1474 commit 8ddf4c8
Show file tree
Hide file tree
Showing 12 changed files with 191 additions and 42 deletions.
5 changes: 4 additions & 1 deletion src/cpp/lpnamer/input_reader/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,25 @@ target_sources(lp_namer_input_reader PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/AdditionalConstraintsReader.cpp
${CMAKE_CURRENT_SOURCE_DIR}/CandidatesINIReader.cpp
${CMAKE_CURRENT_SOURCE_DIR}/GeneralDataReader.cpp
${CMAKE_CURRENT_SOURCE_DIR}/LinkProfileReader.cpp
${CMAKE_CURRENT_SOURCE_DIR}/LpFilesExtractor.cpp
${CMAKE_CURRENT_SOURCE_DIR}/MpsTxtWriter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/SettingsReader.cpp
${CMAKE_CURRENT_SOURCE_DIR}/VariableFileReader.cpp
${CMAKE_CURRENT_SOURCE_DIR}/WeightsFileReader.cpp
${CMAKE_CURRENT_SOURCE_DIR}/WeightsFileWriter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/lpnamer/input_reader/AdditionalConstraintsReader.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/lpnamer/input_reader/CandidatesINIReader.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/lpnamer/input_reader/Exceptions.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/lpnamer/input_reader/GeneralDataReader.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/lpnamer/input_reader/INIReader.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/lpnamer/input_reader/LinkProfileReader.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/lpnamer/input_reader/LpFilesExtractor.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/lpnamer/input_reader/MpsTxtWriter.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/lpnamer/input_reader/SettingsReader.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/lpnamer/input_reader/VariableFileReader.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/lpnamer/input_reader/WeightsFileReader.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/lpnamer/input_reader/WeightsFileWriter.h
${CMAKE_CURRENT_SOURCE_DIR}/LinkProfileReader.cpp
)

target_include_directories(lp_namer_input_reader
Expand Down
3 changes: 2 additions & 1 deletion src/cpp/lpnamer/input_reader/GeneralDataReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
#include <stdexcept>
#include <vector>

#include "antares-xpansion/lpnamer/helper/ProblemGenerationLogger.h"
#include "antares-xpansion/lpnamer/input_reader/Exceptions.h"
#include "antares-xpansion/lpnamer/input_reader/INIReader.h"
#include "antares-xpansion/xpansion_interfaces/LogUtils.h"
#include "antares-xpansion/lpnamer/helper/ProblemGenerationLogger.h"
#include "antares-xpansion/xpansion_interfaces/StringManip.h"
class IniReaderUtils {
public:
Expand Down
54 changes: 54 additions & 0 deletions src/cpp/lpnamer/input_reader/SettingsReader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include <antares-xpansion/lpnamer/input_reader/SettingsReader.h>

#include <regex>

#include "antares-xpansion/lpnamer/input_reader/Exceptions.h"
#include "antares-xpansion/xpansion_interfaces/StringManip.h"

SettingsReader::SettingsReader(const std::filesystem::path& file_path,
ProblemGenerationLog::ProblemGenerationLogger* logger)
: logger_(logger)
{
check_file_exist(file_path);

parse_file(file_path);
settings_.try_emplace("solver", "CBC");
solver_name_ = settings_.at("solver");

}
void SettingsReader::parse_file(const std::filesystem::path& file_path) {
std::ifstream file(file_path);
std::string line;
std::regex regex_token("=");

while (std::getline(file, line)) {
if (std::find_if(line.begin(), line.end(), [](auto c) { return !std::isspace(c); }) == line.end()) {
continue; // skip empty lines
}
std::vector<std::string> values;
std::sregex_token_iterator it(line.begin(), line.end(), regex_token, -1);
std::copy(it, std::sregex_token_iterator(), std::back_inserter(values));
if (values.size() != 2) {
std::ostringstream msg;
msg << "Invalid line in settings file : " << line
<< std::endl;
(*this->logger_)(LogUtils::LOGLEVEL::FATAL) << msg.str();
throw LogUtils::XpansionError<std::runtime_error>(msg.str(), LOGLOCATION);
}
this->settings_[StringManip::trim(values[0])] = StringManip::trim(values[1]);
}
}
void SettingsReader::check_file_exist(
const std::filesystem::path& file_path) const {
if (file_path.empty() || !std::filesystem::exists(file_path)) {
std::ostringstream msg;
msg << LOGLOCATION
<< "General data file is not found : " << file_path.string()
<< std::endl;
(*this->logger_)(LogUtils::LOGLEVEL::FATAL) << msg.str();
throw IniFileNotFound(msg.str());
}
}
std::string SettingsReader::Solver() {
return solver_name_;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once

class IniFileNotFound : public std::runtime_error {
public:
explicit IniFileNotFound(const std::string& msg) : std::runtime_error(msg) {}
};
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@
#include "antares-xpansion/lpnamer/helper/ProblemGenerationLogger.h"
#include "antares-xpansion/xpansion_interfaces/StringManip.h"

class IniFileNotFound : public std::runtime_error {
public:
explicit IniFileNotFound(const std::string& msg) : std::runtime_error(msg) {}
};

class GeneralDataIniReader {
private:
ProblemGenerationLog::ProblemGenerationLoggerSharedPointer logger_;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#pragma once

#include <filesystem>
#include "antares-xpansion/lpnamer/helper/ProblemGenerationLogger.h"

/**
* A class to read the settings.ini file pertaining to antares-xpansion settings
*/
class SettingsReader {
public:
/**
* Constructor for the SettingsReader class
* @param file_path The path to the settings.ini file
*/
explicit SettingsReader(const std::filesystem::path& file_path,
ProblemGenerationLog::ProblemGenerationLogger* logger);

std::string Solver();

private:
ProblemGenerationLog::ProblemGenerationLogger* logger_;
std::string solver_name_;

std::map<std::string, std::string> settings_;
void check_file_exist(const std::filesystem::path& file_path) const;
void parse_file(const std::filesystem::path& file_path);
};
32 changes: 18 additions & 14 deletions src/cpp/lpnamer/main/ProblemGeneration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,31 @@
#include <iostream>
#include <utility>

#include "antares-xpansion/lpnamer/input_reader/SettingsReader.h"
#include "Version.h"
#include "antares-xpansion/helpers/Timer.h"
#include "antares-xpansion/lpnamer/helper/ProblemGenerationLogger.h"
#include "antares-xpansion/lpnamer/input_reader/GeneralDataReader.h"
#include "antares-xpansion/lpnamer/input_reader/LpFilesExtractor.h"
#include "antares-xpansion/lpnamer/input_reader/MpsTxtWriter.h"
#include "antares-xpansion/lpnamer/input_reader/SettingsReader.h"
#include "antares-xpansion/lpnamer/input_reader/WeightsFileReader.h"
#include "antares-xpansion/lpnamer/input_reader/WeightsFileWriter.h"
#include "antares-xpansion/lpnamer/model/ActiveLinks.h"
#include "antares-xpansion/lpnamer/problem_modifier/AdditionalConstraints.h"
#include "antares-xpansion/lpnamer/problem_modifier/FileProblemsProviderAdapter.h"
#include "antares-xpansion/lpnamer/input_reader/GeneralDataReader.h"
#include "antares-xpansion/lpnamer/problem_modifier/LauncherHelpers.h"
#include "antares-xpansion/lpnamer/problem_modifier/LinkProblemsGenerator.h"
#include "antares-xpansion/xpansion_interfaces/LogUtils.h"
#include "antares-xpansion/lpnamer/input_reader/LpFilesExtractor.h"
#include "antares-xpansion/lpnamer/problem_modifier/MPSFileWriter.h"
#include "antares-xpansion/lpnamer/problem_modifier/MasterGeneration.h"
#include "antares-xpansion/lpnamer/problem_modifier/MasterProblemBuilder.h"
#include "antares-xpansion/lpnamer/input_reader/MpsTxtWriter.h"
#include "antares-xpansion/lpnamer/helper/ProblemGenerationLogger.h"
#include "antares-xpansion/lpnamer/problem_modifier/ProblemVariablesFileAdapter.h"
#include "antares-xpansion/lpnamer/problem_modifier/ProblemVariablesFromProblemAdapter.h"
#include "antares-xpansion/lpnamer/problem_modifier/ProblemVariablesZipAdapter.h"
#include "antares-xpansion/xpansion_interfaces/StringManip.h"
#include "antares-xpansion/helpers/Timer.h"
#include "Version.h"
#include "antares-xpansion/lpnamer/input_reader/WeightsFileReader.h"
#include "antares-xpansion/lpnamer/input_reader/WeightsFileWriter.h"
#include "antares-xpansion/lpnamer/problem_modifier/XpansionProblemsFromAntaresProvider.h"
#include "antares-xpansion/lpnamer/problem_modifier/ZipProblemsProviderAdapter.h"
#include "antares-xpansion/xpansion_interfaces/LogUtils.h"
#include "antares-xpansion/xpansion_interfaces/StringManip.h"
#include "config.h"

static const std::string LP_DIRNAME = "lp";
Expand Down Expand Up @@ -111,6 +113,9 @@ std::filesystem::path ProblemGeneration::updateProblems() {
auto weights_file = options_.WeightsFile();
auto unnamed_problems = options_.UnnamedProblems();

SettingsReader settingsReader(xpansion_output_dir, logger.get());
solver_name_ = settingsReader.Solver();

RunProblemGeneration(xpansion_output_dir, master_formulation,
additionalConstraintFilename_l, archive_path, logger,
log_file_path, weights_file, unnamed_problems);
Expand Down Expand Up @@ -226,7 +231,6 @@ void ProblemGeneration::RunProblemGeneration(
(*logger)(LogUtils::LOGLEVEL::INFO)
<< "Launching Problem Generation" << std::endl;
validateMasterFormulation(master_formulation, logger);
std::string solver_name = "CBC"; // TODO Use solver selected by user

SolverLoader::GetAvailableSolvers(logger); // Dirty fix to populate static
// value outside multi thread code
Expand Down Expand Up @@ -258,14 +262,14 @@ void ProblemGeneration::RunProblemGeneration(
auto solver_log_manager = SolverLogManager(log_file_path);
Couplings couplings;
LinkProblemsGenerator linkProblemsGenerator(
lpDir_, links, solver_name, logger, solver_log_manager, rename_problems);
lpDir_, links, solver_name_, logger, solver_log_manager, rename_problems);
std::shared_ptr<ArchiveReader> reader =
antares_archive_path.empty() ? std::make_shared<ArchiveReader>()
: InstantiateZipReader(antares_archive_path);

/* Main stuff */
std::vector<std::shared_ptr<Problem>> xpansion_problems = getXpansionProblems(
solver_log_manager, solver_name, mpsList, lpDir_, reader, lps_);
solver_log_manager, solver_name_, mpsList, lpDir_, reader, lps_);

std::vector<std::pair<std::shared_ptr<Problem>, ProblemData>>
problems_and_data;
Expand Down Expand Up @@ -323,7 +327,7 @@ void ProblemGeneration::RunProblemGeneration(
}
MasterGeneration master_generation(
xpansion_output_dir, links, additionalConstraints, couplings,
master_formulation, solver_name, logger, solver_log_manager);
master_formulation, solver_name_, logger, solver_log_manager);
(*logger)(LogUtils::LOGLEVEL::INFO)
<< "Problem Generation ran in: "
<< format_time_str(problem_generation_timer.elapsed()) << std::endl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,5 @@ class ProblemGeneration {
std::optional<SimulationInputMode> mode_;
virtual std::filesystem::path performAntaresSimulation();
std::filesystem::path simulation_dir_;
std::string solver_name_;
};
12 changes: 8 additions & 4 deletions src/python/antares_xpansion/antares_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def __init__(self, antares_exe_path: Path) -> None:
self.antares_exe_path = antares_exe_path
# antares study dir is set just before launch
self.data_dir = ""

self.use_xpress = False
self.output = 'output'
self.ANTARES_N_CPU_OPTION = "--force-parallel"
self.antares_n_cpu = 1 # default
Expand All @@ -33,8 +33,9 @@ def __init__(self, antares_exe_path: Path) -> None:
self.FIRST_VERSION_WITH_NAMED_PROBLEMS = "8.7"


def launch(self, antares_study_path, antares_n_cpu: int) -> bool:
def launch(self, antares_study_path, antares_n_cpu: int, use_xpress: bool = False) -> bool:
self._set_antares_n_cpu(antares_n_cpu)
self.use_xpress = use_xpress
return self._launch(antares_study_path)

def _set_antares_n_cpu(self, antares_n_cpu: int):
Expand Down Expand Up @@ -104,8 +105,11 @@ def _set_simulation_name(self):
self.simulation_name = list_of_dirs[-1]

def _get_antares_cmd(self):
cmd = [str(self.antares_exe_path), self.data_dir, self.ANTARES_N_CPU_OPTION, str(self.antares_n_cpu), self.zip_option,
"--use-ortools", "--ortools-solver=sirius"]
cmd = [str(self.antares_exe_path), self.data_dir, self.ANTARES_N_CPU_OPTION, str(self.antares_n_cpu), self.zip_option]
if self.use_xpress:
cmd.extend(["--use-ortools", "--ortools-solver=xpress"])
else:
cmd.extend(["--use-ortools", "--ortools-solver=sirius"])
simulator_version = version.parse(__antares_simulator_version__)
simulator_version_with_named_mps = version.parse(self.FIRST_VERSION_WITH_NAMED_PROBLEMS)
if (simulator_version.major > simulator_version_with_named_mps.major) or (simulator_version.major >= simulator_version_with_named_mps.major and simulator_version.minor >= simulator_version_with_named_mps.minor):
Expand Down
5 changes: 4 additions & 1 deletion src/python/antares_xpansion/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,12 @@ def clean_step(self):

def launch_antares_step(self):
self.update_study_settings(memory_mode=False)

use_xpress = str(self.config_loader.options["solver"]).capitalize() == "XPRESS"

try:
ret = self.antares_driver.launch(
self.config_loader.data_dir(), self.config_loader.antares_n_cpu())
self.config_loader.data_dir(), self.config_loader.antares_n_cpu(), use_xpress)
if ret is False:
self._revert_general_data_ini()
else:
Expand Down
34 changes: 18 additions & 16 deletions tests/cpp/lp_namer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,32 @@ find_package (GTest REQUIRED)
# unit tests
# --------------------------------------------------------------------------
add_executable (lp_namer_tests
AdditionalConstraintsTest.cc
ActiveLinkTest.cpp
AdditionalConstraintsReaderTest.cc
LinkdataRecordTest.cc
StudyUpdateTest.cc
AdditionalConstraintsTest.cc
AntaresProblemToXpansionProblemTranslatorTest.cpp
CandidatesINIReaderTest.cpp
ActiveLinkTest.cpp
ChronicleMapProviderTest.cpp
ChronicleMapReaderTest.cpp
GeneralDataReadetTests.cpp
LinkProfileReaderTest.cpp
ProblemModifierTest.cpp
VariableFileReaderTest.cpp
LinkdataRecordTest.cc
LoggerBuilder.cpp
LoggerBuilder.h
LpFilesExtractorTest.cpp
MasterProblemBuilderTest.cpp
ChronicleMapReaderTest.cpp
ChronicleMapProviderTest.cpp
ProblemConstructionTest.cpp
MpsTxtWriterTest.cpp
NOOPSolver.h
ProblemConstructionTest.cpp
ProblemGenerationExeOptionsTest.cpp
LoggerBuilder.h
LoggerBuilder.cpp
ProblemGenerationLoggerTest.cpp
ProblemModifierTest.cpp
ProblemVariablesFromProblemAdapterTest.cpp
SettingsReaderTest.cpp
StudyUpdateTest.cc
VariableFileReaderTest.cpp
WeightsFileReaderTest.cpp
WeightsFileWriterTest.cpp
LpFilesExtractorTest.cpp
MpsTxtWriterTest.cpp
AntaresProblemToXpansionProblemTranslatorTest.cpp
GeneralDataReadetTests.cpp
ProblemVariablesFromProblemAdapterTest.cpp
)

target_link_libraries (lp_namer_tests PRIVATE
Expand All @@ -51,6 +52,7 @@ target_link_libraries (lp_namer_tests PRIVATE
antaresXpansion::lp_namer_problem_modifier
antaresXpansion::xpansion_study_updater_lib
antaresXpansion::problem_generation_main
antaresXpansion::tests_utils
)


Expand Down
49 changes: 49 additions & 0 deletions tests/cpp/lp_namer/SettingsReaderTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include <fstream>

#include "LoggerBuilder.h"
#include "RandomDirGenerator.h"
#include "antares-xpansion/lpnamer/input_reader/SettingsReader.h"
#include "gtest/gtest.h"

TEST(ReadSettings, ReadSettingsProperly) {
auto tmp_path = CreateRandomSubDir(std::filesystem::temp_directory_path());
std::ofstream settings_file(tmp_path / "settings.ini");
settings_file << R"(
uc_type = expansion_fast
master = integer
optimality_gap = 10
additional-constraints = contraintes.txt
solver = Xpress
)" << std::endl;
auto logger = emptyLogger();
ASSERT_NO_THROW(SettingsReader reader(tmp_path / "settings.ini", logger.get()));
}

TEST(ReadSettings, DefaultSolverIsCBC) {
auto tmp_path = CreateRandomSubDir(std::filesystem::temp_directory_path());
std::ofstream settings_file(tmp_path / "settings.ini");
settings_file << R"(
uc_type = expansion_fast
master = integer
optimality_gap = 10
additional-constraints = contraintes.txt
)"<< std::endl;;
auto logger = emptyLogger();
SettingsReader reader(tmp_path / "settings.ini", logger.get());
ASSERT_EQ(reader.Solver(), "CBC");
}

TEST(ReadSettings, ReadSolverProperly) {
auto tmp_path = CreateRandomSubDir(std::filesystem::temp_directory_path());
std::ofstream settings_file(tmp_path / "settings.ini");
settings_file << R"(
uc_type = expansion_fast
master = integer
optimality_gap = 10
additional-constraints = contraintes.txt
solver = Xpress
)"<< std::endl;
auto logger = emptyLogger();
SettingsReader reader(tmp_path / "settings.ini", logger.get());
ASSERT_EQ(reader.Solver(), "Xpress");
}

0 comments on commit 8ddf4c8

Please sign in to comment.