ViennaCL - The Vienna Computing Library  1.7.0
Free open-source GPU-accelerated linear algebra and solver library.
mapped_objects.hpp
Go to the documentation of this file.
1 #ifndef VIENNACL_DEVICE_SPECIFIC_MAPPED_TYPE_HPP
2 #define VIENNACL_DEVICE_SPECIFIC_MAPPED_TYPE_HPP
3 
4 /* =========================================================================
5  Copyright (c) 2010-2015, 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 manual)
17 
18  License: MIT (X11), see file LICENSE in the base directory
19 ============================================================================= */
20 
21 
26 #include <string>
27 
31 
32 namespace viennacl
33 {
34 
35 namespace device_specific
36 {
37 
44 {
45 private:
46  virtual void postprocess(std::string &) const { }
47 
48 protected:
49  struct MorphBase { virtual ~MorphBase(){} };
50  struct MorphBase1D : public MorphBase { public: virtual std::string operator()(std::string const & i) const = 0; };
51  struct MorphBase2D : public MorphBase { public: virtual std::string operator()(std::string const & i, std::string const & j) const = 0; };
52 
53  static void replace_offset(std::string & str, MorphBase const & morph)
54  {
55  vcl_size_t pos = 0;
56  while ((pos=str.find("$OFFSET", pos))!=std::string::npos)
57  {
58  std::string postprocessed;
59  vcl_size_t pos_po = str.find('{', pos);
60  vcl_size_t pos_pe = str.find('}', pos_po);
61 
62  if (MorphBase2D const * p2d = dynamic_cast<MorphBase2D const *>(&morph))
63  {
64  vcl_size_t pos_comma = str.find(',', pos_po);
65  std::string i = str.substr(pos_po + 1, pos_comma - pos_po - 1);
66  std::string j = str.substr(pos_comma + 1, pos_pe - pos_comma - 1);
67  postprocessed = (*p2d)(i, j);
68  }
69  else if (MorphBase1D const * p1d = dynamic_cast<MorphBase1D const *>(&morph))
70  {
71  std::string i = str.substr(pos_po + 1, pos_pe - pos_po - 1);
72  postprocessed = (*p1d)(i);
73  }
74 
75  str.replace(pos, pos_pe + 1 - pos, postprocessed);
76  pos = pos_pe;
77  }
78  }
79 
80  void register_attribute(std::string & attribute, std::string const & key, std::string const & value)
81  {
82  attribute = value;
83  keywords_[key] = attribute;
84  }
85 
86 public:
87  struct node_info
88  {
89  node_info(mapping_type const * _mapping, scheduler::statement const * _statement, vcl_size_t _root_idx) :
90  mapping(_mapping), statement(_statement), root_idx(_root_idx) { }
94  };
95 
96 public:
97  mapped_object(std::string const & scalartype, unsigned int id, std::string const & type_key) : type_key_(type_key)
98  {
99  register_attribute(scalartype_, "#scalartype", scalartype);
100  register_attribute(name_, "#name", "obj" + tools::to_string(id));
101  }
102 
103  virtual ~mapped_object(){ }
104 
105  virtual std::string & append_kernel_arguments(std::set<std::string> &, std::string & str, unsigned int) const { return str; }
106 
107  std::string type_key() const { return type_key_; }
108 
109  std::string const & name() const { return name_; }
110 
111  std::string process(std::string const & in) const
112  {
113  std::string res(in);
114  for (std::map<std::string,std::string>::const_iterator it = keywords_.begin(); it != keywords_.end(); ++it)
115  tools::find_and_replace(res, it->first, it->second);
116  postprocess(res);
117  return res;
118  }
119 
120  std::string evaluate(std::map<std::string, std::string> const & accessors) const
121  {
122  if (accessors.find(type_key_)==accessors.end())
123  return name_;
124  return process(at(accessors, type_key_));
125  }
126 
127 
128 protected:
129  std::string name_;
130  std::string scalartype_;
131  std::string type_key_;
132  std::map<std::string, std::string> keywords_;
133 };
134 
135 
142 {
143 public:
145 
146  void process_recursive(utils::kernel_generation_stream & stream, leaf_t leaf, std::string const & key, std::string const & process_str, std::set<std::string> & already_fetched)
147  {
148  tree_parsing::process(stream, leaf, key, process_str, *info_.statement, info_.root_idx, *info_.mapping, already_fetched);
149  }
150 
151  std::string evaluate_recursive(leaf_t leaf, std::map<std::string, std::string> const & accessors)
152  {
153  return tree_parsing::evaluate(leaf, accessors, *info_.statement, info_.root_idx, *info_.mapping);
154  }
155 
156 protected:
158 };
159 
165 {
166 public:
167  mapped_matrix_product(std::string const & scalartype, unsigned int id, node_info info) : mapped_object(scalartype, id, "matrix_product"), binary_leaf(info) { }
168 };
169 
175 {
176 public:
177  mapped_reduction(std::string const & scalartype, unsigned int id, node_info info, std::string const & type_key) : mapped_object(scalartype, id, type_key), binary_leaf(info){ }
178 
179  vcl_size_t root_idx() const { return info_.root_idx; }
180  scheduler::statement const & statement() const { return *info_.statement; }
183 
185  {
190  return res;
191  }
192 };
193 
199 {
200 public:
201  mapped_scalar_reduction(std::string const & scalartype, unsigned int id, node_info info) : mapped_reduction(scalartype, id, info, "scalar_reduction"){ }
202 };
203 
209 {
210 public:
211  mapped_row_wise_reduction(std::string const & scalartype, unsigned int id, node_info info) : mapped_reduction(scalartype, id, info, "row_wise_reduction") { }
212 };
213 
219 {
220 public:
221  mapped_host_scalar(std::string const & scalartype, unsigned int id) : mapped_object(scalartype, id, "host_scalar"){ }
222 
223  std::string & append_kernel_arguments(std::set<std::string> & already_generated, std::string & str, unsigned int width) const
224  {
225  if (already_generated.insert(name_).second)
226  str += generate_value_kernel_argument(utils::append_width(scalartype_, width), name_);
227  return str;
228  }
229 };
230 
236 {
237 private:
238  virtual void append_optional_arguments(std::string &) const = 0;
239 
240 public:
241  mapped_handle(std::string const & scalartype, unsigned int id, std::string const & type_key) : mapped_object(scalartype, id, type_key)
242  {
243  register_attribute(pointer_, "#pointer", name_ + "_pointer");
244  }
245 
246  std::string & append_kernel_arguments(std::set<std::string> & already_generated, std::string & str, unsigned int width) const
247  {
248  if (already_generated.insert(name_).second)
249  {
250  str += generate_pointer_kernel_argument("__global", utils::append_width(scalartype_, width), pointer_);
251  append_optional_arguments(str);
252  }
253  return str;
254  }
255 
256 private:
257  std::string pointer_;
258 };
259 
260 
266 {
267 private:
268  void append_optional_arguments(std::string &) const{ }
269 
270 public:
271  mapped_scalar(std::string const & scalartype, unsigned int id) : mapped_handle(scalartype, id, "scalar") { }
272 };
273 
279 {
280 public:
281  mapped_buffer(std::string const & scalartype, unsigned int id, std::string const & type_key) : mapped_handle(scalartype, id, type_key){ }
282 };
283 
289 {
290  void append_optional_arguments(std::string & str) const
291  {
292  str += generate_value_kernel_argument("unsigned int", start_);
293  str += generate_value_kernel_argument("unsigned int", stride_);
294  }
295 
296 public:
297  mapped_vector(std::string const & scalartype, unsigned int id) : mapped_buffer(scalartype, id, "vector")
298  {
299  register_attribute(start_, "#start", name_ + "_start");
300  register_attribute(stride_, "#stride", name_ + "_stride");
301  }
302 
303 private:
304  std::string start_;
305  std::string stride_;
306 };
307 
313 {
314 private:
315  void append_optional_arguments(std::string & str) const
316  {
317  str += generate_value_kernel_argument("unsigned int", ld_);
318  str += generate_value_kernel_argument("unsigned int", start1_);
319  str += generate_value_kernel_argument("unsigned int", start2_);
320  str += generate_value_kernel_argument("unsigned int", stride1_);
321  str += generate_value_kernel_argument("unsigned int", stride2_);
322  }
323 
324  void postprocess(std::string & str) const
325  {
326  struct Morph : public MorphBase2D
327  {
328  Morph(bool _is_row_major, std::string const & _ld) : is_row_major(_is_row_major), ld(_ld){ }
329  std::string operator()(std::string const & i, std::string const & j) const
330  {
331  if (is_row_major)
332  return "(" + i + ") * " + ld + " + (" + j + ")";
333  return "(" + i + ") + (" + j + ") * " + ld;
334  }
335  private:
336  bool is_row_major;
337  std::string const & ld;
338  };
339  replace_offset(str, Morph(row_major_, ld_));
340  }
341 
342 public:
343  mapped_matrix(std::string const & scalartype, unsigned int id, bool row_major) : mapped_buffer(scalartype, id, "matrix"), row_major_(row_major)
344  {
345  register_attribute(ld_, "#ld", name_ + "_ld");
346  register_attribute(start1_, "#start1", name_ + "_start1");
347  register_attribute(start2_, "#start2", name_ + "_start2");
348  register_attribute(stride1_, "#stride1", name_ + "_stride1");
349  register_attribute(stride2_, "#stride2", name_ + "_stride2");
350  if (row_major_)
351  keywords_["#nldstride"] = "#stride1";
352  else
353  keywords_["#nldstride"] = "#stride2";
354 
355  if (row_major_)
356  {
357  std::swap(start1_, start2_);
358  std::swap(stride1_, stride2_);
359  }
360  }
361 
362  bool row_major() const
363  {
364  return row_major_;
365  }
366 
367 private:
368  std::string ld_;
369  std::string start1_;
370  std::string start2_;
371  std::string stride1_;
372  std::string stride2_;
373  bool row_major_;
374 };
375 
381 {
382 private:
383  void postprocess(std::string &res) const
384  {
385  std::map<std::string, std::string> accessors;
387  accessors["vector"] = res;
389  }
390 
391 public:
392  mapped_vector_diag(std::string const & scalartype, unsigned int id, node_info info) : mapped_object(scalartype, id, "vector_diag"), binary_leaf(info){ }
393 };
394 
395 
401 {
402 private:
403  void postprocess(std::string &res) const
404  {
405  std::map<std::string, std::string> accessors;
406  accessors["matrix"] = res;
408  }
409 
410 public:
411  mapped_trans(std::string const & scalartype, unsigned int id, node_info info) : mapped_object(scalartype, id, "matrix_trans"), binary_leaf(info){ }
412 };
413 
419 {
420 private:
421  void postprocess(std::string &res) const
422  {
423  std::map<std::string, std::string> accessors;
425  accessors["matrix"] = res;
427  }
428 
429 public:
430  mapped_matrix_row(std::string const & scalartype, unsigned int id, node_info info) : mapped_object(scalartype, id, "matrix_row"), binary_leaf(info)
431  { }
432 };
433 
434 
440 {
441 private:
442  void postprocess(std::string &res) const
443  {
444  std::map<std::string, std::string> accessors;
446  accessors["matrix"] = res;
448  }
449 
450 public:
451  mapped_matrix_column(std::string const & scalartype, unsigned int id, node_info info) : mapped_object(scalartype, id, "matrix_column"), binary_leaf(info)
452  { }
453 };
454 
460 {
461 private:
462  void postprocess(std::string &res) const
463  {
464  std::map<std::string, std::string> accessors;
466  accessors["matrix"] = res;
468  }
469 
470 public:
471  mapped_matrix_diag(std::string const & scalartype, unsigned int id, node_info info) : mapped_object(scalartype, id, "matrix_diag"), binary_leaf(info)
472  { }
473 };
474 
480 {
481 public:
482  mapped_implicit_vector(std::string const & scalartype, unsigned int id) : mapped_object(scalartype, id, "implicit_vector")
483  { }
484 
485  std::string & append_kernel_arguments(std::set<std::string> & /*already_generated*/, std::string & str, unsigned int width) const
486  {
487  str += generate_value_kernel_argument(utils::append_width(scalartype_, width), name_);
488  return str;
489  }
490 };
491 
497 {
498 public:
499  mapped_implicit_matrix(std::string const & scalartype, unsigned int id) : mapped_object(scalartype, id, "implicit_matrix")
500  { }
501 
502  std::string & append_kernel_arguments(std::set<std::string> & /*already_generated*/, std::string & str, unsigned int width) const
503  {
504  str += generate_value_kernel_argument(utils::append_width(scalartype_, width), name_);
505  return str;
506  }
507 };
508 
509 }
510 
511 }
512 #endif
std::string & append_kernel_arguments(std::set< std::string > &, std::string &str, unsigned int width) const
mapped_implicit_matrix(std::string const &scalartype, unsigned int id)
std::string & append_kernel_arguments(std::set< std::string > &already_generated, std::string &str, unsigned int width) const
Helper class for checking whether a matrix has a row-major layout.
Definition: forwards.h:484
std::string evaluate_recursive(leaf_t leaf, std::map< std::string, std::string > const &accessors)
std::string & append_kernel_arguments(std::set< std::string > &already_generated, std::string &str, unsigned int width) const
mapped_handle(std::string const &scalartype, unsigned int id, std::string const &type_key)
virtual std::string & append_kernel_arguments(std::set< std::string > &, std::string &str, unsigned int) const
std::string & append_kernel_arguments(std::set< std::string > &, std::string &str, unsigned int width) const
container_type const & array() const
Definition: forwards.h:528
std::string evaluate(std::map< std::string, std::string > const &accessors) const
Struct for holding the type family as well as the type of an operation (could be addition, subtraction, norm, etc.)
Definition: forwards.h:471
mapped_implicit_vector(std::string const &scalartype, unsigned int id)
virtual std::string operator()(std::string const &i, std::string const &j) const =0
mapped_matrix_product(std::string const &scalartype, unsigned int id, node_info info)
Main namespace in ViennaCL. Holds all the basic types such as vector, matrix, etc. and defines operations upon them.
Definition: cpu_ram.hpp:34
mapped_matrix_diag(std::string const &scalartype, unsigned int id, node_info info)
mapped_trans(std::string const &scalartype, unsigned int id, node_info info)
vcl_size_t ld(matrix_base< NumericT > const &mat)
Helper routine for obtaining the internal number of entries per row of a ViennaCL matrix...
Definition: size.hpp:394
int find_and_replace(std::string &source, std::string const &find, std::string const &replace)
Replace in a source string a pattern by another.
Definition: tools.hpp:160
virtual std::string operator()(std::string const &i) const =0
void register_attribute(std::string &attribute, std::string const &key, std::string const &value)
mapped_host_scalar(std::string const &scalartype, unsigned int id)
std::string evaluate(leaf_t leaf, std::map< std::string, std::string > const &accessors, scheduler::statement const &statement, vcl_size_t root_idx, mapping_type const &mapping)
std::map< std::string, std::string > keywords_
Forwards declaration.
binary_leaf(mapped_object::node_info info)
std::size_t vcl_size_t
Definition: forwards.h:75
std::string process(std::string const &in) const
mapped_vector(std::string const &scalartype, unsigned int id)
Provides the datastructures for dealing with a single statement such as 'x = y + z;'.
viennacl::enable_if< viennacl::is_scalar< ScalarT1 >::value &&viennacl::is_scalar< ScalarT2 >::value >::type swap(ScalarT1 &s1, ScalarT2 &s2)
Swaps the contents of two scalars, data is copied.
node_info(mapping_type const *_mapping, scheduler::statement const *_statement, vcl_size_t _root_idx)
mapped_matrix_row(std::string const &scalartype, unsigned int id, node_info info)
std::map< mapping_key, tools::shared_ptr< mapped_object > > mapping_type
Definition: forwards.h:191
mapped_row_wise_reduction(std::string const &scalartype, unsigned int id, node_info info)
mapped_matrix(std::string const &scalartype, unsigned int id, bool row_major)
mapped_buffer(std::string const &scalartype, unsigned int id, std::string const &type_key)
Internal utils.
operation_node_type type
Definition: forwards.h:474
mapped_object(std::string const &scalartype, unsigned int id, std::string const &type_key)
mapped_scalar_reduction(std::string const &scalartype, unsigned int id, node_info info)
void process_recursive(utils::kernel_generation_stream &stream, leaf_t leaf, std::string const &key, std::string const &process_str, std::set< std::string > &already_fetched)
bool is_index_reduction(scheduler::op_element const &op)
Definition: utils.hpp:370
mapped_scalar(std::string const &scalartype, unsigned int id)
mapped_vector_diag(std::string const &scalartype, unsigned int id, node_info info)
The main class for representing a statement such as x = inner_prod(y,z); at runtime.
Definition: forwards.h:502
scheduler::op_element root_op() const
ValueT const & at(std::map< KeyT, ValueT > const &map, KeyT const &key)
Emulation of C++11's .at() member for std::map<>, const-version.
Definition: forwards.h:142
std::string to_string(T const t)
Definition: tools.hpp:304
mapped_reduction(std::string const &scalartype, unsigned int id, node_info info, std::string const &type_key)
static void replace_offset(std::string &str, MorphBase const &morph)
A tag for row-major storage of a dense matrix.
Definition: forwards.h:304
scheduler::statement const & statement() const
Main datastructure for an node in the statement tree.
Definition: forwards.h:478
mapped_matrix_column(std::string const &scalartype, unsigned int id, node_info info)
scheduler::statement_node root_node() const
void process(utils::kernel_generation_stream &stream, leaf_t leaf, std::string const &type_key, std::string const &to_process, scheduler::statement const &statement, vcl_size_t root_idx, mapping_type const &mapping, std::set< std::string > &already_processed)
std::string append_width(std::string const &str, unsigned int width)
Definition: utils.hpp:558