Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Manage multithreads logs #1764

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
78790e6
set multi threads log dir
a-zakir Nov 12, 2023
151dedd
[skip ci] will not work thank u @guilpier-code
a-zakir Nov 16, 2023
6da7fde
fstream-->ostream ptr
a-zakir Nov 16, 2023
d0697c4
[skip ci] move streams creation
a-zakir Nov 16, 2023
b6e4720
dirty
a-zakir Nov 16, 2023
1586ab5
[skip] better
a-zakir Nov 16, 2023
81ef7b0
suggestion by @flomnes
a-zakir Nov 16, 2023
c935389
direct call
a-zakir Nov 17, 2023
b2a612a
delete deprecated method
a-zakir Nov 17, 2023
2775642
[skip ci] set field width for incoming msg
a-zakir Nov 17, 2023
a69f2df
test SiriusCallback
a-zakir Nov 17, 2023
9756b55
Merge branch 'feature/multi-threads-solver-logs' of https://github.co…
a-zakir Nov 17, 2023
5769816
[skip ci] fix
a-zakir Nov 17, 2023
8c615ae
test Sirius callback: ok
a-zakir Nov 17, 2023
c8d8f82
adaptation for COIN solvers
a-zakir Nov 23, 2023
1535d8c
bug
a-zakir Nov 23, 2023
b1dce69
set log files per thread
a-zakir Nov 23, 2023
30853d1
tmp Revert "bug"
a-zakir Nov 23, 2023
9d1db92
Merge branch 'feature/multi-threads-solver-logs' of https://github.co…
a-zakir Nov 23, 2023
df4a671
copy log files
a-zakir Nov 23, 2023
3a24ba1
remove &
a-zakir Nov 23, 2023
14b1150
fix
a-zakir Nov 23, 2023
00926bc
ok
a-zakir Nov 23, 2023
0a44ba7
clean&clear
a-zakir Nov 23, 2023
568e8f0
update log handler
a-zakir Dec 11, 2023
ae4c29f
update log handler (#1793)
a-zakir Dec 14, 2023
9f44c53
Merge branch 'feature/multi-threads-solver-logs' of https://github.co…
a-zakir Dec 15, 2023
f1cb6aa
remove old code & update
a-zakir Dec 15, 2023
e63468c
use numSpace and thread number
a-zakir Dec 19, 2023
becdf7f
update & fix
a-zakir Dec 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 58 additions & 20 deletions src/solver/optimisation/opt_appel_solveur_lineaire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ extern "C"
{
#include "spx_definition_arguments.h"
#include "spx_fonctions.h"

#include "sirius_callback.h"
#include "srs_api.h"
}

Expand Down Expand Up @@ -96,16 +96,21 @@ struct SimplexResult
long long solveTime = 0;
mpsWriterFactory mps_writer_factory;
};

