Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions pyomo/contrib/solver/common/results.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,14 +197,6 @@ def __init__(
description="A tuple representing the version of the solver in use.",
),
)
self.iteration_count: Optional[int] = self.declare(
'iteration_count',
ConfigValue(
domain=NonNegativeInt,
default=None,
description="The total number of iterations.",
),
)
self.timing_info: ConfigDict = self.declare(
'timing_info', ConfigDict(implicit=True)
)
Expand Down
2 changes: 1 addition & 1 deletion pyomo/contrib/solver/solvers/gurobi_direct.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ def _postsolve(self, timer: HierarchicalTimer, config, loader):
results.incumbent_objective = None
results.objective_bound = None

results.iteration_count = grb_model.getAttr('IterCount')
results.extra_info.iteration_count = grb_model.getAttr('IterCount')

timer.start('load solution')
if config.load_solutions:
Expand Down
2 changes: 1 addition & 1 deletion pyomo/contrib/solver/solvers/gurobi_persistent.py
Original file line number Diff line number Diff line change
Expand Up @@ -857,7 +857,7 @@ def _postsolve(self, timer: HierarchicalTimer):
):
results.incumbent_objective = None

results.iteration_count = gprob.getAttr('IterCount')
results.extra_info.iteration_count = gprob.getAttr('IterCount')

timer.start('load solution')
if config.load_solutions:
Expand Down
10 changes: 9 additions & 1 deletion pyomo/contrib/solver/solvers/highs.py
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,15 @@ def _postsolve(self, stream: io.StringIO):
results.objective_bound = None
else:
results.objective_bound = info.mip_dual_bound
results.iteration_count = info.simplex_iteration_count

if info.valid:
results.extra_info.simplex_iteration_count = (
info.simplex_iteration_count
)
results.extra_info.ipm_iteration_count = info.ipm_iteration_count
results.extra_info.mip_node_count = info.mip_node_count
results.extra_info.pdlp_iteration_count = info.pdlp_iteration_count
results.extra_info.qp_iteration_count = info.qp_iteration_count

if config.load_solutions:
if has_feasible_solution:
Expand Down
8 changes: 5 additions & 3 deletions pyomo/contrib/solver/solvers/ipopt.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ def solve(self, model, **kwds) -> Results:
results = Results()
results.termination_condition = TerminationCondition.provenInfeasible
results.solution_loader = SolSolutionLoader(None, None)
results.iteration_count = 0
results.extra_info.iteration_count = 0
results.timing_info.total_seconds = 0
elif len(nl_info.variables) == 0:
if len(nl_info.eliminated_vars) == 0:
Expand All @@ -487,7 +487,7 @@ def solve(self, model, **kwds) -> Results:
)
results.solution_status = SolutionStatus.optimal
results.solution_loader = SolSolutionLoader(None, nl_info=nl_info)
results.iteration_count = 0
results.extra_info.iteration_count = 0
results.timing_info.total_seconds = 0
else:
if os.path.isfile(basename + '.sol'):
Expand All @@ -503,7 +503,9 @@ def solve(self, model, **kwds) -> Results:
results.solution_loader = SolSolutionLoader(None, None)
else:
try:
results.iteration_count = parsed_output_data.pop('iters')
results.extra_info.iteration_count = parsed_output_data.pop(
'iters'
)
cpu_seconds = parsed_output_data.pop('cpu_seconds')
for k, v in cpu_seconds.items():
results.timing_info[k] = v
Expand Down
2 changes: 1 addition & 1 deletion pyomo/contrib/solver/solvers/knitro/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ def _postsolve(self, config: KnitroConfig, timer: HierarchicalTimer) -> Results:
results.solution_status = self._get_solution_status(status)
results.termination_condition = self._get_termination_condition(status)
results.incumbent_objective = self._engine.get_obj_value()
results.iteration_count = self._engine.get_num_iters()
results.extra_info.iteration_count = self._engine.get_num_iters()
results.timing_info.solve_time = self._engine.get_solve_time()
results.timing_info.timer = timer

