dense_solvers.cpp File Reference
#include <iostream>
#include "BenchTimer.h"
#include <Eigen/Dense>
#include <map>
#include <vector>
#include <string>
#include <sstream>

Functions

template<typename Solver , typename MatrixType >
EIGEN_DONT_INLINE void compute_norm_equation (Solver &solver, const MatrixType &A)
 
template<typename Solver , typename MatrixType >
EIGEN_DONT_INLINE void compute (Solver &solver, const MatrixType &A)
 
template<typename Scalar , int Size>
void bench (int id, int rows, int size=Size)
 
int main ()
 

Variables

std::map< std::string, Array< float, 1, 8, DontAlign|RowMajor > > results
 
std::vector< std::string > labels
 
std::vector< Array2i > sizes
 

Function Documentation

◆ bench()

template<typename Scalar , int Size>
void bench ( int  id,
int  rows,
int  size = Size 
)
28  {
30  typedef Matrix<Scalar, Dynamic, Dynamic> MatDyn;
31  typedef Matrix<Scalar, Size, Size> MatSquare;
32  Mat A(rows, size);
33  A.setRandom();
34  if (rows == size) A = A * A.adjoint();
35  BenchTimer t_llt, t_ldlt, t_lu, t_fplu, t_qr, t_cpqr, t_cod, t_fpqr, t_jsvd, t_bdcsvd;
36 
37  int tries = 5;
38  int rep = 1000 / size;
39  if (rep == 0) rep = 1;
40  // rep = rep*rep;
41 
43  LDLT<MatSquare> ldlt(size);
52 
53  BENCH(t_llt, tries, rep, compute_norm_equation(llt, A));
54  BENCH(t_ldlt, tries, rep, compute_norm_equation(ldlt, A));
55  BENCH(t_lu, tries, rep, compute_norm_equation(lu, A));
56  if (size <= 1000) BENCH(t_fplu, tries, rep, compute_norm_equation(fplu, A));
57  BENCH(t_qr, tries, rep, compute(qr, A));
58  BENCH(t_cpqr, tries, rep, compute(cpqr, A));
59  BENCH(t_cod, tries, rep, compute(cod, A));
60  if (size * rows <= 10000000) BENCH(t_fpqr, tries, rep, compute(fpqr, A));
61  if (size < 500) // JacobiSVD is really too slow for too large matrices
62  BENCH(t_jsvd, tries, rep, jsvd.compute(A));
63  // if(size*rows<=20000000)
64  BENCH(t_bdcsvd, tries, rep, bdcsvd.compute(A));
65 
66  results["LLT"][id] = t_llt.best();
67  results["LDLT"][id] = t_ldlt.best();
68  results["PartialPivLU"][id] = t_lu.best();
69  results["FullPivLU"][id] = t_fplu.best();
70  results["HouseholderQR"][id] = t_qr.best();
71  results["ColPivHouseholderQR"][id] = t_cpqr.best();
72  results["CompleteOrthogonalDecomposition"][id] = t_cod.best();
73  results["FullPivHouseholderQR"][id] = t_fpqr.best();
74  results["JacobiSVD"][id] = t_jsvd.best();
75  results["BDCSVD"][id] = t_bdcsvd.best();
76 }
#define BENCH(TIMER, TRIES, REP, CODE)
Definition: BenchTimer.h:150
HouseholderQR< MatrixXf > qr(A)
int rows
Definition: Tutorial_commainit_02.cpp:1
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
Matrix< SCALARA, Dynamic, Dynamic, opt_A > A
Definition: bench_gemm.cpp:47
class Bidiagonal Divide and Conquer SVD
Definition: BDCSVD.h:85
Definition: BenchTimer.h:55
double best(int TIMER=CPU_TIMER) const
Definition: BenchTimer.h:98
Householder rank-revealing QR decomposition of a matrix with column-pivoting.
Definition: ColPivHouseholderQR.h:54
Complete orthogonal decomposition (COD) of a matrix.
Definition: CompleteOrthogonalDecomposition.h:54
Householder rank-revealing QR decomposition of a matrix with full pivoting.
Definition: FullPivHouseholderQR.h:63
LU decomposition of a matrix with complete pivoting, and related features.
Definition: FullPivLU.h:63
Householder QR decomposition of a matrix.
Definition: HouseholderQR.h:59
Two-sided Jacobi SVD decomposition of a rectangular matrix.
Definition: JacobiSVD.h:500
Robust Cholesky decomposition of a matrix with pivoting.
Definition: LDLT.h:63
Standard Cholesky decomposition (LL^T) of a matrix and associated features.
Definition: LLT.h:70
The matrix class, also used for vectors and row-vectors.
Definition: Eigen/Eigen/src/Core/Matrix.h:186
LU decomposition of a matrix with partial pivoting, and related features.
Definition: PartialPivLU.h:77
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT
Definition: PlainObjectBase.h:192
Derived & setRandom(Index size)
Definition: Random.h:147
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
Definition: PlainObjectBase.h:191
cout<< "Here is the matrix m:"<< endl<< m<< endl;Eigen::FullPivLU< Matrix5x3 > lu(m)
EIGEN_DONT_INLINE void compute(Solver &solver, const MatrixType &A)
Definition: dense_solvers.cpp:23
std::map< std::string, Array< float, 1, 8, DontAlign|RowMajor > > results
Definition: dense_solvers.cpp:10
EIGEN_DONT_INLINE void compute_norm_equation(Solver &solver, const MatrixType &A)
Definition: dense_solvers.cpp:15
Matrix< Scalar, Dynamic, Dynamic > Mat
Definition: gemm_common.h:15
EIGEN_DONT_INLINE void llt(const Mat &A, const Mat &B, Mat &C)
Definition: llt.cpp:4
void cod()
Definition: qr_colpivoting.cpp:17

