Skip to content

Commit e42de8a

Browse files
finozzifapre-commit-ci[bot]FabianHofmann
committed
Re-introduce knitro context closure and export solver quantities (#633)
* code: re-introduce knitro context closure and export solver quantities * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * code: place quantities calculation elsewhere * code: place quantities calculation elsewhere * code: add new quantities extracted from knitro context * code: add int * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * code: add release notes --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Fabian Hofmann <fab.hof@gmx.de>
1 parent 4abf542 commit e42de8a

2 files changed

Lines changed: 58 additions & 5 deletions

File tree

doc/release_notes.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
Release Notes
22
=============
33

4+
Version 0.6.6
5+
-------------
6+
7+
* Free the knitro context and compute necessary quantities within linopy. Knitro context is not exposed anymore.
8+
9+
410
Version 0.6.5
511
-------------
612

linopy/solvers.py

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1745,7 +1745,10 @@ def get_solver_solution() -> Solution:
17451745
return Result(status, solution, m)
17461746

17471747

1748-
KnitroResult = namedtuple("KnitroResult", "knitro_context reported_runtime")
1748+
KnitroResult = namedtuple(
1749+
"KnitroResult",
1750+
"reported_runtime mip_relaxation_bnd mip_number_nodes mip_number_solves mip_rel_gap mip_abs_gap abs_feas_error rel_feas_error abs_opt_error rel_opt_error n_vars n_cons n_integer_vars n_continuous_vars",
1751+
)
17491752

17501753

17511754
class Knitro(Solver[None]):
@@ -1893,8 +1896,38 @@ def solve_problem_from_file(
18931896
ret = int(knitro.KN_solve(kc))
18941897

18951898
reported_runtime: float | None = None
1899+
mip_relaxation_bnd: float | None = None
1900+
mip_number_nodes: int | None = None
1901+
mip_number_solves: int | None = None
1902+
mip_rel_gap: float | None = None
1903+
mip_abs_gap: float | None = None
1904+
abs_feas_error: float | None = None
1905+
rel_feas_error: float | None = None
1906+
abs_opt_error: float | None = None
1907+
rel_opt_error: float | None = None
1908+
n_vars: int | None = None
1909+
n_cons: int | None = None
1910+
n_integer_vars: int | None = None
1911+
n_continuous_vars: int | None = None
18961912
with contextlib.suppress(Exception):
18971913
reported_runtime = float(knitro.KN_get_solve_time_real(kc))
1914+
mip_relaxation_bnd = float(knitro.KN_get_mip_relaxation_bnd(kc))
1915+
mip_number_nodes = int(knitro.KN_get_mip_number_nodes(kc))
1916+
mip_number_solves = int(knitro.KN_get_mip_number_solves(kc))
1917+
mip_rel_gap = float(knitro.KN_get_mip_rel_gap(kc))
1918+
mip_abs_gap = float(knitro.KN_get_mip_abs_gap(kc))
1919+
abs_feas_error = float(knitro.KN_get_abs_feas_error(kc))
1920+
rel_feas_error = float(knitro.KN_get_rel_feas_error(kc))
1921+
abs_opt_error = float(knitro.KN_get_abs_opt_error(kc))
1922+
rel_opt_error = float(knitro.KN_get_rel_opt_error(kc))
1923+
n_vars = int(knitro.KN_get_number_vars(kc))
1924+
n_cons = int(knitro.KN_get_number_cons(kc))
1925+
var_types = list(knitro.KN_get_var_types(kc))
1926+
n_integer_vars = int(
1927+
var_types.count(knitro.KN_VARTYPE_INTEGER)
1928+
+ var_types.count(knitro.KN_VARTYPE_BINARY)
1929+
)
1930+
n_continuous_vars = int(var_types.count(knitro.KN_VARTYPE_CONTINUOUS))
18981931

18991932
if ret in CONDITION_MAP:
19001933
termination_condition = CONDITION_MAP[ret]
@@ -1939,12 +1972,26 @@ def get_solver_solution() -> Solution:
19391972
return Result(
19401973
status,
19411974
solution,
1942-
KnitroResult(knitro_context=kc, reported_runtime=reported_runtime),
1975+
KnitroResult(
1976+
reported_runtime=reported_runtime,
1977+
mip_relaxation_bnd=mip_relaxation_bnd,
1978+
mip_number_nodes=mip_number_nodes,
1979+
mip_number_solves=mip_number_solves,
1980+
mip_rel_gap=mip_rel_gap,
1981+
mip_abs_gap=mip_abs_gap,
1982+
abs_feas_error=abs_feas_error,
1983+
rel_feas_error=rel_feas_error,
1984+
abs_opt_error=abs_opt_error,
1985+
rel_opt_error=rel_opt_error,
1986+
n_vars=n_vars,
1987+
n_cons=n_cons,
1988+
n_integer_vars=n_integer_vars,
1989+
n_continuous_vars=n_continuous_vars,
1990+
),
19431991
)
1944-
19451992
finally:
1946-
# Intentionally keep the Knitro context alive; do not free `kc` here.
1947-
pass
1993+
with contextlib.suppress(Exception):
1994+
knitro.KN_free(kc)
19481995

19491996

19501997
mosek_bas_re = re.compile(r" (XL|XU)\s+([^ \t]+)\s+([^ \t]+)| (LL|UL|BS)\s+([^ \t]+)")

0 commit comments

Comments
 (0)