static SimplexResult OPT_TryToCallSimplex(
const OptimizationOptions& options,
PROBLEME_HEBDO* problemeHebdo,
Optimization::PROBLEME_SIMPLEXE_NOMME& Probleme,
const int NumIntervalle,
const int optimizationNumber,
const OptPeriodStringGenerator& optPeriodStringGenerator,
bool PremierPassage,
IResultWriter& writer)
int SiriusCallback_function(void* caller, const char* sMsg, int nLen, SIRIUS_LOGLEVEL log_level)
{
auto* stdcout = reinterpret_cast<std::ostream*>(caller);
(*stdcout) << sMsg;
return 0;
}
static SimplexResult OPT_TryToCallSimplex(const OptimizationOptions& options,
PROBLEME_HEBDO* problemeHebdo,
Optimization::PROBLEME_SIMPLEXE_NOMME& Probleme,
const int NumIntervalle,
const int optimizationNumber,
const OptPeriodStringGenerator& optPeriodStringGenerator,
bool PremierPassage,
IResultWriter& writer,
OrtoolsLogHandler& ortools_logger)
a-zakir marked this conversation as resolved.
Show resolved Hide resolved
{
const auto& ProblemeAResoudre = problemeHebdo->ProblemeAResoudre;
auto ProbSpx
Expand Down Expand Up @@ -220,12 +225,20 @@ static SimplexResult OPT_TryToCallSimplex(
Probleme.CoutsReduits = ProblemeAResoudre->CoutsReduits.data();

Probleme.NombreDeContraintesCoupes = 0;
// this must be done in Sirius
// auto call_back = (callback_function)Probleme.callback;
// call_back = SiriusCallback_function;
// SPXsetcbmessage(ProbSpx, SiriusCallback_function, &std::cout, SIRIUS_INFO);
/* postponed */ // SPLXsetcbmessage(&Probleme, SiriusCallback_function, &std::cout,
// SIRIUS_INFO);
// Probleme.caller = &std::cout;

if (options.useOrtools)
{
solver = ORTOOLS_ConvertIfNeeded(options.solverName, &Probleme, solver);
}
const std::string filename = createMPSfilename(optPeriodStringGenerator, optimizationNumber);

const std::string filename = createMPSfilename(optPeriodStringGenerator, optimizationNumber);

mpsWriterFactory mps_writer_factory(problemeHebdo->ExportMPS,
problemeHebdo->exportMPSOnError,
Expand All @@ -241,6 +254,11 @@ static SimplexResult OPT_TryToCallSimplex(
if (options.useOrtools)
{
const bool keepBasis = (optimizationNumber == PREMIERE_OPTIMISATION);

if (Probleme.SolverLogs())
{
solver->EnableOutput(&ortools_logger);
}
solver = ORTOOLS_Simplexe(&Probleme, solver, keepBasis);
if (solver != nullptr)
{
Expand Down Expand Up @@ -308,16 +326,30 @@ bool OPT_AppelDuSimplexe(const OptimizationOptions& options,
problemeHebdo->solverLogs);

bool PremierPassage = true;

struct SimplexResult simplexResult =
OPT_TryToCallSimplex(options, problemeHebdo, Probleme, NumIntervalle, optimizationNumber,
optPeriodStringGenerator, PremierPassage, writer);
// tmp
OrtoolsLogHandler ortools_logger(options.solverName, logs.logfile().c_str());
struct SimplexResult simplexResult = OPT_TryToCallSimplex(options,
problemeHebdo,
Probleme,
NumIntervalle,
optimizationNumber,
optPeriodStringGenerator,
PremierPassage,
writer,
ortools_logger);

if (!simplexResult.success)
{
PremierPassage = false;
simplexResult = OPT_TryToCallSimplex(options, problemeHebdo, Probleme, NumIntervalle, optimizationNumber,
optPeriodStringGenerator, PremierPassage, writer);
simplexResult = OPT_TryToCallSimplex(options,
problemeHebdo,
Probleme,
NumIntervalle,
optimizationNumber,
optPeriodStringGenerator,
PremierPassage,
writer,
ortools_logger);
}

long long solveTime = simplexResult.solveTime;
Expand Down Expand Up @@ -372,8 +404,13 @@ bool OPT_AppelDuSimplexe(const OptimizationOptions& options,

Probleme.SetUseNamedProblems(true);

auto MPproblem = std::shared_ptr<MPSolver>(ProblemSimplexeNommeConverter(options.solverName, &Probleme).Convert());
auto MPproblem = std::shared_ptr<MPSolver>(
ProblemSimplexeNommeConverter(options.solverName, &Probleme).Convert());

if (Probleme.SolverLogs())
{
MPproblem->EnableOutput(&ortools_logger);
}
auto analyzer = makeUnfeasiblePbAnalyzer();
analyzer->run(MPproblem.get());
analyzer->printReport();
Expand All @@ -384,6 +421,7 @@ bool OPT_AppelDuSimplexe(const OptimizationOptions& options,

return false;
}

// copy log file(s)
ortools_logger.copy_log(writer);
return true;
}
90 changes: 78 additions & 12 deletions src/solver/utils/ortools_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <antares/exception/AssertionError.hpp>
#include <antares/Enum.hpp>
#include <filesystem>
#include <thread>

using namespace operations_research;

Expand Down Expand Up @@ -31,10 +32,80 @@ namespace Antares
{
namespace Optimization
{

OrtoolsLogHandler::OrtoolsLogHandler(const std::string& solver_name,
const std::filesystem::path& log_directory) :
solver_name_(solver_name), log_directory_(log_directory)
{
init();
}

OrtoolsLogHandler& OrtoolsLogHandler::operator=(const OrtoolsLogHandler& other)
{
if (this == &other)
{
return *this;
}

a-zakir marked this conversation as resolved.
Show resolved Hide resolved
solver_name_ = other.solver_name_;
log_directory_ = other.log_directory_;
init();
return *this;
}
void OrtoolsLogHandler::init()
{
auto myid = std::this_thread::get_id();
a-zakir marked this conversation as resolved.
Show resolved Hide resolved
std::stringstream ss;
ss << myid;
log_file_per_thread_ = log_directory_ / (std::string("thread_") + ss.str() + ".log");

if (solver_name_ == COIN)
{
#ifdef __linux__
if (log_file_per_thread_.empty()
|| (file_pointer = fopen(log_file_per_thread_.string().c_str(), "a+")) == nullptr)
#elif _WIN32
if (log_file_per_thread_.empty()
|| (file_pointer = _fsopen(log_file_per_thread_.string().c_str(), "a+", _SH_DENYNO))
== nullptr)
#endif
{
// logs.error()
std::cerr << "Invalid log file name passed as parameter: "
<< std::quoted(log_file_per_thread_.string()) << std::endl;
}
else
{
setvbuf(file_pointer, nullptr, _IONBF, 0);
}
}
else
{
log_writer_.open(log_file_per_thread_, std::ofstream::out | std::ofstream::app);
}
}

OrtoolsLogHandler::~OrtoolsLogHandler()
{
if (file_pointer)
{
fclose(file_pointer);
file_pointer = nullptr;
}
}

void OrtoolsLogHandler::copy_log(Solver::IResultWriter& writer) const
{
auto log_file_per_thread = log_file_per_thread_.string().c_str();
auto tmp_path_log_per_thread = generateTempPath(log_file_per_thread);
writer.addEntryFromFile(log_file_per_thread, tmp_path_log_per_thread);
removeTemporaryFile(tmp_path_log_per_thread);
}

ProblemSimplexeNommeConverter::ProblemSimplexeNommeConverter(
const std::string& solverName,
const Antares::Optimization::PROBLEME_SIMPLEXE_NOMME* problemeSimplexe)
: solverName_(solverName), problemeSimplexe_(problemeSimplexe)
const std::string& solverName,
const Antares::Optimization::PROBLEME_SIMPLEXE_NOMME* problemeSimplexe) :
solverName_(solverName), problemeSimplexe_(problemeSimplexe)
{
if (problemeSimplexe_->UseNamedProblems())
{
Expand All @@ -55,10 +126,6 @@ MPSolver* ProblemSimplexeNommeConverter::Convert()
CopyRows(solver);

CopyMatrix(solver);
if (problemeSimplexe_->SolverLogs())
{
solver->EnableOutput();
}

return solver;
}
Expand Down Expand Up @@ -372,12 +439,11 @@ void ORTOOLS_LibererProbleme(MPSolver* solver)
{
delete solver;
}

const std::map<std::string, struct OrtoolsUtils::SolverNames> OrtoolsUtils::solverMap
= {{"xpress", {"xpress_lp", "xpress"}},
{"sirius", {"sirius_lp", "sirius"}},
{"coin", {"clp", "cbc"}},
{"glpk", {"glpk_lp", "glpk"}}};
= {{XPRESS, {XPRESS_LP, XPRESS}},
{SIRIUS, {SIRIUS_LP, SIRIUS}},
{COIN, {CLP, CBC}},
{GLPK, {GLPK_LP, GLPK}}};

std::list<std::string> getAvailableOrtoolsSolverName()
{
Expand Down
51 changes: 51 additions & 0 deletions src/solver/utils/ortools_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <map>
#include <string>
#include <fstream>

#include <antares/writer/i_writer.h>

Expand All @@ -11,6 +12,16 @@

using namespace operations_research;

const std::string XPRESS = "xpress";
const std::string XPRESS_LP = "xpress_lp";
const std::string SIRIUS = "sirius";
const std::string SIRIUS_LP = "sirius_lp";
const std::string GLPK = "glpk";
const std::string GLPK_LP = "glpk_lp";
const std::string COIN = "coin";
const std::string CBC = "cbc";
const std::string CLP = "clp";

void ORTOOLS_EcrireJeuDeDonneesLineaireAuFormatMPS(MPSolver* solver,
Antares::Solver::IResultWriter& writer,
const std::string& filename);
Expand Down Expand Up @@ -48,6 +59,46 @@ namespace Antares
namespace Optimization
{

class OrtoolsLogHandler : public LogHandlerInterface
{
public:
// tmp test with std::cout
explicit OrtoolsLogHandler(const std::string& solverName,
const std::filesystem::path& log_directory);

explicit OrtoolsLogHandler(const OrtoolsLogHandler& other) :
OrtoolsLogHandler(other.solver_name_, other.log_directory_)
{
}

OrtoolsLogHandler& operator=(const OrtoolsLogHandler& other);
~OrtoolsLogHandler();
void message(const char* msg, int nLen = 0) override
{
log_writer_ << std::setw(nLen) << msg << std::endl;
}

FILE* where_to_write()
{
return file_pointer;
}

void copy_log(Solver::IResultWriter& writer) const;

private:
void init();
// TODO won't work in ci, needs ortools update
// see https://github.com/rte-france/or-tools/pull/112

// // TODO
std::ofstream log_writer_;
// log_writer.open(log_file_per_thread, std::ofstream::out | std::ofstream::app);
// log_streams.push_back(&log_writer);
FILE* file_pointer = nullptr;
std::string solver_name_;
std::filesystem::path log_directory_ = ".";
std::filesystem::path log_file_per_thread_ = "";
};
class Nomenclature
{
public:
Expand Down
Loading