Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
9ab049e
Update mps_parser_test.cpp
Franc-Z Aug 26, 2025
3140131
Update mps_parser.hpp
Franc-Z Aug 26, 2025
2ae7ce7
Update mps_parser.cpp
Franc-Z Aug 26, 2025
9b1af74
Update mps_data_model.cpp
Franc-Z Aug 26, 2025
28b87a9
Update data_model_view.hpp
Franc-Z Aug 26, 2025
61e2fb8
Update mps_data_model.hpp
Franc-Z Aug 26, 2025
c0429fd
Update parser.hpp
Franc-Z Aug 26, 2025
26d91f4
Update data_model_view.cpp
Franc-Z Aug 26, 2025
f9cc5d6
Merge branch 'NVIDIA:branch-25.10' into branch-25.10
Franc-Z Aug 27, 2025
ad01027
Update data_model_view.hpp
Franc-Z Aug 27, 2025
fd1acee
Update mps_data_model.hpp
Franc-Z Aug 27, 2025
f285d53
Update parser.hpp
Franc-Z Aug 27, 2025
1807641
Update data_model_view.cpp
Franc-Z Aug 27, 2025
4367b0e
Update mps_data_model.cpp
Franc-Z Aug 27, 2025
bf6ea8c
Update mps_parser.cpp
Franc-Z Aug 27, 2025
8c3032b
Update mps_parser.hpp
Franc-Z Aug 27, 2025
a06a83e
Update mps_parser_test.cpp
Franc-Z Aug 27, 2025
b8aedce
Update data_model_view.cpp
Franc-Z Aug 27, 2025
24b9c0d
Update data_model_view.hpp
Franc-Z Aug 27, 2025
0066e4c
Merge branch 'NVIDIA:branch-25.10' into branch-25.10
Franc-Z Aug 28, 2025
7034f25
fix: 修复 pre-commit 配置问题并升级相关组件
Franc-Z Aug 29, 2025
479e4e5
fix style
rgsl888prabhu Aug 29, 2025
f0ae5fd
Clean up MPS/QPS parser tests
Franc-Z Aug 30, 2025
703dd1b
Add quadratic programming dataset files to version control
Franc-Z Aug 30, 2025
3013fad
Update datasets and related configuration files
Franc-Z Sep 1, 2025
7a0d8e6
Merge branch 'NVIDIA:branch-25.10' into branch-25.10
Franc-Z Sep 1, 2025
72f04cf
Update .pre-commit-config.yaml
Franc-Z Sep 2, 2025
e815186
Update .pre-commit-config.yaml
Franc-Z Sep 2, 2025
eff8a1f
Merge branch 'NVIDIA:branch-25.10' into branch-25.10
Franc-Z Sep 2, 2025
8df6310
Update mps_parser_test.cpp
Franc-Z Sep 2, 2025
3e2d668
fix: remove the unnecessary executable attribute of *.qps files
Franc-Z Sep 3, 2025
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
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
*.mps linguist-detectable=false
*.qps linguist-detectable=false
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,5 @@ docs/cuopt/build

# generated version file
cpp/include/cuopt/semantic_version.hpp
!datasets/quadratic_programming
!datasets/quadratic_programming/**
55 changes: 55 additions & 0 deletions cpp/libmps_parser/include/mps_parser/data_model_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,30 @@ class data_model_view_t {
*/
void set_initial_dual_solution(const f_t* initial_dual_solution, i_t size);

/**
* @brief Set the quadratic objective matrix (Q) in CSR format for QPS files.
*
* @note This is used for quadratic programming problems where the objective
* function contains quadratic terms: (1/2) * x^T * Q * x + c^T * x
* cuOpt does not own or copy this data.
*
* @param[in] Q_values Device memory pointer to values of the CSR representation of the quadratic
* objective matrix
* @param size_values Size of the Q_values array
* @param[in] Q_indices Device memory pointer to indices of the CSR representation of the
* quadratic objective matrix
* @param size_indices Size of the Q_indices array
* @param[in] Q_offsets Device memory pointer to offsets of the CSR representation of the
* quadratic objective matrix
* @param size_offsets Size of the Q_offsets array
*/
void set_quadratic_objective_matrix(const f_t* Q_values,
i_t size_values,
const i_t* Q_indices,
i_t size_indices,
const i_t* Q_offsets,
i_t size_offsets);

/**
* @brief Get the sense value (false:minimize, true:maximize)
*
Expand Down Expand Up @@ -339,6 +363,32 @@ class data_model_view_t {
*/
std::string get_objective_name() const noexcept;

// QPS-specific getters
/**
* @brief Get the quadratic objective matrix values
*
* @return span<f_t const>
*/
span<f_t const> get_quadratic_objective_values() const noexcept;
/**
* @brief Get the quadratic objective matrix indices
*
* @return span<i_t const>
*/
span<i_t const> get_quadratic_objective_indices() const noexcept;
/**
* @brief Get the quadratic objective matrix offsets
*
* @return span<i_t const>
*/
span<i_t const> get_quadratic_objective_offsets() const noexcept;
/**
* @brief Check if the problem has quadratic objective terms
*
* @return bool
*/
bool has_quadratic_objective() const noexcept;

