Skip to content

Upgrade HighsInt to int64_t - #3239

Closed
Opt-Mucca wants to merge 1 commit into
latestfrom
redcost-handle-large-bounds
Closed

Upgrade HighsInt to int64_t#3239
Opt-Mucca wants to merge 1 commit into
latestfrom
redcost-handle-large-bounds

Conversation

@Opt-Mucca

Copy link
Copy Markdown
Collaborator

Description

There's currently issues for instances where users pass explicit bounds larger than kHighsIInf but that aren't kHighsInf in reduced cost fixing, e.g., 1e+18. When we cast double to HighsInt, we're ending up with kHighsIInf that will overflow during some future computations. This leads to an infinite loop.

@fwesselm I'm a bit concerned that I am still missing cases here. I think I'm still leaving some fringe cases active, e.g., if exactly std::numeric_limit<int64_t>::max() is passed. Feel free to point anything out or make changes yourself (I'm not the greatest at this) I can email you the instance if interested.

Checklist

  • I have read the contributing guidelines
  • This PR targets the latest branch
  • Tests are passing
  • Documentation was updated where relevant
  • This PR is not primarily AI-generated (per the AI contributions policy in CONTRIBUTING.md)

@Opt-Mucca
Opt-Mucca requested a review from fwesselm August 26, 2026 15:36
@jajhall

jajhall commented Aug 26, 2026

Copy link
Copy Markdown
Member

Are you saying that people are specifying integer variables with upper bounds larger than kHighsIInf, but not big enough (ie at least 1e20) to be treated as as kHighsInf?

Rather make the modifications to use int64_t rather than HighsInt to prevent overflow when these large bounds are cast from double, I'd rather have an infinte_integer_bound option that cannot reach kHighsIInf, and any bounds bigger than this are treated as kHighsInf.

We're never going to solve the LPs if the optimal values of variables with these vast bounds are anything like kHighsIInf, so no meaningful user information is lost. It also strikes me as terrible modelling.

@fwesselm I'm a bit concerned that I am still missing cases here. I think I'm still leaving some fringe cases active, e.g., if exactly std::numeric_limit<int64_t>::max() is passed. Feel free to point anything out or make changes yourself (I'm not the greatest at this) I can email you the instance if interested.

This would also address these concerns

@fwesselm fwesselm left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Opt-Mucca, I like the idea. But, if the main goal is to avoid a stall, could we just treat bounds whose absolute value is greater-equal kHighsIInf as infinite?

mipsolver.mipdata_->getDomain().col_lower_[col]),
static_cast<HighsInt>(
mipsolver.mipdata_->getDomain().col_upper_[col]),
mipsolver.mipdata_->getDomain().col_upper_[col] != kHighsInf,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we just replace this line by:

mipsolver.mipdata_->getDomain().col_upper_[col] < kHighsIInf

mipsolver.mipdata_->getDomain().col_upper_[col]),
static_cast<HighsInt>(
mipsolver.mipdata_->getDomain().col_lower_[col]),
mipsolver.mipdata_->getDomain().col_lower_[col] != -kHighsInf,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mipsolver.mipdata_->getDomain().col_lower_[col] > -kHighsIInf?

@jajhall

jajhall commented Aug 26, 2026

Copy link
Copy Markdown
Member

@Opt-Mucca, I like the idea. But, if the main goal is to avoid a stall, could we just treat bounds whose absolute value is greater-equal kHighsIInf as infinite?

For integer variables, I agree strongly that any bounds greater-equal kHighsIInf should be set to kHighsInf. This can be done in the same method where bounds on continuous variables and constraints exceeding the infinite_bound option value (default 1e20) are set to kHighsInf. A warning is logged for users.

Do I assume correctly that there's no integer cast of bounds on "pure discrete" constraints - those where all the nonzero coefficients involve discrete variables?

@Opt-Mucca

Opt-Mucca commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator Author

@fwesselm I'm going to close this PR in favour of yours. Thank you for saving me from falling down an unnecessary rabbit hole.

Do I assume correctly that there's no integer cast of bounds on "pure discrete" constraints - those where all the nonzero coefficients involve discrete variables?

@jajhall I'm not sure if I understand the question completely. Attempted answer for what I think it is: The bounds are rounded to some integer, but they're still stored as doubles so we don't have to worry about inconsistent types. This is the first time I've seen a large enough value that isn't quite kHighsInf attempt to be cast to HighsInt

Edit: Missed the first comment

Are you saying that people are specifying integer variables with upper bounds larger than kHighsIInf, but not big enough (ie at least 1e20) to be treated as as kHighsInf?

Yes. That was the cause of the infinite loop in the .lp file @galabovaa sent me

@Opt-Mucca Opt-Mucca closed this Aug 27, 2026
@jajhall

jajhall commented Aug 27, 2026

Copy link
Copy Markdown
Member

@fwesselm I'm going to close this PR in favour of yours. Thank you for saving me from falling down an unnecessary rabbit hole.

Do I assume correctly that there's no integer cast of bounds on "pure discrete" constraints - those where all the nonzero coefficients involve discrete variables?

@jajhall I'm not sure if I understand the question completely. Attempted answer for what I think it is: The bounds are rounded to some integer, but they're still stored as doubles so we don't have to worry about inconsistent types. This is the first time I've seen a large enough value that isn't quite kHighsInf attempt to be cast to HighsInt

I was just trying to think laterally - that maybe there's some integer technique that converts a constraint's data to HighsInt, so casting large finite constraint bounds to HighsInt can cause overflow.

Which PR of @fwesselm do you mean?

@Opt-Mucca

Copy link
Copy Markdown
Collaborator Author

I was just trying to think laterally - that maybe there's some integer technique that converts a constraint's data to HighsInt, so casting large finite constraint bounds to HighsInt can cause overflow.

I have no doubt this can be done with some C++ magic.

Which PR of @fwesselm do you mean?

A soon to be PR* (@fwesselm mentioned wanting to check out the overflow possibility a bit more): latest...fwesselm:HiGHS:stallFindLurkingBounds

@jajhall

jajhall commented Aug 27, 2026

Copy link
Copy Markdown
Member

I was just trying to think laterally - that maybe there's some integer technique that converts a constraint's data to HighsInt, so casting large finite constraint bounds to HighsInt can cause overflow.

I have no doubt this can be done with some C++ magic.

Which PR of @fwesselm do you mean?

A soon to be PR* (@fwesselm mentioned wanting to check out the overflow possibility a bit more): latest...fwesselm:HiGHS:stallFindLurkingBounds

I see this now, and it's still necessary

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.

3 participants