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

Legacy ortools behind API - user story 3.1 #2455

Merged
merged 35 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
ab11215
Legacy ortools behind API : in CI, run tests with ortools + sirius
guilpier-code Oct 8, 2024
2f704ca
Legacy ortools behind API : mainly preparing the field for further ch…
guilpier-code Oct 9, 2024
0a308a9
Legacy ortools behind API : put solver creation behind or-tools
guilpier-code Oct 10, 2024
51d19d8
Legacy ortools behind API : fix crash in modeler unit tests
guilpier-code Oct 10, 2024
8223c47
Legacy ortools behind API : fix a crash - smart pointer on ortools so…
guilpier-code Oct 10, 2024
f588590
Legacy ortools behind API : remove duplicate code
guilpier-code Oct 10, 2024
b4ef65f
Legacy ortools behind API : correction due to review
guilpier-code Oct 11, 2024
ef29f1d
Legacy ortools behind API : correction due to review
guilpier-code Oct 11, 2024
b6c9758
activate some tests on new simtest reference
pet-mit Oct 14, 2024
499f548
activate ortools in end-to-end tests
pet-mit Oct 14, 2024
3fdc8fc
fix simtest version
pet-mit Oct 14, 2024
89724ea
fix clang format
pet-mit Oct 14, 2024
f03e705
fix simtest version
pet-mit Oct 14, 2024
96707ac
Merge branch 'develop' into feature/legacy-ortools-behind-api-3.1
pet-mit Oct 14, 2024
836a73a
fix after merge
pet-mit Oct 14, 2024
d326428
fix clang format
pet-mit Oct 14, 2024
c2a02d8
Improve 3.1 (#2461)
pet-mit Oct 14, 2024
8d89138
Merge branch 'develop' into feature/legacy-ortools-behind-api-3.1
pet-mit Oct 14, 2024
678fea0
some fixes
pet-mit Oct 14, 2024
41b9c83
some fixes
pet-mit Oct 14, 2024
c37bf6c
activate long tests
pet-mit Oct 15, 2024
9d9dcfe
Merge branch 'develop' into feature/legacy-ortools-behind-api-3.1
pet-mit Oct 15, 2024
0c7d054
Update src/solver/optimisation/LegacyFiller.cpp
pet-mit Oct 15, 2024
4aa95a2
fix
pet-mit Oct 15, 2024
a0463b8
revert CI test changes
pet-mit Oct 16, 2024
d0a0686
revert CI test changes
pet-mit Oct 16, 2024
342b926
Merge branch 'develop' into feature/legacy-ortools-behind-api-3.1
pet-mit Oct 16, 2024
6a018aa
revert CI test changes
pet-mit Oct 16, 2024
7fc4d93
Merge remote-tracking branch 'origin/feature/legacy-ortools-behind-ap…
pet-mit Oct 16, 2024
33abc2f
revert CI test changes
pet-mit Oct 16, 2024
bf386b9
add message in case of MPS check failure
pet-mit Oct 17, 2024
6b217e9
revert ortools activation in test
pet-mit Oct 17, 2024
399f634
Merge branch 'develop' into feature/legacy-ortools-behind-api-3.1
pet-mit Oct 17, 2024
62863e7
PR comments
pet-mit Oct 22, 2024
5237a6f
remove useless include
pet-mit Oct 23, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ class ILinearProblem
virtual IMipVariable* addNumVariable(double lb, double ub, const std::string& name) = 0;
/// Create a integer variable
virtual IMipVariable* addIntVariable(double lb, double ub, const std::string& name) = 0;
/// Create a continuous or integer variable
virtual IMipVariable* addVariable(double lb, double ub, bool integer, const std::string& name)
= 0;
virtual IMipVariable* getVariable(const std::string& name) const = 0;
virtual int variableCount() const = 0;

Expand All @@ -68,6 +71,9 @@ class ILinearProblem

/// Solve the problem, returns a IMipSolution
virtual IMipSolution* solve(bool verboseSolver) = 0;

// Definition of infinity
virtual double infinity() const = 0;
};

} // namespace Antares::Solver::Modeler::Api
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,18 @@ class MPObjective;
namespace Antares::Solver::Modeler::OrtoolsImpl
{

class OrtoolsLinearProblem final: public Api::ILinearProblem
class OrtoolsLinearProblem: public Api::ILinearProblem
{
public:
OrtoolsLinearProblem(bool isMip, const std::string& solverName);
~OrtoolsLinearProblem() override = default;

OrtoolsMipVariable* addNumVariable(double lb, double ub, const std::string& name) override;
OrtoolsMipVariable* addIntVariable(double lb, double ub, const std::string& name) override;
OrtoolsMipVariable* addVariable(double lb,
double ub,
bool integer,
const std::string& name) override;
OrtoolsMipVariable* getVariable(const std::string& name) const override;
int variableCount() const override;

Expand All @@ -61,11 +65,13 @@ class OrtoolsLinearProblem final: public Api::ILinearProblem
bool isMaximization() const override;

OrtoolsMipSolution* solve(bool verboseSolver) override;
operations_research::MPSolver* MPSolver();

private:
OrtoolsMipVariable* addVariable(double lb, double ub, bool integer, const std::string& name);
double infinity() const override;

protected:
operations_research::MPSolver* MpSolver() const;

private:
operations_research::MPSolver* mpSolver_;
operations_research::MPObjective* objective_;
operations_research::MPSolverParameters params_;
Expand Down
7 changes: 6 additions & 1 deletion src/solver/modeler/ortoolsImpl/linearProblem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ bool OrtoolsLinearProblem::isMaximization() const
return objective_->maximization();
}

MPSolver* OrtoolsLinearProblem::MPSolver()
MPSolver* OrtoolsLinearProblem::MpSolver() const
{
return mpSolver_;
}
Expand All @@ -182,4 +182,9 @@ OrtoolsMipSolution* OrtoolsLinearProblem::solve(bool verboseSolver)
return solution_.get();
}