Expand Down
10 changes: 5 additions & 5 deletions pyomo/contrib/solver/tests/solvers/test_ipopt.py
Original file line number Diff line number Diff line change
Expand Up @@ -594,13 +594,13 @@ def test_ipopt_quiet_print_level(self):
result = ipopt.Ipopt().solve(model, solver_options={'print_level': 0})
# IPOPT doesn't tell us anything about the iters if the print level
# is set to 0
self.assertIsNone(result.iteration_count)
self.assertFalse(hasattr(result.extra_info, 'iteration_count'))
self.assertFalse(hasattr(result.extra_info, 'iteration_log'))
model = self.create_model()
result = ipopt.Ipopt().solve(model, solver_options={'print_level': 3})
# At a slightly higher level, we get some of the info, like
# iteration count, but NOT iteration_log
self.assertEqual(result.iteration_count, 11)
self.assertEqual(result.extra_info.iteration_count, 11)
self.assertFalse(hasattr(result.extra_info, 'iteration_log'))

def test_ipopt_loud_print_level(self):
Expand All @@ -609,13 +609,13 @@ def test_ipopt_loud_print_level(self):
result = ipopt.Ipopt().solve(model, solver_options={'print_level': 8})
# Nothing unexpected should be in the results object at this point,
# except that the solver_log is significantly longer
self.assertEqual(result.iteration_count, 11)
self.assertEqual(result.extra_info.iteration_count, 11)
self.assertEqual(result.incumbent_objective, 7.013645951336496e-25)
self.assertIn('Optimal Solution Found', result.extra_info.solver_message)
self.assertTrue(hasattr(result.extra_info, 'iteration_log'))
model = self.create_model()
result = ipopt.Ipopt().solve(model, solver_options={'print_level': 12})
self.assertEqual(result.iteration_count, 11)
self.assertEqual(result.extra_info.iteration_count, 11)
self.assertEqual(result.incumbent_objective, 7.013645951336496e-25)
self.assertIn('Optimal Solution Found', result.extra_info.solver_message)
self.assertTrue(hasattr(result.extra_info, 'iteration_log'))
Expand All @@ -624,7 +624,7 @@ def test_ipopt_results(self):
model = self.create_model()
results = ipopt.Ipopt().solve(model)
self.assertEqual(results.solver_name, 'ipopt')
self.assertEqual(results.iteration_count, 11)
self.assertEqual(results.extra_info.iteration_count, 11)
self.assertEqual(results.incumbent_objective, 7.013645951336496e-25)
self.assertIn('Optimal Solution Found', results.extra_info.solver_message)

Expand Down
3 changes: 0 additions & 3 deletions pyomo/contrib/solver/tests/solvers/test_solvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -604,9 +604,6 @@ def test_results_object_populated(
for v in res.solver_version:
self.assertIsInstance(v, int)

# iteration_count is nonnegative
self.assertGreaterEqual(res.iteration_count, 0)

# timing_info should exist
self.assertIsNotNone(res.timing_info)

Expand Down
3 changes: 0 additions & 3 deletions pyomo/contrib/solver/tests/unit/test_results.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,6 @@ def test_member_list(self):
expected_declared = {
'extra_info',
'incumbent_objective',
'iteration_count',
'objective_bound',
'solution_loader',
'solution_status',
Expand All @@ -182,7 +181,6 @@ def test_default_initialization(self):
self.assertEqual(res.solution_status, results.SolutionStatus.noSolution)
self.assertIsNone(res.solver_name)
self.assertIsNone(res.solver_version)
self.assertIsNone(res.iteration_count)
self.assertIsInstance(res.timing_info, ConfigDict)
self.assertIsInstance(res.extra_info, ConfigDict)
self.assertIsNone(res.timing_info.start_timestamp)
Expand All @@ -198,7 +196,6 @@ def test_display(self):
objective_bound: None
solver_name: None
solver_version: None
iteration_count: None
timing_info:
start_timestamp: None
wall_time: None
Expand Down
Loading