MyraMath
psyrk1


Source: tests/pdense/psyrk1.cpp

1 // ========================================================================= //
2 // This file is part of MyraMath, copyright (c) 2014-2019 by Ryan A Chilton //
3 // and distributed by MyraCore, LLC. See LICENSE.txt for license terms. //
4 // ========================================================================= //
5 
11 // Containers.
13 #include <myramath/dense/Matrix.h>
15 
16 // Serial algorithms.
18 #include <myramath/dense/syrk.h>
20 
21 // Parallel algorithms.
22 #include <myramath/pdense/psyrk.h>
24 
25 // Reporting.
26 #include <tests/myratest.h>
27 
28 using namespace myra;
29 typedef pdense::Options Options;
30 
31 namespace {
32 
33 template<class Number> void test(int I, int J, typename ReflectPrecision<Number>::type tolerance)
34  {
35  typedef typename ReflectPrecision<Number>::type Precision;
36  myra::out() << typestring<Number>() << std::endl;
37  // Generate random matrix A.
38  auto A = Matrix<Number>::random(I,J);
39  Number alpha = random<Number>();
40  Number beta = random<Number>();
41  // Initialize options.
42  auto options = Options::create().set_nthreads(4);
43  // Check syrk('U','N')
44  {
45  auto C_serial = Matrix<Number>::random(I,I);
46  auto C_parallel = C_serial;
47  syrk_inplace(C_serial,'U',A,'N',alpha,beta);
48  psyrk_inplace(C_parallel,'U',A,'N',alpha,beta,options);
49  Precision error = frobenius(C_serial-C_parallel) / frobenius(C_serial);
50  myra::out() << " |syrk('U','N')-psyrk('U','N')| = " << error << std::endl;
51  REQUIRE(error < tolerance);
52  }
53  // Check syrk('U','T')
54  {
55  auto C_serial = Matrix<Number>::random(J,J);
56  auto C_parallel = C_serial;
57  syrk_inplace(C_serial,'U',A,'T',alpha,beta);
58  psyrk_inplace(C_parallel,'U',A,'T',alpha,beta,options);
59  Precision error = frobenius(C_serial-C_parallel) / frobenius(C_serial);
60  myra::out() << " |syrk('U','T')-psyrk('U','T')| = " << error << std::endl;
61  REQUIRE(error < tolerance);
62  }
63  // Check syrk('U','H')
64  {
65  auto C_serial = Matrix<Number>::random(J,J);
66  auto C_parallel = C_serial;
67  syrk_inplace(C_serial,'U',A,'H',alpha,beta);
68  psyrk_inplace(C_parallel,'U',A,'H',alpha,beta,options);
69  Precision error = frobenius(C_serial-C_parallel) / frobenius(C_serial);
70  myra::out() << " |syrk('U','H')-psyrk('U','H')| = " << error << std::endl;
71  REQUIRE(error < tolerance);
72  }
73  // Check syrk('U','C')
74  {
75  auto C_serial = Matrix<Number>::random(I,I);
76  auto C_parallel = C_serial;
77  syrk_inplace(C_serial,'U',A,'C',alpha,beta);
78  psyrk_inplace(C_parallel,'U',A,'C',alpha,beta,options);
79  Precision error = frobenius(C_serial-C_parallel) / frobenius(C_serial);
80  myra::out() << " |syrk('U','C')-psyrk('U','C')| = " << error << std::endl;
81  REQUIRE(error < tolerance);
82  }
83  // Check syrk('L','N')
84  {
85  auto C_serial = Matrix<Number>::random(I,I);
86  auto C_parallel = C_serial;
87  syrk_inplace(C_serial,'L',A,'N',alpha,beta);
88  psyrk_inplace(C_parallel,'L',A,'N',alpha,beta,options);
89  Precision error = frobenius(C_serial-C_parallel) / frobenius(C_serial);
90  myra::out() << " |syrk('L','N')-psyrk('L','N')| = " << error << std::endl;
91  REQUIRE(error < tolerance);
92  }
93  // Check syrk('L','T')
94  {
95  auto C_serial = Matrix<Number>::random(J,J);
96  auto C_parallel = C_serial;
97  syrk_inplace(C_serial,'L',A,'T',alpha,beta);
98  psyrk_inplace(C_parallel,'L',A,'T',alpha,beta,options);
99  Precision error = frobenius(C_serial-C_parallel) / frobenius(C_serial);
100  myra::out() << " |syrk('L','T')-psyrk('L','T')| = " << error << std::endl;
101  REQUIRE(error < tolerance);
102  }
103  // Check syrk('L','H')
104  {
105  auto C_serial = Matrix<Number>::random(J,J);
106  auto C_parallel = C_serial;
107  syrk_inplace(C_serial,'L',A,'H',alpha,beta);
108  psyrk_inplace(C_parallel,'L',A,'H',alpha,beta,options);
109  Precision error = frobenius(C_serial-C_parallel) / frobenius(C_serial);
110  myra::out() << " |syrk('L','H')-psyrk('L','H')| = " << error << std::endl;
111  REQUIRE(error < tolerance);
112  }
113  // Check syrk('L','C')
114  {
115  auto C_serial = Matrix<Number>::random(I,I);
116  auto C_parallel = C_serial;
117  syrk_inplace(C_serial,'L',A,'C',alpha,beta);
118  psyrk_inplace(C_parallel,'L',A,'C',alpha,beta,options);
119  Precision error = frobenius(C_serial-C_parallel) / frobenius(C_serial);
120  myra::out() << " |syrk('L','C')-psyrk('L','C')| = " << error << std::endl;
121  REQUIRE(error < tolerance);
122  }
123  }
124 
125 } // namespace
126 
127 ADD_TEST("psyrk1","[pdense][parallel]")
128  {
129  int I = 512;
130  int J = 256;
131  test<NumberS>(I,J,1.0e-4f);
132  test<NumberD>(I,J,1.0e-8);
133  test<NumberC>(I,J,1.0e-4f);
134  test<NumberZ>(I,J,1.0e-8);
135  }
Interface class for representing subranges of dense Matrix&#39;s.
Routines for computing Frobenius norms of various algebraic containers.
static Matrix< Number > random(int I, int J)
Generates a random Matrix of specified size.
Definition: Matrix.cpp:353
Options pack for routines in /pdense.
Definition: Options.h:24
Definition: syntax.dox:1
Various utility functions/classes related to scalar Number types.
General purpose dense matrix container, O(i*j) storage.
Options pack for routines in /pdense.
Reflects Precision trait for a Number, scalar Number types should specialize it.
Definition: Number.h:33
Simplistic random number functions.
Routines for symmetric rank-k updates, a specialized form of Matrix*Matrix multiplication.
Thread parallel version of dense/syrk.h, symmetric rank-k updates.


