Skip to content

Commit ddecb9d

Browse files
committed
fix restart
1 parent 5e74cbf commit ddecb9d

File tree

3 files changed

+47
-29
lines changed

3 files changed

+47
-29
lines changed

highs/pdlp/hipdlp/pdhg.cc

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ static constexpr double kDivergentMovement = 1e10;
2626

2727
using namespace std;
2828

29+
void vecPrint(const std::vector<double>& vec, const char* name) {
30+
std::cout << name << ": [";
31+
for (size_t i = 0; i < vec.size(); ++i) {
32+
std::cout << vec[i];
33+
if (i < vec.size() - 1) std::cout << ", ";
34+
}
35+
std::cout << "]" << std::endl;
36+
}
37+
2938
void PDLPSolver::preprocessLp() {
3039
logger_.info(
3140
"Preprocessing LP using cupdlp formulation (slack variables for "
@@ -412,9 +421,9 @@ void PDLPSolver::solve(std::vector<double>& x, std::vector<double>& y) {
412421

413422
// --- 3. Convergence and Restart Check (BEFORE iterate update) ---
414423
bool bool_checking = (iter < 10) ||
415-
(iter == (params_.max_iterations - 1)) ||
416-
(iter > 0 && (iter % PDHG_CHECK_INTERVAL == 0));
417-
424+
(iter == (params_.max_iterations - 1));
425+
426+
bool_checking = (bool_checking || iter % PDHG_CHECK_INTERVAL == 0);
418427
if (bool_checking) {
419428
ComputeAverageIterate(Ax_avg, ATy_avg);
420429
// Reset the average iterate accumulation
@@ -467,36 +476,35 @@ void PDLPSolver::solve(std::vector<double>& x, std::vector<double>& y) {
467476
restart_scheme_.Check(iter, current_results, average_results);
468477

469478
if (restart_info.should_restart) {
470-
std::vector<double> restart_x, restart_y;
471479
if (restart_info.restart_to_average) {
472-
// Restart from the average iterate
473-
restart_x = x_avg_;
474-
restart_y = y_avg_;
480+
restart_scheme_.primal_feas_last_restart_ = average_results.primal_feasibility;
481+
restart_scheme_.dual_feas_last_restart_ = average_results.dual_feasibility;
482+
restart_scheme_.duality_gap_last_restart_ = average_results.duality_gap;
483+
484+
x_current_ = x_avg_;
485+
y_current_ = y_avg_;
475486

476487
Ax_cache_ = Ax_avg;
477488
ATy_cache_ = ATy_avg;
478489
} else {
479-
// Restart from the current iterate
480-
restart_x = x_current_;
481-
restart_y = y_current_;
490+
restart_scheme_.primal_feas_last_restart_ = current_results.primal_feasibility;
491+
restart_scheme_.dual_feas_last_restart_ = current_results.dual_feasibility;
492+
restart_scheme_.duality_gap_last_restart_ = current_results.duality_gap;
482493
}
483494

484495
// Perform the primal weight update using z^{n,0} and z^{n-1,0}
485496
PDHG_Compute_Step_Size_Ratio(working_params);
486497
current_eta_ = working_params.eta;
487498
restart_scheme_.passParams(&working_params);
488-
restart_scheme_.UpdateBeta(working_params.omega * working_params.omega);
489499

490-
x_at_last_restart_ = restart_x; // Current becomes the new last
491-
y_at_last_restart_ = restart_y;
500+
x_at_last_restart_ = x_current_; // Current becomes the new last
501+
y_at_last_restart_ = y_current_;
492502

493503
std::fill(x_sum_.begin(), x_sum_.end(), 0.0);
494504
std::fill(y_sum_.begin(), y_sum_.end(), 0.0);
495505
sum_weights_ = 0.0;
496506

497-
// Set x_current_ and y_current_ for the next iteration's starting point
498-
x_current_ = restart_x;
499-
y_current_ = restart_y;
507+
restart_scheme_.last_restart_iter_ = iter;
500508

501509
// Recompute Ax and ATy for the restarted iterates
502510
linalg::Ax(lp, x_current_, Ax_cache_);
@@ -607,15 +615,15 @@ void PDLPSolver::PDHG_Compute_Step_Size_Ratio(
607615
// iterates.
608616
double primal_diff_norm = linalg::diffTwoNorm(x_at_last_restart_, x_current_);
609617
double dual_diff_norm = linalg::diffTwoNorm(y_at_last_restart_, y_current_);
610-
618+
611619
double dMeanStepSize = std::sqrt(stepsize_.primal_step *
612620
stepsize_.dual_step);
613621

614622

615623
// 2. Update the primal weight (beta = omega^2) if movements are significant.
616624
if (std::min(primal_diff_norm, dual_diff_norm) > 1e-10) {
617625
double beta_update_ratio = dual_diff_norm / primal_diff_norm;
618-
double old_beta = working_params.omega * working_params.omega;
626+
double old_beta = stepsize_.beta;
619627

620628
double dLogBetaUpdate = 0.5 * std::log(beta_update_ratio) +
621629
0.5 * std::log(std::sqrt(old_beta));
@@ -626,6 +634,7 @@ void PDLPSolver::PDHG_Compute_Step_Size_Ratio(
626634
stepsize_.dual_step = stepsize_.primal_step * stepsize_.beta;
627635
working_params.eta = std::sqrt(stepsize_.primal_step * stepsize_.dual_step);
628636
working_params.omega = std::sqrt(stepsize_.beta);
637+
restart_scheme_.UpdateBeta(stepsize_.beta);
629638
}
630639

631640
void PDLPSolver::UpdateAverageIterates(const std::vector<double>& x,
@@ -1365,3 +1374,4 @@ double PDLPSolver::ComputeNonlinearity(const std::vector<double>& delta_primal,
13651374
}
13661375
return std::abs(nonlinearity);
13671376
}
1377+

highs/pdlp/hipdlp/restart.cc

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ RestartInfo RestartScheme::Check(int current_iter,
156156
debugPdlpRestartLog(debug_pdlp_log_file_, current_iter, mu_current,
157157
mu_average);
158158
double candidate_score;
159-
bool restart_to_average;
159+
bool restart_to_average = false;
160160
if (mu_current < mu_average) {
161161
candidate_score = mu_current;
162162
restart_to_average = false;
@@ -168,11 +168,12 @@ RestartInfo RestartScheme::Check(int current_iter,
168168
// 2. Check the three restart conditions in order
169169
bool should_restart = false;
170170
PDHG_restart_choice restart_choice_for_logic = PDHG_NO_RESTART;
171-
171+
172172
if ((current_iter - last_restart_iter_) >= 0.36 * current_iter) {
173173
// Condition 1: Artificial Restart
174174
should_restart = true;
175175
} else {
176+
176177
double mu_last_restart = compute_score(beta_, primal_feas_last_restart_,
177178
dual_feas_last_restart_, duality_gap_last_restart_);
178179

@@ -201,9 +202,13 @@ RestartInfo RestartScheme::Check(int current_iter,
201202
duality_gap_last_candidate_ = current_results.duality_gap;
202203
}
203204

204-
// NOTE: Your main solver loop is responsible for calling `SetLastRestartIter(current_iter)`
205-
// when it receives `should_restart = true`. This function does not modify that state directly,
206-
// it only determines if it *should* happen.
205+
if (should_restart ) {
206+
if (restart_to_average){
207+
std::cout << "Last restart was iter " << last_restart_iter_ << ": average\n";
208+
} else {
209+
std::cout << "Last restart was iter " << last_restart_iter_ << ": current\n";
210+
}
211+
}
207212

208213
return RestartInfo(should_restart, restart_to_average);
209214
}

highs/pdlp/hipdlp/restart.hpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class RestartScheme {
4242
const SolverResults& average_results);
4343

4444
int GetLastRestartIter() const { return last_restart_iter_; }
45+
int last_restart_iter_ = 0;
4546
void passParams(PrimalDualParams* params) { params_ = params; };
4647
void passLogOptions(const HighsLogOptions* log_options) {
4748
log_options_ = log_options;
@@ -59,6 +60,14 @@ class RestartScheme {
5960
};
6061
void SetLastRestartIter(int iter) { last_restart_iter_ = iter; };
6162

63+
// State for adaptive restart
64+
//dPrimalFeasLastRestart = primal_feas_last_restart_
65+
//dDualFeasLastRestart = dual_feas_last_restart_;
66+
//dDualityGapLastRestart = duality_gap_last_restart_;
67+
double primal_feas_last_restart_ = 0.0;
68+
double dual_feas_last_restart_ = 0.0;
69+
double duality_gap_last_restart_ = 0.0;
70+
6271
private:
6372
PrimalDualParams* params_;
6473
const HighsLogOptions* log_options_;
@@ -67,13 +76,7 @@ class RestartScheme {
6776

6877
RestartStrategy strategy_ = RestartStrategy::NO_RESTART;
6978
int fixed_restart_interval_ = 100;
70-
int last_restart_iter_ = 0;
7179
double beta_;
72-
73-
// State for adaptive restart
74-
double primal_feas_last_restart_ = 0.0;
75-
double dual_feas_last_restart_ = 0.0;
76-
double duality_gap_last_restart_ = 0.0;
7780

7881
double primal_feas_last_candidate_ = 0.0;
7982
double dual_feas_last_candidate_ = 0.0;

0 commit comments

Comments
 (0)