Skip to content

Commit 9ba4534

Browse files
committed
Added HiPdlpTimer.h
1 parent 43964d1 commit 9ba4534

File tree

5 files changed

+96
-2
lines changed

5 files changed

+96
-2
lines changed

check/TestPdlp.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,3 +390,23 @@ TEST_CASE("hi-pdlp", "[pdlp]") {
390390
}
391391
h.resetGlobalScheduler(true);
392392
}
393+
394+
TEST_CASE("hi-pdlp-timer", "[pdlp]") {
395+
std::string model = "adlittle";
396+
std::string model_file =
397+
std::string(HIGHS_DIR) + "/check/instances/" + model + ".mps";
398+
Highs h;
399+
// h.setOptionValue("output_flag", dev_run);
400+
REQUIRE(h.readModel(model_file) == HighsStatus::kOk);
401+
REQUIRE(h.setOptionValue("solver", kHiPdlpString) == HighsStatus::kOk);
402+
HighsInt pdlp_features_off =
403+
//kPdlpScalingOff +
404+
//kPdlpRestartOff
405+
kPdlpAdaptiveStepSizeOff
406+
;
407+
h.setOptionValue("pdlp_features_off", pdlp_features_off);
408+
HighsStatus run_status = h.run();
409+
h.resetGlobalScheduler(true);
410+
411+
}
412+