Results: [PASS]

float
|syrk('U','N')-psyrk('U','N')| = 0
|syrk('U','T')-psyrk('U','T')| = 0
|syrk('U','H')-psyrk('U','H')| = 0
|syrk('U','C')-psyrk('U','C')| = 0
|syrk('L','N')-psyrk('L','N')| = 0
|syrk('L','T')-psyrk('L','T')| = 0
|syrk('L','H')-psyrk('L','H')| = 0
|syrk('L','C')-psyrk('L','C')| = 0
double
|syrk('U','N')-psyrk('U','N')| = 0
|syrk('U','T')-psyrk('U','T')| = 0
|syrk('U','H')-psyrk('U','H')| = 0
|syrk('U','C')-psyrk('U','C')| = 0
|syrk('L','N')-psyrk('L','N')| = 0
|syrk('L','T')-psyrk('L','T')| = 0
|syrk('L','H')-psyrk('L','H')| = 0
|syrk('L','C')-psyrk('L','C')| = 0
std::complex<float>
|syrk('U','N')-psyrk('U','N')| = 0
|syrk('U','T')-psyrk('U','T')| = 0
|syrk('U','H')-psyrk('U','H')| = 0
|syrk('U','C')-psyrk('U','C')| = 0
|syrk('L','N')-psyrk('L','N')| = 0
|syrk('L','T')-psyrk('L','T')| = 0
|syrk('L','H')-psyrk('L','H')| = 0
|syrk('L','C')-psyrk('L','C')| = 0
std::complex<double>
|syrk('U','N')-psyrk('U','N')| = 0
|syrk('U','T')-psyrk('U','T')| = 0
|syrk('U','H')-psyrk('U','H')| = 0
|syrk('U','C')-psyrk('U','C')| = 0
|syrk('L','N')-psyrk('L','N')| = 0
|syrk('L','T')-psyrk('L','T')| = 0
|syrk('L','H')-psyrk('L','H')| = 0
|syrk('L','C')-psyrk('L','C')| = 0


Go back to Summary of /test programs.