References BENCH, Eigen::BenchTimer::best(), cod(), Eigen::PlainObjectBase< Derived >::cols(), Eigen::BDCSVD< MatrixType_, Options_ >::compute(), Eigen::JacobiSVD< MatrixType_, Options_ >::compute(), compute(), compute_norm_equation(), llt(), lu(), qr(), results, rows, Eigen::PlainObjectBase< Derived >::rows(), Eigen::PlainObjectBase< Derived >::setRandom(), and size.

◆ compute()

template<typename Solver , typename MatrixType >
EIGEN_DONT_INLINE void compute ( Solver &  solver,
const MatrixType A 
)
23  {
24  solver.compute(A);
25 }
BiCGSTAB< SparseMatrix< double > > solver
Definition: BiCGSTAB_simple.cpp:5

References solver.

Referenced by bench(), Eigen::ArpackGeneralizedSelfAdjointEigenSolver< MatrixType, MatrixSolver, BisSPD >::compute(), and Eigen::GeneralizedSelfAdjointEigenSolver< MatrixType_ >::compute().

◆ compute_norm_equation()

template<typename Solver , typename MatrixType >
EIGEN_DONT_INLINE void compute_norm_equation ( Solver &  solver,
const MatrixType A 
)
15  {
16  if (A.rows() != A.cols())
17  solver.compute(A.transpose() * A);
18  else
19  solver.compute(A);
20 }

References Eigen::PlainObjectBase< Derived >::cols(), Eigen::PlainObjectBase< Derived >::rows(), and solver.

Referenced by bench().

◆ main()

