...
 
Commits (18)
......@@ -291,12 +291,9 @@ else ()
set (COMISO_TAUCS_CONFIG_FILE_SETTINGS "#define COMISO_TAUCS_AVAILABLE 0" )
endif ()
find_package (GUROBI)
if (GUROBI_FOUND )
find_package (Gurobi)
if (TARGET Gurobi::GurobiCXX )
set (COMISO_GUROBI_CONFIG_FILE_SETTINGS "#define COMISO_GUROBI_AVAILABLE 1" )
list( APPEND COMISO_INCLUDE_DIRECTORIES ${GUROBI_INCLUDE_DIRS} )
# list( APPEND COMISO_LINK_DIRECTORIES ${GUROBI_LIBRARY_DIR} )
list( APPEND COMISO_LINK_LIBRARIES ${GUROBI_LIBRARIES} )
else ()
message (STATUS "GUROBI not found!")
set (COMISO_GUROBI_CONFIG_FILE_SETTINGS "#define COMISO_GUROBI_AVAILABLE 0" )
......@@ -475,9 +472,11 @@ if ( QT5_FOUND )
endif()
target_link_libraries (CoMISo
${COMISO_LINK_LIBRARIES}
)
target_link_libraries (CoMISo PUBLIC ${COMISO_LINK_LIBRARIES})
if (TARGET Gurobi::GurobiCXX)
target_link_libraries (CoMISo PRIVATE Gurobi::GurobiCXX)
endif()
# display results
......@@ -622,7 +621,7 @@ if(NOT COMISO_NO_INSTALL)
PATTERN "Debian*" EXCLUDE)
# Install Config File
install( FILES ${CMAKE_BINARY_DIR}/CoMISo/Config/config.hh
install( FILES ${CMAKE_CURRENT_BINARY_DIR}/CoMISo/Config/config.hh
DESTINATION include/CoMISo/Config )
export(EXPORT CoMISoTargets NAMESPACE CoMISo::)
......
......@@ -316,6 +316,7 @@ solve(NProblemInterface* _problem,
try
{
GRBEnv env = GRBEnv();
applyEnvParams(&env);
GRBModel model = GRBModel(env);
auto vars = allocate_variables(_problem, _discrete_constraints, model);
......@@ -375,8 +376,10 @@ solve_two_phase(NProblemInterface* _problem, //
try
{
GRBEnv env = GRBEnv();
applyEnvParams(&env);
GRBModel model = GRBModel(env);
auto vars = allocate_variables(_problem, _discrete_constraints, model);
set_start(_problem, model, vars, start_solution_output_path_);
setup_constraints(_problem, _constraints, model, vars);
......@@ -444,8 +447,10 @@ solve(NProblemInterface* _problem,
//----------------------------------------------
GRBEnv env = GRBEnv();
applyEnvParams(&env);
GRBModel model = GRBModel(env);
auto vars = allocate_variables(_problem, _discrete_constraints, model);
set_start(_problem, model, vars, start_solution_output_path_);
setup_constraints(_problem, _constraints, model, vars);
......@@ -771,6 +776,7 @@ solve(NProblemInterface* _problem,
//----------------------------------------------
GRBEnv env = GRBEnv();
applyEnvParams(&env);
GRBModel model = GRBModel(env);
//----------------------------------------------
......@@ -874,7 +880,13 @@ void
GUROBISolver::
set_solution_input_path(const std::string &_solution_input_path)
{
solution_input_path_ = _solution_input_path;
solution_input_path_ = _solution_input_path;
}
void GUROBISolver::applyEnvParams(GRBEnv *env)
{
env->set(GRB_DoubleParam_Heuristics, grb_Heuristics_);
env->set(GRB_IntParam_MIPFocus, grb_MIPFocus_);
}
......
......@@ -24,6 +24,7 @@
//== FORWARDDECLARATIONS ======================================================
class GRBEnv;
//== NAMESPACES ===============================================================
......@@ -119,6 +120,8 @@ public:
void set_problem_env_output_path ( const std::string &_problem_env_output_path);
void set_solution_input_path ( const std::string &_solution_input_path);
void set_GRB_MIPFocus(int val) { grb_MIPFocus_ = val;}
void set_GRB_Heuristics(double val) { grb_Heuristics_ = val;}
protected:
private:
......@@ -129,6 +132,11 @@ private:
std::string start_solution_output_path_;
std::string problem_env_output_path_;
std::string solution_input_path_;
// gurobi env parameters, set to their gurobi defaults:
void applyEnvParams(GRBEnv *env);
int grb_MIPFocus_ = 0; // https://www.gurobi.com/documentation/8.1/refman/mipfocus.html
double grb_Heuristics_ = 0.05 ; // https://www.gurobi.com/documentation/8.1/refman/heuristics.html
};
......
......@@ -72,8 +72,8 @@ CholmodSolver::~CholmodSolver()
//-----------------------------------------------------------------------------
bool CholmodSolver::calc_system( const std::vector<int>& _colptr,
const std::vector<int>& _rowind,
bool CholmodSolver::calc_system( const std::vector<SuiteSparseInt>& _colptr,
const std::vector<SuiteSparseInt>& _rowind,
const std::vector<double>& _values)
{
if(show_timings_) sw_.start();
......@@ -98,7 +98,7 @@ bool CholmodSolver::calc_system( const std::vector<int>& _colptr,
// matA.stype = -1;
matA.stype = 1;
matA.itype = CHOLMOD_INT;
matA.itype = SuiteSparseITYPE;
matA.xtype = CHOLMOD_REAL;
matA.dtype = CHOLMOD_DOUBLE;
matA.sorted = 1;
......@@ -154,11 +154,11 @@ bool CholmodSolver::calc_system( const std::vector<int>& _colptr,
//-----------------------------------------------------------------------------
bool CholmodSolver::calc_system_prepare_pattern( const std::vector<int>& _colptr,
const std::vector<int>& _rowind,
bool CholmodSolver::calc_system_prepare_pattern( const std::vector<SuiteSparseInt>& _colptr,
const std::vector<SuiteSparseInt>& _rowind,
const std::vector<double>& _values,
const std::vector<int>& _colptr2,
const std::vector<int>& _rowind2,
const std::vector<SuiteSparseInt>& _colptr2,
const std::vector<SuiteSparseInt>& _rowind2,
const std::vector<double>& _values2 )
{
if(show_timings_) sw_.start();
......@@ -179,12 +179,12 @@ bool CholmodSolver::calc_system_prepare_pattern( const std::vector<int>& _col
matA.p = &colptr_[0];
matA.i = &rowind_[0];
matA.x = &values_[0];
matA.nz = 0;
matA.z = 0;
matA.nz = nullptr;
matA.z = nullptr;
// matA.stype = -1;
matA.stype = 1;
matA.itype = CHOLMOD_INT;
matA.itype = SuiteSparseITYPE;
matA.xtype = CHOLMOD_REAL;
matA.dtype = CHOLMOD_DOUBLE;
matA.sorted = 1;
......@@ -197,15 +197,15 @@ bool CholmodSolver::calc_system_prepare_pattern( const std::vector<int>& _col
matA_pattern.ncol = n;
matA_pattern.nzmax = _values2.size();
matA_pattern.p = (int*)(&_colptr2[0]);
matA_pattern.i = (int*)(&_rowind2[0]);
matA_pattern.x = (double*)(&_values2[0]);
matA_pattern.nz = 0;
matA_pattern.z = 0;
matA_pattern.p = (void*)(&_colptr2[0]);
matA_pattern.i = (void*)(&_rowind2[0]);
matA_pattern.x = (void*)(&_values2[0]);
matA_pattern.nz = nullptr;
matA_pattern.z = nullptr;
// matA_pattern.stype = -1;
matA_pattern.stype = 1;
matA_pattern.itype = CHOLMOD_INT;
matA_pattern.itype = SuiteSparseITYPE;
matA_pattern.xtype = CHOLMOD_REAL;
matA_pattern.dtype = CHOLMOD_DOUBLE;
matA_pattern.sorted = 1;
......@@ -221,7 +221,7 @@ bool CholmodSolver::calc_system_prepare_pattern( const std::vector<int>& _col
// compute permutation based on full pattern
std::vector<int> perm(matA_pattern.nrow);
std::vector<SuiteSparseInt> perm(matA_pattern.nrow);
// cholmod_metis(&matA_pattern, 0, 0, 0, perm.data(), mp_cholmodCommon) ;
cholmod_amd(&matA_pattern, 0, 0, perm.data(), mp_cholmodCommon) ;
......@@ -272,8 +272,8 @@ bool CholmodSolver::calc_system_prepare_pattern( const std::vector<int>& _col
//-----------------------------------------------------------------------------
bool CholmodSolver::update_system( const std::vector<int>& _colptr,
const std::vector<int>& _rowind,
bool CholmodSolver::update_system( const std::vector<SuiteSparseInt>& _colptr,
const std::vector<SuiteSparseInt>& _rowind,
const std::vector<double>& _values )
{
if( !mp_L )
......@@ -298,7 +298,7 @@ bool CholmodSolver::update_system( const std::vector<int>& _colptr,
// matA.stype = -1;
matA.stype = 1;
matA.itype = CHOLMOD_INT;
matA.itype = SuiteSparseITYPE;
matA.xtype = CHOLMOD_REAL;
matA.dtype = CHOLMOD_DOUBLE;
matA.sorted = 1;
......@@ -318,8 +318,8 @@ bool CholmodSolver::update_system( const std::vector<int>& _colptr,
//-----------------------------------------------------------------------------
bool CholmodSolver::update_downdate_factor( const std::vector<int>& _colptr,
const std::vector<int>& _rowind,
bool CholmodSolver::update_downdate_factor( const std::vector<SuiteSparseInt>& _colptr,
const std::vector<SuiteSparseInt>& _rowind,
const std::vector<double>& _values,
const bool _upd)
{
......@@ -344,14 +344,14 @@ bool CholmodSolver::update_downdate_factor( const std::vector<int>& _colptr,
matA.z = 0;
matA.stype = 0;
matA.itype = CHOLMOD_INT;
matA.itype = SuiteSparseITYPE;
matA.xtype = CHOLMOD_REAL;
matA.dtype = CHOLMOD_DOUBLE;
matA.sorted = 1;
matA.packed = 1;
// get permuted matrix
cholmod_sparse* matAp = cholmod_submatrix ( &matA, (int*)mp_L->Perm, mp_L->n, 0, -1, true, true, mp_cholmodCommon);
cholmod_sparse* matAp = cholmod_submatrix ( &matA, (SuiteSparseInt*)mp_L->Perm, mp_L->n, 0, -1, true, true, mp_cholmodCommon);
if(show_timings_)
{
std::cerr << " Cholmod conversion Timing: " << sw_.stop()/1000.0 << "s\n";
......@@ -417,9 +417,14 @@ bool CholmodSolver::solve( double * _x, double * _b)
//-----------------------------------------------------------------------------
int CholmodSolver::dimension()
size_t CholmodSolver::dimension()
{
return std::max(int(0), (int)(colptr_.size()-1));
size_t s = colptr_.size();
if (s == 0) {
return 0;
} else {
return s - 1;
}
}
//-----------------------------------------------------------------------------
......
......@@ -52,6 +52,31 @@
// typedef struct cholmod_factor_struct cholmod_factor;
#ifndef USE_CHOLMOD_LONG_MODE
# define USE_CHOLMOD_LONG_MODE 0
#endif
#if USE_CHOLMOD_LONG_MODE
# define SuiteSparseInt SuiteSparse_long
# define SuiteSparseITYPE CHOLMOD_LONG
# define cholmod_amd cholmod_l_amd
# define cholmod_analyze cholmod_l_analyze
# define cholmod_analyze_p cholmod_l_analyze_p
# define cholmod_factorize cholmod_l_factorize
# define cholmod_finish cholmod_l_finish
# define cholmod_free_sparse cholmod_l_free_sparse
# define cholmod_free_dense cholmod_l_free_dense
# define cholmod_free_factor cholmod_l_free_factor
# define cholmod_metis cholmod_l_metis
# define cholmod_solve cholmod_l_solve
# define cholmod_start cholmod_l_start
# define cholmod_submatrix cholmod_l_submatrix
# define cholmod_updown cholmod_l_updown
#else
# define SuiteSparseInt int
# define SuiteSparseITYPE CHOLMOD_INT
#endif
//== NAMESPACES ===============================================================
namespace COMISO {
......@@ -65,15 +90,15 @@ public:
CholmodSolver();
~CholmodSolver();
bool calc_system( const std::vector<int>& _colptr,
const std::vector<int>& _rowind,
bool calc_system( const std::vector<SuiteSparseInt>& _colptr,
const std::vector<SuiteSparseInt>& _rowind,
const std::vector<double>& _values );
bool calc_system_prepare_pattern( const std::vector<int>& _colptr,
const std::vector<int>& _rowind,
bool calc_system_prepare_pattern( const std::vector<SuiteSparseInt>& _colptr,
const std::vector<SuiteSparseInt>& _rowind,
const std::vector<double>& _values,
const std::vector<int>& _colptr2,
const std::vector<int>& _rowind2,
const std::vector<SuiteSparseInt>& _colptr2,
const std::vector<SuiteSparseInt>& _rowind2,
const std::vector<double>& _values2 );
......@@ -88,8 +113,8 @@ public:
bool calc_system_eigen_prepare_pattern( const Eigen_MatrixT& _mat, const Eigen_MatrixT& _mat_pattern);
bool update_system( const std::vector<int>& _colptr,
const std::vector<int>& _rowind,
bool update_system( const std::vector<SuiteSparseInt>& _colptr,
const std::vector<SuiteSparseInt>& _rowind,
const std::vector<double>& _values );
......@@ -100,8 +125,8 @@ public:
bool update_system_eigen( const Eigen_MatrixT& _mat);
bool update_downdate_factor( const std::vector<int>& _colptr,
const std::vector<int>& _rowind,
bool update_downdate_factor( const std::vector<SuiteSparseInt>& _colptr,
const std::vector<SuiteSparseInt>& _rowind,
const std::vector<double>& _values,
const bool _upd);
......@@ -115,7 +140,7 @@ public:
bool& show_timings();
int dimension();
size_t dimension();
private:
......@@ -124,8 +149,8 @@ private:
cholmod_factor * mp_L;
std::vector<double> values_;
std::vector<int> colptr_;
std::vector<int> rowind_;
std::vector<SuiteSparseInt> colptr_;
std::vector<SuiteSparseInt> rowind_;
bool show_timings_;
Base::StopWatch sw_;
......
......@@ -42,8 +42,8 @@ namespace COMISO {
template< class GMM_MatrixT>
bool CholmodSolver::calc_system_gmm( const GMM_MatrixT& _mat)
{
// std::vector<int> colptr;
// std::vector<int> rowind;
// std::vector<SuiteSparseInt> colptr;
// std::vector<SuiteSparseInt> rowind;
// std::vector<double> values;
......@@ -71,8 +71,8 @@ bool CholmodSolver::calc_system_gmm( const GMM_MatrixT& _mat)
template< class GMM_MatrixT>
bool CholmodSolver::update_system_gmm( const GMM_MatrixT& _mat)
{
// std::vector<int> colptr;
// std::vector<int> rowind;
// std::vector<SuiteSparseInt> colptr;
// std::vector<SuiteSparseInt> rowind;
// std::vector<double> values;
COMISO_GMM::get_ccs_symmetric_data( _mat,
......@@ -126,8 +126,8 @@ bool CholmodSolver::calc_system_eigen_prepare_pattern( const Eigen_MatrixT& _mat
#endif
std::vector<double> values2;
std::vector<int> colptr2;
std::vector<int> rowind2;
std::vector<SuiteSparseInt> colptr2;
std::vector<SuiteSparseInt> rowind2;
#if COMISO_EIGEN3_AVAILABLE
COMISO_EIGEN::get_ccs_symmetric_data( _mat_pattern,
......
......@@ -260,6 +260,17 @@ public:
/// Set noise-level (how much std output is given) 0 basically none, 1 important stuff (warning/timing, is default), 2+ not so important
void set_noisy( int _noisy) { noisy_ = _noisy;}
/// Support changing the RHS of the constraint system in resolve(). Enabled by default.
/// If this is needed, it must be enabled for the initial solve, not just before the resolve!
/// Warning: This can impose substantial memory overhead for large sparse constraint systems.
void set_support_constraint_rhs_resolve( bool _val) {
support_constraint_rhs_resolve_ = _val;
if (!_val) {
// Disabling support means we don't need the content of D_ anymore.
this->rhs_update_table_.D_ = {};
}
}
// Get/Set whether the constraint reordering is used (default true)
bool& use_constraint_reordering() { return miso_.use_constraint_reordering(); }
......@@ -361,6 +372,9 @@ private:
int noisy_;
bool do_gcd_;
// User-configurable, whether to store information for constraint-rhs resolve:
bool support_constraint_rhs_resolve_ = true;
// --------------- Update by Marcel to enable efficient re-solve with changed rhs ----------------------
// Store for symbolic elimination information for rhs
class rhsUpdateTable {
......
This diff is collapsed.
......@@ -56,6 +56,11 @@ namespace COMISO_GMM
*/
// cf. issue #3 - gmm5.2 compat
template <typename T>
using linalg_traits = typename gmm::linalg_traits<typename std::remove_const<typename std::remove_reference<T>::type>::type>;
//== FUNCTION DEFINITION ======================================================
/** @name Variable elimination
......
......@@ -50,7 +50,6 @@ namespace COMISO_GMM
//== IMPLEMENTATION ==========================================================
//-----------------------------------------------------------------------------
......@@ -377,8 +376,8 @@ void eliminate_var( const unsigned int _j,
//sw1.start();
typedef typename gmm::linalg_traits< gmm::col_matrix< SVT > >::const_sub_col_type ColT;
typedef typename gmm::linalg_traits<ColT>::const_iterator CIter;
typedef typename linalg_traits< gmm::col_matrix< SVT > >::const_sub_col_type ColT;
typedef typename linalg_traits<ColT>::const_iterator CIter;
unsigned int m = gmm::mat_nrows( _A );
unsigned int n = gmm::mat_ncols( _A );
......@@ -424,7 +423,7 @@ void eliminate_var( const unsigned int _j,
CIter it = gmm::vect_const_begin(col);
CIter ite = gmm::vect_const_end(col);
// compute new index
unsigned int i_new = i;
if( i>_j) --i_new;
......@@ -445,7 +444,7 @@ void eliminate_var( const unsigned int _j,
*/
//sw1.start();
typedef typename gmm::linalg_traits<SVT>::const_iterator SIter;
typedef typename linalg_traits<SVT>::const_iterator SIter;
for ( unsigned int i=0; i<m; ++i )
{
......@@ -580,8 +579,8 @@ void eliminate_vars( const std::vector<IntegerT>& _evar,
VectorT& _rhs )
{
std::cerr << __FUNCTION__ << std::endl;
typedef typename gmm::linalg_traits<MatrixT>::const_sub_col_type ColT;
typedef typename gmm::linalg_traits<ColT>::const_iterator CIter;
typedef typename linalg_traits<MatrixT>::const_sub_col_type ColT;
typedef typename linalg_traits<ColT>::const_iterator CIter;
// unsigned int m = gmm::mat_nrows( _A);
unsigned int n = gmm::mat_ncols( _A );
......@@ -746,7 +745,7 @@ void eliminate_vars( const std::vector<IntegerT>& _evar,
template<class IntegerT, class IntegerT2>
void eliminate_vars_idx( const std::vector<IntegerT >& _evar,
std::vector<IntegerT2>& _idx,
IntegerT2 _dummy,
IntegerT2 _dummy,
IntegerT2 _range )
{
// sort input
......@@ -902,8 +901,8 @@ void regularize_hack( MatrixT& _mat, double _v )
template<class MatrixT, class VectorT>
int gauss_seidel_local( MatrixT& _A, VectorT& _x, VectorT& _rhs, std::vector<unsigned int> _idxs, int _max_iter, double _tolerance )
{
typedef typename gmm::linalg_traits<MatrixT>::const_sub_col_type ColT;
typedef typename gmm::linalg_traits<ColT>::const_iterator CIter;
typedef typename linalg_traits<MatrixT>::const_sub_col_type ColT;
typedef typename linalg_traits<ColT>::const_iterator CIter;
double t2 = _tolerance*_tolerance;
......@@ -1009,10 +1008,10 @@ void factored_to_quadratic( MatrixT& _F, MatrixT2& _Q, VectorT& _rhs)
gmm::resize(Q, n - 1, n - 1);
_rhs.resize(n - 1);
PROGRESS_TICK;
gmm::copy(Q, _Q);
gmm::copy(Q, _Q);
}
//-----------------------------------------------------------------------------
......@@ -1021,16 +1020,16 @@ void factored_to_quadratic_rhs_only( MatrixT& _F, VectorT& _rhs)
{
unsigned int m = gmm::mat_nrows(_F);
unsigned int n = gmm::mat_ncols(_F);
gmm::resize(_rhs, n);
// compute quadratic matrix
MatrixT Q(n,n);
gmm::mult(gmm::transposed(_F),_F,Q);
// extract rhs
gmm::copy( gmm::scaled(gmm::mat_const_row( Q, n - 1),-1.0), _rhs);
_rhs.resize( n - 1);
}
......@@ -1043,7 +1042,7 @@ template<class MatrixT>
void inspect_matrix( const MatrixT& _A)
{
typedef typename MatrixT::value_type VType;
int m = gmm::mat_nrows(_A);
int n = gmm::mat_ncols(_A);
......@@ -1079,12 +1078,12 @@ void inspect_matrix( const MatrixT& _A)
int n_nan = 0;
int n_inf = 0;
// inspect elements
for(int i=0; i<n; ++i)
{
typedef typename gmm::linalg_traits< gmm::col_matrix< gmm::wsvector<VType> > >::const_sub_col_type ColT;
typedef typename gmm::linalg_traits<ColT>::const_iterator CIter;
typedef typename linalg_traits< gmm::col_matrix< gmm::wsvector<VType> > >::const_sub_col_type ColT;
typedef typename linalg_traits<ColT>::const_iterator CIter;
ColT col = mat_const_col( Acol, i );
CIter it = gmm::vect_const_begin( col );
......
# Once done this will define
# GUROBI_FOUND - System has Gurobi
# GUROBI_INCLUDE_DIRS - The Gurobi include directories
# GUROBI_LIBRARIES - The libraries needed to use Gurobi
# Gurobi_FOUND - System has Gurobi
# Targets:
# Gurobi::GurobiC - only the C interface
# Gurobi::GurobiCXX - C and C++ interface
set(GUROBI_ENABLE OFF CACHE BOOL "Enable gurobi?")
if (GUROBI_ENABLE)
set(GUROBI_BASE $ENV{GUROBI_HOME} CACHE PATH "GUROBI root directory.")
find_path(GUROBI_INCLUDE_DIR
NAMES gurobi_c++.h
find_path(GUROBI_HOME
NAMES include/gurobi_c++.h
PATHS
"${GUROBI_BASE}/include"
"$ENV{GUROBI_HOME}/include"
$ENV{GUROBI_HOME}
"/opt/gurobi/linux64/"
)
get_filename_component(GUROBI_LIB_DIR "${GUROBI_INCLUDE_DIR}/../lib" ABSOLUTE)
# GUROBI_BIN_DIR is needed on windows, where it contains the .dll
get_filename_component(GUROBI_BIN_DIR "${GUROBI_INCLUDE_DIR}/../bin" ABSOLUTE)
get_filename_component(GUROBI_SRC_DIR "${GUROBI_INCLUDE_DIR}/../src" ABSOLUTE)
find_path(GUROBI_INCLUDE_DIR
NAMES gurobi_c++.h
HINTS
"${GUROBI_HOME}/include"
)
mark_as_advanced(GUROBI_INCLUDE_DIR)
file(GLOB GUROBI_LIBRARY_LIST
RELATIVE ${GUROBI_LIB_DIR}
${GUROBI_LIB_DIR}/libgurobi*.so
${GUROBI_LIB_DIR}/libgurobi*.dll)
set(GUROBI_BIN_DIR "${GUROBI_HOME}/bin")
set(GUROBI_LIB_DIR "${GUROBI_HOME}/lib")
if (WIN32)
file(GLOB GUROBI_LIBRARY_LIST
RELATIVE ${GUROBI_BIN_DIR}
${GUROBI_BIN_DIR}/gurobi*.dll
)
else()
file(GLOB GUROBI_LIBRARY_LIST
RELATIVE ${GUROBI_LIB_DIR}
${GUROBI_LIB_DIR}/libgurobi*.so
)
endif()
# Ignore libgurobiXY_light.so, libgurobi.so (without version):
string(REGEX MATCHALL
"libgurobi([0-9]+)\\..*"
"gurobi([0-9]+)\\..*"
GUROBI_LIBRARY_LIST
"${GUROBI_LIBRARY_LIST}"
)
string(REGEX REPLACE
"libgurobi([0-9]+)\\..*"
".*gurobi([0-9]+)\\..*"
"\\1"
GUROBI_LIBRARY_VERSIONS
"${GUROBI_LIBRARY_LIST}")
......@@ -44,68 +49,76 @@ list(LENGTH GUROBI_LIBRARY_VERSIONS GUROBI_NUMVER)
#message("GUROBI LIB VERSIONS: ${GUROBI_LIBRARY_VERSIONS}")
if (GUROBI_NUMVER EQUAL 1)
if (GUROBI_NUMVER EQUAL 0)
message(STATUS "Found no Gurobi library version, GUROBI_HOME = ${GUROBI_HOME}.")
elseif (GUROBI_NUMVER EQUAL 1)
list(GET GUROBI_LIBRARY_VERSIONS 0 GUROBI_LIBRARY_VERSION)
set(GUROBI_LIBRARY_NAME "gurobi${GUROBI_LIBRARY_VERSION}")
else()
# none or more than one versioned library -let's try without suffix,
# maybe the user added a symlink to the desired library
set(GUROBI_LIBRARY_NAME "gurobi")
message(STATUS "Found more than one Gurobi library version (${GUROBI_LIBRARY_VERSIONS}), trying without suffix. Set GUROBI_LIBRARY if you want to pick a certain one.")
set(GUROBI_LIBRARY_VERSION "")
endif()
#message("GUROBI LIB NAME: ${GUROBI_LIBRARY_NAME}")
find_library(GUROBI_LIBRARY
NAMES ${GUROBI_LIBRARY_NAME}
PATHS
"${GUROBI_BASE}/lib"
"$ENV{GUROBI_HOME}/lib"
)
if (WIN32)
find_library(GUROBI_LIBRARY
NAMES "gurobi${GUROBI_LIBRARY_VERSION}"
PATHS
${GUROBI_BIN_DIR}
)
find_library(GUROBI_IMPLIB
NAMES "gurobi${GUROBI_LIBRARY_VERSION}"
PATHS
${GUROBI_LIB_DIR}
)
mark_as_advanced(GUROBI_IMPLIB)
else ()
find_library(GUROBI_LIBRARY
NAMES "gurobi${GUROBI_LIBRARY_VERSION}"
PATHS
${GUROBI_LIB_DIR}
)
endif()
mark_as_advanced(GUROBI_LIBRARY)
if(GUROBI_LIBRARY AND NOT TARGET Gurobi::GurobiC)
add_library(Gurobi::GurobiC SHARED IMPORTED)
target_include_directories(Gurobi::GurobiC INTERFACE ${GUROBI_INCLUDE_DIR})
set_target_properties(Gurobi::GurobiC PROPERTIES IMPORTED_LOCATION ${GUROBI_LIBRARY})
if (GUROBI_IMPLIB)
set_target_properties(Gurobi::GurobiC PROPERTIES IMPORTED_IMPLIB ${GUROBI_IMPLIB})
endif()
endif()
# Gurobi ships with some compiled versions of its C++ library for specific
# compilers, however it also comes with the source code. We will compile
# the source code outselves -- this is much safer, as it guarantees the same
# compiler version and flags.
# (Note: doing this is motivated by actual sometimes-subtle ABI compatibility bugs)
# The old behaviour can be enabled with GUROBI_USE_PRECOMPILED_CXX)
option(GUROBI_USE_PRECOMPILED_CXX "Use precompiled C++ libraries instead of building it ourselves. Not recommended." OFF)
mark_as_advanced(GUROBI_USE_PRECOMPILED_CXX)
if(GUROBI_USE_PRECOMPILED_CXX)
if ( CMAKE_GENERATOR MATCHES "^Visual Studio 12.*Win64" )
SET(GUROBI_LIB_NAME "gurobi_c++md2013")
endif()
find_library(GUROBI_CXX_LIBRARY
NAMES gurobi_c++
${GUROBI_LIB_NAME}
PATHS "$ENV{GUROBI_HOME}/lib"
"${GUROBI_BASE}/lib"
)
else()
file(GLOB GUROBI_CXX_SRC CONFIGURE_DEPENDS ${GUROBI_SRC_DIR}/cpp/*.cpp)
if(NOT GUROBI_CXX_SRC)
message(FATAL_ERROR "could not find gurobi c++ sources in GUROBI_SRC_DIR=${GUROBI_SRC_DIR}/cpp/.")
find_path(GUROBI_SRC_DIR NAMES "Model.h" PATHS "${GUROBI_HOME}/src/cpp/")
mark_as_advanced(GUROBI_SRC_DIR)
file(GLOB GUROBI_CXX_SRC CONFIGURE_DEPENDS ${GUROBI_SRC_DIR}/*.cpp)
if(TARGET Gurobi::GurobiC AND GUROBI_CXX_SRC AND NOT TARGET Gurobi::GurobiCXX)
add_library(GurobiCXX STATIC EXCLUDE_FROM_ALL ${GUROBI_CXX_SRC})
add_library(Gurobi::GurobiCXX ALIAS GurobiCXX)
if(MSVC)
target_compile_definitions(GurobiCXX PRIVATE "WIN64")
endif()
add_library(GurobiCXX STATIC ${GUROBI_CXX_SRC})
target_include_directories(GurobiCXX PUBLIC ${GUROBI_INCLUDE_DIR})
target_link_libraries(GurobiCXX PUBLIC Gurobi::GurobiC)
# We need to be able to link this into a shared library:
set_target_properties(GurobiCXX PROPERTIES POSITION_INDEPENDENT_CODE ON)
set(GUROBI_CXX_LIBRARY $<TARGET_FILE:GurobiCXX>)
endif(GUROBI_USE_PRECOMPILED_CXX)
set(GUROBI_INCLUDE_DIRS "${GUROBI_INCLUDE_DIR}" )
set(GUROBI_LIBRARIES "${GUROBI_CXX_LIBRARY};${GUROBI_LIBRARY}" )
endif()
# use c++ headers as default
# set(GUROBI_COMPILER_FLAGS "-DIL_STD" CACHE STRING "Gurobi Compiler Flags")
# legacy support:
set(GUROBI_INCLUDE_DIRS "${GUROBI_INCLUDE_DIR}")
set(GUROBI_LIBRARIES Gurobi::GurobiC Gurobi::GurobiCXX)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GUROBI DEFAULT_MSG
GUROBI_CXX_LIBRARY GUROBI_LIBRARY GUROBI_INCLUDE_DIR)
mark_as_advanced(GUROBI_INCLUDE_DIR GUROBI_LIBRARY GUROBI_CXX_LIBRARY GUROBI_BIN_DIR )
endif(GUROBI_ENABLE)
find_package_handle_standard_args(Gurobi DEFAULT_MSG GUROBI_LIBRARY GUROBI_INCLUDE_DIR GUROBI_SRC_DIR)
This diff is collapsed.