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

Feature/detect xpress at runtime #724

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
3519bf7
start
a-zakir Oct 18, 2023
1cd9fa2
start
a-zakir Oct 18, 2023
d9f7126
add more function
a-zakir Oct 19, 2023
3963904
by default add Xpress in available solvers list
a-zakir Oct 19, 2023
1b7746c
Merge branch 'develop'
a-zakir Oct 19, 2023
45f1a0b
it works!
a-zakir Oct 19, 2023
2e0b58f
it works 2
a-zakir Oct 19, 2023
57461f6
tidy
a-zakir Oct 20, 2023
1c88437
unload unused function
a-zakir Oct 20, 2023
de57ad5
fix conversion path->string
a-zakir Oct 20, 2023
0450e4c
add newline after msf
a-zakir Oct 20, 2023
2393fdd
set xpress dir env var
a-zakir Oct 20, 2023
88ba8c7
windows set env var XPRESSDIR
a-zakir Oct 20, 2023
d784054
update windows getenv method
a-zakir Oct 23, 2023
ca3b226
update getenv
a-zakir Oct 23, 2023
5b8710c
write err in stderr
a-zakir Oct 23, 2023
239c78f
build clean path
a-zakir Oct 23, 2023
f46956a
print clearer err message
a-zakir Oct 23, 2023
d30bdf3
list xpress dir
a-zakir Oct 23, 2023
ea1c4f0
list xpress dir 2
a-zakir Oct 23, 2023
fbd3fda
list xpress dir 3
a-zakir Oct 23, 2023
80a7815
list xpress dir 4
a-zakir Oct 23, 2023
65f0ec1
list xpress dir 5
a-zakir Oct 23, 2023
ccbdf13
remove prepos
a-zakir Oct 24, 2023
682bd83
some move
a-zakir Oct 24, 2023
925a4a7
move header file
a-zakir Oct 24, 2023
9aa3c50
treat warning
a-zakir Oct 24, 2023
b5d1f37
remove prints
a-zakir Oct 24, 2023
d5c55f7
do right
a-zakir Oct 24, 2023
0c9c969
suggestion by @flomnes
a-zakir Nov 10, 2023
daa0971
suggestion by @flomnes
a-zakir Nov 10, 2023
06ed31a
suggestion by @florian
a-zakir Nov 10, 2023
9da5a5a
rename namespace
a-zakir Nov 10, 2023
2ce15ba
remove commented code
a-zakir Nov 10, 2023
562aa15
resolve conflicts
a-zakir Nov 10, 2023
5731bce
init Xpress env if needed
a-zakir Nov 15, 2023
dd28db3
check available Solvers once per program
a-zakir Nov 15, 2023
6340cb2
set Xpress bool check
a-zakir Nov 15, 2023
fa6cbf6
print the right log messages
a-zakir Nov 15, 2023
6aa147d
rename compile unit variable
a-zakir Nov 16, 2023
4a8ad09
tmp disable xpress as this fork doesn't have it
a-zakir Dec 11, 2023
f457cdc
remove comments
a-zakir Dec 11, 2023
3ac1b43
Revert "tmp disable xpress as this fork doesn't have it"
a-zakir Dec 11, 2023
df16339
Merge branch 'feature/detect_xpress_at_runtime' of https://github.com…
a-zakir Dec 11, 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
1 change: 1 addition & 0 deletions .github/workflows/build_windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,5 +141,6 @@ jobs:
run: |
set PATH=%PATH%;C:\Program Files\Microsoft MPI\Bin
set PATH=%PATH%;${{ env.XPRESS }}
set XPRESSDIR=${{ env.XPRESSDIR }}
cd _build
ctest -C Release --output-on-failure -L "medium|unit|benders|lpnamer"
1 change: 1 addition & 0 deletions .github/workflows/windows-vcpkg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ jobs:
run: |
set PATH=%PATH%;C:\Program Files\Microsoft MPI\Bin\
set PATH=%PATH%;${{ env.XPRESS }}
set XPRESSDIR=${{ env.XPRESSDIR }}
cd _build
ctest -C Release --output-on-failure -L "medium|unit|benders|lpnamer"

Expand Down
25 changes: 0 additions & 25 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -237,31 +237,6 @@ endif()

find_package(jsoncpp CONFIG REQUIRED)

# Third-party solver
## Xpress
if(XPRESS)
message("XPRESS is ${XPRESS}")

#Default xpress install dir
if (NOT XPRESS_ROOT)
if (MSVC)
set(XPRESS_ROOT "C:/xpressmp")
elseif(UNIX)
set(XPRESS_ROOT "/opt/xpressmp")
endif()
endif()