cmake/sources.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@ set(highs_headers
459459
parallel/HighsTask.h
460460
parallel/HighsTaskExecutor.h
461461
pdlp/CupdlpWrapper.h
462+
pdlp/HiPdlpTimer.h
462463
pdlp/HiPdlpWrapper.h
463464
pdlp/hipdlp/defs.hpp
464465
pdlp/hipdlp/linalg.hpp

highs/pdlp/HiPdlpWrapper.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ HighsStatus solveLpHiPdlp(const HighsOptions& options, HighsTimer& timer,
7777
debugPdlpFinalSolutionLog(pdlp.debug_pdlp_log_file_,
7878
pdlp_solution.col_value.data(), lp.num_col_,
7979
pdlp_solution.row_dual.data(), lp.num_row_);
80+
pdlp.reportHipdlpTimer();
81+
8082
pdlp.solveReturn();
8183
// --- Print Summary ---
8284
pdlp.logSummary();

highs/pdlp/hipdlp/pdhg.cc

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ void PDLPSolver::printConstraintInfo() {
143143
}
144144

145145
void PDLPSolver::preprocessLp() {
146+
hipdlpTimerStart(kHipdlpClockPreprocess);
146147
logger_.info(
147148
"Preprocessing LP using cupdlp formulation (slack variables for "
148149
"bounds)...");
@@ -337,11 +338,13 @@ void PDLPSolver::preprocessLp() {
337338
", ||b|| = " + std::to_string(unscaled_rhs_norm_));
338339

339340
printConstraintInfo();
341+
hipdlpTimerStop(kHipdlpClockPreprocess);
340342
}
341343

342344
PostSolveRetcode PDLPSolver::postprocess(HighsSolution& solution) {
343345
logger_.info("Post-solving the solution...");
344346

347+
hipdlpTimerStart(kHipdlpClockPostprocess);
345348
if (original_lp_ == nullptr) {
346349
return PostSolveRetcode::DIMENSION_MISMATCH;
347350
}
@@ -456,10 +459,12 @@ PostSolveRetcode PDLPSolver::postprocess(HighsSolution& solution) {
456459
solution.dual_valid = true;
457460
logger_.info("Post-solve complete.");
458461

462+
hipdlpTimerStop(kHipdlpClockPostprocess);
459463
return PostSolveRetcode::OK;
460464
}
461465

462466
void PDLPSolver::solve(std::vector<double>& x, std::vector<double>& y) {
467+
hipdlpTimerStart(kHipdlpClockSolve);
463468
auto solve_start = std::chrono::high_resolution_clock::now();
464469
Timer solver_timer;
465470
const HighsLp& lp = lp_;
@@ -534,6 +539,7 @@ void PDLPSolver::solve(std::vector<double>& x, std::vector<double>& y) {
534539
logger_.info("Time limit reached.");
535540
final_iter_count_ = iter;
536541
results_.term_code = TerminationStatus::TIMEOUT;
542+
hipdlpTimerStop(kHipdlpClockSolve);
537543
return;
538544
}
539545

@@ -543,10 +549,12 @@ void PDLPSolver::solve(std::vector<double>& x, std::vector<double>& y) {
543549

544550
bool_checking = (bool_checking || iter % PDHG_CHECK_INTERVAL == 0);
545551
if (bool_checking) {
552+
hipdlpTimerStart(kHipdlpClockAverageIterate);
546553
auto avg_start = std::chrono::high_resolution_clock::now();
547554
ComputeAverageIterate(Ax_avg, ATy_avg);
548555
auto avg_end = std::chrono::high_resolution_clock::now();
549556
timings_.average_iterate_time += std::chrono::duration<double>(avg_end - avg_start).count();
557+
hipdlpTimerStop(kHipdlpClockAverageIterate);
550558

551559
// Reset the average iterate accumulation
552560
int inner_iter = iter - restart_scheme_.GetLastRestartIter();
@@ -582,6 +590,7 @@ void PDLPSolver::solve(std::vector<double>& x, std::vector<double>& y) {
582590
y = y_current_;
583591
results_ = current_results;
584592
results_.term_code = TerminationStatus::OPTIMAL;
593+
hipdlpTimerStop(kHipdlpClockSolve);
585594
return;
586595
}
587596

@@ -593,6 +602,7 @@ void PDLPSolver::solve(std::vector<double>& x, std::vector<double>& y) {
593602
y = y_avg_;
594603
results_ = average_results;
595604
results_.term_code = TerminationStatus::OPTIMAL;
605+
hipdlpTimerStop(kHipdlpClockSolve);
596606
return;
597607
}
598608

@@ -645,6 +655,7 @@ void PDLPSolver::solve(std::vector<double>& x, std::vector<double>& y) {
645655
}
646656

647657
// --- 5. Core PDHG Update Step ---
658+
hipdlpTimerStart(kHipdlpClockIterateUpdate);
648659
auto update_start = std::chrono::high_resolution_clock::now();
649660
bool step_success = true;
650661

@@ -675,6 +686,8 @@ void PDLPSolver::solve(std::vector<double>& x, std::vector<double>& y) {
675686
// Reset to average and terminate
676687
x = x_avg_;
677688
y = y_avg_;
689+
hipdlpTimerStop(kHipdlpClockIterateUpdate);
690+
hipdlpTimerStop(kHipdlpClockSolve);
678691
return;
679692
}
680693
}
@@ -683,19 +696,24 @@ void PDLPSolver::solve(std::vector<double>& x, std::vector<double>& y) {
683696

684697
// Compute ATy for the new iterate
685698
Ax_cache_ = Ax_next_;
699+
hipdlpTimerStart(kHipdlpClockMatrixTransposeMultiply);
686700
auto aty_start = std::chrono::high_resolution_clock::now();
687701
linalg::ATy(lp, y_next_, ATy_cache_);
688702
auto aty_end = std::chrono::high_resolution_clock::now();
689703
timings_.matrix_multiply_time += std::chrono::duration<double>(aty_end - aty_start).count();
704+
hipdlpTimerStop(kHipdlpClockMatrixTransposeMultiply);
690705

706+
hipdlpTimerStop(kHipdlpClockIterateUpdate);
691707

692708
// --- 6. Update Average Iterates ---
693709
// The number of iterations since the last restart
694710
int inner_iter = iter - restart_scheme_.GetLastRestartIter();
711+
hipdlpTimerStart(kHipdlpClockAverageIterate);
695712
auto avg_update_start = std::chrono::high_resolution_clock::now();
696713
UpdateAverageIterates(x_next_, y_next_, working_params, inner_iter);
697714
auto avg_update_end = std::chrono::high_resolution_clock::now();
698715
timings_.average_iterate_time += std::chrono::duration<double>(avg_update_end - avg_update_start).count();
716+
hipdlpTimerStop(kHipdlpClockAverageIterate);
699717

700718

701719
// --- 7. Prepare for next iteration ---
@@ -715,6 +733,7 @@ void PDLPSolver::solve(std::vector<double>& x, std::vector<double>& y) {
715733
results_.term_code = TerminationStatus::TIMEOUT;
716734
auto solve_end = std::chrono::high_resolution_clock::now();
717735
timings_.total_time = std::chrono::duration<double>(solve_end - solve_start).count();
736+
hipdlpTimerStop(kHipdlpClockSolve);
718737
return;
719738
}
720739

@@ -810,8 +829,15 @@ void PDLPSolver::ComputeAverageIterate(std::vector<double>& ax_avg,
810829
}
811830

812831
debug_pdlp_data_.x_average_norm = linalg::vector_norm_squared(x_avg_);
832+
833+
hipdlpTimerStart(kHipdlpClockAverageIterateMatrixMultiply);
813834
linalg::Ax(lp_, x_avg_, ax_avg);
835+
hipdlpTimerStop(kHipdlpClockAverageIterateMatrixMultiply);
836+
837+
hipdlpTimerStart(kHipdlpClockAverageIterateMatrixTransposeMultiply);
814838
linalg::ATy(lp_, y_avg_, aty_avg);
839+
hipdlpTimerStop(kHipdlpClockAverageIterateMatrixTransposeMultiply);
840+
815841
debug_pdlp_data_.ax_average_norm = linalg::vector_norm_squared(ax_avg);
816842
debug_pdlp_data_.aty_average_norm = linalg::vector_norm_squared(aty_avg);
817843
}
@@ -1178,6 +1204,9 @@ void PDLPSolver::setup(const HighsOptions& options, HighsTimer& timer) {
11781204
logger_.passHighsLogOptions(options.log_options);
11791205
logger_.print_header();
11801206

1207+
hipdlp_clocks_.timer_pointer_ = &timer;
1208+
hipdlp_timer_.initialiseHipdlpClocks(hipdlp_clocks_);
1209+
11811210
params_.initialise();
11821211
// params.eta = 0; Not set in parse_options_file
11831212
// params.omega = 0; Not set in parse_options_file
@@ -1381,23 +1410,31 @@ std::vector<double> PDLPSolver::UpdateY(const std::vector<double> &y, const std:
13811410
}
13821411

13831412
void PDLPSolver::UpdateIteratesFixed() {
1413+
hipdlpTimerStart(kHipdlpClockProjection);
13841414
auto proj_start = std::chrono::high_resolution_clock::now();
13851415
x_next_ = UpdateX(x_current_, ATy_cache_, stepsize_.primal_step);
13861416
auto proj_end = std::chrono::high_resolution_clock::now();
13871417
timings_.projection_time += std::chrono::duration<double>(proj_end - proj_start).count();
1418+
hipdlpTimerStop(kHipdlpClockProjection);
13881419

1420+
hipdlpTimerStart(kHipdlpClockMatrixMultiply);
13891421
auto ax_start = std::chrono::high_resolution_clock::now();
13901422
linalg::Ax(lp_, x_next_, Ax_next_);
13911423
auto ax_end = std::chrono::high_resolution_clock::now();
13921424
timings_.matrix_multiply_time += std::chrono::duration<double>(ax_end - ax_start).count();
1425+
hipdlpTimerStop(kHipdlpClockMatrixMultiply);
13931426

1427+
hipdlpTimerStart(kHipdlpClockProjection);
13941428
auto proj_y_start = std::chrono::high_resolution_clock::now();
13951429
y_next_ = UpdateY(y_current_, Ax_cache_, Ax_next_, stepsize_.dual_step);
13961430
auto proj_y_end = std::chrono::high_resolution_clock::now();
13971431
timings_.projection_time += std::chrono::duration<double>(proj_y_end - proj_y_start).count();
1432+
hipdlpTimerStop(kHipdlpClockProjection);
13981433
}
13991434

14001435
void PDLPSolver::UpdateIteratesAdaptive() {
1436+
hipdlpTimerStart(kHipdlpClockStepSizeAdjustment);
1437+
14011438
auto step_adjust_start = std::chrono::high_resolution_clock::now();
14021439
const double MIN_ETA = 1e-6;
14031440
const double MAX_ETA = 1.0;
@@ -1434,26 +1471,34 @@ void PDLPSolver::UpdateIteratesAdaptive() {
14341471
double dual_step_update = dStepSizeUpdate * std::sqrt(stepsize_.beta);
14351472

14361473
// Primal update
1474+
hipdlpTimerStart(kHipdlpClockProjection);
14371475
auto proj_start = std::chrono::high_resolution_clock::now();
14381476
xupdate = UpdateX(x_candidate, aty_candidate, primal_step_update);
14391477
auto proj_end = std::chrono::high_resolution_clock::now();
14401478
timings_.projection_time += std::chrono::duration<double>(proj_end - proj_start).count();
1441-
1479+
hipdlpTimerStop(kHipdlpClockProjection);
1480+
1481+
hipdlpTimerStart(kHipdlpClockMatrixMultiply);
14421482
auto ax_start = std::chrono::high_resolution_clock::now();
14431483
linalg::Ax(lp_, xupdate, axupdate);
14441484
auto ax_end = std::chrono::high_resolution_clock::now();
14451485
timings_.matrix_multiply_time += std::chrono::duration<double>(ax_end - ax_start).count();
1486+
hipdlpTimerStop(kHipdlpClockMatrixMultiply);
14461487

14471488
// Dual update with timing
1489+
hipdlpTimerStart(kHipdlpClockProjection);
14481490
auto proj_y_start = std::chrono::high_resolution_clock::now();
14491491
yupdate = UpdateY(y_candidate, ax_candidate, axupdate, dual_step_update);
14501492
auto proj_y_end = std::chrono::high_resolution_clock::now();
14511493
timings_.projection_time += std::chrono::duration<double>(proj_y_end - proj_y_start).count();
1494+
hipdlpTimerStop(kHipdlpClockProjection);
14521495

1496+
hipdlpTimerStart(kHipdlpClockMatrixTransposeMultiply);
14531497
auto aty_start = std::chrono::high_resolution_clock::now();
14541498
linalg::ATy(lp_, yupdate, atyupdate);
14551499
auto aty_end = std::chrono::high_resolution_clock::now();
14561500
timings_.matrix_multiply_time += std::chrono::duration<double>(aty_end - aty_start).count();
1501+
hipdlpTimerStop(kHipdlpClockMatrixTransposeMultiply);
14571502

14581503
// Compute deltas
14591504
std::vector<double> delta_x(lp_.num_col_);
@@ -1531,6 +1576,7 @@ void PDLPSolver::UpdateIteratesAdaptive() {
15311576

15321577
auto step_adjust_end = std::chrono::high_resolution_clock::now();
15331578
timings_.step_size_adjustment_time += std::chrono::duration<double>(step_adjust_end - step_adjust_start).count();
1579+
hipdlpTimerStop(kHipdlpClockStepSizeAdjustment);
15341580
}
15351581

15361582
bool PDLPSolver::UpdateIteratesMalitskyPock(
@@ -1588,3 +1634,20 @@ double PDLPSolver::ComputeNonlinearity(const std::vector<double>& delta_primal,
15881634
return nonlinearity; // cupdlp does not take absolute value
15891635
}
15901636

1637+
void PDLPSolver::reportHipdlpTimer() {
1638+
hipdlp_timer_.reportHipdlpCoreClock(hipdlp_clocks_);
1639+
hipdlp_timer_.reportHipdlpSolveClock(hipdlp_clocks_);
1640+
hipdlp_timer_.reportHipdlpIterateUpdateClock(hipdlp_clocks_);
1641+
hipdlp_timer_.reportHipdlpAverageIterateClock(hipdlp_clocks_);
1642+
hipdlp_timer_.reportHipdlpMatrixMultiplyClock(hipdlp_clocks_);
1643+
}
1644+
1645+
void PDLPSolver::hipdlpTimerStart(const HighsInt hipdlp_clock) {
1646+
HighsInt highs_timer_clock = hipdlp_clocks_.clock_[hipdlp_clock];
1647+
hipdlp_clocks_.timer_pointer_->start(highs_timer_clock);
1648+
}
1649+
1650+
void PDLPSolver::hipdlpTimerStop(const HighsInt hipdlp_clock) {
1651+
HighsInt highs_timer_clock = hipdlp_clocks_.clock_[hipdlp_clock];
1652+
hipdlp_clocks_.timer_pointer_->stop(highs_timer_clock);
1653+
}

highs/pdlp/hipdlp/pdhg.hpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <vector>
2121

2222
#include "Highs.h"
23+
#include "pdlp/HiPdlpTimer.h"
2324
#include "linalg.hpp"
2425
#include "logger.hpp"
2526
#include "restart.hpp"
@@ -54,6 +55,8 @@ class PDLPSolver {
5455
DetailedTimings timings_;
5556
const DetailedTimings& getTimings() const { return timings_; }
5657

58+
void reportHipdlpTimer();
59+
5760
private:
5861
// --- Core Algorithm Logic ---
5962
void Initialize();
@@ -99,6 +102,8 @@ class PDLPSolver {
99102
const std::vector<double>& x, const std::vector<double>& y,
100103
const std::vector<double>& lambda);
101104
void PDHG_Compute_Step_Size_Ratio(PrimalDualParams& working_params);
105+
void hipdlpTimerStart(const HighsInt hipdlp_clock);
106+
void hipdlpTimerStop(const HighsInt hipdlp_clock);
102107

103108
// --- Problem Data and Parameters ---
104109
HighsLp lp_;
@@ -129,6 +134,9 @@ class PDLPSolver {
129134
std::vector<double> dSlackNeg_;
130135
Timer total_timer;
131136

137+
HipdlpTimer hipdlp_timer_;
138+
HighsTimerClock hipdlp_clocks_;
139+
132140
// --- Scaling ---
133141
Scaling scaling_;
134142
double unscaled_rhs_norm_ = 0.0;
@@ -146,4 +154,4 @@ class PDLPSolver {
146154
std::vector<double> K_times_x_diff_;
147155
};
148156

149-
#endif
157+
#endif

0 commit comments

Comments
 (0)