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
spmdm.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 
23 //
24 // include necessary system headers
25 //
26 #include <iostream>
27 #include <cmath>
28 
29 //
30 // ublas includes
31 //
32 #include <boost/numeric/ublas/io.hpp>
33 #include <boost/numeric/ublas/triangular.hpp>
34 #include <boost/numeric/ublas/matrix_sparse.hpp>
35 #include <boost/numeric/ublas/matrix.hpp>
36 #include <boost/numeric/ublas/matrix_proxy.hpp>
37 #include <boost/numeric/ublas/operation.hpp>
38 #include <boost/numeric/ublas/operation_sparse.hpp>
39 #include <boost/numeric/ublas/io.hpp>
40 #include <boost/numeric/ublas/lu.hpp>
41 
42 // Must be set if you want to use ViennaCL algorithms on ublas objects
43 #define VIENNACL_WITH_UBLAS 1
44 //#define VIENNACL_WITH_OPENCL 1
45 //#define VIENNACL_WITH_CUDA 1
46 //#define VIENNACL_DEBUG_KERNEL 1
47 //#define VIENNACL_BUILD_INFO 1
48 
49 //
50 // ViennaCL includes
51 //
52 #include "viennacl/scalar.hpp"
53 #include "viennacl/vector.hpp"
54 #include "viennacl/matrix.hpp"
58 #include "viennacl/ell_matrix.hpp"
59 #include "viennacl/hyb_matrix.hpp"
60 #include "viennacl/linalg/prod.hpp" //generic matrix-vector product
61 #include "viennacl/linalg/norm_2.hpp" //generic l2-norm for vectors
63 
64 
65 // Some helper functions for this tutorial:
66 #include "Random.hpp"
67 
68 
69 using namespace boost::numeric;
70 
71 template< typename ScalarType >
72 int check_matrices(const ublas::matrix< ScalarType >& ref_mat, const ublas::matrix< ScalarType >& mat, ScalarType eps) {
73 
74  std::size_t size1, size2;
75  size1 = ref_mat.size1(); size2 = ref_mat.size2();
76  if ( (size1 != mat.size1()) || (size2 != mat.size2()) )
77  return EXIT_FAILURE;
78 
79  for (unsigned int i = 0; i < size1; i++)
80  for (unsigned int j = 0; j < size2; j++)
81  {
82  ScalarType rel_error = std::abs(ref_mat(i,j) - mat(i,j)) / std::max(std::abs(ref_mat(i,j)), std::abs(mat(i,j)));
83  if ( rel_error > eps ) {
84  std::cout << "ERROR: Verification failed at (" << i <<", "<< j << "): "
85  << " Expected: " << ref_mat(i,j) << ", got: " << mat(i,j) << " (relative error: " << rel_error << ")" << std::endl;
86  return EXIT_FAILURE;
87  }
88  }
89 
90  std::cout << "Everything went well!" << std::endl;
91  return EXIT_SUCCESS;
92 }
93 
94 template<typename NumericT, typename ResultLayoutT, typename FactorLayoutT>
95 int test(NumericT epsilon)
96 {
97  int retVal = EXIT_SUCCESS;
98 
99  ublas::compressed_matrix<NumericT> ublas_lhs;
100 
101  if (viennacl::io::read_matrix_market_file(ublas_lhs, "../examples/testdata/mat65k.mtx") == EXIT_FAILURE)
102  {
103  std::cout << "Error reading Matrix file" << std::endl;
104  return EXIT_FAILURE;
105  }
106 
107  // add some extra weight to diagonal in order to avoid issues with round-off errors
108  for (std::size_t i=0; i<ublas_lhs.size1(); ++i)
109  ublas_lhs(i,i) *= NumericT(1.5);
110 
111  std::size_t cols_rhs = 1;
112 
117 
118  ublas::matrix<NumericT> ublas_result;
120 
121  viennacl::copy( ublas_lhs, compressed_lhs);
122  viennacl::copy( ublas_lhs, ell_lhs);
123  viennacl::copy( ublas_lhs, coo_lhs);
124  viennacl::copy( ublas_lhs, hyb_lhs);
125 
126  ublas::matrix<NumericT> ublas_rhs1(ublas_lhs.size2(), cols_rhs);
127  viennacl::matrix<NumericT, FactorLayoutT> rhs1(ublas_lhs.size2(), cols_rhs);
128 
129  ublas::matrix<NumericT> ublas_rhs2;
131 
132  ublas::matrix<NumericT> temp(ublas_rhs1.size1(), cols_rhs);
133 
134  for (unsigned int i = 0; i < ublas_rhs1.size1(); i++)
135  for (unsigned int j = 0; j < ublas_rhs1.size2(); j++)
136  ublas_rhs1(i,j) = NumericT(0.5) + NumericT(0.1) * random<NumericT>();
137  viennacl::copy( ublas_rhs1, rhs1);
138 
139  ublas_rhs2 = ublas::trans( ublas_rhs1);
140  viennacl::copy( ublas_rhs2, rhs2);
141 
142  /* gold result */
143  ublas_result = ublas::prod( ublas_lhs, ublas_rhs1);
144 
145  /******************************************************************/
146  std::cout << "Testing compressed(CSR) lhs * dense rhs" << std::endl;
147  result = viennacl::linalg::prod( compressed_lhs, rhs1);
148 
149  temp.clear();
150  viennacl::copy( result, temp);
151  retVal = check_matrices(ublas_result, temp, epsilon);
152 
153  /******************************************************************/
154  std::cout << "Testing compressed(ELL) lhs * dense rhs" << std::endl;
155  result.clear();
156  result = viennacl::linalg::prod( ell_lhs, rhs1);
157 
158  temp.clear();
159  viennacl::copy( result, temp);
160  check_matrices(ublas_result, temp, epsilon);
161 
162  /******************************************************************/
163 
164  std::cout << "Testing compressed(COO) lhs * dense rhs" << std::endl;
165  result.clear();
166  result = viennacl::linalg::prod( coo_lhs, rhs1);
167 
168  temp.clear();
169  viennacl::copy( result, temp);
170  check_matrices(ublas_result, temp, epsilon);
171 
172  /******************************************************************/
173 
174  std::cout << "Testing compressed(HYB) lhs * dense rhs" << std::endl;
175  result.clear();
176  result = viennacl::linalg::prod( hyb_lhs, rhs1);
177 
178  temp.clear();
179  viennacl::copy( result, temp);
180  check_matrices(ublas_result, temp, epsilon);
181 
182  /******************************************************************/
183 
184  /* gold result */
185  ublas_result = ublas::prod( ublas_lhs, ublas::trans(ublas_rhs2));
186 
187  /******************************************************************/
188  std::cout << std::endl << "Testing compressed(CSR) lhs * transposed dense rhs:" << std::endl;
189  result.clear();
190  result = viennacl::linalg::prod( compressed_lhs, viennacl::trans(rhs2));
191 
192  temp.clear();
193  viennacl::copy( result, temp);
194  retVal = check_matrices(ublas_result, temp, epsilon);
195 
196  /******************************************************************/
197  std::cout << "Testing compressed(ELL) lhs * transposed dense rhs" << std::endl;
198  result.clear();
199  result = viennacl::linalg::prod( ell_lhs, viennacl::trans(rhs2));
200 
201  temp.clear();
202  viennacl::copy( result, temp);
203  check_matrices(ublas_result, temp, epsilon);
204 
205  /******************************************************************/
206  std::cout << "Testing compressed(COO) lhs * transposed dense rhs" << std::endl;
207  result.clear();
208  result = viennacl::linalg::prod( coo_lhs, viennacl::trans(rhs2));
209 
210  temp.clear();
211  viennacl::copy( result, temp);
212  check_matrices(ublas_result, temp, epsilon);
213 
214  /******************************************************************/
215 
216  std::cout << "Testing compressed(HYB) lhs * transposed dense rhs" << std::endl;
217  result.clear();
218  result = viennacl::linalg::prod( hyb_lhs, viennacl::trans(rhs2));
219 
220  temp.clear();
221  viennacl::copy( result, temp);
222  check_matrices(ublas_result, temp, epsilon);
223 
224  /******************************************************************/
225  if (retVal == EXIT_SUCCESS) {
226  std::cout << "Tests passed successfully" << std::endl;
227  }
228 
229  return retVal;
230 }
231 
232 //
233 // -------------------------------------------------------------
234 //
235 int main()
236 {
237  std::cout << std::endl;
238  std::cout << "----------------------------------------------" << std::endl;
239  std::cout << "----------------------------------------------" << std::endl;
240  std::cout << "## Test :: Sparse-Dense Matrix Multiplication" << std::endl;
241  std::cout << "----------------------------------------------" << std::endl;
242  std::cout << "----------------------------------------------" << std::endl;
243  std::cout << std::endl;
244 
245  int retval = EXIT_SUCCESS;
246 
247  std::cout << std::endl;
248  std::cout << "----------------------------------------------" << std::endl;
249  std::cout << std::endl;
250  {
251  typedef float NumericT;
252  NumericT epsilon = static_cast<NumericT>(1E-4);
253  std::cout << "# Testing setup:" << std::endl;
254  std::cout << " eps: " << epsilon << std::endl;
255  std::cout << " numeric: float" << std::endl;
256  std::cout << " layout: row-major, row-major" << std::endl;
257  retval = test<NumericT, viennacl::row_major, viennacl::row_major>(epsilon);
258  if ( retval == EXIT_SUCCESS )
259  std::cout << "# Test passed" << std::endl;
260  else
261  return retval;
262 
263  std::cout << "# Testing setup:" << std::endl;
264  std::cout << " eps: " << epsilon << std::endl;
265  std::cout << " numeric: float" << std::endl;
266  std::cout << " layout: row-major, column-major" << std::endl;
267  retval = test<NumericT, viennacl::row_major, viennacl::column_major>(epsilon);
268  if ( retval == EXIT_SUCCESS )
269  std::cout << "# Test passed" << std::endl;
270  else
271  return retval;
272 
273  std::cout << "# Testing setup:" << std::endl;
274  std::cout << " eps: " << epsilon << std::endl;
275  std::cout << " numeric: float" << std::endl;
276  std::cout << " layout: column-major, row-major" << std::endl;
277  retval = test<NumericT, viennacl::column_major, viennacl::row_major>(epsilon);
278  if ( retval == EXIT_SUCCESS )
279  std::cout << "# Test passed" << std::endl;
280  else
281  return retval;
282 
283  std::cout << "# Testing setup:" << std::endl;
284  std::cout << " eps: " << epsilon << std::endl;
285  std::cout << " numeric: float" << std::endl;
286  std::cout << " layout: column-major, column-major" << std::endl;
287  retval = test<NumericT, viennacl::column_major, viennacl::column_major>(epsilon);
288  if ( retval == EXIT_SUCCESS )
289  std::cout << "# Test passed" << std::endl;
290  else
291  return retval;
292 
293  }
294  std::cout << std::endl;
295  std::cout << "----------------------------------------------" << std::endl;
296  std::cout << std::endl;
297 
298 #ifdef VIENNACL_WITH_OPENCL
300 #endif
301  {
302  {
303  typedef double NumericT;
304  NumericT epsilon = 1.0E-12;
305  std::cout << "# Testing setup:" << std::endl;
306  std::cout << " eps: " << epsilon << std::endl;
307  std::cout << " numeric: double" << std::endl;
308  std::cout << " layout: row-major, row-major" << std::endl;
309  retval = test<NumericT, viennacl::row_major, viennacl::row_major>(epsilon);
310  if ( retval == EXIT_SUCCESS )
311  std::cout << "# Test passed" << std::endl;
312  else
313  return retval;
314 
315  std::cout << "# Testing setup:" << std::endl;
316  std::cout << " eps: " << epsilon << std::endl;
317  std::cout << " numeric: double" << std::endl;
318  std::cout << " layout: row-major, column-major" << std::endl;
319  retval = test<NumericT, viennacl::row_major, viennacl::column_major>(epsilon);
320  if ( retval == EXIT_SUCCESS )
321  std::cout << "# Test passed" << std::endl;
322  else
323  return retval;
324 
325  std::cout << "# Testing setup:" << std::endl;
326  std::cout << " eps: " << epsilon << std::endl;
327  std::cout << " numeric: double" << std::endl;
328  std::cout << " layout: column-major, row-major" << std::endl;
329  retval = test<NumericT, viennacl::column_major, viennacl::row_major>(epsilon);
330  if ( retval == EXIT_SUCCESS )
331  std::cout << "# Test passed" << std::endl;
332  else
333  return retval;
334 
335  std::cout << "# Testing setup:" << std::endl;
336  std::cout << " eps: " << epsilon << std::endl;
337  std::cout << " numeric: double" << std::endl;
338  std::cout << " layout: column-major, column-major" << std::endl;
339  retval = test<NumericT, viennacl::column_major, viennacl::column_major>(epsilon);
340  if ( retval == EXIT_SUCCESS )
341  std::cout << "# Test passed" << std::endl;
342  else
343  return retval;
344  }
345  std::cout << std::endl;
346  std::cout << "----------------------------------------------" << std::endl;
347  std::cout << std::endl;
348  }
349 #ifdef VIENNACL_WITH_OPENCL
350  else
351  std::cout << "No double precision support, skipping test..." << std::endl;
352 #endif
353 
354 
355  std::cout << std::endl;
356  std::cout << "------- Test completed --------" << std::endl;
357  std::cout << std::endl;
358 
359  return retval;
360 }
361 
Sparse matrix class using a hybrid format composed of the ELL and CSR format for storing the nonzeros...
Definition: forwards.h:405
int check_matrices(const ublas::matrix< ScalarType > &ref_mat, const ublas::matrix< ScalarType > &mat, ScalarType eps)
Definition: spmdm.cpp:72
A reader and writer for the matrix market format is implemented here.
Generic interface for the l^2-norm. See viennacl/linalg/vector_operations.hpp for implementations...
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.
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.
vcl_size_t size1(MatrixType const &mat)
Generic routine for obtaining the number of rows of a matrix (ViennaCL, uBLAS, etc.)
Definition: size.hpp:216
A dense matrix class.
Definition: forwards.h:374
int main()
Definition: spmdm.cpp:235
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
result_of::size_type< MatrixType >::type size2(MatrixType const &mat)
Generic routine for obtaining the number of columns of a matrix (ViennaCL, uBLAS, etc...
Definition: size.hpp:245
Implementation of the coordinate_matrix class.
int test(NumericT epsilon)
Definition: spmdm.cpp:95
Implementation of the hyb_matrix class.
VectorT prod(std::vector< std::vector< T, A1 >, A2 > const &matrix, VectorT const &vector)
Definition: prod.hpp:91
Sparse matrix class using the ELLPACK format for storing the nonzeros.
Definition: ell_matrix.hpp:53
void clear()
Resets all entries to zero.
Implementation of the compressed_matrix class.
bool double_support() const
ViennaCL convenience function: Returns true if the device supports double precision.
Definition: device.hpp:956
Implementation of the ell_matrix class.
void prod(const MatrixT1 &A, bool transposed_A, const MatrixT2 &B, bool transposed_B, MatrixT3 &C, ScalarT alpha, ScalarT beta)
Implementations of dense direct solvers are found here.
The vector type with operator-overloads and proxy classes is defined here. Linear algebra operations ...
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) ...
float ScalarType
Definition: fft_1d.cpp:42
long read_matrix_market_file(MatrixT &mat, const char *file, long index_base=1)
Reads a sparse matrix from a file (MatrixMarket format)
Implementation of the ViennaCL scalar class.
A sparse square matrix, where entries are stored as triplets (i,j, val), where i and j are the row an...