Skip to content

Commit 4f5e8fd

Browse files
committed
restore residual check in initialization and clean up code related to initial point
Signed-off-by: YUWEN Chen <yuwchen@nvidia.com>
1 parent d6b9166 commit 4f5e8fd

4 files changed

Lines changed: 54 additions & 54 deletions

File tree

cpp/include/cuopt/mathematical_optimization/utilities/internals.hpp

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -142,20 +142,5 @@ enum presolver_t : int {
142142
PSLP = CUOPT_PRESOLVE_PSLP
143143
};
144144

145-
/**
146-
* @brief Barrier primal-dual initial-point strategy.
147-
*
148-
* Automatic: use Lustig-Marsten-Shanno for LP/QP; Sturm/SeDuMi mu-based point for conic problems.
149-
* LustigMarstenShanno: Mehrotra-style dual start (Lustig, Marsten, Shanno, SIAM J. Optim. 1992).
150-
* DualLeastSquares: solve augmented or ADAT dual least-squares system.
151-
* SedumiMu: Sturm/SeDuMi mu-based primal+dual point (no factorization).
152-
*/
153-
enum barrier_dual_initial_point_t : int {
154-
Automatic = CUOPT_BARRIER_DUAL_INITIAL_POINT_AUTOMATIC,
155-
LustigMarstenShanno = CUOPT_BARRIER_DUAL_INITIAL_POINT_LUSTIG_MARSTEN_SHANNO,
156-
DualLeastSquares = CUOPT_BARRIER_DUAL_INITIAL_POINT_DUAL_LEAST_SQUARES,
157-
SedumiMu = CUOPT_BARRIER_DUAL_INITIAL_POINT_SEDUMI_MU
158-
};
159-
160145
} // namespace mathematical_optimization
161146
} // namespace cuopt

cpp/src/barrier/barrier.cu

Lines changed: 36 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
#include <dual_simplex/presolve.hpp>
2323
#include <dual_simplex/solve.hpp>
2424

25-
#include <cuopt/mathematical_optimization/utilities/internals.hpp>
2625
#include <linear_algebra/sparse_matrix.hpp>
2726
#include <math_optimization/tic_toc.hpp>
2827
#include <math_optimization/types.hpp>
@@ -2359,6 +2358,26 @@ int barrier_solver_t<i_t, f_t>::initial_point(iteration_data_t<i_t, f_t>& data)
23592358
}
23602359
}
23612360

2361+
// Verify A*x = b
2362+
dense_vector_t<i_t, f_t> init_primal_residual(lp.num_rows);
2363+
init_primal_residual = lp.rhs;
2364+
data.cusparse_view_.spmv(1.0, data.x, -1.0, init_primal_residual);
2365+
data.handle_ptr->get_stream().synchronize();
2366+
#ifdef PRINT_INFO
2367+
settings.log.printf("||b - A * x||: %.16e\n", vector_norm2<i_t, f_t>(init_primal_residual));
2368+
#endif
2369+
2370+
if (data.n_upper_bounds > 0) {
2371+
dense_vector_t<i_t, f_t> init_bound_residual(data.n_upper_bounds);
2372+
for (i_t k = 0; k < data.n_upper_bounds; k++) {
2373+
i_t j = data.upper_bounds[k];
2374+
init_bound_residual[k] = lp.upper[j] - data.w[k] - data.x[j];
2375+
}
2376+
#ifdef PRINT_INFO
2377+
settings.log.printf("|| u - w - x||: %e\n", vector_norm2<i_t, f_t>(init_bound_residual));
2378+
#endif
2379+
}
2380+
23622381
float64_t epsilon_adjust = 10.0;
23632382
// Push entries into interior of nonnegative orthant and SOC.
23642383
const bool has_soc = data.has_cones();
@@ -2467,6 +2486,22 @@ int barrier_solver_t<i_t, f_t>::initial_point(iteration_data_t<i_t, f_t>& data)
24672486
data.v.ensure_positive(epsilon_adjust);
24682487
}
24692488

2489+
// Verify A'*y + z - E*v - Q*x = c
2490+
dense_vector_t<i_t, f_t> init_dual_residual(lp.num_cols);
2491+
data.z.pairwise_subtract(data.c, init_dual_residual);
2492+
if (data.Q.n > 0) { matrix_vector_multiply(data.Q, -1.0, data.x, 1.0, init_dual_residual); }
2493+
data.cusparse_view_.transpose_spmv(1.0, data.y, 1.0, init_dual_residual);
2494+
if (data.n_upper_bounds > 0) {
2495+
for (i_t k = 0; k < data.n_upper_bounds; k++) {
2496+
i_t j = data.upper_bounds[k];
2497+
init_dual_residual[j] -= data.v[k];
2498+
}
2499+
}
2500+
#ifdef PRINT_INFO
2501+
settings.log.printf("||A^T y + z - E*v - Q*x - c ||: %e\n",
2502+
vector_norm2<i_t, f_t>(init_dual_residual));
2503+
#endif
2504+
24702505
// Make sure (w, x, v, z) > 0. Skip free variables being handled directly.
24712506
data.w.ensure_positive(epsilon_adjust);
24722507
std::vector<i_t> nonnegative_variables(data.x.size(), 1);
@@ -2487,43 +2522,6 @@ int barrier_solver_t<i_t, f_t>::initial_point(iteration_data_t<i_t, f_t>& data)
24872522
settings.log.printf("min v %e min z %e\n", data.v.minimum(), data.z.minimum());
24882523
#endif
24892524

