Skip to content

Commit 9831690

Browse files
committed
Now included all necessary HiPDLP code, and commented out matrix preprocessing that's not c++11 compliant
1 parent 1631cde commit 9831690

File tree

15 files changed

+2374
-0
lines changed

15 files changed

+2374
-0
lines changed

cmake/sources-python.cmake

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,11 @@ set(highs_sources_python
238238
highs/pdlp/CupdlpWrapper.cpp
239239
highs/pdlp/HiPdlpWrapper.cpp
240240
highs/pdlp/hipdlp/linalg.cc
241+
highs/pdlp/hipdlp/logger.cc
242+
highs/pdlp/hipdlp/pdhg.cc
243+
highs/pdlp/hipdlp/restart.cc
244+
highs/pdlp/hipdlp/scaling.cc
245+
highs/pdlp/hipdlp/step.cc
241246
highs/presolve/HighsPostsolveStack.cpp
242247
highs/presolve/HighsSymmetry.cpp
243248
highs/presolve/HPresolve.cpp
@@ -369,6 +374,13 @@ set(highs_headers_python
369374
highs/parallel/HighsTaskExecutor.h
370375
highs/pdlp/CupdlpWrapper.h
371376
highs/pdlp/HiPdlpWrapper.h
377+
highs/pdlp/hipdlp/linalg.hpp
378+
highs/pdlp/hipdlp/logger.hpp
379+
highs/pdlp/hipdlp/pdhg.hpp
380+
highs/pdlp/hipdlp/restart.hpp
381+
highs/pdlp/hipdlp/scaling.hpp
382+
highs/pdlp/hipdlp/solver_results.hpp
383+
highs/pdlp/hipdlp/step.hpp
372384
highs/presolve/HighsPostsolveStack.h
373385
highs/presolve/HighsSymmetry.h
374386
highs/presolve/HPresolve.h

cmake/sources.cmake

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,11 @@ set(highs_sources
322322
pdlp/CupdlpWrapper.cpp
323323
pdlp/HiPdlpWrapper.cpp
324324
pdlp/hipdlp/linalg.cc
325+
pdlp/hipdlp/logger.cc
326+
pdlp/hipdlp/pdhg.cc
327+
pdlp/hipdlp/restart.cc
328+
pdlp/hipdlp/scaling.cc
329+
pdlp/hipdlp/step.cc
325330
presolve/HighsPostsolveStack.cpp
326331
presolve/HighsSymmetry.cpp
327332
presolve/HPresolve.cpp
@@ -456,6 +461,13 @@ set(highs_headers
456461
parallel/HighsTaskExecutor.h
457462
pdlp/CupdlpWrapper.h
458463
pdlp/HiPdlpWrapper.h
464+
pdlp/hipdlp/linalg.hpp
465+
pdlp/hipdlp/logger.hpp
466+
pdlp/hipdlp/pdhg.hpp
467+
pdlp/hipdlp/restart.hpp
468+
pdlp/hipdlp/scaling.hpp
469+
pdlp/hipdlp/solver_results.hpp
470+
pdlp/hipdlp/step.hpp
459471
presolve/HighsPostsolveStack.h
460472
presolve/HighsSymmetry.h
461473
presolve/HPresolve.h

highs/meson.build

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,12 @@ _srcs = [
254254
'parallel/HighsTaskExecutor.cpp',
255255
'pdlp/CupdlpWrapper.cpp',
256256
'pdlp/HiPdlpWrapper.cpp',
257+
'pdlp/hipdlp/linalg.cc',
258+
'pdlp/hipdlp/logger.cc',
259+
'pdlp/hipdlp/pdhg.cc',
260+
'pdlp/hipdlp/restart.cc',
261+
'pdlp/hipdlp/scaling.cc',
262+
'pdlp/hipdlp/step.cc',
257263
'presolve/HPresolve.cpp',
258264
'presolve/HPresolveAnalysis.cpp',
259265
'presolve/HighsPostsolveStack.cpp',

highs/pdlp/HiPdlpWrapper.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
* @author Julian Hall
1111
*/
1212
#include "pdlp/HiPdlpWrapper.h"
13+
#include "pdlp/hipdlp/restart.hpp"
14+
15+
void getHiPpdlpParamsFromOptions(const HighsOptions& options);
16+
1317
HighsStatus solveLpHiPdlp(HighsLpSolverObject& solver_object) {
1418
return solveLpHiPdlp(solver_object.options_, solver_object.timer_,
1519
solver_object.lp_, solver_object.basis_,
@@ -25,6 +29,49 @@ HighsStatus solveLpHiPdlp(const HighsOptions& options, HighsTimer& timer,
2529
// Indicate that no imprecise solution has (yet) been found
2630
resetModelStatusAndHighsInfo(model_status, highs_info);
2731

32+
33+
2834
return HighsStatus::kError;
2935
}
3036

37+
void getHiPpdlpParamsFromOptions(const HighsOptions& options, PrimalDualParams& params) {
38+
params.initialise();
39+
params.tolerance = 1e-4;
40+
params.max_iterations = 40000;
41+
}
42+
43+
void PrimalDualParams::initialise() {
44+
this->eta = 0 ;
45+
this->omega = 0;
46+
this->tolerance = 0;
47+
this->max_iterations = 0;
48+
this->device_type = Device::CPU;
49+
this->time_limit = 3600.0;
50+
this->restart_strategy = RestartStrategy::NO_RESTART;
51+
this->fixed_restart_interval = 0;
52+
this->use_halpern_restart = false;
53+
this->scaling_method = ScalingMethod::NONE;
54+
this->use_ruiz_scaling = false;
55+
this->use_pc_scaling = false;
56+
this->use_l2_scaling = false;
57+
this->ruiz_iterations = 10;
58+
this->ruiz_norm = INFINITY;
59+
this->pc_alpha = 1.0;
60+
this->step_size_strategy = StepSizeStrategy::FIXED;
61+
this->malitsky_pock_params.initialise();
62+
this->adaptive_linesearch_params.initialise();
63+
}
64+
65+
void MalitskyPockParams::initialise() {
66+
this->step_size_interpolation = 0.5; // Between 0 and 1
67+
this->step_size_downscaling_factor = 0.7;
68+
this->linesearch_contraction_factor = 0.99;
69+
}
70+
71+
72+
void AdaptiveLinesearchParams::initialise() {
73+
this->step_size_reduction_exponent = 0.3;
74+
this->step_size_growth_exponent = 0.6;
75+
}
76+
77+

highs/pdlp/hipdlp/logger.cc

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
#include "logger.hpp"
2+
#include <iostream>
3+
#include <sstream>
4+
#include <map>
5+
6+
// Helper to convert enums to strings for pretty printing
7+
template<typename T>
8+
std::string enum_to_string(T e, const std::map<T, std::string>& map) {
9+
auto it = map.find(e);
10+
return it != map.end() ? it->second : "UNKNOWN";
11+
}
12+
13+
// Timer implementation
14+
Timer::Timer() { reset(); }
15+
void Timer::reset() { start_time_ = std::chrono::high_resolution_clock::now(); }
16+
double Timer::read() {
17+
auto end_time = std::chrono::high_resolution_clock::now();
18+
std::chrono::duration<double> elapsed = end_time - start_time_;
19+
return elapsed.count();
20+
}
21+
22+
// Logger implementation
23+
Logger::Logger(LogLevel level) : console_level_(level) {}
24+
25+
void Logger::set_log_file(const std::string& filename) {
26+
log_file_.open(filename, std::ios::out | std::ios::trunc);
27+
if (!log_file_.is_open()) {
28+
std::cerr << "Error: Could not open log file: " << filename << std::endl;
29+
}
30+
}
31+
32+
void Logger::log(LogLevel level, const std::string& message) {
33+
if (level <= console_level_) {
34+
std::cout << message << std::endl;
35+
}
36+
if (log_file_.is_open()) {
37+
log_file_ << message << std::endl;
38+
}
39+
}
40+
41+
void Logger::info(const std::string& message) { log(LogLevel::kInfo, message); }
42+
void Logger::verbose(const std::string& message) { log(LogLevel::kVerbose, message); }
43+
void Logger::debug(const std::string& message) { log(LogLevel::kDebug, message); }
44+
45+
void Logger::print_header() {
46+
info("------------------------------------------------------------");
47+
info(" PDLP Solver - C++ Implementation ");
48+
info("------------------------------------------------------------");
49+
}
50+
51+
void Logger::print_params(const PrimalDualParams& params) {
52+
info("\nSolver Parameters:");
53+
std::stringstream ss;
54+
55+
std::map<RestartStrategy, std::string> restart_map = {{RestartStrategy::NO_RESTART, "None"}, {RestartStrategy::FIXED_RESTART, "Fixed"}, {RestartStrategy::ADAPTIVE_RESTART, "Adaptive"}};
56+
std::map<ScalingMethod, std::string> scaling_map = {{ScalingMethod::NONE, "None"}, {ScalingMethod::RUIZ, "Ruiz"}, {ScalingMethod::POCK_CHAMBOLLE, "Pock-Chambolle"}, {ScalingMethod::L2_NORM, "L2-Norm"}};
57+
std::map<StepSizeStrategy, std::string> step_size_map = {{StepSizeStrategy::FIXED, "Fixed"}, {StepSizeStrategy::ADAPTIVE, "Adaptive"}, {StepSizeStrategy::MALITSKY_POCK, "Malitsky-Pock"}};
58+
59+
ss << " - Max Iterations: " << params.max_iterations;
60+
info(ss.str()); ss.str("");
61+
ss << " - Tolerance: " << params.tolerance;
62+
info(ss.str()); ss.str("");
63+
ss << " - Restart Strategy: " << enum_to_string(params.restart_strategy, restart_map);
64+
info(ss.str()); ss.str("");
65+
ss << " - Scaling Method: " << enum_to_string(params.scaling_method, scaling_map);
66+
info(ss.str()); ss.str("");
67+
ss << " - Step Size Strategy: " << enum_to_string(params.step_size_strategy, step_size_map);
68+
info(ss.str());
69+
info("------------------------------------------------------------");
70+
}
71+
72+
void Logger::print_iteration_header() {
73+
verbose("\n-------------------------------------------------------------------------------------------------");
74+
verbose(" Iter | Primal Feas | Dual Feas | Duality Gap | Step Size");
75+
verbose("-------------------------------------------------------------------------------------------------");
76+
}
77+
78+
void Logger::print_iteration_stats(int iter, const SolverResults& results, double step_size) {
79+
std::stringstream ss;
80+
ss << std::fixed << std::setprecision(4)
81+
<< " " << std::setw(6) << iter << " | "
82+
<< std::scientific << std::setprecision(2)
83+
<< std::setw(11) << results.primal_feasibility << " | "
84+
<< std::setw(10) << results.dual_feasibility << " | "
85+
<< std::setw(11) << results.duality_gap << " | "
86+
<< std::fixed << std::setprecision(4)
87+
<< std::setw(9) << step_size;
88+
verbose(ss.str());
89+
}
90+
91+
void Logger::print_summary(const SolverResults& results, int total_iter, double total_time) {
92+
info("\n-------------------- Solver Summary --------------------");
93+
std::stringstream ss;
94+
95+
std::map<TerminationStatus, std::string> term_map = {{TerminationStatus::OPTIMAL, "Optimal"}, {TerminationStatus::TIMEOUT, "Timeout"}, {TerminationStatus::FEASIBLE, "Feasible"}};
96+
97+
ss << " - Termination Status: " << enum_to_string(results.term_code, term_map);
98+
info(ss.str()); ss.str("");
99+
ss << " - Total Iterations: " << total_iter;
100+
info(ss.str()); ss.str("");
101+
ss << " - Total Time: " << std::fixed << std::setprecision(3) << total_time << " seconds";
102+
info(ss.str()); ss.str("");
103+
ss << " - Final Primal Objective: " << std::scientific << std::setprecision(6) << results.primal_obj;
104+
info(ss.str()); ss.str("");
105+
ss << " - Final Duality Gap: " << std::scientific << std::setprecision(6) << results.duality_gap;
106+
info(ss.str()); ss.str("");
107+
ss << " - Final Primal Feasibility: " << std::scientific << std::setprecision(6) << results.primal_feasibility;
108+
info(ss.str()); ss.str("");
109+
ss << " - Final Dual Feasibility: " << std::scientific << std::setprecision(6) << results.dual_feasibility;
110+
info(ss.str());
111+
info("------------------------------------------------------------");
112+
}

highs/pdlp/hipdlp/logger.hpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* @Author: Zhou Yanyu(周妍妤) [email protected]
3+
* @Date: 2025-08-11 10:52:55
4+
* @LastEditors: Zhou Yanyu(周妍妤) [email protected]
5+
* @LastEditTime: 2025-08-11 10:53:02
6+
* @FilePath: /cupdlp-CPP/include/logger.hpp
7+
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
8+
*/
9+
#ifndef LOGGER_HPP
10+
#define LOGGER_HPP
11+
12+
#include <iostream>
13+
#include <fstream>
14+
#include <string>
15+
#include <chrono>
16+
#include <iomanip>
17+
#include <memory>
18+
#include "solver_results.hpp"
19+
#include "restart.hpp" // For PrimalDualParams
20+
21+
// Log verbosity level
22+
enum class LogLevel {
23+
kNone, // No output
24+
kInfo, // Standard output: summary, termination, major events
25+
kVerbose, // Detailed output: iteration-level info
26+
kDebug // Verbose + debug info for developers
27+
};
28+
29+
class Timer {
30+
public:
31+
Timer();
32+
void reset();
33+
double read();
34+
private:
35+
std::chrono::high_resolution_clock::time_point start_time_;
36+
};
37+
38+
class Logger {
39+
public:
40+
Logger(LogLevel level = LogLevel::kInfo);
41+
void set_log_file(const std::string& filename);
42+
43+
// Logging methods for different levels
44+
void info(const std::string& message);
45+
void verbose(const std::string& message);
46+
void debug(const std::string& message);
47+
48+
// Formatted printing functions
49+
void print_header();
50+
void print_params(const PrimalDualParams& params);
51+
void print_iteration_header();
52+
void print_iteration_stats(int iter, const SolverResults& current_results, double current_eta);
53+
void print_summary(const SolverResults& results, int total_iter, double total_time);
54+
55+
private:
56+
void log(LogLevel level, const std::string& message);
57+
LogLevel console_level_;
58+
std::ofstream log_file_;
59+
};
60+
61+
#endif // LOGGER_HPP

0 commit comments

Comments
 (0)