1 #ifndef VIENNACL_DEVICE_SPECIFIC_TEMPLATES_REDUCTION_UTILS_HPP
2 #define VIENNACL_DEVICE_SPECIFIC_TEMPLATES_REDUCTION_UTILS_HPP
3 
4 /* =========================================================================
5    Copyright (c) 2010-2016, 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 
22 /** @file viennacl/device_specific/templates/utils.hpp
23  *
24  * A collection of utilities for the device specific execution templates.
25 */
26 
27 #include <vector>
28 
29 #include "viennacl/scheduler/forwards.h"
30 
31 #include "viennacl/device_specific/tree_parsing.hpp"
32 #include "viennacl/device_specific/utils.hpp"
33 
34 
35 namespace viennacl
36 {
37 namespace device_specific
38 {
39 
compute_reduction(utils::kernel_generation_stream & os,std::string acc,std::string cur,scheduler::op_element const & op)40 inline void compute_reduction(utils::kernel_generation_stream & os, std::string acc, std::string cur, scheduler::op_element const & op)
41 {
42   if (utils::elementwise_function(op))
43     os << acc << "=" << tree_parsing::evaluate(op.type) << "(" << acc << "," << cur << ");" << std::endl;
44   else
45     os << acc << "= (" << acc << ")" << tree_parsing::evaluate(op.type)  << "(" << cur << ");" << std::endl;
46 }
47 
compute_index_reduction(utils::kernel_generation_stream & os,std::string acc,std::string cur,std::string const & acc_value,std::string const & cur_value,scheduler::op_element const & op)48 inline void compute_index_reduction(utils::kernel_generation_stream & os, std::string acc, std::string cur, std::string const & acc_value, std::string const & cur_value, scheduler::op_element const & op)
49 {
50   //        os << acc << " = " << cur_value << ">" << acc_value  << "?" << cur << ":" << acc << ";" << std::endl;
51   os << acc << "= select(" << acc << "," << cur << "," << cur_value << ">" << acc_value << ");" << std::endl;
52   os << acc_value << "=";
53   if (op.type==scheduler::OPERATION_BINARY_ELEMENT_ARGFMAX_TYPE) os << "fmax";
54   if (op.type==scheduler::OPERATION_BINARY_ELEMENT_ARGMAX_TYPE) os << "max";
55   if (op.type==scheduler::OPERATION_BINARY_ELEMENT_ARGFMIN_TYPE) os << "fmin";
56   if (op.type==scheduler::OPERATION_BINARY_ELEMENT_ARGMIN_TYPE) os << "min";
57   os << "(" << acc_value << "," << cur_value << ");"<< std::endl;
58 }
59 
process_all(std::string const & type_key,std::string const & str,utils::kernel_generation_stream & stream,std::vector<mapping_type> const & mappings)60 inline void process_all(std::string const & type_key, std::string const & str,
61                         utils::kernel_generation_stream & stream, std::vector<mapping_type> const & mappings)
62 {
63   for (std::vector<mapping_type>::const_iterator mit = mappings.begin(); mit != mappings.end(); ++mit)
64     for (mapping_type::const_iterator mmit = mit->begin(); mmit != mit->end(); ++mmit)
65       if (mmit->second->type_key()==type_key)
66         stream << mmit->second->process(str) << std::endl;
67 }
68 
69 
process_all_at(std::string const & type_key,std::string const & str,utils::kernel_generation_stream & stream,std::vector<mapping_type> const & mappings,vcl_size_t root_idx,leaf_t leaf)70 inline void process_all_at(std::string const & type_key, std::string const & str,
71                            utils::kernel_generation_stream & stream, std::vector<mapping_type> const & mappings,
72                            vcl_size_t root_idx, leaf_t leaf)
73 {
74   for (std::vector<mapping_type>::const_iterator mit = mappings.begin(); mit != mappings.end(); ++mit)
75   {
76     mapped_object * obj = at(*mit, mapping_key(root_idx, leaf)).get();
77     if (obj->type_key()==type_key)
78       stream << obj->process(str) << std::endl;
79   }
80 }
81 
neutral_element(scheduler::op_element const & op)82 inline std::string neutral_element(scheduler::op_element const & op)
83 {
84   switch (op.type)
85   {
86   case scheduler::OPERATION_BINARY_ADD_TYPE : return "0";
87   case scheduler::OPERATION_BINARY_MULT_TYPE : return "1";
88   case scheduler::OPERATION_BINARY_DIV_TYPE : return "1";
89   case scheduler::OPERATION_BINARY_ELEMENT_FMAX_TYPE : return "-INFINITY";
90   case scheduler::OPERATION_BINARY_ELEMENT_ARGFMAX_TYPE : return "-INFINITY";
91   case scheduler::OPERATION_BINARY_ELEMENT_MAX_TYPE : return "-INFINITY";
92   case scheduler::OPERATION_BINARY_ELEMENT_ARGMAX_TYPE : return "-INFINITY";
93   case scheduler::OPERATION_BINARY_ELEMENT_FMIN_TYPE : return "INFINITY";
94   case scheduler::OPERATION_BINARY_ELEMENT_ARGFMIN_TYPE : return "INFINITY";
95   case scheduler::OPERATION_BINARY_ELEMENT_MIN_TYPE : return "INFINITY";
96   case scheduler::OPERATION_BINARY_ELEMENT_ARGMIN_TYPE : return "INFINITY";
97 
98   default: throw generator_not_supported_exception("Unsupported reduction operator : no neutral element known");
99   }
100 }
101 
102 }
103 }
104 
105 #endif
106