From c76bec01b6cb2e92c68d431b9681aef8be041568 Mon Sep 17 00:00:00 2001 From: Dominik Kamp Date: Sun, 11 Oct 2026 18:12:08 +0200 Subject: [PATCH 1/2] Extend soplex interface --- ipet/parsing/Solver.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/ipet/parsing/Solver.py b/ipet/parsing/Solver.py index 1a3e9cf..1d029cd 100644 --- a/ipet/parsing/Solver.py +++ b/ipet/parsing/Solver.py @@ -648,11 +648,17 @@ class SoPlexSolver(Solver): solverId = "SoPlex" recognition_expr = re.compile(r"^SoPlex version ") version_expr = re.compile(r"^SoPlex version (\S+)") + mode_expr = re.compile(r"^SoPlex version .*\[mode: ([^\]]+)\]") primalbound_expr = re.compile(r"^ Objective value\s+: (\S+)") dualbound_expr = re.compile(r"^ Objective value\s+: (\S+)") - solvingtime_expr = re.compile(r"^ Solving\s+: (\S+)") + solvingtime_expr = re.compile(r"^Solving time \(sec\)\s+: (\S+)") + totalreadingtime_expr = re.compile(r"^ Reading\s+: (\S+)") + totalsolvingtime_expr = re.compile(r"^ Solving\s+: (\S+)") violbound_expr = re.compile(r"^ Max/sum bound\s+: (\S+)") viollp_expr = re.compile(r"^ Max/sum row\s+: (\S+)") + columns_expr = re.compile(r"^ Columns\s+: (\d+)") + rows_expr = re.compile(r"^ Rows\s+: (\d+)") + presolved_expr = re.compile(r"^Reduced LP has (\d+) rows (\d+) columns") githash_expr = re.compile(r"^SoPlex version .*\[[Gg]it[Hh]ash: (\S+)\]") iterations_expr = re.compile(r"^Iterations\s+: (\d+)") @@ -708,8 +714,20 @@ def extractOptionalInformation(self, line : str): m = self.dualfeas_expr.match(line) if m: self.dualfeasible = m.groups()[0] == "feasible" + self.extractByExpression(line, self.mode_expr, Key.Mode, str) self.extractByExpression(line, self.githash_expr, Key.GitHash, str) self.extractByExpression(line, self.iterations_expr, "Iterations", int) + self.extractByExpression(line, self.totalreadingtime_expr, "TotalTime_reading") + self.extractByExpression(line, self.totalsolvingtime_expr, "TotalTime_solving") + self.extractByExpression(line, self.columns_expr, "OriginalProblem_Vars", int) + self.extractByExpression(line, self.rows_expr, "OriginalProblem_InitialNCons", int) + m = self.presolved_expr.match(line) + if m: + self.addData("PresolvedProblem_Vars", int(m.groups()[1])) + self.addData("PresolvedProblem_InitialNCons", int(m.groups()[0])) + elif self.getData("PresolvedProblem_InitialNCons") is None and self.getData("OriginalProblem_InitialNCons") is not None: + self.addData("PresolvedProblem_Vars", self.getData("OriginalProblem_Vars")) + self.addData("PresolvedProblem_InitialNCons", self.getData("OriginalProblem_InitialNCons")) def cleanupData(self): if self.getData(Key.SolverStatus) in (Key.SolverStatusCodes.Crashed, Key.SolverStatusCodes.Readerror): From 4420a3d5c3e36c702e85bed210f821dca65ce3d3 Mon Sep 17 00:00:00 2001 From: Dominik Kamp Date: Sun, 11 Oct 2026 18:12:46 +0200 Subject: [PATCH 2/2] Extend soplex tests --- test/SolverTest.py | 37 +++++++++++++++++++++++++++------ test/data/soplex800-optimal.out | 33 ++++++++++++++--------------- 2 files changed, 47 insertions(+), 23 deletions(-) diff --git a/test/SolverTest.py b/test/SolverTest.py index 416e2ea..561e321 100644 --- a/test/SolverTest.py +++ b/test/SolverTest.py @@ -609,50 +609,75 @@ class SolverTest(unittest.TestCase): Key.Solver: "SoPlex", Key.Version: "8.0.0", Key.GitHash: "2207cfb2", - "Iterations": 1, + Key.Mode: "debug", + "Iterations": 0, Key.SolvingTime: 0.0, Key.ObjectiveSense: Key.ObjectiveSenseCode.MINIMIZE, - Key.SolverStatus: Key.SolverStatusCodes.Optimal }, { + Key.SolverStatus: Key.SolverStatusCodes.Optimal, + "OriginalProblem_Vars": 1, + "OriginalProblem_InitialNCons": 1, + "PresolvedProblem_Vars": 0, + "PresolvedProblem_InitialNCons": 0 }, { Key.PrimalBound: 1.0, Key.DualBound: 1.0} ], "soplex800-infeasible" : [ { Key.Solver: "SoPlex", Key.Version: "8.0.0", Key.GitHash: "2207cfb2", + Key.Mode: "debug", "Iterations": 0, Key.SolvingTime: 0.0, Key.ObjectiveSense: Key.ObjectiveSenseCode.MINIMIZE, - Key.SolverStatus: Key.SolverStatusCodes.Infeasible }, { + Key.SolverStatus: Key.SolverStatusCodes.Infeasible, + "OriginalProblem_Vars": 1, + "OriginalProblem_InitialNCons": 1, + "PresolvedProblem_Vars": 1, + "PresolvedProblem_InitialNCons": 1 }, { Key.PrimalBound: 1e+100, Key.DualBound: 1e+100} ], "soplex800-unbounded" : [ { Key.Solver: "SoPlex", Key.Version: "8.0.0", Key.GitHash: "2207cfb2", + Key.Mode: "debug", "Iterations": 0, Key.SolvingTime: 0.0, Key.ObjectiveSense: Key.ObjectiveSenseCode.MINIMIZE, - Key.SolverStatus: Key.SolverStatusCodes.Unbounded }, { + Key.SolverStatus: Key.SolverStatusCodes.Unbounded, + "OriginalProblem_Vars": 1, + "OriginalProblem_InitialNCons": 1, + "PresolvedProblem_Vars": 1, + "PresolvedProblem_InitialNCons": 1 }, { Key.PrimalBound: -1e+100, Key.DualBound: -1e+100} ], "soplex800-primalfeasible" : [ { Key.Solver: "SoPlex", Key.Version: "8.0.0", Key.GitHash: "2207cfb2", + Key.Mode: "debug", "Iterations": 1, Key.SolvingTime: 0.0, Key.ObjectiveSense: Key.ObjectiveSenseCode.MAXIMIZE, - Key.SolverStatus: Key.SolverStatusCodes.Interrupted }, { + Key.SolverStatus: Key.SolverStatusCodes.Interrupted, + "OriginalProblem_Vars": 2, + "OriginalProblem_InitialNCons": 2, + "PresolvedProblem_Vars": 2, + "PresolvedProblem_InitialNCons": 2 }, { Key.PrimalBound: 1.0, Key.DualBound: None} ], "soplex800-dualfeasible" : [ { Key.Solver: "SoPlex", Key.Version: "8.0.0", Key.GitHash: "2207cfb2", + Key.Mode: "debug", "Iterations": 1, Key.SolvingTime: 0.0, Key.ObjectiveSense: Key.ObjectiveSenseCode.MINIMIZE, - Key.SolverStatus: Key.SolverStatusCodes.Interrupted }, { + Key.SolverStatus: Key.SolverStatusCodes.Interrupted, + "OriginalProblem_Vars": 2, + "OriginalProblem_InitialNCons": 2, + "PresolvedProblem_Vars": 2, + "PresolvedProblem_InitialNCons": 2 }, { Key.PrimalBound: None, Key.DualBound: 1.0} ], "conopt439-tutorial" : [ { diff --git a/test/data/soplex800-optimal.out b/test/data/soplex800-optimal.out index cd61631..8c2f1c6 100644 --- a/test/data/soplex800-optimal.out +++ b/test/data/soplex800-optimal.out @@ -1,23 +1,22 @@ SoPlex version 8.0.0 [mode: debug] [precision: 8 byte] [rational: GMP 6.3.0] [PaPILO: not available] [githash: 2207cfb2] Copyright (c) 1996-2025 Zuse Institute Berlin (ZIB) -int:simplifier = 0 - Reading (real) LP file . . . Reading took 0.00 seconds. LP has 1 rows 1 columns and 1 nonzeros. Equilibrium scaling LP (persistent) -type | time | iters | facts | shift | viol sum | viol num | obj value - L | 0.0 | 0 | 2 | 0.00e+00 | 1.00e+00 | 1 | 0.00000000e+00 - L | 0.0 | 1 | 3 | 0.00e+00 | 0.00e+00 | 0 | 1.00000000e+00 +Simplifier removed 1 rows, 1 columns, 1 nonzeros, 1 col bounds, 0 row bounds +Reduced LP has 0 rows 0 columns 0 nonzeros +Simplifier removed all rows and columns + --- unsimplifying solution and basis --- unscaling external solution --- verifying computed solution SoPlex status : problem is solved [optimal] Solving time (sec) : 0.00 -Iterations : 1 +Iterations : 0 Objective value : 1.00000000e+00 Primal solution feasible in original problem (max. violation = 0.00000000e+00). @@ -76,11 +75,11 @@ Precision boosts : 0 Pivoting : 0 Feasibility : 0 Unboundedness : 0 -Iterations : 1 - From scratch : 1 (100.00%) - From basis : 0 (0.00%) - Primal : 0 (0.00%) - Dual : 1 (100.00%) +Iterations : 0 + From scratch : 0 + From basis : 0 + Primal : 0 + Dual : 0 Bound flips : 0 Sol. polishing : 0 First FP solve : 0 @@ -91,11 +90,11 @@ IterationsBoosted : 0 Dual : 0 Bound flips : 0 Sol. polishing : 0 -LU factorizations : 3 - Factor. frequency : 0.33 iterations per factorization +LU factorizations : 0 + Factor. frequency : - Factor. time : 0.00 -LU solves : 10 - Solve frequency : 10.00 solves per iteration +LU solves : 0 + Solve frequency : - Solve time : 0.00 Matrix-Vector ops : Sparse time : 0.00 @@ -105,7 +104,7 @@ Matrix-Vector ops : Colwise time : 0.00 calls : 0 (0.00% of iterations) Unsetup time : 0.00 - calls : 1 (99.01% of iterations) + calls : 0 (0.00% of iterations) Rat. factorizations : 0 Rat. factor. time : 0.00 Rat. solve time : 0.00 @@ -119,4 +118,4 @@ Degeneracy : Average Primal : 0.00 Average Dual : 0.00 Numerics : - Condition Number : 1.00000000e+00 + Condition Number : 1.00000000e+100