Skip to content

Commit a114099

Browse files
author
YUWEN Chen
committed
feat(mps_parser): add QCMATRIX parsing and quadratic-constraint model support
1 parent 24fdb60 commit a114099

6 files changed

Lines changed: 315 additions & 13 deletions

File tree

cpp/libmps_parser/include/mps_parser/mps_data_model.hpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,40 @@ class mps_data_model_t {
262262
const i_t* Q_offsets,
263263
i_t size_offsets);
264264

265+
/**
266+
* @brief CSR of Q for one quadratic constraint (MPS QCMATRIX).
267+
*
268+
* @c constraint_row_index is the row index in the linear constraint matrix A (0-based),
269+
* matching the order of non-objective rows in the ROWS section.
270+
*/
271+
struct quadratic_constraint_matrix_t {
272+
i_t constraint_row_index{};
273+
std::vector<f_t> values;
274+
std::vector<i_t> indices;
275+
std::vector<i_t> offsets;
276+
};
277+
278+
/**
279+
* @brief Append one quadratic constraint matrix (QCMATRIX) in CSR format.
280+
*
281+
* @param constraint_row_index Row index in A (0-based), matching non-objective ROWS order.
282+
* @param[in] Qc_values Values of the CSR representation; copied into the model.
283+
* @param size_values Size of the Qc_values array.
284+
* @param[in] Qc_indices Indices of the CSR representation; copied into the model.
285+
* @param size_indices Size of the Qc_indices array.
286+
* @param[in] Qc_offsets Offsets of the CSR representation; copied into the model.
287+
* @param size_offsets Size of the Qc_offsets array.
288+
*/
289+
void append_quadratic_constraint_matrix(i_t constraint_row_index,
290+
const f_t* Qc_values,
291+
i_t size_values,
292+
const i_t* Qc_indices,
293+
i_t size_indices,
294+
const i_t* Qc_offsets,
295+
i_t size_offsets);
296+
297+
const std::vector<quadratic_constraint_matrix_t>& get_quadratic_constraint_matrices() const;
298+
265299
i_t get_n_variables() const;
266300
i_t get_n_constraints() const;
267301
i_t get_nnz() const;
@@ -306,6 +340,8 @@ class mps_data_model_t {
306340

307341
bool has_quadratic_objective() const noexcept;
308342

343+
bool has_quadratic_constraints() const noexcept;
344+
309345
/** whether to maximize or minimize the objective function */
310346
bool maximize_;
311347
/**
@@ -361,6 +397,9 @@ class mps_data_model_t {
361397
std::vector<i_t> Q_objective_indices_;
362398
std::vector<i_t> Q_objective_offsets_;
363399

400+
/** One CSR matrix per QCMATRIX block, in order of appearance in the file */
401+
std::vector<quadratic_constraint_matrix_t> quadratic_constraint_matrices_;
402+
364403
}; // class mps_data_model_t
365404

366405
} // namespace cuopt::mps_parser

cpp/libmps_parser/include/mps_parser/parser.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ namespace cuopt::mps_parser {
2323
* QPS files (for quadratic programming). QPS files are MPS files with additional
2424
* sections:
2525
* - QUADOBJ: Defines quadratic terms in the objective function
26+
* - QMATRIX: Full symmetric quadratic objective matrix (alternative to QUADOBJ)
27+
* - QCMATRIX: Symmetric quadratic terms for a named constraint row (QCQP)
2628
*
2729
* Note: Compressed MPS files .mps.gz, .mps.bz2 can only be read if the compression
2830
* libraries zlib or libbzip2 are installed, respectively.

cpp/libmps_parser/src/mps_data_model.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <utilities/error.hpp>
1010

1111
#include <algorithm>
12+
#include <utility>
1213

1314
namespace cuopt::mps_parser {
1415

@@ -219,6 +220,51 @@ void mps_data_model_t<i_t, f_t>::set_quadratic_objective_matrix(const f_t* Q_val
219220
std::copy(Q_offsets, Q_offsets + size_offsets, Q_objective_offsets_.data());
220221
}
221222

223+
template <typename i_t, typename f_t>
224+
void mps_data_model_t<i_t, f_t>::append_quadratic_constraint_matrix(i_t constraint_row_index,
225+
const f_t* Qc_values,
226+
i_t size_values,
227+
const i_t* Qc_indices,
228+
i_t size_indices,
229+
const i_t* Qc_offsets,
230+
i_t size_offsets)
231+
{
232+
if (size_values != 0) {
233+
mps_parser_expects(
234+
Qc_values != nullptr, error_type_t::ValidationError, "Qc_values cannot be null");
235+
}
236+
if (size_indices != 0) {
237+
mps_parser_expects(
238+
Qc_indices != nullptr, error_type_t::ValidationError, "Qc_indices cannot be null");
239+
}
240+
mps_parser_expects(
241+
Qc_offsets != nullptr, error_type_t::ValidationError, "Qc_offsets cannot be null");
242+
mps_parser_expects(
243+
size_offsets > 0, error_type_t::ValidationError, "size_offsets cannot be empty");
244+
245+
quadratic_constraint_matrix_t qcm;
246+
qcm.constraint_row_index = constraint_row_index;
247+
qcm.values.resize(size_values);
248+
if (size_values > 0) {
249+
std::copy(Qc_values, Qc_values + size_values, qcm.values.data());
250+
}
251+
qcm.indices.resize(size_indices);
252+
if (size_indices > 0) {
253+
std::copy(Qc_indices, Qc_indices + size_indices, qcm.indices.data());
254+
}
255+
qcm.offsets.resize(size_offsets);
256+
std::copy(Qc_offsets, Qc_offsets + size_offsets, qcm.offsets.data());
257+
258+
quadratic_constraint_matrices_.push_back(std::move(qcm));
259+
}
260+
261+
template <typename i_t, typename f_t>
262+
auto mps_data_model_t<i_t, f_t>::get_quadratic_constraint_matrices() const
263+
-> const std::vector<quadratic_constraint_matrix_t>&
264+
{
265+
return quadratic_constraint_matrices_;
266+
}
267+
222268
template <typename i_t, typename f_t>
223269
const std::vector<f_t>& mps_data_model_t<i_t, f_t>::get_constraint_matrix_values() const
224270
{
@@ -460,6 +506,12 @@ bool mps_data_model_t<i_t, f_t>::has_quadratic_objective() const noexcept
460506
return !Q_objective_values_.empty();
461507
}
462508

509+
template <typename i_t, typename f_t>
510+
bool mps_data_model_t<i_t, f_t>::has_quadratic_constraints() const noexcept
511+
{
512+
return !quadratic_constraint_matrices_.empty();
513+
}
514+
463515
// NOTE: Explicitly instantiate all types here in order to avoid linker error
464516
template class mps_data_model_t<int, float>;
465517

0 commit comments

Comments
 (0)