find_package(XPRESS REQUIRED)

# Add solver variables for usage in C++ source code
# There are already some variables defined by SOLVER, -DUSE_XPRESS, -DUSE_CBC
# But they are exclusive, only one can be set to True
# We need to keep COIN-OR at least COIN-OR to True while it is required in lpnamer
# and we want to allow compilation with several solvers so that the user can switch
# the solver without any compilation phase.
# @TODO : I think those parameters should be merged in a future version
add_definitions( -DXPRESS=true )
endif(XPRESS)


## Coin-OR (Clp and CBC solvers)
Expand Down
2 changes: 0 additions & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ if (COIN_OR)
SET(AVAILABLE_SOLVER_YML_LIST "${AVAILABLE_SOLVER_YML_LIST}- Cbc\n")
SET(AVAILABLE_SOLVER_YML_LIST "${AVAILABLE_SOLVER_YML_LIST}- Coin\n")
endif()
if (XPRESS)
SET(AVAILABLE_SOLVER_YML_LIST "${AVAILABLE_SOLVER_YML_LIST}- Xpress\n")
endif()


#configure file to define antares-solver executable
Expand Down
106 changes: 27 additions & 79 deletions src/cpp/lpnamer/main/RunProblemGeneration.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@

#include "RunProblemGeneration.h"

#include <boost/archive/text_iarchive.hpp>
#include <execution>
#include <iostream>

#include "ActiveLinks.h"
#include "AdditionalConstraints.h"
#include "Clock.h"
#include "GeneralDataReader.h"
#include "LauncherHelpers.h"
#include "LinkProblemsGenerator.h"
Expand All @@ -17,14 +15,12 @@
#include "MasterGeneration.h"
#include "MasterProblemBuilder.h"
#include "MpsTxtWriter.h"
#include "ProblemGenerationExeOptions.h"
#include "ProblemVariablesFromProblemAdapter.h"
#include "ProblemVariablesZipAdapter.h"
#include "StringManip.h"
#include "Timer.h"
#include "WeightsFileReader.h"
#include "WeightsFileWriter.h"
#include "XpansionProblemsFromAntaresProvider.h"
#include "ZipProblemsProviderAdapter.h"
#include "config.h"

Expand Down Expand Up @@ -59,6 +55,7 @@ struct Version {
int major;
int minor;
};

std::shared_ptr<ArchiveReader> InstantiateZipReader(
const std::filesystem::path& antares_archive_path);
void ProcessWeights(
Expand Down Expand Up @@ -128,6 +125,7 @@ std::vector<std::shared_ptr<Problem>> getXpansionProblems(
problem_names);
return adapter->provideProblems(solver_name, solver_log_manager);
}

