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

Support multiple quadratic solvers #2574

Draft
wants to merge 6 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
6 changes: 4 additions & 2 deletions docs/user-guide/solver/02-command-line.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ 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) |
| --solver=VALUE | The optimization solver to use. Possible values are: `sirius` (default), `coin`, `xpress`, `scip` |
| --linear-solver=VALUE | The optimization solver to use for linear problems. Possible values are: `sirius` (default), `coin`, `xpress`, `scip` |
| --quadratic-solver=VALUE | The optimization solver to use for quadratic problems. Possible values are: `sirius` (default), `scip` |

## Parameters

Expand All @@ -43,7 +44,8 @@ hide:
| -m, --mps-export | Export anonymous MPS, weekly or daily optimal UC+dispatch linear (MPS will be named if the problem is infeasible) |
| -s, --named-mps-problems | Export named MPS, weekly or daily optimal UC+dispatch linear |
| --solver-logs | Print solver logs |
| --solver-parameters | Set solver-specific parameters, for instance `--solver-parameters="THREADS 1 PRESOLVE 1"` for XPRESS or `--solver-parameters="parallel/maxnthreads 1, lp/presolving TRUE"` for SCIP. Syntax is solver-dependent, and only supported for SCIP & XPRESS. |
| --linear-solver-parameters | Set solver-specific parameters for linear problems, for instance `--solver-parameters="THREADS 1 PRESOLVE 1"` for XPRESS or `--solver-parameters="parallel/maxnthreads 1, lp/presolving TRUE"` for SCIP. Syntax is solver-dependent, and only supported for SCIP & XPRESS. |
| --quadratic-solver-parameters | Set solver-specific parameters for quadratic problems. |

## Misc.

Expand Down
20 changes: 13 additions & 7 deletions docs/user-guide/solver/static-modeler/04-parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -483,14 +483,20 @@ _**This section is under construction**_
> _**Note:**_ You can find more information on this parameter [here](../03-appendix.md#details-on-the-include-unfeasible-problem-behavior-parameter).

---
#### solver-parameters
[//]: # (TODO: document this parameter)
_**This section is under construction**_
#### linear-solver-parameters
- **Expected value:** a string
- **Required:** **no**
- **Default value:** empty
- **Usage:** Set solver-specific parameters for linear problems, for instance `--solver-parameters="THREADS 1 PRESOLVE 1"`
for XPRESS or `--solver-parameters="parallel/maxnthreads 1, lp/presolving TRUE"` for SCIP. Syntax is solver-dependent, and only supported for SCIP & XPRESS.

- **Expected value:**
- **Required:** **yes**
- **Default value:**
- **Usage:**
---
#### quadratic-solver-parameters
- **Expected value:** a string
- **Required:** **no**
- **Default value:** empty
- **Usage:** Set solver-specific parameters for quadratic problems, for instance `--solver-parameters="THREADS 1 PRESOLVE 1"`
for XPRESS or `--solver-parameters="parallel/maxnthreads 1, lp/presolving TRUE"` for SCIP. Syntax is solver-dependent, and only supported for SCIP & XPRESS.

---
## Adequacy-patch parameters
Expand Down
7 changes: 5 additions & 2 deletions src/libs/antares/InfoCollection/StudyInfoCollector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,11 @@ void StudyInfoCollector::solverVersionToFileContent(FileContent& file_content)

void StudyInfoCollector::ORToolsSolver(FileContent& file_content)
{
std::string solverName = study_.parameters.optOptions.ortoolsSolver;
file_content.addItemToSection("study", "ortools solver", solverName);
std::string linearSolverName = study_.parameters.optOptions.linearSolver;
file_content.addItemToSection("study", "linear solver", linearSolverName);

std::string quadraticSolverName = study_.parameters.optOptions.linearSolver;
file_content.addItemToSection("study", "quadratic solver", quadraticSolverName);
}

// Collecting data optimization problem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ namespace Antares::Solver::Optimization
struct OptimizationOptions
{
//! The solver name, sirius is the default
std::string ortoolsSolver = "sirius";
std::string linearSolver = "sirius";
std::string quadraticSolver = "sirius";
std::string linearSolverParameters;
std::string quadraticSolverParameters;
bool solverLogs = false;
std::string solverParameters;
};
} // namespace Antares::Solver::Optimization
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class StudyLoadOptions
//! A non-zero value if the data will be used for a simulation
bool usedByTheSolver;

//! All options related to optimization
//! All options related to linear & quadratic optimization
Antares::Solver::Optimization::OptimizationOptions optOptions;

//! Temporary string for passing log message
Expand Down
2 changes: 1 addition & 1 deletion src/libs/antares/study/include/antares/study/parameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ class Parameters final
// Naming constraints and variables in problems
bool namedProblems;

// All options related to optimization
// All options related to linear & quadratic optimization
Antares::Solver::Optimization::OptimizationOptions optOptions;

private:
Expand Down
13 changes: 9 additions & 4 deletions src/libs/antares/study/parameters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1283,8 +1283,10 @@ bool Parameters::loadFromINI(const IniFile& ini, const StudyVersion& version)
void Parameters::handleOptimizationOptions(const StudyLoadOptions& options)
{
// Options only set from the command-line
optOptions.ortoolsSolver = options.optOptions.ortoolsSolver;
optOptions.solverParameters = options.optOptions.solverParameters;
optOptions.linearSolver = options.optOptions.linearSolver;
optOptions.linearSolverParameters = options.optOptions.linearSolverParameters;
optOptions.quadraticSolver = options.optOptions.quadraticSolver;
optOptions.quadraticSolverParameters = options.optOptions.quadraticSolverParameters;

// Options that can be set both in command-line and file
optOptions.solverLogs = options.optOptions.solverLogs || optOptions.solverLogs;
Expand Down Expand Up @@ -1780,8 +1782,11 @@ void Parameters::prepareForSimulation(const StudyLoadOptions& options)
logs.info() << " :: ignoring solution export";
}

logs.info() << " :: solver " << options.optOptions.ortoolsSolver
<< " is used for problem resolution";
logs.info() << " :: solver " << options.optOptions.linearSolver
<< " is used for linear problem resolution";

logs.info() << " :: solver " << options.optOptions.quadraticSolver
<< " is used for quadratic problem resolution";

// indicated that Problems will be named
if (namedProblems)
Expand Down
6 changes: 4 additions & 2 deletions src/solver/application/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ namespace
{
void printSolvers()
{
std::cout << "Available solvers: " << availableOrToolsSolversString() << std::endl;
std::cout << "Available linear solvers: " << availableOrToolsSolversString(LINEAR) << std::endl;
std::cout << "Available quadratic solvers: " << availableOrToolsSolversString(QUADRATIC)
<< std::endl;
}
} // namespace

Expand Down Expand Up @@ -275,7 +277,7 @@ 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.ortoolsSolver);
pParameters->optOptions.linearSolver);

