Skip to content

Commit

Permalink
Remove direct use of Sirius solver (ANT-1152) (#2450)
Browse files Browse the repository at this point in the history
This PR intends to be a first work in order to remove the direct call of
**Sirius** as a solver, **regarding the optimization weekly problem
only**.
We want to keep the use of **Sirius**, but only called through
**or-tools** interface.
The associated **gopro** ticket is [this
one](https://gopro-tickets.rte-france.com/browse/ANT-1152).
Here we intend to : 
- remove the use of command line option **--use-ortools**
- rename current command line option **--ortools-solver** into
**--solver**
- handle direct consequences of these changes.
- adapt legacy GUI (especially remove **use ortools** check box)

So this PR does not intend to be thorough : these first changes leave
remaining dead code to be removed
and renaming to be done. This further changes will be done in a coming
PR.

**Remaining to be done** : 
- or-tools (even if we use **Sirius** behind it) does not print
correctly MPS for named problems : optimization variables names are
composed with time steps, set once for all (0, ..., 167) before running
any year, and not updated at each week (we could expect step numbers to
be inside [0, ..., 8759] depending on the week).
So we left the code that print these correctly. We'll have to find a
solution for this.
We could leave the responsibility of printing these named MPS to Antares
code (as it did when Sirius was run alone) for a moment
- Banish all direct calls to **Sirius** from **Antares Simulator**
(calls to **Sirius** are done in **hydro heuristics**, **adequacy patch
CSR** and annual **quadratic** post-treatments of flows) does not seem
to be suitable and urgent for now.
- What else ?

---------

Co-authored-by: Florian OMNES <florian.omnes@rte-france.com>
  • Loading branch information
guilpier-code and flomnes authored Nov 28, 2024
1 parent a7b0702 commit f7422c7
Show file tree
Hide file tree
Showing 30 changed files with 88 additions and 323 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/cucumber-tests/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ runs:
shell: bash
run: |
cd src/tests/cucumber
behave --tags ${{ inputs.tags }} ${{ inputs.feature }} --define use-ortools=false
behave --tags ${{ inputs.tags }} ${{ inputs.feature }}
1 change: 1 addition & 0 deletions docs/developer-guide/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ toc_depth: 2
#### Removed features
* Remove hydro hotstart (#2131)
* Remove adequacy patch lmr [ANT-1933] (#2341)
* Possibility to disable OR-Tools. All problems are now solved through OR-Tools (#2450)

#### Improvements
* Changed the formula for the number of cores [details](../user-guide/solver/optional-features/multi-threading.md)
Expand Down
3 changes: 1 addition & 2 deletions docs/user-guide/solver/02-command-line.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ hide:
| --adequacy | Force the simulation in [adequacy](static-modeler/04-parameters.md#mode) mode |
| --parallel | Enable [parallel](optional-features/multi-threading.md) computation of MC years |
| --force-parallel=VALUE | Override the max number of years computed [simultaneously](optional-features/multi-threading.md) |
| --use-ortools | Use the [OR-Tools](https://developers.google.com/optimization) modelling library (under the hood) |
| --ortools-solver=VALUE | The solver to use (only available if use-ortools is activated). Possible values are: `sirius` (default), `coin`, `xpress`, `scip` |
| --ortools-solver=VALUE | The optimization solver to use. Possible values are: `sirius` (default), `coin`, `xpress`, `scip` |

## Parameters

Expand Down
2 changes: 1 addition & 1 deletion docs/user-guide/solver/optional-features/xpress.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Antares Solver only uses LP, with plans to use MILP at some point in the future.

## Using Xpress in the command-line
```
antares-x.y-solver --use-ortools --ortools-solver xpress [options] <study>
antares-solver --ortools-solver xpress [options] <study>
```

## Setup
Expand Down
16 changes: 2 additions & 14 deletions src/libs/antares/InfoCollection/StudyInfoCollector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ void StudyInfoCollector::toFileContent(FileContent& file_content)
unitCommitmentModeToFileContent(file_content);
maxNbYearsInParallelToFileContent(file_content);
solverVersionToFileContent(file_content);
ORToolsUsed(file_content);
ORToolsSolver(file_content);
}

Expand Down Expand Up @@ -144,21 +143,10 @@ void StudyInfoCollector::solverVersionToFileContent(FileContent& file_content)
file_content.addItemToSection("study", "antares version", version);
}

void StudyInfoCollector::ORToolsUsed(FileContent& file_content)
{
const bool& ortoolsUsed = study_.parameters.optOptions.ortoolsUsed;
file_content.addItemToSection("study", "ortools used", ortoolsUsed ? "true" : "false");
}

void StudyInfoCollector::ORToolsSolver(FileContent& file_content)
{
const bool& ortoolsUsed = study_.parameters.optOptions.ortoolsUsed;
std::string ortoolsSolver = "none";
if (ortoolsUsed)
{
ortoolsSolver = study_.parameters.optOptions.ortoolsSolver;
}
file_content.addItemToSection("study", "ortools solver", ortoolsSolver);
std::string solverName = study_.parameters.optOptions.ortoolsSolver;
file_content.addItemToSection("study", "ortools solver", solverName);
}

// Collecting data optimization problem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ class StudyInfoCollector
void maxNbYearsInParallelToFileContent(FileContent& file_content);
void solverVersionToFileContent(FileContent& file_content);

void ORToolsUsed(FileContent& file_content);
void ORToolsSolver(FileContent& file_content);

// Member data
Expand Down
13 changes: 2 additions & 11 deletions src/libs/antares/checks/checkLoadedInputData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,12 @@
namespace Antares::Check
{
void checkSolverMILPincompatibility(Antares::Data::UnitCommitmentMode ucMode,
bool ortoolsUsed,
const std::string& solverName)
{
using namespace Antares::Data;
if (ucMode == UnitCommitmentMode::ucMILP)
if (ucMode == UnitCommitmentMode::ucMILP && solverName == "sirius")
{
if (!ortoolsUsed)
{
throw Error::IncompatibleMILPWithoutOrtools();
}

if (solverName == "sirius")
{
throw Error::IncompatibleMILPOrtoolsSolver();
}
throw Error::IncompatibleMILPOrtoolsSolver();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ namespace Antares::Check
{

void checkSolverMILPincompatibility(Antares::Data::UnitCommitmentMode ucMode,
bool ortoolsUsed,
const std::string& solverName);

void checkStudyVersion(const AnyString& optStudyFolder);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ namespace Antares::Solver::Optimization

struct OptimizationOptions
{
//! Force ortools use
bool ortoolsUsed = false;
//! The solver name, sirius is the default
std::string ortoolsSolver = "sirius";
bool solverLogs = false;
Expand Down
9 changes: 2 additions & 7 deletions src/libs/antares/study/parameters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1230,7 +1230,6 @@ bool Parameters::loadFromINI(const IniFile& ini, const StudyVersion& version)
void Parameters::handleOptimizationOptions(const StudyLoadOptions& options)
{
// Options only set from the command-line
optOptions.ortoolsUsed = options.optOptions.ortoolsUsed;
optOptions.ortoolsSolver = options.optOptions.ortoolsSolver;
optOptions.solverParameters = options.optOptions.solverParameters;

Expand Down Expand Up @@ -1724,12 +1723,8 @@ void Parameters::prepareForSimulation(const StudyLoadOptions& options)
logs.info() << " :: ignoring hurdle costs";
}

// Indicate ortools solver used
if (options.optOptions.ortoolsUsed)
{
logs.info() << " :: ortools solver " << options.optOptions.ortoolsSolver
<< " used for problem resolution";
}
logs.info() << " :: solver " << options.optOptions.ortoolsSolver
<< " is used for problem resolution";

// indicated that Problems will be named
if (namedProblems)
Expand Down
1 change: 0 additions & 1 deletion src/solver/application/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,6 @@ void Application::postParametersChecks() const
{ // Some more checks require the existence of pParameters, hence of a study.
// Their execution is delayed up to this point.
checkSolverMILPincompatibility(pParameters->unitCommitment.ucMode,
pParameters->optOptions.ortoolsUsed,
pParameters->optOptions.ortoolsSolver);

checkSimplexRangeHydroPricing(pParameters->simplexOptimizationRange,
Expand Down
30 changes: 9 additions & 21 deletions src/solver/misc/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,11 @@ std::unique_ptr<Yuni::GetOpt::Parser> CreateParser(Settings& settings, StudyLoad
"force-parallel",
"Override the max number of years computed simultaneously");

// add option for ortools use
// --use-ortools
parser->addFlag(options.optOptions.ortoolsUsed,
' ',
"use-ortools",
"Use ortools library to launch solver");

//--ortools-solver
parser->add(options.optOptions.ortoolsSolver,
' ',
"ortools-solver",
"Ortools solver used for simulation (only available with use-ortools "
"option)\nAvailable solver list : "
"solver",
"Solver used for simulation\nAvailable solver list : "
+ availableOrToolsSolversString());

//--xpress-parameters
Expand Down Expand Up @@ -265,18 +257,14 @@ void checkAndCorrectSettingsAndOptions(Settings& settings, Data::StudyLoadOption

void checkOrtoolsSolver(const Antares::Solver::Optimization::OptimizationOptions& optOptions)
{
if (optOptions.ortoolsUsed)
{
const std::string& solverName = optOptions.ortoolsSolver;
const std::list<std::string> availableSolverList = getAvailableOrtoolsSolverName();
const std::string& solverName = optOptions.ortoolsSolver;
const std::list<std::string> availableSolverList = getAvailableOrtoolsSolverName();

// Check if solver is available
bool found = (std::ranges::find(availableSolverList, solverName)
!= availableSolverList.end());
if (!found)
{
throw Error::InvalidSolver(optOptions.ortoolsSolver, availableOrToolsSolversString());
}
// Check if solver is available
bool found = (std::ranges::find(availableSolverList, solverName) != availableSolverList.end());
if (!found)
{
throw Error::InvalidSolver(optOptions.ortoolsSolver, availableOrToolsSolversString());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ bool OPT_AppelDuSimplexe(const OptimizationOptions& options,
const int,
const OptPeriodStringGenerator&,
Antares::Solver::IResultWriter& writer);
void OPT_LiberationProblemesSimplexe(const OptimizationOptions& options, const PROBLEME_HEBDO*);
void OPT_LiberationProblemesSimplexe(const PROBLEME_HEBDO*);

bool OPT_OptimisationLineaire(const OptimizationOptions& options,
PROBLEME_HEBDO* problemeHebdo,
Expand Down
73 changes: 21 additions & 52 deletions src/solver/optimisation/opt_appel_solveur_lineaire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,20 +90,18 @@ static SimplexResult OPT_TryToCallSimplex(const OptimizationOptions& options,
IResultWriter& writer)
{
const auto& ProblemeAResoudre = problemeHebdo->ProblemeAResoudre;
auto ProbSpx = (PROBLEME_SPX*)(ProblemeAResoudre->ProblemesSpx[(int)NumIntervalle]);
auto solver = (MPSolver*)(ProblemeAResoudre->ProblemesSpx[(int)NumIntervalle]);
auto solver = (MPSolver*)(ProblemeAResoudre->ProblemesSpx[NumIntervalle]);

const int opt = optimizationNumber - 1;
assert(opt >= 0 && opt < 2);
OptimizationStatistics& optimizationStatistics = problemeHebdo->optimizationStatistics[opt];
TIME_MEASURE timeMeasure;
if (!PremierPassage)
{
ProbSpx = nullptr;
solver = nullptr;
}

if (ProbSpx == nullptr && solver == nullptr)
if (solver == nullptr)
{
Probleme.Contexte = SIMPLEXE_SEUL;
Probleme.BaseDeDepartFournie = NON_SPX;
Expand All @@ -112,17 +110,13 @@ static SimplexResult OPT_TryToCallSimplex(const OptimizationOptions& options,
{
if (problemeHebdo->ReinitOptimisation)
{
if (options.ortoolsUsed && solver)
if (solver)
{
ORTOOLS_LibererProbleme(solver);
}
else if (ProbSpx != nullptr)
{
SPX_LibererProbleme(ProbSpx);
}

ProblemeAResoudre->ProblemesSpx[NumIntervalle] = nullptr;

ProbSpx = nullptr;
solver = nullptr;
Probleme.Contexte = SIMPLEXE_SEUL;
Probleme.BaseDeDepartFournie = NON_SPX;
Expand All @@ -133,31 +127,20 @@ static SimplexResult OPT_TryToCallSimplex(const OptimizationOptions& options,
Probleme.BaseDeDepartFournie = UTILISER_LA_BASE_DU_PROBLEME_SPX;

TimeMeasurement updateMeasure;
if (options.ortoolsUsed)
{
ORTOOLS_ModifierLeVecteurCouts(solver,
ProblemeAResoudre->CoutLineaire.data(),
ProblemeAResoudre->NombreDeVariables);
ORTOOLS_ModifierLeVecteurSecondMembre(solver,
ProblemeAResoudre->SecondMembre.data(),
ProblemeAResoudre->Sens.data(),
ProblemeAResoudre->NombreDeContraintes);
ORTOOLS_CorrigerLesBornes(solver,
ProblemeAResoudre->Xmin.data(),
ProblemeAResoudre->Xmax.data(),
ProblemeAResoudre->TypeDeVariable.data(),
ProblemeAResoudre->NombreDeVariables);
}
else
{
SPX_ModifierLeVecteurCouts(ProbSpx,

ORTOOLS_ModifierLeVecteurCouts(solver,
ProblemeAResoudre->CoutLineaire.data(),
ProblemeAResoudre->NombreDeVariables);
SPX_ModifierLeVecteurSecondMembre(ProbSpx,
ORTOOLS_ModifierLeVecteurSecondMembre(solver,
ProblemeAResoudre->SecondMembre.data(),
ProblemeAResoudre->Sens.data(),
ProblemeAResoudre->NombreDeContraintes);
}
ORTOOLS_CorrigerLesBornes(solver,
ProblemeAResoudre->Xmin.data(),
ProblemeAResoudre->Xmax.data(),
ProblemeAResoudre->TypeDeVariable.data(),
ProblemeAResoudre->NombreDeVariables);

updateMeasure.tick();
timeMeasure.updateTime = updateMeasure.duration_ms();
optimizationStatistics.addUpdateTime(timeMeasure.updateTime);
Expand Down Expand Up @@ -214,7 +197,7 @@ static SimplexResult OPT_TryToCallSimplex(const OptimizationOptions& options,
FillContext fillCtx(0, 167);
LinearProblemBuilder linearProblemBuilder(fillersCollection);

if (options.ortoolsUsed && solver == nullptr)
if (solver == nullptr)
{
linearProblemBuilder.build(*ortoolsProblem, LP_Data, fillCtx);
solver = ortoolsProblem->getMpSolver();
Expand All @@ -225,30 +208,20 @@ static SimplexResult OPT_TryToCallSimplex(const OptimizationOptions& options,
problemeHebdo->exportMPSOnError,
optimizationNumber,
&Probleme,
options.ortoolsUsed,
solver);

auto mps_writer = mps_writer_factory.create();
mps_writer->runIfNeeded(writer, filename);

TimeMeasurement measure;
if (options.ortoolsUsed)
{
const bool keepBasis = (optimizationNumber == PREMIERE_OPTIMISATION);
solver = ORTOOLS_Simplexe(&Probleme, solver, keepBasis, options);
if (solver != nullptr)
{
ProblemeAResoudre->ProblemesSpx[NumIntervalle] = (void*)solver;
}
}
else

const bool keepBasis = (optimizationNumber == PREMIERE_OPTIMISATION);
solver = ORTOOLS_Simplexe(&Probleme, solver, keepBasis, options);
if (solver)
{
ProbSpx = SPX_Simplexe(&Probleme, ProbSpx);
if (ProbSpx != nullptr)
{
ProblemeAResoudre->ProblemesSpx[NumIntervalle] = (void*)ProbSpx;
}
ProblemeAResoudre->ProblemesSpx[NumIntervalle] = (void*)solver;
}

measure.tick();
timeMeasure.solveTime = measure.duration_ms();
optimizationStatistics.addSolveTime(timeMeasure.solveTime);
Expand All @@ -258,14 +231,10 @@ static SimplexResult OPT_TryToCallSimplex(const OptimizationOptions& options,
{
if (ProblemeAResoudre->ExistenceDUneSolution != SPX_ERREUR_INTERNE)
{
if (options.ortoolsUsed && solver)
if (solver)
{
ORTOOLS_LibererProbleme(solver);
}
else if (ProbSpx != nullptr)
{
SPX_LibererProbleme(ProbSpx);
}

logs.info() << " Solver: Standard resolution failed";
logs.info() << " Solver: Retry in safe mode"; // second trial w/o scaling
Expand Down
12 changes: 2 additions & 10 deletions src/solver/optimisation/opt_liberation_problemes_simplexe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,12 @@

#include <spx_fonctions.h>

#include "antares/optimization-options/options.h"
#include "antares/solver/simulation/sim_structure_probleme_economique.h"
#include "antares/solver/utils/ortools_utils.h"

using namespace Antares::Solver::Optimization;

void OPT_LiberationProblemesSimplexe(const OptimizationOptions& options,
const PROBLEME_HEBDO* problemeHebdo)
void OPT_LiberationProblemesSimplexe(const PROBLEME_HEBDO* problemeHebdo)
{
int NombreDePasDeTempsPourUneOptimisation;
if (!problemeHebdo->OptimisationAuPasHebdomadaire)
Expand All @@ -52,19 +50,13 @@ void OPT_LiberationProblemesSimplexe(const OptimizationOptions& options,
{
for (int numIntervalle = 0; numIntervalle < nbIntervalles; numIntervalle++)
{
auto ProbSpx = (PROBLEME_SPX*)(ProblemeAResoudre->ProblemesSpx[numIntervalle]);
auto solver = (MPSolver*)(ProblemeAResoudre->ProblemesSpx[numIntervalle]);

if (options.ortoolsUsed && solver)
if (solver)
{
ORTOOLS_LibererProbleme(solver);
solver = nullptr;
}
else if (ProbSpx)
{
SPX_LibererProbleme(ProbSpx);
ProbSpx = nullptr;
}
}
}
}
Loading

0 comments on commit f7422c7

Please sign in to comment.