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