checkSimplexRangeHydroPricing(pParameters->simplexOptimizationRange,
pParameters->hydroPricing.hpMode);
Expand Down
2 changes: 1 addition & 1 deletion src/solver/misc/include/antares/solver/misc/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,5 +75,5 @@ std::unique_ptr<Yuni::GetOpt::Parser> CreateParser(Settings& settings,

void checkAndCorrectSettingsAndOptions(Settings& settings, Data::StudyLoadOptions& options);

void checkOrtoolsSolver(const Antares::Solver::Optimization::OptimizationOptions& optOptions);
void checkSolvers(Data::StudyLoadOptions& options);
#endif /* __SOLVER_MISC_GETOPT_H__ */
64 changes: 50 additions & 14 deletions src/solver/misc/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#include <limits>
#include <string.h>

#include <boost/algorithm/string/join.hpp>

#include <yuni/yuni.h>

#include <antares/antares/constants.h>
Expand Down Expand Up @@ -75,22 +77,53 @@ std::unique_ptr<Yuni::GetOpt::Parser> CreateParser(Settings& settings, StudyLoad
"force-parallel",
"Override the max number of years computed simultaneously");

//--linear-solver
parser->add(options.optOptions.linearSolver,
' ',
"linear-solver",
"Solver used for linear optimizations during simulation\nAvailable solver list : "
+ availableOrToolsSolversString(LINEAR));

//--solver
parser->add(options.optOptions.ortoolsSolver,
parser->add(options.optOptions.linearSolver,
' ',
"solver",
"Solver used for simulation\nAvailable solver list : "
+ availableOrToolsSolversString());
"Deprecated, use linear-solver instead.");

//--solver-parameters
//--linear-solver-parameters
parser->add(
options.optOptions.solverParameters,
options.optOptions.linearSolverParameters,
' ',
"solver-parameters",
"Set solver-specific parameters, for instance --solver-parameters=\"THREADS 1 PRESOLVE 1\""
"linear-solver-parameters",
"Set linear solver-specific parameters, for instance --linear-solver-parameters=\"THREADS 1 "
"PRESOLVE 1\""
"for XPRESS or --solver-parameters=\"parallel/maxnthreads 1, lp/presolving TRUE\" for SCIP."
"Syntax is solver-dependent, and only supported for SCIP & XPRESS.");

//--solver-parameters
parser->add(options.optOptions.linearSolverParameters,
' ',
"solver-parameters",
"Deprecated, use linear-solver-parameters instead.");

//--quadratic-solver
parser->add(
options.optOptions.quadraticSolver,
' ',
"quadratic-solver",
"Solver used for quadratic optimizations during simulation\nAvailable solver list : "
+ availableOrToolsSolversString(QUADRATIC));

//--quadratic-solver-parameters
parser->add(
options.optOptions.quadraticSolverParameters,
' ',
"quadratic-solver-parameters",
"Set quadratic solver-specific parameters, for instance "
"--quadratic-solver-parameters=\"THREADS 1 PRESOLVE 1\""
"for XPRESS or --solver-parameters=\"parallel/maxnthreads 1, lp/presolving TRUE\" for SCIP."
"Syntax is solver-dependent.");

parser->addParagraph("\nParameters");
// --name
parser->add(settings.simulationName,
Expand Down Expand Up @@ -246,7 +279,7 @@ void checkAndCorrectSettingsAndOptions(Settings& settings, Data::StudyLoadOption
}

options.checkForceSimulationMode();
checkOrtoolsSolver(options.optOptions);
checkSolvers(options);

// no-output and force-zip-output
if (settings.noOutput && settings.forceZipOutput)
Expand All @@ -255,19 +288,22 @@ void checkAndCorrectSettingsAndOptions(Settings& settings, Data::StudyLoadOption
}
}

void checkOrtoolsSolver(const Antares::Solver::Optimization::OptimizationOptions& optOptions)
void checkSolverExists(std::string solverName, const std::list<std::string> availableSolversList)
{
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());
bool found = std::ranges::find(availableSolversList, solverName) != availableSolversList.end();
if (!found)
{
throw Error::InvalidSolver(optOptions.ortoolsSolver, availableOrToolsSolversString());
throw Error::InvalidSolver(solverName, boost::algorithm::join(availableSolversList, ","));
}
}

