Skip to content

B&B Halt - #1760

Open
nguidotti wants to merge 4 commits into
rensfrom
bnb-halt
Open

B&B Halt#1760
nguidotti wants to merge 4 commits into
rensfrom
bnb-halt

Conversation

@nguidotti

Copy link
Copy Markdown
Contributor

With this PR, the B&B code can now be stopped via the concurrent_halt flag in the simplex_solver_settings. This also fixes the improper handle of the concurrent_halt flag during the cut passes and replaces the sub-MIP halt mechanism with the newer version.

Checklist

  • I am familiar with the Contributing Guidelines.
  • Testing
    • New or existing tests cover these changes
    • Added tests
    • Created an issue to follow-up
    • NA
  • Documentation
    • The documentation is up to date with these changes
    • Added new documentation
    • NA

@nguidotti nguidotti added this to the 26.10 milestone Aug 21, 2026
@nguidotti nguidotti self-assigned this Aug 21, 2026
@nguidotti nguidotti added non-breaking Introduces a non-breaking change improvement Improves an existing functionality mip labels Aug 21, 2026
@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown

CI Test Summary

⏭️ All 5 test job(s) skipped.

return;
}

if (halt != nullptr && halt->load(std::memory_order_acquire)) { return; }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Use submip_settings.concurrent_halt here for consistency

f_t fixrate,
i_t simplex_iter_used)
i_t simplex_iter_used,
std::atomic<int>* halt)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It's a bit strange to be passing the halt pointers around. They are meant to be contained within the settings. It might be better to create the settings with the halt and pass the settings in here.

const std::vector<f_t>& current_incumbent,
const std::vector<variable_type_t>& var_types)
const std::vector<variable_type_t>& var_types,
std::atomic<int>* halt)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same here. Could you just pass in the settings with the halt set?


while (solver_status_ == mip_status_t::UNSET && is_running_ && !worker->halt) {
while (solver_status_ == mip_status_t::UNSET && is_running_ &&
!(halt && halt->load(std::memory_order::acquire))) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could we use submip_settings.concurrent_halt here instead of a bare halt.

f_t root_relax_objective,
i_t& cut_pool_size,
[[maybe_unused]] const std::vector<f_t>& saved_solution) -> cut_pass_result_t
[[maybe_unused]] const std::vector<f_t>& saved_solution) -> cut_pass_action_t

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Good to see the return type simiplified

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would you mind replacing the auto with cut_pass_action_t and removing the -> cut_pass_action_t here?

f_t root_relax_elapsed_time = toc(root_relax_start_time);
exploration_stats_.total_lp_solve_time = root_relax_elapsed_time;

scope_guard cliques_scope([&]() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm not a fan of scope guards. These make it difficult to understand what is happening in the code. Since code is executing that may be defined far away from the actual return statement.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I understand that it is helpful to avoid having to have do this clean up at every return though. Is it possible to put this in the cliques destructor instead maybe?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If not, could you add a comment here explaining the need for the scope guard; so a reader is aware.

csr_matrix_t<i_t, f_t> Arow_;
std::vector<f_t> root_solution_;
std::vector<f_t> root_edge_norm_;
std::atomic<int> halt_;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why do we need a bare halt here? Can we store the halt in settings?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We need to store the actual object somewhere, right? The concurrent_halt points to this object.

Signed-off-by: Nicolas L. Guidotti <nguidotti@nvidia.com>
Signed-off-by: Nicolas L. Guidotti <nguidotti@nvidia.com>
Signed-off-by: Nicolas L. Guidotti <nguidotti@nvidia.com>
Signed-off-by: Nicolas L. Guidotti <nguidotti@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

improvement Improves an existing functionality mip non-breaking Introduces a non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants