From a5ca80be21b9278766f3befbd5ff076c02860f42 Mon Sep 17 00:00:00 2001 From: Joao-Dionisio Date: Sat, 14 Feb 2026 21:23:29 +0000 Subject: [PATCH] Add getMemUsed, getMemTotal, and getMemExternEstim methods --- src/pyscipopt/scip.pxd | 5 +++++ src/pyscipopt/scip.pxi | 35 +++++++++++++++++++++++++++++++++++ src/pyscipopt/scip.pyi | 3 +++ tests/test_model.py | 20 ++++++++++++++++++++ 4 files changed, 63 insertions(+) diff --git a/src/pyscipopt/scip.pxd b/src/pyscipopt/scip.pxd index 2e78296e3..cb756dc1f 100644 --- a/src/pyscipopt/scip.pxd +++ b/src/pyscipopt/scip.pxd @@ -1822,6 +1822,11 @@ cdef extern from "blockmemshell/memory.h": void BMScheckEmptyMemory() long long BMSgetMemoryUsed() +cdef extern from "scip/scip_mem.h": + SCIP_Longint SCIPgetMemUsed(SCIP* scip) + SCIP_Longint SCIPgetMemTotal(SCIP* scip) + SCIP_Longint SCIPgetMemExternEstim(SCIP* scip) + cdef extern from "scip/scip_expr.h": SCIP_RETCODE SCIPcreateExpr(SCIP* scip, SCIP_EXPR** expr, diff --git a/src/pyscipopt/scip.pxi b/src/pyscipopt/scip.pxi index 9c21942bd..db862467c 100644 --- a/src/pyscipopt/scip.pxi +++ b/src/pyscipopt/scip.pxi @@ -11467,6 +11467,41 @@ cdef class Model: locale.setlocale(locale.LC_NUMERIC,user_locale) + def getMemUsed(self): + """ + Gets the total number of bytes used in block and buffer memory. + + Returns + ------- + int + + """ + return SCIPgetMemUsed(self._scip) + + def getMemTotal(self): + """ + Gets the total number of bytes in block and buffer memory + (i.e., total allocated, including unused). + + Returns + ------- + int + + """ + return SCIPgetMemTotal(self._scip) + + def getMemExternEstim(self): + """ + Gets the estimated number of bytes used by external software, + e.g., the LP solver. + + Returns + ------- + int + + """ + return SCIPgetMemExternEstim(self._scip) + def getNLPs(self): """ Gets total number of LPs solved so far. diff --git a/src/pyscipopt/scip.pyi b/src/pyscipopt/scip.pyi index e8bbc46d5..2728cf513 100644 --- a/src/pyscipopt/scip.pyi +++ b/src/pyscipopt/scip.pyi @@ -1153,6 +1153,9 @@ class Model: def getNLPIterations(self) -> Incomplete: ... def getNLPRows(self) -> Incomplete: ... def getNLPs(self) -> Incomplete: ... + def getMemUsed(self) -> int: ... + def getMemTotal(self) -> int: ... + def getMemExternEstim(self) -> int: ... def getNLeaves(self) -> Incomplete: ... def getNLimSolsFound(self) -> Incomplete: ... def getNNlRows(self) -> Incomplete: ... diff --git a/tests/test_model.py b/tests/test_model.py index 683006b4a..6736fbb5f 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -642,3 +642,23 @@ def test_getSolVal(): m.getVal("not_a_var") with pytest.raises(TypeError): m.getSolVal(sol, "not_a_var") + + +def test_memory_methods(): + m = Model() + + # Memory values should be non-negative even on an empty model + assert m.getMemUsed() >= 0 + assert m.getMemTotal() >= 0 + assert m.getMemExternEstim() >= 0 + + # Total allocated should be at least as much as actively used + assert m.getMemTotal() >= m.getMemUsed() + + # After adding variables and solving, memory usage should increase + x = m.addVar("x", vtype="C", obj=1.0) + m.addCons(x >= 0) + m.optimize() + + assert m.getMemUsed() > 0 + assert m.getMemTotal() > 0