From 6bea3e0941761e79282126acec7916258cbc21d6 Mon Sep 17 00:00:00 2001 From: Joao-Dionisio Date: Fri, 27 Jun 2025 16:22:18 +0100 Subject: [PATCH 1/6] Add enableDebugSol --- CHANGELOG.md | 1 + src/pyscipopt/scip.pxd | 1 + src/pyscipopt/scip.pxi | 8 ++++++++ 3 files changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f917ec92..cf0195dbc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased ### Added +- Added enableDebugSol - More support for AND-Constraints - Added support for knapsack constraints - Added isPositive(), isNegative(), isFeasLE(), isFeasLT(), isFeasGE(), isFeasGT(), isHugeValue(), and tests diff --git a/src/pyscipopt/scip.pxd b/src/pyscipopt/scip.pxd index b198b221d..5f2b43004 100644 --- a/src/pyscipopt/scip.pxd +++ b/src/pyscipopt/scip.pxd @@ -924,6 +924,7 @@ cdef extern from "scip/scip.h": SCIP_Real SCIPgetSolTime(SCIP* scip, SCIP_SOL* sol) SCIP_RETCODE SCIPsetRelaxSolVal(SCIP* scip, SCIP_RELAX* relax, SCIP_VAR* var, SCIP_Real val) + void SCIPenableDebugSol(SCIP* scip) # Row Methods SCIP_RETCODE SCIPcreateRow(SCIP* scip, SCIP_ROW** row, const char* name, int len, SCIP_COL** cols, SCIP_Real* vals, diff --git a/src/pyscipopt/scip.pxi b/src/pyscipopt/scip.pxi index 7c7216c83..64709de67 100644 --- a/src/pyscipopt/scip.pxi +++ b/src/pyscipopt/scip.pxi @@ -7495,6 +7495,14 @@ cdef class Model: """ PY_SCIP_CALL(SCIPsetRelaxSolVal(self._scip, NULL, var.scip_var, val)) + def enableDebugSol(self): + """ + Enables the debug solution mechanism, which allows tracing back the invalidation of + a debug solution during the solution process of SCIP. It must be explicitly + enabled for the SCIP data structure. + """ + SCIPenableDebugSol(self._scip) + def getConss(self, transformed=True): """ Retrieve all constraints. From 7410cd34a38a92f9e2481bb50b9c35166dccd9bc Mon Sep 17 00:00:00 2001 From: Joao-Dionisio Date: Fri, 4 Jul 2025 16:37:44 +0100 Subject: [PATCH 2/6] Add disableDebugSol and check --- CHANGELOG.md | 2 +- src/pyscipopt/scip.pxd | 1 + src/pyscipopt/scip.pxi | 23 ++++++++++++++++++++--- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf0195dbc..f95097e2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unreleased ### Added -- Added enableDebugSol +- Added enableDebugSol, disableDebugSol, and check for WITH_DEBUG_SOLUTION flag - More support for AND-Constraints - Added support for knapsack constraints - Added isPositive(), isNegative(), isFeasLE(), isFeasLT(), isFeasGE(), isFeasGT(), isHugeValue(), and tests diff --git a/src/pyscipopt/scip.pxd b/src/pyscipopt/scip.pxd index 5f2b43004..1618636b6 100644 --- a/src/pyscipopt/scip.pxd +++ b/src/pyscipopt/scip.pxd @@ -925,6 +925,7 @@ cdef extern from "scip/scip.h": SCIP_RETCODE SCIPsetRelaxSolVal(SCIP* scip, SCIP_RELAX* relax, SCIP_VAR* var, SCIP_Real val) void SCIPenableDebugSol(SCIP* scip) + void SCIPdisableDebugSol(SCIP* scip) # Row Methods SCIP_RETCODE SCIPcreateRow(SCIP* scip, SCIP_ROW** row, const char* name, int len, SCIP_COL** cols, SCIP_Real* vals, diff --git a/src/pyscipopt/scip.pxi b/src/pyscipopt/scip.pxi index 64709de67..469fe76b3 100644 --- a/src/pyscipopt/scip.pxi +++ b/src/pyscipopt/scip.pxi @@ -56,6 +56,16 @@ else: _SCIP_BOUNDTYPE_TO_STRING = {SCIP_BOUNDTYPE_UPPER: '<=', SCIP_BOUNDTYPE_LOWER: '>='} +cdef extern from "scip/config.h": + """ + #ifndef WITH_DEBUG_SOLUTION + #define WITH_DEBUG_SOLUTION 0 + #endif + """ + bint WITH_DEBUG_SOLUTION + +cdef bint with_debug_solution = WITH_DEBUG_SOLUTION + # Mapping the SCIP_RESULT enum to a python class # This is required to return SCIP_RESULT in the python code # In __init__.py this is imported as SCIP_RESULT to keep the @@ -141,7 +151,6 @@ cdef class PY_SCIP_STATUS: INFORUNBD = SCIP_STATUS_INFORUNBD StageNames = {} - cdef class PY_SCIP_STAGE: INIT = SCIP_STAGE_INIT PROBLEM = SCIP_STAGE_PROBLEM @@ -171,7 +180,6 @@ cdef class PY_SCIP_NODETYPE: SUBROOT = SCIP_NODETYPE_SUBROOT REFOCUSNODE = SCIP_NODETYPE_REFOCUSNODE - cdef class PY_SCIP_PROPTIMING: BEFORELP = SCIP_PROPTIMING_BEFORELP DURINGLPLOOP = SCIP_PROPTIMING_DURINGLPLOOP @@ -198,7 +206,6 @@ cdef class PY_SCIP_HEURTIMING: AFTERPROPLOOP = SCIP_HEURTIMING_AFTERPROPLOOP EventNames = {} - cdef class PY_SCIP_EVENTTYPE: DISABLED = SCIP_EVENTTYPE_DISABLED VARADDED = SCIP_EVENTTYPE_VARADDED @@ -7501,7 +7508,17 @@ cdef class Model: a debug solution during the solution process of SCIP. It must be explicitly enabled for the SCIP data structure. """ + if not with_debug_solution: + raise RuntimeError("SCIP was not built with the WITH_DEBUG_SOLUTION flag. Please rebuild SCIP with this flag enabled.") SCIPenableDebugSol(self._scip) + + def disableDebugSol(self): + """ + Disables the debug solution mechanism. + """ + if not with_debug_solution: + raise RuntimeError("SCIP was not built with the WITH_DEBUG_SOLUTION flag. Please rebuild SCIP with this flag enabled.") + SCIPdisableDebugSol(self._scip) def getConss(self, transformed=True): """ From 8a1278b0f3989d3546c2abd56475abf2b0f12e9d Mon Sep 17 00:00:00 2001 From: Joao-Dionisio Date: Fri, 4 Jul 2025 17:00:20 +0100 Subject: [PATCH 3/6] update docs --- docs/build.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/build.rst b/docs/build.rst index ad8f74356..16e45a3c4 100644 --- a/docs/build.rst +++ b/docs/build.rst @@ -159,8 +159,9 @@ Build with Debug To use debug information in PySCIPOpt you need to build it with the following command: .. code-block:: - - python -m pip install --install-option="--debug" . + + export CFLAGS="-UNDEBUG" + python -m pip install . .. note:: Be aware that you will need the debug library of the SCIP Optimization Suite for this to work (cmake .. -DCMAKE_BUILD_TYPE=Debug). From 5af4224fd1db4ad6f3f6f58e8922385581d2bad7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Dion=C3=ADsio?= <57299939+Joao-Dionisio@users.noreply.github.com> Date: Sat, 5 Jul 2025 00:50:39 +0100 Subject: [PATCH 4/6] Apply suggestions from code review Co-authored-by: DominikKamp <130753997+DominikKamp@users.noreply.github.com> --- CHANGELOG.md | 2 +- docs/build.rst | 1 + src/pyscipopt/scip.pxi | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f95097e2f..6e7ca3e4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unreleased ### Added -- Added enableDebugSol, disableDebugSol, and check for WITH_DEBUG_SOLUTION flag +- Added enableDebugSol() and disableDebugSol() for controlling the debug solution mechanism if DEBUGSOL=true - More support for AND-Constraints - Added support for knapsack constraints - Added isPositive(), isNegative(), isFeasLE(), isFeasLT(), isFeasGE(), isFeasGT(), isHugeValue(), and tests diff --git a/docs/build.rst b/docs/build.rst index 16e45a3c4..43f343b26 100644 --- a/docs/build.rst +++ b/docs/build.rst @@ -161,6 +161,7 @@ To use debug information in PySCIPOpt you need to build it with the following co .. code-block:: export CFLAGS="-UNDEBUG" + export CXXFLAGS="-UNDEBUG" python -m pip install . .. note:: Be aware that you will need the debug library of the SCIP Optimization Suite for this to work diff --git a/src/pyscipopt/scip.pxi b/src/pyscipopt/scip.pxi index 469fe76b3..707a72a3c 100644 --- a/src/pyscipopt/scip.pxi +++ b/src/pyscipopt/scip.pxi @@ -7509,7 +7509,7 @@ cdef class Model: enabled for the SCIP data structure. """ if not with_debug_solution: - raise RuntimeError("SCIP was not built with the WITH_DEBUG_SOLUTION flag. Please rebuild SCIP with this flag enabled.") + raise RuntimeError("SCIP must be built with `DEBUGSOL=true` to enable the debug solution mechanism.") SCIPenableDebugSol(self._scip) def disableDebugSol(self): @@ -7517,7 +7517,7 @@ cdef class Model: Disables the debug solution mechanism. """ if not with_debug_solution: - raise RuntimeError("SCIP was not built with the WITH_DEBUG_SOLUTION flag. Please rebuild SCIP with this flag enabled.") + raise RuntimeError("SCIP must be built with `DEBUGSOL=true` to disable the debug solution mechanism.") SCIPdisableDebugSol(self._scip) def getConss(self, transformed=True): From 2e040ff46b8a423812b924b4770934c2509ed4e6 Mon Sep 17 00:00:00 2001 From: Joao-Dionisio Date: Sat, 5 Jul 2025 00:52:28 +0100 Subject: [PATCH 5/6] remove redundant variable --- src/pyscipopt/scip.pxi | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/pyscipopt/scip.pxi b/src/pyscipopt/scip.pxi index 707a72a3c..a3e2aa6ea 100644 --- a/src/pyscipopt/scip.pxi +++ b/src/pyscipopt/scip.pxi @@ -64,8 +64,6 @@ cdef extern from "scip/config.h": """ bint WITH_DEBUG_SOLUTION -cdef bint with_debug_solution = WITH_DEBUG_SOLUTION - # Mapping the SCIP_RESULT enum to a python class # This is required to return SCIP_RESULT in the python code # In __init__.py this is imported as SCIP_RESULT to keep the @@ -7508,7 +7506,7 @@ cdef class Model: a debug solution during the solution process of SCIP. It must be explicitly enabled for the SCIP data structure. """ - if not with_debug_solution: + if not WITH_DEBUG_SOLUTION: raise RuntimeError("SCIP must be built with `DEBUGSOL=true` to enable the debug solution mechanism.") SCIPenableDebugSol(self._scip) @@ -7516,7 +7514,7 @@ cdef class Model: """ Disables the debug solution mechanism. """ - if not with_debug_solution: + if not WITH_DEBUG_SOLUTION: raise RuntimeError("SCIP must be built with `DEBUGSOL=true` to disable the debug solution mechanism.") SCIPdisableDebugSol(self._scip) From c3d59f6034060dabf4710473306000aa4fec5dcc Mon Sep 17 00:00:00 2001 From: Gennesaret Kharistio Tjusila <33521666+gtjusila@users.noreply.github.com> Date: Mon, 28 Jul 2025 15:53:32 +0200 Subject: [PATCH 6/6] Fixed error during compilation, changed flag to PYSCIPOPT_WITH_DEBUG_SOLUTION to avoid side effect (#1040) --- src/pyscipopt/scip.pxi | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/pyscipopt/scip.pxi b/src/pyscipopt/scip.pxi index a3e2aa6ea..e1663d736 100644 --- a/src/pyscipopt/scip.pxi +++ b/src/pyscipopt/scip.pxi @@ -58,11 +58,13 @@ _SCIP_BOUNDTYPE_TO_STRING = {SCIP_BOUNDTYPE_UPPER: '<=', cdef extern from "scip/config.h": """ - #ifndef WITH_DEBUG_SOLUTION - #define WITH_DEBUG_SOLUTION 0 + #ifdef WITH_DEBUG_SOLUTION + #define PYSCIPOPT_WITH_DEBUG_SOLUTION 1 + #else + #define PYSCIPOPT_WITH_DEBUG_SOLUTION 0 #endif """ - bint WITH_DEBUG_SOLUTION + bint PYSCIPOPT_WITH_DEBUG_SOLUTION # Mapping the SCIP_RESULT enum to a python class # This is required to return SCIP_RESULT in the python code @@ -7506,7 +7508,7 @@ cdef class Model: a debug solution during the solution process of SCIP. It must be explicitly enabled for the SCIP data structure. """ - if not WITH_DEBUG_SOLUTION: + if not PYSCIPOPT_WITH_DEBUG_SOLUTION: raise RuntimeError("SCIP must be built with `DEBUGSOL=true` to enable the debug solution mechanism.") SCIPenableDebugSol(self._scip) @@ -7514,7 +7516,7 @@ cdef class Model: """ Disables the debug solution mechanism. """ - if not WITH_DEBUG_SOLUTION: + if not PYSCIPOPT_WITH_DEBUG_SOLUTION: raise RuntimeError("SCIP must be built with `DEBUGSOL=true` to disable the debug solution mechanism.") SCIPdisableDebugSol(self._scip)