ViennaCL - The Vienna Computing Library  1.5.2
helpers.hpp
Go to the documentation of this file.
1 #ifndef VIENNACL_GENERATOR_GENERATE_UTILS_HPP
2 #define VIENNACL_GENERATOR_GENERATE_UTILS_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 <set>
27 
28 #ifdef __APPLE__
29 #include <OpenCL/cl.h>
30 #else
31 #include "CL/cl.h"
32 #endif
33 
34 #include "viennacl/forwards.h"
36 
39 
40 namespace viennacl{
41 
42  namespace generator{
43 
44  namespace detail{
45 
47  static std::string generate_value_kernel_argument(std::string const & scalartype, std::string const & name){
48  return scalartype + ' ' + name + ",";
49  }
50 
52  static std::string generate_pointer_kernel_argument(std::string const & address_space, std::string const & scalartype, std::string const & name){
53  return address_space + " " + scalartype + "* " + name + ",";
54  }
55 
58  // unary expression
59  switch(type){
73  default : throw "not implemented";
74  }
75  }
76 
82  }
83 
93 // ||op_type == viennacl::scheduler::OPERATION_BINARY_INPLACE_DIV_TYPE
94 // ||op_type == viennacl::scheduler::OPERATION_BINARY_INPLACE_MULT_TYPE
97 
98  }
99 
101  template<class Fun>
102  static void traverse(viennacl::scheduler::statement const & statement, viennacl::scheduler::statement_node const & root_node, Fun const & fun, bool recurse_binary_leaf /* see forwards.h for default argument */){
103 
105  {
106  //Self:
107  fun(&statement, &root_node, PARENT_NODE_TYPE);
108 
109  //Lhs:
110  fun.call_before_expansion();
112  traverse(statement, statement.array()[root_node.lhs.node_index], fun, recurse_binary_leaf);
113  fun(&statement, &root_node, LHS_NODE_TYPE);
114  fun.call_after_expansion();
115  }
117  {
118  bool deep_recursion = recurse_binary_leaf || !is_binary_leaf_operator(root_node.op.type);
119 
120  fun.call_before_expansion();
121 
122  //Lhs:
123  if(deep_recursion){
125  traverse(statement, statement.array()[root_node.lhs.node_index], fun, recurse_binary_leaf);
126  fun(&statement, &root_node, LHS_NODE_TYPE);
127  }
128 
129  //Self:
130  fun(&statement, &root_node, PARENT_NODE_TYPE);
131 
132  //Rhs:
133  if(deep_recursion){
135  traverse(statement, statement.array()[root_node.rhs.node_index], fun, recurse_binary_leaf);
136  fun(&statement, &root_node, RHS_NODE_TYPE);
137  }
138 
139  fun.call_after_expansion();
140 
141  }
142  }
143 
146  public:
147  void call_before_expansion() const { }
148  void call_after_expansion() const { }
149  };
150 
153  private:
154  std::set<std::string> & already_generated_;
155  std::string & str_;
156  unsigned int vector_size_;
157  mapping_type const & mapping_;
158  public:
159  prototype_generation_traversal(std::set<std::string> & already_generated, std::string & str, unsigned int vector_size, mapping_type const & mapping) : already_generated_(already_generated), str_(str), vector_size_(vector_size), mapping_(mapping){ }
160 
164  append_kernel_arguments(already_generated_, str_, vector_size_, *at(mapping_, std::make_pair(root_node,node_type)));
165  }
166  };
167 
170  private:
171  std::set<std::string> & fetched_;
172  std::pair<std::string, std::string> index_string_;
173  unsigned int vectorization_;
175  mapping_type const & mapping_;
176  public:
177  fetch_traversal(std::set<std::string> & fetched, std::pair<std::string, std::string> const & index, unsigned int vectorization, utils::kernel_generation_stream & stream, mapping_type const & mapping) : fetched_(fetched), index_string_(index), vectorization_(vectorization), stream_(stream), mapping_(mapping){ }
178 
182  fetch(index_string_, vectorization_, fetched_, stream_, *at(mapping_, std::make_pair(root_node, node_type)));
183  }
184  };
185 
190  static void fetch_all_lhs(std::set<std::string> & fetched
191  , viennacl::scheduler::statement const & statement
192  , viennacl::scheduler::statement_node const & root_node
193  , std::pair<std::string, std::string> const & index
194  , vcl_size_t const & vectorization
196  , detail::mapping_type const & mapping){
198  detail::traverse(statement, statement.array()[root_node.lhs.node_index], detail::fetch_traversal(fetched, index, static_cast<unsigned int>(vectorization), stream, mapping));
199  else
200  detail::fetch(index, static_cast<unsigned int>(vectorization),fetched, stream, *at(mapping, std::make_pair(&root_node,detail::LHS_NODE_TYPE)));
201 
202  }
203 
208  static void fetch_all_rhs(std::set<std::string> & fetched
209  , viennacl::scheduler::statement const & statement
210  , viennacl::scheduler::statement_node const & root_node
211  , std::pair<std::string, std::string> const & index
212  , vcl_size_t const & vectorization
213  , utils::kernel_generation_stream & stream
214  , detail::mapping_type const & mapping){
216  detail::traverse(statement, statement.array()[root_node.rhs.node_index], detail::fetch_traversal(fetched, index, static_cast<unsigned int>(vectorization), stream, mapping));
217  else
218  detail::fetch(index, static_cast<unsigned int>(vectorization),fetched, stream, *at(mapping, std::make_pair(&root_node,detail::RHS_NODE_TYPE)));
219 
220  }
221 
222 
225  private:
226  std::pair<std::string, std::string> index_string_;
227  int vector_element_;
228  std::string & str_;
229  mapping_type const & mapping_;
230 
231  public:
232  expression_generation_traversal(std::pair<std::string, std::string> const & index, int vector_element, std::string & str, mapping_type const & mapping) : index_string_(index), vector_element_(vector_element), str_(str), mapping_(mapping){ }
233 
234  void call_before_expansion() const { str_+="("; }
235  void call_after_expansion() const { str_+=")"; }
236 
238  if(node_type==PARENT_NODE_TYPE)
239  {
240  if(is_binary_leaf_operator(root_node->op.type))
241  str_ += generate(index_string_, vector_element_, *at(mapping_, std::make_pair(root_node, node_type)));
242  else if(is_arithmetic_operator(root_node->op.type))
243  str_ += generate(root_node->op.type);
244  }
245  else{
246  if(node_type==LHS_NODE_TYPE){
248  str_ += detail::generate(index_string_,vector_element_, *at(mapping_, std::make_pair(root_node,node_type)));
249  }
250  else if(node_type==RHS_NODE_TYPE){
252  str_ += detail::generate(index_string_,vector_element_, *at(mapping_, std::make_pair(root_node,node_type)));
253  }
254  }
255  }
256  };
257 
258  static void generate_all_lhs(viennacl::scheduler::statement const & statement
259  , viennacl::scheduler::statement_node const & root_node
260  , std::pair<std::string, std::string> const & index
261  , int vector_element
262  , std::string & str
263  , detail::mapping_type const & mapping){
265  detail::traverse(statement, statement.array()[root_node.lhs.node_index], detail::expression_generation_traversal(index, vector_element, str, mapping));
266  else
267  str += detail::generate(index, vector_element,*at(mapping, std::make_pair(&root_node,detail::LHS_NODE_TYPE)));
268  }
269 
270 
271  static void generate_all_rhs(viennacl::scheduler::statement const & statement
272  , viennacl::scheduler::statement_node const & root_node
273  , std::pair<std::string, std::string> const & index
274  , int vector_element
275  , std::string & str
276  , detail::mapping_type const & mapping){
278  detail::traverse(statement, statement.array()[root_node.rhs.node_index], detail::expression_generation_traversal(index, vector_element, str, mapping));
279  else
280  str += detail::generate(index, vector_element,*at(mapping, std::make_pair(&root_node,detail::RHS_NODE_TYPE)));
281  }
282 
283  }
284  }
285 }
286 #endif
A stream class where the kernel sources are streamed to. Takes care of indentation of the sources...
Definition: utils.hpp:233
std::map< key_type, container_ptr_type > mapping_type
Definition: forwards.h:122
std::size_t vcl_size_t
Definition: forwards.h:58
void call_after_expansion() const
Definition: helpers.hpp:148
vcl_size_t node_index
Definition: forwards.h:276
Internal utils for a dynamic OpenCL kernel generation.
lhs_rhs_element lhs
Definition: forwards.h:422
expression_generation_traversal(std::pair< std::string, std::string > const &index, int vector_element, std::string &str, mapping_type const &mapping)
Definition: helpers.hpp:232
fetch_traversal(std::set< std::string > &fetched, std::pair< std::string, std::string > const &index, unsigned int vectorization, utils::kernel_generation_stream &stream, mapping_type const &mapping)
Definition: helpers.hpp:177
This file provides the forward declarations for the main types used within ViennaCL.
operation_node_type_family type_family
Definition: forwards.h:415
ValueT const & at(std::map< KeyT, ValueT > const &map, KeyT const &key)
Emulation of C++11's .at() member for std::map<>
Definition: forwards.h:97
lhs_rhs_element rhs
Definition: forwards.h:424
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 call_before_expansion() const
Definition: helpers.hpp:147
prototype_generation_traversal(std::set< std::string > &already_generated, std::string &str, unsigned int vector_size, mapping_type const &mapping)
Definition: helpers.hpp:159
void operator()(viennacl::scheduler::statement const *, viennacl::scheduler::statement_node const *root_node, detail::node_type node_type) const
Definition: helpers.hpp:237
void operator()(viennacl::scheduler::statement const *, viennacl::scheduler::statement_node const *root_node, detail::node_type node_type) const
Definition: helpers.hpp:179
functor for fetching the elements of a statement
Definition: helpers.hpp:169
base functor class for traversing a statement
Definition: helpers.hpp:145
functor for generating the prototype of a statement
Definition: helpers.hpp:152
Forwards declaration.
Provides the datastructures for dealing with a single statement such as 'x = y + z;'.
operation_node_type
Enumeration for identifying the possible operations.
Definition: forwards.h:61
node_type
Definition: forwards.h:112
container_type const & array() const
Definition: forwards.h:473
void operator()(viennacl::scheduler::statement const *, viennacl::scheduler::statement_node const *root_node, detail::node_type node_type) const
Definition: helpers.hpp:161
bool is_binary_leaf_operator(viennacl::scheduler::operation_node_type const &op_type)
checks whether an operator is both a binary node and a leaf
Definition: helpers.hpp:78
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
void call_after_expansion() const
Definition: helpers.hpp:235
std::string generate(std::pair< std::string, std::string > const &index, int vector_element, mapped_object const &s)
Definition: mapped_objects.hpp:325
void call_before_expansion() const
Definition: helpers.hpp:234
bool is_arithmetic_operator(viennacl::scheduler::operation_node_type const &op_type)
checks whether an operator is arithmetic or not
Definition: helpers.hpp:85
op_element op
Definition: forwards.h:423
functor for generating the expression string from a statement
Definition: helpers.hpp:224
Main datastructure for an node in the statement tree.
Definition: forwards.h:420
operation_node_type type
Definition: forwards.h:416