Adding diag

This commit is contained in:
Philippe Tillet
2015-01-16 19:39:26 -05:00
parent 0e48c78bce
commit 1d70396711
9 changed files with 124 additions and 61 deletions

View File

@@ -113,7 +113,7 @@ public:
};
atidlas::array_expression diag(std::size_t, atidlas::value_scalar const &);
atidlas::array_expression eye(std::size_t, std::size_t, atidlas::numeric_type, cl::Context ctx = cl::default_context());
array_expression zeros(std::size_t N, numeric_type dtype);

View File

@@ -30,14 +30,16 @@ typedef std::map<mapping_key, tools::shared_ptr<mapped_object> > mapping_type;
class mapped_object
{
private:
virtual void postprocess(std::string &) const;
virtual void preprocess(std::string &) const;
protected:
struct MorphBase { virtual ~MorphBase(){} };
struct MorphBase1D : public MorphBase { public: virtual std::string operator()(std::string const & i) const = 0; };
struct MorphBase2D : public MorphBase { public: virtual std::string operator()(std::string const & i, std::string const & j) const = 0; };
struct MorphBase {
virtual std::string operator()(std::string const & i) const = 0;
virtual std::string operator()(std::string const & i, std::string const & j) const = 0;
virtual ~MorphBase(){}
};
static void replace_offset(std::string & str, MorphBase const & morph);
static void replace_macro(std::string & str, std::string const &, MorphBase const & morph);
void register_attribute(std::string & attribute, std::string const & key, std::string const & value);
public:
@@ -129,6 +131,7 @@ public:
*/
class mapped_host_scalar : public mapped_object
{
void preprocess(std::string & str) const;
public:
mapped_host_scalar(std::string const & scalartype, unsigned int id);
};
@@ -182,7 +185,7 @@ public:
class mapped_array : public mapped_buffer
{
private:
void postprocess(std::string & str) const;
void preprocess(std::string & str) const;
public:
mapped_array(std::string const & scalartype, unsigned int id, char type);
private:
@@ -197,7 +200,7 @@ private:
class mapped_vector_diag : public mapped_object, public binary_leaf
{
private:
void postprocess(std::string &res) const;
void preprocess(std::string &res) const;
public:
mapped_vector_diag(std::string const & scalartype, unsigned int id, node_info info);
};
@@ -205,7 +208,7 @@ public:
class mapped_trans: public mapped_object, public binary_leaf
{
private:
void postprocess(std::string &res) const;
void preprocess(std::string &res) const;
public:
mapped_trans(std::string const & scalartype, unsigned int id, node_info info);
};
@@ -213,7 +216,7 @@ public:
class mapped_matrix_row : public mapped_object, binary_leaf
{
private:
void postprocess(std::string &res) const;
void preprocess(std::string &res) const;
public:
mapped_matrix_row(std::string const & scalartype, unsigned int id, node_info info);
};
@@ -221,7 +224,7 @@ public:
class mapped_matrix_column : public mapped_object, binary_leaf
{
private:
void postprocess(std::string &res) const;
void preprocess(std::string &res) const;
public:
mapped_matrix_column(std::string const & scalartype, unsigned int id, node_info info);
};
@@ -229,7 +232,7 @@ public:
class mapped_matrix_repeat : public mapped_object, binary_leaf
{
private:
void postprocess(std::string &res) const;
void preprocess(std::string &res) const;
public:
mapped_matrix_repeat(std::string const & scalartype, unsigned int id, node_info info);
};
@@ -237,7 +240,7 @@ public:
class mapped_matrix_diag : public mapped_object, binary_leaf
{
private:
void postprocess(std::string &res) const;
void preprocess(std::string &res) const;
public:
mapped_matrix_diag(std::string const & scalartype, unsigned int id, node_info info);
};

View File

@@ -428,8 +428,14 @@ DEFINE_ELEMENT_UNARY_OPERATOR(OPERATOR_TANH_TYPE, tanh)
#undef DEFINE_ELEMENT_UNARY_OPERATOR
//---------------------------------------
///*--- Misc----*/
////---------------------------------------
atidlas::array_expression eye(std::size_t M, std::size_t N, atidlas::numeric_type dtype, cl::Context ctx)
{
return array_expression(value_scalar(1), value_scalar(0), op_element(OPERATOR_UNARY_TYPE_FAMILY, OPERATOR_VECTOR_DIAG_TYPE), ctx, dtype, size4(M, N));
}
inline size4 trans(size4 const & shape)
{ return size4(shape._2, shape._1);}

View File

@@ -1,6 +1,8 @@
#include <set>
#include <string>
#include <iostream>
#include "atidlas/backend/mapped_object.h"
#include "atidlas/backend/parse.h"
#include "atidlas/backend/stream.h"
@@ -12,30 +14,29 @@ namespace atidlas
{
void mapped_object::postprocess(std::string &) const { }
void mapped_object::preprocess(std::string &) const { }
void mapped_object::replace_offset(std::string & str, MorphBase const & morph)
void mapped_object::replace_macro(std::string & str, std::string const & macro, MorphBase const & morph)
{
size_t pos = 0;
while ((pos=str.find("$OFFSET", pos))!=std::string::npos)
while ((pos=str.find(macro, pos))!=std::string::npos)
{
std::string postprocessed;
size_t pos_po = str.find('{', pos);
size_t pos_pe = str.find('}', pos_po);
if (MorphBase2D const * p = dynamic_cast<MorphBase2D const *>(&morph))
{
size_t pos_comma = str.find(',', pos_po);
std::string i = str.substr(pos_po + 1, pos_comma - pos_po - 1);
std::string j = str.substr(pos_comma + 1, pos_pe - pos_comma - 1);
postprocessed = (*p)(i, j);
}
else if (MorphBase1D const * p = dynamic_cast<MorphBase1D const *>(&morph))
if(pos_comma > pos_pe)
{
std::string i = str.substr(pos_po + 1, pos_pe - pos_po - 1);
postprocessed = (*p)(i);
postprocessed = morph(i);
}
else
{
std::string i = str.substr(pos_po + 1, pos_comma - pos_po - 1);
std::string j = str.substr(pos_comma + 1, pos_pe - pos_comma - 1);
postprocessed = morph(i, j);
}
str.replace(pos, pos_pe + 1 - pos, postprocessed);
pos = pos_pe;
}
@@ -71,9 +72,9 @@ std::map<std::string, std::string> const & mapped_object::keywords() const
std::string mapped_object::process(std::string const & in) const
{
std::string res(in);
preprocess(res);
for (std::map<std::string,std::string>::const_iterator it = keywords_.begin(); it != keywords_.end(); ++it)
tools::find_and_replace(res, it->first, it->second);
postprocess(res);
return res;
}
@@ -137,6 +138,20 @@ mapped_scalar_reduction::mapped_scalar_reduction(std::string const & scalartype,
mapped_mreduction::mapped_mreduction(std::string const & scalartype, unsigned int id, node_info info) : mapped_reduction(scalartype, id, info, "mreduction") { }
//
void mapped_host_scalar::preprocess(std::string & str) const
{
struct Morph : public MorphBase
{
std::string operator()(std::string const &) const
{ return "#name"; }
std::string operator()(std::string const &, std::string const &) const
{ return "#name"; }
};
replace_macro(str, "$VALUE", Morph());
}
mapped_host_scalar::mapped_host_scalar(std::string const & scalartype, unsigned int id) : mapped_object(scalartype, id, "host_scalar"){ }
//
@@ -157,11 +172,37 @@ mapped_scalar::mapped_scalar(std::string const & scalartype, unsigned int id) :
mapped_buffer::mapped_buffer(std::string const & scalartype, unsigned int id, std::string const & type_key) : mapped_handle(scalartype, id, type_key){ }
//
void mapped_array::postprocess(std::string & str) const
void mapped_array::preprocess(std::string & str) const
{
struct Morph : public MorphBase2D
struct MorphValue : public MorphBase
{
Morph(std::string const & _ld, char _type) : ld(_ld), type(_type){ }
MorphValue(std::string const & _ld, char _type) : ld(_ld), type(_type){ }
std::string operator()(std::string const & i) const
{ return "#pointer[" + i + "]"; }
std::string operator()(std::string const & i, std::string const & j) const
{
if(type=='c')
return "#pointer["+i+"]";
else if(type=='r')
return "#pointer["+j+"]";
else
return "#pointer[(" + i + ") + (" + j + ") * " + ld + "]";
}
private:
std::string const & ld;
char type;
};
struct MorphOffset : public MorphBase
{
MorphOffset(std::string const & _ld, char _type) : ld(_ld), type(_type){ }
std::string operator()(std::string const & i) const
{ return i; }
std::string operator()(std::string const & i, std::string const & j) const
{
if(type=='c')
@@ -175,7 +216,9 @@ void mapped_array::postprocess(std::string & str) const
std::string const & ld;
char type;
};
replace_offset(str, Morph(ld_, type_));
replace_macro(str, "$VALUE", MorphValue(ld_, type_));
replace_macro(str, "$OFFSET", MorphOffset(ld_, type_));
}
mapped_array::mapped_array(std::string const & scalartype, unsigned int id, char type) : mapped_buffer(scalartype, id, "array"), type_(type)
@@ -189,18 +232,20 @@ mapped_array::mapped_array(std::string const & scalartype, unsigned int id, char
}
//
void mapped_vector_diag::postprocess(std::string &res) const
void mapped_vector_diag::preprocess(std::string &res) const
{
std::map<std::string, std::string> accessors;
tools::find_and_replace(res, "#diag_offset", atidlas::evaluate(RHS_NODE_TYPE, accessors, *info_.symbolic_expression, info_.root_idx, *info_.mapping));
accessors["array"] = res;
accessors["host_scalar"] = res;
res = atidlas::evaluate(LHS_NODE_TYPE, accessors, *info_.symbolic_expression, info_.root_idx, *info_.mapping);
std::cout << res << std::endl;
}
mapped_vector_diag::mapped_vector_diag(std::string const & scalartype, unsigned int id, node_info info) : mapped_object(scalartype, id, "vector_diag"), binary_leaf(info){ }
mapped_vector_diag::mapped_vector_diag(std::string const & scalartype, unsigned int id, node_info info) : mapped_object(scalartype, id, "vector_diag"), binary_leaf(info){}
//
void mapped_trans::postprocess(std::string &res) const
void mapped_trans::preprocess(std::string &res) const
{
std::map<std::string, std::string> accessors;
accessors["array"] = res;
@@ -210,7 +255,7 @@ void mapped_trans::postprocess(std::string &res) const
mapped_trans::mapped_trans(std::string const & scalartype, unsigned int id, node_info info) : mapped_object(scalartype, id, "matrix_trans"), binary_leaf(info){ }
//
void mapped_matrix_row::postprocess(std::string &res) const
void mapped_matrix_row::preprocess(std::string &res) const
{
std::map<std::string, std::string> accessors;
tools::find_and_replace(res, "#row", atidlas::evaluate(RHS_NODE_TYPE, accessors, *info_.symbolic_expression, info_.root_idx, *info_.mapping));
@@ -222,7 +267,7 @@ mapped_matrix_row::mapped_matrix_row(std::string const & scalartype, unsigned in
{ }
//
void mapped_matrix_column::postprocess(std::string &res) const
void mapped_matrix_column::preprocess(std::string &res) const
{
std::map<std::string, std::string> accessors;
tools::find_and_replace(res, "#column", atidlas::evaluate(RHS_NODE_TYPE, accessors, *info_.symbolic_expression, info_.root_idx, *info_.mapping));
@@ -234,19 +279,25 @@ mapped_matrix_column::mapped_matrix_column(std::string const & scalartype, unsig
{ }
//
void mapped_matrix_repeat::postprocess(std::string &res) const
void mapped_matrix_repeat::preprocess(std::string &res) const
{
std::map<std::string, std::string> accessors;
accessors["array"] = info_.mapping->at(std::make_pair(info_.root_idx,RHS_NODE_TYPE))->process(res);
mapped_object& args = *(info_.mapping->at(std::make_pair(info_.root_idx,RHS_NODE_TYPE)));
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"));
tools::find_and_replace(res, "#tuplearg4", args.process("#tuplearg4"));
accessors["array"] = res;
res = atidlas::evaluate(LHS_NODE_TYPE, accessors, *info_.symbolic_expression, info_.root_idx, *info_.mapping);
}
mapped_matrix_repeat::mapped_matrix_repeat(std::string const & scalartype, unsigned int id, node_info info) : mapped_object(scalartype, id, "matrix_repeat"), binary_leaf(info)
{ }
{
}
//
void mapped_matrix_diag::postprocess(std::string &res) const
void mapped_matrix_diag::preprocess(std::string &res) const
{
std::map<std::string, std::string> accessors;
tools::find_and_replace(res, "#diag_offset", atidlas::evaluate(RHS_NODE_TYPE, accessors, *info_.symbolic_expression, info_.root_idx, *info_.mapping));

View File

@@ -2,6 +2,8 @@
#include "atidlas/tools/make_map.hpp"
#include "atidlas/tools/make_vector.hpp"
#include <iostream>
namespace atidlas
{
@@ -33,7 +35,7 @@ std::string maxpy::generate_impl(unsigned int label, symbolic_expressions_contai
stream.inc_tab();
process(stream, PARENT_NODE_TYPE, tools::make_map<std::multimap<std::string, std::string> >("scalar", "#scalartype #namereg = *#pointer;")
("array", "#pointer += $OFFSET{#start1, #start2};"), symbolic_expressions, mappings);
("array", "#pointer = &$VALUE{#start1, #start2};"), symbolic_expressions, mappings);
fetching_loop_info(p_.fetching_policy, "M", stream, init0, upper_bound0, inc0, "get_global_id(0)", "get_global_size(0)");
stream << "for(unsigned int i = " << init0 << "; i < " << upper_bound0 << "; i += " << inc0 << ")" << std::endl;
@@ -44,9 +46,10 @@ std::string maxpy::generate_impl(unsigned int label, symbolic_expressions_contai
stream << "{" << std::endl;
stream.inc_tab();
process(stream, PARENT_NODE_TYPE, tools::make_map<std::multimap<std::string, std::string> >("array", append_width("#scalartype",simd_width) + " #namereg = #pointer[$OFFSET{i*#stride1,j*#stride2}];")
("vector_diag", "#scalartype #namereg = ((i + ((#diag_offset<0)?#diag_offset:0))!=(j-((#diag_offset>0)?#diag_offset:0)))?0:#pointer[min(i*#stride, j*#stride)];")
("matrix_repeat", "#scalartype #namereg = #pointer[$OFFSET{(i%#tuplearg0)*#stride1, (j%#tuplearg1)*#stride2}];"), symbolic_expressions, mappings);
process(stream, PARENT_NODE_TYPE, tools::make_map<std::multimap<std::string, std::string> >
("array", append_width("#scalartype",simd_width) + " #namereg = $VALUE{i*#stride1,j*#stride2};")
("vector_diag", "#scalartype #namereg = ((i + ((#diag_offset<0)?#diag_offset:0))!=(j-((#diag_offset>0)?#diag_offset:0)))?0:$VALUE{min(i*#stride1, j*#stride1)};")
("matrix_repeat", "#scalartype #namereg = $VALUE{(i%#tuplearg0)*#stride1, (j%#tuplearg1)*#stride2};"), symbolic_expressions, mappings);
evaluate(stream, PARENT_NODE_TYPE, tools::make_map<std::map<std::string, std::string> >("array", "#namereg")
("vector_diag", "#namereg")
@@ -54,7 +57,7 @@ std::string maxpy::generate_impl(unsigned int label, symbolic_expressions_contai
("scalar", "#namereg")
, symbolic_expressions, mappings);
process(stream, LHS_NODE_TYPE, tools::make_map<std::multimap<std::string, std::string> >("array", "#pointer[$OFFSET{i*#stride1,j*#stride2}] = #namereg;")
process(stream, LHS_NODE_TYPE, tools::make_map<std::multimap<std::string, std::string> >("array", "$VALUE{i*#stride1,j*#stride2} = #namereg;")
, symbolic_expressions, mappings);
stream.dec_tab();

View File

@@ -75,7 +75,7 @@ std::string mreduction::generate_impl(unsigned int label, symbolic_expressions_c
for (std::vector<mapped_mreduction*>::const_iterator it = exprs.begin(); it != exprs.end(); ++it)
{
std::multimap<std::string, std::string> accessors;
accessors.insert(std::make_pair("matrix_repeat", "#scalartype #namereg = #pointer[$OFFSET{(r%#tuplearg0)*#stride1, (c%#tuplearg1)*#stride2}];"));
accessors.insert(std::make_pair("matrix_repeat", "#scalartype #namereg = $VALUE{(r%#tuplearg0)*#stride1, (c%#tuplearg1)*#stride2};"));
if(reduction==REDUCE_COLUMNS)
accessors.insert(std::make_pair("array", data_type + " #namereg = " + vload(simd_width, "c*#stride1", "#pointer + r*#ld")+";"));
else
@@ -162,7 +162,6 @@ std::string mreduction::generate_impl(unsigned int label, symbolic_expressions_c
stream.dec_tab();
stream << "}" << std::endl;
return stream.str();
}

View File

@@ -30,7 +30,7 @@ numeric_type template_base::map_functor::get_numeric_type(atidlas::symbolic_expr
template<class T>
tools::shared_ptr<mapped_object> template_base::map_functor::binary_leaf(atidlas::symbolic_expression const * symbolic_expression, int_t root_idx, mapping_type const * mapping) const
{
return tools::shared_ptr<mapped_object>(new T(numeric_type_to_string(get_numeric_type(symbolic_expression,root_idx)), binder_.get(NULL), mapped_object::node_info(mapping, symbolic_expression, root_idx)));
return tools::shared_ptr<mapped_object>(new T(numeric_type_to_string(symbolic_expression->dtype()), binder_.get(NULL), mapped_object::node_info(mapping, symbolic_expression, root_idx)));
}
/** @brief Scalar mapping */

View File

@@ -50,8 +50,8 @@ std::vector<std::string> vaxpy::generate_impl(unsigned int label, symbolic_expre
stream.inc_tab();
process(stream, PARENT_NODE_TYPE,
tools::make_map<std::multimap<std::string, std::string> >("array", data_type + " #namereg = #pointer[i*#stride1];")
("matrix_row", "#scalartype #namereg = #pointer[$OFFSET{#row*#stride1, i*#stride2}];")
("matrix_column", "#scalartype #namereg = #pointer[$OFFSET{i*#stride1,#column*#stride2}];")
("matrix_row", "#scalartype #namereg = $VALUE{#row*#stride1, i*#stride2};")
("matrix_column", "#scalartype #namereg = $VALUE{i*#stride1,#column*#stride2};")
("matrix_diag", "#scalartype #namereg = #pointer[#diag_offset<0?$OFFSET{(i - #diag_offset)*#stride1, i*#stride2}:$OFFSET{i*#stride1, (i + #diag_offset)*#stride2}];")
, symbolic_expressions, mappings);
@@ -62,9 +62,9 @@ std::vector<std::string> vaxpy::generate_impl(unsigned int label, symbolic_expre
("scalar", "#namereg"), symbolic_expressions, mappings);
process(stream, LHS_NODE_TYPE, tools::make_map<std::multimap<std::string, std::string> >("array", "#pointer[i*#stride1] = #namereg;")
("matrix_row", "#pointer[$OFFSET{#row, i}] = #namereg;")
("matrix_column", "#pointer[$OFFSET{i, #column}] = #namereg;")
("matrix_diag", "#pointer[#diag_offset<0?$OFFSET{i - #diag_offset, i}:$OFFSET{i, i + #diag_offset}] = #namereg;")
("matrix_row", "$VALUE{#row, i} = #namereg;")
("matrix_column", "$VALUE{i, #column} = #namereg;")
("matrix_diag", "#diag_offset<0?$VALUE{(i - #diag_offset)*#stride1, i*#stride2}:$VALUE{i*#stride1, (i + #diag_offset)*#stride2} = #namereg;")
,symbolic_expressions, mappings);
stream.dec_tab();

View File

@@ -72,16 +72,17 @@ void test(T epsilon, simple_matrix_base<T> & cA, simple_matrix_base<T>& cB, simp
RUN_TEST("C = tan(A)", cC(i,j) = tan(cA(i,j)), C= tan(A))
RUN_TEST("C = tanh(A)", cC(i,j) = tanh(cA(i,j)), C= tanh(A))
RUN_TEST("z = x.*y", cC(i,j) = cA(i,j)*cB(i,j), C= A*B)
RUN_TEST("z = x./y", cC(i,j) = cA(i,j)/cB(i,j), C= A/B)
RUN_TEST("z = x==y", cC(i,j) = cA(i,j)==cB(i,j), C= A==B)
RUN_TEST("z = x>=y", cC(i,j) = cA(i,j)>=cB(i,j), C= A>=B)
RUN_TEST("z = x>y", cC(i,j) = cA(i,j)>cB(i,j), C= A>B)
RUN_TEST("z = x<=y", cC(i,j) = cA(i,j)<=cB(i,j), C= A<=B)
RUN_TEST("z = x<y", cC(i,j) = cA(i,j)<cB(i,j), C= A<B)
RUN_TEST("z = x!=y", cC(i,j) = cA(i,j)!=cB(i,j), C= A!=B)
RUN_TEST("z = pow(x,y)", cC(i,j) = pow(cA(i,j), cB(i,j)), C= pow(A,B))
RUN_TEST("C = A.*B", cC(i,j) = cA(i,j)*cB(i,j), C= A*B)
RUN_TEST("C = A./B", cC(i,j) = cA(i,j)/cB(i,j), C= A/B)
RUN_TEST("C = A==B", cC(i,j) = cA(i,j)==cB(i,j), C= A==B)
RUN_TEST("C = A>=B", cC(i,j) = cA(i,j)>=cB(i,j), C= A>=B)
RUN_TEST("C = A>B", cC(i,j) = cA(i,j)>cB(i,j), C= A>B)
RUN_TEST("C = A<=B", cC(i,j) = cA(i,j)<=cB(i,j), C= A<=B)
RUN_TEST("C = A<B", cC(i,j) = cA(i,j)<cB(i,j), C= A<B)
RUN_TEST("C = A!=B", cC(i,j) = cA(i,j)!=cB(i,j), C= A!=B)
RUN_TEST("C = pow(A,B)", cC(i,j) = pow(cA(i,j), cB(i,j)), C= pow(A,B))
RUN_TEST("C = eye(M, N)", cC(i,j) = i==j, C= eye(M, N, C.dtype()))
#undef RUN_TEST
if(failure_count > 0)