double OrtoolsLinearProblem::infinity() const
{
return MPSolver::infinity();
}

} // namespace Antares::Solver::Modeler::OrtoolsImpl
255 changes: 128 additions & 127 deletions src/solver/optimisation/CMakeLists.txt

Large diffs are not rendered by default.

70 changes: 23 additions & 47 deletions src/solver/optimisation/LegacyOrtoolsFiller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,17 @@ void LegacyOrtoolsFiller::addVariables(ILinearProblem& pb,
LinearProblemData& data,
FillContext& ctx)
{
auto* mpSolver = dynamic_cast<operations_research::MPSolver*>(&pb);
if (mpSolver)
{
// Create the variables and set objective cost.
CopyVariables(mpSolver);
}
else
{
logs.error() << "Invalid cast, ortools MPSolver expected.";
throw std::bad_cast();
}
// Create the variables and set objective cost.
CopyVariables(pb);
}

void LegacyOrtoolsFiller::addConstraints(ILinearProblem& pb,
LinearProblemData& data,
FillContext& ctx)
{
auto* mpSolver = dynamic_cast<operations_research::MPSolver*>(&pb);
if (mpSolver)
{
// Create constraints and set coefs
CopyRows(mpSolver);
CopyMatrix(mpSolver);
}
else
{
logs.error() << "Invalid cast, ortools MPSolver expected.";
throw std::bad_cast();
}
// Create constraints and set coefs
CopyRows(pb);
CopyMatrix(pb);
}

