Skip to content

Commit 453cc05

Browse files
committed
revert to same result
1 parent 89adafb commit 453cc05

File tree

4 files changed

+56
-31
lines changed

4 files changed

+56
-31
lines changed

check/TestPdlp.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ TEST_CASE("pdlp-restart-add-row", "[pdlp]") {
336336

337337
TEST_CASE("hi-pdlp", "[pdlp]") {
338338
std::string model =
339-
"adlittle"; //"adlittle";//"afiro";// shell// stair //25fv47 //fit2p
339+
"25fv47"; //"adlittle";//"afiro";// shell// stair //25fv47 //fit2p
340340
std::string model_file =
341341
std::string(HIGHS_DIR) + "/check/instances/" + model + ".mps";
342342
Highs h;
@@ -359,7 +359,7 @@ TEST_CASE("hi-pdlp", "[pdlp]") {
359359
h.setOptionValue("pdlp_scaling_mode", pdlp_scaling);
360360
h.setOptionValue("pdlp_step_size_strategy", 1);
361361
h.setOptionValue("pdlp_restart_strategy", 2);
362-
h.setOptionValue("pdlp_iteration_limit", 3520);
362+
// h.setOptionValue("pdlp_iteration_limit", 3520);
363363
// h.setOptionValue("log_dev_level", kHighsLogDevLevelVerbose);
364364
auto start_hipdlp = std::chrono::high_resolution_clock::now();
365365
HighsStatus run_status = h.run();

highs/pdlp/cupdlp/cupdlp_defs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ extern "C" {
4141
#define CUPDLP_DUMP_LINESEARCH_STATS (1)
4242
#define CUPDLP_INEXACT_EPS (1e-4)
4343

44-
#define PDLP_DEBUG_LOG (0)
44+
#define PDLP_DEBUG_LOG (1)
4545

4646
typedef struct CUPDLP_CUDA_DENSE_VEC CUPDLPvec;
4747
typedef struct CUPDLP_DENSE_MATRIX CUPDLPdense;

highs/pdlp/hipdlp/pdhg.cc

Lines changed: 52 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ void PDLPSolver::preprocessLp() {
164164

165165
int num_new_cols = 0;
166166
int nEqs = 0;
167+
sense_origin_ = (original_lp_->sense_ == ObjSense::kMinimize) ? 1 : -1;
167168
constraint_types_.resize(nRows_orig);
168169

169170
// 1. First pass: Classify constraints and count slack variables needed
@@ -433,21 +434,27 @@ PostSolveRetcode PDLPSolver::postprocess(HighsSolution& solution) {
433434
}
434435
}
435436

436-
std::vector<double> ax_current_(unscaled_processed_lp_.num_row_);
437-
linalg::Ax(unscaled_processed_lp_, x_current_, ax_current_);
437+
std::vector<double> ax_original(original_lp_->num_row_, 0.0);
438+
439+
// Get original matrix in column-wise format
440+
HighsSparseMatrix orig_matrix = original_lp_->a_matrix_;
441+
orig_matrix.ensureColwise();
442+
443+
// Compute Ax using only the original columns (not slack variables)
444+
for (int col = 0; col < original_num_col_; ++col) {
445+
double x_val = x_current_[col]; // Use unscaled x values
446+
447+
for (int el = orig_matrix.start_[col];
448+
el < orig_matrix.start_[col + 1]; ++el) {
449+
int row = orig_matrix.index_[el];
450+
double a_val = orig_matrix.value_[el];
451+
ax_original[row] += a_val * x_val;
452+
}
453+
}
438454

439-
int slack_variable_idx = original_num_col_;
455+
// Now ax_original contains the correct row activity values
440456
for (int orig_row = 0; orig_row < original_lp_->num_row_; ++orig_row) {
441-
int reordered_row = constraint_new_idx_[orig_row];
442-
443-
if (constraint_types_[orig_row] == BOUND ||
444-
constraint_types_[orig_row] == FREE) {
445-
solution.row_value[orig_row] = x_current_[slack_variable_idx++];
446-
} else if (constraint_types_[orig_row] == LEQ) {
447-
solution.row_value[orig_row] = -ax_current_[reordered_row];
448-
} else { // EQ, GEQ
449-
solution.row_value[orig_row] = ax_current_[reordered_row];
450-
}
457+
solution.row_value[orig_row] = ax_original[orig_row];
451458
}
452459

453460
// 6. Recover Dual Column Values (Reduced Costs)
@@ -461,6 +468,7 @@ PostSolveRetcode PDLPSolver::postprocess(HighsSolution& solution) {
461468
return PostSolveRetcode::DIMENSION_MISMATCH;
462469
}
463470
solution.col_dual[i] = dSlackPos_[i] - dSlackNeg_[i];
471+
solution.col_dual[i] *= sense_origin_;
464472
}
465473

466474
solution.value_valid = true; // to do
@@ -635,8 +643,12 @@ void PDLPSolver::solve(std::vector<double>& x, std::vector<double>& y) {
635643

636644
restart_scheme_.last_restart_iter_ = iter;
637645
// Recompute Ax and ATy for the restarted iterates
646+
hipdlpTimerStart(kHipdlpClockMatrixMultiply);
638647
linalg::Ax(lp, x_current_, Ax_cache_);
648+
hipdlpTimerStop(kHipdlpClockMatrixMultiply);
649+
hipdlpTimerStart(kHipdlpClockMatrixTransposeMultiply);
639650
linalg::ATy(lp, y_current_, ATy_cache_);
651+
hipdlpTimerStop(kHipdlpClockMatrixTransposeMultiply);
640652

641653
restart_scheme_.SetLastRestartIter(iter);
642654
}
@@ -679,9 +691,12 @@ void PDLPSolver::solve(std::vector<double>& x, std::vector<double>& y) {
679691

680692
// Compute ATy for the new iterate
681693
Ax_cache_ = Ax_next_;
694+
/*
682695
hipdlpTimerStart(kHipdlpClockMatrixTransposeMultiply);
683696
linalg::ATy(lp, y_next_, ATy_cache_);
684697
hipdlpTimerStop(kHipdlpClockMatrixTransposeMultiply);
698+
*/
699+
ATy_cache_ = ATy_next_;
685700

686701
hipdlpTimerStop(kHipdlpClockIterateUpdate);
687702

@@ -866,16 +881,23 @@ void PDLPSolver::computeDualSlacks(const std::vector<double>& ATy_vector) {
866881
if (dSlackNeg_.size() != lp_.num_col_) dSlackNeg_.resize(lp_.num_col_);
867882

868883
for (HighsInt i = 0; i < lp_.num_col_; ++i) {
869-
double reduced_cost = lp_.col_cost_[i] - ATy_vector[i];
870-
871-
// Slack for lower bound l_i <= x_i (dual variable is non-negative)
872-
dSlackPos_[i] =
873-
(lp_.col_lower_[i] > -kHighsInf) ? std::max(0.0, reduced_cost) : 0.0;
884+
double dual_residual = lp_.col_cost_[i] - ATy_vector[i];
874885

875-
// Slack for upper bound x_i <= u_i (dual variable is non-positive, so slack
876-
// is non-negative)
877-
dSlackNeg_[i] =
878-
(lp_.col_upper_[i] < kHighsInf) ? std::max(0.0, -reduced_cost) : 0.0;
886+
// Compute positive slack (for lower bounds)
887+
// CUPDLP: max(dual_residual, 0) * hasLower
888+
if (lp_.col_lower_[i] > -kHighsInf) {
889+
dSlackPos_[i] = std::max(0.0, dual_residual);
890+
} else {
891+
dSlackPos_[i] = 0.0;
892+
}
893+
894+
// Compute negative slack (for upper bounds)
895+
// CUPDLP: -min(dual_residual, 0) * hasUpper
896+
if (lp_.col_upper_[i] < kHighsInf) {
897+
dSlackNeg_[i] = std::max(0.0, -dual_residual);
898+
} else {
899+
dSlackNeg_[i] = 0.0;
900+
}
879901
}
880902
}
881903

@@ -1239,7 +1261,6 @@ void PDLPSolver::setup(const HighsOptions& options, HighsTimer& timer) {
12391261
restart_scheme_.passParams(&params_);
12401262
// Copy what's needed to use HiGHS logging
12411263
params_.log_options_ = options.log_options;
1242-
12431264
// log the options
12441265
logger_.print_params(params_);
12451266
}
@@ -1249,9 +1270,6 @@ void PDLPSolver::scaleProblem() {
12491270
scaling_.passParams(&params_);
12501271
scaling_.Initialize(lp_);
12511272
scaling_.scaleProblem();
1252-
//print the norm of lp_.col_cost_
1253-
unscaled_c_norm_ = linalg::vector_norm(lp_.col_cost_);
1254-
std::cout << "Unscaled cost norm = " << unscaled_c_norm_ << std::endl;
12551273
}
12561274

12571275
void PDLPSolver::unscaleSolution(std::vector<double>& x,
@@ -1264,8 +1282,10 @@ void PDLPSolver::unscaleSolution(std::vector<double>& x,
12641282
const std::vector<double>& col_scale = scaling_.GetColScaling();
12651283
if (!dSlackPos_.empty() && col_scale.size() == dSlackPos_.size()) {
12661284
for (size_t i = 0; i < dSlackPos_.size(); ++i) {
1267-
dSlackPos_[i] /= col_scale[i];
1268-
dSlackNeg_[i] /= col_scale[i];
1285+
std::cout << "dSlackPos_ before unscale[" << i << "] = " << dSlackPos_[i]
1286+
<< std::endl;
1287+
dSlackPos_[i] *= col_scale[i];
1288+
dSlackNeg_[i] *= col_scale[i];
12691289
}
12701290
}
12711291
}
@@ -1403,6 +1423,10 @@ void PDLPSolver::updateIteratesFixed() {
14031423
hipdlpTimerStart(kHipdlpClockProjectY);
14041424
y_next_ = updateY(y_current_, Ax_cache_, Ax_next_, stepsize_.dual_step);
14051425
hipdlpTimerStop(kHipdlpClockProjectY);
1426+
1427+
hipdlpTimerStart(kHipdlpClockMatrixTransposeMultiply);
1428+
linalg::ATy(lp_, y_next_, ATy_next_);
1429+
hipdlpTimerStop(kHipdlpClockMatrixTransposeMultiply);
14061430
}
14071431

14081432
void PDLPSolver::updateIteratesAdaptive() {

highs/pdlp/hipdlp/pdhg.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ class PDLPSolver {
121121
std::vector<bool> is_equality_row_;
122122
std::vector<int> constraint_new_idx_;
123123
std::vector<ConstraintType> constraint_types_;
124+
int sense_origin_ = 1;
124125

125126
// --- Solver State ---
126127
int final_iter_count_ = 0;

0 commit comments

Comments
 (0)