void checkSolvers(StudyLoadOptions& options)
{
checkSolverExists(options.optOptions.linearSolver, getAvailableOrtoolsMpSolverName());
checkSolverExists(options.optOptions.quadraticSolver, getAvailableOrtoolsQuadraticSolverName());
}

void Settings::checkAndSetStudyFolder(const std::string& folder)
{
// The study folder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ bool OPT_PilotageOptimisationLineaire(const OptimizationOptions& options,
Solver::IResultWriter& writer,
Solver::Simulation::ISimulationObserver& simulationObserver);
void OPT_VerifierPresenceReserveJmoins1(PROBLEME_HEBDO*);
bool OPT_PilotageOptimisationQuadratique(PROBLEME_HEBDO*);
bool OPT_PilotageOptimisationQuadratique(const OptimizationOptions& options, PROBLEME_HEBDO*);

/*!
** \brief Appel du solver
Expand Down
4 changes: 2 additions & 2 deletions src/solver/optimisation/opt_appel_solveur_lineaire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ static SimplexResult OPT_TryToCallSimplex(const OptimizationOptions& options,
Probleme.NombreDeContraintesCoupes = 0;

auto ortoolsProblem = std::make_unique<LegacyOrtoolsLinearProblem>(Probleme.isMIP(),
options.ortoolsSolver);
options.linearSolver);
auto legacyOrtoolsFiller = std::make_unique<LegacyFiller>(&Probleme);
std::vector<LinearProblemFiller*> fillersCollection = {legacyOrtoolsFiller.get()};
LinearProblemData LP_Data;
Expand Down Expand Up @@ -353,7 +353,7 @@ bool OPT_AppelDuSimplexe(const OptimizationOptions& options,
Probleme.SetUseNamedProblems(true);

auto ortoolsProblem = std::make_unique<LegacyOrtoolsLinearProblem>(Probleme.isMIP(),
options.ortoolsSolver);
options.linearSolver);
auto legacyOrtoolsFiller = std::make_unique<LegacyFiller>(&Probleme);
std::vector<LinearProblemFiller*> fillersCollection = {legacyOrtoolsFiller.get()};
LinearProblemData LP_Data;
Expand Down
6 changes: 3 additions & 3 deletions src/solver/optimisation/opt_optimisation_hebdo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@

using namespace Antares::Data;

using Antares::Solver::Optimization::OptimizationOptions;
using Solver::Optimization::OptimizationOptions;

bool OPT_PilotageOptimisationLineaire(const OptimizationOptions&,
PROBLEME_HEBDO*,
Solver::IResultWriter&,
Solver::Simulation::ISimulationObserver&);
bool OPT_PilotageOptimisationQuadratique(PROBLEME_HEBDO*);
bool OPT_PilotageOptimisationQuadratique(const OptimizationOptions&, PROBLEME_HEBDO*);
void OPT_LiberationProblemesSimplexe(const PROBLEME_HEBDO*);

void OPT_OptimisationHebdomadaire(const OptimizationOptions& options,
Expand All @@ -52,7 +52,7 @@ void OPT_OptimisationHebdomadaire(const OptimizationOptions& options,
else if (pProblemeHebdo->TypeDOptimisation == OPTIMISATION_QUADRATIQUE)
{
OPT_LiberationProblemesSimplexe(pProblemeHebdo);
if (!OPT_PilotageOptimisationQuadratique(pProblemeHebdo))
if (!OPT_PilotageOptimisationQuadratique(options, pProblemeHebdo))
{
logs.error() << "Quadratic optimization failed";
throw UnfeasibleProblemError("Quadratic optimization failed");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,15 @@
#include "antares/solver/optimisation/constraints/constraint_builder_utils.h"
#include "antares/solver/optimisation/opt_fonctions.h"

bool OPT_PilotageOptimisationQuadratique(PROBLEME_HEBDO* problemeHebdo)
bool OPT_PilotageOptimisationQuadratique(const OptimizationOptions& options,
PROBLEME_HEBDO* problemeHebdo)
{
if (options.quadraticSolver != "sirius")
{
const std::string notFound = "Solver " + options.quadraticSolver
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t understand this condition

+ " not supported for quadratic problems optimization.";
throw new std::invalid_argument(notFound);
}
if (!problemeHebdo->LeProblemeADejaEteInstancie)
{
OPT_ConstruireLaListeDesVariablesOptimiseesDuProblemeQuadratique(problemeHebdo);
Expand Down
30 changes: 25 additions & 5 deletions src/solver/utils/include/antares/solver/utils/ortools_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,43 @@

using namespace operations_research;

enum SolverClass
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use enum class

{
LINEAR,
QUADRATIC
};

void ORTOOLS_EcrireJeuDeDonneesLineaireAuFormatMPS(MPSolver* solver,
Antares::Solver::IResultWriter& writer,
const std::string& filename);

/*!
* \brief Return list of available ortools solver name on our side
* \brief Return list of available ortools solver names on our side
*
* \return List of available ortools solver names
*/
std::list<std::string> getAvailableOrtoolsSolverNames(SolverClass solverClass);

/*!
* \brief Return list of available ortools linear solver names on our side
*
* \return List of available ortools linear solver names
*/
std::list<std::string> getAvailableOrtoolsMpSolverName();

/*!
* \brief Return list of available ortools quadratic solver names on our side
*
* \return List of available ortools solver name
* \return List of available ortools quadratic solver names
*/
std::list<std::string> getAvailableOrtoolsSolverName();
std::list<std::string> getAvailableOrtoolsQuadraticSolverName();

/*!
* \brief Return a single string containing all solvers available, separated by a ", " and ending
* with a ".".
*
*/
std::string availableOrToolsSolversString();
std::string availableOrToolsSolversString(SolverClass solverClass);

/*!
* \brief Create a MPSolver with correct linear or mixed variant
Expand All @@ -68,7 +88,7 @@ class OrtoolsUtils
public:
struct SolverNames
{
std::string LPSolverName, MIPSolverName;
std::string LPSolverName, MIPSolverName, QuadraticSolverName;
};
static const std::map<std::string, struct SolverNames> solverMap;
};
Loading
Loading