ViennaCL - The Vienna Computing Library  1.5.2
execute_axbx.hpp
Go to the documentation of this file.
1 #ifndef VIENNACL_SCHEDULER_EXECUTE_AXBX_HPP
2 #define VIENNACL_SCHEDULER_EXECUTE_AXBX_HPP
3 
4 /* =========================================================================
5  Copyright (c) 2010-2014, Institute for Microelectronics,
6  Institute for Analysis and Scientific Computing,
7  TU Wien.
8  Portions of this software are copyright by UChicago Argonne, LLC.
9 
10  -----------------
11  ViennaCL - The Vienna Computing Library
12  -----------------
13 
14  Project Head: Karl Rupp rupp@iue.tuwien.ac.at
15 
16  (A list of authors and contributors can be found in the PDF manual)
17 
18  License: MIT (X11), see file LICENSE in the base directory
19 ============================================================================= */
20 
21 
26 #include "viennacl/forwards.h"
28 
31 
32 namespace viennacl
33 {
34  namespace scheduler
35  {
36  namespace detail
37  {
39  inline void execute_axbx(statement const & s, statement_node const & root_node)
40  {
41  statement::container_type const & expr = s.array();
42 
43  statement_node const & leaf = expr[root_node.rhs.node_index];
44 
45  if (leaf.op.type == OPERATION_BINARY_ADD_TYPE || leaf.op.type == OPERATION_BINARY_SUB_TYPE) // x = (y) +- (z) where y and z are either data objects or expressions
46  {
47  bool flip_sign_z = (leaf.op.type == OPERATION_BINARY_SUB_TYPE);
48 
51  {
52  lhs_rhs_element u = root_node.lhs;
53  lhs_rhs_element v = leaf.lhs;
54  lhs_rhs_element w = leaf.rhs;
55  switch (root_node.op.type)
56  {
58  detail::axbx(u,
59  v, 1.0, 1, false, false,
60  w, 1.0, 1, false, flip_sign_z);
61  break;
64  v, 1.0, 1, false, false,
65  w, 1.0, 1, false, flip_sign_z);
66  break;
69  v, 1.0, 1, false, true,
70  w, 1.0, 1, false, !flip_sign_z);
71  break;
72  default:
73  throw statement_not_supported_exception("Unsupported binary operator for operation in root note (should be =, +=, or -=)");
74  }
75  }
77  && leaf.rhs.type_family != COMPOSITE_OPERATION_FAMILY) // x = (y) + z, y being a subtree itself, z being a scalar, vector, or matrix
78  {
79  statement_node const & y = expr[leaf.lhs.node_index];
80 
82  {
83  // y might be 'v * alpha' or 'v / alpha' with {scalar|vector|matrix} v
87  {
88  lhs_rhs_element u = root_node.lhs;
89  lhs_rhs_element v = y.lhs;
90  lhs_rhs_element w = leaf.rhs;
91  lhs_rhs_element alpha = y.rhs;
92 
94  switch (root_node.op.type)
95  {
97  detail::axbx(u,
98  v, alpha, 1, is_division, false,
99  w, 1.0, 1, false, flip_sign_z);
100  break;
102  detail::axbx_x(u,
103  v, alpha, 1, is_division, false,
104  w, 1.0, 1, false, flip_sign_z);
105  break;
107  detail::axbx_x(u,
108  v, alpha, 1, is_division, true,
109  w, 1.0, 1, false, !flip_sign_z);
110  break;
111  default:
112  throw statement_not_supported_exception("Unsupported binary operator for vector operation in root note (should be =, +=, or -=)");
113  }
114  }
115  else // no built-in kernel, we use a temporary.
116  {
117  statement_node new_root_y;
118 
119  detail::new_element(new_root_y.lhs, root_node.lhs);
120 
122  new_root_y.op.type = OPERATION_BINARY_ASSIGN_TYPE;
123 
125  new_root_y.rhs.subtype = INVALID_SUBTYPE;
127  new_root_y.rhs.node_index = leaf.lhs.node_index;
128 
129  // work on subexpression:
130  // TODO: Catch exception, free temporary, then rethrow
131  execute_composite(s, new_root_y);
132 
133  // now add:
134  lhs_rhs_element u = root_node.lhs;
135  lhs_rhs_element v = new_root_y.lhs;
136  lhs_rhs_element w = leaf.rhs;
137  switch (root_node.op.type)
138  {
140  detail::axbx(u,
141  v, 1.0, 1, false, false,
142  w, 1.0, 1, false, flip_sign_z);
143  break;
145  detail::axbx_x(u,
146  v, 1.0, 1, false, false,
147  w, 1.0, 1, false, flip_sign_z);
148  break;
150  detail::axbx_x(u,
151  v, 1.0, 1, false, true,
152  w, 1.0, 1, false, !flip_sign_z);
153  break;
154  default:
155  throw statement_not_supported_exception("Unsupported binary operator for vector operation in root note (should be =, +=, or -=)");
156  }
157 
158  detail::delete_element(new_root_y.lhs);
159  }
160  }
161  else
162  throw statement_not_supported_exception("Cannot deal with unary operations on vectors");
163 
164  }
165  else if ( leaf.lhs.type_family != COMPOSITE_OPERATION_FAMILY
166  && leaf.rhs.type_family == COMPOSITE_OPERATION_FAMILY) // x = y + (z), y being vector, z being a subtree itself
167  {
168  statement_node const & z = expr[leaf.rhs.node_index];
169 
171  {
172  // z might be 'v * alpha' or 'v / alpha' with vector v
176  {
177  lhs_rhs_element u = root_node.lhs;
178  lhs_rhs_element v = leaf.lhs;
179  lhs_rhs_element w = z.lhs;
180  lhs_rhs_element beta = z.rhs;
181 
183  switch (root_node.op.type)
184  {
186  detail::axbx(u,
187  v, 1.0, 1, false, false,
188  w, beta, 1, is_division, flip_sign_z);
189  break;
191  detail::axbx_x(u,
192  v, 1.0, 1, false, false,
193  w, beta, 1, is_division, flip_sign_z);
194  break;
196  detail::axbx_x(u,
197  v, 1.0, 1, false, true,
198  w, beta, 1, is_division, !flip_sign_z);
199  break;
200  default:
201  throw statement_not_supported_exception("Unsupported binary operator for vector operation in root note (should be =, +=, or -=)");
202  }
203  }
204  else // no built-in kernel, we use a temporary.
205  {
206  statement_node new_root_z;
207 
208  detail::new_element(new_root_z.lhs, root_node.lhs);
209 
211  new_root_z.op.type = OPERATION_BINARY_ASSIGN_TYPE;
212 
214  new_root_z.rhs.subtype = INVALID_SUBTYPE;
216  new_root_z.rhs.node_index = leaf.rhs.node_index;
217 
218  // work on subexpression:
219  // TODO: Catch exception, free temporary, then rethrow
220  execute_composite(s, new_root_z);
221 
222  // now add:
223  lhs_rhs_element u = root_node.lhs;
224  lhs_rhs_element v = leaf.lhs;
225  lhs_rhs_element w = new_root_z.lhs;
226  switch (root_node.op.type)
227  {
229  detail::axbx(u,
230  v, 1.0, 1, false, false,
231  w, 1.0, 1, false, flip_sign_z);
232  break;
234  detail::axbx_x(u,
235  v, 1.0, 1, false, false,
236  w, 1.0, 1, false, flip_sign_z);
237  break;
239  detail::axbx_x(u,
240  v, 1.0, 1, false, true,
241  w, 1.0, 1, false, !flip_sign_z);
242  break;
243  default:
244  throw statement_not_supported_exception("Unsupported binary operator for vector operation in root note (should be =, +=, or -=)");
245  }
246 
247  detail::delete_element(new_root_z.lhs);
248  }
249  }
250  else
251  throw statement_not_supported_exception("Cannot deal with unary operations on vectors");
252 
253  }
254  else if ( leaf.lhs.type_family == COMPOSITE_OPERATION_FAMILY
255  && leaf.rhs.type_family == COMPOSITE_OPERATION_FAMILY) // x = (y) + (z), y and z being subtrees
256  {
257  statement_node const & y = expr[leaf.lhs.node_index];
258  statement_node const & z = expr[leaf.rhs.node_index];
259 
262  {
263  // z might be 'v * alpha' or 'v / alpha' with vector v
270  {
271  lhs_rhs_element u = root_node.lhs;
272  lhs_rhs_element v = y.lhs;
273  lhs_rhs_element w = z.lhs;
274  lhs_rhs_element alpha = y.rhs;
275  lhs_rhs_element beta = z.rhs;
276 
277  bool is_division_y = (y.op.type == OPERATION_BINARY_DIV_TYPE);
278  bool is_division_z = (z.op.type == OPERATION_BINARY_DIV_TYPE);
279  switch (root_node.op.type)
280  {
282  detail::axbx(u,
283  v, alpha, 1, is_division_y, false,
284  w, beta, 1, is_division_z, flip_sign_z);
285  break;
287  detail::axbx_x(u,
288  v, alpha, 1, is_division_y, false,
289  w, beta, 1, is_division_z, flip_sign_z);
290  break;
292  detail::axbx_x(u,
293  v, alpha, 1, is_division_y, true,
294  w, beta, 1, is_division_z, !flip_sign_z);
295  break;
296  default:
297  throw statement_not_supported_exception("Unsupported binary operator for vector operation in root note (should be =, +=, or -=)");
298  }
299  }
300  else // no built-in kernel, we use a temporary.
301  {
302  statement_node new_root_y;
303 
304  detail::new_element(new_root_y.lhs, root_node.lhs);
305 
307  new_root_y.op.type = OPERATION_BINARY_ASSIGN_TYPE;
308 
310  new_root_y.rhs.subtype = INVALID_SUBTYPE;
312  new_root_y.rhs.node_index = leaf.lhs.node_index;
313 
314  // work on subexpression:
315  // TODO: Catch exception, free temporary, then rethrow
316  execute_composite(s, new_root_y);
317 
318  statement_node new_root_z;
319 
320  detail::new_element(new_root_z.lhs, root_node.lhs);
321 
323  new_root_z.op.type = OPERATION_BINARY_ASSIGN_TYPE;
324 
326  new_root_z.rhs.subtype = INVALID_SUBTYPE;
328  new_root_z.rhs.node_index = leaf.rhs.node_index;
329 
330  // work on subexpression:
331  // TODO: Catch exception, free temporaries, then rethrow
332  execute_composite(s, new_root_z);
333 
334  // now add:
335  lhs_rhs_element u = root_node.lhs;
336  lhs_rhs_element v = new_root_y.lhs;
337  lhs_rhs_element w = new_root_z.lhs;
338 
339  switch (root_node.op.type)
340  {
342  detail::axbx(u,
343  v, 1.0, 1, false, false,
344  w, 1.0, 1, false, flip_sign_z);
345  break;
347  detail::axbx_x(u,
348  v, 1.0, 1, false, false,
349  w, 1.0, 1, false, flip_sign_z);
350  break;
352  detail::axbx_x(u,
353  v, 1.0, 1, false, true,
354  w, 1.0, 1, false, !flip_sign_z);
355  break;
356  default:
357  throw statement_not_supported_exception("Unsupported binary operator for vector operation in root note (should be =, +=, or -=)");
358  }
359 
360  detail::delete_element(new_root_y.lhs);
361  detail::delete_element(new_root_z.lhs);
362  }
363  }
364  else
365  throw statement_not_supported_exception("Cannot deal with unary operations on vectors");
366  }
367  else
368  throw statement_not_supported_exception("Cannot deal with addition of vectors");
369  }
370  else
371  throw statement_not_supported_exception("Unsupported binary operator for vector operations");
372  }
373 
374  } // namespace detail
375  } // namespace scheduler
376 } // namespace viennacl
377 
378 #endif
379 
statement_node_subtype subtype
Definition: forwards.h:270
Definition: forwards.h:182
vcl_size_t node_index
Definition: forwards.h:276
void new_element(lhs_rhs_element &new_elem, lhs_rhs_element const &old_element)
Definition: execute_util.hpp:102
lhs_rhs_element lhs
Definition: forwards.h:422
This file provides the forward declarations for the main types used within ViennaCL.
A class representing the 'data' for the LHS or RHS operand of the respective node.
Definition: forwards.h:267
operation_node_type_family type_family
Definition: forwards.h:415
Provides unified wrappers for the common routines {as(), asbs(), asbs_s()}, {av(), avbv(), avbv_v()}, and {am(), ambm(), ambm_m()} such that scheduler logic is not cluttered with numeric type decutions.
lhs_rhs_element rhs
Definition: forwards.h:424
Deals with the execution of x = RHS; for a vector x and any compatible right hand side expression RHS...
void delete_element(lhs_rhs_element &elem)
Definition: execute_util.hpp:179
Definition: forwards.h:170
statement_node_numeric_type numeric_type
Definition: forwards.h:271
void axbx(lhs_rhs_element &x1, lhs_rhs_element const &x2, ScalarType1 const &alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha, lhs_rhs_element const &x3, ScalarType2 const &beta, vcl_size_t len_beta, bool reciprocal_beta, bool flip_sign_beta)
Wrapper for viennacl::linalg::avbv(), taking care of the argument unwrapping.
Definition: execute_generic_dispatcher.hpp:67
void execute_axbx(statement const &s, statement_node const &root_node)
Deals with x = (y) +- (z) where y and z are either data objects or expressions.
Definition: execute_axbx.hpp:39
Provides the datastructures for dealing with a single statement such as 'x = y + z;'.
std::vector< value_type > container_type
Definition: forwards.h:452
Helper metafunction for checking whether the provided type is viennacl::op_div (for division) ...
Definition: predicate.hpp:448
container_type const & array() const
Definition: forwards.h:473
void execute_composite(statement const &s, statement_node const &root_node)
Deals with x = RHS where RHS is an expression and x is either a scalar, a vector, or a matrix...
Definition: execute.hpp:41
statement_node_type_family type_family
Definition: forwards.h:269
The main class for representing a statement such as x = inner_prod(y,z); at runtime.
Definition: forwards.h:447
op_element op
Definition: forwards.h:423
void axbx_x(lhs_rhs_element &x1, lhs_rhs_element const &x2, ScalarType1 const &alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha, lhs_rhs_element const &x3, ScalarType2 const &beta, vcl_size_t len_beta, bool reciprocal_beta, bool flip_sign_beta)
Wrapper for viennacl::linalg::avbv_v(), taking care of the argument unwrapping.
Definition: execute_generic_dispatcher.hpp:99
Main datastructure for an node in the statement tree.
Definition: forwards.h:420
Exception for the case the scheduler is unable to deal with the operation.
Definition: forwards.h:36
operation_node_type type
Definition: forwards.h:416