Skip to content

Fix: handle HighsModelStatus.kSolutionLimit like kIterationLimit #3634

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

rschwarz
Copy link

@rschwarz rschwarz commented Jun 16, 2025

Was previously not handled at all, resulting in termination_condition of unknown, and no further information about whether a solution was found.

kIterationLimit may not be exact, but it's the best fit among the current enum values, I guess.

Fixes #3632 .

Summary/Motivation

handle HighsModelStatus.kSolutionLimit like kIterationLimit

Changes proposed in this PR:

  • add case for kSolutionLimit
  • add warning for the else branch

Legal Acknowledgement

By contributing to this software project, I have read the contribution guide and agree to the following terms and conditions for my contribution:

  1. I agree my contributions are submitted under the BSD license.
  2. I represent I am authorized to make the contributions and grant the license. If my employer has rights to intellectual property that includes these contributions, I represent that I have received permission to make contributions and grant the required license on behalf of that employer.

Was previously not handled at all, resulting in termination_condition of
unknown, and no further information about whether a solution was found.

kIterationLimit may not be exact, but it's the best fit among the current enum
values, I guess.
@mrmundt
Copy link
Contributor

mrmundt commented Jun 16, 2025

So I understand - does kSolutionLimit exist for all versions of highspy, or is it only present in 1.5?

@rschwarz
Copy link
Author

rschwarz commented Jun 16, 2025

My understanding is that it was added to HiGHS v1.5, and has remained to the present day.

EDIT: See this HiGHS test which is still on the main branch:

https://github.com/ERGO-Code/HiGHS/blob/364c83a51e44ba6c27def9c8fc1a49b1daf5ad5c/check/TestMipSolver.cpp#L62-L67

@mrmundt
Copy link
Contributor

mrmundt commented Jun 16, 2025

Okay, then this is going to need a bit of work. This change would effectively pin us to a minimum version of highspy, and we try our best to maintain backwards compatibility as much as possible. Additionally, there are actually two different HiGHS interfaces - contrib/appsi and contrib/solver. We have a dev call tomorrow and will talk about it then. Thanks for submitting the PR! I'll let you know soon what we decide.

@rschwarz
Copy link
Author

If it helps, I could add in an additional version check for HiGHS in the code.

@jsiirola
Copy link
Member

A version check would be OK, but something like

       elif status == getattr(highspy.HighsModelStatus, "kSolutionLimit", NOTSET):
            results.termination_condition = TerminationCondition.maxIterations

might be more performant and simpler.

@rschwarz
Copy link
Author

A version check would be OK, but something like

       elif status == getattr(highspy.HighsModelStatus, "kSolutionLimit", NOTSET):
            results.termination_condition = TerminationCondition.maxIterations

might be more performant and simpler.

This looks good to me, but I'm not sure if this might cause some type problems, as highspy.HighsModelStatus is actually an enum at the C++ level.

Please let me know if which changes I should apply, if any.

PS: I'm now aware of the non-APPSI interface to HiGHS, which is affected by the same problem.

@mrmundt
Copy link
Contributor

mrmundt commented Jun 17, 2025

Okay, we talked about this today, and we think using @jsiirola 's proposed solution above on both files should be good. Please make those changes and we'll happily move forward!

Copy link

codecov bot commented Jun 18, 2025

Codecov Report

Attention: Patch coverage is 25.00000% with 6 lines in your changes missing coverage. Please review.

Project coverage is 88.94%. Comparing base (dc503c2) to head (55b3300).
Report is 40 commits behind head on main.

Files with missing lines Patch % Lines
pyomo/contrib/appsi/solvers/highs.py 25.00% 3 Missing ⚠️
pyomo/contrib/solver/solvers/highs.py 25.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3634      +/-   ##
==========================================
+ Coverage   88.92%   88.94%   +0.02%     
==========================================
  Files         888      888              
  Lines      102347   102709     +362     
==========================================
+ Hits        91009    91356     +347     
- Misses      11338    11353      +15     
Flag Coverage Δ
builders 26.68% <25.00%> (-0.01%) ⬇️
default 85.50% <25.00%> (?)
expensive 34.05% <25.00%> (?)
linux 86.74% <25.00%> (-1.94%) ⬇️
linux_other 86.74% <25.00%> (+0.01%) ⬆️
osx 83.04% <25.00%> (+0.01%) ⬆️
win 84.91% <25.00%> (-0.04%) ⬇️
win_other 84.96% <25.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@rschwarz
Copy link
Author

I see that the newly added lines are not covered by the existing tests. Should I attempt to set up a MIP problem of moderate size where this status would result after a node limit of 1, or would that be overkill?

@jsiirola
Copy link
Member

That would be fantastic. We (i.e., @mrmundt) are working on building a new set of "standard solver tests" that we can use to exercise all the solver interfaces in a semi-consistent manner (in particular to exercise the expected solver return status flags), and it would be great to include this in the suite. Testing it for HiGHS specifically is fine for now -- at least it will be in the repo and can be pulled into the new test suite as it gets assembled.

@rschwarz
Copy link
Author

It's good that I tried to add tests, and for both interfaces of HiGHS: I was unaware that multiple versions of the TerminationCondition class exist, and that the field is sometimes called maxIterations, and sometimes iterationLimit.

I'm using a Knapsack instance based on random data, which is not solved to optimality in the root with my version of HiGHS and on my machine, so I hope this will also be the case for GitHub.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

HiGHS status kSolutionLimit is not handled
4 participants