ViennaCL - The Vienna Computing Library  1.5.2
execute.hpp
Go to the documentation of this file.
1 #ifndef VIENNACL_SCHEDULER_EXECUTE_HPP
2 #define VIENNACL_SCHEDULER_EXECUTE_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 
33 
34 namespace viennacl
35 {
36  namespace scheduler
37  {
38  namespace detail
39  {
41  void execute_composite(statement const & s, statement_node const & root_node)
42  {
43  statement::container_type const & expr = s.array();
44 
45  statement_node const & leaf = expr[root_node.rhs.node_index];
46 
47  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
48  {
49  execute_axbx(s, root_node);
50  }
51  else if (leaf.op.type == OPERATION_BINARY_MULT_TYPE || leaf.op.type == OPERATION_BINARY_DIV_TYPE) // x = (y) * / alpha;
52  {
53  bool scalar_is_temporary = (leaf.rhs.type_family != SCALAR_TYPE_FAMILY);
54 
55  statement_node scalar_temp_node;
56  if (scalar_is_temporary)
57  {
58  lhs_rhs_element temp;
61  temp.numeric_type = root_node.lhs.numeric_type;
62  detail::new_element(scalar_temp_node.lhs, temp);
63 
64  scalar_temp_node.op.type_family = OPERATION_BINARY_TYPE_FAMILY;
65  scalar_temp_node.op.type = OPERATION_BINARY_ASSIGN_TYPE;
66 
67  scalar_temp_node.rhs.type_family = COMPOSITE_OPERATION_FAMILY;
68  scalar_temp_node.rhs.subtype = INVALID_SUBTYPE;
69  scalar_temp_node.rhs.numeric_type = INVALID_NUMERIC_TYPE;
70  scalar_temp_node.rhs.node_index = leaf.rhs.node_index;
71 
72  // work on subexpression:
73  // TODO: Catch exception, free temporary, then rethrow
74  execute_composite(s, scalar_temp_node);
75  }
76 
77  if (leaf.lhs.type_family == COMPOSITE_OPERATION_FAMILY) //(y) is an expression, so introduce a temporary z = (y):
78  {
79  statement_node new_root_y;
80 
81  new_root_y.lhs.type_family = root_node.lhs.type_family;
82  new_root_y.lhs.subtype = root_node.lhs.subtype;
83  new_root_y.lhs.numeric_type = root_node.lhs.numeric_type;
84  detail::new_element(new_root_y.lhs, root_node.lhs);
85 
88 
90  new_root_y.rhs.subtype = INVALID_SUBTYPE;
92  new_root_y.rhs.node_index = leaf.lhs.node_index;
93 
94  // work on subexpression:
95  // TODO: Catch exception, free temporary, then rethrow
96  execute_composite(s, new_root_y);
97 
98  // now compute x = z * / alpha:
99  lhs_rhs_element u = root_node.lhs;
100  lhs_rhs_element v = new_root_y.lhs;
101  lhs_rhs_element alpha = scalar_is_temporary ? scalar_temp_node.lhs : leaf.rhs;
102 
103  bool is_division = (leaf.op.type == OPERATION_BINARY_DIV_TYPE);
104  switch (root_node.op.type)
105  {
107  detail::ax(u,
108  v, alpha, 1, is_division, false);
109  break;
111  detail::axbx(u,
112  u, 1.0, 1, false, false,
113  v, alpha, 1, is_division, false);
114  break;
116  detail::axbx(u,
117  u, 1.0, 1, false, false,
118  v, alpha, 1, is_division, true);
119  break;
120  default:
121  throw statement_not_supported_exception("Unsupported binary operator for vector operation in root note (should be =, +=, or -=)");
122  }
123 
124  detail::delete_element(new_root_y.lhs);
125  }
126  else if (leaf.lhs.type_family != COMPOSITE_OPERATION_FAMILY)
127  {
128  lhs_rhs_element u = root_node.lhs;
129  lhs_rhs_element v = leaf.lhs;
130  lhs_rhs_element alpha = scalar_is_temporary ? scalar_temp_node.lhs : leaf.rhs;
131 
132  bool is_division = (leaf.op.type == OPERATION_BINARY_DIV_TYPE);
133  switch (root_node.op.type)
134  {
136  detail::ax(u,
137  v, alpha, 1, is_division, false);
138  break;
140  detail::axbx(u,
141  u, 1.0, 1, false, false,
142  v, alpha, 1, is_division, false);
143  break;
145  detail::axbx(u,
146  u, 1.0, 1, false, false,
147  v, alpha, 1, is_division, true);
148  break;
149  default:
150  throw statement_not_supported_exception("Unsupported binary operator for vector operation in root note (should be =, +=, or -=)");
151  }
152  }
153  else
154  throw statement_not_supported_exception("Unsupported binary operator for OPERATION_BINARY_MULT_TYPE || OPERATION_BINARY_DIV_TYPE on leaf node.");
155 
156  // clean up
157  if (scalar_is_temporary)
158  detail::delete_element(scalar_temp_node.lhs);
159  }
160  else if ( leaf.op.type == OPERATION_BINARY_INNER_PROD_TYPE
164  {
165  execute_scalar_assign_composite(s, root_node);
166  }
169  || leaf.op.type == OPERATION_BINARY_ELEMENT_DIV_TYPE) // element-wise operations
170  {
171  execute_element_composite(s, root_node);
172  }
173  else if ( leaf.op.type == OPERATION_BINARY_MAT_VEC_PROD_TYPE
175  {
176  execute_matrix_prod(s, root_node);
177  }
178  else if ( leaf.op.type == OPERATION_UNARY_TRANS_TYPE)
179  {
180  assign_trans(root_node.lhs, leaf.lhs);
181  }
182  else
183  throw statement_not_supported_exception("Unsupported binary operator");
184  }
185 
186 
188  inline void execute_single(statement const &, statement_node const & root_node)
189  {
190  lhs_rhs_element u = root_node.lhs;
191  lhs_rhs_element v = root_node.rhs;
192  switch (root_node.op.type)
193  {
195  detail::ax(u,
196  v, 1.0, 1, false, false);
197  break;
199  detail::axbx(u,
200  u, 1.0, 1, false, false,
201  v, 1.0, 1, false, false);
202  break;
204  detail::axbx(u,
205  u, 1.0, 1, false, false,
206  v, 1.0, 1, false, true);
207  break;
208  default:
209  throw statement_not_supported_exception("Unsupported binary operator for operation in root note (should be =, +=, or -=)");
210  }
211 
212  }
213 
214 
215  inline void execute_impl(statement const & s, statement_node const & root_node)
216  {
217  if ( root_node.lhs.type_family != SCALAR_TYPE_FAMILY
218  && root_node.lhs.type_family != VECTOR_TYPE_FAMILY
219  && root_node.lhs.type_family != MATRIX_TYPE_FAMILY)
220  throw statement_not_supported_exception("Unsupported lvalue encountered in head node.");
221 
222  switch (root_node.rhs.type_family)
223  {
225  execute_composite(s, root_node);
226  break;
227  case SCALAR_TYPE_FAMILY:
228  case VECTOR_TYPE_FAMILY:
229  case MATRIX_TYPE_FAMILY:
230  execute_single(s, root_node);
231  break;
232  default:
233  throw statement_not_supported_exception("Invalid rvalue encountered in vector assignment");
234  }
235 
236  }
237  }
238 
239  inline void execute(statement const & s)
240  {
241  // simply start execution from the root node:
242  detail::execute_impl(s, s.array()[s.root()]);
243  }
244 
245 
246  }
247 
248 } //namespace viennacl
249 
250 #endif
251 
statement_node_subtype subtype
Definition: forwards.h:270
Deals with the execution of unary and binary element-wise operations.
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
void execute_matrix_prod(statement const &s, statement_node const &root_node)
Definition: execute_matrix_prod.hpp:393
lhs_rhs_element lhs
Definition: forwards.h:422
void assign_trans(lhs_rhs_element const &A, lhs_rhs_element const &B)
Scheduler unwrapper for A = trans(B)
Definition: execute_matrix_dispatcher.hpp:205
Definition: forwards.h:176
Deals with matrix-vector and matrix-matrix products.
Definition: forwards.h:185
void execute_scalar_assign_composite(statement const &s, statement_node const &root_node)
Deals with x = RHS where RHS is a vector expression.
Definition: execute_scalar_assign.hpp:35
This file provides the forward declarations for the main types used within ViennaCL.
void execute(statement const &s)
Definition: execute.hpp:239
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
void execute_element_composite(statement const &s, statement_node const &root_node)
Deals with x = RHS where RHS is a vector expression.
Definition: execute_elementwise.hpp:390
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
Main namespace in ViennaCL. Holds all the basic types such as vector, matrix, etc. and defines operations upon them.
Definition: cpu_ram.hpp:29
void execute_single(statement const &, statement_node const &root_node)
Deals with x = y for a scalar/vector/matrix x, y.
Definition: execute.hpp:188
Definition: forwards.h:170
void execute_impl(statement const &s, statement_node const &root_node)
Definition: execute.hpp:215
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
size_type root() const
Definition: forwards.h:475
Definition: forwards.h:173
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
void ax(lhs_rhs_element &x1, lhs_rhs_element const &x2, ScalarType1 const &alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha)
Wrapper for viennacl::linalg::av(), taking care of the argument unwrapping.
Definition: execute_generic_dispatcher.hpp:44
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
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
Provides the datastructures for dealing with statements of the type x = (y) +- (z) ...
operation_node_type type
Definition: forwards.h:416