@@ -645,7 +645,6 @@ if (DEBUG_MODE){
645645 }
646646
647647 CUDA_CHECK (cudaGraphLaunch (graphExec, gpu_stream_));
648- CUDA_CHECK (cudaStreamSynchronize (gpu_stream_));
649648#else
650649 for (int i = 2 ; i <= PDHG_CHECK_INTERVAL - 1 ; i++) {
651650 performHalpernPdhgStep (false , i);
@@ -1362,7 +1361,8 @@ double PDLPSolver::computePrimalFeasibility(
13621361 }
13631362 }
13641363
1365- return linalg::vectorNorm (primal_residual);
1364+ return linalg::vectorNorm (primal_residual) /
1365+ scaling_.getConstraintBoundScaling ();
13661366}
13671367
13681368void PDLPSolver::computeDualSlacks (const std::vector<double >& dualResidual,
@@ -1448,7 +1448,8 @@ double PDLPSolver::computeDualFeasibility(const std::vector<double>& ATy_vector,
14481448 }
14491449 }
14501450
1451- double dual_feasibility = linalg::vectorNorm (dual_residual);
1451+ double dual_feasibility = linalg::vectorNorm (dual_residual) /
1452+ scaling_.getObjectiveVectorScaling ();
14521453
14531454 return dual_feasibility;
14541455}
@@ -1493,7 +1494,7 @@ PDLPSolver::computeDualityGap(const std::vector<double>& x,
14931494double PDLPSolver::computeDualObjective (const std::vector<double >& y,
14941495 const std::vector<double >& dSlackPos,
14951496 const std::vector<double >& dSlackNeg) {
1496- double dual_obj = lp_. offset_ ;
1497+ double dual_obj = 0.0 ;
14971498
14981499 // Compute b'y (or rhs'y in cuPDLP notation)
14991500 for (HighsInt i = 0 ; i < lp_.num_row_ ; ++i) {
@@ -1514,7 +1515,10 @@ double PDLPSolver::computeDualObjective(const std::vector<double>& y,
15141515 }
15151516 }
15161517
1517- return dual_obj;
1518+ return dual_obj /
1519+ (scaling_.getConstraintBoundScaling () *
1520+ scaling_.getObjectiveVectorScaling ()) +
1521+ lp_.offset_ ;
15181522}
15191523
15201524bool PDLPSolver::checkConvergence (
@@ -1537,27 +1541,31 @@ bool PDLPSolver::checkConvergence(
15371541 results.dual_feasibility = dual_feasibility;
15381542
15391543 // Compute objectives
1540- double primal_obj = lp_. offset_ ;
1544+ double primal_obj = 0.0 ;
15411545 for (HighsInt i = 0 ; i < lp_.num_col_ ; ++i) {
15421546 primal_obj += lp_.col_cost_ [i] * x[i];
15431547 }
1544- results.primal_obj = primal_obj;
1548+ primal_obj /=
1549+ scaling_.getConstraintBoundScaling () *
1550+ scaling_.getObjectiveVectorScaling ();
1551+ results.primal_obj = primal_obj + lp_.offset_ ;
15451552
15461553 // Pass the now-populated slack vectors to computeDualObjective
15471554 double dual_obj = computeDualObjective (y, dSlackPos, dSlackNeg);
15481555 results.dual_obj = dual_obj;
15491556
15501557 // Compute duality gap
1551- double duality_gap = primal_obj - dual_obj;
1558+ double duality_gap = results. primal_obj - dual_obj;
15521559 results.duality_gap = std::abs (duality_gap);
15531560
15541561 // Compute relative gap (matching cuPDLP formula)
15551562 double relative_obj_gap =
1556- std::abs (duality_gap) / (1.0 + std::abs (primal_obj) + std::abs (dual_obj));
1563+ std::abs (duality_gap) /
1564+ (1.0 + std::abs (results.primal_obj ) + std::abs (dual_obj));
15571565 results.relative_obj_gap = relative_obj_gap;
15581566
15591567#if PDLP_DEBUG_LOG
1560- debugPdlpFeasOptLog (debug_pdlp_log_file_, iter, primal_obj, dual_obj,
1568+ debugPdlpFeasOptLog (debug_pdlp_log_file_, iter, results. primal_obj , dual_obj,
15611569 relative_obj_gap,
15621570 primal_feasibility / (1.0 + unscaled_rhs_norm_),
15631571 dual_feasibility / (1.0 + unscaled_c_norm_), type);
@@ -1936,10 +1944,11 @@ void PDLPSolver::unscaleSolution(std::vector<double>& x,
19361944 y_current_ = y;
19371945
19381946 const std::vector<double >& col_scale = scaling_.getColScaling ();
1947+ const double objective_scale = scaling_.getObjectiveVectorScaling ();
19391948 if (!dSlackPos_.empty () && col_scale.size () == dSlackPos_.size ()) {
19401949 for (size_t i = 0 ; i < dSlackPos_.size (); ++i) {
1941- dSlackPos_[i] *= col_scale[i];
1942- dSlackNeg_[i] *= col_scale[i];
1950+ dSlackPos_[i] *= col_scale[i] / objective_scale ;
1951+ dSlackNeg_[i] *= col_scale[i] / objective_scale ;
19431952 }
19441953 }
19451954}
@@ -1994,7 +2003,7 @@ void PDLPSolver::initializeStepSizes() {
19942003 best_primal_weight_ = primal_weight_;
19952004 stepsize_.beta = primal_weight_ * primal_weight_;
19962005 params_.omega = primal_weight_;
1997-
2006+
19982007 if (params_.step_size_strategy != StepSizeStrategy::FIXED &&
19992008 params_.step_size_strategy != StepSizeStrategy::PID) {
20002009 logger_.info (
@@ -2828,13 +2837,16 @@ bool PDLPSolver::checkConvergenceGpu(const HighsInt iter, const double* d_x,
28282837 cudaMemcpyDeviceToHost, gpu_stream_));
28292838 CUDA_CHECK (cudaStreamSynchronize (gpu_stream_));
28302839
2840+ const double constraint_scale = scaling_.getConstraintBoundScaling ();
2841+ const double objective_scale = scaling_.getObjectiveVectorScaling ();
2842+ const double combined_scale = constraint_scale * objective_scale;
28312843 double primal_feas_sq = h_results[0 ];
28322844 double dual_feas_sq = h_results[1 ];
2833- double primal_obj = h_results[2 ] + lp_.offset_ ;
2834- double dual_obj = h_results[3 ] + lp_.offset_ ;
2845+ double primal_obj = h_results[2 ] / combined_scale + lp_.offset_ ;
2846+ double dual_obj = h_results[3 ] / combined_scale + lp_.offset_ ;
28352847
2836- results.primal_feasibility = std::sqrt (primal_feas_sq);
2837- results.dual_feasibility = std::sqrt (dual_feas_sq);
2848+ results.primal_feasibility = std::sqrt (primal_feas_sq) / constraint_scale ;
2849+ results.dual_feasibility = std::sqrt (dual_feas_sq) / objective_scale ;
28382850 results.primal_obj = primal_obj;
28392851 results.dual_obj = dual_obj;
28402852
0 commit comments