Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
7063060
fix(socp): canonicalize QC Q COO for rotated SOC detection (#1435)
yuwenchen95 Jun 15, 2026
5f0e06b
clarify require_symmetric_* for MPS symmetric-half input only, and tr…
yuwenchen95 Jun 16, 2026
9ff9b03
refactor(io): simplify QC COO canonicalization API and merge rules
yuwenchen95 Jun 17, 2026
b555adf
drop unused symmetric flag from canonicalize_quadratic_constraints
yuwenchen95 Jun 17, 2026
334bbb7
Move COO canonicalization into mps_parser; split QCMATRIX validation …
yuwenchen95 Jun 21, 2026
aa69c54
Add a python test to the problem in Issue 1435
yuwenchen95 Jun 21, 2026
3829701
Align the grpc data generation to the change of triplet form of quadr…
yuwenchen95 Jun 22, 2026
b9d16a3
Polish comment and tests
yuwenchen95 Jun 23, 2026
f15eac8
Replace the unordered_map-based QCMATRIX symmetry check and COO canon…
yuwenchen95 Jun 23, 2026
3912c48
Merge branch 'main' into fix-qcqp-canonical-coo
yuwenchen95 Jun 23, 2026
a516ff6
Update the guard of dimension for fast check of rotated socs and adju…
yuwenchen95 Jun 23, 2026
e17ede7
Polish comment and improve the sorting efficiency in canonicalization
yuwenchen95 Jun 25, 2026
5fcbcc6
Add automatic sorting selection for COO input format in canonicalization
yuwenchen95 Jun 29, 2026
c6fb7b1
Merge branch 'main' into fix-qcqp-canonical-coo
yuwenchen95 Jun 29, 2026
f1061c5
Merge branch 'main' into fix-qcqp-canonical-coo
yuwenchen95 Jun 29, 2026
a917131
Replace automatic_sort with the polished bucket sorting
yuwenchen95 Jul 1, 2026
afe9115
Merge branch 'main' into fix-qcqp-canonical-coo
yuwenchen95 Jul 2, 2026
7fdaf62
Merge branch 'main' into fix-qcqp-canonical-coo
yuwenchen95 Jul 3, 2026
470f170
Improving complexity of canonicalization by reusing workspace
yuwenchen95 Jul 3, 2026
fc12d4a
format update
yuwenchen95 Jul 3, 2026
0cdbfe1
code cleanup
yuwenchen95 Jul 7, 2026
fdc9601
code cleanup
yuwenchen95 Jul 7, 2026
6decb20
Hide reusable workspace class for all data input paths
yuwenchen95 Jul 7, 2026
4fa522b
Stylish fix
yuwenchen95 Jul 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#pragma once

#include <cuopt/mathematical_optimization/io/mps_data_model.hpp>
#include <cuopt/mathematical_optimization/optimization_problem_interface.hpp>

#include <raft/core/handle.hpp>
Expand Down Expand Up @@ -45,6 +46,11 @@ class cpu_optimization_problem_t : public optimization_problem_interface_t<i_t,
using typename optimization_problem_interface_t<i_t, f_t>::quadratic_constraint_t;

cpu_optimization_problem_t();
cpu_optimization_problem_t(const cpu_optimization_problem_t<i_t, f_t>& other);
cpu_optimization_problem_t(cpu_optimization_problem_t<i_t, f_t>&& other) noexcept;
cpu_optimization_problem_t& operator=(const cpu_optimization_problem_t<i_t, f_t>& other);
cpu_optimization_problem_t& operator=(cpu_optimization_problem_t<i_t, f_t>&& other) noexcept;
~cpu_optimization_problem_t();

// Setters
void set_maximize(bool maximize) override;
Expand Down Expand Up @@ -212,6 +218,8 @@ class cpu_optimization_problem_t : public optimization_problem_interface_t<i_t,
std::vector<f_t> Q_values_;

std::vector<quadratic_constraint_t> quadratic_constraints_{};
// Scratch storage reused across add_quadratic_constraint calls. Not thread-safe.
std::unique_ptr<io::coo_canonicalization_workspace_t<i_t, f_t>> qc_coo_workspace_;

std::vector<f_t> variable_lower_bounds_;
std::vector<f_t> variable_upper_bounds_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,19 @@

namespace cuopt::mathematical_optimization::io {

template <typename i_t, typename f_t>
class coo_canonicalization_workspace_t;

/**
* @brief Canonicalize a symmetric matrix in COO form to upper-triangular storage
* using reusable workspace storage.
*/
template <typename i_t, typename f_t>
void canonicalize_coo_matrix(std::vector<i_t>& rows,
Comment thread
yuwenchen95 marked this conversation as resolved.
std::vector<i_t>& cols,
std::vector<f_t>& vals,
coo_canonicalization_workspace_t<i_t, f_t>& workspace);

/**
* @brief A representation of a linear programming (LP) optimization problem
*
Expand Down Expand Up @@ -278,7 +291,8 @@ class mps_data_model_t {
f_t rhs_value,
std::span<const f_t> vals,
std::span<const i_t> rows,
std::span<const i_t> cols);
std::span<const i_t> cols,
coo_canonicalization_workspace_t<i_t, f_t>& workspace);

const std::vector<quadratic_constraint_t>& get_quadratic_constraints() const;

Expand Down Expand Up @@ -397,8 +411,7 @@ class mps_data_model_t {
*
* @param constraints Quadratic constraints whose rows, cols, and vals are updated.
*/
template <typename i_t, typename f_t>
void canonicalize_quadratic_constraints(
std::vector<typename mps_data_model_t<i_t, f_t>::quadratic_constraint_t>& constraints);
template <typename qc_t>
void canonicalize_quadratic_constraints(std::vector<qc_t>& constraints);

} // namespace cuopt::mathematical_optimization::io
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#pragma once

#include <cuopt/mathematical_optimization/io/mps_data_model.hpp>
#include <cuopt/mathematical_optimization/optimization_problem_interface.hpp>
#include <cuopt/mathematical_optimization/utilities/internals.hpp>

Expand Down Expand Up @@ -117,8 +118,9 @@ class optimization_problem_t : public optimization_problem_interface_t<i_t, f_t>

explicit optimization_problem_t(raft::handle_t const* handle_ptr);
optimization_problem_t(const optimization_problem_t<i_t, f_t>& other);
optimization_problem_t(optimization_problem_t<i_t, f_t>&&) noexcept = default;
optimization_problem_t& operator=(optimization_problem_t<i_t, f_t>&&) noexcept = default;
optimization_problem_t(optimization_problem_t<i_t, f_t>&& other) noexcept;
optimization_problem_t& operator=(optimization_problem_t<i_t, f_t>&& other) noexcept;
~optimization_problem_t();

std::vector<internals::base_solution_callback_t*> mip_callbacks_;

Expand Down Expand Up @@ -411,6 +413,8 @@ class optimization_problem_t : public optimization_problem_interface_t<i_t, f_t>

/** QCQP: quadratic constraints **/
std::vector<quadratic_constraint_t> quadratic_constraints_{};
// Scratch storage reused across add_quadratic_constraint calls. Not thread-safe.
std::unique_ptr<io::coo_canonicalization_workspace_t<i_t, f_t>> qc_coo_workspace_;

rmm::device_uvector<f_t> variable_lower_bounds_;
rmm::device_uvector<f_t> variable_upper_bounds_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ void populate_from_data_model_view(
// Raw Q COO from data_model_view is canonicalized here before solver storage.
if (data_model->has_quadratic_constraints()) {
auto qcs = data_model->get_quadratic_constraints();
io::canonicalize_quadratic_constraints<i_t, f_t>(qcs);
io::canonicalize_quadratic_constraints(qcs);
problem->set_quadratic_constraints(std::move(qcs));
}
}
Expand Down
12 changes: 6 additions & 6 deletions cpp/src/grpc/codegen/generate_conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2215,12 +2215,12 @@ def _gen_proto_to_problem(registry, indent=" "):
f'{b["name"]} size mismatch");'
)
lines.append(f"{ind} }}")
lines.append(f"{ind} _entries.push_back(std::move(_entry));")
lines.append(f"{ind} }}")
if name == "quadratic_constraints":
lines.append(
f"{ind} io::canonicalize_coo_matrix(_entry.rows, _entry.cols, _entry.vals);"
f"{ind} io::canonicalize_quadratic_constraints(_entries);"
)
lines.append(f"{ind} _entries.push_back(std::move(_entry));")
lines.append(f"{ind} }}")
lines.append(f"{ind} cpu_problem.{setter}(std::move(_entries));")
lines.append(f"{ind}}}")

