Skip to content

Conversation

@akifcorduk
Copy link
Contributor

Description

This PR adds improvements to heuristics framework with the following:

  • Adds solution hash to check if an integer assignment has been locally searched before. If so, we skip that after few trials.
  • Adds dual simplex root relaxation solution to heuristics and halts(or prevents) PDLP root run.
  • Implements the multi armed bandit algorithm for the LS, currently disabled because no clear benefit was observed. The experiments will be continued here.
  • Generalized the MAB algorithm so that it could be used for any purpose which has discrete options to choose from.

@akifcorduk akifcorduk added this to the 25.08 milestone Jul 17, 2025
@akifcorduk akifcorduk requested review from a team as code owners July 17, 2025 11:38
@akifcorduk akifcorduk requested a review from tmckayus July 17, 2025 11:38
@akifcorduk akifcorduk added non-breaking Introduces a non-breaking change improvement Improves an existing functionality labels Jul 17, 2025
@akifcorduk akifcorduk requested review from aliceb-nv and rg20 July 17, 2025 11:38
@akifcorduk akifcorduk added the mip label Jul 17, 2025
@copy-pr-bot
Copy link

copy-pr-bot bot commented Jul 17, 2025

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@akifcorduk
Copy link
Contributor Author

/ok to test 03ade15

Copy link
Contributor

@aliceb-nv aliceb-nv left a comment

Choose a reason for hiding this comment

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

Looking good :) Just a few questions regarding the hashing
Thank you Akif!

Comment on lines +122 to +124
#if !MIP_INSTANTIATE_FLOAT && !MIP_INSTANTIATE_DOUBLE
static_assert(false, "MIP_INSTANTIATE_FLOAT or MIP_INSTANTIATE_DOUBLE must be defined");
#endif
Copy link
Contributor

Choose a reason for hiding this comment

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

Those atrocious linking errors :) I wish there was a way to throw an error at preprocessor/link time without having to add explicit checks

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, this is the second time i spend significant amount of time to these issues.

Copy link
Contributor

Choose a reason for hiding this comment

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

Should we just remove FLOAT? do we anticipate using it for MIP?

Comment on lines 80 to 84
thrust::gather(solution.handle_ptr->get_thrust_policy(),
solution.problem_ptr->integer_indices.begin(),
solution.problem_ptr->integer_indices.end(),
solution.assignment.begin(),
integer_assignment.begin());
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we ought to be careful with the implicit cast to size_t performed here. The C++ standard states that any value that cannot be represented in the target cast type yields undefined behavior:

Real floating-integer conversions
A finite value of any real floating type can be implicitly converted to any integer type. Except where covered by boolean conversion above, the rules are:

The fractional part is discarded (truncated towards zero).
If the resulting value can be represented by the target type, that value is used
otherwise, the behavior is undefined.
int n = 3.14; // n == 3
int x = 1e10; // undefined behavior for 32-bit int

I think this mean there might be issues in the case of negative and large (>1e20) assignments. It's probably better to compute the hash in a bitwise manner

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, fixed!

Comment on lines 34 to 35
hash_1 ^= hash_2 + 0x9e3779b9 + (hash_1 << 6) + (hash_1 >> 2);
return hash_1;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is a 32-bit hash, with 64-bit values this might not work properly

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks fixed!

@akifcorduk
Copy link
Contributor Author

/ok to test 6bcd726

@akifcorduk
Copy link
Contributor Author

/ok to test 08d8372

Copy link
Contributor

@aliceb-nv aliceb-nv left a comment

Choose a reason for hiding this comment

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

Awesome work Akif!

solution.problem_ptr->integer_indices.end(),
solution.assignment.begin(),
integer_assignment.begin());
reinterpret_cast<double*>(integer_assignment.data()));
Copy link
Contributor

Choose a reason for hiding this comment

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

I seriously doubt we will ever use anything but FP64, but in the rare case we instantiate the solver with f_t=FP32, this is going to break/behave badly. We might want to add a static_assert to make sure sizeof(f_t) == sizeof(size_t) in order not to cause issues if users decide to try out FP32

Copy link
Contributor Author

Choose a reason for hiding this comment

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

okay let me add the static assert here.

@akifcorduk
Copy link
Contributor Author

/ok to test a92b9d4

@akifcorduk
Copy link
Contributor Author

/merge

@rapids-bot rapids-bot bot merged commit 47fb158 into NVIDIA:branch-25.08 Jul 22, 2025
344 of 352 checks passed
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.

4 participants