Skip to content

Commit

Permalink
Handle save/restore in benders
Browse files Browse the repository at this point in the history
  • Loading branch information
JasonMarechal25 committed Jan 17, 2025
1 parent e4db64e commit f778faf
Show file tree
Hide file tree
Showing 13 changed files with 117 additions and 60 deletions.
4 changes: 2 additions & 2 deletions src/cpp/benders/benders_core/BendersBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -774,7 +774,7 @@ void BendersBase::AddSubproblem(
subproblem_map[kvp.first] = std::make_shared<SubproblemWorker>(
kvp.second, GetSubproblemPath(kvp.first),
SubproblemWeight(_data.nsubproblem, kvp.first), _options.SOLVER_NAME,
_options.LOG_LEVEL, solver_log_manager_, _logger);
_options.LOG_LEVEL, solver_log_manager_, _logger, _options.PROBLEMS_FORMAT);
}

void BendersBase::free_subproblems() {
Expand Down Expand Up @@ -953,7 +953,7 @@ void BendersBase::ResetMasterFromLastIteration() {
reset_master<WorkerMaster>(master_variable_map_, LastMasterPath(),
get_solver_name(), get_log_level(),
_data.nsubproblem, solver_log_manager_,
IsResumeMode(), _logger);
IsResumeMode(), _logger, Options().PROBLEMS_FORMAT);
}
bool BendersBase::MasterIsEmpty() const { return master_is_empty_; }

