cu-vector-test.cc
Go to the documentation of this file.
1 // cudamatrix/cu-vector-test.cc
2 
3 // Copyright 2013 Lucas Ondel
4 // 2013 Johns Hopkins University (author: Daniel Povey)
5 // 2017 Hossein Hadian, Daniel Galvez
6 
7 // See ../../COPYING for clarification regarding multiple authors
8 //
9 // Licensed under the Apache License, Version 2.0 (the "License");
10 // you may not use this file except in compliance with the License.
11 // You may obtain a copy of the License at
12 //
13 // http://www.apache.org/licenses/LICENSE-2.0
14 //
15 // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
17 // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
18 // MERCHANTABLITY OR NON-INFRINGEMENT.
19 // See the Apache 2 License for the specific language governing permissions and
20 // limitations under the License.
21 
22 
23 #include <iostream>
24 #include <vector>
25 #include <cstdlib>
26 #include <cmath>
27 #include "base/kaldi-common.h"
28 #include "util/common-utils.h"
29 #include "cudamatrix/cu-matrix.h"
30 #include "cudamatrix/cu-vector.h"
33 #include "cudamatrix/cu-math.h"
34 
35 
36 namespace kaldi {
37 
38 /*
39  * INITIALIZERS
40  */
41 
42 
43 /*
44  * Unit tests
45  */
46 
47 template<class Real>
48 static void UnitTestCuVectorIO() {
49  for (int32 i = 0; i < 10; i++) {
50  int32 dimM = Rand() % 255;
51  if (i % 5 == 0) { dimM = 0; }
52  CuVector<Real> vec(dimM);
53  vec.SetRandn();
54  std::ostringstream os;
55  bool binary = (i % 4 < 2);
56  vec.Write(os, binary);
57 
58  CuVector<Real> vec2;
59  std::istringstream is(os.str());
60  vec2.Read(is, binary);
61  AssertEqual(vec, vec2);
62  }
63 }
64 
65 
66 template<typename Real, typename OtherReal>
68  for (int32 i = 1; i < 10; i++) {
69  MatrixIndexT dim = 10 * i;
70  Vector<Real> A(dim);
71  A.SetRandn();
73  Vector<Real> C(B);
74  CuVector<Real> D(dim);
75  D.CopyFromVec(C);
76  Vector<OtherReal> E(dim);
77  E.CopyFromVec(D);
78  CuVector<Real> F(E);
79  CuVector<Real> A2(A);
80  AssertEqual(F, A2);
81  }
82 }
83 
84 template<typename Real>
85 static void UnitTestCuSubVector() {
86  for (int32 iter = 0 ; iter < 10; iter++) {
87  int32 M1 = 1 + rand () % 10, M2 = 1 + Rand() % 1, M3 = 1 + Rand() % 10, M = M1 + M2 + M3,
88  m = Rand() % M2;
89  CuVector<Real> vec(M);
90  vec.SetRandn();
91  CuSubVector<Real> subvec1(vec, M1, M2),
92  subvec2 = vec.Range(M1, M2);
93  Real f1 = vec(M1 + m), f2 = subvec1(m), f3 = subvec2(m);
94  KALDI_ASSERT(f1 == f2);
95  KALDI_ASSERT(f2 == f3);
96  }
97 }
98 
99 
100 
101 template<typename Real>
102 static void UnitTestCuVectorMulTp() {
103  for (int32 i = 1; i < 10; i++) {
104  MatrixIndexT dim = 10 * i;
105  Vector<Real> A(dim);
106  A.SetRandn();
107  TpMatrix<Real> B(dim);
108  B.SetRandn();
109 
110  CuVector<Real> C(A);
111  CuTpMatrix<Real> D(B);
112 
113  A.MulTp(B, kNoTrans);
114  C.MulTp(D, kNoTrans);
115 
116  CuVector<Real> E(A);
117  AssertEqual(C, E);
118  }
119 }
120 
121 template<typename Real>
122 static void UnitTestCuVectorAddTp() {
123  for (int32 i = 1; i < 10; i++) {
124  MatrixIndexT dim = 10 * i;
125  Vector<Real> A(dim);
126  A.SetRandn();
127  TpMatrix<Real> B(dim);
128  B.SetRandn();
129  Vector<Real> C(dim);
130  C.SetRandn();
131 
132  CuVector<Real> D(A);
133  CuTpMatrix<Real> E(B);
134  CuVector<Real> F(C);
135 
136  A.AddTpVec(1.0, B, kNoTrans, C, 1.0);
137  D.AddTpVec(1.0, E, kNoTrans, F, 1.0);
138 
139  CuVector<Real> G(A);
140  AssertEqual(D, G);
141  }
142 }
143 
144 template<typename Real> void CuVectorUnitTestVecVec() {
145  int32 M = 10 + Rand() % 100;
146  CuVector<Real> vec1(M), vec2(M);
147  vec1.SetRandn();
148  vec2.SetRandn();
149  Real prod = 0.0;
150  for (int32 i = 0; i < M; i++)
151  prod += vec1(i) * vec2(i);
152  AssertEqual(prod, VecVec(vec1, vec2));
153 }
154 
155 template<typename Real> void CuVectorUnitTestAddVec() {
156  int32 M = 10 + Rand() % 100;
157  CuVector<Real> vec1(M);
158  CuVector<Real> vec2(M);
159  vec1.SetRandn();
160  vec2.SetRandn();
161  CuVector<Real> vec1_orig(vec1);
162  BaseFloat alpha = 0.43243;
163  vec1.AddVec(alpha, vec2);
164 
165  for (int32 i = 0; i < M; i++)
166  AssertEqual(vec1_orig(i) + alpha * vec2(i), vec1(i));
167 }
168 
169 template<typename Real> void CuVectorUnitTestAddVecCross() {
170  for (int32 i = 0; i < 4; i++) {
171  int32 M = 10 + Rand() % 100;
172  CuVector<float> vec1(M);
173  CuVector<Real> vec2(M);
174  vec1.SetRandn();
175  vec2.SetRandn();
176 
177  if (i == 0) {
178  CuVector<Real> vec1_orig(vec1);
179  Real alpha = 0.43243;
180  vec1.AddVec(alpha, vec2);
181 
182  for (int32 i = 0; i < M; i++)
183  AssertEqual(vec1_orig(i) + alpha * vec2(i), vec1(i));
184  } else {
185  CuVector<Real> vec2_orig(vec2);
186  Real alpha = 0.43243;
187  vec2.AddVec(alpha, vec1);
188  for (int32 i = 0; i < M; i++)
189  AssertEqual(vec2_orig(i) + alpha * vec1(i), vec2(i));
190  }
191  }
192 }
193 
194 template<typename Real> void CuVectorUnitTestAddVecExtra() {
195  int32 M = 10 + Rand() % 100;
196  CuVector<Real> vec1(M), vec2(M);
197  vec1.SetRandn();
198  vec2.SetRandn();
199  CuVector<Real> vec1_orig(vec1);
200  BaseFloat alpha = 0.43243, beta = 1.4321;
201  vec1.AddVec(alpha, vec2, beta);
202 
203  for (int32 i = 0; i < M; i++)
204  AssertEqual(beta * vec1_orig(i) + alpha * vec2(i), vec1(i));
205 }
206 
207 template<typename Real> void CuVectorUnitTestCopyElements() {
208  int32 dim = 10 + Rand() % 100, N = 20 + Rand() % 50;
209  CuVector<Real> V(dim);
210  V.SetRandn();
211  CuVector<Real> V_copy(V);
212  for (int n = 0; n < 2; n++) {
213  bool transpose = (n == 0);
214  CuMatrix<Real> M;
215  if (!transpose)
216  M.Resize(dim, N, kUndefined);
217  else
218  M.Resize(N, dim, kUndefined);
219  M.SetRandn();
220  std::vector<int32> elements(dim);
221  for (int32 i = 0; i < dim; i++) {
222  int32 j = elements[i] = Rand() % N;
223  if (!transpose)
224  V_copy(i) = M(i, j);
225  else
226  V_copy(i) = M(j, i);
227  }
228  CuArray<int32> cu_elements(elements);
229  V.CopyElements(M, transpose ? kTrans : kNoTrans, cu_elements);
230  AssertEqual(V, V_copy);
231  }
232 }
233 
234 template<typename Real> void UnitTestVecMatVec() {
235  int32 NR = 10 + Rand() % 100, NC = 20 + Rand() % 100;
236  CuVector<Real> v1(NR), v2(NC);
237  v1.SetRandn();
238  v2.SetRandn();
239  CuMatrix<Real> M(NR, NC);
240  M.SetRandn();
241  Real sum = 0;
242  for (int32 i = 0; i < NR; i++)
243  for (int32 j = 0; j < NC; j++)
244  sum += v1(i) * M(i, j) * v2(j);
245  Real result = VecMatVec(v1, M, v2);
246  AssertEqual(sum, result);
247 }
248 
249 template<typename Real> void CuVectorUnitTestAddRowSumMat() {
250  int32 M = 10 + Rand() % 280, N = 10 + Rand() % 20;
251  BaseFloat alpha = 10.0143432, beta = 43.4321;
252  CuMatrix<Real> mat(N, M);
253  mat.SetRandn();
254  CuVector<Real> vec(M);
255  mat.SetRandn();
256  Matrix<Real> mat2(mat);
257  Vector<Real> vec2(M);
258  vec.AddRowSumMat(alpha, mat, beta);
259  vec2.AddRowSumMat(alpha, mat2, beta);
260  Vector<Real> vec3(vec);
261  AssertEqual(vec2, vec3);
262 }
263 
264 template<typename Real> void CuVectorUnitTestAddColSumMat() {
265  int32 M = 10 + Rand() % 280, N = 10 + Rand() % 20;
266  BaseFloat alpha = 10.0143432, beta = 43.4321;
267  CuMatrix<Real> mat(M, N);
268  mat.SetRandn();
269  CuVector<Real> vec(M);
270  mat.SetRandn();
271  Matrix<Real> mat2(mat);
272  Vector<Real> vec2(M);
273  vec.AddColSumMat(alpha, mat, beta);
274  vec2.AddColSumMat(alpha, mat2, beta);
275  Vector<Real> vec3(vec);
276  AssertEqual(vec2, vec3);
277 }
278 
279 
280 template<typename Real> void CuVectorUnitTestApproxEqual() {
281  int32 M = 10 + Rand() % 100;
282  CuVector<Real> vec1(M), vec2(M);
283  vec1.SetRandn();
284  vec2.SetRandn();
285  Real tol = 0.5;
286  for (int32 i = 0; i < 10; i++) {
287  Real sumsq = 0.0, sumsq_orig = 0.0;
288  for (int32 j = 0; j < M; j++) {
289  sumsq += (vec1(j) - vec2(j)) * (vec1(j) - vec2(j));
290  sumsq_orig += vec1(j) * vec1(j);
291  }
292  Real rms = sqrt(sumsq), rms_orig = sqrt(sumsq_orig);
293  KALDI_ASSERT(vec1.ApproxEqual(vec2, tol) == (rms <= tol * rms_orig));
294  tol *= 2.0;
295  }
296 }
297 
298 template<typename Real> static void UnitTestCuVectorReplaceValue() {
299  for (int32 i = 0; i < 5; i++) {
300  int32 dim = 100 + Rand() % 200;
301  Real orig = 0.1 * (Rand() % 100), changed = 0.1 * (Rand() % 50);
302  Vector<Real> vec(dim);
303  vec.SetRandn();
304  vec(dim / 2) = orig;
305  CuVector<Real> vec1(vec);
306  vec.ReplaceValue(orig, changed);
307  vec1.ReplaceValue(orig, changed);
308  Vector<Real> vec2(vec1);
309  AssertEqual(vec, vec2);
310  }
311 }
312 
313 template<typename Real> static void UnitTestCuVectorSum() {
314  for (int32 i = 0; i < 200; i++) {
315  int32 start_dim = RandInt(1, 500), end_dim = RandInt(1, 500);
316  int32 dim = RandInt(10, 12000) + start_dim + end_dim;
317  Real quiet_nan = nan(""); // this is from <cmath>.
318  Vector<BaseFloat> vec(start_dim + dim + end_dim);
319  vec.Range(0, start_dim).Set(quiet_nan);
320  vec.Range(start_dim, dim).Set(1.0);
321  vec.Range(start_dim + dim, end_dim).Set(quiet_nan);
322  BaseFloat sum = vec.Range(start_dim, dim).Sum();
323  KALDI_ASSERT(ApproxEqual(sum, dim));
324  }
325 }
326 
327 template<typename Real> void CuVectorUnitTestInvertElements() {
328  // Also tests MulElements();
329  int32 M = 256 + Rand() % 100;
330  CuVector<Real> vec1(M);
331  vec1.SetRandn();
332  CuVector<Real> vec2(vec1);
333  vec2.InvertElements();
334  CuVector<Real> vec3(vec1);
335  vec3.MulElements(vec2);
336  // vec3 should be all ones.
337  Real prod = VecVec(vec3, vec3);
338  AssertEqual(prod, static_cast<Real>(M));
339 }
340 
341 template<typename Real> void CuVectorUnitTestSum() {
342  for (int32 p = 1; p <= 1000000; p *= 2) {
343  MatrixIndexT dim = p + Rand() % 500;
344  CuVector<Real> A(dim), ones(dim);
345  A.SetRandn();
346  ones.Set(1.0);
347 
348  Real x = VecVec(A, ones);
349  Real y = A.Sum();
350  Real diff = std::abs(x - y);
351  // Note: CuVectorBase<> does not have an ApplyAbs() member
352  // function, so we copy back to a host vector for simplicity in
353  // this test case.
354  Vector<Real> A_host(A);
355  A_host.ApplyAbs();
356  Real s = A_host.Sum();
357  KALDI_ASSERT ( diff <= 1.0e-04 * s);
358  }
359 }
360 
361 template<typename Real> void CuVectorUnitTestScale() {
362  for (int32 i = 0; i < 4; i++) {
363  int32 dim = 100 + Rand() % 400;
364  CuVector<Real> cu_vec(dim);
365  cu_vec.SetRandn();
366  Vector<Real> vec(cu_vec);
367  BaseFloat scale = 0.333;
368  cu_vec.Scale(scale);
369  vec.Scale(scale);
370  Vector<Real> vec2(cu_vec);
371  KALDI_ASSERT(ApproxEqual(vec, vec2));
372  }
373 }
374 
375 template<typename Real> void CuVectorUnitTestCopyFromMat() {
376  int32 M = 100 + Rand() % 255, N = 100 + Rand() % 255;
377  CuMatrix<Real> cu_matrix(M, N);
378  cu_matrix.SetRandn();
379  for(int32 i = 0; i < N; i++) {
380  CuVector<Real> vector(M);
381  vector.CopyColFromMat(cu_matrix, i);
382  for(int32 j = 0; j < M; j++) {
383  KALDI_ASSERT(vector(j)==cu_matrix(j, i));
384  }
385  }
386  Matrix<Real> matrix(cu_matrix), matrix2(M, N);
387  CuMatrix<Real> matrix3(M, N);
388 
389  CuVector<Real> vector(M * N), vector2(M * N);
390  vector.CopyRowsFromMat(cu_matrix);
391  vector2.CopyRowsFromMat(matrix);
392  matrix2.CopyRowsFromVec(vector2);
393  matrix3.CopyRowsFromVec(Vector<Real>(vector2));
394  Vector<Real> vector3(M * N);
395  vector3.CopyRowsFromMat(cu_matrix);
396 
397 
398  for(int32 j = 0; j < M*N; j++) {
399  if (Rand() % 500 == 0) { // random small subset (it was slow)
400  KALDI_ASSERT(vector(j) == cu_matrix(j/N, j%N));
401  KALDI_ASSERT(vector2(j) == cu_matrix(j/N, j%N));
402  KALDI_ASSERT(vector2(j) == matrix2(j/N, j%N));
403  KALDI_ASSERT(vector3(j) == matrix2(j/N, j%N));
404  KALDI_ASSERT(vector3(j) == matrix3(j/N, j%N));
405  }
406  }
407 }
408 
409 template<typename Real> void CuVectorUnitTestCopyDiagFromPacked() {
410  for (int32 i = 0; i < 5; i++) {
411  int32 N = 100 + Rand() % 255;
412  CuSpMatrix<Real> S(N);
413  S.SetRandn();
415  V.CopyDiagFromPacked(S);
416  SpMatrix<Real> cpu_S(S);
417  Vector<Real> cpu_V(N);
418  cpu_V.CopyDiagFromPacked(cpu_S);
419  Vector<Real> cpu_V2(V);
420  KALDI_ASSERT(cpu_V.ApproxEqual(cpu_V2));
421  }
422 }
423 
424 template<typename Real> void CuVectorUnitTestCopyCross() {
425  for (int32 i = 0; i < 10; i++) {
426  int32 M = 100 + Rand() % 255;
427  if (Rand() % 3 == 0) M = 0;
428  CuVector<Real> v1(M);
429  v1.SetRandn();
430  CuVector<float> v2(M);
431  v2.CopyFromVec(v1);
432  CuVector<Real> v3(M);
433  v3.CopyFromVec(v2);
434  AssertEqual(v1, v3);
435  }
436 }
437 
438 template<typename Real> void CuVectorUnitTestCopyCross2() {
439  for (int32 i = 0; i < 10; i++) {
440  int32 M = 100 + Rand() % 255;
441  if (Rand() % 3 == 0) M = 0;
442  CuVector<Real> v1(M);
443  v1.SetRandn();
444  Vector<float> v2(M);
445  v2.CopyFromVec(v1);
446  CuVector<Real> v3(M);
447  v3.CopyFromVec(v2);
448  AssertEqual(v1, v3);
449  }
450 }
451 
452 template<typename Real> void CuVectorUnitTestCopyDiagFromMat() {
453  for (int32 i = 0; i < 5; i++) {
454  int32 M = 100 + Rand() % 255, N = M + Rand() % 2;
455  Matrix<Real> matrix(M, N);
456  if (i % 2 == 0) matrix.Transpose();
457  matrix.SetRandn();
458  Vector<Real> vector(M, kUndefined);
459  vector.CopyDiagFromMat(matrix);
460 
461  CuMatrix<Real> cuda_matrix(matrix);
462  CuVector<Real> cuda_vector(M, kUndefined);
463  cuda_vector.CopyDiagFromMat(cuda_matrix);
464  Vector<Real> vector2(cuda_vector);
465  AssertEqual(vector, vector2);
466  AssertEqual(vector.Sum(), cuda_matrix.Trace(false));
467  AssertEqual(cuda_vector.Sum(), matrix.Trace(false));
468  }
469 }
470 
471 
472 template<typename Real> void CuVectorUnitTestNorm() {
473  int32 dim = 2;
474  CuVector<Real> cu_vector(dim);
475  cu_vector(0) = 1.0;
476  cu_vector(1) = -2.0;
477  KALDI_ASSERT(ApproxEqual(cu_vector.Norm(1.0), 3.0));
478  KALDI_ASSERT(ApproxEqual(cu_vector.Norm(2.0), sqrt(5.0)));
479 }
480 
481 
482 template<typename Real> void CuVectorUnitTestMin() {
483  for (int32 p = 1; p <= 1000000; p *= 2) {
484  int32 dim = p + Rand() % 500;
485  CuVector<Real> cu_vector(dim);
486  cu_vector.SetRandn();
487  Vector<Real> vector(cu_vector);
488  Real min1 = cu_vector.Min(), min2 = vector.Min();
489  KALDI_ASSERT(min1 == min2);
490  }
491 }
492 
493 
494 template<typename Real> void CuVectorUnitTestMax() {
495  for (int32 p = 1; p <= 1000000; p *= 2) {
496  int32 dim = p + Rand() % 500;
497  CuVector<Real> cu_vector(dim);
498  cu_vector.SetRandn();
499  Vector<Real> vector(cu_vector);
500  Real max1 = cu_vector.Max(), max2 = vector.Max();
501  KALDI_ASSERT(max1 == max2);
502  }
503 }
504 
505 
506 template<typename Real> void CuVectorUnitTestApplySoftMax() {
507  for (int32 i = 0; i < 10; i++) {
508  int32 dim = 100 + Rand() % 300;
509  //int32 dim = 1024;
510  CuVector<Real> cu_vector(dim);
511  cu_vector.SetRandn();
512  Vector<Real> vector(cu_vector);
513 
514  cu_vector.ApplySoftMax();
515  vector.ApplySoftMax();
516  CuVector<Real> cu_vector2(vector);
517  //std::cout<<cu_vector <<"\n"<<cu_vector2<<std::endl;
518  AssertEqual(cu_vector, cu_vector2);
519  }
520 }
521 
522 template<typename Real> void CuVectorUnitTestApplyExp() {
523  int32 dim = 100;
524  CuVector<Real> vector(dim);
525  vector.SetRandn();
526  CuVector<Real> vector2(vector);
527 
528  vector.ApplyExp();
529  for(int32 j = 0; j < dim; j++) {
530  //std::cout<<"diff is "<<exp(vector2(j))-vector(j)<<std::endl;;
531  KALDI_ASSERT(std::abs(Exp(vector2(j))-vector(j)) < 0.00001);
532  }
533 
534 }
535 
536 template<typename Real> void CuVectorUnitTestApplyLog() {
537  int32 dim = 100;
538  CuVector<Real> vector(dim);
539  vector.SetRandn();
540  for(int32 j = 0; j < dim; j++) {
541  if(vector(j) <= 0.0)
542  vector(j) = 1.0 - vector(j);
543  }
544 
545  CuVector<Real> vector2(vector);
546 
547  vector.ApplyLog();
548  for(int32 j = 0; j < dim; j++) {
549  //std::cout<<"diff is "<<exp(vector2(j))-vector(j)<<std::endl;;
550  KALDI_ASSERT(std::abs(Log(vector2(j))-vector(j)) < 0.000001 );
551  }
552 }
553 
554 template<typename Real> void CuVectorUnitTestApplyFloor() {
555  for (int32 l = 0; l < 10; l++) {
556  int32 dim = 100 + Rand() % 700;
557  CuVector<Real> cu_vector(dim);
558  cu_vector.SetRandn();
559 
560  Vector<Real> vector(cu_vector);
561  BaseFloat floor = 0.33 * (-5 + Rand() % 10);
562  MatrixIndexT i, j;
563  cu_vector.ApplyFloor(floor, &i);
564  vector.ApplyFloor(floor, &j);
565 
566  CuVector<Real> cu2(vector);
567 
568  AssertEqual(cu2, cu_vector);
569  if (i != j) {
570  KALDI_WARN << "ApplyFloor return code broken...";
571  }
572  KALDI_ASSERT(i==j);
573  }
574 }
575 
576 template<typename Real> void CuVectorUnitTestApplyFloorNoCount() {
577  for (int32 l = 0; l < 10; l++) {
578  int32 dim = 100 + Rand() % 700;
579  CuVector<Real> cu_vector1(dim);
580  cu_vector1.SetRandn();
581  CuVector<Real> cu_vector2(cu_vector1);
582 
583  BaseFloat floor = 0.33 * (-5 + Rand() % 10);
584  MatrixIndexT dummy_count;
585  cu_vector1.ApplyFloor(floor, &dummy_count);
586  cu_vector2.ApplyFloor(floor, nullptr);
587  AssertEqual(cu_vector1, cu_vector2);
588  }
589 }
590 
591 template<typename Real> void CuVectorUnitTestApplyCeiling() {
592  for (int32 l = 0; l < 10; l++) {
593  int32 dim = 100 + Rand() % 700;
594  CuVector<Real> cu_vector(dim);
595  cu_vector.SetRandn();
596 
597  Vector<Real> vector(cu_vector);
598  BaseFloat floor = 0.33 * (-5 + Rand() % 10);
599  MatrixIndexT i, j;
600  cu_vector.ApplyCeiling(floor, &i);
601  vector.ApplyCeiling(floor, &j);
602 
603  CuVector<Real> cu2(vector);
604 
605  AssertEqual(cu2, cu_vector);
606  if (i != j) {
607  KALDI_WARN << "ApplyCeiling return code broken...";
608  }
609  KALDI_ASSERT(i==j);
610  }
611 }
612 
613 template<typename Real> void CuVectorUnitTestApplyCeilingNoCount() {
614  for (int32 l = 0; l < 10; l++) {
615  int32 dim = 100 + Rand() % 700;
616  CuVector<Real> cu_vector1(dim);
617  cu_vector1.SetRandn();
618  CuVector<Real> cu_vector2(cu_vector1);
619 
620  BaseFloat floor = 0.33 * (-5 + Rand() % 10);
621  MatrixIndexT dummy_count;
622  cu_vector1.ApplyCeiling(floor, &dummy_count);
623  cu_vector2.ApplyCeiling(floor, nullptr);
624  AssertEqual(cu_vector1, cu_vector2);
625  }
626 }
627 
628 template<typename Real> void CuVectorUnitTestApplyPow() {
629  for (int32 l = 0; l < 10; l++) {
630  int32 dim = 100 + Rand() % 700;
631 
632  CuVector<Real> cu_vector(dim);
633  cu_vector.SetRandn();
634 
635  Vector<Real> vector(cu_vector);
636 
637  BaseFloat pow = -2 + (Rand() % 5);
638  cu_vector.ApplyPow(pow);
639  vector.ApplyPow(pow);
640 
641  CuVector<Real> cu2(vector);
642 
643  AssertEqual(cu2, cu_vector);
644  }
645 }
646 
647 template<typename Real> void CuVectorUnitTestAddVecVec() {
648  int32 dim = 100;
649  CuVector<Real> cu_vector(dim);
650  cu_vector.SetRandn();
651  Vector<Real> vector(cu_vector);
652 
653  Real beta = Rand();
654  Real alpha = Rand();
655  Vector<Real> v(dim), r(dim);
656  v.SetRandn(); r.SetRandn();
657  CuVector<Real> cuV(v), cuR(r);
658 
659 
660  cu_vector.AddVecVec(alpha, cuR, cuV, beta);
661  vector.AddVecVec(alpha, r, v, beta);
662 
663  CuVector<Real> cu2(vector);
664  std::cout<<cu2(0)<<' '<<cu_vector(0)<<std::endl;
665  AssertEqual(cu2, cu_vector);
666 }
667 
668 template<typename Real> void CuVectorUnitTestAddDiagMat2() {
669  for (int p = 0; p < 4; p++) {
670  int32 M = 230 + Rand() % 100, N = 230 + Rand() % 100;
671  BaseFloat alpha = 0.2 + Rand() % 3, beta = 0.3 + Rand() % 2;
672  CuVector<Real> cu_vector(M);
673  cu_vector.SetRandn();
674 
675  CuMatrix<Real> cu_mat_orig(M, N);
676  cu_mat_orig.SetRandn();
677  MatrixTransposeType trans = (p % 2 == 0 ? kNoTrans : kTrans);
678  CuMatrix<Real> cu_mat(cu_mat_orig, trans);
679 
680  Vector<Real> vector(cu_vector);
681  Matrix<Real> mat(cu_mat);
682 
683  vector.AddDiagMat2(alpha, mat, trans, beta);
684  cu_vector.AddDiagMat2(alpha, cu_mat, trans, beta);
685 
686  Vector<Real> vector2(cu_vector);
687  AssertEqual(vector, vector2);
688  }
689 }
690 
691 template<typename Real>
693  for (MatrixIndexT iter = 0; iter < 4; iter++) {
694  BaseFloat alpha = 0.432 + Rand() % 5, beta = 0.043 + Rand() % 2;
695  MatrixIndexT dimM = 10 + Rand() % 300,
696  dimN = 5 + Rand() % 300;
697  CuVector<Real> v(dimM);
698  CuMatrix<Real> M_orig(dimM, dimN), N_orig(dimN, dimM);
699  M_orig.SetRandn();
700  N_orig.SetRandn();
701  MatrixTransposeType transM = (iter % 2 == 0 ? kNoTrans : kTrans);
702  MatrixTransposeType transN = ((iter/2) % 2 == 0 ? kNoTrans : kTrans);
703  CuMatrix<Real> M(M_orig, transM), N(N_orig, transN);
704 
705  v.SetRandn();
706  CuVector<Real> w(v);
707 
708  w.AddDiagMatMat(alpha, M, transM, N, transN, beta);
709 
710  {
711  CuVector<Real> w2(v);
712  CuMatrix<Real> MN(dimM, dimM);
713  MN.AddMatMat(1.0, M, transM, N, transN, 0.0);
714  CuVector<Real> d(dimM);
715  d.CopyDiagFromMat(MN);
716  w2.Scale(beta);
717  w2.AddVec(alpha, d);
718  AssertEqual(w, w2);
719  }
720  }
721 }
722 
723 
724 
725 template<typename Real> void CuVectorUnitTestAddMatVec() {
726  for (int32 i = 0; i < 10; i++) {
727  int32 M = 10 + Rand() % 500, N = 10 + Rand() % 400;
728 
729  bool transpose = (i % 2 == 0);
730 
731  CuVector<Real> src_cu(M);
732  src_cu.SetRandn();
733  Vector<Real> src(src_cu);
734 
735  CuVector<Real> dst_cu(N);
736  dst_cu.SetRandn();
737  Vector<Real> dst(dst_cu);
738 
739  CuMatrix<Real> mat_cu(transpose ? M : N, transpose ? N : M);
740  mat_cu.SetRandn();
741  Matrix<Real> mat(mat_cu);
742 
743  BaseFloat alpha = 0.5 * (Rand() % 10), beta = 0.5 * (Rand() % 10);
744  dst_cu.AddMatVec(alpha, mat_cu, transpose ? kTrans : kNoTrans,
745  src_cu, beta);
746  dst.AddMatVec(alpha, mat, transpose ? kTrans : kNoTrans,
747  src, beta);
748  Vector<Real> dst2(dst_cu);
749  AssertEqual(dst, dst2);
750  }
751 }
752 
753 
754 template<typename Real> void CuVectorUnitTestAddSpVec() {
755  for (int32 i = 0; i < 5; i++) {
756  int32 M = 100 + Rand() % 256;
757 
758  CuVector<Real> src_cu(M);
759  src_cu.SetRandn();
760  Vector<Real> src(src_cu);
761 
762  CuVector<Real> dst_cu(M);
763  dst_cu.SetRandn();
764  Vector<Real> dst(dst_cu);
765 
766  CuSpMatrix<Real> mat_cu(M);
767  mat_cu.SetRandn();
768  SpMatrix<Real> mat(mat_cu);
769 
770  BaseFloat alpha = 0.5 * (Rand() % 5), beta = 0.5 * (Rand() % 5);
771  dst_cu.AddSpVec(alpha, mat_cu, src_cu, beta);
772  dst.AddSpVec(alpha, mat, src, beta);
773  Vector<Real> dst2(dst_cu);
774  AssertEqual(dst, dst2);
775  }
776 }
777 
778 
779 
780 template<typename Real> void CuVectorUnitTest() {
781  UnitTestCuVectorCopyFromVec<Real, float>();
782 #if HAVE_CUDA == 1
783  if (CuDevice::Instantiate().DoublePrecisionSupported())
784 #endif
785  UnitTestCuVectorCopyFromVec<Real, double>();
786  UnitTestCuVectorIO<Real>();
787  CuVectorUnitTestVecVec<Real>();
788  CuVectorUnitTestAddVec<Real>();
789  CuVectorUnitTestAddVecCross<Real>();
790  CuVectorUnitTestAddVecExtra<Real>();
791  CuVectorUnitTestApproxEqual<Real>();
792  CuVectorUnitTestScale<Real>();
793  CuVectorUnitTestSum<Real>();
794  CuVectorUnitTestInvertElements<Real>();
795  UnitTestCuVectorSum<Real>();
796  CuVectorUnitTestAddRowSumMat<Real>();
797  CuVectorUnitTestAddColSumMat<Real>();
798  UnitTestCuVectorReplaceValue<Real>();
799  UnitTestCuVectorAddTp<Real>();
800  UnitTestCuVectorMulTp<Real>();
801  UnitTestCuSubVector<Real>();
802  CuVectorUnitTestCopyFromMat<Real>();
803  CuVectorUnitTestMin<Real>();
804  CuVectorUnitTestMax<Real>();
805  CuVectorUnitTestApplySoftMax<Real>();
806  CuVectorUnitTestCopyDiagFromPacked<Real>();
807  CuVectorUnitTestCopyDiagFromMat<Real>();
808  CuVectorUnitTestCopyCross<Real>();
809  CuVectorUnitTestCopyCross2<Real>();
810  CuVectorUnitTestNorm<Real>();
811  CuVectorUnitTestApplyExp<Real>();
812  CuVectorUnitTestApplyLog<Real>();
813  CuVectorUnitTestApplyFloor<Real>();
814  CuVectorUnitTestApplyFloorNoCount<Real>();
815  CuVectorUnitTestApplyCeilingNoCount<Real>();
816  CuVectorUnitTestApplyCeiling<Real>();
817  CuVectorUnitTestApplyPow<Real>();
818  CuVectorUnitTestAddMatVec<Real>();
819  CuVectorUnitTestAddSpVec<Real>();
820  CuVectorUnitTestAddVecVec<Real>();
821  CuVectorUnitTestAddDiagMat2<Real>();
822  CuVectorUnitTestAddDiagMatMat<Real>();
823  CuVectorUnitTestCopyElements<Real>();
824  UnitTestVecMatVec<Real>();
825 }
826 
827 
828 } // namespace kaldi
829 
830 
831 int main(int argc, char *argv[]) {
832  using namespace kaldi;
833  SetVerboseLevel(1);
834  const char *usage = "Usage: cu-vector-test [options]";
835 
836  ParseOptions po(usage);
837  std::string use_gpu = "yes";
838  po.Register("use-gpu", &use_gpu, "yes|no|optional");
839  po.Read(argc, argv);
840 
841  if (po.NumArgs() != 0) {
842  po.PrintUsage();
843  exit(1);
844  }
845 
846  int32 loop = 0;
847 #if HAVE_CUDA == 1
848  for (; loop < 2; loop++) {
849  CuDevice::Instantiate().SetDebugStrideMode(true);
850  if (loop == 0)
851  CuDevice::Instantiate().SelectGpuId("no"); // -1 means no GPU
852  else
853  CuDevice::Instantiate().SelectGpuId(use_gpu);
854 #endif
855 
856  kaldi::CuVectorUnitTest<float>();
857 #if HAVE_CUDA == 1
858  if (CuDevice::Instantiate().DoublePrecisionSupported()) {
859  kaldi::CuVectorUnitTest<double>();
860  } else {
861  KALDI_WARN << "Double precision not supported";
862  }
863 #else
864  kaldi::CuVectorUnitTest<double>();
865 #endif
866 
867  if (loop == 0)
868  KALDI_LOG << "Tests without GPU use succeeded.";
869  else
870  KALDI_LOG << "Tests with GPU use (if available) succeeded.";
871 #if HAVE_CUDA == 1
872  }
873  CuDevice::Instantiate().PrintProfile();
874 #endif
875  return 0;
876 }
void MulElements(const CuVectorBase< Real > &v)
Definition: cu-vector.cc:838
void CuVectorUnitTestCopyCross2()
bool ApproxEqual(const VectorBase< Real > &other, float tol=0.01) const
Returns true if ((*this)-other).Norm(2.0) <= tol * (*this).Norm(2.0).
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
double Exp(double x)
Definition: kaldi-math.h:83
Packed symetric matrix class.
Definition: matrix-common.h:62
void CopyDiagFromPacked(const CuPackedMatrix< Real > &M)
Extracts the diagonal of a packed matrix M; works for Sp or Tp.
Definition: cu-vector.cc:1177
Real Trace(bool check_square=true) const
Return the trace. If check_square = true, will crash if matrix is not square.
Definition: cu-matrix.cc:3075
void CuVectorUnitTestApproxEqual()
void CuVectorUnitTestInvertElements()
void CuVectorUnitTestApplyCeiling()
void MulTp(const CuTpMatrix< Real > &M, const MatrixTransposeType trans)
Multiplies this vector by lower-triangular marix: *this <– *this *M.
Definition: cu-vector.cc:727
void AddRowSumMat(Real alpha, const MatrixBase< Real > &M, Real beta=1.0)
Does *this = alpha * (sum of rows of M) + beta * *this.
void Transpose()
Transpose the matrix.
void CuVectorUnitTestApplySoftMax()
void ApplyCeiling(Real ceiling_val, MatrixIndexT *ceiled_count=NULL)
Definition: cu-vector.h:143
void CopyDiagFromMat(const MatrixBase< Real > &M)
Extracts the diagonal of the matrix M.
void CopyColFromMat(const CuMatrixBase< Real > &mat, MatrixIndexT col)
Definition: cu-vector.cc:103
void CuVectorUnitTestSum()
void CuVectorUnitTestApplyLog()
void PrintUsage(bool print_command_line=false)
Prints the usage documentation [provided in the constructor].
void ApplyCeiling(Real ceil_val, MatrixIndexT *ceiled_count=nullptr)
Applies ceiling to all elements.
Definition: kaldi-vector.h:155
Real Sum() const
Definition: cu-vector.cc:297
void Set(Real value)
Definition: cu-vector.cc:1135
Real Trace(bool check_square=true) const
Returns trace of matrix.
void CuVectorUnitTestApplyFloor()
void CopyDiagFromMat(const CuMatrix< Real > &M)
Extracts the diagonal of a matrix.
Definition: cu-vector.cc:1198
void AddDiagMat2(Real alpha, const CuMatrixBase< Real > &M, MatrixTransposeType trans, Real beta)
Add the diagonal of a matrix times itself: *this = diag(M M^T) + beta * *this (if trans == kNoTrans)...
Definition: cu-vector.cc:595
void AddDiagMat2(Real alpha, const MatrixBase< Real > &M, MatrixTransposeType trans=kNoTrans, Real beta=1.0)
Add the diagonal of a matrix times itself: *this = diag(M M^T) + beta * *this (if trans == kNoTrans)...
void UnitTestVecMatVec()
kaldi::int32 int32
Real VecMatVec(const VectorBase< Real > &v1, const MatrixBase< Real > &M, const VectorBase< Real > &v2)
Returns .
void MulTp(const TpMatrix< Real > &M, const MatrixTransposeType trans)
Multiplies this vector by lower-triangular matrix: *this <– *this *M.
void CuVectorUnitTestCopyDiagFromPacked()
A class for storing matrices.
Definition: kaldi-matrix.h:823
void CuVectorUnitTestApplyExp()
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 CopyRowsFromVec(const CuVectorBase< Real > &v)
This function has two modes of operation.
Definition: cu-matrix.cc:2301
void AddSpVec(const Real alpha, const SpMatrix< Real > &M, const VectorBase< Real > &v, const Real beta)
Add symmetric positive definite matrix times vector: this <– beta*this + alpha*M*v.
void CuVectorUnitTestAddVecCross()
Real ApplySoftMax()
Apply soft-max to vector and return normalizer (log sum of exponentials).
Real Min() const
Returns the minimum value of any element, or +infinity for the empty vector.
void ApplyFloor(Real floor_val, MatrixIndexT *floored_count=NULL)
Definition: cu-vector.h:139
void SetRandn()
< Set to unit matrix.
void CuVectorUnitTest()
void Register(const std::string &name, bool *ptr, const std::string &doc)
void CuVectorUnitTestAddColSumMat()
void ReplaceValue(Real orig, Real changed)
Definition: cu-vector.cc:820
void SetRandn()
< Set to unit matrix.
void AddDiagMatMat(Real alpha, const CuMatrixBase< Real > &M, MatrixTransposeType transM, const CuMatrixBase< Real > &N, MatrixTransposeType transN, Real beta=1.0)
Add the diagonal of a matrix product: *this = diag(M N), assuming the "trans" arguments are both kNoT...
Definition: cu-vector.cc:611
void CopyElements(const CuMatrixBase< Real > &mat, const MatrixTransposeType trans, const CuArrayBase< int32 > &elements)
Copies selected elements from &#39;mat&#39; to *this.
Definition: cu-vector.cc:1340
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 AddVecVec(Real alpha, const VectorBase< Real > &v, const VectorBase< Real > &r, Real beta)
Add element-by-element product of vectors:
void CuVectorUnitTestAddVec()
void ApplyFloor(Real floor_val, MatrixIndexT *floored_count=nullptr)
Applies floor to all elements.
Definition: kaldi-vector.h:149
void CopyFromVec(const VectorBase< Real > &v)
Copy data from another vector (must match own size).
void Write(std::ostream &is, bool binary) const
Definition: cu-vector.cc:973
void CuVectorUnitTestScale()
void CopyDiagFromPacked(const PackedMatrix< Real > &M)
Extracts the diagonal of a packed matrix M; works for Sp or Tp.
void CuVectorUnitTestAddMatVec()
void AddMatVec(const Real alpha, const CuMatrixBase< Real > &M, MatrixTransposeType trans, const CuVectorBase< Real > &v, const Real beta)
Definition: cu-vector.cc:506
int32 MatrixIndexT
Definition: matrix-common.h:98
void CopyFromVec(const CuVectorBase< Real > &src)
Copy functions; these will crash if the dimension do not match.
Definition: cu-vector.cc:1078
The class ParseOptions is for parsing command-line options; see Parsing command-line options for more...
Definition: parse-options.h:36
double Log(double x)
Definition: kaldi-math.h:100
int main(int argc, char *argv[])
void AddColSumMat(Real alpha, const CuMatrixBase< Real > &mat, Real beta=1.0)
Sum the columns of the matrix, add to vector.
Definition: cu-vector.cc:1298
void CuVectorUnitTestAddRowSumMat()
void CuVectorUnitTestMax()
static void UnitTestCuVectorAddTp()
void CuVectorUnitTestMin()
void CuVectorUnitTestAddVecExtra()
void CuVectorUnitTestCopyFromMat()
struct rnnlm::@11::@12 n
void SetRandn()
Sets to random values of a normal distribution.
int Read(int argc, const char *const *argv)
Parses the command line options and fills the ParseOptions-registered variables.
void AddSpVec(const Real alpha, const CuSpMatrix< Real > &S, const CuVectorBase< Real > &v, const Real beta)
Definition: cu-vector.cc:535
void CuVectorUnitTestAddVecVec()
Real Max() const
Returns the maximum value of any element, or -infinity for the empty vector.
void ApplyPow(Real power)
Definition: cu-vector.h:147
Packed symetric matrix class.
Definition: matrix-common.h:63
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 UnitTestCuVectorIO()
void CuVectorUnitTestApplyPow()
static void UnitTestCuVectorReplaceValue()
void Scale(Real alpha)
Multiplies all elements by this constant.
void AddMatVec(const Real alpha, const MatrixBase< Real > &M, const MatrixTransposeType trans, const VectorBase< Real > &v, const Real beta)
Add matrix times vector : this <– beta*this + alpha*M*v.
Definition: kaldi-vector.cc:92
void CuVectorUnitTestApplyFloorNoCount()
int Rand(struct RandomState *state)
Definition: kaldi-math.cc:45
Real Sum() const
Returns sum of the elements.
void CuVectorUnitTestAddDiagMat2()
void SetRandn()
Set vector to random normally-distributed noise.
static void CuVectorUnitTestAddDiagMatMat()
void CuVectorUnitTestCopyCross()
Real Max() const
Returns the maximum value of any element, or -infinity for the empty vector.
Definition: cu-vector.cc:782
void AddVec(Real alpha, const CuVectorBase< Real > &vec, Real beta=1.0)
Definition: cu-vector.cc:1237
int NumArgs() const
Number of positional parameters (c.f. argc-1).
CuSubVector< Real > Range(const MatrixIndexT o, const MatrixIndexT l)
Definition: cu-vector.h:160
void CuVectorUnitTestCopyDiagFromMat()
void AddTpVec(const Real alpha, const TpMatrix< Real > &M, const MatrixTransposeType trans, const VectorBase< Real > &v, const Real beta)
Add triangular matrix times vector: this <– beta*this + alpha*M*v.
A class representing a vector.
Definition: kaldi-vector.h:406
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
void ApplyPow(Real power)
Take all elements of vector to a power.
Definition: kaldi-vector.h:179
void CuVectorUnitTestAddSpVec()
Real Norm(Real p)
Definition: cu-vector.cc:193
void Read(std::istream &is, bool binary)
I/O.
Definition: cu-vector.cc:963
void AddVecVec(Real alpha, const CuVectorBase< Real > &v, const CuVectorBase< Real > &r, Real beta)
Definition: cu-vector.cc:560
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
static void UnitTestCuSubVector()
void Scale(Real value)
Definition: cu-vector.cc:1216
void CopyRowsFromMat(const MatrixBase< Real > &M)
Performs a row stack of the matrix M.
static void UnitTestCuVectorCopyFromVec()
void CuVectorUnitTestApplyCeilingNoCount()
void ReplaceValue(Real orig, Real changed)
Set each element to y = (x == orig ? changed : x).
void CuVectorUnitTestNorm()
void ApplyAbs()
Take absolute value of each of the elements.
void AddColSumMat(Real alpha, const MatrixBase< Real > &M, Real beta=1.0)
Does *this = alpha * (sum of columns of M) + beta * *this.
void AddTpVec(const Real alpha, const CuTpMatrix< Real > &M, const MatrixTransposeType trans, const CuVectorBase< Real > &v, const Real beta)
Add triangular matrix times vector: this <– beta*this + alpha*M*v.
Definition: cu-vector.cc:698
void CopyRowsFromVec(const VectorBase< Real > &v)
This function has two modes of operation.
static void UnitTestCuVectorMulTp()
#define KALDI_LOG
Definition: kaldi-error.h:153
static void UnitTestCuVectorSum()
Real VecVec(const VectorBase< Real > &a, const VectorBase< Real > &b)
Returns dot product between v1 and v2.
Definition: kaldi-vector.cc:37
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
void CopyRowsFromMat(const CuMatrixBase< Real > &M)
Definition: cu-vector.cc:164
void Resize(MatrixIndexT rows, MatrixIndexT cols, MatrixResizeType resize_type=kSetZero, MatrixStrideType stride_type=kDefaultStride)
Allocate the memory.
Definition: cu-matrix.cc:50
Real Min() const
Returns the minimum value of any element, or +infinity for the empty vector.
Definition: cu-vector.cc:744
void AddRowSumMat(Real alpha, const CuMatrixBase< Real > &mat, Real beta=1.0)
Sum the rows of the matrix, add to vector.
Definition: cu-vector.cc:1277
int32 RandInt(int32 min_val, int32 max_val, struct RandomState *state)
Definition: kaldi-math.cc:95
void CuVectorUnitTestCopyElements()
void CuVectorUnitTestVecVec()
SubVector< Real > Range(const MatrixIndexT o, const MatrixIndexT l)
Returns a sub-vector of a vector (a range of elements).
Definition: kaldi-vector.h:94