Feature: Merged kernel-fusion branch

* Fuses multiple AXPY kernel
* Possibility to add thread-wise for loops in AXPY-like kernels
This commit is contained in:
Philippe Tillet
2015-09-30 15:31:41 -04:00
parent 149441b9e2
commit feeb1e9862
64 changed files with 10047 additions and 1119 deletions

View File

@@ -13,8 +13,8 @@ namespace detail
{
bool is_node_leaf(op_element const & op);
bool is_scalar_dot(array_expression::node const & node);
bool is_vector_dot(array_expression::node const & node);
bool is_scalar_dot(math_expression::node const & node);
bool is_vector_dot(math_expression::node const & node);
bool is_assignment(op_element const & op);
bool is_elementwise_operator(op_element const & op);
bool is_elementwise_function(op_element const & op);
@@ -24,58 +24,58 @@ namespace detail
class scalar;
/** @brief base functor class for traversing a array_expression */
/** @brief base functor class for traversing a math_expression */
class traversal_functor
{
public:
void call_before_expansion(array_expression const &, std::size_t) const { }
void call_after_expansion(array_expression const &, std::size_t) const { }
void call_before_expansion(math_expression const &, std::size_t) const { }
void call_after_expansion(math_expression const &, std::size_t) const { }
};
/** @brief Recursively execute a functor on a array_expression */
/** @brief Recursively execute a functor on a math_expression */
template<class Fun>
inline void traverse(isaac::array_expression const & array_expression, std::size_t root_idx, Fun const & fun, bool inspect)
inline void traverse(isaac::math_expression const & math_expression, std::size_t root_idx, Fun const & fun, bool inspect)
{
array_expression::node const & root_node = array_expression.tree()[root_idx];
math_expression::node const & root_node = math_expression.tree()[root_idx];
bool recurse = detail::is_node_leaf(root_node.op)?inspect:true;
bool bypass = detail::bypass(root_node.op);
if(!bypass)
fun.call_before_expansion(array_expression, root_idx);
fun.call_before_expansion(math_expression, root_idx);
//Lhs:
if (recurse)
{
if (root_node.lhs.type_family==COMPOSITE_OPERATOR_FAMILY)
traverse(array_expression, root_node.lhs.node_index, fun, inspect);
traverse(math_expression, root_node.lhs.node_index, fun, inspect);
if (root_node.lhs.type_family != INVALID_TYPE_FAMILY)
fun(array_expression, root_idx, LHS_NODE_TYPE);
fun(math_expression, root_idx, LHS_NODE_TYPE);
}
//Self:
if(!bypass)
fun(array_expression, root_idx, PARENT_NODE_TYPE);
fun(math_expression, root_idx, PARENT_NODE_TYPE);
//Rhs:
if (recurse && root_node.rhs.type_family!=INVALID_TYPE_FAMILY)
{
if (root_node.rhs.type_family==COMPOSITE_OPERATOR_FAMILY)
traverse(array_expression, root_node.rhs.node_index, fun, inspect);
traverse(math_expression, root_node.rhs.node_index, fun, inspect);
if (root_node.rhs.type_family != INVALID_TYPE_FAMILY)
fun(array_expression, root_idx, RHS_NODE_TYPE);
fun(math_expression, root_idx, RHS_NODE_TYPE);
}
if(!bypass)
fun.call_after_expansion(array_expression, root_idx);
fun.call_after_expansion(math_expression, root_idx);
}
class filter_fun : public traversal_functor
{
public:
typedef bool (*pred_t)(array_expression::node const & node);
typedef bool (*pred_t)(math_expression::node const & node);
filter_fun(pred_t pred, std::vector<size_t> & out);
void operator()(isaac::array_expression const & array_expression, size_t root_idx, leaf_t) const;
void operator()(isaac::math_expression const & math_expression, size_t root_idx, leaf_t) const;
private:
pred_t pred_;
std::vector<size_t> & out_;
@@ -84,22 +84,23 @@ private:
class filter_elements_fun : public traversal_functor
{
public:
filter_elements_fun(array_expression_node_subtype subtype, std::vector<lhs_rhs_element> & out);
void operator()(isaac::array_expression const & array_expression, size_t root_idx, leaf_t) const;
filter_elements_fun(math_expression_node_subtype subtype, std::vector<lhs_rhs_element> & out);
void operator()(isaac::math_expression const & math_expression, size_t root_idx, leaf_t) const;
private:
array_expression_node_subtype subtype_;
math_expression_node_subtype subtype_;
std::vector<lhs_rhs_element> & out_;
};
std::vector<size_t> filter_nodes(bool (*pred)(array_expression::node const & node),
isaac::array_expression const & array_expression,
std::vector<size_t> filter_nodes(bool (*pred)(math_expression::node const & node),
isaac::math_expression const & math_expression,
size_t root,
bool inspect);
std::vector<lhs_rhs_element> filter_elements(array_expression_node_subtype subtype,
isaac::array_expression const & array_expression);
std::vector<lhs_rhs_element> filter_elements(math_expression_node_subtype subtype,
isaac::math_expression const & math_expression);
const char * evaluate(operation_node_type type);
/** @brief functor for generating the expression string from a array_expression */
/** @brief functor for generating the expression string from a math_expression */
class evaluate_expression_traversal: public traversal_functor
{
private:
@@ -109,24 +110,24 @@ private:
public:
evaluate_expression_traversal(std::map<std::string, std::string> const & accessors, std::string & str, mapping_type const & mapping);
void call_before_expansion(isaac::array_expression const & array_expression, std::size_t root_idx) const;
void call_after_expansion(array_expression const & /*array_expression*/, std::size_t /*root_idx*/) const;
void operator()(isaac::array_expression const & array_expression, std::size_t root_idx, leaf_t leaf) const;
void call_before_expansion(isaac::math_expression const & math_expression, std::size_t root_idx) const;
void call_after_expansion(math_expression const & /*math_expression*/, std::size_t /*root_idx*/) const;
void operator()(isaac::math_expression const & math_expression, std::size_t root_idx, leaf_t leaf) const;
};
std::string evaluate(leaf_t leaf, std::map<std::string, std::string> const & accessors,
isaac::array_expression const & array_expression, std::size_t root_idx, mapping_type const & mapping);
isaac::math_expression const & math_expression, std::size_t root_idx, mapping_type const & mapping);
void evaluate(kernel_generation_stream & stream, leaf_t leaf, std::map<std::string, std::string> const & accessors,
expressions_tuple const & expressions, std::vector<mapping_type> const & mappings);
math_expression const & expressions, mapping_type const & mappings);
/** @brief functor for fetching or writing-back the elements in a array_expression */
/** @brief functor for fetching or writing-back the elements in a math_expression */
class process_traversal : public traversal_functor
{
public:
process_traversal(std::map<std::string, std::string> const & accessors, kernel_generation_stream & stream,
mapping_type const & mapping, std::set<std::string> & already_processed);
void operator()(array_expression const & array_expression, std::size_t root_idx, leaf_t leaf) const;
void operator()(math_expression const & math_expression, std::size_t root_idx, leaf_t leaf) const;
private:
std::map<std::string, std::string> accessors_;
kernel_generation_stream & stream_;
@@ -135,21 +136,21 @@ private:
};
void process(kernel_generation_stream & stream, leaf_t leaf, std::map<std::string, std::string> const & accessors,
isaac::array_expression const & array_expression, size_t root_idx, mapping_type const & mapping, std::set<std::string> & already_processed);
isaac::math_expression const & math_expression, size_t root_idx, mapping_type const & mapping, std::set<std::string> & already_processed);
void process(kernel_generation_stream & stream, leaf_t leaf, std::map<std::string, std::string> const & accessors,
expressions_tuple const & expressions, std::vector<mapping_type> const & mappings);
math_expression const & expressions, mapping_type const & mappings);
class array_expression_representation_functor : public traversal_functor{
class math_expression_representation_functor : public traversal_functor{
private:
static void append_id(char * & ptr, unsigned int val);
void append(driver::Buffer const & h, numeric_type dtype, char prefix) const;
void append(lhs_rhs_element const & lhs_rhs) const;
void append(lhs_rhs_element const & lhs_rhs, bool is_assigned) const;
public:
array_expression_representation_functor(symbolic_binder & binder, char *& ptr);
math_expression_representation_functor(symbolic_binder & binder, char *& ptr);
void append(char*& p, const char * str) const;
void operator()(isaac::array_expression const & array_expression, std::size_t root_idx, leaf_t leaf_t) const;
void operator()(isaac::math_expression const & math_expression, std::size_t root_idx, leaf_t leaf_t) const;
private:
symbolic_binder & binder_;
char *& ptr_;