void LegacyOrtoolsFiller::addObjective(ILinearProblem& pb,
Expand All @@ -55,52 +37,46 @@ void LegacyOrtoolsFiller::addObjective(ILinearProblem& pb,
{
}

void LegacyOrtoolsFiller::CopyMatrix(const MPSolver* solver) const
void LegacyOrtoolsFiller::CopyMatrix(ILinearProblem& pb) const
{
auto variables = solver->variables();
auto constraints = solver->constraints();

for (int idxRow = 0; idxRow < problemeSimplexe_->NombreDeContraintes; ++idxRow)
{
MPConstraint* const ct = constraints[idxRow];
auto* ct = pb.getConstraint(constraintNameManager_.GetName(idxRow));
int debutLigne = problemeSimplexe_->IndicesDebutDeLigne[idxRow];
for (int idxCoef = 0; idxCoef < problemeSimplexe_->NombreDeTermesDesLignes[idxRow];
++idxCoef)
{
int pos = debutLigne + idxCoef;
ct->SetCoefficient(variables[problemeSimplexe_->IndicesColonnes[pos]],
problemeSimplexe_->CoefficientsDeLaMatriceDesContraintes[pos]);
auto* var = pb.getVariable(
variableNameManager_.GetName(problemeSimplexe_->IndicesColonnes[pos]));
ct->setCoefficient(var, problemeSimplexe_->CoefficientsDeLaMatriceDesContraintes[pos]);
}
}
}

void LegacyOrtoolsFiller::CreateVariable(unsigned idxVar,
MPSolver* solver,
MPObjective* const objective) const
void LegacyOrtoolsFiller::CreateVariable(unsigned idxVar, ILinearProblem& pb) const
{
double min_l = problemeSimplexe_->Xmin[idxVar];
double max_l = problemeSimplexe_->Xmax[idxVar];
bool isIntegerVariable = problemeSimplexe_->IntegerVariable(idxVar);
const MPVariable* var = solver->MakeVar(min_l,
max_l,
isIntegerVariable,
variableNameManager_.GetName(idxVar));
objective->SetCoefficient(var, problemeSimplexe_->CoutLineaire[idxVar]);
auto* var = pb.addVariable(min_l,
max_l,
isIntegerVariable,
variableNameManager_.GetName(idxVar));
pb.setObjectiveCoefficient(var, problemeSimplexe_->CoutLineaire[idxVar]);
}

void LegacyOrtoolsFiller::CopyVariables(MPSolver* solver) const

void LegacyOrtoolsFiller::CopyVariables(ILinearProblem& pb) const
{
MPObjective* const objective = solver->MutableObjective();
for (int idxVar = 0; idxVar < problemeSimplexe_->NombreDeVariables; ++idxVar)
{
CreateVariable(idxVar, solver, objective);
CreateVariable(idxVar, pb);
}
}

void LegacyOrtoolsFiller::UpdateContraints(unsigned idxRow, MPSolver* solver) const
void LegacyOrtoolsFiller::UpdateContraints(unsigned idxRow, ILinearProblem& pb) const
{
double bMin = -MPSolver::infinity(), bMax = MPSolver::infinity();
double bMin = -pb.infinity(), bMax = pb.infinity();
if (problemeSimplexe_->Sens[idxRow] == '=')
{
bMin = bMax = problemeSimplexe_->SecondMembre[idxRow];
Expand All @@ -114,14 +90,14 @@ void LegacyOrtoolsFiller::UpdateContraints(unsigned idxRow, MPSolver* solver) co
bMin = problemeSimplexe_->SecondMembre[idxRow];
}

solver->MakeRowConstraint(bMin, bMax, constraintNameManager_.GetName(idxRow));
pb.addConstraint(bMin, bMax, constraintNameManager_.GetName(idxRow));
}

void LegacyOrtoolsFiller::CopyRows(MPSolver* solver) const
void LegacyOrtoolsFiller::CopyRows(ILinearProblem& pb) const
{
for (int idxRow = 0; idxRow < problemeSimplexe_->NombreDeContraintes; ++idxRow)
{
UpdateContraints(idxRow, solver);
UpdateContraints(idxRow, pb);
}
}
} // namespace Antares::Optimization
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,14 @@ class LegacyOrtoolsFiller: public LinearProblemFiller
void addObjective(ILinearProblem& pb, LinearProblemData& data, FillContext& ctx) override;

private:
operations_research::MPSolver* mpSolver_ = nullptr;
const Antares::Optimization::PROBLEME_SIMPLEXE_NOMME* problemeSimplexe_;
Nomenclature variableNameManager_ = Nomenclature('x');
Nomenclature constraintNameManager_ = Nomenclature('c');

void CreateVariable(unsigned idxVar, MPSolver* solver, MPObjective* const objective) const;
void CopyVariables(MPSolver* solver) const;
void UpdateContraints(unsigned idxRow, MPSolver* solver) const;
void CopyRows(MPSolver* solver) const;
void CopyMatrix(const MPSolver* solver) const;
void CreateVariable(unsigned idxVar, ILinearProblem& pb) const;
void CopyVariables(ILinearProblem& pb) const;
void UpdateContraints(unsigned idxRow, ILinearProblem& pb) const;
void CopyRows(ILinearProblem& pb) const;
void CopyMatrix(ILinearProblem& pb) const;
};
} // namespace Antares::Optimization
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright 2007-2024, RTE (https://www.rte-france.com)
* See AUTHORS.txt
* SPDX-License-Identifier: MPL-2.0
* This file is part of Antares-Simulator,
* Adequacy and Performance assessment for interconnected energy networks.
*
* Antares_Simulator is free software: you can redistribute it and/or modify
* it under the terms of the Mozilla Public Licence 2.0 as published by
* the Mozilla Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Antares_Simulator is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Mozilla Public Licence 2.0 for more details.
*
* You should have received a copy of the Mozilla Public Licence 2.0
* along with Antares_Simulator. If not, see <https://opensource.org/license/mpl-2-0/>.
*/

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can't understand the point of this new class.
It seems like it adds nothing to its parent class.
Is the parent class not enough ?

Copy link
Contributor

Choose a reason for hiding this comment

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

For now, this only makes MPSolver public. As MPSolver is only needed in legacy code, this allows us to keep the design of the parent class clean: other users of the parent class must not need access to MPSolver

#pragma once

#include <antares/solver/modeler/ortoolsImpl/linearProblem.h>

namespace Antares::Optimization
{

class LegacyOrtoolsLinearProblem final
: public Antares::Solver::Modeler::OrtoolsImpl::OrtoolsLinearProblem
{
public:
LegacyOrtoolsLinearProblem(bool isMip, const std::string& solverName):
OrtoolsLinearProblem(isMip, solverName)
{
// nothing else to do
}

operations_research::MPSolver* getMpSolver()
{
return MpSolver();
}
};

} // namespace Antares::Optimization
14 changes: 7 additions & 7 deletions src/solver/optimisation/opt_appel_solveur_lineaire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
#include "antares/optimization-options/options.h"
#include "antares/solver/infeasible-problem-analysis/unfeasible-pb-analyzer.h"
#include "antares/solver/modeler/api/linearProblemBuilder.h"
#include "antares/solver/modeler/ortoolsImpl/linearProblem.h"
#include "antares/solver/optimisation/LegacyOrtoolsFiller.h"
#include "antares/solver/optimisation/LegacyOrtoolsLinearProblem.h"
#include "antares/solver/optimisation/opt_structure_probleme_a_resoudre.h"
#include "antares/solver/simulation/sim_structure_probleme_economique.h"
#include "antares/solver/utils/filename.h"
Expand Down Expand Up @@ -206,8 +206,8 @@ static SimplexResult OPT_TryToCallSimplex(const OptimizationOptions& options,

Probleme.NombreDeContraintesCoupes = 0;

auto ortoolsProblem = std::make_unique<OrtoolsLinearProblem>(Probleme.isMIP(),
options.ortoolsSolver);
auto ortoolsProblem = std::make_unique<LegacyOrtoolsLinearProblem>(Probleme.isMIP(),
options.ortoolsSolver);
auto legacyOrtoolsFiller = std::make_unique<LegacyOrtoolsFiller>(&Probleme);
std::vector<LinearProblemFiller*> fillersCollection = {legacyOrtoolsFiller.get()};
LinearProblemData LP_Data;
Expand All @@ -217,7 +217,7 @@ static SimplexResult OPT_TryToCallSimplex(const OptimizationOptions& options,
if (options.ortoolsUsed && solver == nullptr)
{
linearProblemBuilder.build(*ortoolsProblem, LP_Data, fillCtx);
solver = ortoolsProblem->MPSolver();
solver = ortoolsProblem->getMpSolver();
}
const std::string filename = createMPSfilename(optPeriodStringGenerator, optimizationNumber);

Expand Down Expand Up @@ -384,16 +384,16 @@ bool OPT_AppelDuSimplexe(const OptimizationOptions& options,

Probleme.SetUseNamedProblems(true);

auto ortoolsProblem = std::make_unique<OrtoolsLinearProblem>(Probleme.isMIP(),
options.ortoolsSolver);
auto ortoolsProblem = std::make_unique<LegacyOrtoolsLinearProblem>(Probleme.isMIP(),
options.ortoolsSolver);
auto legacyOrtoolsFiller = std::make_unique<LegacyOrtoolsFiller>(&Probleme);
std::vector<LinearProblemFiller*> fillersCollection = {legacyOrtoolsFiller.get()};
LinearProblemData LP_Data;
FillContext fillCtx(0, 167);
LinearProblemBuilder linearProblemBuilder(fillersCollection);

linearProblemBuilder.build(*ortoolsProblem, LP_Data, fillCtx);
auto MPproblem = std::shared_ptr<MPSolver>(ortoolsProblem->MPSolver());
auto MPproblem = std::shared_ptr<MPSolver>(ortoolsProblem->getMpSolver());

auto analyzer = makeUnfeasiblePbAnalyzer();
analyzer->run(MPproblem.get());
Expand Down
6 changes: 4 additions & 2 deletions src/tests/run-study-tests/actions_on_study/study_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ def run(self):
solver_full_path = str(Path(self.solver_path).resolve())

command = [solver_full_path, "-i", str(self.study_path)]
self.use_ortools = True
self.ortools_solver = "sirius"

if self.use_ortools:
command.append('--use-ortools')
command.append('--ortools-solver=' + self.ortools_solver)
else:
command.append('--use-ortools')
command.append('--ortools-solver=sirius')
if self.named_mps_problems:
command.append('--named-mps-problems')
if self.parallel:
Expand Down
Loading