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:
@@ -1,14 +1,14 @@
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "isaac/tuple.h"
|
||||
#include "isaac/kernels/mapped_object.h"
|
||||
#include "isaac/kernels/parse.h"
|
||||
#include "isaac/kernels/stream.h"
|
||||
#include "isaac/symbolic/expression.h"
|
||||
|
||||
#include <string>
|
||||
#include "find_and_replace.hpp"
|
||||
#include "to_string.hpp"
|
||||
|
||||
@@ -51,15 +51,18 @@ void mapped_object::register_attribute(std::string & attribute, std::string cons
|
||||
keywords_[key] = attribute;
|
||||
}
|
||||
|
||||
mapped_object::node_info::node_info(mapping_type const * _mapping, isaac::array_expression const * _array_expression, size_t _root_idx) :
|
||||
mapping(_mapping), array_expression(_array_expression), root_idx(_root_idx) { }
|
||||
mapped_object::node_info::node_info(mapping_type const * _mapping, isaac::math_expression const * _math_expression, size_t _root_idx) :
|
||||
mapping(_mapping), math_expression(_math_expression), root_idx(_root_idx) { }
|
||||
|
||||
mapped_object::mapped_object(std::string const & scalartype, unsigned int id, std::string const & type_key) : type_key_(type_key)
|
||||
mapped_object::mapped_object(std::string const & scalartype, std::string const & name, std::string const & type_key) : type_key_(type_key), name_(name)
|
||||
{
|
||||
register_attribute(scalartype_, "#scalartype", scalartype);
|
||||
register_attribute(name_, "#name", "obj" + tools::to_string(id));
|
||||
keywords_["#name"] = name;
|
||||
}
|
||||
|
||||
mapped_object::mapped_object(std::string const & scalartype, unsigned int id, std::string const & type_key) : mapped_object(scalartype, "obj" + tools::to_string(id), type_key)
|
||||
{ }
|
||||
|
||||
mapped_object::~mapped_object()
|
||||
{ }
|
||||
|
||||
@@ -89,18 +92,28 @@ std::string mapped_object::evaluate(std::map<std::string, std::string> const & a
|
||||
return process(accessors.at(type_key_));
|
||||
}
|
||||
|
||||
mapped_object& get(math_expression::container_type const & tree, size_t root, mapping_type const & mapping, size_t idx)
|
||||
{
|
||||
for(unsigned int i = 0 ; i < idx ; ++i){
|
||||
math_expression::node node = tree[root];
|
||||
if(node.rhs.type_family==COMPOSITE_OPERATOR_FAMILY)
|
||||
root = node.rhs.node_index;
|
||||
else
|
||||
return *(mapping.at(std::make_pair(root, RHS_NODE_TYPE)));
|
||||
}
|
||||
return *(mapping.at(std::make_pair(root, LHS_NODE_TYPE)));
|
||||
}
|
||||
|
||||
binary_leaf::binary_leaf(mapped_object::node_info info) : info_(info){ }
|
||||
|
||||
void binary_leaf::process_recursive(kernel_generation_stream & stream, leaf_t leaf, std::map<std::string, std::string> const & accessors)
|
||||
void binary_leaf::process_recursive(kernel_generation_stream & stream, leaf_t leaf, std::map<std::string, std::string> const & accessors, std::set<std::string> & already_fetched)
|
||||
{
|
||||
std::set<std::string> already_fetched;
|
||||
process(stream, leaf, accessors, *info_.array_expression, info_.root_idx, *info_.mapping, already_fetched);
|
||||
process(stream, leaf, accessors, *info_.math_expression, info_.root_idx, *info_.mapping, already_fetched);
|
||||
}
|
||||
|
||||
std::string binary_leaf::evaluate_recursive(leaf_t leaf, std::map<std::string, std::string> const & accessors)
|
||||
{
|
||||
return evaluate(leaf, accessors, *info_.array_expression, info_.root_idx, *info_.mapping);
|
||||
return evaluate(leaf, accessors, *info_.math_expression, info_.root_idx, *info_.mapping);
|
||||
}
|
||||
|
||||
|
||||
@@ -114,11 +127,11 @@ mapped_dot::mapped_dot(std::string const & scalartype, unsigned int id, node_inf
|
||||
size_t mapped_dot::root_idx() const
|
||||
{ return info_.root_idx; }
|
||||
|
||||
isaac::array_expression const & mapped_dot::array_expression() const
|
||||
{ return *info_.array_expression; }
|
||||
isaac::math_expression const & mapped_dot::math_expression() const
|
||||
{ return *info_.math_expression; }
|
||||
|
||||
array_expression::node mapped_dot::root_node() const
|
||||
{ return array_expression().tree()[root_idx()]; }
|
||||
math_expression::node mapped_dot::root_node() const
|
||||
{ return math_expression().tree()[root_idx()]; }
|
||||
|
||||
bool mapped_dot::is_index_dot() const
|
||||
{
|
||||
@@ -131,7 +144,7 @@ bool mapped_dot::is_index_dot() const
|
||||
|
||||
op_element mapped_dot::root_op() const
|
||||
{
|
||||
return info_.array_expression->tree()[info_.root_idx].op;
|
||||
return info_.math_expression->tree()[info_.root_idx].op;
|
||||
}
|
||||
|
||||
|
||||
@@ -155,15 +168,11 @@ void mapped_host_scalar::preprocess(std::string & str) const
|
||||
replace_macro(str, "$VALUE", Morph());
|
||||
}
|
||||
|
||||
|
||||
mapped_host_scalar::mapped_host_scalar(std::string const & scalartype, unsigned int id) : mapped_object(scalartype, id, "host_scalar"){ }
|
||||
//
|
||||
mapped_placeholder::mapped_placeholder(unsigned int level) : mapped_object("int", "sforidx" + tools::to_string(level), "placeholder"){}
|
||||
|
||||
//
|
||||
mapped_tuple::mapped_tuple(std::string const & scalartype, unsigned int id, size_t size) : mapped_object(scalartype, id, "tuple"+tools::to_string(size)), size_(size), names_(size)
|
||||
{
|
||||
for(size_t i = 0 ; i < size_ ; ++i)
|
||||
register_attribute(names_[i], "#tuplearg"+tools::to_string(i), name_ + tools::to_string(i));
|
||||
}
|
||||
mapped_host_scalar::mapped_host_scalar(std::string const & scalartype, unsigned int id) : mapped_object(scalartype, id, "host_scalar"){ }
|
||||
|
||||
//
|
||||
mapped_handle::mapped_handle(std::string const & scalartype, unsigned int id, std::string const & type_key) : mapped_object(scalartype, id, type_key)
|
||||
@@ -230,22 +239,34 @@ mapped_array::mapped_array(std::string const & scalartype, unsigned int id, char
|
||||
void mapped_vdiag::postprocess(std::string &res) const
|
||||
{
|
||||
std::map<std::string, std::string> accessors;
|
||||
tools::find_and_replace(res, "#diag_offset", isaac::evaluate(RHS_NODE_TYPE, accessors, *info_.array_expression, info_.root_idx, *info_.mapping));
|
||||
tools::find_and_replace(res, "#diag_offset", isaac::evaluate(RHS_NODE_TYPE, accessors, *info_.math_expression, info_.root_idx, *info_.mapping));
|
||||
accessors["array1"] = res;
|
||||
accessors["host_scalar"] = res;
|
||||
res = isaac::evaluate(LHS_NODE_TYPE, accessors, *info_.array_expression, info_.root_idx, *info_.mapping);
|
||||
res = isaac::evaluate(LHS_NODE_TYPE, accessors, *info_.math_expression, info_.root_idx, *info_.mapping);
|
||||
}
|
||||
|
||||
mapped_vdiag::mapped_vdiag(std::string const & scalartype, unsigned int id, node_info info) : mapped_object(scalartype, id, "vdiag"), binary_leaf(info){}
|
||||
|
||||
//
|
||||
void mapped_array_access::postprocess(std::string &res) const
|
||||
{
|
||||
std::map<std::string, std::string> accessors;
|
||||
tools::find_and_replace(res, "#index", isaac::evaluate(RHS_NODE_TYPE, accessors, *info_.math_expression, info_.root_idx, *info_.mapping));
|
||||
accessors["array1"] = res;
|
||||
accessors["array2"] = res;
|
||||
res = isaac::evaluate(LHS_NODE_TYPE, accessors, *info_.math_expression, info_.root_idx, *info_.mapping);
|
||||
}
|
||||
|
||||
mapped_array_access::mapped_array_access(std::string const & scalartype, unsigned int id, node_info info) : mapped_object(scalartype, id, "array_access"), binary_leaf(info)
|
||||
{ }
|
||||
|
||||
//
|
||||
void mapped_matrix_row::postprocess(std::string &res) const
|
||||
{
|
||||
std::map<std::string, std::string> accessors;
|
||||
tools::find_and_replace(res, "#row", isaac::evaluate(RHS_NODE_TYPE, accessors, *info_.array_expression, info_.root_idx, *info_.mapping));
|
||||
tools::find_and_replace(res, "#row", isaac::evaluate(RHS_NODE_TYPE, accessors, *info_.math_expression, info_.root_idx, *info_.mapping));
|
||||
accessors["array2"] = res;
|
||||
res = isaac::evaluate(LHS_NODE_TYPE, accessors, *info_.array_expression, info_.root_idx, *info_.mapping);
|
||||
res = isaac::evaluate(LHS_NODE_TYPE, accessors, *info_.math_expression, info_.root_idx, *info_.mapping);
|
||||
}
|
||||
|
||||
mapped_matrix_row::mapped_matrix_row(std::string const & scalartype, unsigned int id, node_info info) : mapped_object(scalartype, id, "matrix_row"), binary_leaf(info)
|
||||
@@ -255,34 +276,45 @@ mapped_matrix_row::mapped_matrix_row(std::string const & scalartype, unsigned in
|
||||
void mapped_matrix_column::postprocess(std::string &res) const
|
||||
{
|
||||
std::map<std::string, std::string> accessors;
|
||||
tools::find_and_replace(res, "#column", isaac::evaluate(RHS_NODE_TYPE, accessors, *info_.array_expression, info_.root_idx, *info_.mapping));
|
||||
tools::find_and_replace(res, "#column", isaac::evaluate(RHS_NODE_TYPE, accessors, *info_.math_expression, info_.root_idx, *info_.mapping));
|
||||
accessors["array2"] = res;
|
||||
res = isaac::evaluate(LHS_NODE_TYPE, accessors, *info_.array_expression, info_.root_idx, *info_.mapping);
|
||||
res = isaac::evaluate(LHS_NODE_TYPE, accessors, *info_.math_expression, info_.root_idx, *info_.mapping);
|
||||
}
|
||||
|
||||
mapped_matrix_column::mapped_matrix_column(std::string const & scalartype, unsigned int id, node_info info) : mapped_object(scalartype, id, "matrix_column"), binary_leaf(info)
|
||||
{ }
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
char mapped_repeat::get_type(node_info const & info)
|
||||
{
|
||||
repeat_infos const & infos = info.array_expression->tree()[info.root_idx].rhs.tuple;
|
||||
if(infos.sub1>1 && infos.sub2==1)
|
||||
math_expression::container_type const & tree = info.math_expression->tree();
|
||||
size_t tuple_root = tree[info.root_idx].rhs.node_index;
|
||||
|
||||
int sub0 = tuple_get(tree, tuple_root, 2);
|
||||
int sub1 = tuple_get(tree, tuple_root, 3);
|
||||
if(sub0>1 && sub1==1)
|
||||
return 'c';
|
||||
else if(infos.sub1==1 && infos.sub2>1)
|
||||
else if(sub0==1 && sub1>1)
|
||||
return 'r';
|
||||
else
|
||||
return 'm';
|
||||
}
|
||||
|
||||
|
||||
|
||||
void mapped_repeat::postprocess(std::string &res) const
|
||||
{
|
||||
std::map<std::string, std::string> accessors;
|
||||
mapped_object& args = *(info_.mapping->at(std::make_pair(info_.root_idx,RHS_NODE_TYPE)));
|
||||
tools::find_and_replace(res, "#tuplearg0", args.process("#tuplearg0"));
|
||||
tools::find_and_replace(res, "#tuplearg1", args.process("#tuplearg1"));
|
||||
tools::find_and_replace(res, "#tuplearg2", args.process("#tuplearg2"));
|
||||
tools::find_and_replace(res, "#tuplearg3", args.process("#tuplearg3"));
|
||||
math_expression::container_type const & tree = info_.math_expression->tree();
|
||||
size_t tuple_root = tree[info_.root_idx].rhs.node_index;
|
||||
|
||||
tools::find_and_replace(res, "#rep0", get(tree, tuple_root, *info_.mapping, 0).process("#name"));
|
||||
tools::find_and_replace(res, "#rep1", get(tree, tuple_root, *info_.mapping, 1).process("#name"));
|
||||
tools::find_and_replace(res, "#sub0", get(tree, tuple_root, *info_.mapping, 2).process("#name"));
|
||||
tools::find_and_replace(res, "#sub1", get(tree, tuple_root, *info_.mapping, 3).process("#name"));
|
||||
|
||||
struct MorphValue : public MorphBase
|
||||
{
|
||||
@@ -303,7 +335,7 @@ void mapped_repeat::postprocess(std::string &res) const
|
||||
replace_macro(res, "$VALUE", MorphValue(type_));
|
||||
accessors["array1"] = res;
|
||||
accessors["array2"] = res;
|
||||
res = isaac::evaluate(LHS_NODE_TYPE, accessors, *info_.array_expression, info_.root_idx, *info_.mapping);
|
||||
res = isaac::evaluate(LHS_NODE_TYPE, accessors, *info_.math_expression, info_.root_idx, *info_.mapping);
|
||||
}
|
||||
|
||||
mapped_repeat::mapped_repeat(std::string const & scalartype, unsigned int id, node_info info) : mapped_object(scalartype, id, "repeat"), binary_leaf(info), type_(get_type(info))
|
||||
@@ -315,9 +347,9 @@ mapped_repeat::mapped_repeat(std::string const & scalartype, unsigned int id, no
|
||||
void mapped_matrix_diag::postprocess(std::string &res) const
|
||||
{
|
||||
std::map<std::string, std::string> accessors;
|
||||
tools::find_and_replace(res, "#diag_offset", isaac::evaluate(RHS_NODE_TYPE, accessors, *info_.array_expression, info_.root_idx, *info_.mapping));
|
||||
tools::find_and_replace(res, "#diag_offset", isaac::evaluate(RHS_NODE_TYPE, accessors, *info_.math_expression, info_.root_idx, *info_.mapping));
|
||||
accessors["array2"] = res;
|
||||
res = isaac::evaluate(LHS_NODE_TYPE, accessors, *info_.array_expression, info_.root_idx, *info_.mapping);
|
||||
res = isaac::evaluate(LHS_NODE_TYPE, accessors, *info_.math_expression, info_.root_idx, *info_.mapping);
|
||||
}
|
||||
|
||||
mapped_matrix_diag::mapped_matrix_diag(std::string const & scalartype, unsigned int id, node_info info) : mapped_object(scalartype, id, "matrix_diag"), binary_leaf(info)
|
||||
@@ -333,7 +365,7 @@ void mapped_outer::postprocess(std::string &res) const
|
||||
{
|
||||
std::map<std::string, std::string> accessors;
|
||||
accessors["array1"] = "$VALUE{"+i+"}";
|
||||
return isaac::evaluate(leaf_, accessors, *i_.array_expression, i_.root_idx, *i_.mapping);
|
||||
return isaac::evaluate(leaf_, accessors, *i_.math_expression, i_.root_idx, *i_.mapping);
|
||||
}
|
||||
std::string operator()(std::string const &, std::string const &) const{return "";}
|
||||
private:
|
||||
|
Reference in New Issue
Block a user