Expand Down Expand Up @@ -2815,12 +2815,12 @@ def _gen_chunked_arrays_to_problem(registry, indent=" "):
f'{b["name"]} size mismatch");'
)
lines.append(f"{ind} }}")
lines.append(f"{ind} _entries.push_back(std::move(_entry));")
lines.append(f"{ind} }}")
if name == "quadratic_constraints":
lines.append(
f"{ind} io::canonicalize_coo_matrix(_entry.rows, _entry.cols, _entry.vals);"
f"{ind} io::canonicalize_quadratic_constraints(_entries);"
)
lines.append(f"{ind} _entries.push_back(std::move(_entry));")
lines.append(f"{ind} }}")
lines.append(f"{ind} cpu_problem.{setter}(std::move(_entries));")
lines.append(f"{ind}}}")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,8 @@
if (_entry.cols.size() != _entry.vals.size()) {
throw std::invalid_argument("set_quadratic_constraints: cols/vals size mismatch");
}
io::canonicalize_coo_matrix(_entry.rows, _entry.cols, _entry.vals);
_entries.push_back(std::move(_entry));
}
io::canonicalize_quadratic_constraints(_entries);
cpu_problem.set_quadratic_constraints(std::move(_entries));
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@
if (_entry.cols.size() != _entry.vals.size()) {
throw std::invalid_argument("set_quadratic_constraints: cols/vals size mismatch");
}
io::canonicalize_coo_matrix(_entry.rows, _entry.cols, _entry.vals);
_entries.push_back(std::move(_entry));
}
io::canonicalize_quadratic_constraints(_entries);
cpu_problem.set_quadratic_constraints(std::move(_entries));
}
5 changes: 4 additions & 1 deletion cpp/src/io/lp_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include <file_to_string.hpp>
#include <lp_parser.hpp>
#include <mps_parser_internal.hpp>
#include <utilities/error.hpp>

#include <algorithm>
Expand Down Expand Up @@ -1471,6 +1472,7 @@ void flush_quadratic_constraints(mps_data_model_t<i_t, f_t>& problem,
const lp_parser_t<i_t, f_t>& parser)
{
const i_t linear_row_count = static_cast<i_t>(parser.row_names.size());
coo_canonicalization_workspace_t<i_t, f_t> qc_workspace;
for (i_t k = 0; k < static_cast<i_t>(parser.quadratic_constraint_blocks.size()); k++) {
const auto& block = parser.quadratic_constraint_blocks[k];
problem.append_quadratic_constraint(linear_row_count + k,
Expand All @@ -1481,7 +1483,8 @@ void flush_quadratic_constraints(mps_data_model_t<i_t, f_t>& problem,
block.rhs_value,
block.quad_triples.vals,
block.quad_triples.rows,
block.quad_triples.cols);
block.quad_triples.cols,
qc_workspace);
}
}

Expand Down
Loading