private:
bool maximize_{false};
span<f_t const> A_;
Expand All @@ -361,6 +411,11 @@ class data_model_view_t {
span<f_t const> initial_primal_solution_;
span<f_t const> initial_dual_solution_;

// QPS-specific data members for quadratic programming support
span<f_t const> Q_objective_;
span<i_t const> Q_objective_indices_;
span<i_t const> Q_objective_offsets_;

}; // class data_model_view_t

} // namespace cuopt::mps_parser
37 changes: 37 additions & 0 deletions cpp/libmps_parser/include/mps_parser/mps_data_model.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,26 @@ class mps_data_model_t {
*/
void set_initial_dual_solution(const f_t* initial_dual_solution, i_t size);

/**
* @brief Set the quadratic objective matrix (Q) in CSR format for QPS files.
*
* @note This is used for quadratic programming problems where the objective
* function contains quadratic terms: (1/2) * x^T * Q * x + c^T * x
*
* @param[in] Q_values Values of the CSR representation of the quadratic objective matrix
* @param size_values Size of the Q_values array
* @param[in] Q_indices Indices of the CSR representation of the quadratic objective matrix
* @param size_indices Size of the Q_indices array
* @param[in] Q_offsets Offsets of the CSR representation of the quadratic objective matrix
* @param size_offsets Size of the Q_offsets array
*/
void set_quadratic_objective_matrix(const f_t* Q_values,
i_t size_values,
const i_t* Q_indices,
i_t size_indices,
const i_t* Q_offsets,
i_t size_offsets);

i_t get_n_variables() const;
i_t get_n_constraints() const;
i_t get_nnz() const;
Expand Down Expand Up @@ -285,6 +305,16 @@ class mps_data_model_t {
const std::vector<std::string>& get_variable_names() const;
const std::vector<std::string>& get_row_names() const;

// QPS-specific getters
const std::vector<f_t>& get_quadratic_objective_values() const;
std::vector<f_t>& get_quadratic_objective_values();
const std::vector<i_t>& get_quadratic_objective_indices() const;
std::vector<i_t>& get_quadratic_objective_indices();
const std::vector<i_t>& get_quadratic_objective_offsets() const;
std::vector<i_t>& get_quadratic_objective_offsets();

bool has_quadratic_objective() const noexcept;

/** whether to maximize or minimize the objective function */
bool maximize_;
/**
Expand Down Expand Up @@ -333,6 +363,13 @@ class mps_data_model_t {
std::vector<f_t> initial_primal_solution_;
/** Initial dual solution */
std::vector<f_t> initial_dual_solution_;

// QPS-specific data members for quadratic programming support
/** Quadratic objective matrix in CSR format (for (1/2) * x^T * Q * x term) */
std::vector<f_t> Q_objective_;
std::vector<i_t> Q_objective_indices_;
std::vector<i_t> Q_objective_offsets_;

}; // class mps_data_model_t

} // namespace cuopt::mps_parser
13 changes: 9 additions & 4 deletions cpp/libmps_parser/include/mps_parser/parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,19 @@
namespace cuopt::mps_parser {

/**
* @brief Reads the equation from the input text file which is MPS formatted
* @brief Reads the equation from the input text file which is MPS or QPS formatted
*
* Read this link http://lpsolve.sourceforge.net/5.5/mps-format.htm for more
* details on both free and fixed MPS format.
*
* @param[in] mps_file_path Path to MPS formatted file.
* @param[in] fixed_mps_format If MPS file should be parsed as fixed, false by default
* @return mps_data_model_t A fully formed LP problem which represents the given MPS file
* This function supports both standard MPS files (for linear programming) and
* QPS files (for quadratic programming). QPS files are MPS files with additional
* sections:
* - QUADOBJ: Defines quadratic terms in the objective function
*
* @param[in] mps_file_path Path to MPS or QPS formatted file.
* @param[in] fixed_mps_format If MPS/QPS file should be parsed as fixed format, false by default
* @return mps_data_model_t A fully formed LP/QP problem which represents the given MPS/QPS file
*/
template <typename i_t, typename f_t>
mps_data_model_t<i_t, f_t> parse_mps(const std::string& mps_file_path,
Expand Down
52 changes: 52 additions & 0 deletions cpp/libmps_parser/src/data_model_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,33 @@ void data_model_view_t<i_t, f_t>::set_initial_dual_solution(const f_t* initial_d
initial_dual_solution_ = span<f_t const>(initial_dual_solution, size);
}

template <typename i_t, typename f_t>
void data_model_view_t<i_t, f_t>::set_quadratic_objective_matrix(const f_t* Q_values,
i_t size_values,
const i_t* Q_indices,
i_t size_indices,
const i_t* Q_offsets,
i_t size_offsets)
{
if (size_values != 0) {
mps_parser_expects(
Q_values != nullptr, error_type_t::ValidationError, "Q_values cannot be null");
}
Q_objective_ = span<f_t const>(Q_values, size_values);

if (size_indices != 0) {
mps_parser_expects(
Q_indices != nullptr, error_type_t::ValidationError, "Q_indices cannot be null");
}
Q_objective_indices_ = span<i_t const>(Q_indices, size_indices);

mps_parser_expects(
Q_offsets != nullptr, error_type_t::ValidationError, "Q_offsets cannot be null");
mps_parser_expects(
size_offsets > 0, error_type_t::ValidationError, "size_offsets cannot be empty");
Q_objective_offsets_ = span<i_t const>(Q_offsets, size_offsets);
}

template <typename i_t, typename f_t>
void data_model_view_t<i_t, f_t>::set_row_types(const char* row_types, i_t size)
{
Expand Down Expand Up @@ -279,6 +306,31 @@ bool data_model_view_t<i_t, f_t>::get_sense() const noexcept
return maximize_;
}

// QPS-specific getter implementations
template <typename i_t, typename f_t>
span<const f_t> data_model_view_t<i_t, f_t>::get_quadratic_objective_values() const noexcept
{
return Q_objective_;
}

template <typename i_t, typename f_t>
span<const i_t> data_model_view_t<i_t, f_t>::get_quadratic_objective_indices() const noexcept
{
return Q_objective_indices_;
}

template <typename i_t, typename f_t>
span<const i_t> data_model_view_t<i_t, f_t>::get_quadratic_objective_offsets() const noexcept
{
return Q_objective_offsets_;
}

template <typename i_t, typename f_t>
bool data_model_view_t<i_t, f_t>::has_quadratic_objective() const noexcept
{
return Q_objective_.size() > 0;
}

// NOTE: Explicitly instantiate all types here in order to avoid linker error
template class data_model_view_t<int, float>;

Expand Down
73 changes: 73 additions & 0 deletions cpp/libmps_parser/src/mps_data_model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,36 @@ void mps_data_model_t<i_t, f_t>::set_initial_dual_solution(const f_t* initial_du
std::copy(initial_dual_solution, initial_dual_solution + size, initial_dual_solution_.data());
}

template <typename i_t, typename f_t>
void mps_data_model_t<i_t, f_t>::set_quadratic_objective_matrix(const f_t* Q_values,
i_t size_values,
const i_t* Q_indices,
i_t size_indices,
const i_t* Q_offsets,
i_t size_offsets)
{
if (size_values != 0) {
mps_parser_expects(
Q_values != nullptr, error_type_t::ValidationError, "Q_values cannot be null");
}
Q_objective_.resize(size_values);
std::copy(Q_values, Q_values + size_values, Q_objective_.data());

if (size_indices != 0) {
mps_parser_expects(
Q_indices != nullptr, error_type_t::ValidationError, "Q_indices cannot be null");
}
Q_objective_indices_.resize(size_indices);
std::copy(Q_indices, Q_indices + size_indices, Q_objective_indices_.data());

mps_parser_expects(
Q_offsets != nullptr, error_type_t::ValidationError, "Q_offsets cannot be null");
mps_parser_expects(
size_offsets > 0, error_type_t::ValidationError, "size_offsets cannot be empty");
Q_objective_offsets_.resize(size_offsets);
std::copy(Q_offsets, Q_offsets + size_offsets, Q_objective_offsets_.data());
}

template <typename i_t, typename f_t>
const std::vector<f_t>& mps_data_model_t<i_t, f_t>::get_constraint_matrix_values() const
{
Expand Down Expand Up @@ -397,6 +427,49 @@ i_t mps_data_model_t<i_t, f_t>::get_nnz() const
return A_.size();
}

// QPS-specific getter implementations
template <typename i_t, typename f_t>
const std::vector<f_t>& mps_data_model_t<i_t, f_t>::get_quadratic_objective_values() const
{
return Q_objective_;
}

template <typename i_t, typename f_t>
std::vector<f_t>& mps_data_model_t<i_t, f_t>::get_quadratic_objective_values()
{
return Q_objective_;
}

template <typename i_t, typename f_t>
const std::vector<i_t>& mps_data_model_t<i_t, f_t>::get_quadratic_objective_indices() const
{
return Q_objective_indices_;
}

template <typename i_t, typename f_t>
std::vector<i_t>& mps_data_model_t<i_t, f_t>::get_quadratic_objective_indices()
{
return Q_objective_indices_;
}

template <typename i_t, typename f_t>
const std::vector<i_t>& mps_data_model_t<i_t, f_t>::get_quadratic_objective_offsets() const
{
return Q_objective_offsets_;
}

template <typename i_t, typename f_t>
std::vector<i_t>& mps_data_model_t<i_t, f_t>::get_quadratic_objective_offsets()
{
return Q_objective_offsets_;
}

template <typename i_t, typename f_t>
bool mps_data_model_t<i_t, f_t>::has_quadratic_objective() const noexcept
{
return !Q_objective_.empty();
}

// NOTE: Explicitly instantiate all types here in order to avoid linker error
template class mps_data_model_t<int, float>;

Expand Down
Loading