cu-sparse-matrix-test.cc
Go to the documentation of this file.
1 // cudamatrix/cu-sparse-matrix-test.cc
2 
3 // Copyright 2015 Guoguo Chen
4 // 2017 Shiyin Kang
5 
6 // See ../../COPYING for clarification regarding multiple authors
7 //
8 // Licensed under the Apache License, Version 2.0 (the "License");
9 // you may not use this file except in compliance with the License.
10 // You may obtain a copy of the License at
11 //
12 // http://www.apache.org/licenses/LICENSE-2.0
13 //
14 // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
16 // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
17 // MERCHANTABLITY OR NON-INFRINGEMENT.
18 // See the Apache 2 License for the specific language governing permissions and
19 // limitations under the License.
20 
21 #include <vector>
22 #include <algorithm>
23 #include <cstdlib>
24 
25 #include "base/kaldi-common.h"
26 #include "util/common-utils.h"
28 
29 using namespace kaldi;
30 
31 namespace kaldi {
32 
33 template<typename Real>
35  for (int32 i = 0; i < 2; i++) {
36  MatrixIndexT row = 10 + Rand() % 40;
37  MatrixIndexT col = 10 + Rand() % 50;
38 
39  MatrixTransposeType trans = (i % 2 == 0 ? kNoTrans : kTrans);
40 
41  std::vector<int32> idx(row);
42  Vector<Real> weights(row);
43  for (int i = 0; i < row; ++i) {
44  idx[i] = Rand() % col;
45  weights(i) = Rand() % 100;
46  }
47  CuArray<int32> cuidx(idx);
48  CuVector<Real> cuweights(weights);
49 
50  // construct smat
51  SparseMatrix<Real> smat1(idx, col, trans);
52  CuSparseMatrix<Real> cusmat1(cuidx, col, trans);
53 
54  // copy to mat
55  Matrix<Real> mat1(smat1.NumRows(), smat1.NumCols());
56  smat1.CopyToMat(&mat1);
57  CuMatrix<Real> cumat1(cusmat1.NumRows(), cusmat1.NumCols());
58  cusmat1.CopyToMat(&cumat1);
59 
60  // compare
61  Matrix<Real> mat1ver2(cumat1);
62  AssertEqual(mat1, mat1ver2, 0.00001);
63 
64  // construct smat with weights
65  SparseMatrix<Real> smat2(idx, weights, col, trans);
66  CuSparseMatrix<Real> cusmat2(cuidx, cuweights, col, trans);
67 
68  // copy to mat
69  Matrix<Real> mat2(smat2.NumRows(), smat2.NumCols());
70  smat2.CopyToMat(&mat2);
71  CuMatrix<Real> cumat2(cusmat2.NumRows(), cusmat2.NumCols());
72  cusmat2.CopyToMat(&cumat2);
73 
74  // compare
75  Matrix<Real> mat2ver2(cumat2);
76  AssertEqual(mat2, mat2ver2, 0.00001);
77  }
78 }
79 
80 
81 template <typename Real>
83  for (int32 i = 0; i < 2; i++) {
84  MatrixIndexT row = 10 + Rand() % 40;
85  MatrixIndexT col = 10 + Rand() % 50;
86 
87  SparseMatrix<Real> sp_input(row, col);
88  sp_input.SetRandn(0.8);
89  CuSparseMatrix<Real> cusp_input(sp_input);
90 
91  std::vector<int32> idx(row + col);
92  for (auto && e : idx) {
93  e = Rand() % row;
94  }
95  CuArray<int32> cu_idx(idx);
96 
97  // select on cpu
98  SparseMatrix<Real> sp_selected2;
99  sp_selected2.SelectRows(idx, sp_input);
100  // select on gpu
101  CuSparseMatrix<Real> cusp_selected;
102  cusp_selected.SelectRows(cu_idx, cusp_input);
103 
104  // transpose by CopyToMat
105  CuSparseMatrix<Real> cusp_selected2(sp_selected2);
106  CuMatrix<Real> cu_selected2_trans(cusp_selected2.NumCols(),
107  cusp_selected2.NumRows());
108  cusp_selected2.CopyToMat(&cu_selected2_trans, kTrans);
109  // transpose by Constructor
110  CuSparseMatrix<Real> cusp_selected_trans(cusp_selected, kTrans);
111  CuMatrix<Real> cu_selected_trans(cusp_selected_trans.NumRows(),
112  cusp_selected_trans.NumCols());
113  cusp_selected_trans.CopyToMat(&cu_selected_trans);
114 
115  CuMatrix<Real> cu_selected(row+col, col);
116  CuMatrix<Real> cu_selected2(row+col, col);
117  cusp_selected.CopyToMat(&cu_selected);
118  cusp_selected2.CopyToMat(&cu_selected2);
119 
120  AssertEqual(cu_selected, cu_selected2, 0.00001);
121  AssertEqual(cu_selected_trans, cu_selected2_trans, 0.00001);
122  }
123 }
124 
125 template <typename Real>
127  for (int32 i = 0; i < 2; i++) {
128  MatrixIndexT row = 10 + Rand() % 40;
129  MatrixIndexT col = 10 + Rand() % 50;
130 
131  CuMatrix<Real> mat1(row, col);
132  CuMatrix<Real> mat2(col, row);
133  CuMatrix<Real> mat3(row, col);
134  mat1.SetRandn();
135  mat2.SetRandn();
136  mat3.SetRandn();
137 
138  SparseMatrix<Real> smat1(row, col);
139  SparseMatrix<Real> smat2(col, row);
140  smat1.SetRandn(0.8);
141  smat2.SetRandn(0.8);
142  CuSparseMatrix<Real> cu_smat1x(smat1);
143  CuSparseMatrix<Real> cu_smat1(cu_smat1x); // Test constructor.
144  CuSparseMatrix<Real> cu_smat2(smat2);
145 
146  cu_smat1.CopyToMat(&mat1);
147  cu_smat2.CopyToMat(&mat2);
148 
149  Real trace1 = TraceMatMat(mat3, mat1, kTrans);
150  Real trace2 = TraceMatSmat(mat3, cu_smat1, kTrans);
151  AssertEqual(trace1, trace2, 0.00001);
152 
153  trace1 = TraceMatMat(mat3, mat2, kNoTrans);
154  trace2 = TraceMatSmat(mat3, cu_smat2, kNoTrans);
155  AssertEqual(trace1, trace2, 0.00001);
156  }
157 }
158 
159 template <typename Real>
161  for (int32 i = 0; i < 2; i++) {
162  MatrixIndexT row = 10 + Rand() % 40;
163  MatrixIndexT col = 10 + Rand() % 50;
164 
165  CuMatrix<Real> mat(row, col);
166  mat.SetRandn();
167 
168  SparseMatrix<Real> smat(row, col);
169  smat.SetRandn(0.8);
170  CuSparseMatrix<Real> cu_smat(smat);
171 
172  cu_smat.CopyToMat(&mat);
173 
174  Real sum1 = cu_smat.Sum();
175  Real sum2 = mat.Sum();
176  KALDI_ASSERT(fabs(sum1 - sum2) < 1.0e-04);
177  }
178 }
179 
180 template <typename Real>
182  for (int32 i = 0; i < 2; i++) {
183  MatrixIndexT row = 10 + Rand() % 40;
184  MatrixIndexT col = 10 + Rand() % 50;
185 
186  CuMatrix<Real> mat(row, col);
187  mat.SetRandn();
188 
189  SparseMatrix<Real> smat(row, col);
190  smat.SetRandn(0.8);
191  CuSparseMatrix<Real> cu_smat(smat);
192 
193  cu_smat.CopyToMat(&mat);
194 
195  Real sum1 = cu_smat.FrobeniusNorm();
196  Real sum2 = mat.FrobeniusNorm();
197  AssertEqual(sum1, sum2, 0.00001);
198  }
199 }
200 
201 template <typename Real>
203  for (int32 i = 0; i < 2; i++) {
204  MatrixIndexT row = 10 + Rand() % 40;
205  MatrixIndexT col = 10 + Rand() % 50;
206 
207  SparseMatrix<Real> smat1(row, col);
208  smat1.SetRandn(0.8);
209  CuSparseMatrix<Real> cu_smat1(smat1);
210 
211  SparseMatrix<Real> smat2(col, row);
212  cu_smat1.CopyToSmat(&smat2);
213  CuSparseMatrix<Real> cu_smat2(smat2);
214 
215  CuMatrix<Real> mat1(row, col);
216  CuMatrix<Real> mat2(row, col);
217 
218  cu_smat1.CopyToMat(&mat1);
219  cu_smat2.CopyToMat(&mat2);
220 
221  AssertEqual(mat1, mat2, 0.00001);
222  }
223 }
224 
225 template <typename Real>
227  for (int32 i = 0; i < 2; i++) {
228  MatrixIndexT row = 10 + Rand() % 40;
229  MatrixIndexT col = 10 + Rand() % 50;
230 
231  CuMatrix<Real> mat1, mat2, mat3, mat4;
232 
233  SparseMatrix<Real> smat1(row, col);
234  smat1.SetRandn(0.8);
235  SparseMatrix<Real> smat2 = smat1;
236  mat2.Resize(smat2.NumRows(), smat2.NumCols());
237  CuSparseMatrix<Real> tmp1(smat2);
238  tmp1.CopyToMat(&mat2);
239 
240  SparseMatrix<Real> smat3(col, row);
241  smat3.SetRandn(0.5);
242  CuSparseMatrix<Real> cu_smat1(smat3);
243  CuSparseMatrix<Real> cu_smat2 = cu_smat1;
244  mat4.Resize(cu_smat2.NumRows(), cu_smat2.NumCols());
245  cu_smat2.CopyToMat(&mat4);
246 
247  cu_smat1.Swap(&smat1);
248 
249  mat1.Resize(smat1.NumRows(), smat1.NumCols());
250  mat3.Resize(cu_smat1.NumRows(), cu_smat1.NumCols());
251  CuSparseMatrix<Real> tmp2(smat1);
252  tmp2.CopyToMat(&mat1);
253  cu_smat1.CopyToMat(&mat3);
254 
255  AssertEqual(mat3, mat2, 0.00001);
256  AssertEqual(mat1, mat4, 0.00001);
257 
258  cu_smat2.Swap(&cu_smat1);
259 
260  mat1.Resize(cu_smat1.NumRows(), cu_smat1.NumCols());
261  cu_smat1.CopyToMat(&mat1);
262  mat2.Resize(cu_smat2.NumRows(), cu_smat2.NumCols());
263  cu_smat2.CopyToMat(&mat2);
264 
265  AssertEqual(mat3, mat2, 0.00001);
266  AssertEqual(mat1, mat4, 0.00001);
267  }
268 }
269 
270 template <typename Real>
272  UnitTestCuSparseMatrixConstructFromIndexes<Real>();
273  UnitTestCuSparseMatrixSelectRowsAndTranspose<Real>();
274  UnitTestCuSparseMatrixTraceMatSmat<Real>();
275  UnitTestCuSparseMatrixSum<Real>();
276  UnitTestCuSparseMatrixFrobeniusNorm<Real>();
277  UnitTestCuSparseMatrixCopyToSmat<Real>();
278  UnitTestCuSparseMatrixSwap<Real>();
279 }
280 
281 
282 } // namespace kaldi
283 
284 
285 int main() {
286  int32 loop = 0;
287 #if HAVE_CUDA == 1
288  for (; loop < 2; loop++) {
289  CuDevice::Instantiate().SetDebugStrideMode(true);
290  if (loop == 0)
291  CuDevice::Instantiate().SelectGpuId("no");
292  else
293  CuDevice::Instantiate().SelectGpuId("yes");
294 #endif
295 
296  kaldi::CudaSparseMatrixUnitTest<float>();
297 
298 #if HAVE_CUDA == 1
299  if (CuDevice::Instantiate().DoublePrecisionSupported()) {
300  kaldi::CudaSparseMatrixUnitTest<double>();
301  } else {
302  KALDI_WARN << "Double precision not supported";
303  }
304 #else
305  kaldi::CudaSparseMatrixUnitTest<double>();
306 #endif
307 
308  if (loop == 0)
309  KALDI_LOG << "Tests without GPU use succeeded.";
310  else
311  KALDI_LOG << "Tests with GPU use (if available) succeeded.";
312  SetVerboseLevel(4);
313 #if HAVE_CUDA == 1
314  }
315  CuDevice::Instantiate().PrintProfile();
316 #endif
317  return 0;
318 }
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
MatrixIndexT NumRows() const
static void UnitTestCuSparseMatrixSwap()
void SelectRows(const std::vector< int32 > &row_indexes, const SparseMatrix< Real > &smat_other)
Select a subset of the rows of a SparseMatrix.
void CopyToMat(CuMatrixBase< OtherReal > *dest, MatrixTransposeType trans=kNoTrans) const
void Swap(SparseMatrix< Real > *smat)
Swap with CPU-based matrix.
static void UnitTestCuSparseMatrixFrobeniusNorm()
void CudaSparseMatrixUnitTest()
void SelectRows(const CuArray< int32 > &row_indexes, const CuSparseMatrix< Real > &smat_other)
Select a subset of the rows of a CuSparseMatrix.
Real Sum() const
Definition: cu-matrix.cc:3012
static void UnitTestCuSparseMatrixSum()
static void UnitTestCuSparseMatrixSelectRowsAndTranspose()
kaldi::int32 int32
A class for storing matrices.
Definition: kaldi-matrix.h:823
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
void CopyToMat(MatrixBase< OtherReal > *other, MatrixTransposeType t=kNoTrans) const
Copy to matrix. It must already have the correct size.
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
MatrixIndexT NumCols() const
int32 MatrixIndexT
Definition: matrix-common.h:98
static void UnitTestCuSparseMatrixTraceMatSmat()
static void UnitTestCuSparseMatrixConstructFromIndexes()
#define KALDI_WARN
Definition: kaldi-error.h:150
Real TraceMatMat(const MatrixBase< Real > &A, const MatrixBase< Real > &B, MatrixTransposeType trans)
We need to declare this here as it will be a friend function.
int Rand(struct RandomState *state)
Definition: kaldi-math.cc:45
void CopyToSmat(SparseMatrix< OtherReal > *smat) const
Copy to CPU-based matrix.
int main()
A class representing a vector.
Definition: kaldi-vector.h:406
void SetRandn(BaseFloat zero_prob)
Sets up to a pseudo-randomly initialized matrix, with each element zero with probability zero_prob an...
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
MatrixIndexT NumRows() const
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
Real FrobeniusNorm() const
Definition: cu-matrix.h:226
static void UnitTestCuSparseMatrixCopyToSmat()
Real TraceMatSmat(const MatrixBase< Real > &A, const SparseMatrix< Real > &B, MatrixTransposeType trans)
#define KALDI_LOG
Definition: kaldi-error.h:153
void Resize(MatrixIndexT rows, MatrixIndexT cols, MatrixResizeType resize_type=kSetZero, MatrixStrideType stride_type=kDefaultStride)
Allocate the memory.
Definition: cu-matrix.cc:50
MatrixIndexT NumCols() const