diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 1c25002..eb07cf7 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -60,15 +60,16 @@ jobs: with: python-version: ${{ matrix.python-version }} miniforge-version: latest - use-mamba: true - channels: conda-forge,gurobi,defaults channel-priority: true - name: install build deps - run: mamba install scip=9.1.0 gurobi gcovr + run: conda install -c conda-forge scip=9.1.0 gcovr + + - name: install gurobi + if: runner.os != 'Windows' + run: conda install -c gurobi gurobi=11.0.3 - name: add gurobi license - shell: bash id: write-license env: LICENSE: ${{ secrets.GRB_LICENSE_FILE }} @@ -78,6 +79,7 @@ jobs: - name: install package run: | + conda list python -m pip install -U pip python -m pip install -e .[dev] python setup.py build_ext --inplace # required for C coverage diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7e35fa3..a9dabd5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,20 +5,20 @@ ci: repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.3.4 + rev: v0.8.2 hooks: - id: ruff args: [--fix] - id: ruff-format - repo: https://github.com/MarcoGorelli/cython-lint - rev: v0.16.0 + rev: v0.16.6 hooks: - id: cython-lint - id: double-quote-cython-strings - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.9.0 + rev: v1.13.0 hooks: - id: mypy files: "^ilpy/" diff --git a/README.md b/README.md index d424317..ac64326 100644 --- a/README.md +++ b/README.md @@ -16,17 +16,23 @@ conda install -c funkelab ilpy ## Local development -ilpy links against SCIP, so you must have SCIP installed in your environment. -(You can install via conda) +Clone the repo and install in editable mode. -```bash -conda install scip==9.1.0 -``` - -Then clone the repo and install in editable mode. +Note, `ilpy` links against SCIP, so you must have SCIP installed in your environment, +in order to build: ```bash git clone cd ilpy + +conda create -n ilpy -c conda-forge -c gurobi python scip==9.1.0 gurobi==11.0.3 +conda activate ilpy pip install -e .[dev] ``` + +If you make local change and want to rebuild the extension quickly, you can run: + +```bash +rm -rf build +python setup.py build_ext --inplace +``` diff --git a/ilpy/__init__.py b/ilpy/__init__.py index 8888331..4a0938a 100644 --- a/ilpy/__init__.py +++ b/ilpy/__init__.py @@ -33,11 +33,11 @@ "Scip", "Sense", "Solution", - "solve", "Solver", "Solver", "Variable", "VariableType", + "solve", ] diff --git a/ilpy/expressions.py b/ilpy/expressions.py index 9595374..601cf74 100644 --- a/ilpy/expressions.py +++ b/ilpy/expressions.py @@ -2,7 +2,7 @@ import ast import sys -from collections.abc import Iterator, Sequence +from collections.abc import Iterator from contextlib import contextmanager from typing import Any, ClassVar, Union @@ -22,7 +22,7 @@ def recursion_limit_raised_by(N: int = 5000) -> Iterator[None]: sys.setrecursionlimit(old_limit) -class Expression(ast.AST): +class Expression(ast.expr): """Base class for all expression nodes. Expressions allow ilpy to represent mathematical expressions in an @@ -147,8 +147,8 @@ class Compare(Expression, ast.Compare): def __init__( self, left: Expression, - ops: Sequence[ast.cmpop], - comparators: Sequence[Expression | Number], + ops: list[ast.cmpop], + comparators: list[Expression | Number], **kwargs: Any, ) -> None: super().__init__( diff --git a/ilpy/impl/gurobi_c.h b/ilpy/impl/gurobi_c.h index 149c2a6..ca93f29 100644 --- a/ilpy/impl/gurobi_c.h +++ b/ilpy/impl/gurobi_c.h @@ -1,4 +1,4 @@ -/* Copyright 2022, Gurobi Optimization, LLC */ +/* Copyright 2024, Gurobi Optimization, LLC */ #ifndef _GUROBI_C_H #define _GUROBI_C_H @@ -40,9 +40,9 @@ typedef struct _GRBenv GRBenv; /* Version numbers */ -#define GRB_VERSION_MAJOR 9 -#define GRB_VERSION_MINOR 5 -#define GRB_VERSION_TECHNICAL 1 +#define GRB_VERSION_MAJOR 11 +#define GRB_VERSION_MINOR 0 +#define GRB_VERSION_TECHNICAL 3 /* Default and max priority for Compute Server jobs */ @@ -57,8 +57,9 @@ typedef struct _GRBenv GRBenv; #define DEFAULT_CS_HANGUP 60 -/* Error codes */ +/* Error codes: adjust MIN/MAX if adding new codes */ +#define GRB_C_MIN_ERROR 10001 #define GRB_ERROR_OUT_OF_MEMORY 10001 #define GRB_ERROR_NULL_ARGUMENT 10002 #define GRB_ERROR_INVALID_ARGUMENT 10003 @@ -91,6 +92,7 @@ typedef struct _GRBenv GRBenv; #define GRB_ERROR_CSWORKER 10030 #define GRB_ERROR_TUNE_MODEL_TYPES 10031 #define GRB_ERROR_SECURITY 10032 +#define GRB_C_MAX_ERROR 10032 /* Constraint senses */ @@ -251,6 +253,9 @@ int __stdcall GRBgetlogcallbackfuncenv(GRBenv *env, int (__stdcall **cbP)(LOGCB_ARGS), void **logdataP); + +int __stdcall + GRBcbproceed(void *cbdata_in); int __stdcall GRBcbget(void *cbdata, int where, int what, void *resultP); int __stdcall @@ -259,7 +264,7 @@ int __stdcall GRBcbsolution(void *cbdata, const double *solution, double *objvalP); int __stdcall GRBcbcut(void *cbdata, int cutlen, const int *cutind, const double *cutval, - char cutsense, double cutrhs); + char cutsense, double cutrhs); int __stdcall GRBcblazy(void *cbdata, int lazylen, const int *lazyind, const double *lazyval, char lazysense, double lazyrhs); @@ -287,11 +292,9 @@ int __stdcall #define GRB_INT_ATTR_MODELSENSE "ModelSense" /* 1=min, -1=max */ #define GRB_DBL_ATTR_OBJCON "ObjCon" /* Objective constant */ #define GRB_INT_ATTR_IS_MIP "IsMIP" /* Is model a MIP? */ -#define GRB_INT_ATTR_IS_QP "IsQP" /* Model has quadratic obj? */ +#define GRB_INT_ATTR_IS_QP "IsQP" /* Is model a QP/MIQP (without Q/NL constraints)? */ #define GRB_INT_ATTR_IS_QCP "IsQCP" /* Model has quadratic constr? */ #define GRB_INT_ATTR_IS_MULTIOBJ "IsMultiObj" /* Model has multiple objectives? */ -#define GRB_STR_ATTR_SERVER "Server" /* Name of Compute Server */ -#define GRB_STR_ATTR_JOBID "JobID" /* Compute Server job ID */ #define GRB_INT_ATTR_LICENSE_EXPIRATION "LicenseExpiration" /* License expiration date */ #define GRB_INT_ATTR_NUMTAGGED "NumTagged" /* number of tagged elements in model */ #define GRB_INT_ATTR_FINGERPRINT "Fingerprint" /* fingerprint computed from the model data and attributes influencing the optimization process */ @@ -343,9 +346,10 @@ int __stdcall /* General function constraint attributes */ #define GRB_INT_ATTR_FUNCPIECES "FuncPieces" /* An option for PWL translation */ -#define GRB_DBL_ATTR_FUNCPIECEERROR "FuncPieceError" /* An option for PWL translation */ +#define GRB_DBL_ATTR_FUNCPIECEERROR "FuncPieceError" /* An option for PWL translation */ #define GRB_DBL_ATTR_FUNCPIECELENGTH "FuncPieceLength" /* An option for PWL translation */ #define GRB_DBL_ATTR_FUNCPIECERATIO "FuncPieceRatio" /* An option for PWL translation */ +#define GRB_INT_ATTR_FUNCNONLINEAR "FuncNonlinear" /* An option for PWL translation */ /* Model statistics */ @@ -550,6 +554,7 @@ int __stdcall #define GRB_GENCONSTR_SIN 14 #define GRB_GENCONSTR_COS 15 #define GRB_GENCONSTR_TAN 16 +#define GRB_GENCONSTR_LOGISTIC 17 /* CALLBACKS @@ -633,6 +638,8 @@ int __stdcall #define GRB_CB_IIS_BOUNDMAX 9005 #define GRB_CB_IIS_BOUNDGUESS 9006 +/* FeasRelax method parameter values */ + #define GRB_FEASRELAX_LINEAR 0 #define GRB_FEASRELAX_QUADRATIC 1 #define GRB_FEASRELAX_CARDINALITY 2 @@ -694,6 +701,9 @@ int __stdcall GRBgetgenconstrExp(GRBmodel *model, int genconstr, int *xvarP, int *yvarP); int __stdcall GRBgetgenconstrLog(GRBmodel *model, int genconstr, int *xvarP, int *yvarP); +int __stdcall + GRBgetgenconstrLogistic(GRBmodel *model, int genconstr, int *xvarP, + int *yvarP); int __stdcall GRBgetgenconstrSin(GRBmodel *model, int genconstr, int *xvarP, int *yvarP); int __stdcall @@ -725,6 +735,8 @@ int __stdcall GRBmodel * __stdcall GRBcopymodel(GRBmodel *model); +int __stdcall + GRBcopymodeltoenv(GRBmodel *model, GRBenv *env, GRBmodel **resultP); int __stdcall GRBfixmodel(GRBmodel *model, GRBmodel **fixedP); int __stdcall @@ -765,18 +777,7 @@ int __stdcall #define THREADJOINCB_ARGS void *thread, void *syscbusrdata int __stdcall - GRBloadenvsyscb(GRBenv **envP, const char *logfilename, - void * (__stdcall *malloccb)(MALLOCCB_ARGS), - void * (__stdcall *calloccb)(CALLOCCB_ARGS), - void * (__stdcall *realloccb)(REALLOCCB_ARGS), - void (__stdcall *freecb)(FREECB_ARGS), - int (__stdcall *threadcreatecb)(THREADCREATECB_ARGS), - void (__stdcall *threadjoincb)(THREADJOINCB_ARGS), - void *syscbusrdata); - - -int __stdcall - GRBemptyenvadv(GRBenv **envP, int apitype, int major, int minor, int tech, + GRBemptyenvadv(GRBenv **envP, void * (__stdcall *malloccb)(MALLOCCB_ARGS), void * (__stdcall *calloccb)(CALLOCCB_ARGS), void * (__stdcall *realloccb)(REALLOCCB_ARGS), @@ -785,6 +786,16 @@ int __stdcall void (__stdcall *threadjoincb)(THREADJOINCB_ARGS), void *syscbusrdata); +int __stdcall + GRBemptyenvadvinternal(GRBenv **envP, int apitype, int major, int minor, int tech, + void * (__stdcall *malloccb)(MALLOCCB_ARGS), + void * (__stdcall *calloccb)(CALLOCCB_ARGS), + void * (__stdcall *realloccb)(REALLOCCB_ARGS), + void (__stdcall *freecb)(FREECB_ARGS), + int (__stdcall *threadcreatecb)(THREADCREATECB_ARGS), + void (__stdcall *threadjoincb)(THREADJOINCB_ARGS), + void *syscbusrdata); + int __stdcall GRBreadmodel(GRBenv *env, const char *filename, GRBmodel **modelP); int __stdcall @@ -920,6 +931,9 @@ int __stdcall int __stdcall GRBaddgenconstrTan(GRBmodel *model, const char *name, int xvar, int yvar, const char *options); +int __stdcall + GRBaddgenconstrLogistic(GRBmodel *model, const char *name, int xvar, + int yvar, const char *options); int __stdcall GRBaddqconstr(GRBmodel *model, int numlnz, int *lind, double *lval, int numqnz, int *qrow, int *qcol, double *qval, @@ -997,6 +1011,9 @@ int __stdcall int __stdcall GRBcbstoponemultiobj(GRBmodel *model, void *cbdata, int objnum); +int __stdcall + GRBsingularvectors(GRBmodel *model, double *left, double *right); + /* Model status codes */ #define GRB_LOADED 1 @@ -1015,6 +1032,7 @@ int __stdcall #define GRB_INPROGRESS 14 #define GRB_USER_OBJ_LIMIT 15 #define GRB_WORK_LIMIT 16 +#define GRB_MEM_LIMIT 17 /* Basis status info */ @@ -1042,6 +1060,7 @@ int __stdcall #define GRB_DBL_PAR_TIMELIMIT "TimeLimit" #define GRB_DBL_PAR_WORKLIMIT "WorkLimit" #define GRB_DBL_PAR_MEMLIMIT "MemLimit" +#define GRB_DBL_PAR_SOFTMEMLIMIT "SoftMemLimit" #define GRB_DBL_PAR_BESTOBJSTOP "BestObjStop" #define GRB_DBL_PAR_BESTBDSTOP "BestBdStop" @@ -1057,17 +1076,18 @@ int __stdcall /* Simplex */ -#define GRB_INT_PAR_METHOD "Method" -#define GRB_DBL_PAR_PERTURBVALUE "PerturbValue" -#define GRB_DBL_PAR_OBJSCALE "ObjScale" -#define GRB_INT_PAR_SCALEFLAG "ScaleFlag" -#define GRB_INT_PAR_SIMPLEXPRICING "SimplexPricing" -#define GRB_INT_PAR_QUAD "Quad" -#define GRB_INT_PAR_NORMADJUST "NormAdjust" -#define GRB_INT_PAR_SIFTING "Sifting" -#define GRB_INT_PAR_SIFTMETHOD "SiftMethod" -#define GRB_INT_PAR_LPWARMSTART "LPWarmStart" -#define GRB_INT_PAR_NETWORKALG "NetworkAlg" +#define GRB_INT_PAR_METHOD "Method" +#define GRB_INT_PAR_CONCURRENTMETHOD "ConcurrentMethod" +#define GRB_DBL_PAR_PERTURBVALUE "PerturbValue" +#define GRB_DBL_PAR_OBJSCALE "ObjScale" +#define GRB_INT_PAR_SCALEFLAG "ScaleFlag" +#define GRB_INT_PAR_SIMPLEXPRICING "SimplexPricing" +#define GRB_INT_PAR_QUAD "Quad" +#define GRB_INT_PAR_NORMADJUST "NormAdjust" +#define GRB_INT_PAR_SIFTING "Sifting" +#define GRB_INT_PAR_SIFTMETHOD "SiftMethod" +#define GRB_INT_PAR_LPWARMSTART "LPWarmStart" +#define GRB_INT_PAR_NETWORKALG "NetworkAlg" /* Barrier */ @@ -1097,6 +1117,7 @@ int __stdcall #define GRB_INT_PAR_NODEMETHOD "NodeMethod" #define GRB_DBL_PAR_NORELHEURTIME "NoRelHeurTime" #define GRB_DBL_PAR_NORELHEURWORK "NoRelHeurWork" +#define GRB_INT_PAR_OBBT "OBBT" #define GRB_INT_PAR_PUMPPASSES "PumpPasses" #define GRB_INT_PAR_RINS "RINS" #define GRB_STR_PAR_SOLFILES "SolFiles" @@ -1131,6 +1152,7 @@ int __stdcall #define GRB_INT_PAR_BQPCUTS "BQPCuts" #define GRB_INT_PAR_PSDCUTS "PSDCuts" #define GRB_INT_PAR_LIFTPROJECTCUTS "LiftProjectCuts" +#define GRB_INT_PAR_MIXINGCUTS "MixingCuts" #define GRB_INT_PAR_CUTAGGPASSES "CutAggPasses" #define GRB_INT_PAR_CUTPASSES "CutPasses" @@ -1168,6 +1190,7 @@ int __stdcall #define GRB_STR_PAR_WLSACCESSID "WLSAccessID" #define GRB_STR_PAR_WLSSECRET "WLSSecret" #define GRB_INT_PAR_WLSTOKENDURATION "WLSTokenDuration" +#define GRB_DBL_PAR_WLSTOKENREFRESH "WLSTokenRefresh" #define GRB_STR_PAR_WLSTOKEN "WLSToken" #define GRB_INT_PAR_LICENSEID "LicenseID" @@ -1208,6 +1231,7 @@ int __stdcall #define GRB_INT_PAR_RECORD "Record" #define GRB_STR_PAR_RESULTFILE "ResultFile" #define GRB_INT_PAR_SEED "Seed" +#define GRB_INT_PAR_SOLUTIONTARGET "SolutionTarget" #define GRB_INT_PAR_THREADS "Threads" #define GRB_DBL_PAR_TUNETIMELIMIT "TuneTimeLimit" #define GRB_INT_PAR_TUNERESULTS "TuneResults" @@ -1219,6 +1243,7 @@ int __stdcall #define GRB_DBL_PAR_TUNETARGETMIPGAP "TuneTargetMIPGap" #define GRB_DBL_PAR_TUNETARGETTIME "TuneTargetTime" #define GRB_INT_PAR_TUNEMETRIC "TuneMetric" +#define GRB_INT_PAR_TUNEDYNAMICJOBS "TuneDynamicJobs" #define GRB_INT_PAR_UPDATEMODE "UpdateMode" #define GRB_INT_PAR_OBJNUMBER "ObjNumber" #define GRB_INT_PAR_MULTIOBJMETHOD "MultiObjMethod" @@ -1236,27 +1261,30 @@ int __stdcall #define GRB_DBL_PAR_FUNCPIECEERROR "FuncPieceError" #define GRB_DBL_PAR_FUNCPIECERATIO "FuncPieceRatio" #define GRB_DBL_PAR_FUNCMAXVAL "FuncMaxVal" +#define GRB_INT_PAR_FUNCNONLINEAR "FuncNonlinear" #define GRB_STR_PAR_DUMMY "Dummy" - -/* Deprecated */ - #define GRB_STR_PAR_JOBID "JobID" /* Parameter enumerations */ -/* All *CUTS parameters */ +/* Cuts parameter values */ + #define GRB_CUTS_AUTO -1 #define GRB_CUTS_OFF 0 #define GRB_CUTS_CONSERVATIVE 1 #define GRB_CUTS_AGGRESSIVE 2 #define GRB_CUTS_VERYAGGRESSIVE 3 +/* Presolve parameter values */ + #define GRB_PRESOLVE_AUTO -1 #define GRB_PRESOLVE_OFF 0 #define GRB_PRESOLVE_CONSERVATIVE 1 #define GRB_PRESOLVE_AGGRESSIVE 2 +/* Method parameter values */ + #define GRB_METHOD_NONE -1 #define GRB_METHOD_AUTO -1 #define GRB_METHOD_PRIMAL 0 @@ -1264,20 +1292,34 @@ int __stdcall #define GRB_METHOD_BARRIER 2 #define GRB_METHOD_CONCURRENT 3 #define GRB_METHOD_DETERMINISTIC_CONCURRENT 4 -#define GRB_METHOD_DETERMINISTIC_CONCURRENT_SIMPLEX 5 +#define GRB_METHOD_DETERMINISTIC_CONCURRENT_SIMPLEX 5 /* Deprecated since v11 */ + +#define GRB_CONCURRENTMETHOD_AUTO -1 +#define GRB_CONCURRENTMETHOD_BARRIER_PRIMAL_DUAL 0 +#define GRB_CONCURRENTMETHOD_BARRIER_DUAL 1 +#define GRB_CONCURRENTMETHOD_BARRIER_PRIMAL 2 +#define GRB_CONCURRENTMETHOD_PRIMAL_DUAL 3 + +/* BarHomogeneous parameter values */ #define GRB_BARHOMOGENEOUS_AUTO -1 #define GRB_BARHOMOGENEOUS_OFF 0 #define GRB_BARHOMOGENEOUS_ON 1 +/* BarOrder parameter values */ + +#define GRB_BARORDER_AUTOMATIC -1 +#define GRB_BARORDER_AMD 0 +#define GRB_BARORDER_NESTEDDISSECTION 1 + +/* MIPFocus parameter values */ + #define GRB_MIPFOCUS_BALANCED 0 #define GRB_MIPFOCUS_FEASIBILITY 1 #define GRB_MIPFOCUS_OPTIMALITY 2 #define GRB_MIPFOCUS_BESTBOUND 3 -#define GRB_BARORDER_AUTOMATIC -1 -#define GRB_BARORDER_AMD 0 -#define GRB_BARORDER_NESTEDDISSECTION 1 +/* SimplexPricing parameter values */ #define GRB_SIMPLEXPRICING_AUTO -1 #define GRB_SIMPLEXPRICING_PARTIAL 0 @@ -1285,18 +1327,24 @@ int __stdcall #define GRB_SIMPLEXPRICING_DEVEX 2 #define GRB_SIMPLEXPRICING_STEEPEST_QUICK 3 +/* VarBranch parameter values */ + #define GRB_VARBRANCH_AUTO -1 #define GRB_VARBRANCH_PSEUDO_REDUCED 0 #define GRB_VARBRANCH_PSEUDO_SHADOW 1 #define GRB_VARBRANCH_MAX_INFEAS 2 #define GRB_VARBRANCH_STRONG 3 +/* PartitionPlace parameter values */ + #define GRB_PARTITION_EARLY 16 #define GRB_PARTITION_ROOTSTART 8 #define GRB_PARTITION_ROOTEND 4 #define GRB_PARTITION_NODES 2 #define GRB_PARTITION_CLEANUP 1 +/* Callback phase values */ + #define GRB_PHASE_MIP_NOREL 0 #define GRB_PHASE_MIP_SEARCH 1 #define GRB_PHASE_MIP_IMPROVE 2 @@ -1307,8 +1355,6 @@ void __stdcall GRBsetsignal(GRBmodel *model); void __stdcall GRBterminate(GRBmodel *model); -void __stdcall - GRBcbproceed(GRBmodel *model); int __stdcall GRBreplay(const char *filename); int __stdcall @@ -1330,17 +1376,8 @@ void __stdcall GRBmsg(GRBenv *env, const char *message); -/* The following four routines are deprecated in Gurobi 2.0. - Use the 'LogFile' parameter to control logging instead. */ - -int __stdcall - GRBgetlogfile(GRBenv *env, FILE **logfileP); - - /* Parameter routines */ -int __stdcall - GRBfixtuneparam(GRBenv *env, const char *paramname); int __stdcall GRBgetintparam(GRBenv *env, const char *paramname, int *valueP); int __stdcall @@ -1379,10 +1416,12 @@ int __stdcall GRBwriteparams(GRBenv *env, const char *filename); int __stdcall GRBreadparams(GRBenv *env, const char *filename); +int __stdcall + GRBreadtunebasesettings(GRBenv *env, const char *filename); int __stdcall GRBgetnumparams(GRBenv *env); int __stdcall - GRBgetparamname(GRBenv *env, int i, char **paramnameP); + GRBgetparamname(GRBenv *env, int parnum, char **paramnameP); int __stdcall GRBgetnumattributes(GRBmodel *model); int __stdcall @@ -1402,33 +1441,9 @@ int __stdcall const char *server, const char *router, const char *password, const char *group, int priority, int idletimeout, - const char *accessid, const char *secretkey, + const char *cloudaccessid, const char *cloudsecretkey, int (__stdcall *cb)(CB_ARGS), void *usrdata, int (__stdcall *logcb)(LOGCB_ARGS), void *logdata); -GRB_DEPRECATED("Replaced by GRBemptyenv() and parameter settings", -int __stdcall - GRBloadclientenv(GRBenv **envP, const char *logfilename, - const char *computeserver, const char *router, - const char *password, const char *group, int CStlsinsecure, - int priority, double timeout)); -int __stdcall - GRBloadclientenvadv(GRBenv **envP, const char *logfilename, - const char *computeserver, const char *router, - const char *password, const char *group, int CStlsinsecure, - int priority, double timeout, int apitype, - int major, int minor, int tech, - int (__stdcall *cb)(CB_ARGS), void *usrdata); -GRB_DEPRECATED("Replaced by GRBemptyenv() and parameter settings", -int __stdcall - GRBloadcloudenv(GRBenv **envP, const char *logfilename, - const char *accessID, const char *secretKey, - const char *pool, int priority)); -int __stdcall - GRBloadcloudenvadv(GRBenv **envP, const char *logfilename, - const char *accessID, const char *secretKey, - const char *pool, int priority, int apitype, int major, - int minor, int tech, - int (__stdcall *cb)(CB_ARGS), void *usrdata); GRBenv *__stdcall GRBgetenv(GRBmodel *model); GRBenv *__stdcall @@ -1461,6 +1476,9 @@ void __stdcall void __stdcall GRBversion(int *majorP, int *minorP, int *technicalP); +void __stdcall + GRBgetdistro(char *str); + char * __stdcall GRBplatform(void); @@ -1470,18 +1488,8 @@ char * __stdcall int __stdcall GRBlisttokens(void); -/* Tuning */ - -void __stdcall - GRBprinttuneparams(void); -int __stdcall - GRBtunemodel(GRBmodel *model); int __stdcall - GRBtunemodels(GRBenv *env, int nummodels, GRBmodel **models); -int __stdcall - GRBgettuneresult(GRBmodel *model, int i); -int __stdcall - GRBgettunelog(GRBmodel *model, int i, char **logP); + GRBgetwlstokenlifespan(GRBenv *env, int *lifespanP); /* Used in Matlab API */ void __stdcall @@ -1544,6 +1552,18 @@ int __stdcall int __stdcall GRBprefetchattr(GRBmodel *model, const char *attrname); +/* Tuning */ + +int __stdcall + GRBtunemodel(GRBmodel *model); +int __stdcall + GRBtunemodels(GRBenv *env, int nummodels, GRBmodel **models); +int __stdcall + GRBgettuneresult(GRBmodel *model, int i); +int __stdcall + GRBgettunelog(GRBmodel *model, int i, char **logP); +void __stdcall + GRBtuneparamsPrint(void); #ifdef __cplusplus } diff --git a/ilpy/impl/solvers/GurobiBackend.cpp b/ilpy/impl/solvers/GurobiBackend.cpp index ce6986e..7917fb9 100644 --- a/ilpy/impl/solvers/GurobiBackend.cpp +++ b/ilpy/impl/solvers/GurobiBackend.cpp @@ -142,7 +142,7 @@ GurobiBackend::setConstraints(const Constraints &constraints) if (numConstrs > 0) { int *constraintIndicies = new int[numConstrs]; - for (unsigned int i = 0; i < numConstrs; i++) + for (int i = 0; i < numConstrs; i++) constraintIndicies[i] = i; GRB_CHECK(GRBdelconstrs(_model, numConstrs, constraintIndicies)); diff --git a/ilpy/impl/solvers/ScipBackend.cpp b/ilpy/impl/solvers/ScipBackend.cpp index 03045e5..8d1f7ad 100644 --- a/ilpy/impl/solvers/ScipBackend.cpp +++ b/ilpy/impl/solvers/ScipBackend.cpp @@ -52,7 +52,7 @@ ScipBackend::initialize( // delete previous variables freeVariables(); - for (int i = 0; i < _numVariables; i++) { + for (unsigned int i = 0; i < _numVariables; i++) { SCIP_VAR* v; std::string name("x"); diff --git a/pyproject.toml b/pyproject.toml index c4d010d..288a19d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,26 +14,29 @@ authors = [ { email = "talley.lambert@gmail.com", name = "Talley Lambert" }, ] dynamic = ["version", "readme"] -dependencies = [] +# these are required... but hard to install from pypi +# we list them here for completeness, but it's up to the user to install them :( +dependencies = [ + # "gurobi==11.0.3", + # "scip==9.1.0", +] # extras # https://peps.python.org/pep-0621/#dependencies-optional-dependencies [project.optional-dependencies] dev = [ - "ruff", + "cython", + "gurobipy==11.0.3; sys_platform!='windows' and python_version<'3.12'", # used to confirm equality of results + "ipython", "mypy", - "pytest", + "numpy", + "pre-commit", "pytest-cov", - "cython", + "pytest", + "ruff", "setuptools==71.1.0", - "numpy", - "gurobipy", # used on CI to confirm equality of results -] -docs = [ - "sphinx", - "sphinx_rtd_theme", - "sphinx-autodoc-typehints", ] +docs = ["sphinx", "sphinx_rtd_theme", "sphinx-autodoc-typehints"] [project.urls] homepage = "https://github.com/funkelab/ilpy" diff --git a/setup.py b/setup.py index 30f414d..cdda3cc 100644 --- a/setup.py +++ b/setup.py @@ -5,17 +5,24 @@ from setuptools import setup from setuptools.extension import Extension +CONDA_PREFIX = os.environ.get("CONDA_PREFIX") +if CONDA_PREFIX: + # gurobi seems to be putting its libraries in the top of the conda env + os.environ["PATH"] += os.pathsep + CONDA_PREFIX +else: + print("CONDA_PREFIX not set!, did you active a conda environment?") + + # enable test coverage tracing if CYTHON_TRACE is set to a non-zero value CYTHON_TRACE = int(os.getenv("CYTHON_TRACE") in ("1", "True")) libraries = ["libscip"] if os.name == "nt" else ["scip"] include_dirs = ["ilpy/impl"] -library_dirs = [] -compile_args = ["-O3", "-DHAVE_SCIP"] +library_dirs = [CONDA_PREFIX] if CONDA_PREFIX else [] if os.name == "nt": - compile_args.append("/std:c++17") + compile_args = ["/O2", "/DHAVE_SCIP", "/std:c++17", "/wd4702"] else: - compile_args.append("-std=c++17") + compile_args = ["-O3", "-DHAVE_SCIP", "-std=c++17", "-Wno-unreachable-code"] # include conda environment windows include/lib if it exists # this will be done automatically by conda build, but is useful if someone @@ -27,12 +34,12 @@ # look for various gurobi versions, which are annoyingly # suffixed with the version number, and wildcards don't work -for v in range(80, 200): - GUROBI_LIB = f"libgurobi{v}" if os.name == "nt" else f"gurobi{v}" - if (gurolib := util.find_library(GUROBI_LIB)) is not None: - print("FOUND GUROBI library: ", gurolib) - libraries.append(GUROBI_LIB) - compile_args.append("-DHAVE_GUROBI") +for prefix in ("lib", ""): + gurobi_lib = f"{prefix}gurobi110" # only using gurobi 11 at the moment + if found := util.find_library(gurobi_lib): + print("FOUND GUROBI library: ", found) + libraries.append(gurobi_lib) + compile_args.append("/DHAVE_GUROBI" if os.name == "nt" else "-DHAVE_GUROBI") break else: print("WARNING: GUROBI library not found")