cu-block-matrix-test.cc
Go to the documentation of this file.
1 // cudamatrix/cu-block-matrix-test.cc
2 
3 // Copyright 2013 Johns Hopkins University (author: Daniel Povey)
4 
5 // See ../../COPYING for clarification regarding multiple authors
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 // http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
15 // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
16 // MERCHANTABLITY OR NON-INFRINGEMENT.
17 // See the Apache 2 License for the specific language governing permissions and
18 // limitations under the License.
19 
20 
21 #include <iostream>
22 #include <vector>
23 #include <cstdlib>
24 
25 #include "base/kaldi-common.h"
26 #include "util/common-utils.h"
28 
29 using namespace kaldi;
30 
31 
32 namespace kaldi {
33 
34 template<typename Real>
35 static bool ApproxEqual(const CuBlockMatrix<Real> &A,
36  const CuBlockMatrix<Real> &B,
37  float tol = 0.001) {
38  CuMatrix<Real> Acopy(A), Bcopy(B);
39  return Acopy.ApproxEqual(Bcopy, tol);
40 }
41 
42 
43 
44 
45 template<class Real>
46 static void UnitTestCuBlockMatrixIO() {
47  for (int32 i = 0; i < 10; i++) {
48  int32 num_blocks = Rand() % 5;
49  std::vector<CuMatrix<Real> > data(num_blocks);
50  for (int32 b = 0; b < num_blocks; b++) {
51  int32 dimM = 100 + Rand() % 255, dimN = 10 + Rand() % 20;
52  if (b % 2 == 0) std::swap(dimM, dimN);
53  data[b].Resize(dimM, dimN);
54  data[b].SetRandn();
55  }
56  CuBlockMatrix<Real> B(data);
57 
58  std::ostringstream os;
59  bool binary = (i % 4 < 2);
60  B.Write(os, binary);
61 
63  std::istringstream is(os.str());
64  B2.Read(is, binary);
65 
66  CuMatrix<Real> mat(B), mat2(B2);
67  AssertEqual(mat, mat2);
68  if (!data.empty())
69  KALDI_ASSERT(mat.Sum() != 0.0);
70  }
71 }
72 
73 
74 
75 template<class Real>
77  for (int32 i = 0; i < 20; i++) {
78  int32 num_blocks = Rand() % 5;
79  std::vector<CuMatrix<Real> > data(num_blocks);
80  for (int32 b = 0; b < num_blocks; b++) {
81  int32 dimM = 100 + Rand() % 255, dimN = 10 + Rand() % 20;
82  // early failures will have small dim for easier eyeballing.
83  if (b % 2 == 0) std::swap(dimM, dimN);
84  data[b].Resize(dimM, dimN);
85  data[b].SetRandn();
86  }
87  CuBlockMatrix<Real> B(data);
88  int32 B_num_rows = B.NumRows(), B_num_cols = B.NumCols();
89  // will do X += A B
90 
91  MatrixTransposeType transB = (i % 2 == 1 ? kTrans : kNoTrans),
92  transA = (i % 3 == 1 ? kTrans : kNoTrans);
93  if (transB == kTrans) std::swap(B_num_rows, B_num_cols);
94 
95  int32 X_num_rows = 100 + Rand() % 255, X_num_cols = B_num_cols,
96  A_num_rows = X_num_rows, A_num_cols = B_num_rows;
97  if (data.size() == 0) { X_num_rows = 0; A_num_rows = 0; }
98  if (transA == kTrans) std::swap(A_num_rows, A_num_cols);
99 
100  Real alpha = 2.0, beta = -1.0;
101  CuMatrix<Real> X(X_num_rows, X_num_cols);
102  X.SetRandn();
103  CuMatrix<Real> A(A_num_rows, A_num_cols);
104  A.SetRandn();
105 
106  CuMatrix<Real> Xcopy(X), Bcopy(B), Xorig(X), Aorig(A);
107  Xcopy.AddMatMat(alpha, A, transA, Bcopy, transB, beta);
108  X.AddMatBlock(alpha, A, transA, B, transB, beta);
109 
110  AssertEqual(X, Xcopy);
111  }
112 }
113 
114 
115 template<class Real>
117  for (int32 i = 0; i < 20; i++) {
118  int32 num_blocks = Rand() % 5 + 1;
119  std::vector<CuMatrix<Real> > data(num_blocks);
120  for (int32 b = 0; b < num_blocks; b++) {
121  int32 dimM = 100 + Rand() % 255, dimN = 10 + Rand() % 20;
122  if (i == 0) { dimM = 1; dimN = 1; }
123  // early failures will have small dim for easier eyeballing.
124  if (b % 2 == 0) std::swap(dimM, dimN);
125  data[b].Resize(dimM, dimN);
126  KALDI_LOG << "dimM " << dimM << ", dimN " << dimN << ", stride " << data[b].Stride();
127  data[b].SetRandn();
128  }
129 
130  CuBlockMatrix<Real> B(data);
131  int32 B_num_rows = B.NumRows(), B_num_cols = B.NumCols();
132  // will do B += C D
133 
134  int32 C_num_rows = B_num_rows, C_num_cols = 100 + Rand() % 255;
135  if (C_num_rows == 0) C_num_cols = 0;
136  int32 D_num_rows = C_num_cols, D_num_cols = B_num_cols;
137 
138  MatrixTransposeType transC = (i % 2 == 1 ? kTrans : kNoTrans),
139  transD = (i % 3 == 1 ? kTrans : kNoTrans);
140  if (transC == kTrans) std::swap(C_num_rows, C_num_cols);
141  if (transD == kTrans) std::swap(D_num_rows, D_num_cols);
142 
143  CuMatrix<Real> C(C_num_rows, C_num_cols), D(D_num_rows, D_num_cols);
144  C.SetRandn();
145  D.SetRandn();
146 
147  CuMatrix<Real> Bmat(B);
148 
149  Real alpha = 2.0, beta = -1.0;
150 
151  CuBlockMatrix<Real> Bcopy(B);
152 
153  B.AddMatMat(alpha, C, transC, D, transD, beta);
154 
155  Bmat.AddMatMat(alpha, C, transC, D, transD, beta);
156 
157  // Now check that the block-structured part of Bmat is the
158  // same as B.
159  Bcopy.CopyFromMat(Bmat); // copy block-structured part from Bmat to Bcopy.
160 
161  if (!ApproxEqual(B, Bcopy)) {
162  KALDI_WARN << "CuBlockMatrixTest failure, please report to maintainers: Bcopy = "
163  << Bcopy << ", B = " << B << ", C = " << C << ", D = " << D
164  << ", Bmat = " << B << " transD = " << transD << ", transC = "
165  << transC;
166  KALDI_ERR << "Please give this log to the maintainers.";
167  }
168  KALDI_ASSERT(Bmat.Sum() != 0 || B_num_rows == 0);
169  }
170 }
171 
172 
173 template<typename Real> void CuBlockMatrixUnitTest() {
174  UnitTestCuBlockMatrixIO<Real>();
175  UnitTestCuBlockMatrixAddMatBlock<Real>();
176  UnitTestCuBlockMatrixAddMatMat<Real>();
177 }
178 
179 
180 } // namespace kaldi
181 
182 
183 int main() {
184  SetVerboseLevel(1);
185  int32 loop = 0;
186 #if HAVE_CUDA == 1
187  for (; loop < 2; loop++) {
188  CuDevice::Instantiate().SetDebugStrideMode(true);
189  if (loop == 0)
190  CuDevice::Instantiate().SelectGpuId("no"); // -1 means no GPU
191  else
192  CuDevice::Instantiate().SelectGpuId("yes"); // -2 .. automatic selection
193 #endif
194 
195  kaldi::CuBlockMatrixUnitTest<float>();
196 #if HAVE_CUDA == 1
197  if (CuDevice::Instantiate().DoublePrecisionSupported()) {
198  kaldi::CuBlockMatrixUnitTest<double>();
199  } else {
200  KALDI_WARN << "Double precision not supported";
201  }
202 #else
203  kaldi::CuBlockMatrixUnitTest<double>();
204 #endif
205 
206  if (loop == 0)
207  KALDI_LOG << "Tests without GPU use succeeded.";
208  else
209  KALDI_LOG << "Tests with GPU use (if available) succeeded.";
210 #if HAVE_CUDA == 1
211  }
212  CuDevice::Instantiate().PrintProfile();
213 #endif
214  return 0;
215 }
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
static void UnitTestCuBlockMatrixAddMatBlock()
void CuBlockMatrixUnitTest()
void CopyFromMat(const CuMatrix< Real > &M)
Copies elements within the block structure from matrix M, discarding others.
Real Sum() const
Definition: cu-matrix.cc:3012
void AddMatBlock(Real alpha, const CuMatrixBase< Real > &A, MatrixTransposeType transA, const CuBlockMatrix< Real > &B, MatrixTransposeType transB, Real beta)
This function is like AddMatMat but for where the second argument is of type CuBlockMatrix (a block-d...
Definition: cu-matrix.cc:3205
void swap(basic_filebuf< CharT, Traits > &x, basic_filebuf< CharT, Traits > &y)
The class CuBlockMatrix holds a vector of objects of type CuMatrix, say, M_1, M_2, .
kaldi::int32 int32
This class represents a matrix that&#39;s stored on the GPU if we have one, and in memory if not...
Definition: matrix-common.h:71
MatrixIndexT NumRows() const
void SetVerboseLevel(int32 i)
This should be rarely used, except by programs using Kaldi as library; command-line programs set the ...
Definition: kaldi-error.h:64
void AddMatMat(BaseFloat alpha, const CuMatrix< Real > &A, MatrixTransposeType transA, const CuMatrix< Real > &B, MatrixTransposeType transB, BaseFloat beta)
Does *this = alpha A B + beta * *this, discarding elements of the product outside the block structure...
#define KALDI_ERR
Definition: kaldi-error.h:147
void AddMatMat(Real alpha, const CuMatrixBase< Real > &A, MatrixTransposeType transA, const CuMatrixBase< Real > &B, MatrixTransposeType transB, Real beta)
C = alpha * A(^T)*B(^T) + beta * C.
Definition: cu-matrix.cc:1291
#define KALDI_WARN
Definition: kaldi-error.h:150
static void UnitTestCuBlockMatrixAddMatMat()
int Rand(struct RandomState *state)
Definition: kaldi-math.cc:45
static void UnitTestCuBlockMatrixIO()
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
MatrixTransposeType
Definition: matrix-common.h:32
static void AssertEqual(float a, float b, float relative_tolerance=0.001)
assert abs(a - b) <= relative_tolerance * (abs(a)+abs(b))
Definition: kaldi-math.h:276
void Read(std::istream &is, bool binary)
MatrixIndexT NumCols() const
#define KALDI_LOG
Definition: kaldi-error.h:153
static bool ApproxEqual(float a, float b, float relative_tolerance=0.001)
return abs(a - b) <= relative_tolerance * (abs(a)+abs(b)).
Definition: kaldi-math.h:265
int main()
void Write(std::ostream &os, bool binary) const