ViennaCL - The Vienna Computing Library  1.6.0
Free open-source GPU-accelerated linear algebra and solver library.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
matrix_product_float_double.hpp
Go to the documentation of this file.
1 /* =========================================================================
2  Copyright (c) 2010-2014, Institute for Microelectronics,
3  Institute for Analysis and Scientific Computing,
4  TU Wien.
5  Portions of this software are copyright by UChicago Argonne, LLC.
6 
7  -----------------
8  ViennaCL - The Vienna Computing Library
9  -----------------
10 
11  Project Head: Karl Rupp rupp@iue.tuwien.ac.at
12 
13  (A list of authors and contributors can be found in the PDF manual)
14 
15  License: MIT (X11), see file LICENSE in the base directory
16 ============================================================================= */
17 
18 #ifndef TEST_MATRIX_PRODUCT_FLOAT_DOUBLE_HPP_
19 #define TEST_MATRIX_PRODUCT_FLOAT_DOUBLE_HPP_
20 
21 // We don't need debug mode in UBLAS:
22 #define BOOST_UBLAS_NDEBUG
23 
24 #include <cstddef>
25 
26 #include "viennacl/matrix.hpp"
28 #include "viennacl/linalg/prod.hpp"
29 
30 #include "boost/numeric/ublas/matrix.hpp"
31 #include "boost/numeric/ublas/matrix_proxy.hpp"
32 #include "boost/numeric/ublas/io.hpp"
33 
34 #include "Random.hpp"
35 
36 template<typename ScalarType, typename VCLMatrixType>
37 ScalarType diff(boost::numeric::ublas::matrix<ScalarType> const & mat1, VCLMatrixType const & mat2)
38 {
39  boost::numeric::ublas::matrix<ScalarType> mat2_cpu(mat2.size1(), mat2.size2());
40  viennacl::backend::finish(); //workaround for a bug in APP SDK 2.7 on Trinity APUs (with Catalyst 12.8)
41  viennacl::copy(mat2, mat2_cpu);
42  ScalarType ret = 0;
43  ScalarType act = 0;
44 
45  for (unsigned int i = 0; i < mat2_cpu.size1(); ++i)
46  {
47  for (unsigned int j = 0; j < mat2_cpu.size2(); ++j)
48  {
49  act = std::fabs(mat2_cpu(i,j) - mat1(i,j)) / std::max( std::fabs(mat2_cpu(i, j)), std::fabs(mat1(i,j)) );
50  if (act > ret)
51  ret = act;
52  }
53  }
54 
55  return ret;
56 }
57 
58 
59 template<class UBlasType, class F>
60 struct matrix_maker;
61 
62 template<class T, class F>
63 struct matrix_maker< boost::numeric::ublas::matrix<T>, F>
64 {
66  static result_type make(viennacl::matrix<T, F> const &, boost::numeric::ublas::matrix<T> & base)
67  {
68  viennacl::matrix<T, F> result(base.size1(), base.size2());
69  viennacl::copy(base, result);
70  return result;
71  }
72 };
73 
74 template<class MatrixT, class F>
75 struct matrix_maker< boost::numeric::ublas::matrix_range<MatrixT>, F>
76 {
77  typedef typename MatrixT::value_type T;
79 
80  static result_type make(viennacl::matrix<T, F> & M, boost::numeric::ublas::matrix_range<MatrixT> & base)
81  {
82  viennacl::range r0(base.start1(), base.start1() + base.size1());
83  viennacl::range r1(base.start2(), base.start2() + base.size2());
84  result_type result(M, r0, r1);
85  viennacl::copy(base, result);
86  return result;
87  }
88 };
89 
90 template<class MatrixT, class F>
91 struct matrix_maker< boost::numeric::ublas::matrix_slice<MatrixT>, F>
92 {
93  typedef typename MatrixT::value_type T;
95 
96  static result_type make(viennacl::matrix<T, F> & M, boost::numeric::ublas::matrix_slice<MatrixT> & base)
97  {
98  viennacl::slice s0(base.start1(), std::size_t(base.stride1()), base.size1());
99  viennacl::slice s1(base.start2(), std::size_t(base.stride2()), base.size2());
100  result_type result(M, s0, s1);
101  viennacl::copy(base, result);
102  return result;
103  }
104 };
105 
106 template<typename T, typename CType, typename AType, typename BType>
107 int test_layout(CType & C, AType const & A, AType const & AT, BType const & B, BType const & BT,
108  boost::numeric::ublas::matrix<T> const & ground, T epsilon)
109 {
111  using viennacl::trans;
112 
113  std::cout << "C = A.B" << std::endl;
114  C = prod(A, B);
115  if (diff(ground, C)>epsilon)
116  return EXIT_FAILURE;
117 
118  std::cout << "C = A'.B" << std::endl;
119  C = prod(trans(AT), B);
120  if (diff(ground, C)>epsilon)
121  return EXIT_FAILURE;
122 
123  std::cout << "C = A.B'" << std::endl;
124  C = prod(A, trans(BT));
125  if (diff(ground, C)>epsilon)
126  return EXIT_FAILURE;
127 
128  std::cout << "C = A'.B'" << std::endl;
129  C = prod(trans(AT), trans(BT));
130  if (diff(ground, C)>epsilon)
131  return EXIT_FAILURE;
132 
133  return EXIT_SUCCESS;
134 }
135 
136 template<typename T, typename RefAType, typename RefBType, typename RefCType>
137 int test_all_layouts(std::size_t CM, std::size_t CN, RefCType & cC,
138  std::size_t AM, std::size_t AK, RefAType & cA, RefAType & cAT,
139  std::size_t BK, std::size_t BN, RefBType & cB, RefBType & cBT,
140  T epsilon)
141 {
147 
153 
154 
160 
166 
167 
168  boost::numeric::ublas::matrix<T> ground = boost::numeric::ublas::prod(cA, cB);
169 
170 #define TEST_LAYOUT(Clayout, Alayout, Blayout) \
171  std::cout << "> " #Clayout " = " #Alayout "." #Blayout << std::endl; \
172  if (test_layout(C ## Clayout, A ## Alayout, AT ## Alayout, B ## Blayout, BT ## Blayout, ground, epsilon) != EXIT_SUCCESS) \
173  return EXIT_FAILURE; \
174 
175  TEST_LAYOUT(row, row, row);
176  TEST_LAYOUT(row, row, col);
177  TEST_LAYOUT(row, col, row);
178  TEST_LAYOUT(row, col, col);
179  TEST_LAYOUT(col, row, row);
180  TEST_LAYOUT(col, row, col);
181  TEST_LAYOUT(col, col, row);
182  TEST_LAYOUT(col, col, col);
183 
184 #undef TEST_LAYOUT
185 
186  return EXIT_SUCCESS;
187 }
188 
189 template<class MatrixType>
190 void init_rand(MatrixType & A)
191 {
192  typedef typename MatrixType::value_type T;
193  for (unsigned int i = 0; i < A.size1(); ++i)
194  for (unsigned int j = 0; j < A.size2(); ++j)
195  A(i, j) = static_cast<T>(0.1) * random<T>();
196 }
197 
198 template<typename T>
199 int run_test(T epsilon)
200 {
201  typedef boost::numeric::ublas::range range_type;
202  typedef boost::numeric::ublas::slice slice_type;
203  typedef boost::numeric::ublas::matrix<T> matrix_type;
204  typedef boost::numeric::ublas::matrix_range<matrix_type> matrix_range_type;
205  typedef boost::numeric::ublas::matrix_slice<matrix_type> matrix_slice_type;
206 
207  typedef typename matrix_type::difference_type difference_type;
208 
209  std::size_t matrix_holder_M = 143;
210  std::size_t matrix_holder_N = 124;
211  std::size_t matrix_holder_K = 184;
212 
213  std::size_t start_M = 14;
214  std::size_t start_N = 20;
215  std::size_t start_K = 73;
216 
217  std::size_t range_holder_M = start_M + matrix_holder_M;
218  std::size_t range_holder_N = start_N + matrix_holder_N;
219  std::size_t range_holder_K = start_K + matrix_holder_K;
220 
221  range_type range_M(start_M, range_holder_M);
222  range_type range_N(start_N, range_holder_N);
223  range_type range_K(start_K, range_holder_K);
224 
225  difference_type stride_M = 9;
226  difference_type stride_N = 13;
227  difference_type stride_K = 4;
228 
229  std::size_t slice_holder_M = start_M + std::size_t(stride_M)*matrix_holder_M;
230  std::size_t slice_holder_N = start_N + std::size_t(stride_N)*matrix_holder_N;
231  std::size_t slice_holder_K = start_K + std::size_t(stride_K)*matrix_holder_K;
232 
233  slice_type slice_M(start_M, stride_M, matrix_holder_M);
234  slice_type slice_N(start_N, stride_N, matrix_holder_N);
235  slice_type slice_K(start_K, stride_K, matrix_holder_K);
236 
237 #define DECLARE(NAME, size1, size2) \
238  matrix_type NAME ## _matrix(matrix_holder_ ## size1, matrix_holder_ ## size2);\
239  init_rand(NAME ## _matrix);\
240  matrix_type NAME ## T_matrix = boost::numeric::ublas::trans(NAME ## _matrix);\
241  \
242  matrix_type NAME ## _range_holder(range_holder_ ## size1, range_holder_ ## size2);\
243  init_rand(NAME ## _range_holder);\
244  matrix_range_type NAME ## _range(NAME ## _range_holder, range_ ## size1, range_ ## size2);\
245  matrix_type NAME ## T_range_holder = boost::numeric::ublas::trans(NAME ## _range_holder);\
246  matrix_range_type NAME ## T_range(NAME ## T_range_holder, range_ ## size2, range_ ## size1);\
247  \
248  matrix_type NAME ## _slice_holder(slice_holder_ ## size1, slice_holder_ ## size2);\
249  init_rand(NAME ## _slice_holder);\
250  matrix_slice_type NAME ## _slice(NAME ## _slice_holder, slice_ ## size1, slice_ ## size2);\
251  matrix_type NAME ## T_slice_holder = boost::numeric::ublas::trans(NAME ## _slice_holder);\
252  matrix_slice_type NAME ## T_slice(NAME ## T_slice_holder, slice_ ## size2, slice_ ## size1);\
253 
254  DECLARE(A, M, K);
255  DECLARE(B, K, N);
256  DECLARE(C, M, N);
257 #undef DECLARE
258 
259 #define TEST_ALL_LAYOUTS(C_TYPE, A_TYPE, B_TYPE)\
260  std::cout << ">> " #C_TYPE " = " #A_TYPE "." #B_TYPE << std::endl;\
261  if (test_all_layouts<T>(C_TYPE ## _holder_M, C_TYPE ## _holder_N, C_ ## C_TYPE,\
262  A_TYPE ## _holder_M, A_TYPE ## _holder_K, A_ ## A_TYPE, AT_ ## A_TYPE,\
263  B_TYPE ## _holder_K, B_TYPE ## _holder_N, B_ ## B_TYPE, BT_ ## B_TYPE, epsilon) != EXIT_SUCCESS)\
264  return EXIT_FAILURE;\
265 
266 // //C=matrix
267  TEST_ALL_LAYOUTS(matrix, matrix, matrix)
268  TEST_ALL_LAYOUTS(matrix, matrix, range)
269  TEST_ALL_LAYOUTS(matrix, matrix, slice)
270 
271  TEST_ALL_LAYOUTS(matrix, range, matrix)
272  TEST_ALL_LAYOUTS(matrix, range, range)
273  TEST_ALL_LAYOUTS(matrix, range, slice)
274 
275  TEST_ALL_LAYOUTS(matrix, slice, matrix)
276  TEST_ALL_LAYOUTS(matrix, slice, range)
277  TEST_ALL_LAYOUTS(matrix, slice, slice)
278 
279 // C = range
280  TEST_ALL_LAYOUTS(range, matrix, matrix)
281  TEST_ALL_LAYOUTS(range, matrix, range)
282  TEST_ALL_LAYOUTS(range, matrix, slice)
283 
284  TEST_ALL_LAYOUTS(range, range, matrix)
287 
288  TEST_ALL_LAYOUTS(range, slice, matrix)
291 
292 // C = slice
293  TEST_ALL_LAYOUTS(slice, matrix, matrix)
294  TEST_ALL_LAYOUTS(slice, matrix, range)
295  TEST_ALL_LAYOUTS(slice, matrix, slice)
296 
297  TEST_ALL_LAYOUTS(slice, range, matrix)
300 
301  TEST_ALL_LAYOUTS(slice, slice, matrix)
304 
305 #undef TEST_ALL_LAYOUTS
306 
307  return EXIT_SUCCESS;
308 }
309 
310 #endif
#define TEST_LAYOUT(Clayout, Alayout, Blayout)
viennacl::enable_if< viennacl::is_any_sparse_matrix< M1 >::value, matrix_expression< const M1, const M1, op_trans > >::type trans(const M1 &mat)
Returns an expression template class representing a transposed matrix.
Class for representing strided submatrices of a bigger matrix A.
Definition: forwards.h:442
void trans(matrix_expression< const matrix_base< NumericT, SizeT, DistanceT >, const matrix_base< NumericT, SizeT, DistanceT >, op_trans > const &proxy, matrix_base< NumericT > &temp_trans)
Generic interface for matrix-vector and matrix-matrix products. See viennacl/linalg/vector_operations...
Implementation of the dense matrix class.
void finish()
Synchronizes the execution. finish() will only return after all compute kernels (CUDA, OpenCL) have completed.
Definition: memory.hpp:54
A dense matrix class.
Definition: forwards.h:374
viennacl::scalar< float > s1
T max(const T &lhs, const T &rhs)
Maximum.
Definition: util.hpp:59
#define DECLARE(NAME, size1, size2)
#define TEST_ALL_LAYOUTS(C_TYPE, A_TYPE, B_TYPE)
ScalarType diff(boost::numeric::ublas::matrix< ScalarType > const &mat1, VCLMatrixType const &mat2)
basic_range range
Definition: forwards.h:423
VectorT prod(std::vector< std::vector< T, A1 >, A2 > const &matrix, VectorT const &vector)
Definition: prod.hpp:91
int test_all_layouts(std::size_t CM, std::size_t CN, RefCType &cC, std::size_t AM, std::size_t AK, RefAType &cA, RefAType &cAT, std::size_t BK, std::size_t BN, RefBType &cB, RefBType &cBT, T epsilon)
void init_rand(MatrixType &A)
static result_type make(viennacl::matrix< T, F > const &, boost::numeric::ublas::matrix< T > &base)
void prod(const MatrixT1 &A, bool transposed_A, const MatrixT2 &B, bool transposed_B, MatrixT3 &C, ScalarT alpha, ScalarT beta)
vector_expression< const matrix_base< NumericT, F >, const unsigned int, op_row > row(const matrix_base< NumericT, F > &A, unsigned int i)
Definition: matrix.hpp:853
Proxy classes for matrices.
static result_type make(viennacl::matrix< T, F > &M, boost::numeric::ublas::matrix_slice< MatrixT > &base)
basic_slice slice
Definition: forwards.h:428
static result_type make(viennacl::matrix< T, F > &M, boost::numeric::ublas::matrix_range< MatrixT > &base)
void copy(std::vector< NumericT > &cpu_vec, circulant_matrix< NumericT, AlignmentV > &gpu_mat)
Copies a circulant matrix from the std::vector to the OpenCL device (either GPU or multi-core CPU) ...
A range class that refers to an interval [start, stop), where 'start' is included, and 'stop' is excluded.
Definition: forwards.h:423
float ScalarType
Definition: fft_1d.cpp:42
int run_test(T epsilon)
Class for representing non-strided submatrices of a bigger matrix A.
Definition: forwards.h:439
int test_layout(CType &C, AType const &A, AType const &AT, BType const &B, BType const &BT, boost::numeric::ublas::matrix< T > const &ground, T epsilon)
A slice class that refers to an interval [start, stop), where 'start' is included, and 'stop' is excluded.
Definition: forwards.h:428