void RunProblemGeneration(
const std::filesystem::path& xpansion_output_dir,
const std::string& master_formulation,
Expand Down Expand Up @@ -169,14 +167,10 @@ void RunProblemGeneration(
auto files_mapper = FilesMapper(antares_archive_path);
auto mpsList = files_mapper.MpsAndVariablesFilesVect();

bool use_zip_implementation = true;
bool use_file_implementation = false;

auto solver_log_manager = SolverLogManager(log_file_path);
Couplings couplings;
LinkProblemsGenerator linkProblemsGenerator(
lpDir_, links, solver_name, logger, solver_log_manager, rename_problems);
if (use_zip_implementation) {
std::shared_ptr<ArchiveReader> reader =
InstantiateZipReader(antares_archive_path);

Expand All @@ -185,79 +179,33 @@ void RunProblemGeneration(
getXpansionProblems(solver_log_manager, solver_name, mpsList, lpDir_,
reader);

std::vector<std::pair<std::shared_ptr<Problem>, ProblemData>>
problems_and_data;
for (int i = 0; i < xpansion_problems.size(); ++i) {
xpansion_problems.at(i)->_name = mpsList.at(i)._problem_mps;
problems_and_data.emplace_back(xpansion_problems.at(i), mpsList.at(i));
}
auto mps_file_writer = std::make_shared<MPSFileWriter>(lpDir_);
std::for_each(
std::execution::par, problems_and_data.begin(), problems_and_data.end(),
[&](const auto& problem_and_data) {
const auto& [problem, data] = problem_and_data;
std::shared_ptr<IProblemVariablesProviderPort> variables_provider;
if (rename_problems) {
variables_provider = std::make_shared<ProblemVariablesZipAdapter>(
reader, data, links, logger);
} else {
variables_provider =
std::make_shared<ProblemVariablesFromProblemAdapter>(
problem, links, logger);
}
linkProblemsGenerator.treat(data._problem_mps, couplings, problem.get(),
variables_provider.get(), mps_file_writer.get());
});

reader->Close();
reader->Delete();
} else if (use_file_implementation) {
/* Main stuff */
auto mps_file_writer = std::make_shared<MPSFileWriter>(lpDir_);
linkProblemsGenerator.treatloop(xpansion_output_dir, couplings, mpsList,
std::vector<std::pair<std::shared_ptr<Problem>, ProblemData>>
problems_and_data;
for (int i = 0; i < xpansion_problems.size(); ++i) {
xpansion_problems.at(i)->_name = mpsList.at(i)._problem_mps;
problems_and_data.emplace_back(xpansion_problems.at(i), mpsList.at(i));
}
auto mps_file_writer = std::make_shared<MPSFileWriter>(lpDir_);
std::for_each(
std::execution::par, problems_and_data.begin(), problems_and_data.end(),
[&](const auto& problem_and_data) {
const auto& [problem, data] = problem_and_data;
std::shared_ptr<IProblemVariablesProviderPort> variables_provider;
if (rename_problems) {
variables_provider = std::make_shared<ProblemVariablesZipAdapter>(
reader, data, links, logger);
} else {
variables_provider =
std::make_shared<ProblemVariablesFromProblemAdapter>(
problem, links, logger);
}
linkProblemsGenerator.treat(data._problem_mps, couplings, problem.get(),
variables_provider.get(),
mps_file_writer.get());
} else {
std::filesystem::path path =
xpansion_output_dir.parent_path().parent_path() /
"fichierDeSerialisation";
std::ifstream ifs(xpansion_output_dir.parent_path().parent_path() /
"fichierDeSerialisation");
boost::archive::text_iarchive ia(ifs);

LpsFromAntares lps;
ia >> lps;
lps._constant->Mdeb.push_back(lps._constant->NombreDeCoefficients);

XpansionProblemsFromAntaresProvider adapter(lps);
auto xpansion_problems =
adapter.provideProblems(solver_name, solver_log_manager);
std::vector<std::pair<std::shared_ptr<Problem>, ProblemData>>
problems_and_data;
for (int i = 0; i < xpansion_problems.size(); ++i) {
xpansion_problems.at(i)->_name = mpsList.at(i)._problem_mps;
problems_and_data.emplace_back(xpansion_problems.at(i), mpsList.at(i));
}

auto reader = InstantiateZipReader(antares_archive_path);
auto mps_file_writer = std::make_shared<MPSFileWriter>(lpDir_);
});

std::for_each(
std::execution::par, problems_and_data.begin(), problems_and_data.end(),
[&](const auto& problem_and_data) {
const auto& [problem, data] = problem_and_data;
std::shared_ptr<IProblemVariablesProviderPort> variables_provider;
if (rename_problems) {
variables_provider = std::make_shared<ProblemVariablesZipAdapter>(
reader, data, links, logger);
} else {
variables_provider =
std::make_shared<ProblemVariablesFromProblemAdapter>(
problem, links, logger);
}
linkProblemsGenerator.treat(data._problem_mps, couplings, problem.get(),
variables_provider.get(), mps_file_writer.get());
});
}
reader->Close();
reader->Delete();

MasterGeneration master_generation(
xpansion_output_dir, links, additionalConstraints, couplings,
Expand Down
15 changes: 6 additions & 9 deletions src/cpp/multisolver_interface/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ list(APPEND Solver_sources
${CMAKE_CURRENT_LIST_DIR}/SolverFactory.cpp
)

list(APPEND XPRESS_LOAD
${CMAKE_CURRENT_LIST_DIR}/environment.cc
)

# XPRESS
IF( XPRESS )
list(APPEND Solver_sources
${CMAKE_CURRENT_LIST_DIR}/SolverXpress.cpp
)
ENDIF( XPRESS )

#Clp - CBc
IF(COIN_OR)
Expand All @@ -39,6 +41,7 @@ ENDIF(COIN_OR)
# ---------------------------------------------------------------------------
add_library (solvers STATIC
${Solver_sources}
${XPRESS_LOAD}
)
get_target_property(xpansion_interfaces_path xpansion_interfaces INTERFACE_INCLUDE_DIRECTORIES)
target_include_directories (solvers
Expand All @@ -51,13 +54,6 @@ target_include_directories (solvers
)


# XPRESS
if(XPRESS)
target_link_libraries (solvers
PUBLIC
XPRESS::XPRESS
)
endif()

#CLP-CBC
if(COIN_OR)
Expand All @@ -68,5 +64,6 @@ if(COIN_OR)
Coin::CoinUtils
Coin::Osi
Coin::Cbc
${CMAKE_DL_LIBS}
)
endif()
47 changes: 25 additions & 22 deletions src/cpp/multisolver_interface/SolverFactory.cpp
Original file line number Diff line number Diff line change
@@ -1,34 +1,44 @@
#ifdef XPRESS

#include "SolverXpress.h"
#endif
#include "multisolver_interface/environment.h"

#ifdef COIN_OR
#include "SolverCbc.h"
#include "SolverClp.h"
#endif
#include "LogUtils.h"
#include "multisolver_interface/SolverFactory.h"
std::vector<std::string> available_solvers;

SolverFactory::SolverFactory() {
_available_solvers.clear();
#ifdef XPRESS
_available_solvers.push_back(XPRESS_STR);
#endif
std::vector<std::string> SolverLoader::GetAvailableSolvers() {
if (available_solvers.empty()) {
if (LoadXpress::XpressIsCorrectlyInstalled()) {
available_solvers.push_back(XPRESS_STR);
}
#ifdef COIN_OR
_available_solvers.push_back(CLP_STR);
_available_solvers.push_back(CBC_STR);
available_solvers.push_back(CLP_STR);
available_solvers.push_back(CBC_STR);
#endif
}
return available_solvers;
}

SolverFactory::SolverFactory()
: _available_solvers(SolverLoader::GetAvailableSolvers()) {
isXpress_available_ =
std::find(available_solvers.cbegin(), available_solvers.cend(),
XPRESS_STR) != available_solvers.cend();
}

SolverAbstract::Ptr SolverFactory::create_solver(
const std::string &solver_name, const SOLVER_TYPE solver_type) const {
if (solver_name == "") {
throw InvalidSolverNameException(solver_name, LOGLOCATION);
}
#ifdef XPRESS
else if (solver_name == XPRESS_STR) {

else if (isXpress_available_ && solver_name == XPRESS_STR) {
return std::make_shared<SolverXpress>();
}
#endif
#ifdef COIN_OR
if (solver_name == COIN_STR && solver_type == SOLVER_TYPE::CONTINUOUS) {
return std::make_shared<SolverClp>();
Expand Down Expand Up @@ -58,12 +68,9 @@ SolverAbstract::Ptr SolverFactory::create_solver(
const std::string &solver_name) const {
if (solver_name == "") {
throw InvalidSolverNameException(solver_name, LOGLOCATION);
}
#ifdef XPRESS
else if (solver_name == XPRESS_STR) {
} else if (isXpress_available_ && solver_name == XPRESS_STR) {
return std::make_shared<SolverXpress>();
}
#endif
#ifdef COIN_OR
else if (solver_name == CLP_STR) {
return std::make_shared<SolverClp>();
Expand All @@ -81,11 +88,9 @@ SolverAbstract::Ptr SolverFactory::create_solver(
if (solver_name == "") {
throw InvalidSolverNameException(solver_name, LOGLOCATION);
}
#ifdef XPRESS
else if (solver_name == XPRESS_STR) {
if (isXpress_available_ && solver_name == XPRESS_STR) {
return std::make_shared<SolverXpress>(log_manager);
}
#endif
#ifdef COIN_OR
else if (solver_name == CLP_STR) {
return std::make_shared<SolverClp>(log_manager);
Expand All @@ -105,11 +110,9 @@ SolverAbstract::Ptr SolverFactory::copy_solver(
if (solver_name == "") {
throw InvalidSolverNameException(solver_name, LOGLOCATION);
}
#ifdef XPRESS
else if (solver_name == XPRESS_STR) {
if (isXpress_available_ && solver_name == XPRESS_STR) {
return std::make_shared<SolverXpress>(to_copy);
}
#endif
#ifdef COIN_OR
else if (solver_name == CLP_STR) {
return std::make_shared<SolverClp>(to_copy);
Expand Down
3 changes: 3 additions & 0 deletions src/cpp/multisolver_interface/SolverXpress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

#include "StringManip.h"

using namespace LoadXpress;

/*************************************************************************************************
----------------------------------- Constructor/Desctructor
--------------------------------
Expand All @@ -25,6 +27,7 @@ SolverXpress::SolverXpress() {
std::lock_guard<std::mutex> guard(license_guard);
int status = 0;
if (_NumberOfProblems == 0) {
initXpressEnv();
status = XPRSinit(NULL);
zero_status_check(status, "initialize XPRESS environment", LOGLOCATION);
}
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 @@ -4,7 +4,7 @@
#include <mutex>

#include "multisolver_interface/SolverAbstract.h"
#include "xprs.h"
#include "multisolver_interface/environment.h"

/*!
* \class class SolverXpress
Expand Down
Loading
Loading