Skip to content

Commit

Permalink
implement SolverLogManager
Browse files Browse the repository at this point in the history
  • Loading branch information
a-zakir committed Oct 11, 2023
1 parent c407a97 commit c4ef40a
Show file tree
Hide file tree
Showing 16 changed files with 83 additions and 64 deletions.
9 changes: 5 additions & 4 deletions src/cpp/benders/benders_core/Worker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,13 @@ void Worker::init(VariableMap const &variable_map,
const std::filesystem::path &log_name) {
_path_to_mps = path_to_mps;
SolverFactory factory;
auto solver_log_manager = std::make_shared<SolverLogManager>(log_name);
if (_is_master) {
_solver =
factory.create_solver(solver_name, SOLVER_TYPE::INTEGER, log_name);
_solver = factory.create_solver(solver_name, SOLVER_TYPE::INTEGER,
solver_log_manager);
} else {
_solver =
factory.create_solver(solver_name, SOLVER_TYPE::CONTINUOUS, log_name);
_solver = factory.create_solver(solver_name, SOLVER_TYPE::CONTINUOUS,
solver_log_manager);
}

_solver->init();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ AntaresProblemToXpansionProblemTranslator::translateToXpansionProblem(
const std::string& solver_name,
const std::filesystem::path& log_file_path) {
SolverFactory factory;
auto solver_log_manager = std::make_shared<SolverLogManager>(log_file_path);
auto problem = std::make_shared<Problem>(
factory.create_solver(solver_name, log_file_path));
factory.create_solver(solver_name, solver_log_manager));
problem->init();
const auto& constant = lps._constant;
const auto& hebdo = lps._hebdo.at({year, week});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ std::shared_ptr<Problem> MPSFileProblemProviderAdapter::provide_problem(
const std::filesystem::path& log_file_path) const {
SolverFactory factory;
auto const lp_mps_name = lp_dir_ / problem_name_;
auto solver_log_manager = std::make_shared<SolverLogManager>(log_file_path);
auto in_prblm = std::make_shared<Problem>(
factory.create_solver(solver_name, log_file_path));
factory.create_solver(solver_name, solver_log_manager));

in_prblm->read_prob_mps(lp_mps_name);
return in_prblm;
Expand Down
3 changes: 2 additions & 1 deletion src/cpp/lpnamer/problem_modifier/MasterProblemBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ std::shared_ptr<SolverAbstract> MasterProblemBuilder::build(
_indexOfPmaxVar.clear();

SolverFactory factory;
auto master_l = factory.create_solver(solverName, log_file_path);
auto solver_log_manager = std::make_shared<SolverLogManager>(log_file_path);
auto master_l = factory.create_solver(solverName, solver_log_manager);

addVariablesPmaxOnEachCandidate(candidates, master_l);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ std::shared_ptr<Problem> ZipProblemProviderAdapter::provide_problem(
SolverFactory factory;
auto const lp_mps_name = ZipProblemProviderAdapter::lp_dir_ /
ZipProblemProviderAdapter::problem_name_;
auto solver_log_manager = std::make_shared<SolverLogManager>(log_file_path);
auto in_prblm = std::make_shared<Problem>(
factory.create_solver(solver_name, log_file_path));
factory.create_solver(solver_name, solver_log_manager));

in_prblm->read_prob_mps(lp_mps_name);
return in_prblm;
Expand Down
27 changes: 9 additions & 18 deletions src/cpp/multisolver_interface/SolverCbc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,16 @@
*************************************************************************************************/
int SolverCbc::_NumberOfProblems = 0;

SolverCbc::SolverCbc(const std::filesystem::path &log_file) : SolverCbc() {
_log_file = log_file;
if (_log_file.empty()) {
SolverCbc::SolverCbc(std::shared_ptr<SolverLogManager> log_manager)
: SolverCbc() {
_fp = log_manager->log_file_ptr;
if (!_fp) {
std::cout << "Empty log file name, fallback to default behaviour"
<< std::endl;
} else {
if ((_fp = fopen(_log_file.string().c_str(), "a+")) == nullptr) {
std::cerr << "Invalid log file name passed as parameter: " << _log_file
<< std::endl;
} else {
setvbuf(_fp, nullptr, _IONBF, 0);
_clp_inner_solver.messageHandler()->setFilePointer(_fp);
_cbc.messageHandler()->setFilePointer(_fp);
}
setvbuf(_fp, nullptr, _IONBF, 0);
_clp_inner_solver.messageHandler()->setFilePointer(_fp);
_cbc.messageHandler()->setFilePointer(_fp);
}
}
SolverCbc::SolverCbc() {
Expand All @@ -34,9 +30,8 @@ SolverCbc::SolverCbc(const std::shared_ptr<const SolverAbstract> toCopy)
// Try to cast the solver in fictif to a SolverCbc
if (const auto c = dynamic_cast<const SolverCbc *>(toCopy.get())) {
_clp_inner_solver = OsiClpSolverInterface(c->_clp_inner_solver);
_log_file = toCopy->_log_file;
_fp = fopen(_log_file.string().c_str(), "a+");
if (_fp != nullptr) {
_fp = toCopy->_fp;
if (_fp) {
setvbuf(_fp, nullptr, _IONBF, 0);
_clp_inner_solver.messageHandler()->setFilePointer(_fp);
_cbc.messageHandler()->setFilePointer(_fp);
Expand All @@ -51,10 +46,6 @@ SolverCbc::SolverCbc(const std::shared_ptr<const SolverAbstract> toCopy)

SolverCbc::~SolverCbc() {
_NumberOfProblems -= 1;
if (_fp != nullptr) {
fclose(_fp);
_fp = nullptr;
}
free();
}

Expand Down
2 changes: 1 addition & 1 deletion src/cpp/multisolver_interface/SolverCbc.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class SolverCbc : public SolverAbstract {
* @brief Default constructor of a CBC solver
*/
SolverCbc();
explicit SolverCbc(const std::filesystem::path &log_file);
explicit SolverCbc(std::shared_ptr<SolverLogManager> log_manager);

/**
* @brief Copy constructor of solver, copy the problem toCopy in memory and
Expand Down
27 changes: 8 additions & 19 deletions src/cpp/multisolver_interface/SolverClp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,29 @@
*************************************************************************************************/
int SolverClp::_NumberOfProblems = 0;

SolverClp::SolverClp(const std::filesystem::path &log_file) : SolverClp() {
_log_file = log_file;
if (_log_file.empty()) {
SolverClp::SolverClp(std::shared_ptr<SolverLogManager> log_manager)
: SolverClp() {
_fp = log_manager->log_file_ptr;
if (!log_manager) {
std::cout << "Empty log file name, fallback to default behaviour"
<< std::endl;
} else {
if ((_fp = fopen(_log_file.string().c_str(), "a+")) == NULL) {
std::cerr << "Invalid log file name passed as parameter: " << _log_file
<< std::endl;
} else {
setvbuf(_fp, NULL, _IONBF, 0);
_clp.messageHandler()->setFilePointer(_fp);
}
setvbuf(log_manager->log_file_ptr, NULL, _IONBF, 0);
_clp.messageHandler()->setFilePointer(log_manager->log_file_ptr);
}
}
SolverClp::SolverClp() {
_NumberOfProblems += 1;
_fp = nullptr;
set_output_log_level(0);
}

SolverClp::SolverClp(const std::shared_ptr<const SolverAbstract> toCopy)
: SolverClp() {
_fp = nullptr;
// Try to cast the solver in fictif to a SolverClp
if (const auto c = dynamic_cast<const SolverClp *>(toCopy.get())) {
_clp = ClpSimplex(c->_clp);
_log_file = toCopy->_log_file;
_fp = fopen(_log_file.string().c_str(), "a+");
if (_fp != nullptr) {
_fp = toCopy->_fp;
if (_fp) {
setvbuf(_fp, nullptr, _IONBF, 0);
_clp.messageHandler()->setFilePointer(_fp);
}
Expand All @@ -50,10 +43,6 @@ SolverClp::SolverClp(const std::shared_ptr<const SolverAbstract> toCopy)

SolverClp::~SolverClp() {
_NumberOfProblems -= 1;
if (_fp != nullptr) {
fclose(_fp);
_fp = nullptr;
}
free();
}

Expand Down
2 changes: 1 addition & 1 deletion src/cpp/multisolver_interface/SolverClp.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class SolverClp : public SolverAbstract {
* @brief Default constructor of a CLP solver
*/
SolverClp();
explicit SolverClp(const std::filesystem::path &log_file);
explicit SolverClp(std::shared_ptr<SolverLogManager> log_manager);

/**
* @brief Copy constructor of CLP, copy the problem toCopy in memory and name
Expand Down
22 changes: 12 additions & 10 deletions src/cpp/multisolver_interface/SolverFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,40 +21,42 @@ SolverFactory::SolverFactory() {

SolverAbstract::Ptr SolverFactory::create_solver(
const std::string &solver_name, const SOLVER_TYPE solver_type) const {
return create_solver(solver_name, solver_type, "");
auto log_manager = std::make_shared<SolverLogManager>("");
return create_solver(solver_name, solver_type, log_manager);
}
SolverAbstract::Ptr SolverFactory::create_solver(
const std::string &solver_name, const SOLVER_TYPE solver_type,
const std::filesystem::path &log_name) const {
std::shared_ptr<SolverLogManager> log_manager) const {
#ifdef COIN_OR
if (solver_name == COIN_STR && solver_type == SOLVER_TYPE::CONTINUOUS) {
return std::make_shared<SolverClp>(log_name);
return std::make_shared<SolverClp>(log_manager);
} else if (solver_name == COIN_STR && solver_type == SOLVER_TYPE::INTEGER) {
return std::make_shared<SolverCbc>(log_name);
return std::make_shared<SolverCbc>(log_manager);
}
#endif
return create_solver(solver_name, log_name);
return create_solver(solver_name, log_manager);
}
SolverAbstract::Ptr SolverFactory::create_solver(
const std::string &solver_name) const {
return create_solver(solver_name, "");
auto log_manager = std::make_shared<SolverLogManager>("");
return create_solver(solver_name, log_manager);
}
SolverAbstract::Ptr SolverFactory::create_solver(
const std::string &solver_name,
const std::filesystem::path &log_name) const {
std::shared_ptr<SolverLogManager> log_manager) const {
if (solver_name == "") {
throw InvalidSolverNameException(solver_name, LOGLOCATION);
}
#ifdef XPRESS
else if (solver_name == XPRESS_STR) {
return std::make_shared<SolverXpress>(log_name);
return std::make_shared<SolverXpress>(log_manager);
}
#endif
#ifdef COIN_OR
else if (solver_name == CLP_STR) {
return std::make_shared<SolverClp>(log_name);
return std::make_shared<SolverClp>(log_manager);
} else if (solver_name == CBC_STR) {
return std::make_shared<SolverCbc>(log_name);
return std::make_shared<SolverCbc>(log_manager);
}
#endif
else {
Expand Down
4 changes: 2 additions & 2 deletions src/cpp/multisolver_interface/SolverXpress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ int SolverXpress::_NumberOfProblems = 0;
std::mutex SolverXpress::license_guard;
const std::map<int, std::string> TYPETONAME = {{1, "rows"}, {2, "columns"}};

SolverXpress::SolverXpress(const std::filesystem::path &log_file)
SolverXpress::SolverXpress(std::shared_ptr<SolverLogManager> log_manager)
: SolverXpress() {
_log_file = log_file;
_log_file = log_manager->log_file_path;
if (_log_file != "") {
_log_stream.open(_log_file, std::ofstream::out | std::ofstream::app);
add_stream(_log_stream);
Expand Down
2 changes: 1 addition & 1 deletion src/cpp/multisolver_interface/SolverXpress.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class SolverXpress : public SolverAbstract {
* @brief Default constructor of a XPRESS solver
*/
SolverXpress();
SolverXpress(const std::filesystem::path &log_file);
SolverXpress(std::shared_ptr<SolverLogManager> log_manager);

/**
* @brief Copy constructor of XPRESS, copy the problem toCopy in memory and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <cstdio>
#include <filesystem>
#include <iomanip>
#include <iostream>
#include <list>
#include <memory>
Expand All @@ -12,6 +13,32 @@

#include "LogUtils.h"

class SolverLogManager {
public:
explicit SolverLogManager(const std::filesystem::path &log_file)
: log_file_path(log_file) {
#ifdef __linux__
if ((log_file_ptr = fopen(log_file_path.string().c_str(), "a+")) == nullptr)
#elif _WIN32
if ((log_file_ptr = _fsopen(log_file_path.string().c_str(), "a+",
_SH_DENYNO)) == nullptr)
#endif
{
std::cerr << "Invalid log file name passed as parameter: "
<< std::quoted(log_file.string()) << std::endl;
}
}
~SolverLogManager() {
if (log_file_ptr) {
fclose(log_file_ptr);
log_file_ptr = nullptr;
}
}

FILE *log_file_ptr = nullptr;
std::filesystem::path log_file_path = "";
};

class InvalidStatusException
: public LogUtils::XpansionError<std::runtime_error> {
public:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class SolverFactory {
SolverAbstract::Ptr create_solver(const std::string &solver_name) const;
SolverAbstract::Ptr create_solver(
const std::string &solver_name,
const std::filesystem::path &log_name) const;
std::shared_ptr<SolverLogManager> log_manager) const;

/**
* @brief Creates and returns to an object solver from the wanted
Expand All @@ -46,7 +46,7 @@ class SolverFactory {
const SOLVER_TYPE solver_type) const;
SolverAbstract::Ptr create_solver(
const std::string &solver_name, const SOLVER_TYPE solver_type,
const std::filesystem::path &log_name) const;
std::shared_ptr<SolverLogManager> log_manager) const;

/**
* @brief Copy constructor : Creates and returns to an object solver from the
Expand Down
5 changes: 4 additions & 1 deletion tests/cpp/sensitivity/SensitivityPbModifierTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ class SensitivityProblemModifierTest : public ::testing::Test
std::string solver_name = "CBC";
SolverFactory factory;

SolverAbstract::Ptr solver_model = factory.create_solver(solver_name, std::tmpnam(nullptr));
auto solver_log_manager =
std::make_shared<SolverLogManager>(std::tmpnam(nullptr));
SolverAbstract::Ptr solver_model =
factory.create_solver(solver_name, solver_log_manager);
solver_model->init();
solver_model->read_prob_mps(last_master_mps_path);

Expand Down
4 changes: 3 additions & 1 deletion tests/cpp/sensitivity/SensitivityStudyTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ class SensitivityStudyTest : public ::testing::Test {

void init_solver(std::string solver_name, std::string last_master_mps_path) {
SolverFactory factory;
math_problem = factory.create_solver(solver_name, std::tmpnam(nullptr));
auto solver_log_manager =
std::make_shared<SolverLogManager>(std::tmpnam(nullptr));
math_problem = factory.create_solver(solver_name, solver_log_manager);
math_problem->init();
math_problem->read_prob_mps(last_master_mps_path);
}
Expand Down

0 comments on commit c4ef40a

Please sign in to comment.