-
Notifications
You must be signed in to change notification settings - Fork 81
Concurrent LP in get_relaxed_lp (used in FP) and lay foundations for future PDLP warm start #173
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
base: branch-25.08
Are you sure you want to change the base?
Conversation
* @return optimization_problem_solution_t<i_t, f_t> owning container for the solver solution | ||
*/ | ||
template <typename i_t, typename f_t> | ||
optimization_problem_solution_t<i_t, f_t> solve_lp( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is used purely in MIP context. It is cleaner to rename this to solve_relaxed_lp
or solve_lp_relaxation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that for now this is just used in the context of MIP but some people might want to solve an LP using the detail::problem representation instead of the optimization_problem one. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@akifcorduk do you have an opinion there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think renaming it kind of pins it to MIP use-cases, I agree with Nicolas that it is just another LP interface that accepts problem_t
. In the MIP context, the naming doesn't matter too much because we have other functions like run_lp_with_vars_fixed
std::tuple<dual_simplex::lp_solution_t<i_t, f_t>, dual_simplex::lp_status_t, f_t, f_t, f_t> | ||
run_dual_simplex(dual_simplex::user_problem_t<i_t, f_t>& user_problem, | ||
pdlp_solver_settings_t<i_t, f_t> const& settings) | ||
pdlp_solver_settings_t<i_t, f_t> const& settings, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should consider changing pdlp_solver_settings
to lp_settings
} | ||
|
||
template <typename i_t, typename f_t> | ||
optimization_problem_solution_t<i_t, f_t> solve_lp(optimization_problem_t<i_t, f_t>& op_problem, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this for pure LP?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as above, yes currently this used in the context LP as its using the optimization_problem_t representation.
detail::problem_t<i_t, f_t>& problem, | ||
pdlp_solver_settings_t<i_t, f_t> const& settings) | ||
pdlp_solver_settings_t<i_t, f_t> const& settings, | ||
bool inside_mip) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is inside_mip currently used anywhere? or is it for future purposes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I'm passing it to both PDLP and Dual Simplex
* @return optimization_problem_solution_t<i_t, f_t> owning container for the solver solution | ||
*/ | ||
template <typename i_t, typename f_t> | ||
optimization_problem_solution_t<i_t, f_t> solve_lp( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think renaming it kind of pins it to MIP use-cases, I agree with Nicolas that it is just another LP interface that accepts problem_t
. In the MIP context, the naming doesn't matter too much because we have other functions like run_lp_with_vars_fixed
cpp/src/linear_programming/pdlp.cu
Outdated
if (settings.has_pdlp_warm_start_data()) { | ||
const auto& warm_start_data = settings.get_pdlp_warm_start_data(); | ||
if (!warm_start_data.solved_by_pdlp_) { | ||
CUOPT_LOG_INFO( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't put INFO logs here, it would bloat the regular solution logs. DEBUG would be more appropiate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, changed
cpp/src/linear_programming/pdlp.cu
Outdated
} else if (pdlp_hyper_params::restart_strategy == | ||
static_cast<int>( | ||
pdlp_restart_strategy_t<i_t, f_t>::restart_strategy_t::TRUST_REGION_RESTART)) { | ||
CUOPT_LOG_INFO( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same: INFO is only for solution progress info to be conveyed to the user.
CUOPT_LOG_INFO("Solved with dual simplex"); | ||
sol_pdlp.copy_from(op_problem.get_handle_ptr(), sol_dual_simplex); | ||
// TODO confirm with Akif that using the problem handle ptr is not a problem | ||
sol_pdlp.copy_from(problem.handle_ptr, sol_dual_simplex); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think using problem handle_ptr should be okay given that there are no races across host threads. Even a different handle is used, the thread is default_per_thread
so it should be fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, removed the comment
cpp/src/mip/relaxed_lp/relaxed_lp.cu
Outdated
lp_solver.set_inside_mip(true); | ||
auto solver_response = lp_solver.run_solver(start_time); | ||
// TODO check that we do want to do problem checking here | ||
auto solver_response = solve_lp(op_problem, settings, true, true, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would name the boolean argument, so that it is easier to read.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. But regarding the comment, should we do problem checking here? Maybe just when we are in assert/debug mode
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At this point we don't need to do problem checks because we are not modifiying the problem. It is done in places where we modify the problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It did help me in the debug process, will add it in only assert/debug mode
}); | ||
lp_solver.set_initial_primal_solution(lp_state.prev_primal); | ||
lp_solver.set_initial_dual_solution(lp_state.prev_dual); | ||
settings.set_initial_primal_solution(lp_state.prev_primal.data(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So currently, we are not using the full warm start data yet and this code is a base/skeleton for adding the future warm start data?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excatly, because we could need to add the warm start data to the lp_state which is also tied to the mip problem
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs changes in the server warmstart population
pdlpwarmstart_data = { |
cpp/src/linear_programming/solve.cu
Outdated
problem_checking_t<i_t, f_t>::check_initial_solution_representation( | ||
*problem.original_problem_ptr, settings); | ||
} else { | ||
problem.check_problem_representation(true, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this might be unnecessary as we are doing the problem check in the problem cstr. We could maybe convert it to an assert? I think we should do the runtime problem check only at the beginning from the user, later problem checks should be asserts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree we should do it in as assert. But I believe we should keep the checks for two reasons:
- We also check the initial solutions which is not done in the problem constructor
- Even if we check in the problem constructor this is more for the case where the problem has been modified in an invalid way, we then need to check the problem again
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just looked at the changes that touched the code for starting dual simplex. They look fine. It is fine to add info about inside mip to the dual simplex solve. Right now this is only used for changing how optimality information is printed.
I did not review the other parts of this PR. (Sorry ran out of time.) I think ideally we want to use primal simplex warm starting inside FP. I'm not sure how this PR relates to that.
Approving so this can be merged while I am out of office.
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
Set to 25.10 milestone when it is created |
This PR aims at multiple improvements in MIP:
Eventually we want to add plug warm start in FP for both PDLP and Dual Simplex.