matrix-lib-speed-test.cc
Go to the documentation of this file.
1 // matrix/matrix-lib-speed-test.cc
2 
3 // Copyright 2009-2014 Microsoft Corporation; Mohit Agarwal; Lukas Burget;
4 // Ondrej Glembek; Saarland University (Author: Arnab Ghoshal);
5 // Go Vivace Inc.; Yanmin Qian; Jan Silovsky;
6 // Johns Hopkins University (Author: Daniel Povey);
7 // Haihua Xu; Wei Shi; Karel Vesely
8 
9 // See ../../COPYING for clarification regarding multiple authors
10 //
11 // Licensed under the Apache License, Version 2.0 (the "License");
12 // you may not use this file except in compliance with the License.
13 // You may obtain a copy of the License at
14 
15 // http://www.apache.org/licenses/LICENSE-2.0
16 
17 // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18 // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
19 // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
20 // MERCHANTABLITY OR NON-INFRINGEMENT.
21 // See the Apache 2 License for the specific language governing permissions and
22 // limitations under the License.
23 
24 #include "matrix/matrix-lib.h"
25 #include "base/timer.h"
26 #include <numeric>
27 
28 namespace kaldi {
29 
30 template<typename Real> std::string NameOf() {
31  return (sizeof(Real) == 8 ? "<double>" : "<float>");
32 }
33 
34 template<typename Real> static void CsvResult(std::string test, int dim, BaseFloat measure, std::string units) {
35  std::cout << test << "," << (sizeof(Real) == 8 ? "double" : "float") << "," << dim << "," << measure << "," << units << "\n";
36 }
37 
38 template<typename Real> static void UnitTestRealFftSpeed() {
39  // First, test RealFftInefficient.
40  Timer t;
41  MatrixIndexT sz = 512; // fairly typical size.
42  for (MatrixIndexT i = 0; i < 3000; i++) {
43  if (i % 1000 == 0) KALDI_LOG << "done 1000 [ == ten seconds of speech]";
44  Vector<Real> v(sz);
45  RealFft(&v, true);
46  }
47  CsvResult<Real>(__func__, 512, t.Elapsed(), "seconds");
48 }
49 
50 template<typename Real> static void UnitTestSplitRadixRealFftSpeed() {
51  Timer t;
52  MatrixIndexT sz = 512; // fairly typical size.
53  SplitRadixRealFft<Real> srfft(sz);
54  for (MatrixIndexT i = 0; i < 6000; i++) {
55  if (i % 1000 == 0)
56  KALDI_LOG << "done 1000 [ == ten seconds of speech, split-radix]";
57  Vector<Real> v(sz);
58  srfft.Compute(v.Data(), true);
59  }
60  CsvResult<Real>(__func__, 512, t.Elapsed(), "seconds");
61 }
62 
63 template<typename Real>
64 static void UnitTestSvdSpeed() {
65  Timer t;
66  std::vector<MatrixIndexT> sizes;
67  sizes.push_back(100);
68  sizes.push_back(150);
69  sizes.push_back(200);
70  sizes.push_back(300);
71  // sizes.push_back(500);
72  // sizes.push_back(750);
73  for (size_t i = 0; i < sizes.size(); i++) {
74  MatrixIndexT size = sizes[i];
75  {
76  Timer t1;
77  SpMatrix<Real> S(size);
78  Vector<Real> l(size);
79  S.Eig(&l);
80  CsvResult<Real>("Eig w/o eigenvectors", size, t1.Elapsed(), "seconds");
81  }
82  {
83  Timer t1;
84  SpMatrix<Real> S(size);
85  S.SetRandn();
86  Vector<Real> l(size);
87  Matrix<Real> P(size, size);
88  S.Eig(&l, &P);
89  CsvResult<Real>("Eig with eigenvectors", size, t1.Elapsed(), "seconds");
90  }
91  {
92  Timer t1;
93  Matrix<Real> M(size, size);
94  M.SetRandn();
95  Vector<Real> l(size);
96  M.Svd(&l, NULL, NULL);
97  CsvResult<Real>("SVD w/o eigenvectors", size, t1.Elapsed(), "seconds");
98  }
99  {
100  Timer t1;
101  Matrix<Real> M(size, size), U(size, size), V(size, size);
102  M.SetRandn();
103  Vector<Real> l(size);
104  M.Svd(&l, &U, &V);
105  CsvResult<Real>("SVD with eigenvectors", size, t1.Elapsed(), "seconds");
106  }
107  }
108  CsvResult<Real>(__func__, sizes.size(), t.Elapsed(), "seconds");
109 }
110 
111 template<typename Real>
112 static void UnitTestAddMatMatSpeed() {
113  Timer t;
114  std::vector<MatrixIndexT> sizes;
115  sizes.push_back(512);
116  sizes.push_back(1024);
117  for (size_t i = 0; i < sizes.size(); i++) {
118  MatrixIndexT size = sizes[i];
119  {
120  Timer t1;
121  for (int32 j=0; j<2; j++) {
122  Matrix<Real> A(size,size), B(size,size), C(size,size);
123  A.SetRandn(); B.SetRandn();
124  C.AddMatMat(1.0, A, kNoTrans, B, kNoTrans, 0.0);
125  C.AddMatMat(1.0, A, kNoTrans, B, kTrans, 0.0);
126  C.AddMatMat(1.0, A, kTrans, B, kNoTrans, 0.0);
127  C.AddMatMat(1.0, A, kTrans, B, kTrans, 0.0);
128  }
129  CsvResult<Real>("AddMatMat", size, t1.Elapsed(), "seconds");
130  }
131  }
132  CsvResult<Real>(__func__, sizes.size(), t.Elapsed(), "seconds");
133 }
134 
135 template<typename Real>
137  Timer t;
138  std::vector<MatrixIndexT> sizes;
139  int32 size = 4, num = 5;
140  for(int32 i = 0; i < num; i++) {
141  sizes.push_back(size);
142  size *= 4;
143  }
144 
145  for(size_t i = 0; i < sizes.size(); i++) {
146  MatrixIndexT size = sizes[i];
147  Matrix<Real> M(size, size);
148  M.SetRandn();
149  Vector<Real> Vr(size);
150 
151  int32 iter = 0;
152  BaseFloat time_in_secs = 0.02;
153  Timer t1;
154  for (;t1.Elapsed() < time_in_secs; iter++) {
155  Vr.AddRowSumMat(0.4, M, 0.5);
156  }
157 
158  BaseFloat fdim = size;
159  BaseFloat gflops = (fdim * fdim * iter) / (t1.Elapsed() * 1.0e+09);
160  CsvResult<Real>("AddRowSumMat", size, gflops, "gigaflops");
161  }
162  CsvResult<Real>(__func__, sizes.size(), t.Elapsed(), "seconds");
163 }
164 
165 template<typename Real>
167  Timer t;
168  std::vector<MatrixIndexT> sizes;
169  int32 size = 4, num = 5;
170  for(int32 i = 0; i < num; i++) {
171  sizes.push_back(size);
172  size *= 4;
173  }
174 
175  for(size_t i = 0; i < sizes.size(); i++) {
176  MatrixIndexT size = sizes[i];
177  Matrix<Real> M(size, size);
178  M.SetRandn();
179  Vector<Real> Vc(size);
180 
181  int32 iter = 0;
182  BaseFloat time_in_secs = 0.02;
183  Timer t1;
184  for (;t1.Elapsed() < time_in_secs; iter++) {
185  Vc.AddColSumMat(0.4, M, 0.5);
186  }
187 
188  BaseFloat fdim = size;
189  BaseFloat gflops = (fdim * fdim * iter) / (t1.Elapsed() * 1.0e+09);
190  CsvResult<Real>("AddColSumMat", size, gflops, "gigaflops");
191  }
192  CsvResult<Real>(__func__, sizes.size(), t.Elapsed(), "seconds");
193 }
194 
195 template<typename Real>
197  Timer t;
198  std::vector<MatrixIndexT> sizes;
199  int32 size = 4, num = 5;
200  for(int32 i = 0; i < num; i++) {
201  sizes.push_back(size);
202  size *= 4;
203  }
204 
205  for(size_t i = 0; i < sizes.size(); i++) {
206  MatrixIndexT size = sizes[i];
207  Matrix<Real> M(size, size);
208  M.SetRandn();
209  Vector<Real> Vc(size);
210  Vc.SetRandn();
211 
212  int32 iter = 0;
213  BaseFloat time_in_secs = 0.02;
214  Timer t1;
215  for (;t1.Elapsed() < time_in_secs; iter++) {
216  M.AddVecToRows(0.5, Vc);
217  }
218 
219  BaseFloat fdim = size;
220  BaseFloat gflops = (fdim * fdim * iter) / (t1.Elapsed() * 1.0e+09);
221  CsvResult<Real>("AddVecToRows", size, gflops, "gigaflops");
222  }
223  CsvResult<Real>(__func__, sizes.size(), t.Elapsed(), "seconds");
224 }
225 
226 template<typename Real>
228  Timer t;
229  std::vector<MatrixIndexT> sizes;
230  int32 size = 4, num = 5;
231  for(int32 i = 0; i < num; i++) {
232  sizes.push_back(size);
233  size *= 4;
234  }
235 
236  for(size_t i = 0; i < sizes.size(); i++) {
237  MatrixIndexT size = sizes[i];
238  Matrix<Real> M(size, size);
239  M.SetRandn();
240  Vector<Real> Vr(size);
241  Vr.SetRandn();
242 
243  int32 iter = 0;
244  BaseFloat time_in_secs = 0.02;
245  Timer t1;
246  for (;t1.Elapsed() < time_in_secs; iter++) {
247  M.AddVecToCols(0.5, Vr);
248  }
249 
250  BaseFloat fdim = size;
251  BaseFloat gflops = (fdim * fdim * iter) / (t1.Elapsed() * 1.0e+09);
252  CsvResult<Real>("AddVecToCols", size, gflops, "gigaflops");
253  }
254  CsvResult<Real>(__func__, sizes.size(), t.Elapsed(), "seconds");
255 }
256 
257 template<typename Real> static void MatrixUnitSpeedTest() {
258  UnitTestRealFftSpeed<Real>();
259  UnitTestSplitRadixRealFftSpeed<Real>();
260  UnitTestSvdSpeed<Real>();
261  UnitTestAddMatMatSpeed<Real>();
262  UnitTestAddRowSumMatSpeed<Real>();
263  UnitTestAddColSumMatSpeed<Real>();
264  UnitTestAddVecToRowsSpeed<Real>();
265  UnitTestAddVecToColsSpeed<Real>();
266 }
267 
268 } // namespace kaldi
269 
270 int main() {
271  using namespace kaldi;
272  Timer t;
273  KALDI_LOG << "Starting, Single precision";
274  kaldi::MatrixUnitSpeedTest<float>();
275  KALDI_LOG << "Starting, Double precision";
276  kaldi::MatrixUnitSpeedTest<double>();
277  KALDI_LOG << "Tests succeeded, total duration " << t.Elapsed() << " seconds.";
278 }
279 
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
Packed symetric matrix class.
Definition: matrix-common.h:62
static void CsvResult(std::string test, int dim, BaseFloat measure, std::string units)
static void MatrixUnitSpeedTest()
void AddRowSumMat(Real alpha, const MatrixBase< Real > &M, Real beta=1.0)
Does *this = alpha * (sum of rows of M) + beta * *this.
static void UnitTestRealFftSpeed()
std::string NameOf()
kaldi::int32 int32
void Eig(VectorBase< Real > *s, MatrixBase< Real > *P=NULL) const
Solves the symmetric eigenvalue problem: at end we should have (*this) = P * diag(s) * P^T...
Definition: qr.cc:433
A class for storing matrices.
Definition: kaldi-matrix.h:823
void SetRandn()
< Set to unit matrix.
float BaseFloat
Definition: kaldi-types.h:29
int32 MatrixIndexT
Definition: matrix-common.h:98
static void UnitTestSplitRadixRealFftSpeed()
static void UnitTestAddRowSumMatSpeed()
void AddVecToRows(const Real alpha, const VectorBase< OtherReal > &v)
[each row of *this] += alpha * v
static void UnitTestSvdSpeed()
static void UnitTestAddVecToRowsSpeed()
void SetRandn()
Sets to random values of a normal distribution.
static void UnitTestAddColSumMatSpeed()
void AddMatMat(const Real alpha, const MatrixBase< Real > &A, MatrixTransposeType transA, const MatrixBase< Real > &B, MatrixTransposeType transB, const Real beta)
Real * Data()
Returns a pointer to the start of the vector&#39;s data.
Definition: kaldi-vector.h:70
void SetRandn()
Set vector to random normally-distributed noise.
A class representing a vector.
Definition: kaldi-vector.h:406
static void UnitTestAddMatMatSpeed()
void AddVecToCols(const Real alpha, const VectorBase< OtherReal > &v)
[each col of *this] += alpha * v
int main()
void Svd(VectorBase< Real > *s, MatrixBase< Real > *U, MatrixBase< Real > *Vt) const
Compute SVD (*this) = U diag(s) Vt.
void AddColSumMat(Real alpha, const MatrixBase< Real > &M, Real beta=1.0)
Does *this = alpha * (sum of columns of M) + beta * *this.
#define KALDI_LOG
Definition: kaldi-error.h:153
double Elapsed() const
Returns time in seconds.
Definition: timer.h:74
static void UnitTestAddVecToColsSpeed()
void Compute(Real *x, bool forward)
If forward == true, this function transforms from a sequence of N real points to its complex fourier ...
Definition: srfft.cc:356
void RealFft(VectorBase< Real > *v, bool forward)
RealFft is a fourier transform of real inputs.