ViennaCL - The Vienna Computing Library  1.6.2
Free open-source GPU-accelerated linear algebra and solver library.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
scheduler_vector.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 
24 //
25 // *** System
26 //
27 #include <iostream>
28 #include <iomanip>
29 
30 //
31 // *** Boost
32 //
33 #include <boost/numeric/ublas/io.hpp>
34 #include <boost/numeric/ublas/vector.hpp>
35 #include <boost/numeric/ublas/vector_proxy.hpp>
36 
37 //
38 // *** ViennaCL
39 //
40 //#define VIENNACL_DEBUG_ALL
41 #define VIENNACL_WITH_UBLAS 1
42 #include "viennacl/vector.hpp"
43 #include "viennacl/matrix.hpp"
49 
52 
53 #include "Random.hpp"
54 
55 using namespace boost::numeric;
56 
57 
58 //
59 // -------------------------------------------------------------
60 //
61 template<typename ScalarType>
63 {
65  if (std::fabs(s1 - s2) > 0)
66  return (s1 - s2) / std::max(std::fabs(s1), std::fabs(s2));
67  return 0;
68 }
69 //
70 // -------------------------------------------------------------
71 //
72 template<typename ScalarType>
74 {
76  if (std::fabs(s1 - s2) > 0)
77  return (s1 - s2) / std::max(std::fabs(s1), std::fabs(s2));
78  return 0;
79 }
80 //
81 // -------------------------------------------------------------
82 //
83 template<typename ScalarType>
85 {
87  if (std::fabs(s1 - s2) > 0)
88  return (s1 - s2) / std::max(std::fabs(s1), std::fabs(s2));
89  return 0;
90 }
91 //
92 // -------------------------------------------------------------
93 //
94 template<typename ScalarType, typename ViennaCLVectorType>
95 ScalarType diff(ublas::vector<ScalarType> const & v1, ViennaCLVectorType const & vcl_vec)
96 {
97  ublas::vector<ScalarType> v2_cpu(vcl_vec.size());
99  viennacl::copy(vcl_vec, v2_cpu);
100 
101  for (unsigned int i=0;i<v1.size(); ++i)
102  {
103  if ( std::max( std::fabs(v2_cpu[i]), std::fabs(v1[i]) ) > 0 )
104  v2_cpu[i] = std::fabs(v2_cpu[i] - v1[i]) / std::max( std::fabs(v2_cpu[i]), std::fabs(v1[i]) );
105  else
106  v2_cpu[i] = 0.0;
107  }
108 
109  return ublas::norm_inf(v2_cpu);
110 }
111 
112 
113 template<typename T1, typename T2>
114 int check(T1 const & t1, T2 const & t2, double epsilon)
115 {
116  int retval = EXIT_SUCCESS;
117 
118  double temp = std::fabs(diff(t1, t2));
119  if (temp > epsilon)
120  {
121  std::cout << "# Error! Relative difference: " << temp << std::endl;
122  retval = EXIT_FAILURE;
123  }
124  else
125  std::cout << "PASSED!" << std::endl;
126  return retval;
127 }
128 
129 
130 //
131 // -------------------------------------------------------------
132 //
133 template< typename NumericT, typename Epsilon, typename UblasVectorType, typename ViennaCLVectorType1, typename ViennaCLVectorType2 >
134 int test(Epsilon const& epsilon,
135  UblasVectorType & ublas_v1, UblasVectorType & ublas_v2,
136  ViennaCLVectorType1 & vcl_v1, ViennaCLVectorType2 & vcl_v2)
137 {
138  int retval = EXIT_SUCCESS;
139 
140  NumericT cpu_result = 42.0;
141  viennacl::scalar<NumericT> gpu_result = 43.0;
142  NumericT alpha = NumericT(3.1415);
143  NumericT beta = NumericT(2.7172);
144 
145  //
146  // Initializer:
147  //
148  std::cout << "Checking for zero_vector initializer..." << std::endl;
149  ublas_v1 = ublas::zero_vector<NumericT>(ublas_v1.size());
150  vcl_v1 = viennacl::zero_vector<NumericT>(vcl_v1.size());
151  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
152  return EXIT_FAILURE;
153 
154  std::cout << "Checking for scalar_vector initializer..." << std::endl;
155  ublas_v1 = ublas::scalar_vector<NumericT>(ublas_v1.size(), cpu_result);
156  vcl_v1 = viennacl::scalar_vector<NumericT>(vcl_v1.size(), cpu_result);
157  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
158  return EXIT_FAILURE;
159 
160  ublas_v1 = ublas::scalar_vector<NumericT>(ublas_v1.size(), gpu_result);
161  vcl_v1 = viennacl::scalar_vector<NumericT>(vcl_v1.size(), gpu_result);
162  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
163  return EXIT_FAILURE;
164 
165  std::cout << "Checking for unit_vector initializer..." << std::endl;
166  ublas_v1 = ublas::unit_vector<NumericT>(ublas_v1.size(), 5);
167  vcl_v1 = viennacl::unit_vector<NumericT>(vcl_v1.size(), 5);
168  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
169  return EXIT_FAILURE;
170 
171 
172  for (std::size_t i=0; i<ublas_v1.size(); ++i)
173  {
174  ublas_v1[i] = NumericT(1.0) + random<NumericT>();
175  ublas_v2[i] = NumericT(1.0) + random<NumericT>();
176  }
177 
178  viennacl::copy(ublas_v1.begin(), ublas_v1.end(), vcl_v1.begin()); //resync
179  viennacl::copy(ublas_v2.begin(), ublas_v2.end(), vcl_v2.begin());
180 
181  std::cout << "Checking for successful copy..." << std::endl;
182  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
183  return EXIT_FAILURE;
184  if (check(ublas_v2, vcl_v2, epsilon) != EXIT_SUCCESS)
185  return EXIT_FAILURE;
186 
187 
188  // --------------------------------------------------------------------------
189 
190  std::cout << "Testing simple assignments..." << std::endl;
191 
192  {
193  ublas_v1 = ublas_v2;
194  viennacl::scheduler::statement my_statement(vcl_v1, viennacl::op_assign(), vcl_v2); // same as vcl_v1 = vcl_v2;
195  viennacl::scheduler::execute(my_statement);
196 
197  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
198  return EXIT_FAILURE;
199  }
200 
201  {
202  ublas_v1 += ublas_v2;
203  viennacl::scheduler::statement my_statement(vcl_v1, viennacl::op_inplace_add(), vcl_v2); // same as vcl_v1 += vcl_v2;
204  viennacl::scheduler::execute(my_statement);
205 
206  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
207  return EXIT_FAILURE;
208  }
209 
210  {
211  ublas_v1 -= ublas_v2;
212  viennacl::scheduler::statement my_statement(vcl_v1, viennacl::op_inplace_sub(), vcl_v2); // same as vcl_v1 -= vcl_v2;
213  viennacl::scheduler::execute(my_statement);
214 
215  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
216  return EXIT_FAILURE;
217  }
218 
219  std::cout << "Testing composite assignments..." << std::endl;
220  {
221  ublas_v1 = ublas_v1 + ublas_v2;
222  viennacl::scheduler::statement my_statement(vcl_v1, viennacl::op_assign(), vcl_v1 + vcl_v2); // same as vcl_v1 = vcl_v1 + vcl_v2;
223  viennacl::scheduler::execute(my_statement);
224 
225  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
226  return EXIT_FAILURE;
227  }
228  {
229  ublas_v1 += alpha * ublas_v1 - beta * ublas_v2 + ublas_v1 / beta - ublas_v2 / alpha;
230  viennacl::scheduler::statement my_statement(vcl_v1, viennacl::op_inplace_add(), alpha * vcl_v1 - beta * vcl_v2 + vcl_v1 / beta - vcl_v2 / alpha); // same as vcl_v1 += alpha * vcl_v1 - beta * vcl_v2 + beta * vcl_v1 - alpha * vcl_v2;
231  viennacl::scheduler::execute(my_statement);
232 
233  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
234  return EXIT_FAILURE;
235  }
236 
237  {
238  ublas_v1 = ublas_v1 - ublas_v2;
239  viennacl::scheduler::statement my_statement(vcl_v1, viennacl::op_assign(), vcl_v1 - vcl_v2); // same as vcl_v1 = vcl_v1 - vcl_v2;
240  viennacl::scheduler::execute(my_statement);
241 
242  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
243  return EXIT_FAILURE;
244  }
245 
246  std::cout << "--- Testing reductions ---" << std::endl;
247  std::cout << "inner_prod..." << std::endl;
248  {
249  cpu_result = inner_prod(ublas_v1, ublas_v2);
250  viennacl::scheduler::statement my_statement(gpu_result, viennacl::op_assign(), viennacl::linalg::inner_prod(vcl_v1, vcl_v2)); // same as gpu_result = inner_prod(vcl_v1, vcl_v2);
251  viennacl::scheduler::execute(my_statement);
252 
253  if (check(cpu_result, gpu_result, epsilon) != EXIT_SUCCESS)
254  return EXIT_FAILURE;
255  }
256 
257  {
258  cpu_result = inner_prod(ublas_v1 + ublas_v2, ublas_v2);
259  viennacl::scheduler::statement my_statement(gpu_result, viennacl::op_assign(), viennacl::linalg::inner_prod(vcl_v1 + vcl_v2, vcl_v2)); // same as gpu_result = inner_prod(vcl_v1 + vcl_v2, vcl_v2);
260  viennacl::scheduler::execute(my_statement);
261 
262  if (check(cpu_result, gpu_result, epsilon) != EXIT_SUCCESS)
263  return EXIT_FAILURE;
264  }
265 
266  {
267  cpu_result = inner_prod(ublas_v1, ublas_v2 - ublas_v1);
268  viennacl::scheduler::statement my_statement(gpu_result, viennacl::op_assign(), viennacl::linalg::inner_prod(vcl_v1, vcl_v2 - vcl_v1)); // same as gpu_result = inner_prod(vcl_v1, vcl_v2 - vcl_v1);
269  viennacl::scheduler::execute(my_statement);
270 
271  if (check(cpu_result, gpu_result, epsilon) != EXIT_SUCCESS)
272  return EXIT_FAILURE;
273  }
274 
275  {
276  cpu_result = inner_prod(ublas_v1 - ublas_v2, ublas_v2 + ublas_v1);
277  viennacl::scheduler::statement my_statement(gpu_result, viennacl::op_assign(), viennacl::linalg::inner_prod(vcl_v1 - vcl_v2, vcl_v2 + vcl_v1)); // same as gpu_result = inner_prod(vcl_v1 - vcl_v2, vcl_v2 + vcl_v1);
278  viennacl::scheduler::execute(my_statement);
279 
280  if (check(cpu_result, gpu_result, epsilon) != EXIT_SUCCESS)
281  return EXIT_FAILURE;
282  }
283 
284  std::cout << "norm_1..." << std::endl;
285  {
286  cpu_result = norm_1(ublas_v1);
287  viennacl::scheduler::statement my_statement(gpu_result, viennacl::op_assign(), viennacl::linalg::norm_1(vcl_v1)); // same as gpu_result = norm_1(vcl_v1);
288  viennacl::scheduler::execute(my_statement);
289 
290  if (check(cpu_result, gpu_result, epsilon) != EXIT_SUCCESS)
291  return EXIT_FAILURE;
292  }
293 
294  {
295  cpu_result = norm_1(ublas_v1 + ublas_v2);
296  viennacl::scheduler::statement my_statement(gpu_result, viennacl::op_assign(), viennacl::linalg::norm_1(vcl_v1 + vcl_v2)); // same as gpu_result = norm_1(vcl_v1 + vcl_v2);
297  viennacl::scheduler::execute(my_statement);
298 
299  if (check(cpu_result, gpu_result, epsilon) != EXIT_SUCCESS)
300  return EXIT_FAILURE;
301  }
302 
303  std::cout << "norm_2..." << std::endl;
304  {
305  cpu_result = norm_2(ublas_v1);
306  viennacl::scheduler::statement my_statement(gpu_result, viennacl::op_assign(), viennacl::linalg::norm_2(vcl_v1)); // same as gpu_result = norm_2(vcl_v1);
307  viennacl::scheduler::execute(my_statement);
308 
309  if (check(cpu_result, gpu_result, epsilon) != EXIT_SUCCESS)
310  return EXIT_FAILURE;
311  }
312 
313  {
314  cpu_result = norm_2(ublas_v1 + ublas_v2);
315  viennacl::scheduler::statement my_statement(gpu_result, viennacl::op_assign(), viennacl::linalg::norm_2(vcl_v1 + vcl_v2)); // same as gpu_result = norm_2(vcl_v1 + vcl_v2);
316  viennacl::scheduler::execute(my_statement);
317 
318  if (check(cpu_result, gpu_result, epsilon) != EXIT_SUCCESS)
319  return EXIT_FAILURE;
320  }
321 
322  std::cout << "norm_inf..." << std::endl;
323  {
324  cpu_result = norm_inf(ublas_v1);
325  viennacl::scheduler::statement my_statement(gpu_result, viennacl::op_assign(), viennacl::linalg::norm_inf(vcl_v1)); // same as gpu_result = norm_inf(vcl_v1);
326  viennacl::scheduler::execute(my_statement);
327 
328  if (check(cpu_result, gpu_result, epsilon) != EXIT_SUCCESS)
329  return EXIT_FAILURE;
330  }
331 
332  {
333  cpu_result = norm_inf(ublas_v1 - ublas_v2);
334  viennacl::scheduler::statement my_statement(gpu_result, viennacl::op_assign(), viennacl::linalg::norm_inf(vcl_v1 - vcl_v2)); // same as gpu_result = norm_inf(vcl_v1 - vcl_v2);
335  viennacl::scheduler::execute(my_statement);
336 
337  if (check(cpu_result, gpu_result, epsilon) != EXIT_SUCCESS)
338  return EXIT_FAILURE;
339  }
340 
341  std::cout << "--- Testing elementwise operations (binary) ---" << std::endl;
342  std::cout << "x = element_prod(x, y)... ";
343  {
344  ublas_v1 = element_prod(ublas_v1, ublas_v2);
346  viennacl::scheduler::execute(my_statement);
347 
348  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
349  return EXIT_FAILURE;
350  }
351 
352  std::cout << "x = element_prod(x + y, y)... ";
353  {
354  ublas_v1 = element_prod(ublas_v1 + ublas_v2, ublas_v2);
355  viennacl::scheduler::statement my_statement(vcl_v1, viennacl::op_assign(), viennacl::linalg::element_prod(vcl_v1 + vcl_v2, vcl_v2));
356  viennacl::scheduler::execute(my_statement);
357 
358  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
359  return EXIT_FAILURE;
360  }
361 
362  std::cout << "x = element_prod(x, x + y)... ";
363  {
364  ublas_v1 = element_prod(ublas_v1, ublas_v1 + ublas_v2);
365  viennacl::scheduler::statement my_statement(vcl_v1, viennacl::op_assign(), viennacl::linalg::element_prod(vcl_v1, vcl_v2 + vcl_v1));
366  viennacl::scheduler::execute(my_statement);
367 
368  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
369  return EXIT_FAILURE;
370  }
371 
372  std::cout << "x = element_prod(x - y, y + x)... ";
373  {
374  ublas_v1 = element_prod(ublas_v1 - ublas_v2, ublas_v2 + ublas_v1);
375  viennacl::scheduler::statement my_statement(vcl_v1, viennacl::op_assign(), viennacl::linalg::element_prod(vcl_v1 - vcl_v2, vcl_v2 + vcl_v1));
376  viennacl::scheduler::execute(my_statement);
377 
378  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
379  return EXIT_FAILURE;
380  }
381 
382 
383 
384  std::cout << "x = element_div(x, y)... ";
385  {
386  ublas_v1 = element_div(ublas_v1, ublas_v2);
388  viennacl::scheduler::execute(my_statement);
389 
390  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
391  return EXIT_FAILURE;
392  }
393 
394  std::cout << "x = element_div(x + y, y)... ";
395  {
396  ublas_v1 = element_div(ublas_v1 + ublas_v2, ublas_v2);
397  viennacl::scheduler::statement my_statement(vcl_v1, viennacl::op_assign(), viennacl::linalg::element_div(vcl_v1 + vcl_v2, vcl_v2));
398  viennacl::scheduler::execute(my_statement);
399 
400  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
401  return EXIT_FAILURE;
402  }
403 
404  std::cout << "x = element_div(x, x + y)... ";
405  {
406  ublas_v1 = element_div(ublas_v1, ublas_v1 + ublas_v2);
407  viennacl::scheduler::statement my_statement(vcl_v1, viennacl::op_assign(), viennacl::linalg::element_div(vcl_v1, vcl_v2 + vcl_v1));
408  viennacl::scheduler::execute(my_statement);
409 
410  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
411  return EXIT_FAILURE;
412  }
413 
414  std::cout << "x = element_div(x - y, y + x)... ";
415  {
416  ublas_v1 = element_div(ublas_v1 - ublas_v2, ublas_v2 + ublas_v1);
417  viennacl::scheduler::statement my_statement(vcl_v1, viennacl::op_assign(), viennacl::linalg::element_div(vcl_v1 - vcl_v2, vcl_v2 + vcl_v1));
418  viennacl::scheduler::execute(my_statement);
419 
420  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
421  return EXIT_FAILURE;
422  }
423 
424 
425  std::cout << "x = element_pow(x, y)... ";
426  {
427  for (std::size_t i=0; i<ublas_v1.size(); ++i)
428  {
429  ublas_v1[i] = NumericT(2.0) + random<NumericT>();
430  ublas_v2[i] = NumericT(1.0) + random<NumericT>();
431  }
432  viennacl::copy(ublas_v1, vcl_v1);
433  viennacl::copy(ublas_v2, vcl_v2);
434 
435  for (std::size_t i=0; i<ublas_v1.size(); ++i)
436  ublas_v1[i] = std::pow(ublas_v1[i], ublas_v2[i]);
437  viennacl::scheduler::statement my_statement(vcl_v1, viennacl::op_assign(), viennacl::linalg::element_pow(vcl_v1, vcl_v2));
438  viennacl::scheduler::execute(my_statement);
439 
440  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
441  return EXIT_FAILURE;
442  }
443 
444  std::cout << "x = element_pow(x + y, y)... ";
445  {
446  for (std::size_t i=0; i<ublas_v1.size(); ++i)
447  {
448  ublas_v1[i] = NumericT(2.0) + random<NumericT>();
449  ublas_v2[i] = NumericT(1.0) + random<NumericT>();
450  }
451  viennacl::copy(ublas_v1, vcl_v1);
452  viennacl::copy(ublas_v2, vcl_v2);
453 
454  for (std::size_t i=0; i<ublas_v1.size(); ++i)
455  ublas_v1[i] = std::pow(ublas_v1[i] + ublas_v2[i], ublas_v2[i]);
456  viennacl::scheduler::statement my_statement(vcl_v1, viennacl::op_assign(), viennacl::linalg::element_pow(vcl_v1 + vcl_v2, vcl_v2));
457  viennacl::scheduler::execute(my_statement);
458 
459  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
460  return EXIT_FAILURE;
461  }
462 
463  std::cout << "x = element_pow(x, x + y)... ";
464  {
465  for (std::size_t i=0; i<ublas_v1.size(); ++i)
466  {
467  ublas_v1[i] = NumericT(2.0) + random<NumericT>();
468  ublas_v2[i] = NumericT(1.0) + random<NumericT>();
469  }
470  viennacl::copy(ublas_v1, vcl_v1);
471  viennacl::copy(ublas_v2, vcl_v2);
472 
473  for (std::size_t i=0; i<ublas_v1.size(); ++i)
474  ublas_v1[i] = std::pow(ublas_v1[i], ublas_v1[i] + ublas_v2[i]);
475  viennacl::scheduler::statement my_statement(vcl_v1, viennacl::op_assign(), viennacl::linalg::element_pow(vcl_v1, vcl_v2 + vcl_v1));
476  viennacl::scheduler::execute(my_statement);
477 
478  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
479  return EXIT_FAILURE;
480  }
481 
482  std::cout << "x = element_pow(x - y, y + x)... ";
483  {
484  for (std::size_t i=0; i<ublas_v1.size(); ++i)
485  {
486  ublas_v1[i] = NumericT(2.0) + random<NumericT>();
487  ublas_v2[i] = NumericT(1.0) + random<NumericT>();
488  }
489  viennacl::copy(ublas_v1, vcl_v1);
490  viennacl::copy(ublas_v2, vcl_v2);
491 
492  for (std::size_t i=0; i<ublas_v1.size(); ++i)
493  ublas_v1[i] = std::pow(ublas_v1[i] - ublas_v2[i], ublas_v2[i] + ublas_v1[i]);
494  viennacl::scheduler::statement my_statement(vcl_v1, viennacl::op_assign(), viennacl::linalg::element_pow(vcl_v1 - vcl_v2, vcl_v2 + vcl_v1));
495  viennacl::scheduler::execute(my_statement);
496 
497  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
498  return EXIT_FAILURE;
499  }
500 
501  std::cout << "--- Testing elementwise operations (unary) ---" << std::endl;
502 #define GENERATE_UNARY_OP_TEST(OPNAME) \
503  ublas_v1 = ublas::scalar_vector<NumericT>(ublas_v1.size(), NumericT(0.21)); \
504  ublas_v2 = NumericT(3.1415) * ublas_v1; \
505  viennacl::copy(ublas_v1.begin(), ublas_v1.end(), vcl_v1.begin()); \
506  viennacl::copy(ublas_v2.begin(), ublas_v2.end(), vcl_v2.begin()); \
507  { \
508  for (std::size_t i=0; i<ublas_v1.size(); ++i) \
509  ublas_v1[i] = std::OPNAME(ublas_v2[i]); \
510  viennacl::scheduler::statement my_statement(vcl_v1, viennacl::op_assign(), viennacl::linalg::element_##OPNAME(vcl_v2)); \
511  viennacl::scheduler::execute(my_statement); \
512  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS) \
513  return EXIT_FAILURE; \
514  } \
515  { \
516  for (std::size_t i=0; i<ublas_v1.size(); ++i) \
517  ublas_v1[i] = std::OPNAME(ublas_v2[i] / NumericT(2)); \
518  viennacl::scheduler::statement my_statement(vcl_v1, viennacl::op_assign(), viennacl::linalg::element_##OPNAME(vcl_v2 / NumericT(2))); \
519  viennacl::scheduler::execute(my_statement); \
520  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS) \
521  return EXIT_FAILURE; \
522  }
523 
527  GENERATE_UNARY_OP_TEST(floor);
530  GENERATE_UNARY_OP_TEST(log10);
534  //GENERATE_UNARY_OP_TEST(abs); //OpenCL allows abs on integers only
538 
539 #undef GENERATE_UNARY_OP_TEST
540 
541  std::cout << "--- Testing complicated composite operations ---" << std::endl;
542  std::cout << "x = inner_prod(x, y) * y..." << std::endl;
543  {
544  ublas_v1 = inner_prod(ublas_v1, ublas_v2) * ublas_v2;
545  viennacl::scheduler::statement my_statement(vcl_v1, viennacl::op_assign(), viennacl::linalg::inner_prod(vcl_v1, vcl_v2) * vcl_v2);
546  viennacl::scheduler::execute(my_statement);
547 
548  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
549  return EXIT_FAILURE;
550  }
551 
552  std::cout << "x = y / norm_1(x)..." << std::endl;
553  {
554  ublas_v1 = ublas_v2 / norm_1(ublas_v1);
555  viennacl::scheduler::statement my_statement(vcl_v1, viennacl::op_assign(), vcl_v2 / viennacl::linalg::norm_1(vcl_v1) );
556  viennacl::scheduler::execute(my_statement);
557 
558  if (check(ublas_v1, vcl_v1, epsilon) != EXIT_SUCCESS)
559  return EXIT_FAILURE;
560  }
561 
562 
563  // --------------------------------------------------------------------------
564  return retval;
565 }
566 
567 
568 template< typename NumericT, typename Epsilon >
569 int test(Epsilon const& epsilon)
570 {
571  int retval = EXIT_SUCCESS;
572  std::size_t size = 24656;
573 
574  std::cout << "Running tests for vector of size " << size << std::endl;
575 
576  //
577  // Set up UBLAS objects
578  //
579  ublas::vector<NumericT> ublas_full_vec(size);
580  ublas::vector<NumericT> ublas_full_vec2(ublas_full_vec.size());
581 
582  for (std::size_t i=0; i<ublas_full_vec.size(); ++i)
583  {
584  ublas_full_vec[i] = NumericT(1.0) + random<NumericT>();
585  ublas_full_vec2[i] = NumericT(1.0) + random<NumericT>();
586  }
587 
588  ublas::range r1( ublas_full_vec.size() / 4, 2 * ublas_full_vec.size() / 4);
589  ublas::range r2(2 * ublas_full_vec2.size() / 4, 3 * ublas_full_vec2.size() / 4);
590  ublas::vector_range< ublas::vector<NumericT> > ublas_range_vec(ublas_full_vec, r1);
591  ublas::vector_range< ublas::vector<NumericT> > ublas_range_vec2(ublas_full_vec2, r2);
592 
593  ublas::slice s1( ublas_full_vec.size() / 4, 3, ublas_full_vec.size() / 4);
594  ublas::slice s2(2 * ublas_full_vec2.size() / 4, 2, ublas_full_vec2.size() / 4);
595  ublas::vector_slice< ublas::vector<NumericT> > ublas_slice_vec(ublas_full_vec, s1);
596  ublas::vector_slice< ublas::vector<NumericT> > ublas_slice_vec2(ublas_full_vec2, s2);
597 
598  //
599  // Set up ViennaCL objects
600  //
601  viennacl::vector<NumericT> vcl_full_vec(ublas_full_vec.size());
602  viennacl::vector<NumericT> vcl_full_vec2(ublas_full_vec2.size());
603 
604  viennacl::fast_copy(ublas_full_vec.begin(), ublas_full_vec.end(), vcl_full_vec.begin());
605  viennacl::copy(ublas_full_vec2.begin(), ublas_full_vec2.end(), vcl_full_vec2.begin());
606 
607  viennacl::range vcl_r1( vcl_full_vec.size() / 4, 2 * vcl_full_vec.size() / 4);
608  viennacl::range vcl_r2(2 * vcl_full_vec2.size() / 4, 3 * vcl_full_vec2.size() / 4);
609  viennacl::vector_range< viennacl::vector<NumericT> > vcl_range_vec(vcl_full_vec, vcl_r1);
610  viennacl::vector_range< viennacl::vector<NumericT> > vcl_range_vec2(vcl_full_vec2, vcl_r2);
611 
612  {
613  viennacl::vector<NumericT> vcl_short_vec(vcl_range_vec);
614  viennacl::vector<NumericT> vcl_short_vec2 = vcl_range_vec2;
615 
616  ublas::vector<NumericT> ublas_short_vec(ublas_range_vec);
617  ublas::vector<NumericT> ublas_short_vec2(ublas_range_vec2);
618 
619  std::cout << "Testing creation of vectors from range..." << std::endl;
620  if (check(ublas_short_vec, vcl_short_vec, epsilon) != EXIT_SUCCESS)
621  return EXIT_FAILURE;
622  if (check(ublas_short_vec2, vcl_short_vec2, epsilon) != EXIT_SUCCESS)
623  return EXIT_FAILURE;
624  }
625 
626  viennacl::slice vcl_s1( vcl_full_vec.size() / 4, 3, vcl_full_vec.size() / 4);
627  viennacl::slice vcl_s2(2 * vcl_full_vec2.size() / 4, 2, vcl_full_vec2.size() / 4);
628  viennacl::vector_slice< viennacl::vector<NumericT> > vcl_slice_vec(vcl_full_vec, vcl_s1);
629  viennacl::vector_slice< viennacl::vector<NumericT> > vcl_slice_vec2(vcl_full_vec2, vcl_s2);
630 
631  viennacl::vector<NumericT> vcl_short_vec(vcl_slice_vec);
632  viennacl::vector<NumericT> vcl_short_vec2 = vcl_slice_vec2;
633 
634  ublas::vector<NumericT> ublas_short_vec(ublas_slice_vec);
635  ublas::vector<NumericT> ublas_short_vec2(ublas_slice_vec2);
636 
637  std::cout << "Testing creation of vectors from slice..." << std::endl;
638  if (check(ublas_short_vec, vcl_short_vec, epsilon) != EXIT_SUCCESS)
639  return EXIT_FAILURE;
640  if (check(ublas_short_vec2, vcl_short_vec2, epsilon) != EXIT_SUCCESS)
641  return EXIT_FAILURE;
642 
643 
644  //
645  // Now start running tests for vectors, ranges and slices:
646  //
647 
648  std::cout << " ** vcl_v1 = vector, vcl_v2 = vector **" << std::endl;
649  retval = test<NumericT>(epsilon,
650  ublas_short_vec, ublas_short_vec2,
651  vcl_short_vec, vcl_short_vec2);
652  if (retval != EXIT_SUCCESS)
653  return EXIT_FAILURE;
654 
655  std::cout << " ** vcl_v1 = vector, vcl_v2 = range **" << std::endl;
656  retval = test<NumericT>(epsilon,
657  ublas_short_vec, ublas_short_vec2,
658  vcl_short_vec, vcl_range_vec2);
659  if (retval != EXIT_SUCCESS)
660  return EXIT_FAILURE;
661 
662  std::cout << " ** vcl_v1 = vector, vcl_v2 = slice **" << std::endl;
663  retval = test<NumericT>(epsilon,
664  ublas_short_vec, ublas_short_vec2,
665  vcl_short_vec, vcl_slice_vec2);
666  if (retval != EXIT_SUCCESS)
667  return EXIT_FAILURE;
668 
670 
671  std::cout << " ** vcl_v1 = range, vcl_v2 = vector **" << std::endl;
672  retval = test<NumericT>(epsilon,
673  ublas_short_vec, ublas_short_vec2,
674  vcl_range_vec, vcl_short_vec2);
675  if (retval != EXIT_SUCCESS)
676  return EXIT_FAILURE;
677 
678  std::cout << " ** vcl_v1 = range, vcl_v2 = range **" << std::endl;
679  retval = test<NumericT>(epsilon,
680  ublas_short_vec, ublas_short_vec2,
681  vcl_range_vec, vcl_range_vec2);
682  if (retval != EXIT_SUCCESS)
683  return EXIT_FAILURE;
684 
685  std::cout << " ** vcl_v1 = range, vcl_v2 = slice **" << std::endl;
686  retval = test<NumericT>(epsilon,
687  ublas_short_vec, ublas_short_vec2,
688  vcl_range_vec, vcl_slice_vec2);
689  if (retval != EXIT_SUCCESS)
690  return EXIT_FAILURE;
691 
693 
694  std::cout << " ** vcl_v1 = slice, vcl_v2 = vector **" << std::endl;
695  retval = test<NumericT>(epsilon,
696  ublas_short_vec, ublas_short_vec2,
697  vcl_slice_vec, vcl_short_vec2);
698  if (retval != EXIT_SUCCESS)
699  return EXIT_FAILURE;
700 
701  std::cout << " ** vcl_v1 = slice, vcl_v2 = range **" << std::endl;
702  retval = test<NumericT>(epsilon,
703  ublas_short_vec, ublas_short_vec2,
704  vcl_slice_vec, vcl_range_vec2);
705  if (retval != EXIT_SUCCESS)
706  return EXIT_FAILURE;
707 
708  std::cout << " ** vcl_v1 = slice, vcl_v2 = slice **" << std::endl;
709  retval = test<NumericT>(epsilon,
710  ublas_short_vec, ublas_short_vec2,
711  vcl_slice_vec, vcl_slice_vec2);
712  if (retval != EXIT_SUCCESS)
713  return EXIT_FAILURE;
714 
715  return EXIT_SUCCESS;
716 }
717 
718 
719 
720 //
721 // -------------------------------------------------------------
722 //
723 int main()
724 {
725  std::cout << std::endl;
726  std::cout << "----------------------------------------------" << std::endl;
727  std::cout << "----------------------------------------------" << std::endl;
728  std::cout << "## Test :: Vector" << std::endl;
729  std::cout << "----------------------------------------------" << std::endl;
730  std::cout << "----------------------------------------------" << std::endl;
731  std::cout << std::endl;
732 
733  int retval = EXIT_SUCCESS;
734 
735  std::cout << std::endl;
736  std::cout << "----------------------------------------------" << std::endl;
737  std::cout << std::endl;
738  {
739  typedef float NumericT;
740  NumericT epsilon = static_cast<NumericT>(1.0E-4);
741  std::cout << "# Testing setup:" << std::endl;
742  std::cout << " eps: " << epsilon << std::endl;
743  std::cout << " numeric: float" << std::endl;
744  retval = test<NumericT>(epsilon);
745  if ( retval == EXIT_SUCCESS )
746  std::cout << "# Test passed" << std::endl;
747  else
748  return retval;
749  }
750  std::cout << std::endl;
751  std::cout << "----------------------------------------------" << std::endl;
752  std::cout << std::endl;
753 #ifdef VIENNACL_WITH_OPENCL
755 #endif
756  {
757  {
758  typedef double NumericT;
759  NumericT epsilon = 1.0E-12;
760  std::cout << "# Testing setup:" << std::endl;
761  std::cout << " eps: " << epsilon << std::endl;
762  std::cout << " numeric: double" << std::endl;
763  retval = test<NumericT>(epsilon);
764  if ( retval == EXIT_SUCCESS )
765  std::cout << "# Test passed" << std::endl;
766  else
767  return retval;
768  }
769  std::cout << std::endl;
770  std::cout << "----------------------------------------------" << std::endl;
771  std::cout << std::endl;
772  }
773 
774  std::cout << std::endl;
775  std::cout << "------- Test completed --------" << std::endl;
776  std::cout << std::endl;
777 
778 
779  return retval;
780 }
viennacl::vector_expression< const vector_base< T >, const vector_base< T >, op_element_binary< op_div > > element_div(vector_base< T > const &v1, vector_base< T > const &v2)
T norm_2(std::vector< T, A > const &v1)
Definition: norm_2.hpp:86
This class represents a single scalar value on the GPU and behaves mostly like a built-in scalar type...
Definition: forwards.h:226
Generic interface for the l^2-norm. See viennacl/linalg/vector_operations.hpp for implementations...
int test(Epsilon const &epsilon, UblasVectorType &ublas_v1, UblasVectorType &ublas_v2, ViennaCLVectorType1 &vcl_v1, ViennaCLVectorType2 &vcl_v2)
Implementation of the dense matrix class.
Some helper routines for reading/writing/printing scheduler expressions.
A tag class representing assignment.
Definition: forwards.h:80
void finish()
Synchronizes the execution. finish() will only return after all compute kernels (CUDA, OpenCL) have completed.
Definition: memory.hpp:54
int check(T1 const &t1, T2 const &t2, double epsilon)
viennacl::enable_if< viennacl::is_stl< typename viennacl::traits::tag_of< VectorT1 >::type >::value, typename VectorT1::value_type >::type inner_prod(VectorT1 const &v1, VectorT2 const &v2)
Definition: inner_prod.hpp:89
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
Generic interface for the computation of inner products. See viennacl/linalg/vector_operations.hpp for implementations.
int main()
A tag class representing inplace addition.
Definition: forwards.h:82
Generic interface for the l^1-norm. See viennacl/linalg/vector_operations.hpp for implementations...
basic_range range
Definition: forwards.h:423
viennacl::vector< float > v1
vcl_size_t size(VectorType const &vec)
Generic routine for obtaining the size of a vector (ViennaCL, uBLAS, etc.)
Definition: size.hpp:144
Class for representing non-strided subvectors of a bigger vector x.
Definition: forwards.h:433
Class for representing strided subvectors of a bigger vector x.
Definition: forwards.h:436
bool double_support() const
ViennaCL convenience function: Returns true if the device supports double precision.
Definition: device.hpp:956
#define GENERATE_UNARY_OP_TEST(OPNAME)
Proxy classes for vectors.
A tag class representing inplace subtraction.
Definition: forwards.h:84
Represents a vector consisting of 1 at a given index and zeros otherwise.
Definition: vector_def.hpp:76
basic_slice slice
Definition: forwards.h:428
The vector type with operator-overloads and proxy classes is defined here. Linear algebra operations ...
Represents a vector consisting of scalars 's' only, i.e. v[i] = s for all i. To be used as an initial...
Definition: vector_def.hpp:87
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) ...
T norm_1(std::vector< T, A > const &v1)
Definition: norm_1.hpp:61
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
ScalarType diff(ScalarType const &s1, ScalarType const &s2)
viennacl::vector_expression< const vector_base< T >, const vector_base< T >, op_element_binary< op_prod > > element_prod(vector_base< T > const &v1, vector_base< T > const &v2)
Provides the datastructures for dealing with a single statement such as 'x = y + z;'.
The main class for representing a statement such as x = inner_prod(y,z); at runtime.
Definition: forwards.h:504
A slice class that refers to an interval [start, stop), where 'start' is included, and 'stop' is excluded.
Definition: forwards.h:428
A proxy class for a single element of a vector or matrix. This proxy should not be noticed by end-use...
Definition: forwards.h:232
Generic interface for the l^infty-norm. See viennacl/linalg/vector_operations.hpp for implementations...
void fast_copy(const const_vector_iterator< SCALARTYPE, ALIGNMENT > &gpu_begin, const const_vector_iterator< SCALARTYPE, ALIGNMENT > &gpu_end, CPU_ITERATOR cpu_begin)