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
direct_solve.cpp
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 
19 /*
20 * Benchmark: Direct solve matrix-matrix and matrix-vecotor
21 *
22 */
23 #include <iostream>
24 
25 
26 #define VIENNACL_WITH_UBLAS 1
27 #include "viennacl/scalar.hpp"
28 #include "viennacl/matrix.hpp"
30 #include "viennacl/vector.hpp"
31 #include "viennacl/linalg/prod.hpp"
35 
36 #include "benchmark-utils.hpp"
37 
38 #define BENCHMARK_RUNS 10
39 
40 template<typename NumericT>
42 {
43  for (std::size_t i = 0; i < mat.size1(); ++i)
44  {
45  for (std::size_t j = 0; j < mat.size2(); ++j)
46  mat(i, j) = static_cast<NumericT>(-0.5) * random<NumericT>();
47  mat(i, i) = NumericT(1.0) + NumericT(2.0) * random<NumericT>(); //some extra weight on diagonal for stability
48  }
49 }
50 
51 template<typename NumericT>
53 {
54  for (std::size_t i = 0; i < vec.size(); ++i)
55  vec(i) = NumericT(1.0) + NumericT(2.0) * random<NumericT>(); //some extra weight on diagonal for stability
56 }
57 
58 template<typename NumericT,typename MatrixT1, typename MatrixT2,typename MatrixT3, typename SolverTag>
59 void run_solver_matrix(MatrixT1 const & matrix1, MatrixT2 const & matrix2,MatrixT3 & result, SolverTag)
60 {
61  std::cout << "------- Solver tag: " <<SolverTag::name()<<" ----------" << std::endl;
62  result = viennacl::linalg::solve(matrix1, matrix2, SolverTag());
63 
64  Timer timer;
66 
67  timer.start();
68  for (int runs=0; runs<BENCHMARK_RUNS; ++runs)
69  result = viennacl::linalg::solve(matrix1, matrix2, SolverTag());
70 
71  double exec_time = timer.get();
73  std::cout << "GPU: ";printOps(double(matrix1.size1() * matrix1.size1() * matrix2.size2()),(static_cast<double>(exec_time) / static_cast<double>(BENCHMARK_RUNS)));
74  std::cout << "GPU: " << double(matrix1.size1() * matrix1.size1() * matrix2.size2() * sizeof(NumericT)) / (static_cast<double>(exec_time) / static_cast<double>(BENCHMARK_RUNS)) / 1e9 << " GB/sec" << std::endl;
75  std::cout << "Execution time: " << exec_time/BENCHMARK_RUNS << std::endl;
76  std::cout << "------- Finnished: " << SolverTag::name() << " ----------" << std::endl;
77 }
78 
79 template<typename NumericT,typename VectorT, typename VectorT2,typename MatrixT, typename SolverTag>
80 void run_solver_vector(MatrixT const & matrix, VectorT2 const & vector2,VectorT & result, SolverTag)
81 {
82  std::cout << "------- Solver tag: " <<SolverTag::name()<<" ----------" << std::endl;
83  result = viennacl::linalg::solve(matrix, vector2, SolverTag());
84 
85  Timer timer;
87 
88  timer.start();
89  for (int runs=0; runs<BENCHMARK_RUNS; ++runs)
90  {
91  result = viennacl::linalg::solve(matrix, vector2, SolverTag());
92  }
93  double exec_time = timer.get();
95  std::cout << "GPU: ";printOps(double(matrix.size1() * matrix.size1()),(static_cast<double>(exec_time) / static_cast<double>(BENCHMARK_RUNS)));
96  std::cout << "GPU: "<< double(matrix.size1() * matrix.size1() * sizeof(NumericT)) / (static_cast<double>(exec_time) / static_cast<double>(BENCHMARK_RUNS)) / 1e9 << " GB/sec" << std::endl;
97  std::cout << "Execution time: " << exec_time/BENCHMARK_RUNS << std::endl;
98  std::cout << "------- Finished: " << SolverTag::name() << " ----------" << std::endl;
99 }
100 
101 template<typename NumericT,typename F_A, typename F_B>
103 {
104  std::size_t matrix_size = 1500; //some odd number, not too large
105  std::size_t rhs_num = 153;
106 
107  viennacl::matrix<NumericT, F_A> vcl_A(matrix_size, matrix_size);
108  viennacl::matrix<NumericT, F_B> vcl_B(matrix_size, rhs_num);
109  viennacl::matrix<NumericT, F_B> result(matrix_size, rhs_num);
110 
111  viennacl::vector<NumericT> vcl_vec_B(matrix_size);
112  viennacl::vector<NumericT> vcl_vec_result(matrix_size);
113 
114  fill_matrix(vcl_A);
115  fill_matrix(vcl_B);
116 
117  fill_vector(vcl_vec_B);
118  std::cout << "------- Solve Matrix-Matrix: ----------\n" << std::endl;
119  run_solver_matrix<NumericT>(vcl_A,vcl_B,result,viennacl::linalg::lower_tag());
120  run_solver_matrix<NumericT>(vcl_A,vcl_B,result,viennacl::linalg::unit_lower_tag());
121  run_solver_matrix<NumericT>(vcl_A,vcl_B,result,viennacl::linalg::upper_tag());
122  run_solver_matrix<NumericT>(vcl_A,vcl_B,result,viennacl::linalg::unit_upper_tag());
123  std::cout << "------- End Matrix-Matrix: ----------\n" << std::endl;
124 
125  std::cout << "------- Solve Matrix-Vector: ----------\n" << std::endl;
126  run_solver_vector<NumericT>(vcl_A,vcl_vec_B,vcl_vec_result,viennacl::linalg::lower_tag());
127  run_solver_vector<NumericT>(vcl_A,vcl_vec_B,vcl_vec_result,viennacl::linalg::unit_lower_tag());
128  run_solver_vector<NumericT>(vcl_A,vcl_vec_B,vcl_vec_result,viennacl::linalg::upper_tag());
129  run_solver_vector<NumericT>(vcl_A,vcl_vec_B,vcl_vec_result,viennacl::linalg::unit_upper_tag());
130  std::cout << "------- End Matrix-Vector: ----------\n" << std::endl;
131 }
132 
133 int main()
134 {
135  std::cout << std::endl;
136  std::cout << "----------------------------------------------" << std::endl;
137  std::cout << " Device Info" << std::endl;
138  std::cout << "----------------------------------------------" << std::endl;
139 
140 #ifdef VIENNACL_WITH_OPENCL
141  std::cout << viennacl::ocl::current_device().info() << std::endl;
142 #endif
143  std::cout << std::endl;
144  std::cout << "----------------------------------------------" << std::endl;
145  std::cout << "----------------------------------------------" << std::endl;
146  std::cout << "## Benchmark :: Direct solve" << std::endl;
147  std::cout << "----------------------------------------------" << std::endl;
148  std::cout << std::endl;
149  std::cout << " -------------------------------" << std::endl;
150  std::cout << " # benchmarking single-precision" << std::endl;
151  std::cout << " -------------------------------" << std::endl;
152  run_benchmark<float,viennacl::row_major,viennacl::row_major>();
153 #ifdef VIENNACL_WITH_OPENCL
155 #endif
156  {
157  std::cout << std::endl;
158  std::cout << " -------------------------------" << std::endl;
159  std::cout << " # benchmarking double-precision" << std::endl;
160  std::cout << " -------------------------------" << std::endl;
161  run_benchmark<double,viennacl::row_major,viennacl::row_major>();
162  }
163  return 0;
164 }
void run_solver_vector(MatrixT const &matrix, VectorT2 const &vector2, VectorT &result, SolverTag)
Generic interface for the l^2-norm. See viennacl/linalg/vector_operations.hpp for implementations...
void run_solver_matrix(MatrixT1 const &matrix1, MatrixT2 const &matrix2, MatrixT3 &result, SolverTag)
Generic interface for matrix-vector and matrix-matrix products. See viennacl/linalg/vector_operations...
Implementation of the dense matrix class.
A tag class representing a lower triangular matrix.
Definition: forwards.h:809
void finish()
Synchronizes the execution. finish() will only return after all compute kernels (CUDA, OpenCL) have completed.
Definition: memory.hpp:54
#define BENCHMARK_RUNS
void start()
A dense matrix class.
Definition: forwards.h:374
double get() const
viennacl::ocl::device const & current_device()
Convenience function for returning the active device in the current context.
Definition: backend.hpp:351
void printOps(double num_ops, double exec_time)
void fill_matrix(viennacl::matrix< NumericT > &mat)
std::string info(vcl_size_t indent=0, char indent_char= ' ') const
Returns an info string with a few properties of the device. Use full_info() to get all details...
Definition: device.hpp:995
A tag class representing an upper triangular matrix.
Definition: forwards.h:814
void fill_vector(viennacl::vector< NumericT > &vec)
bool double_support() const
ViennaCL convenience function: Returns true if the device supports double precision.
Definition: device.hpp:956
size_type size2() const
Returns the number of columns.
Definition: matrix_def.hpp:217
int main()
size_type size1() const
Returns the number of rows.
Definition: matrix_def.hpp:215
Implementations of dense direct solvers are found here.
Proxy classes for matrices.
The vector type with operator-overloads and proxy classes is defined here. Linear algebra operations ...
void run_benchmark()
size_type size() const
Returns the length of the vector (cf. std::vector)
Definition: vector_def.hpp:118
A tag class representing a lower triangular matrix with unit diagonal.
Definition: forwards.h:819
Implementation of the ViennaCL scalar class.
A tag class representing an upper triangular matrix with unit diagonal.
Definition: forwards.h:824
viennacl::vector< NumericT > solve(MatrixT const &A, viennacl::vector_base< NumericT > const &rhs, bicgstab_tag const &tag, viennacl::linalg::no_precond)
Implementation of a pipelined stabilized Bi-conjugate gradient solver.
Definition: bicgstab.hpp:88