ViennaCL - The Vienna Computing Library  1.7.0
Free open-source GPU-accelerated linear algebra and solver library.
scheduler_matrix_matrix.cpp
Go to the documentation of this file.
1 /* =========================================================================
2  Copyright (c) 2010-2015, 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 
23 //
24 // *** System
25 //
26 #include <iostream>
27 
28 //
29 // *** Boost
30 //
31 #include <boost/numeric/ublas/io.hpp>
32 #include <boost/numeric/ublas/triangular.hpp>
33 #include <boost/numeric/ublas/matrix_sparse.hpp>
34 #include <boost/numeric/ublas/matrix.hpp>
35 #include <boost/numeric/ublas/matrix_proxy.hpp>
36 #include <boost/numeric/ublas/lu.hpp>
37 #include <boost/numeric/ublas/io.hpp>
38 
39 //
40 // *** ViennaCL
41 //
42 //#define VIENNACL_DEBUG_ALL
43 //#define VIENNACL_DEBUG_BUILD
44 #define VIENNACL_WITH_UBLAS 1
45 #include "viennacl/scalar.hpp"
46 #include "viennacl/matrix.hpp"
48 #include "viennacl/vector.hpp"
49 #include "viennacl/linalg/prod.hpp"
53 
56 
57 //
58 // -------------------------------------------------------------
59 //
60 using namespace boost::numeric;
61 //
62 // -------------------------------------------------------------
63 //
64 template<typename ScalarType>
66 {
68  if (s1 != s2)
69  return (s1 - s2) / std::max(std::fabs(s1), std::fabs(s2));
70  return 0;
71 }
72 
73 template<typename ScalarType>
74 ScalarType diff(ublas::vector<ScalarType> & v1, viennacl::vector<ScalarType> & v2)
75 {
76  ublas::vector<ScalarType> v2_cpu(v2.size());
77  viennacl::backend::finish(); //workaround for a bug in APP SDK 2.7 on Trinity APUs (with Catalyst 12.8)
78  viennacl::copy(v2.begin(), v2.end(), v2_cpu.begin());
79 
80  for (std::size_t i=0;i<v1.size(); ++i)
81  {
82  if ( std::max( std::fabs(v2_cpu[i]), std::fabs(v1[i]) ) > 0 )
83  v2_cpu[i] = std::fabs(v2_cpu[i] - v1[i]) / std::max( std::fabs(v2_cpu[i]), std::fabs(v1[i]) );
84  else
85  v2_cpu[i] = 0.0;
86  }
87 
88  return norm_inf(v2_cpu);
89 }
90 
91 
92 template<typename ScalarType, typename VCLMatrixType>
93 ScalarType diff(ublas::matrix<ScalarType> & mat1, VCLMatrixType & mat2)
94 {
95  ublas::matrix<ScalarType> mat2_cpu(mat2.size1(), mat2.size2());
96  viennacl::backend::finish(); //workaround for a bug in APP SDK 2.7 on Trinity APUs (with Catalyst 12.8)
97  viennacl::copy(mat2, mat2_cpu);
98  ScalarType ret = 0;
99  ScalarType act = 0;
100 
101  for (unsigned int i = 0; i < mat2_cpu.size1(); ++i)
102  {
103  for (unsigned int j = 0; j < mat2_cpu.size2(); ++j)
104  {
105  act = std::fabs(mat2_cpu(i,j) - mat1(i,j)) / std::max( std::fabs(mat2_cpu(i, j)), std::fabs(mat1(i,j)) );
106  if (act > ret)
107  ret = act;
108  }
109  }
110  //std::cout << ret << std::endl;
111  return ret;
112 }
113 
114 
115 
116 
117 
118 
119 //
120 // Part 1: Matrix-matrix multiplications
121 //
122 
123 
124 template< typename NumericT, typename Epsilon,
125  typename ReferenceMatrixTypeA, typename ReferenceMatrixTypeB, typename ReferenceMatrixTypeC,
126  typename MatrixTypeA, typename MatrixTypeB, typename MatrixTypeC>
127 int test_prod(Epsilon const& epsilon,
128 
129  ReferenceMatrixTypeA const & A, ReferenceMatrixTypeA const & A_trans,
130  ReferenceMatrixTypeB const & B, ReferenceMatrixTypeB const & B_trans,
131  ReferenceMatrixTypeC & C,
132 
133  MatrixTypeA const & vcl_A, MatrixTypeA const & vcl_A_trans,
134  MatrixTypeB const & vcl_B, MatrixTypeB const & vcl_B_trans,
135  MatrixTypeC & vcl_C
136  )
137 {
138  int retval = EXIT_SUCCESS;
139  NumericT act_diff = 0;
140 
141 
142  // Test: C +-= A * B --------------------------------------------------------------------------
143  C = viennacl::linalg::prod(A, B);
144  {
145  viennacl::scheduler::statement my_statement(vcl_C, viennacl::op_assign(), viennacl::linalg::prod(vcl_A, vcl_B));
146  viennacl::scheduler::execute(my_statement);
147  }
148  act_diff = std::fabs(diff(C, vcl_C));
149 
150  if ( act_diff > epsilon )
151  {
152  std::cout << "# Error at operation: matrix-matrix product" << std::endl;
153  std::cout << " diff: " << act_diff << std::endl;
154  retval = EXIT_FAILURE;
155  }
156  else
157  std::cout << "Test C = A * B passed!" << std::endl;
158 
159 
160  C += viennacl::linalg::prod(A, B);
161  {
163  viennacl::scheduler::execute(my_statement);
164  }
165  act_diff = std::fabs(diff(C, vcl_C));
166 
167  if ( act_diff > epsilon )
168  {
169  std::cout << "# Error at operation: matrix-matrix product" << std::endl;
170  std::cout << " diff: " << act_diff << std::endl;
171  retval = EXIT_FAILURE;
172  }
173  else
174  std::cout << "Test C += A * B passed!" << std::endl;
175 
176  C -= viennacl::linalg::prod(A, B);
177  {
179  viennacl::scheduler::execute(my_statement);
180  }
181  act_diff = std::fabs(diff(C, vcl_C));
182 
183  if ( act_diff > epsilon )
184  {
185  std::cout << "# Error at operation: matrix-matrix product" << std::endl;
186  std::cout << " diff: " << act_diff << std::endl;
187  retval = EXIT_FAILURE;
188  }
189  else
190  std::cout << "Test C -= A * B passed!" << std::endl;
191 
192 
193 
194 
195 
196  // Test: C +-= A * trans(B) --------------------------------------------------------------------------
197  C = boost::numeric::ublas::prod(A, trans(B_trans));
198  {
199  viennacl::scheduler::statement my_statement(vcl_C, viennacl::op_assign(), viennacl::linalg::prod(vcl_A, trans(vcl_B_trans)));
200  viennacl::scheduler::execute(my_statement);
201  }
202  act_diff = std::fabs(diff(C, vcl_C));
203 
204  if ( act_diff > epsilon )
205  {
206  std::cout << "# Error at operation: matrix-matrix product" << std::endl;
207  std::cout << " diff: " << act_diff << std::endl;
208  retval = EXIT_FAILURE;
209  }
210  else
211  std::cout << "Test C = A * trans(B) passed!" << std::endl;
212 
213 
214  C += boost::numeric::ublas::prod(A, trans(B_trans));
215  {
216  viennacl::scheduler::statement my_statement(vcl_C, viennacl::op_inplace_add(), viennacl::linalg::prod(vcl_A, trans(vcl_B_trans)));
217  viennacl::scheduler::execute(my_statement);
218  }
219  act_diff = std::fabs(diff(C, vcl_C));
220 
221  if ( act_diff > epsilon )
222  {
223  std::cout << "# Error at operation: matrix-matrix product" << std::endl;
224  std::cout << " diff: " << act_diff << std::endl;
225  retval = EXIT_FAILURE;
226  }
227  else
228  std::cout << "Test C += A * trans(B) passed!" << std::endl;
229 
230 
231  C -= boost::numeric::ublas::prod(A, trans(B_trans));
232  {
233  viennacl::scheduler::statement my_statement(vcl_C, viennacl::op_inplace_sub(), viennacl::linalg::prod(vcl_A, trans(vcl_B_trans)));
234  viennacl::scheduler::execute(my_statement);
235  }
236  act_diff = std::fabs(diff(C, vcl_C));
237 
238  if ( act_diff > epsilon )
239  {
240  std::cout << "# Error at operation: matrix-matrix product" << std::endl;
241  std::cout << " diff: " << act_diff << std::endl;
242  retval = EXIT_FAILURE;
243  }
244  else
245  std::cout << "Test C -= A * trans(B) passed!" << std::endl;
246 
247 
248 
249  // Test: C +-= trans(A) * B --------------------------------------------------------------------------
250  C = boost::numeric::ublas::prod(trans(A_trans), B);
251  {
252  viennacl::scheduler::statement my_statement(vcl_C, viennacl::op_assign(), viennacl::linalg::prod(trans(vcl_A_trans), vcl_B));
253  viennacl::scheduler::execute(my_statement);
254  }
255  act_diff = std::fabs(diff(C, vcl_C));
256 
257  if ( act_diff > epsilon )
258  {
259  std::cout << "# Error at operation: matrix-matrix product" << std::endl;
260  std::cout << " diff: " << act_diff << std::endl;
261  retval = EXIT_FAILURE;
262  }
263  else
264  std::cout << "Test C = trans(A) * B passed!" << std::endl;
265 
266 
267  C += boost::numeric::ublas::prod(trans(A_trans), B);
268  {
269  viennacl::scheduler::statement my_statement(vcl_C, viennacl::op_inplace_add(), viennacl::linalg::prod(trans(vcl_A_trans), vcl_B));
270  viennacl::scheduler::execute(my_statement);
271  }
272  act_diff = std::fabs(diff(C, vcl_C));
273 
274  if ( act_diff > epsilon )
275  {
276  std::cout << "# Error at operation: matrix-matrix product" << std::endl;
277  std::cout << " diff: " << act_diff << std::endl;
278  retval = EXIT_FAILURE;
279  }
280  else
281  std::cout << "Test C += trans(A) * B passed!" << std::endl;
282 
283 
284  C -= boost::numeric::ublas::prod(trans(A_trans), B);
285  {
286  viennacl::scheduler::statement my_statement(vcl_C, viennacl::op_inplace_sub(), viennacl::linalg::prod(trans(vcl_A_trans), vcl_B));
287  viennacl::scheduler::execute(my_statement);
288  }
289  act_diff = std::fabs(diff(C, vcl_C));
290 
291  if ( act_diff > epsilon )
292  {
293  std::cout << "# Error at operation: matrix-matrix product" << std::endl;
294  std::cout << " diff: " << act_diff << std::endl;
295  retval = EXIT_FAILURE;
296  }
297  else
298  std::cout << "Test C -= trans(A) * B passed!" << std::endl;
299 
300 
301 
302 
303 
304  // Test: C +-= trans(A) * trans(B) --------------------------------------------------------------------------
305  C = boost::numeric::ublas::prod(trans(A_trans), trans(B_trans));
306  {
307  viennacl::scheduler::statement my_statement(vcl_C, viennacl::op_assign(), viennacl::linalg::prod(trans(vcl_A_trans), trans(vcl_B_trans)));
308  viennacl::scheduler::execute(my_statement);
309  }
310  act_diff = std::fabs(diff(C, vcl_C));
311 
312  if ( act_diff > epsilon )
313  {
314  std::cout << "# Error at operation: matrix-matrix product" << std::endl;
315  std::cout << " diff: " << act_diff << std::endl;
316  retval = EXIT_FAILURE;
317  }
318  else
319  std::cout << "Test C = trans(A) * trans(B) passed!" << std::endl;
320 
321  C += boost::numeric::ublas::prod(trans(A_trans), trans(B_trans));
322  {
323  viennacl::scheduler::statement my_statement(vcl_C, viennacl::op_inplace_add(), viennacl::linalg::prod(trans(vcl_A_trans), trans(vcl_B_trans)));
324  viennacl::scheduler::execute(my_statement);
325  }
326  act_diff = std::fabs(diff(C, vcl_C));
327 
328  if ( act_diff > epsilon )
329  {
330  std::cout << "# Error at operation: matrix-matrix product" << std::endl;
331  std::cout << " diff: " << act_diff << std::endl;
332  retval = EXIT_FAILURE;
333  }
334  else
335  std::cout << "Test C += trans(A) * trans(B) passed!" << std::endl;
336 
337 
338  C -= boost::numeric::ublas::prod(trans(A_trans), trans(B_trans));
339  {
340  viennacl::scheduler::statement my_statement(vcl_C, viennacl::op_inplace_sub(), viennacl::linalg::prod(trans(vcl_A_trans), trans(vcl_B_trans)));
341  viennacl::scheduler::execute(my_statement);
342  }
343  act_diff = std::fabs(diff(C, vcl_C));
344 
345  if ( act_diff > epsilon )
346  {
347  std::cout << "# Error at operation: matrix-matrix product" << std::endl;
348  std::cout << " diff: " << act_diff << std::endl;
349  retval = EXIT_FAILURE;
350  }
351  else
352  std::cout << "Test C -= trans(A) * trans(B) passed!" << std::endl;
353 
354 
355 
356 
357  return retval;
358 }
359 
360 
361 
362 template< typename NumericT, typename F_A, typename F_B, typename F_C, typename Epsilon >
363 int test_prod(Epsilon const& epsilon)
364 {
365  int ret;
366 
368 
369  std::size_t matrix_size1 = 29; //some odd number, not too large
370  std::size_t matrix_size2 = 47; //some odd number, not too large
371  std::size_t matrix_size3 = 33; //some odd number, not too large
372  //std::size_t matrix_size1 = 128; //some odd number, not too large
373  //std::size_t matrix_size2 = 64; //some odd number, not too large
374  //std::size_t matrix_size3 = 128; //some odd number, not too large
375  //std::size_t matrix_size1 = 256; // for testing AMD kernels
376  //std::size_t matrix_size2 = 256; // for testing AMD kernels
377  //std::size_t matrix_size3 = 256; // for testing AMD kernels
378 
379  // --------------------------------------------------------------------------
380 
381  // ublas reference:
382  ublas::matrix<NumericT> A(matrix_size1, matrix_size2);
383  ublas::matrix<NumericT> big_A = ublas::scalar_matrix<NumericT>(4*matrix_size1, 4*matrix_size2, NumericT(3.1415));
384 
385  ublas::matrix<NumericT> B(matrix_size2, matrix_size3);
386  ublas::matrix<NumericT> big_B = ublas::scalar_matrix<NumericT>(4*matrix_size2, 4*matrix_size3, NumericT(42.0));
387 
388  ublas::matrix<NumericT> C(matrix_size1, matrix_size3);
389 
390  //fill A and B:
391  for (unsigned int i = 0; i < A.size1(); ++i)
392  for (unsigned int j = 0; j < A.size2(); ++j)
393  A(i,j) = static_cast<NumericT>(0.1) * randomNumber();
394  for (unsigned int i = 0; i < B.size1(); ++i)
395  for (unsigned int j = 0; j < B.size2(); ++j)
396  B(i,j) = static_cast<NumericT>(0.1) * randomNumber();
397 
398  ublas::matrix<NumericT> A_trans = trans(A);
399  ublas::matrix<NumericT> big_A_trans = trans(big_A);
400 
401  ublas::matrix<NumericT> B_trans = trans(B);
402  ublas::matrix<NumericT> big_B_trans = trans(big_B);
403 
404  //
405  // ViennaCL objects
406  //
407 
408  // A
409  viennacl::range range1_A(matrix_size1, 2*matrix_size1);
410  viennacl::range range2_A(matrix_size2, 2*matrix_size2);
411  viennacl::slice slice1_A(matrix_size1, 2, matrix_size1);
412  viennacl::slice slice2_A(matrix_size2, 3, matrix_size2);
413 
414  viennacl::matrix<NumericT, F_A> vcl_A(matrix_size1, matrix_size2);
415  viennacl::copy(A, vcl_A);
416 
417  viennacl::matrix<NumericT, F_A> vcl_big_range_A(4*matrix_size1, 4*matrix_size2);
418  viennacl::matrix_range<viennacl::matrix<NumericT, F_A> > vcl_range_A(vcl_big_range_A, range1_A, range2_A);
419  viennacl::copy(A, vcl_range_A);
420 
421  viennacl::matrix<NumericT, F_A> vcl_big_slice_A(4*matrix_size1, 4*matrix_size2);
422  viennacl::matrix_slice<viennacl::matrix<NumericT, F_A> > vcl_slice_A(vcl_big_slice_A, slice1_A, slice2_A);
423  viennacl::copy(A, vcl_slice_A);
424 
425 
426  // A^T
427  viennacl::matrix<NumericT, F_A> vcl_A_trans(matrix_size2, matrix_size1);
428  viennacl::copy(A_trans, vcl_A_trans);
429 
430  viennacl::matrix<NumericT, F_A> vcl_big_range_A_trans(4*matrix_size2, 4*matrix_size1);
431  viennacl::matrix_range<viennacl::matrix<NumericT, F_A> > vcl_range_A_trans(vcl_big_range_A_trans, range2_A, range1_A);
432  viennacl::copy(A_trans, vcl_range_A_trans);
433 
434  viennacl::matrix<NumericT, F_A> vcl_big_slice_A_trans(4*matrix_size2, 4*matrix_size1);
435  viennacl::matrix_slice<viennacl::matrix<NumericT, F_A> > vcl_slice_A_trans(vcl_big_slice_A_trans, slice2_A, slice1_A);
436  viennacl::copy(A_trans, vcl_slice_A_trans);
437 
438 
439 
440  // B
441  viennacl::range range1_B(2*matrix_size2, 3*matrix_size2);
442  viennacl::range range2_B(2*matrix_size3, 3*matrix_size3);
443  viennacl::slice slice1_B(matrix_size2, 3, matrix_size2);
444  viennacl::slice slice2_B(matrix_size3, 2, matrix_size3);
445 
446  viennacl::matrix<NumericT, F_B> vcl_B(matrix_size2, matrix_size3);
447  viennacl::copy(B, vcl_B);
448 
449  viennacl::matrix<NumericT, F_B> vcl_big_range_B(4*matrix_size2, 4*matrix_size3);
450  viennacl::matrix_range<viennacl::matrix<NumericT, F_B> > vcl_range_B(vcl_big_range_B, range1_B, range2_B);
451  viennacl::copy(B, vcl_range_B);
452 
453  viennacl::matrix<NumericT, F_B> vcl_big_slice_B(4*matrix_size2, 4*matrix_size3);
454  viennacl::matrix_slice<viennacl::matrix<NumericT, F_B> > vcl_slice_B(vcl_big_slice_B, slice1_B, slice2_B);
455  viennacl::copy(B, vcl_slice_B);
456 
457 
458  // B^T
459 
460  viennacl::matrix<NumericT, F_B> vcl_B_trans(matrix_size3, matrix_size2);
461  viennacl::copy(B_trans, vcl_B_trans);
462 
463  viennacl::matrix<NumericT, F_B> vcl_big_range_B_trans(4*matrix_size3, 4*matrix_size2);
464  viennacl::matrix_range<viennacl::matrix<NumericT, F_B> > vcl_range_B_trans(vcl_big_range_B_trans, range2_B, range1_B);
465  viennacl::copy(B_trans, vcl_range_B_trans);
466 
467  viennacl::matrix<NumericT, F_B> vcl_big_slice_B_trans(4*matrix_size3, 4*matrix_size2);
468  viennacl::matrix_slice<viennacl::matrix<NumericT, F_B> > vcl_slice_B_trans(vcl_big_slice_B_trans, slice2_B, slice1_B);
469  viennacl::copy(B_trans, vcl_slice_B_trans);
470 
471 
472  // C
473 
474  viennacl::range range1_C(matrix_size1-1, 2*matrix_size1-1);
475  viennacl::range range2_C(matrix_size3-1, 2*matrix_size3-1);
476  viennacl::slice slice1_C(matrix_size1-1, 3, matrix_size1);
477  viennacl::slice slice2_C(matrix_size3-1, 3, matrix_size3);
478 
479  viennacl::matrix<NumericT, F_C> vcl_C(matrix_size1, matrix_size3);
480 
481  viennacl::matrix<NumericT, F_C> vcl_big_range_C(4*matrix_size1, 4*matrix_size3);
482  viennacl::matrix_range<viennacl::matrix<NumericT, F_C> > vcl_range_C(vcl_big_range_C, range1_C, range2_C);
483 
484  viennacl::matrix<NumericT, F_C> vcl_big_slice_C(4*matrix_size1, 4*matrix_size3);
485  viennacl::matrix_slice<viennacl::matrix<NumericT, F_C> > vcl_slice_C(vcl_big_slice_C, slice1_C, slice2_C);
486 
487 
488  std::cout << "--- Part 1: Testing matrix-matrix products ---" << std::endl;
489 
493 
494  //
495  //
496  std::cout << "Now using A=matrix, B=matrix, C=matrix" << std::endl;
497  ret = test_prod<NumericT>(epsilon,
498  A, A_trans, B, B_trans, C,
499  vcl_A, vcl_A_trans,
500  vcl_B, vcl_B_trans,
501  vcl_C);
502  if (ret != EXIT_SUCCESS)
503  return ret;
504 
505 
506  //
507  //
508  std::cout << "Now using A=matrix, B=matrix, C=range" << std::endl;
509  ret = test_prod<NumericT>(epsilon,
510  A, A_trans, B, B_trans, C,
511  vcl_A, vcl_A_trans,
512  vcl_B, vcl_B_trans,
513  vcl_range_C);
514  if (ret != EXIT_SUCCESS)
515  return ret;
516 
517  //
518  //
519  std::cout << "Now using A=matrix, B=matrix, C=slice" << std::endl;
520  ret = test_prod<NumericT>(epsilon,
521  A, A_trans, B, B_trans, C,
522  vcl_A, vcl_A_trans,
523  vcl_B, vcl_B_trans,
524  vcl_slice_C);
525  if (ret != EXIT_SUCCESS)
526  return ret;
527 
528 
529 
530  //
531  //
532  std::cout << "Now using A=matrix, B=range, C=matrix" << std::endl;
533  ret = test_prod<NumericT>(epsilon,
534  A, A_trans, B, B_trans, C,
535  vcl_A, vcl_A_trans,
536  vcl_range_B, vcl_range_B_trans,
537  vcl_C);
538  if (ret != EXIT_SUCCESS)
539  return ret;
540 
541 
542  //
543  //
544  std::cout << "Now using A=matrix, B=range, C=range" << std::endl;
545  ret = test_prod<NumericT>(epsilon,
546  A, A_trans, B, B_trans, C,
547  vcl_A, vcl_A_trans,
548  vcl_range_B, vcl_range_B_trans,
549  vcl_range_C);
550  if (ret != EXIT_SUCCESS)
551  return ret;
552 
553  //
554  //
555  std::cout << "Now using A=matrix, B=range, C=slice" << std::endl;
556  ret = test_prod<NumericT>(epsilon,
557  A, A_trans, B, B_trans, C,
558  vcl_A, vcl_A_trans,
559  vcl_range_B, vcl_range_B_trans,
560  vcl_slice_C);
561  if (ret != EXIT_SUCCESS)
562  return ret;
563 
564 
565  //
566  //
567  std::cout << "Now using A=matrix, B=slice, C=matrix" << std::endl;
568  ret = test_prod<NumericT>(epsilon,
569  A, A_trans, B, B_trans, C,
570  vcl_A, vcl_A_trans,
571  vcl_slice_B, vcl_slice_B_trans,
572  vcl_C);
573  if (ret != EXIT_SUCCESS)
574  return ret;
575 
576 
577  //
578  //
579  std::cout << "Now using A=matrix, B=slice, C=range" << std::endl;
580  ret = test_prod<NumericT>(epsilon,
581  A, A_trans, B, B_trans, C,
582  vcl_A, vcl_A_trans,
583  vcl_slice_B, vcl_slice_B_trans,
584  vcl_range_C);
585  if (ret != EXIT_SUCCESS)
586  return ret;
587 
588  //
589  //
590  std::cout << "Now using A=matrix, B=slice, C=slice" << std::endl;
591  ret = test_prod<NumericT>(epsilon,
592  A, A_trans, B, B_trans, C,
593  vcl_A, vcl_A_trans,
594  vcl_slice_B, vcl_slice_B_trans,
595  vcl_slice_C);
596  if (ret != EXIT_SUCCESS)
597  return ret;
598 
599 
603 
604  //
605  //
606  std::cout << "Now using A=range, B=matrix, C=matrix" << std::endl;
607  ret = test_prod<NumericT>(epsilon,
608  A, A_trans, B, B_trans, C,
609  vcl_range_A, vcl_range_A_trans,
610  vcl_B, vcl_B_trans,
611  vcl_C);
612  if (ret != EXIT_SUCCESS)
613  return ret;
614 
615 
616  //
617  //
618  std::cout << "Now using A=range, B=matrix, C=range" << std::endl;
619  ret = test_prod<NumericT>(epsilon,
620  A, A_trans, B, B_trans, C,
621  vcl_range_A, vcl_range_A_trans,
622  vcl_B, vcl_B_trans,
623  vcl_range_C);
624  if (ret != EXIT_SUCCESS)
625  return ret;
626 
627  //
628  //
629  std::cout << "Now using A=range, B=matrix, C=slice" << std::endl;
630  ret = test_prod<NumericT>(epsilon,
631  A, A_trans, B, B_trans, C,
632  vcl_range_A, vcl_range_A_trans,
633  vcl_B, vcl_B_trans,
634  vcl_slice_C);
635  if (ret != EXIT_SUCCESS)
636  return ret;
637 
638 
639 
640  //
641  //
642  std::cout << "Now using A=range, B=range, C=matrix" << std::endl;
643  ret = test_prod<NumericT>(epsilon,
644  A, A_trans, B, B_trans, C,
645  vcl_range_A, vcl_range_A_trans,
646  vcl_range_B, vcl_range_B_trans,
647  vcl_C);
648  if (ret != EXIT_SUCCESS)
649  return ret;
650 
651 
652  //
653  //
654  std::cout << "Now using A=range, B=range, C=range" << std::endl;
655  ret = test_prod<NumericT>(epsilon,
656  A, A_trans, B, B_trans, C,
657  vcl_range_A, vcl_range_A_trans,
658  vcl_range_B, vcl_range_B_trans,
659  vcl_range_C);
660  if (ret != EXIT_SUCCESS)
661  return ret;
662 
663  //
664  //
665  std::cout << "Now using A=range, B=range, C=slice" << std::endl;
666  ret = test_prod<NumericT>(epsilon,
667  A, A_trans, B, B_trans, C,
668  vcl_range_A, vcl_range_A_trans,
669  vcl_range_B, vcl_range_B_trans,
670  vcl_slice_C);
671  if (ret != EXIT_SUCCESS)
672  return ret;
673 
674 
675  //
676  //
677  std::cout << "Now using A=range, B=slice, C=matrix" << std::endl;
678  ret = test_prod<NumericT>(epsilon,
679  A, A_trans, B, B_trans, C,
680  vcl_range_A, vcl_range_A_trans,
681  vcl_slice_B, vcl_slice_B_trans,
682  vcl_C);
683  if (ret != EXIT_SUCCESS)
684  return ret;
685 
686 
687  //
688  //
689  std::cout << "Now using A=range, B=slice, C=range" << std::endl;
690  ret = test_prod<NumericT>(epsilon,
691  A, A_trans, B, B_trans, C,
692  vcl_range_A, vcl_range_A_trans,
693  vcl_slice_B, vcl_slice_B_trans,
694  vcl_range_C);
695  if (ret != EXIT_SUCCESS)
696  return ret;
697 
698  //
699  //
700  std::cout << "Now using A=range, B=slice, C=slice" << std::endl;
701  ret = test_prod<NumericT>(epsilon,
702  A, A_trans, B, B_trans, C,
703  vcl_range_A, vcl_range_A_trans,
704  vcl_slice_B, vcl_slice_B_trans,
705  vcl_slice_C);
706  if (ret != EXIT_SUCCESS)
707  return ret;
708 
709 
710 
714 
715  //
716  //
717  std::cout << "Now using A=slice, B=matrix, C=matrix" << std::endl;
718  ret = test_prod<NumericT>(epsilon,
719  A, A_trans, B, B_trans, C,
720  vcl_slice_A, vcl_slice_A_trans,
721  vcl_B, vcl_B_trans,
722  vcl_C);
723  if (ret != EXIT_SUCCESS)
724  return ret;
725 
726 
727  //
728  //
729  std::cout << "Now using A=slice, B=matrix, C=range" << std::endl;
730  ret = test_prod<NumericT>(epsilon,
731  A, A_trans, B, B_trans, C,
732  vcl_slice_A, vcl_slice_A_trans,
733  vcl_B, vcl_B_trans,
734  vcl_range_C);
735  if (ret != EXIT_SUCCESS)
736  return ret;
737 
738  //
739  //
740  std::cout << "Now using A=slice, B=matrix, C=slice" << std::endl;
741  ret = test_prod<NumericT>(epsilon,
742  A, A_trans, B, B_trans, C,
743  vcl_slice_A, vcl_slice_A_trans,
744  vcl_B, vcl_B_trans,
745  vcl_slice_C);
746  if (ret != EXIT_SUCCESS)
747  return ret;
748 
749 
750 
751  //
752  //
753  std::cout << "Now using A=slice, B=range, C=matrix" << std::endl;
754  ret = test_prod<NumericT>(epsilon,
755  A, A_trans, B, B_trans, C,
756  vcl_slice_A, vcl_slice_A_trans,
757  vcl_range_B, vcl_range_B_trans,
758  vcl_C);
759  if (ret != EXIT_SUCCESS)
760  return ret;
761 
762 
763  //
764  //
765  std::cout << "Now using A=slice, B=range, C=range" << std::endl;
766  ret = test_prod<NumericT>(epsilon,
767  A, A_trans, B, B_trans, C,
768  vcl_slice_A, vcl_slice_A_trans,
769  vcl_range_B, vcl_range_B_trans,
770  vcl_range_C);
771  if (ret != EXIT_SUCCESS)
772  return ret;
773 
774  //
775  //
776  std::cout << "Now using A=slice, B=range, C=slice" << std::endl;
777  ret = test_prod<NumericT>(epsilon,
778  A, A_trans, B, B_trans, C,
779  vcl_slice_A, vcl_slice_A_trans,
780  vcl_range_B, vcl_range_B_trans,
781  vcl_slice_C);
782  if (ret != EXIT_SUCCESS)
783  return ret;
784 
785 
786  //
787  //
788  std::cout << "Now using A=slice, B=slice, C=matrix" << std::endl;
789  ret = test_prod<NumericT>(epsilon,
790  A, A_trans, B, B_trans, C,
791  vcl_slice_A, vcl_slice_A_trans,
792  vcl_slice_B, vcl_slice_B_trans,
793  vcl_C);
794  if (ret != EXIT_SUCCESS)
795  return ret;
796 
797 
798  //
799  //
800  std::cout << "Now using A=slice, B=slice, C=range" << std::endl;
801  ret = test_prod<NumericT>(epsilon,
802  A, A_trans, B, B_trans, C,
803  vcl_slice_A, vcl_slice_A_trans,
804  vcl_slice_B, vcl_slice_B_trans,
805  vcl_range_C);
806  if (ret != EXIT_SUCCESS)
807  return ret;
808 
809  //
810  //
811  std::cout << "Now using A=slice, B=slice, C=slice" << std::endl;
812  ret = test_prod<NumericT>(epsilon,
813  A, A_trans, B, B_trans, C,
814  vcl_slice_A, vcl_slice_A_trans,
815  vcl_slice_B, vcl_slice_B_trans,
816  vcl_slice_C);
817  if (ret != EXIT_SUCCESS)
818  return ret;
819 
820 
821  return ret;
822 
823 }
824 
825 
826 //
827 // Control functions
828 //
829 
830 
831 
832 template< typename NumericT, typename Epsilon >
833 int test(Epsilon const& epsilon)
834 {
835  int ret;
836 
837  std::cout << "///////////////////////////////////////" << std::endl;
838  std::cout << "/// Now testing A=row, B=row, C=row ///" << std::endl;
839  std::cout << "///////////////////////////////////////" << std::endl;
840  ret = test_prod<NumericT, viennacl::row_major, viennacl::row_major, viennacl::row_major>(epsilon);
841  if (ret != EXIT_SUCCESS)
842  return ret;
843 
844  std::cout << "///////////////////////////////////////" << std::endl;
845  std::cout << "/// Now testing A=row, B=row, C=col ///" << std::endl;
846  std::cout << "///////////////////////////////////////" << std::endl;
847  ret = test_prod<NumericT, viennacl::row_major, viennacl::row_major, viennacl::column_major>(epsilon);
848  if (ret != EXIT_SUCCESS)
849  return ret;
850 
851  std::cout << "///////////////////////////////////////" << std::endl;
852  std::cout << "/// Now testing A=row, B=col, C=row ///" << std::endl;
853  std::cout << "///////////////////////////////////////" << std::endl;
854  ret = test_prod<NumericT, viennacl::row_major, viennacl::column_major, viennacl::row_major>(epsilon);
855  if (ret != EXIT_SUCCESS)
856  return ret;
857 
858  std::cout << "///////////////////////////////////////" << std::endl;
859  std::cout << "/// Now testing A=row, B=col, C=col ///" << std::endl;
860  std::cout << "///////////////////////////////////////" << std::endl;
861  ret = test_prod<NumericT, viennacl::row_major, viennacl::column_major, viennacl::column_major>(epsilon);
862  if (ret != EXIT_SUCCESS)
863  return ret;
864 
865  std::cout << "///////////////////////////////////////" << std::endl;
866  std::cout << "/// Now testing A=col, B=row, C=row ///" << std::endl;
867  std::cout << "///////////////////////////////////////" << std::endl;
868  ret = test_prod<NumericT, viennacl::column_major, viennacl::row_major, viennacl::row_major>(epsilon);
869  if (ret != EXIT_SUCCESS)
870  return ret;
871 
872  std::cout << "///////////////////////////////////////" << std::endl;
873  std::cout << "/// Now testing A=col, B=row, C=col ///" << std::endl;
874  std::cout << "///////////////////////////////////////" << std::endl;
875  ret = test_prod<NumericT, viennacl::column_major, viennacl::row_major, viennacl::column_major>(epsilon);
876  if (ret != EXIT_SUCCESS)
877  return ret;
878 
879  std::cout << "///////////////////////////////////////" << std::endl;
880  std::cout << "/// Now testing A=col, B=col, C=row ///" << std::endl;
881  std::cout << "///////////////////////////////////////" << std::endl;
882  ret = test_prod<NumericT, viennacl::column_major, viennacl::column_major, viennacl::row_major>(epsilon);
883  if (ret != EXIT_SUCCESS)
884  return ret;
885 
886  std::cout << "///////////////////////////////////////" << std::endl;
887  std::cout << "/// Now testing A=col, B=col, C=col ///" << std::endl;
888  std::cout << "///////////////////////////////////////" << std::endl;
889  ret = test_prod<NumericT, viennacl::column_major, viennacl::column_major, viennacl::column_major>(epsilon);
890  if (ret != EXIT_SUCCESS)
891  return ret;
892 
893 
894 
895  return ret;
896 }
897 
898 //
899 // -------------------------------------------------------------
900 //
901 int main()
902 {
903  std::cout << std::endl;
904  std::cout << "----------------------------------------------" << std::endl;
905  std::cout << "----------------------------------------------" << std::endl;
906  std::cout << "## Test :: BLAS 3 routines" << std::endl;
907  std::cout << "----------------------------------------------" << std::endl;
908  std::cout << "----------------------------------------------" << std::endl;
909  std::cout << std::endl;
910 
911  int retval = EXIT_SUCCESS;
912 
913  std::cout << std::endl;
914  std::cout << "----------------------------------------------" << std::endl;
915  std::cout << std::endl;
916  {
917  typedef float NumericT;
918  NumericT epsilon = NumericT(1.0E-3);
919  std::cout << "# Testing setup:" << std::endl;
920  std::cout << " eps: " << epsilon << std::endl;
921  std::cout << " numeric: float" << std::endl;
922  retval = test<NumericT>(epsilon);
923  if ( retval == EXIT_SUCCESS )
924  std::cout << "# Test passed" << std::endl;
925  else
926  return retval;
927  }
928  std::cout << std::endl;
929  std::cout << "----------------------------------------------" << std::endl;
930  std::cout << std::endl;
931 #ifdef VIENNACL_WITH_OPENCL
933 #endif
934  {
935  {
936  typedef double NumericT;
937  NumericT epsilon = 1.0E-11;
938  std::cout << "# Testing setup:" << std::endl;
939  std::cout << " eps: " << epsilon << std::endl;
940  std::cout << " numeric: double" << std::endl;
941  retval = test<NumericT>(epsilon);
942  if ( retval == EXIT_SUCCESS )
943  std::cout << "# Test passed" << std::endl;
944  else
945  return retval;
946  }
947  std::cout << std::endl;
948  std::cout << "----------------------------------------------" << std::endl;
949  std::cout << std::endl;
950  }
951 
952  std::cout << std::endl;
953  std::cout << "------- Test completed --------" << std::endl;
954  std::cout << std::endl;
955 
956 
957  return retval;
958 }
This class represents a single scalar value on the GPU and behaves mostly like a built-in scalar type...
Definition: forwards.h:227
Generic interface for the l^2-norm. See viennacl/linalg/vector_operations.hpp for implementations...
Class for representing strided submatrices of a bigger matrix A.
Definition: forwards.h:443
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.
Some helper routines for reading/writing/printing scheduler expressions.
A tag class representing assignment.
Definition: forwards.h:81
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:375
void execute(statement const &s)
Definition: execute.hpp:279
viennacl::scalar< int > s2
viennacl::scalar< float > s1
T max(const T &lhs, const T &rhs)
Maximum.
Definition: util.hpp:59
viennacl::ocl::device const & current_device()
Convenience function for returning the active device in the current context.
Definition: backend.hpp:351
A tag class representing inplace addition.
Definition: forwards.h:83
float NumericT
Definition: bisect.cpp:40
viennacl::vector< float > v1
VectorT prod(std::vector< std::vector< T, A1 >, A2 > const &matrix, VectorT const &vector)
Definition: prod.hpp:102
Random number generator for returning uniformly distributed values in the closed interval [0...
Definition: random.hpp:44
int test_prod(Epsilon const &epsilon, ReferenceMatrixTypeA const &A, ReferenceMatrixTypeA const &A_trans, ReferenceMatrixTypeB const &B, ReferenceMatrixTypeB const &B_trans, ReferenceMatrixTypeC &C, MatrixTypeA const &vcl_A, MatrixTypeA const &vcl_A_trans, MatrixTypeB const &vcl_B, MatrixTypeB const &vcl_B_trans, MatrixTypeC &vcl_C)
iterator begin()
Returns an iterator pointing to the beginning of the vector (STL like)
Definition: vector.hpp:841
ScalarType diff(ScalarType &s1, viennacl::scalar< ScalarType > &s2)
bool double_support() const
ViennaCL convenience function: Returns true if the device supports double precision.
Definition: device.hpp:956
Implementations of dense direct solvers are found here.
Proxy classes for matrices.
A tag class representing inplace subtraction.
Definition: forwards.h:85
viennacl::vector< int > v2
void prod(std::vector< std::map< IndexT, NumericT > > const &stl_A, std::vector< std::map< IndexT, NumericT > > const &stl_B, std::vector< std::map< IndexT, NumericT > > &stl_C)
The vector type with operator-overloads and proxy classes is defined here. Linear algebra operations ...
T norm_inf(std::vector< T, A > const &v1)
Definition: norm_inf.hpp:60
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 small collection of sequential random number generators.
size_type size() const
Returns the length of the vector (cf. std::vector)
Definition: vector_def.hpp:118
A range class that refers to an interval [start, stop), where 'start' is included, and 'stop' is excluded.
Definition: forwards.h:424
float ScalarType
Definition: fft_1d.cpp:42
Provides the datastructures for dealing with a single statement such as 'x = y + z;'.
int test(Epsilon const &epsilon)
Class for representing non-strided submatrices of a bigger matrix A.
Definition: forwards.h:440
The main class for representing a statement such as x = inner_prod(y,z); at runtime.
Definition: forwards.h:502
iterator end()
Returns an iterator pointing to the end of the vector (STL like)
Definition: vector.hpp:848
A slice class that refers to an interval [start, stop), where 'start' is included, and 'stop' is excluded.
Definition: forwards.h:429
Implementation of the ViennaCL scalar class.