21#include "Eigen/SparseCore"
22#include "absl/memory/memory.h"
23#include "absl/strings/string_view.h"
35void WarnIfMatrixUnbalanced(
36 const Eigen::SparseMatrix<double, Eigen::ColMajor, int64_t>& matrix,
37 absl::string_view matrix_name, int64_t density_limit) {
38 if (matrix.cols() == 0)
return;
39 int64_t worst_column = 0;
40 for (int64_t
col = 0;
col < matrix.cols(); ++
col) {
41 if (matrix.col(
col).nonZeros() > matrix.col(worst_column).nonZeros()) {
45 if (matrix.col(worst_column).nonZeros() > density_limit) {
49 <<
"The " << matrix_name <<
" has "
50 << matrix.col(worst_column).nonZeros() <<
" non-zeros in its "
52 <<
"th column. For best parallelization all rows and columns should "
55 <<
" non-zeros. Consider rewriting the QP to split the corresponding "
56 "variable or constraint.";
63 const int num_threads,
66 transposed_constraint_matrix_(qp_.constraint_matrix.transpose()),
67 thread_pool_(num_threads == 1
70 constraint_matrix_sharder_(qp_.constraint_matrix, num_shards,
72 transposed_constraint_matrix_sharder_(transposed_constraint_matrix_,
73 num_shards, thread_pool_.get()),
76 dual_sharder_(qp_.constraint_lower_bounds.size(), num_shards,
80 if (num_threads > 1) {
81 thread_pool_->StartWorkers();
85 const int64_t column_density_limit = work_per_iteration / num_threads;
87 column_density_limit);
88 WarnIfMatrixUnbalanced(transposed_constraint_matrix_,
89 "transposed constraint matrix",
90 column_density_limit);
100 const Eigen::VectorXd& col_scaling_vec,
101 const Eigen::VectorXd& row_scaling_vec,
const Sharder& sharder,
102 Eigen::SparseMatrix<double, Eigen::ColMajor, int64_t>& matrix) {
103 CHECK_EQ(matrix.cols(), col_scaling_vec.size());
104 CHECK_EQ(matrix.rows(), row_scaling_vec.size());
106 auto matrix_shard = shard(matrix);
107 auto col_scaling_vec_shard = shard(col_scaling_vec);
108 for (int64_t col_num = 0; col_num < shard(matrix).outerSize(); ++col_num) {
109 for (
decltype(matrix_shard)::InnerIterator it(matrix_shard, col_num); it;
112 row_scaling_vec[it.row()] * col_scaling_vec_shard[it.col()];
121 const Eigen::VectorXd& col_scaling_vec,
122 const Eigen::VectorXd& row_scaling_vec) {
126 CHECK((shard(col_scaling_vec).array() > 0.0).all());
137 shard(col_scaling_vec).cwiseProduct(shard(col_scaling_vec)));
141 CHECK((shard(row_scaling_vec).array() > 0.0).all());
148 ScaleMatrix(col_scaling_vec, row_scaling_vec, constraint_matrix_sharder_,
150 ScaleMatrix(row_scaling_vec, col_scaling_vec,
151 transposed_constraint_matrix_sharder_,
152 transposed_constraint_matrix_);
#define CHECK_EQ(val1, val2)
#define CHECK_GE(val1, val2)
void RescaleQuadraticProgram(const Eigen::VectorXd &col_scaling_vec, const Eigen::VectorXd &row_scaling_vec)
ShardedQuadraticProgram(QuadraticProgram qp, int num_threads, int num_shards)
int64_t PrimalSize() const
void ParallelForEachShard(const std::function< void(const Shard &)> &func) const
bool IsLinearProgram(const QuadraticProgram &qp)
Eigen::VectorXd variable_upper_bounds
Eigen::VectorXd variable_lower_bounds
Eigen::VectorXd constraint_lower_bounds
Eigen::SparseMatrix< double, Eigen::ColMajor, int64_t > constraint_matrix
std::optional< Eigen::DiagonalMatrix< double, Eigen::Dynamic > > objective_matrix
Eigen::VectorXd constraint_upper_bounds
Eigen::VectorXd objective_vector
VectorXd variable_lower_bounds