int main ( )
78  {
79  labels.push_back("LLT");
80  labels.push_back("LDLT");
81  labels.push_back("PartialPivLU");
82  labels.push_back("FullPivLU");
83  labels.push_back("HouseholderQR");
84  labels.push_back("ColPivHouseholderQR");
85  labels.push_back("CompleteOrthogonalDecomposition");
86  labels.push_back("FullPivHouseholderQR");
87  labels.push_back("JacobiSVD");
88  labels.push_back("BDCSVD");
89 
90  for (int i = 0; i < labels.size(); ++i) results[labels[i]].fill(-1);
91 
92  const int small = 8;
93  sizes.push_back(Array2i(small, small));
94  sizes.push_back(Array2i(100, 100));
95  sizes.push_back(Array2i(1000, 1000));
96  sizes.push_back(Array2i(4000, 4000));
97  sizes.push_back(Array2i(10000, small));
98  sizes.push_back(Array2i(10000, 100));
99  sizes.push_back(Array2i(10000, 1000));
100  sizes.push_back(Array2i(10000, 4000));
101 
102  using namespace std;
103 
104  for (int k = 0; k < sizes.size(); ++k) {
105  cout << sizes[k](0) << "x" << sizes[k](1) << "...\n";
106  bench<float, Dynamic>(k, sizes[k](0), sizes[k](1));
107  }
108 
109  cout.width(32);
110  cout << "solver/size";
111  cout << " ";
112  for (int k = 0; k < sizes.size(); ++k) {
113  std::stringstream ss;
114  ss << sizes[k](0) << "x" << sizes[k](1);
115  cout.width(10);
116  cout << ss.str();
117  cout << " ";
118  }
119  cout << endl;
120 
121  for (int i = 0; i < labels.size(); ++i) {
122  cout.width(32);
123  cout << labels[i];
124  cout << " ";
125  ArrayXf r = (results[labels[i]] * 100000.f).floor() / 100.f;
126  for (int k = 0; k < sizes.size(); ++k) {
127  cout.width(10);
128  if (r(k) >= 1e6)
129  cout << "-";
130  else
131  cout << r(k);
132  cout << " ";
133  }
134  cout << endl;
135  }
136 
137  // HTML output
138  cout << "<table class=\"manual\">" << endl;
139  cout << "<tr><th>solver/size</th>" << endl;
140  for (int k = 0; k < sizes.size(); ++k) cout << " <th>" << sizes[k](0) << "x" << sizes[k](1) << "</th>";
141  cout << "</tr>" << endl;
142  for (int i = 0; i < labels.size(); ++i) {
143  cout << "<tr";
144  if (i % 2 == 1) cout << " class=\"alt\"";
145  cout << "><td>" << labels[i] << "</td>";
146  ArrayXf r = (results[labels[i]] * 100000.f).floor() / 100.f;
147  for (int k = 0; k < sizes.size(); ++k) {
148  if (r(k) >= 1e6)
149  cout << "<td>-</td>";
150  else {
151  cout << "<td>" << r(k);
152  if (i > 0) cout << " (x" << numext::round(10.f * results[labels[i]](k) / results["LLT"](k)) / 10.f << ")";
153  if (i < 4 && sizes[k](0) != sizes[k](1)) cout << " <sup><a href=\"#note_ls\">*</a></sup>";
154  cout << "</td>";
155  }
156  }
157  cout << "</tr>" << endl;
158  }
159  cout << "</table>" << endl;
160 
161  // cout << "LLT (ms) " << (results["LLT"]*1000.).format(fmt) << "\n";
162  // cout << "LDLT (%) " << (results["LDLT"]/results["LLT"]).format(fmt) << "\n";
163  // cout << "PartialPivLU (%) " << (results["PartialPivLU"]/results["LLT"]).format(fmt) << "\n";
164  // cout << "FullPivLU (%) " << (results["FullPivLU"]/results["LLT"]).format(fmt) << "\n";
165  // cout << "HouseholderQR (%) " << (results["HouseholderQR"]/results["LLT"]).format(fmt) <<
166  // "\n"; cout << "ColPivHouseholderQR (%) " <<
167  // (results["ColPivHouseholderQR"]/results["LLT"]).format(fmt) << "\n"; cout << "CompleteOrthogonalDecomposition (%)
168  // " << (results["CompleteOrthogonalDecomposition"]/results["LLT"]).format(fmt) << "\n"; cout <<
169  // "FullPivHouseholderQR (%) " << (results["FullPivHouseholderQR"]/results["LLT"]).format(fmt) << "\n";
170  // cout << "JacobiSVD (%) " << (results["JacobiSVD"]/results["LLT"]).format(fmt) << "\n";
171  // cout << "BDCSVD (%) " << (results["BDCSVD"]/results["LLT"]).format(fmt) << "\n";
172 }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
std::vector< Array2i > sizes
Definition: dense_solvers.cpp:12
std::vector< std::string > labels
Definition: dense_solvers.cpp:11
char char char int int * k
Definition: level2_impl.h:374
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 floor(const bfloat16 &a)
Definition: BFloat16.h:643
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 round(const bfloat16 &a)
Definition: BFloat16.h:646
r
Definition: UniformPSDSelfTest.py:20

References Eigen::bfloat16_impl::floor(), i, k, labels, UniformPSDSelfTest::r, results, Eigen::numext::round(), and sizes.

Variable Documentation

◆ labels

std::vector<std::string> labels

Referenced by main().

◆ results

std::map<std::string, Array<float, 1, 8, DontAlign | RowMajor> > results

◆ sizes