ViennaCL - The Vienna Computing Library: examples/benchmarks/direct_solve.cpp Source File

ViennaCL - The Vienna Computing Library 1.7.1 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-2016, 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 #include "viennacl/scalar.hpp"
27 #include "viennacl/matrix.hpp"
28 #include "viennacl/matrix_proxy.hpp"
29 #include "viennacl/vector.hpp"
30 #include "viennacl/linalg/prod.hpp"
31 #include "viennacl/linalg/norm_2.hpp"
32 #include "viennacl/linalg/direct_solve.hpp"
33 #include "viennacl/tools/random.hpp"
34 #include "viennacl/tools/timer.hpp"
35
36 #define BENCHMARK_RUNS 10
37
38
39 inline void printOps(double num_ops, double exec_time)
40 {
41 std::cout << "GFLOPs: " << num_ops / (1000000 * exec_time * 1000) << std::endl;
42 }
43
44
45 template<typename NumericT>
46 void fill_matrix(viennacl::matrix<NumericT> & mat)
47 {
48 viennacl::tools::uniform_random_numbers<NumericT> randomNumber;
49
50 for (std::size_t i = 0; i < mat.size1(); ++i)
51 {
52 for (std::size_t j = 0; j < mat.size2(); ++j)
53 mat(i, j) = static_cast<NumericT>(-0.5) * randomNumber();
54 mat(i, i) = NumericT(1.0) + NumericT(2.0) * randomNumber(); //some extra weight on diagonal for stability
55 }
56 }
57
58 template<typename NumericT>
59 void fill_vector(viennacl::vector<NumericT> & vec)
60 {
61 viennacl::tools::uniform_random_numbers<NumericT> randomNumber;
62
63 for (std::size_t i = 0; i < vec.size(); ++i)
64 vec(i) = NumericT(1.0) + NumericT(2.0) * randomNumber(); //some extra weight on diagonal for stability
65 }
66
67 template<typename NumericT,typename MatrixT1, typename MatrixT2,typename MatrixT3, typename SolverTag>
68 void run_solver_matrix(MatrixT1 const & matrix1, MatrixT2 const & matrix2,MatrixT3 & result, SolverTag)
69 {
70 std::cout << "------- Solver tag: " <<SolverTag::name()<<" ----------" << std::endl;
71 result = viennacl::linalg::solve(matrix1, matrix2, SolverTag());
72
73 viennacl::tools::timer timer;
74 viennacl::backend::finish();
75
76 timer.start();
77 for (int runs=0; runs<BENCHMARK_RUNS; ++runs)
78 result = viennacl::linalg::solve(matrix1, matrix2, SolverTag());
79
80 double exec_time = timer.get();
81 viennacl::backend::finish();
82 std::cout << "GPU: ";printOps(double(matrix1.size1() * matrix1.size1() * matrix2.size2()),(static_cast<double>(exec_time) / static_cast<double>(BENCHMARK_RUNS)));
83 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;
84 std::cout << "Execution time: " << exec_time/BENCHMARK_RUNS << std::endl;
85 std::cout << "------- Finnished: " << SolverTag::name() << " ----------" << std::endl;
86 }
87
88 template<typename NumericT,typename VectorT, typename VectorT2,typename MatrixT, typename SolverTag>
89 void run_solver_vector(MatrixT const & matrix, VectorT2 const & vector2,VectorT & result, SolverTag)
90 {
91 std::cout << "------- Solver tag: " <<SolverTag::name()<<" ----------" << std::endl;
92 result = viennacl::linalg::solve(matrix, vector2, SolverTag());
93
94 viennacl::tools::timer timer;
95 viennacl::backend::finish();
96
97 timer.start();
98 for (int runs=0; runs<BENCHMARK_RUNS; ++runs)
99 {
100 result = viennacl::linalg::solve(matrix, vector2, SolverTag());
101 }
102 double exec_time = timer.get();
103 viennacl::backend::finish();
104 std::cout << "GPU: ";printOps(double(matrix.size1() * matrix.size1()),(static_cast<double>(exec_time) / static_cast<double>(BENCHMARK_RUNS)));
105 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;
106 std::cout << "Execution time: " << exec_time/BENCHMARK_RUNS << std::endl;
107 std::cout << "------- Finished: " << SolverTag::name() << " ----------" << std::endl;
108 }
109
110 template<typename NumericT,typename F_A, typename F_B>
111 void run_benchmark()
112 {
113 std::size_t matrix_size = 1500; //some odd number, not too large
114 std::size_t rhs_num = 153;
115
116 viennacl::matrix<NumericT, F_A> vcl_A(matrix_size, matrix_size);
117 viennacl::matrix<NumericT, F_B> vcl_B(matrix_size, rhs_num);
118 viennacl::matrix<NumericT, F_B> result(matrix_size, rhs_num);
119
120 viennacl::vector<NumericT> vcl_vec_B(matrix_size);
121 viennacl::vector<NumericT> vcl_vec_result(matrix_size);
122
123 fill_matrix(vcl_A);
124 fill_matrix(vcl_B);
125
126 fill_vector(vcl_vec_B);
127 std::cout << "------- Solve Matrix-Matrix: ----------\n" << std::endl;
128 run_solver_matrix<NumericT>(vcl_A,vcl_B,result,viennacl::linalg::lower_tag());
129 run_solver_matrix<NumericT>(vcl_A,vcl_B,result,viennacl::linalg::unit_lower_tag());
130 run_solver_matrix<NumericT>(vcl_A,vcl_B,result,viennacl::linalg::upper_tag());
131 run_solver_matrix<NumericT>(vcl_A,vcl_B,result,viennacl::linalg::unit_upper_tag());
132 std::cout << "------- End Matrix-Matrix: ----------\n" << std::endl;
133
134 std::cout << "------- Solve Matrix-Vector: ----------\n" << std::endl;
135 run_solver_vector<NumericT>(vcl_A,vcl_vec_B,vcl_vec_result,viennacl::linalg::lower_tag());
136 run_solver_vector<NumericT>(vcl_A,vcl_vec_B,vcl_vec_result,viennacl::linalg::unit_lower_tag());
137 run_solver_vector<NumericT>(vcl_A,vcl_vec_B,vcl_vec_result,viennacl::linalg::upper_tag());
138 run_solver_vector<NumericT>(vcl_A,vcl_vec_B,vcl_vec_result,viennacl::linalg::unit_upper_tag());
139 std::cout << "------- End Matrix-Vector: ----------\n" << std::endl;
140 }
141
142 int main()
143 {
144 std::cout << std::endl;
145 std::cout << "----------------------------------------------" << std::endl;
146 std::cout << " Device Info" << std::endl;
147 std::cout << "----------------------------------------------" << std::endl;
148
149 #ifdef VIENNACL_WITH_OPENCL
150 std::cout << viennacl::ocl::current_device().info() << std::endl;
151 #endif
152 std::cout << std::endl;
153 std::cout << "----------------------------------------------" << std::endl;
154 std::cout << "----------------------------------------------" << std::endl;
155 std::cout << "## Benchmark :: Direct solve" << std::endl;
156 std::cout << "----------------------------------------------" << std::endl;
157 std::cout << std::endl;
158 std::cout << " -------------------------------" << std::endl;
159 std::cout << " # benchmarking single-precision" << std::endl;
160 std::cout << " -------------------------------" << std::endl;
161 run_benchmark<float,viennacl::row_major,viennacl::row_major>();
162 #ifdef VIENNACL_WITH_OPENCL
163 if ( viennacl::ocl::current_device().double_support() )
164 #endif
165 {
166 std::cout << std::endl;
167 std::cout << " -------------------------------" << std::endl;
168 std::cout << " # benchmarking double-precision" << std::endl;
169 std::cout << " -------------------------------" << std::endl;
170 run_benchmark<double,viennacl::row_major,viennacl::row_major>();
171 }
172 return 0;
173 }
viennacl::tools::timer
Simple timer class based on gettimeofday (POSIX) or QueryPerformanceCounter (Windows).
Definition: timer.hpp:90
run_solver_vector
void run_solver_vector(MatrixT const &matrix, VectorT2 const &vector2, VectorT &result, SolverTag)
Definition: direct_solve.cpp:89
norm_2.hpp
Generic interface for the l^2-norm. See viennacl/linalg/vector_operations.hpp for implementations...
run_solver_matrix
void run_solver_matrix(MatrixT1 const &matrix1, MatrixT2 const &matrix2, MatrixT3 &result, SolverTag)
Definition: direct_solve.cpp:68
prod.hpp
Generic interface for matrix-vector and matrix-matrix products. See viennacl/linalg/vector_operations...
matrix.hpp
Implementation of the dense matrix class.
viennacl::linalg::lower_tag
A tag class representing a lower triangular matrix.
Definition: forwards.h:849
viennacl::backend::finish
void finish()
Synchronizes the execution. finish() will only return after all compute kernels (CUDA, OpenCL) have completed.
Definition: memory.hpp:54
BENCHMARK_RUNS
#define BENCHMARK_RUNS
Definition: direct_solve.cpp:36
viennacl::matrix< NumericT >
viennacl::ocl::current_device
viennacl::ocl::device const & current_device()
Convenience function for returning the active device in the current context.
Definition: backend.hpp:351
fill_matrix
void fill_matrix(viennacl::matrix< NumericT > &mat)
Definition: direct_solve.cpp:46
viennacl::linalg::solve
VectorT solve(MatrixT const &matrix, VectorT const &rhs, bicgstab_tag const &tag, PreconditionerT const &precond)
Definition: bicgstab.hpp:496
viennacl::ocl::device::info
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
NumericT
float NumericT
Definition: bisect.cpp:40
viennacl::tools::uniform_random_numbers
Random number generator for returning uniformly distributed values in the closed interval [0...
Definition: random.hpp:44
viennacl::linalg::upper_tag
A tag class representing an upper triangular matrix.
Definition: forwards.h:854
fill_vector
void fill_vector(viennacl::vector< NumericT > &vec)
Definition: direct_solve.cpp:59
viennacl::ocl::device::double_support
bool double_support() const
ViennaCL convenience function: Returns true if the device supports double precision.
Definition: device.hpp:956
viennacl::matrix_base::size2
size_type size2() const
Returns the number of columns.
Definition: matrix_def.hpp:226
main
int main()
Definition: direct_solve.cpp:142
viennacl::vector< NumericT >
printOps
void printOps(double num_ops, double exec_time)
Definition: direct_solve.cpp:39
viennacl::matrix_base::size1
size_type size1() const
Returns the number of rows.
Definition: matrix_def.hpp:224
direct_solve.hpp
Implementations of dense direct solvers are found here.
timer.hpp
A simple, yet (mostly) sufficiently accurate timer for benchmarking and profiling.
matrix_proxy.hpp
Proxy classes for matrices.
vector.hpp
The vector type with operator-overloads and proxy classes is defined here. Linear algebra operations ...
random.hpp
A small collection of sequential random number generators.
run_benchmark
void run_benchmark()
Definition: direct_solve.cpp:111
viennacl::vector_base::size
size_type size() const
Returns the length of the vector (cf. std::vector)
Definition: vector_def.hpp:118
viennacl::linalg::unit_lower_tag
A tag class representing a lower triangular matrix with unit diagonal.
Definition: forwards.h:859
viennacl::tools::timer::get
double get() const
Definition: timer.hpp:104
viennacl::tools::timer::start
void start()
Definition: timer.hpp:97
scalar.hpp
Implementation of the ViennaCL scalar class.
viennacl::linalg::unit_upper_tag
A tag class representing an upper triangular matrix with unit diagonal.
Definition: forwards.h:864