2490-
// Residual checks below reflect the final initial point, after positivity shifts.
2491-
// Verify A*x = b
2492-
dense_vector_t<i_t, f_t> init_primal_residual(lp.num_rows);
2493-
init_primal_residual = lp.rhs;
2494-
data.cusparse_view_.spmv(1.0, data.x, -1.0, init_primal_residual);
2495-
data.handle_ptr->get_stream().synchronize();
2496-
#ifdef PRINT_INFO
2497-
settings.log.printf("||b - A * x||: %.16e\n", vector_norm2<i_t, f_t>(init_primal_residual));
2498-
#endif
2499-
2500-
if (data.n_upper_bounds > 0) {
2501-
dense_vector_t<i_t, f_t> init_bound_residual(data.n_upper_bounds);
2502-
for (i_t k = 0; k < data.n_upper_bounds; k++) {
2503-
i_t j = data.upper_bounds[k];
2504-
init_bound_residual[k] = lp.upper[j] - data.w[k] - data.x[j];
2505-
}
2506-
#ifdef PRINT_INFO
2507-
settings.log.printf("|| u - w - x||: %e\n", vector_norm2<i_t, f_t>(init_bound_residual));
2508-
#endif
2509-
}
2510-
2511-
// Verify A'*y + z - E*v - Q*x = c
2512-
dense_vector_t<i_t, f_t> init_dual_residual(lp.num_cols);
2513-
data.z.pairwise_subtract(data.c, init_dual_residual);
2514-
if (data.Q.n > 0) { matrix_vector_multiply(data.Q, -1.0, data.x, 1.0, init_dual_residual); }
2515-
data.cusparse_view_.transpose_spmv(1.0, data.y, 1.0, init_dual_residual);
2516-
if (data.n_upper_bounds > 0) {
2517-
for (i_t k = 0; k < data.n_upper_bounds; k++) {
2518-
i_t j = data.upper_bounds[k];
2519-
init_dual_residual[j] -= data.v[k];
2520-
}
2521-
}
2522-
#ifdef PRINT_INFO
2523-
settings.log.printf("||A^T y + z - E*v - Q*x - c ||: %e\n",
2524-
vector_norm2<i_t, f_t>(init_dual_residual));
2525-
#endif
2526-
25272525
return 0;
25282526
}
25292527

cpp/src/barrier/barrier.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include <linear_algebra/dense_vector.hpp>
1010

11+
#include <cuopt/mathematical_optimization/constants.h>
1112
#include <dual_simplex/presolve.hpp>
1213
#include <dual_simplex/simplex_solver_settings.hpp>
1314
#include <dual_simplex/solution.hpp>
@@ -18,6 +19,21 @@
1819
#include <rmm/device_uvector.hpp>
1920
namespace cuopt::mathematical_optimization::barrier {
2021

22+
/**
23+
* @brief Barrier primal-dual initial-point strategy.
24+
*
25+
* Automatic: use Lustig-Marsten-Shanno for LP/QP; Sturm/SeDuMi mu-based point for conic problems.
26+
* LustigMarstenShanno: Mehrotra-style dual start (Lustig, Marsten, Shanno, SIAM J. Optim. 1992).
27+
* DualLeastSquares: solve augmented or ADAT dual least-squares system.
28+
* SedumiMu: Sturm/SeDuMi mu-based primal+dual point (no factorization).
29+
*/
30+
enum barrier_dual_initial_point_t : int {
31+
Automatic = CUOPT_BARRIER_DUAL_INITIAL_POINT_AUTOMATIC,
32+
LustigMarstenShanno = CUOPT_BARRIER_DUAL_INITIAL_POINT_LUSTIG_MARSTEN_SHANNO,
33+
DualLeastSquares = CUOPT_BARRIER_DUAL_INITIAL_POINT_DUAL_LEAST_SQUARES,
34+
SedumiMu = CUOPT_BARRIER_DUAL_INITIAL_POINT_SEDUMI_MU
35+
};
36+
2137
/** Validates SOC layout on an simplex::lp_problem_t before barrier presolve/solve. */
2238
template <typename i_t, typename f_t>
2339
bool validate_barrier_cone_layout(const simplex::lp_problem_t<i_t, f_t>& problem,

cpp/src/dual_simplex/simplex_solver_settings.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ struct simplex_solver_settings_t {
167167
i_t augmented; // -1 automatic, 0 to solve with ADAT, 1 to solve with augmented system
168168
i_t dualize; // -1 automatic, 0 to not dualize, 1 to dualize
169169
i_t ordering; // -1 automatic, 0 to use nested dissection, 1 to use AMD
170-
i_t barrier_dual_initial_point; // barrier_dual_initial_point_t; see internals.hpp
170+
i_t barrier_dual_initial_point; // -1 automatic, 0 Lustig-Marsten-Shanno,
171+
// 1 dual least squares, 2 SeDuMi mu-based
171172
bool check_Q; // true to check if Q is positive semidefinite
172173
bool crossover; // true to do crossover, false to not
173174
i_t refactor_frequency; // number of basis updates before refactorization

0 commit comments

Comments
 (0)