Expand Down
4 changes: 4 additions & 0 deletions src/cpp/benders/benders_core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ target_sources(benders_core PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/LastIterationReader.cpp
${CMAKE_CURRENT_SOURCE_DIR}/LastIterationWriter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/MasterUpdateBase.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ProblemFormatStream.cpp
${CMAKE_CURRENT_SOURCE_DIR}/SimulationOptions.cpp
${CMAKE_CURRENT_SOURCE_DIR}/SolverIO.cpp
${CMAKE_CURRENT_SOURCE_DIR}/StartUp.cpp
${CMAKE_CURRENT_SOURCE_DIR}/SubproblemWorker.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Worker.cpp
Expand All @@ -40,7 +42,9 @@ target_sources(benders_core PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/benders/benders_core/LastIterationWriter.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/benders/benders_core/MasterUpdate.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/benders/benders_core/ProblemFormat.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/benders/benders_core/ProblemFormatStream.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/benders/benders_core/SimulationOptions.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/benders/benders_core/SolverIO.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/benders/benders_core/StartUp.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/benders/benders_core/SubproblemWorker.h
${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/benders/benders_core/VariablesGroup.h
Expand Down
1 change: 1 addition & 0 deletions src/cpp/benders/benders_core/SimulationOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <filesystem>

#include "antares-xpansion/xpansion_interfaces/LogUtils.h"
#include "antares-xpansion/benders/benders_core/ProblemFormatStream.h"
Json::Value SimulationOptions::get_value_from_json(
const std::filesystem::path &file_name) {
Json::Value _input;
Expand Down
37 changes: 37 additions & 0 deletions src/cpp/benders/benders_core/SolverIO.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@

#include <antares-xpansion/benders/benders_core/SolverIO.h>
#include <antares-xpansion/benders/benders_core/ProblemFormatStream.h>
#include <fmt/format.h>

void SolverIO::write(SolverAbstract* solver,
const std::filesystem::path& path) const {
switch (format_) {
case ProblemsFormat::MPS_FILE:
solver->write_prob_mps(path);
break;
case ProblemsFormat::SAVED_FILE:
solver->save_prob(path);
break;
default:
throw LogUtils::XpansionError<std::runtime_error>(
fmt::format("Unknown file format {} for problem file: {}", format_, path.string()), LOGLOCATION);
}
}
void SolverIO::read(SolverAbstract* solver,
const std::filesystem::path& path) const {
switch (format_) {
case ProblemsFormat::MPS_FILE:
solver->read_prob_mps(path);
break;
case ProblemsFormat::SAVED_FILE:
solver->restore_prob(path);
break;
default:
throw LogUtils::XpansionError<std::runtime_error>(
fmt::format("Unknown file format {} for problem file: {}", format_, path.string()), LOGLOCATION);
}
}
void SolverIO::configure(const std::string& solver_name, ProblemsFormat format) {
solver_config_ = solver_name;
format_ = format;
}
17 changes: 11 additions & 6 deletions src/cpp/benders/benders_core/SubproblemWorker.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "antares-xpansion/benders/benders_core/SubproblemWorker.h"

#include <utility>

#include "antares-xpansion/helpers/solver_utils.h"

/*!
Expand All @@ -10,12 +12,15 @@
* \param problem_name : Name of the problem
*
*/
SubproblemWorker::SubproblemWorker(
VariableMap const &variable_map, const std::filesystem::path &path_to_mps,
double const &slave_weight, const std::string &solver_name,
const int log_level, SolverLogManager &solver_log_manager, Logger logger)
: Worker(std::move(logger)) {
init(variable_map, path_to_mps, solver_name, log_level, solver_log_manager);
SubproblemWorker::SubproblemWorker(VariableMap const &variable_map,
const std::filesystem::path &path_to_mps,
double const &slave_weight,
const std::string &solver_name,
const int log_level,
SolverLogManager &solver_log_manager,
Logger logger, ProblemsFormat format)
: Worker(variable_map, path_to_mps, std::move(logger)) {
init(solver_name, log_level, solver_log_manager, format);

int mps_ncols(_solver->get_ncols());
DblVector obj_func_coeffs(mps_ncols);
Expand Down
43 changes: 22 additions & 21 deletions src/cpp/benders/benders_core/Worker.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#include "antares-xpansion/benders/benders_core/Worker.h"

#include "antares-xpansion/xpansion_interfaces/LogUtils.h"
#include <utility>

#include "antares-xpansion/helpers/solver_utils.h"
#include "antares-xpansion/xpansion_interfaces/LogUtils.h"
/*!
* \brief Free the problem
*/
Expand Down Expand Up @@ -34,11 +35,9 @@ void Worker::get_value(double &lb) const {
*
* \param problem_name : name of the problem
*/
void Worker::init(VariableMap const &variable_map,
const std::filesystem::path &path_to_mps,
std::string const &solver_name, int log_level,
SolverLogManager&solver_log_manager) {
_path_to_mps = path_to_mps;
void Worker::init(const std::string &solver_name, int log_level,
SolverLogManager &solver_log_manager, ProblemsFormat format) {
solver_io_.configure(solver_name, format);
SolverFactory factory(logger_);

if (_is_master) {
Expand All @@ -51,11 +50,9 @@ void Worker::init(VariableMap const &variable_map,

_solver->set_threads(1);
_solver->set_output_log_level(log_level);
read_prob(_solver.get(), path_to_mps);
read_prob(_solver.get(), _path_to_mps);

_name_to_id = variable_map;

for (auto const &kvp : variable_map) {
for (auto const &kvp : _name_to_id) {
_id_to_name[kvp.second] = kvp.first;
}
}
Expand Down Expand Up @@ -85,7 +82,7 @@ void Worker::solve(int &lp_status, const std::string &outputroot,

msg << "written in " << error_file_path.string() << std::endl;
logger_->display_message(msg.str());
_solver->write_prob_mps(error_file_path);
writeProb(error_file_path);
Output::ProblemData data;
data.name = _path_to_mps.filename().string();
data.path = error_file_path;
Expand All @@ -100,8 +97,7 @@ void Worker::solve(int &lp_status, const std::string &outputroot,
}

if (_is_master) {
_solver->write_prob_mps(std::filesystem::path(outputroot) /
output_master_mps_file_name);
writeProb(std::filesystem::path(outputroot) / output_master_mps_file_name);
}
}
/*!
Expand Down Expand Up @@ -150,13 +146,18 @@ int Worker::Getncols() const { return _solver->get_ncols(); }
* @param problem
* @param path
*/
void Worker::read_prob(SolverAbstract * problem,
void Worker::read_prob(SolverAbstract *problem,
const std::filesystem::path &path) const {
if (path.extension() == ".mps") {
problem->read_prob_mps(path);
} else if (path.extension() == ".svf") {//Brittle
problem->restore_prob(path);
} else {
throw LogUtils::XpansionError<std::runtime_error>("Unknown file extension for problem file: " + path.string(), LOGLOCATION);
}
solver_io_.read(_solver.get(), path);
}
std::shared_ptr<SolverAbstract> Worker::solver() const { return _solver; }

Worker::Worker(VariableMap variable_map, std::filesystem::path path_to_mps,
Logger logger)
: _path_to_mps{std::move(path_to_mps)},
_name_to_id{std::move(variable_map)},
logger_{std::move(logger)} {}

void Worker::writeProb(const std::filesystem::path &out) const {
solver_io_.write(_solver.get(), out);
}
25 changes: 11 additions & 14 deletions src/cpp/benders/benders_core/WorkerMaster.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
#include "antares-xpansion/benders/benders_core/WorkerMaster.h"


#include "antares-xpansion/helpers/solver_utils.h"

WorkerMaster::WorkerMaster(Logger logger) : Worker(logger) {
_is_master = true;
}

/*!
* \brief Constructor of a Master Problem
*
Expand All @@ -19,17 +14,19 @@ WorkerMaster::WorkerMaster(Logger logger) : Worker(logger) {
* \param log_level : solver log level
* \param subproblems_count : number of subproblems
*/
WorkerMaster::WorkerMaster(
VariableMap const &variable_map, const std::filesystem::path &path_to_mps,
const std::string &solver_name, const int log_level, int subproblems_count,
SolverLogManager&solver_log_manager,
const bool mps_has_alpha, Logger logger)
: Worker(std::move(logger)),
subproblems_count(subproblems_count),
_mps_has_alpha(mps_has_alpha) {
WorkerMaster::WorkerMaster(VariableMap const &variable_map,
const std::filesystem::path &path_to_mps,
const std::string &solver_name, const int log_level,
int subproblems_count,
SolverLogManager &solver_log_manager,
const bool mps_has_alpha, Logger logger, ProblemsFormat format)
: Worker(variable_map, path_to_mps, std::move(logger)),
subproblems_count{subproblems_count},
_mps_has_alpha{mps_has_alpha}
{
_is_master = true;

init(variable_map, path_to_mps, solver_name, log_level, solver_log_manager);
init(solver_name, log_level, solver_log_manager, format);
if (!_mps_has_alpha) {
_set_upper_bounds();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

#include "ProblemFormat.h"
#include "antares-xpansion/multisolver_interface/SolverAbstract.h"
#include "antares-xpansion/multisolver_interface/SolverConfig.h"

class SolverIO {
SolverConfig solver_config_{"Coin"};
ProblemsFormat format_;
public:
void configure(const std::string& solver_name, ProblemsFormat format);
void write(SolverAbstract* solver, const std::filesystem::path& path) const;
void read(SolverAbstract* solver, const std::filesystem::path& path) const;
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ typedef std::map<std::string, SubproblemWorkerPtr> SubproblemsMapPtr;

class SubproblemWorker : public Worker {
public:
explicit SubproblemWorker(Logger logger) : Worker(logger) {}
using Worker::Worker;
SubproblemWorker(VariableMap const &variable_map,
const std::filesystem::path &path_to_mps,
double const &slave_weight, const std::string &solver_name,
const int log_level,
SolverLogManager&solver_log_manager,
Logger logger);
Logger logger, ProblemsFormat format);
virtual ~SubproblemWorker() = default;
void get_solution(std::vector<double> &solution) const;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,24 @@

#include <filesystem>

#include "SolverIO.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"
#include "antares-xpansion/multisolver_interface/Solver.h"
class Worker;
typedef std::shared_ptr<Worker> WorkerPtr;

/*!
* \class Worker
* \brief Mother-class Worker
*
* This class opens and sets a problem from a mps and a mapping variable map
*/

class Worker {
public:
explicit Worker(Logger logger) : logger_(std::move(logger)) {}
void init(VariableMap const &variable_map,
const std::filesystem::path &path_to_mps,
std::string const &solver_name, int log_level,
SolverLogManager&solver_log_manager);
Worker(VariableMap variable_map, std::filesystem::path path_to_mps,
Logger logger);
void init(const std::string &solver_name, int log_level,
SolverLogManager &solver_log_manager, ProblemsFormat format);
virtual ~Worker() = default;

void get_value(double &lb) const;
Expand All @@ -31,7 +28,7 @@ class Worker {

void free();
void write_basis(const std::filesystem::path &filename) const;
virtual SolverAbstract::Ptr solver() const { return _solver; }
[[nodiscard]] virtual std::shared_ptr<SolverAbstract> solver() const;

public:
std::filesystem::path _path_to_mps;
Expand Down Expand Up @@ -65,7 +62,7 @@ class Worker {
int Getncols() const;

public:
SolverAbstract::Ptr _solver =
std::shared_ptr<SolverAbstract> _solver =
nullptr; /*!< Problem stocked in the instance Worker*/
bool _is_master = false;

Expand All @@ -74,4 +71,6 @@ class Worker {
private:
void read_prob(SolverAbstract * problem,
const std::filesystem::path &path) const;
SolverIO solver_io_;
void writeProb(const std::filesystem::path& out) const;
};
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,12 @@ typedef std::shared_ptr<WorkerMaster> WorkerMasterPtr;

class WorkerMaster : public Worker {
public:
explicit WorkerMaster(Logger logger);
WorkerMaster(VariableMap const &variable_map,
const std::filesystem::path &path_to_mps,
const std::string &solver_name, int log_level,
int subproblems_count,
SolverLogManager&solver_log_manager,
bool mps_has_alpha, Logger logger);
bool mps_has_alpha, Logger logger, ProblemsFormat format);
~WorkerMaster() override = default;

void get(Point &x0, double &overall_subpb_cost_under_approx,
Expand Down
2 changes: 1 addition & 1 deletion src/cpp/benders/benders_mpi/BendersMPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ void BendersMpi::BuildMasterProblem() {
reset_master<WorkerMaster>(master_variable_map_, get_master_path(),
get_solver_name(), get_log_level(),
_data.nsubproblem, solver_log_manager_,
IsResumeMode(), _logger);
IsResumeMode(), _logger, Options().PROBLEMS_FORMAT);
}
}
/*!
Expand Down
2 changes: 1 addition & 1 deletion src/cpp/benders/benders_sequential/BendersSequential.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ void BendersSequential::InitializeProblems() {
reset_master<WorkerMaster>(master_variable_map_, get_master_path(),
get_solver_name(), get_log_level(),
_data.nsubproblem, solver_log_manager_,
IsResumeMode(), _logger);
IsResumeMode(), _logger, Options().PROBLEMS_FORMAT);
for (const auto &problem : coupling_map_) {
const auto subProblemFilePath = GetSubproblemPath(problem.first);

Expand Down

0 comments on commit f778faf

Please sign in to comment.