Skip to content

Commit

Permalink
Feature/detect xpress at runtime (#724)
Browse files Browse the repository at this point in the history
* start

* start

* add more function

* by default add Xpress in available solvers list

* it works!

* it works 2

* tidy

* unload unused function

* fix conversion path->string

* add newline after msf

* set xpress dir env var

* windows set env var XPRESSDIR

* update windows getenv method

* update getenv

* write err in stderr

* build clean path

* print clearer err message

* list xpress dir

* list xpress dir 2

* list xpress dir 3

* list xpress dir 4

* list xpress dir 5

* remove prepos

* some move

* move header file

* treat warning

* remove prints

* do right

* suggestion by @flomnes

Co-authored-by: Florian Omnès <[email protected]>

* suggestion by @flomnes

Co-authored-by: Florian Omnès <[email protected]>

* suggestion by @florian

* rename namespace

* remove commented code

* resolve conflicts

* init Xpress env if needed

* check available Solvers once per program

* set Xpress bool check

* print the right log messages

* rename compile unit variable

* tmp disable xpress as this fork doesn't have it

* remove comments

* Revert "tmp disable xpress as this fork doesn't have it"

This reverts commit 4a8ad09.

---------

Co-authored-by: Florian Omnès <[email protected]>
  • Loading branch information
a-zakir and flomnes authored Dec 11, 2023
1 parent cbda47e commit e5ffb74
Show file tree
Hide file tree
Showing 13 changed files with 1,063 additions and 68 deletions.
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
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

0 comments on commit e5ffb74

Please sign in to comment.