Skip to content

Commit ac31344

Browse files
authored
Merge branch 'master' into expr/unarys
2 parents bc3cfb3 + 89f092f commit ac31344

23 files changed

Lines changed: 225 additions & 86 deletions

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66
- `Expr` and `GenExpr` support NumPy binary functions (`np.add`, `np.subtract`, `np.multiply`, `np.divide`, `np.true_divide`, `np.power`, `np.less_equal`, `np.greater_equal`, `np.equal`)
77
- Added `getBase()` and `setBase()` methods to `LP` class for getting/setting basis status
88
- Added `getMemUsed()`, `getMemTotal()`, and `getMemExternEstim()` methods
9+
- Added `isReoptEnabled()` and raising error if not enabled upon calling `reoptSolve()`
910
### Fixed
1011
- Removed `Py_INCREF`/`Py_DECREF` on `Model` in `catchEvent`/`dropEvent` that caused memory leak for imbalanced usage
1112
- Used `getIndex()` instead of `ptr()` for sorting nonlinear expression terms to avoid nondeterministic behavior
1213
- Fixed stubtest failures with mypy 1.20 by marking dunder method parameters as positional-only
1314
- Return `MatrixGenExpr` in `buildGenExprObj` instead of `MatrixExpr`
15+
- Plugins now hold strong references to their `Model` instead of `weakref.proxy`, fixing `ReferenceError` during cleanup callbacks (#1193)
1416
### Changed
1517
- Speed up `constant * Expr` via C-level API
1618
- Speed up `Term.__eq__` via the C-level API

src/pyscipopt/benders.pxi

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ cdef SCIP_RETCODE PyBendersFree (SCIP* scip, SCIP_BENDERS* benders) noexcept wit
7676
bendersdata = SCIPbendersGetData(benders)
7777
PyBenders = <Benders>bendersdata
7878
PyBenders.bendersfree()
79-
Py_DECREF(PyBenders)
8079
return SCIP_OKAY
8180

8281
cdef SCIP_RETCODE PyBendersInit (SCIP* scip, SCIP_BENDERS* benders) noexcept with gil:

src/pyscipopt/benderscut.pxi

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ cdef SCIP_RETCODE PyBenderscutFree (SCIP* scip, SCIP_BENDERSCUT* benderscut) noe
3131
benderscutdata = SCIPbenderscutGetData(benderscut)
3232
PyBenderscut = <Benderscut>benderscutdata
3333
PyBenderscut.benderscutfree()
34-
Py_DECREF(PyBenderscut)
3534
return SCIP_OKAY
3635

3736
cdef SCIP_RETCODE PyBenderscutInit (SCIP* scip, SCIP_BENDERSCUT* benderscut) noexcept with gil:

src/pyscipopt/branchrule.pxi

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ cdef SCIP_RETCODE PyBranchruleFree (SCIP* scip, SCIP_BRANCHRULE* branchrule) noe
4747
branchruledata = SCIPbranchruleGetData(branchrule)
4848
PyBranchrule = <Branchrule>branchruledata
4949
PyBranchrule.branchfree()
50-
Py_DECREF(PyBranchrule)
5150
return SCIP_OKAY
5251

5352
cdef SCIP_RETCODE PyBranchruleInit (SCIP* scip, SCIP_BRANCHRULE* branchrule) noexcept with gil:

src/pyscipopt/conshdlr.pxi

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,6 @@ cdef SCIP_RETCODE PyConshdlrCopy (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_Bool
159159
cdef SCIP_RETCODE PyConsFree (SCIP* scip, SCIP_CONSHDLR* conshdlr) noexcept with gil:
160160
PyConshdlr = getPyConshdlr(conshdlr)
161161
PyConshdlr.consfree()
162-
Py_DECREF(PyConshdlr)
163162
return SCIP_OKAY
164163

165164
cdef SCIP_RETCODE PyConsInit (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil:

src/pyscipopt/cutsel.pxi

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ cdef SCIP_RETCODE PyCutselFree (SCIP* scip, SCIP_CUTSEL* cutsel) noexcept with g
3737
cutseldata = SCIPcutselGetData(cutsel)
3838
PyCutsel = <Cutsel>cutseldata
3939
PyCutsel.cutselfree()
40-
Py_DECREF(PyCutsel)
4140
return SCIP_OKAY
4241

4342
cdef SCIP_RETCODE PyCutselInit (SCIP* scip, SCIP_CUTSEL* cutsel) noexcept with gil:

src/pyscipopt/event.pxi

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
cdef class Eventhdlr:
44
cdef public Model model
55
cdef public str name
6+
# eventtypes caught via `Model.catchEvent`, auto-dropped on `eventexit`.
7+
cdef list _caught_events
8+
9+
def __cinit__(self):
10+
self._caught_events = []
611

712
def eventcopy(self):
813
'''sets copy callback for all events of this event handler '''
@@ -51,7 +56,6 @@ cdef SCIP_RETCODE PyEventCopy (SCIP* scip, SCIP_EVENTHDLR* eventhdlr) noexcept w
5156
cdef SCIP_RETCODE PyEventFree (SCIP* scip, SCIP_EVENTHDLR* eventhdlr) noexcept with gil:
5257
PyEventhdlr = getPyEventhdlr(eventhdlr)
5358
PyEventhdlr.eventfree()
54-
Py_DECREF(PyEventhdlr)
5559
return SCIP_OKAY
5660

5761
cdef SCIP_RETCODE PyEventInit (SCIP* scip, SCIP_EVENTHDLR* eventhdlr) noexcept with gil:
@@ -62,6 +66,10 @@ cdef SCIP_RETCODE PyEventInit (SCIP* scip, SCIP_EVENTHDLR* eventhdlr) noexcept w
6266
cdef SCIP_RETCODE PyEventExit (SCIP* scip, SCIP_EVENTHDLR* eventhdlr) noexcept with gil:
6367
PyEventhdlr = getPyEventhdlr(eventhdlr)
6468
PyEventhdlr.eventexit()
69+
# Auto-drop any events not explicitly dropped by the user
70+
for eventtype in PyEventhdlr._caught_events:
71+
SCIPdropEvent(scip, eventtype, eventhdlr, NULL, -1)
72+
PyEventhdlr._caught_events = []
6573
return SCIP_OKAY
6674

6775
cdef SCIP_RETCODE PyEventInitsol (SCIP* scip, SCIP_EVENTHDLR* eventhdlr) noexcept with gil:

src/pyscipopt/heuristic.pxi

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ cdef SCIP_RETCODE PyHeurFree (SCIP* scip, SCIP_HEUR* heur) noexcept with gil:
3838
heurdata = SCIPheurGetData(heur)
3939
PyHeur = <Heur>heurdata
4040
PyHeur.heurfree()
41-
Py_DECREF(PyHeur)
4241
return SCIP_OKAY
4342

4443
cdef SCIP_RETCODE PyHeurInit (SCIP* scip, SCIP_HEUR* heur) noexcept with gil:

src/pyscipopt/iisfinder.pxi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
##@file iisfinder.pxi
22
#@brief Base class of the IIS finder Plugin
33
cdef class IISfinder:
4+
cdef public Model model
45
cdef public IIS iis
5-
cdef SCIP_IIS* scip_iis
6+
cdef SCIP_IIS* scip_iis
67
cdef SCIP_IISFINDER* scip_iisfinder
78

89
def iisfinderfree(self):
@@ -22,7 +23,6 @@ cdef SCIP_RETCODE PyiisfinderFree (SCIP* scip, SCIP_IISFINDER* iisfinder) noexce
2223
iisfinderdata = SCIPiisfinderGetData(iisfinder)
2324
PyIIS = <IISfinder>iisfinderdata
2425
PyIIS.iisfinderfree()
25-
Py_DECREF(PyIIS)
2626
return SCIP_OKAY
2727

2828
cdef SCIP_RETCODE PyiisfinderExec (SCIP_IIS* iis, SCIP_IISFINDER* iisfinder, SCIP_RESULT* result) noexcept with gil:

src/pyscipopt/nodesel.pxi

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ cdef SCIP_RETCODE PyNodeselFree (SCIP* scip, SCIP_NODESEL* nodesel) noexcept wit
5050
nodeseldata = SCIPnodeselGetData(nodesel)
5151
PyNodesel = <Nodesel>nodeseldata
5252
PyNodesel.nodefree()
53-
Py_DECREF(PyNodesel)
5453
return SCIP_OKAY
5554

5655
cdef SCIP_RETCODE PyNodeselInit (SCIP* scip, SCIP_NODESEL* nodesel) noexcept with gil:

0 commit comments

Comments
 (0)