Some cleaning + outer product

This commit is contained in:
Philippe Tillet
2015-01-17 10:48:02 -05:00
parent 1d70396711
commit 0068560bc6
28 changed files with 317 additions and 255 deletions

View File

@@ -197,9 +197,9 @@ array_expression norm(array_expression const &, unsigned int order = 2);
#undef ATIDLAS_DECLARE_UNARY_OPERATOR
struct array_repeat_infos
struct repeat_infos
{
array_repeat_infos(size4 const & _sub, size4 const & _rep) : sub(_sub), rep(_rep){ }
repeat_infos(size4 const & _sub, size4 const & _rep) : sub(_sub), rep(_rep){ }
size4 sub;
size4 rep;
};

View File

@@ -31,6 +31,7 @@ class mapped_object
{
private:
virtual void preprocess(std::string &) const;
virtual void postprocess(std::string &) const;
protected:
struct MorphBase {
@@ -73,7 +74,7 @@ class binary_leaf
public:
binary_leaf(mapped_object::node_info info);
void process_recursive(kernel_generation_stream & stream, leaf_t leaf, std::multimap<std::string, std::string> const & accessors);
void process_recursive(kernel_generation_stream & stream, leaf_t leaf, std::map<std::string, std::string> const & accessors);
std::string evaluate_recursive(leaf_t leaf, std::map<std::string, std::string> const & accessors);
protected:
mapped_object::node_info info_;
@@ -197,18 +198,18 @@ private:
char type_;
};
class mapped_vector_diag : public mapped_object, public binary_leaf
class mapped_vdiag : public mapped_object, public binary_leaf
{
private:
void preprocess(std::string &res) const;
void postprocess(std::string &res) const;
public:
mapped_vector_diag(std::string const & scalartype, unsigned int id, node_info info);
mapped_vdiag(std::string const & scalartype, unsigned int id, node_info info);
};
class mapped_trans: public mapped_object, public binary_leaf
{
private:
void preprocess(std::string &res) const;
void postprocess(std::string &res) const;
public:
mapped_trans(std::string const & scalartype, unsigned int id, node_info info);
};
@@ -216,7 +217,7 @@ public:
class mapped_matrix_row : public mapped_object, binary_leaf
{
private:
void preprocess(std::string &res) const;
void postprocess(std::string &res) const;
public:
mapped_matrix_row(std::string const & scalartype, unsigned int id, node_info info);
};
@@ -224,26 +225,35 @@ public:
class mapped_matrix_column : public mapped_object, binary_leaf
{
private:
void preprocess(std::string &res) const;
void postprocess(std::string &res) const;
public:
mapped_matrix_column(std::string const & scalartype, unsigned int id, node_info info);
};
class mapped_matrix_repeat : public mapped_object, binary_leaf
class mapped_repeat : public mapped_object, binary_leaf
{
private:
void preprocess(std::string &res) const;
void postprocess(std::string &res) const;
public:
mapped_matrix_repeat(std::string const & scalartype, unsigned int id, node_info info);
mapped_repeat(std::string const & scalartype, unsigned int id, node_info info);
};
class mapped_matrix_diag : public mapped_object, binary_leaf
{
private:
void preprocess(std::string &res) const;
void postprocess(std::string &res) const;
public:
mapped_matrix_diag(std::string const & scalartype, unsigned int id, node_info info);
};
class mapped_outer : public mapped_object, binary_leaf
{
private:
void postprocess(std::string &res) const;
public:
mapped_outer(std::string const & scalartype, unsigned int id, node_info info);
};
}
#endif

View File

@@ -119,20 +119,20 @@ void evaluate(kernel_generation_stream & stream, leaf_t leaf, std::map<std::stri
class process_traversal : public traversal_functor
{
public:
process_traversal(std::multimap<std::string, std::string> const & accessors, kernel_generation_stream & stream,
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()(symbolic_expression const & symbolic_expression, int_t root_idx, leaf_t leaf) const;
private:
std::multimap<std::string, std::string> accessors_;
std::map<std::string, std::string> accessors_;
kernel_generation_stream & stream_;
mapping_type const & mapping_;
std::set<std::string> & already_processed_;
};
void process(kernel_generation_stream & stream, leaf_t leaf, std::multimap<std::string, std::string> const & accessors,
void process(kernel_generation_stream & stream, leaf_t leaf, std::map<std::string, std::string> const & accessors,
atidlas::symbolic_expression const & symbolic_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::multimap<std::string, std::string> const & accessors,
void process(kernel_generation_stream & stream, leaf_t leaf, std::map<std::string, std::string> const & accessors,
symbolic_expressions_container const & symbolic_expressions, std::vector<mapping_type> const & mappings);

View File

@@ -1,5 +1,5 @@
#ifndef ATIDLAS_TEMPLATES_TEMPLATE_BASE_
#define ATIDLAS_TEMPLATES_TEMPLATE_BASE_
#ifndef ATIDLAS_TEMPLATES_base_
#define ATIDLAS_TEMPLATES_base_
#include <list>
@@ -44,7 +44,7 @@ static const int TEMPLATE_LOCAL_FETCH_0_MUST_BE_NL_MULTIPLE = -16;
static const int TEMPLATE_LOCAL_FETCH_1_MUST_BE_KL_MULTIPLE = -17;
static const int TEMPLATE_LOCAL_FETCH_1_MUST_BE_ML_MULTIPLE = -18;
class template_base
class base
{
public:
struct parameters_type
@@ -81,7 +81,7 @@ protected:
/** @brief Creates a vector mapping */
tools::shared_ptr<mapped_object> create(array const &) const;
/** @brief Creates a tuple mapping */
tools::shared_ptr<mapped_object> create(array_repeat_infos const &) const;
tools::shared_ptr<mapped_object> create(repeat_infos const &) const;
/** @brief Creates a mapping */
tools::shared_ptr<mapped_object> create(lhs_rhs_element const &) const;
public:
@@ -102,7 +102,7 @@ protected:
set_arguments_functor(symbolic_binder & binder, unsigned int & current_arg, cl::Kernel & kernel);
void set_arguments(numeric_type dtype, values_holder const & scal) const;
void set_arguments(array const & ) const;
void set_arguments(array_repeat_infos const & i) const;
void set_arguments(repeat_infos const & i) const;
void set_arguments(lhs_rhs_element const & lhs_rhs) const;
void operator()(atidlas::symbolic_expression const & symbolic_expression, int_t root_idx, leaf_t leaf_t) const;
@@ -129,14 +129,14 @@ protected:
kernel_generation_stream & stream, std::vector<mapping_type> const & mappings,
size_t root_idx, leaf_t leaf);
static std::string neutral_element(op_element const & op);
static std::string generate_arguments(std::vector<mapping_type> const & mappings, std::multimap<std::string, std::string> const & accessors,
static std::string generate_arguments(std::vector<mapping_type> const & mappings, std::map<std::string, std::string> const & accessors,
symbolic_expressions_container const & symbolic_expressions);
static std::string generate_arguments(std::string const & data_type, std::vector<mapping_type> const & mappings,
symbolic_expressions_container const & symbolic_expressions);
static void fill_kernel_name(char * ptr, unsigned int label, const char * suffix);
static bool is_node_trans(symbolic_expression::container_type const & array, size_t root_idx, leaf_t leaf_type);
static std::string append_simd_suffix(std::string const & str, unsigned int i);
static bool is_offset_modifier(symbolic_expression_node const & node);
static bool is_strided(symbolic_expression_node const & node);
static int_t vector_size(symbolic_expression_node const & node);
static std::pair<int_t, int_t> matrix_size(symbolic_expression_node const & node);
static unsigned int align(unsigned int to_round, unsigned int base);
@@ -155,24 +155,24 @@ private:
virtual std::vector<std::string> generate_impl(unsigned int label, symbolic_expressions_container const & symbolic_expressions, std::vector<mapping_type> const & mapping) const = 0;
public:
template_base(binding_policy_t binding_policy);
base(binding_policy_t binding_policy);
virtual unsigned int lmem_usage(symbolic_expressions_container const &) const;
virtual unsigned int registers_usage(symbolic_expressions_container const &) const;
virtual std::vector<int_t> input_sizes(symbolic_expressions_container const & symbolic_expressions) = 0;
virtual ~template_base();
virtual ~base();
std::vector<std::string> generate(unsigned int label, symbolic_expressions_container const & symbolic_expressions, cl::Device const & device);
virtual int check_invalid(symbolic_expressions_container const & symbolic_expressions, cl::Device const & device) const = 0;
virtual void enqueue(cl::CommandQueue & queue,
std::vector<cl::lazy_compiler> & programs,
unsigned int label, symbolic_expressions_container const & symbolic_expressions) = 0;
virtual tools::shared_ptr<template_base> clone() const = 0;
virtual tools::shared_ptr<base> clone() const = 0;
private:
binding_policy_t binding_policy_;
};
template<class TemplateType, class ParametersType>
class template_base_impl : public template_base
class base_impl : public base
{
private:
virtual int check_invalid_impl(cl::Device const &, symbolic_expressions_container const &) const;
@@ -180,10 +180,10 @@ protected:
bool has_misaligned_offset(symbolic_expressions_container const & symbolic_expressions);
public:
typedef ParametersType parameters_type;
template_base_impl(parameters_type const & parameters, binding_policy_t binding_policy);
base_impl(parameters_type const & parameters, binding_policy_t binding_policy);
int_t local_size_0() const;
int_t local_size_1() const;
tools::shared_ptr<template_base> clone() const;
tools::shared_ptr<base> clone() const;
/** @brief returns whether or not the profile has undefined behavior on particular device */
int check_invalid(symbolic_expressions_container const & symbolic_expressions, cl::Device const & device) const;
protected:

View File

@@ -2,12 +2,12 @@
#define ATIDLAS_BACKEND_TEMPLATES_MAXPY_H
#include <vector>
#include "atidlas/backend/templates/template_base.h"
#include "atidlas/backend/templates/base.h"
namespace atidlas
{
class maxpy_parameters : public template_base::parameters_type
class maxpy_parameters : public base::parameters_type
{
public:
maxpy_parameters(unsigned int _simd_width,
@@ -20,7 +20,7 @@ public:
fetching_policy_type fetching_policy;
};
class maxpy : public template_base_impl<maxpy, maxpy_parameters>
class maxpy : public base_impl<maxpy, maxpy_parameters>
{
private:
int check_invalid_impl(cl::Device const &, symbolic_expressions_container const &) const;

View File

@@ -1,12 +1,12 @@
#ifndef ATIDLAS_BACKEND_TEMPLATES_MPRODUCT_H
#define ATIDLAS_BACKEND_TEMPLATES_MPRODUCT_H
#include "atidlas/backend/templates/template_base.h"
#include "atidlas/backend/templates/base.h"
namespace atidlas
{
struct mproduct_parameters : public template_base::parameters_type
struct mproduct_parameters : public base::parameters_type
{
mproduct_parameters(unsigned int simd_width
, int_t local_size_0, int_t KL, int_t local_size_1
@@ -30,7 +30,7 @@ struct mproduct_parameters : public template_base::parameters_type
int_t nL;
};
class mproduct : public template_base_impl<mproduct, mproduct_parameters>
class mproduct : public base_impl<mproduct, mproduct_parameters>
{
private:
unsigned int lmem_usage(symbolic_expressions_container const & symbolic_expressions) const;

View File

@@ -4,12 +4,12 @@
#include <vector>
#include "atidlas/symbolic/expression.h"
#include "atidlas/backend/templates/template_base.h"
#include "atidlas/backend/templates/base.h"
namespace atidlas
{
struct mreduction_parameters : public template_base::parameters_type
struct mreduction_parameters : public base::parameters_type
{
mreduction_parameters(unsigned int _simd_width,
unsigned int _local_size_0, unsigned int _local_size_1,
@@ -19,7 +19,7 @@ struct mreduction_parameters : public template_base::parameters_type
};
class mreduction : public template_base_impl<mreduction, mreduction_parameters>
class mreduction : public base_impl<mreduction, mreduction_parameters>
{
protected:
enum reduction_type

View File

@@ -1,12 +1,12 @@
#ifndef ATIDLAS_BACKEND_TEMPLATES_REDUCTION_H
#define ATIDLAS_BACKEND_TEMPLATES_REDUCTION_H
#include "atidlas/backend/templates/template_base.h"
#include "atidlas/backend/templates/base.h"
namespace atidlas
{
struct reduction_parameters : public template_base::parameters_type
struct reduction_parameters : public base::parameters_type
{
reduction_parameters(unsigned int _simd_width,
unsigned int _group_size, unsigned int _num_groups,
@@ -15,7 +15,7 @@ struct reduction_parameters : public template_base::parameters_type
fetching_policy_type fetching_policy;
};
class reduction : public template_base_impl<reduction, reduction_parameters>
class reduction : public base_impl<reduction, reduction_parameters>
{
private:
unsigned int lmem_usage(symbolic_expressions_container const & symbolic_expressions) const;

View File

@@ -1,12 +1,12 @@
#ifndef ATIDLAS_BACKEND_TEMPLATES_VAXPY_H
#define ATIDLAS_BACKEND_TEMPLATES_VAXPY_H
#include "atidlas/backend/templates/template_base.h"
#include "atidlas/backend/templates/base.h"
namespace atidlas
{
class vaxpy_parameters : public template_base::parameters_type
class vaxpy_parameters : public base::parameters_type
{
public:
vaxpy_parameters(unsigned int _simd_width, unsigned int _group_size, unsigned int _num_groups, fetching_policy_type _fetching_policy);
@@ -14,7 +14,7 @@ public:
fetching_policy_type fetching_policy;
};
class vaxpy : public template_base_impl<vaxpy, vaxpy_parameters>
class vaxpy : public base_impl<vaxpy, vaxpy_parameters>
{
private:
virtual int check_invalid_impl(cl::Device const &, symbolic_expressions_container const &) const;

View File

@@ -5,7 +5,7 @@
#include <vector>
#include <map>
#include "atidlas/backend/templates/template_base.h"
#include "atidlas/backend/templates/base.h"
#include "atidlas/cl/compare.hpp"
#include "atidlas/cl/lazy_compiler.h"
#include "atidlas/model/predictors/random_forest.h"
@@ -16,7 +16,7 @@ namespace atidlas
class model
{
typedef std::vector< tools::shared_ptr<template_base> > templates_container;
typedef std::vector< tools::shared_ptr<base> > templates_container;
private:
std::string define_extension(std::string const & extensions, std::string const & ext);
@@ -24,9 +24,9 @@ namespace atidlas
std::vector<cl::lazy_compiler>& init(symbolic_expressions_container const & symbolic_expressions, cl::Context const & context, cl::Device const & device, bool force_recompilation);
public:
model(predictors::random_forest const &, std::vector< tools::shared_ptr<template_base> > const &, cl::CommandQueue &);
model(std::vector< tools::shared_ptr<template_base> > const &, cl::CommandQueue &);
model(template_base const &, cl::CommandQueue &);
model(predictors::random_forest const &, std::vector< tools::shared_ptr<base> > const &, cl::CommandQueue &);
model(std::vector< tools::shared_ptr<base> > const &, cl::CommandQueue &);
model(base const &, cl::CommandQueue &);
void execute(symbolic_expressions_container const &, bool bypass_predictor = false, bool force_recompilation = false);
void tune(symbolic_expressions_container const &);

View File

@@ -12,7 +12,7 @@ namespace atidlas
{
class array;
class array_repeat_infos;
class repeat_infos;
/** @brief Optimization enum for grouping operations into unary or binary operations. Just for optimization of lookups. */
enum operation_node_type_family
@@ -99,11 +99,12 @@ enum operation_node_type
OPERATOR_ELEMENT_MAX_TYPE,
OPERATOR_ELEMENT_MIN_TYPE,
OPERATOR_OUTER_PROD_TYPE,
OPERATOR_MATRIX_DIAG_TYPE,
OPERATOR_MATRIX_ROW_TYPE,
OPERATOR_MATRIX_COLUMN_TYPE,
OPERATOR_MATRIX_REPEAT_TYPE,
OPERATOR_VECTOR_DIAG_TYPE,
OPERATOR_REPEAT_TYPE,
OPERATOR_VDIAG_TYPE,
OPERATOR_MATRIX_PRODUCT_NN_TYPE,
OPERATOR_MATRIX_PRODUCT_TN_TYPE,
@@ -129,7 +130,7 @@ enum symbolic_expression_node_subtype
INVALID_SUBTYPE = 0,
VALUE_SCALAR_TYPE,
DENSE_ARRAY_TYPE,
MATRIX_REPEAT_INFOS_TYPE
REPEAT_INFOS_TYPE
};
struct lhs_rhs_element
@@ -138,7 +139,7 @@ struct lhs_rhs_element
lhs_rhs_element(unsigned int _node_index);
lhs_rhs_element(atidlas::array const & x);
lhs_rhs_element(value_scalar const & x);
lhs_rhs_element(array_repeat_infos const & x);
lhs_rhs_element(repeat_infos const & x);
symbolic_expression_node_type_family type_family;
symbolic_expression_node_subtype subtype;
@@ -149,7 +150,7 @@ struct lhs_rhs_element
unsigned int node_index;
atidlas::array * array;
values_holder vscalar;
array_repeat_infos * repeat_infos;
atidlas::repeat_infos * tuple;
};
};

View File

@@ -7,10 +7,10 @@
namespace atidlas
{
inline std::string to_string(symbolic_expression_node_subtype const & f);
inline std::string to_string(lhs_rhs_element const & e);
inline std::ostream & operator<<(std::ostream & os, symbolic_expression_node const & s_node);
inline std::string to_string(atidlas::symbolic_expression const & s);
std::string to_string(symbolic_expression_node_subtype const & f);
std::string to_string(lhs_rhs_element const & e);
std::ostream & operator<<(std::ostream & os, symbolic_expression_node const & s_node);
std::string to_string(atidlas::symbolic_expression const & s);
}

View File

@@ -347,6 +347,7 @@ bool check_elementwise(U const & u, V const & v)
return max(u.shape())==1 || max(v.shape())==1 || u.shape()==v.shape();
}
#define DEFINE_ELEMENT_BINARY_OPERATOR(OP, OPNAME) \
array_expression OPNAME (array_expression const & x, array_expression const & y) \
{ assert(check_elementwise(x, y));\
@@ -392,6 +393,12 @@ DEFINE_ELEMENT_BINARY_OPERATOR(OPERATOR_ELEMENT_MAX_TYPE, max)
DEFINE_ELEMENT_BINARY_OPERATOR(OPERATOR_ELEMENT_MIN_TYPE, min)
DEFINE_ELEMENT_BINARY_OPERATOR(OPERATOR_ELEMENT_POW_TYPE, pow)
array_expression outer(array const & x, array const & y)
{
assert(x.nshape()==1 && y.nshape()==1);
return array_expression(x, y, op_element(OPERATOR_BINARY_TYPE_FAMILY, OPERATOR_OUTER_PROD_TYPE), x.context(), x.dtype(), size4(max(x.shape()), max(y.shape())) );
}
namespace detail
{
DEFINE_ELEMENT_BINARY_OPERATOR(OPERATOR_ASSIGN_TYPE, assign)
@@ -433,7 +440,7 @@ DEFINE_ELEMENT_UNARY_OPERATOR(OPERATOR_TANH_TYPE, tanh)
////---------------------------------------
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));
return array_expression(value_scalar(1), value_scalar(0), op_element(OPERATOR_UNARY_TYPE_FAMILY, OPERATOR_VDIAG_TYPE), ctx, dtype, size4(M, N));
}
inline size4 trans(size4 const & shape)
@@ -450,18 +457,18 @@ array_expression trans(array_expression const & x) \
array_expression repmat(array const & A, int_t const & rep1, int_t const & rep2)
{
static array_repeat_infos infos(A.shape(), size4(rep1, rep2));
infos = array_repeat_infos(A.shape(), size4(rep1, rep2));
static repeat_infos infos(A.shape(), size4(rep1, rep2));
infos = repeat_infos(A.shape(), size4(rep1, rep2));
size4 newshape = prod(infos.sub, infos.rep);
return array_expression(A, infos, op_element(OPERATOR_BINARY_TYPE_FAMILY, OPERATOR_MATRIX_REPEAT_TYPE), A.context(), A.dtype(), newshape);
return array_expression(A, infos, op_element(OPERATOR_BINARY_TYPE_FAMILY, OPERATOR_REPEAT_TYPE), A.context(), A.dtype(), newshape);
}
array_expression repmat(array_expression const & A, int_t const & rep1, int_t const & rep2)
{
static array_repeat_infos infos(A.shape(), size4(rep1, rep2));
infos = array_repeat_infos(A.shape(), size4(rep1, rep2));
static repeat_infos infos(A.shape(), size4(rep1, rep2));
infos = repeat_infos(A.shape(), size4(rep1, rep2));
size4 newshape = prod(infos.sub, infos.rep);
return array_expression(A, infos, op_element(OPERATOR_BINARY_TYPE_FAMILY, OPERATOR_MATRIX_REPEAT_TYPE), newshape);
return array_expression(A, infos, op_element(OPERATOR_BINARY_TYPE_FAMILY, OPERATOR_REPEAT_TYPE), newshape);
}
////---------------------------------------
@@ -631,6 +638,7 @@ DEFINE_DOT(array_expression, array_expression)
#undef DEFINE_DOT
#define DEFINE_NORM(TYPE)\
array_expression norm(TYPE const & x, unsigned int order)\
{\

View File

@@ -13,9 +13,10 @@
namespace atidlas
{
void mapped_object::preprocess(std::string &) const { }
void mapped_object::postprocess(std::string &) const { }
void mapped_object::replace_macro(std::string & str, std::string const & macro, MorphBase const & morph)
{
size_t pos = 0;
@@ -75,6 +76,7 @@ std::string mapped_object::process(std::string const & in) const
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;
}
@@ -88,7 +90,7 @@ std::string mapped_object::evaluate(std::map<std::string, std::string> const & a
binary_leaf::binary_leaf(mapped_object::node_info info) : info_(info){ }
void binary_leaf::process_recursive(kernel_generation_stream & stream, leaf_t leaf, std::multimap<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;
process(stream, leaf, accessors, *info_.symbolic_expression, info_.root_idx, *info_.mapping, already_fetched);
@@ -232,20 +234,19 @@ mapped_array::mapped_array(std::string const & scalartype, unsigned int id, char
}
//
void mapped_vector_diag::preprocess(std::string &res) const
void mapped_vdiag::postprocess(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_vdiag::mapped_vdiag(std::string const & scalartype, unsigned int id, node_info info) : mapped_object(scalartype, id, "vdiag"), binary_leaf(info){}
//
void mapped_trans::preprocess(std::string &res) const
void mapped_trans::postprocess(std::string &res) const
{
std::map<std::string, std::string> accessors;
accessors["array"] = res;
@@ -255,7 +256,7 @@ void mapped_trans::preprocess(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::preprocess(std::string &res) const
void mapped_matrix_row::postprocess(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));
@@ -267,7 +268,7 @@ mapped_matrix_row::mapped_matrix_row(std::string const & scalartype, unsigned in
{ }
//
void mapped_matrix_column::preprocess(std::string &res) const
void mapped_matrix_column::postprocess(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));
@@ -279,25 +280,24 @@ mapped_matrix_column::mapped_matrix_column(std::string const & scalartype, unsig
{ }
//
void mapped_matrix_repeat::preprocess(std::string &res) const
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"));
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)
{
}
mapped_repeat::mapped_repeat(std::string const & scalartype, unsigned int id, node_info info) : mapped_object(scalartype, id, "repeat"), binary_leaf(info)
{}
//
void mapped_matrix_diag::preprocess(std::string &res) const
void mapped_matrix_diag::postprocess(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));
@@ -308,6 +308,29 @@ void mapped_matrix_diag::preprocess(std::string &res) const
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)
{ }
//
void mapped_outer::postprocess(std::string &res) const
{
struct Morph : public MorphBase
{
Morph(leaf_t const & leaf, node_info const & i) : leaf_(leaf), i_(i){}
std::string operator()(std::string const & i) const
{
std::map<std::string, std::string> accessors;
accessors["array"] = "$VALUE{"+i+"}";
return atidlas::evaluate(leaf_, accessors, *i_.symbolic_expression, i_.root_idx, *i_.mapping);
}
std::string operator()(std::string const &, std::string const &) const{return "";}
private:
leaf_t leaf_;
node_info i_;
};
replace_macro(res, "$LVALUE", Morph(LHS_NODE_TYPE, info_));
replace_macro(res, "$RVALUE", Morph(RHS_NODE_TYPE, info_));
}
mapped_outer::mapped_outer(std::string const & scalartype, unsigned int id, node_info info) : mapped_object(scalartype, id, "outer"), binary_leaf(info)
{ }
}

View File

@@ -13,13 +13,14 @@ namespace detail
return op.type==OPERATOR_TRANS_TYPE
|| op.type_family==OPERATOR_MATRIX_PRODUCT_TYPE_FAMILY
|| op.type==OPERATOR_MATRIX_DIAG_TYPE
|| op.type==OPERATOR_VECTOR_DIAG_TYPE
|| op.type==OPERATOR_MATRIX_REPEAT_TYPE
|| op.type==OPERATOR_VDIAG_TYPE
|| op.type==OPERATOR_REPEAT_TYPE
|| op.type==OPERATOR_MATRIX_ROW_TYPE
|| op.type==OPERATOR_MATRIX_COLUMN_TYPE
|| op.type_family==OPERATOR_VECTOR_REDUCTION_TYPE_FAMILY
|| op.type_family==OPERATOR_ROWS_REDUCTION_TYPE_FAMILY
|| op.type_family==OPERATOR_COLUMNS_REDUCTION_TYPE_FAMILY;
|| op.type_family==OPERATOR_COLUMNS_REDUCTION_TYPE_FAMILY
|| op.type==OPERATOR_OUTER_PROD_TYPE;
}
bool is_scalar_reduction(symbolic_expression_node const & node)
@@ -211,7 +212,7 @@ const char * evaluate(operation_node_type type)
case OPERATOR_MATRIX_PRODUCT_TN_TYPE : return "prodTN";
case OPERATOR_MATRIX_PRODUCT_NT_TYPE : return "prodNT";
case OPERATOR_MATRIX_PRODUCT_TT_TYPE : return "prodTT";
case OPERATOR_VECTOR_DIAG_TYPE : return "vdiag";
case OPERATOR_VDIAG_TYPE : return "vdiag";
case OPERATOR_MATRIX_DIAG_TYPE : return "mdiag";
case OPERATOR_MATRIX_ROW_TYPE : return "row";
case OPERATOR_MATRIX_COLUMN_TYPE : return "col";
@@ -339,7 +340,7 @@ void evaluate(kernel_generation_stream & stream, leaf_t leaf, std::map<std::stri
stream << evaluate(leaf, accessors, **sit, (*sit)->root(), *mit) << ";" << std::endl;
}
process_traversal::process_traversal(std::multimap<std::string, std::string> const & accessors, kernel_generation_stream & stream,
process_traversal::process_traversal(std::map<std::string, std::string> const & accessors, kernel_generation_stream & stream,
mapping_type const & mapping, std::set<std::string> & already_processed) :
accessors_(accessors), stream_(stream), mapping_(mapping), already_processed_(already_processed)
{ }
@@ -351,19 +352,24 @@ void process_traversal::operator()(symbolic_expression const & /*symbolic_expres
{
mapped_object * obj = it->second.get();
std::string name = obj->name();
if(accessors_.find(name)!=accessors_.end() && already_processed_.insert(obj->process("#name")).second)
for(std::multimap<std::string, std::string>::const_iterator it = accessors_.lower_bound(name) ; it != accessors_.upper_bound(name) ; ++it)
stream_ << obj->process(it->second) << std::endl;
if(accessors_.find(name)!=accessors_.end() && already_processed_.insert(name).second)
for(std::map<std::string, std::string>::const_iterator itt = accessors_.lower_bound(name) ; itt != accessors_.upper_bound(name) ; ++itt)
{
stream_ << obj->process(itt->second) << std::endl;
}
std::string key = obj->type_key();
if(accessors_.find(key)!=accessors_.end() && already_processed_.insert(obj->process("#name")).second)
for(std::multimap<std::string, std::string>::const_iterator it = accessors_.lower_bound(key) ; it != accessors_.upper_bound(key) ; ++it)
stream_ << obj->process(it->second) << std::endl;
if(accessors_.find(key)!=accessors_.end() && already_processed_.insert(name).second)
for(std::map<std::string, std::string>::const_iterator itt = accessors_.lower_bound(key) ; itt != accessors_.upper_bound(key) ; ++itt)
{
stream_ << obj->process(itt->second) << std::endl;
}
}
}
void process(kernel_generation_stream & stream, leaf_t leaf, std::multimap<std::string, std::string> const & accessors,
void process(kernel_generation_stream & stream, leaf_t leaf, std::map<std::string, std::string> const & accessors,
atidlas::symbolic_expression const & symbolic_expression, size_t root_idx, mapping_type const & mapping, std::set<std::string> & already_processed)
{
process_traversal traversal_functor(accessors, stream, mapping, already_processed);
@@ -389,7 +395,7 @@ void process(kernel_generation_stream & stream, leaf_t leaf, std::multimap<std::
}
}
void process(kernel_generation_stream & stream, leaf_t leaf, std::multimap<std::string, std::string> const & accessors,
void process(kernel_generation_stream & stream, leaf_t leaf, std::map<std::string, std::string> const & accessors,
symbolic_expressions_container const & symbolic_expressions, std::vector<mapping_type> const & mappings)
{
symbolic_expressions_container::data_type::const_iterator sit;

View File

@@ -6,19 +6,20 @@
#include "atidlas/backend/templates/maxpy.h"
#include "atidlas/backend/templates/mreduction.h"
#include "atidlas/backend/templates/mproduct.h"
#include "atidlas/backend/templates/template_base.h"
#include "atidlas/backend/templates/base.h"
#include "atidlas/backend/parse.h"
#include "atidlas/exception/operation_not_supported.h"
#include "atidlas/tools/to_string.hpp"
#include "atidlas/tools/make_map.hpp"
#include "atidlas/symbolic/io.h"
namespace atidlas
{
template_base::parameters_type::parameters_type(unsigned int _simd_width, int_t _local_size_1, int_t _local_size_2, int_t _num_kernels) : simd_width(_simd_width), local_size_0(_local_size_1), local_size_1(_local_size_2), num_kernels(_num_kernels)
base::parameters_type::parameters_type(unsigned int _simd_width, int_t _local_size_1, int_t _local_size_2, int_t _num_kernels) : simd_width(_simd_width), local_size_0(_local_size_1), local_size_1(_local_size_2), num_kernels(_num_kernels)
{ }
numeric_type template_base::map_functor::get_numeric_type(atidlas::symbolic_expression const * symbolic_expression, int_t root_idx) const
numeric_type base::map_functor::get_numeric_type(atidlas::symbolic_expression const * symbolic_expression, int_t root_idx) const
{
symbolic_expression_node const * root_node = &symbolic_expression->tree()[root_idx];
while (root_node->lhs.dtype==INVALID_NUMERIC_TYPE)
@@ -28,20 +29,20 @@ numeric_type template_base::map_functor::get_numeric_type(atidlas::symbolic_expr
/** @brief Binary leaf */
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
tools::shared_ptr<mapped_object> 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(symbolic_expression->dtype()), binder_.get(NULL), mapped_object::node_info(mapping, symbolic_expression, root_idx)));
}
/** @brief Scalar mapping */
tools::shared_ptr<mapped_object> template_base::map_functor::create(numeric_type dtype, values_holder) const
tools::shared_ptr<mapped_object> base::map_functor::create(numeric_type dtype, values_holder) const
{
std::string strdtype = numeric_type_to_string(dtype);
return tools::shared_ptr<mapped_object>(new mapped_host_scalar(strdtype, binder_.get(NULL)));
}
/** @brief Vector mapping */
tools::shared_ptr<mapped_object> template_base::map_functor::create(array const & a) const
tools::shared_ptr<mapped_object> base::map_functor::create(array const & a) const
{
std::string dtype = numeric_type_to_string(a.dtype());
unsigned int id = binder_.get(&a.data());
@@ -61,17 +62,17 @@ tools::shared_ptr<mapped_object> template_base::map_functor::create(array const
}
}
tools::shared_ptr<mapped_object> template_base::map_functor::create(array_repeat_infos const &) const
tools::shared_ptr<mapped_object> base::map_functor::create(repeat_infos const &) const
{
//TODO: Make it less specific!
return tools::shared_ptr<mapped_object>(new mapped_tuple("int",binder_.get(NULL),4));
}
tools::shared_ptr<mapped_object> template_base::map_functor::create(lhs_rhs_element const & lhs_rhs) const
tools::shared_ptr<mapped_object> base::map_functor::create(lhs_rhs_element const & lhs_rhs) const
{
switch(lhs_rhs.type_family)
{
case INFOS_TYPE_FAMILY: return create(*lhs_rhs.repeat_infos);
case INFOS_TYPE_FAMILY: return create(*lhs_rhs.tuple);
case VALUE_TYPE_FAMILY: return create(lhs_rhs.dtype, lhs_rhs.vscalar);
case ARRAY_TYPE_FAMILY: return create(*lhs_rhs.array);
default: throw "";
@@ -79,10 +80,10 @@ tools::shared_ptr<mapped_object> template_base::map_functor::create(lhs_rhs_elem
}
template_base::map_functor::map_functor(symbolic_binder & binder, mapping_type & mapping) : binder_(binder), mapping_(mapping){ }
base::map_functor::map_functor(symbolic_binder & binder, mapping_type & mapping) : binder_(binder), mapping_(mapping){ }
/** @brief Traversal functor */
void template_base::map_functor::operator()(atidlas::symbolic_expression const & symbolic_expression, int_t root_idx, leaf_t leaf_t) const {
void base::map_functor::operator()(atidlas::symbolic_expression const & symbolic_expression, int_t root_idx, leaf_t leaf_t) const {
mapping_type::key_type key(root_idx, leaf_t);
symbolic_expression_node const & root_node = symbolic_expression.tree()[root_idx];
@@ -92,8 +93,8 @@ void template_base::map_functor::operator()(atidlas::symbolic_expression const &
mapping_.insert(mapping_type::value_type(key, create(root_node.rhs)));
else if ( leaf_t== PARENT_NODE_TYPE)
{
if (root_node.op.type==OPERATOR_VECTOR_DIAG_TYPE)
mapping_.insert(mapping_type::value_type(key, binary_leaf<mapped_vector_diag>(&symbolic_expression, root_idx, &mapping_)));
if (root_node.op.type==OPERATOR_VDIAG_TYPE)
mapping_.insert(mapping_type::value_type(key, binary_leaf<mapped_vdiag>(&symbolic_expression, root_idx, &mapping_)));
else if (root_node.op.type==OPERATOR_MATRIX_DIAG_TYPE)
mapping_.insert(mapping_type::value_type(key, binary_leaf<mapped_matrix_diag>(&symbolic_expression, root_idx, &mapping_)));
else if (root_node.op.type==OPERATOR_MATRIX_ROW_TYPE)
@@ -108,16 +109,17 @@ void template_base::map_functor::operator()(atidlas::symbolic_expression const &
mapping_.insert(mapping_type::value_type(key, binary_leaf<mapped_mproduct>(&symbolic_expression, root_idx, &mapping_)));
else if (root_node.op.type == OPERATOR_TRANS_TYPE)
mapping_.insert(mapping_type::value_type(key, binary_leaf<mapped_trans>(&symbolic_expression, root_idx, &mapping_)));
else if (root_node.op.type == OPERATOR_MATRIX_REPEAT_TYPE){
mapping_.insert(mapping_type::value_type(key, binary_leaf<mapped_matrix_repeat>(&symbolic_expression, root_idx, &mapping_)));
}
else if (root_node.op.type == OPERATOR_REPEAT_TYPE)
mapping_.insert(mapping_type::value_type(key, binary_leaf<mapped_repeat>(&symbolic_expression, root_idx, &mapping_)));
else if (root_node.op.type == OPERATOR_OUTER_PROD_TYPE)
mapping_.insert(mapping_type::value_type(key, binary_leaf<mapped_outer>(&symbolic_expression, root_idx, &mapping_)));
}
}
template_base::set_arguments_functor::set_arguments_functor(symbolic_binder & binder, unsigned int & current_arg, cl::Kernel & kernel) :
base::set_arguments_functor::set_arguments_functor(symbolic_binder & binder, unsigned int & current_arg, cl::Kernel & kernel) :
binder_(binder), current_arg_(current_arg), kernel_(kernel){ }
void template_base::set_arguments_functor::set_arguments(numeric_type dtype, values_holder const & scal) const
void base::set_arguments_functor::set_arguments(numeric_type dtype, values_holder const & scal) const
{
switch(dtype)
{
@@ -136,7 +138,7 @@ void template_base::set_arguments_functor::set_arguments(numeric_type dtype, val
}
/** @brief Vector mapping */
void template_base::set_arguments_functor::set_arguments(array const & x) const
void base::set_arguments_functor::set_arguments(array const & x) const
{
bool is_bound = binder_.bind(&x.data());
if (is_bound)
@@ -159,7 +161,7 @@ void template_base::set_arguments_functor::set_arguments(array const & x) const
}
}
void template_base::set_arguments_functor::set_arguments(array_repeat_infos const & i) const
void base::set_arguments_functor::set_arguments(repeat_infos const & i) const
{
kernel_.setArg(current_arg_++, cl_uint(i.sub._1));
kernel_.setArg(current_arg_++, cl_uint(i.sub._2));
@@ -167,19 +169,19 @@ void template_base::set_arguments_functor::set_arguments(array_repeat_infos cons
kernel_.setArg(current_arg_++, cl_uint(i.rep._2));
}
void template_base::set_arguments_functor::set_arguments(lhs_rhs_element const & lhs_rhs) const
void base::set_arguments_functor::set_arguments(lhs_rhs_element const & lhs_rhs) const
{
switch(lhs_rhs.type_family)
{
case VALUE_TYPE_FAMILY: return set_arguments(lhs_rhs.dtype, lhs_rhs.vscalar);
case ARRAY_TYPE_FAMILY: return set_arguments(*lhs_rhs.array);
case INFOS_TYPE_FAMILY: return set_arguments(*lhs_rhs.repeat_infos);
case INFOS_TYPE_FAMILY: return set_arguments(*lhs_rhs.tuple);
default: throw "oh noez";
}
}
/** @brief Traversal functor: */
void template_base::set_arguments_functor::operator()(atidlas::symbolic_expression const & symbolic_expression, int_t root_idx, leaf_t leaf_t) const
void base::set_arguments_functor::operator()(atidlas::symbolic_expression const & symbolic_expression, int_t root_idx, leaf_t leaf_t) const
{
symbolic_expression_node const & root_node = symbolic_expression.tree()[root_idx];
if (leaf_t==LHS_NODE_TYPE && root_node.lhs.type_family != COMPOSITE_OPERATOR_FAMILY)
@@ -188,7 +190,7 @@ void template_base::set_arguments_functor::operator()(atidlas::symbolic_expressi
set_arguments(root_node.rhs);
}
void template_base::compute_reduction(kernel_generation_stream & os, std::string acc, std::string cur, op_element const & op)
void base::compute_reduction(kernel_generation_stream & os, std::string acc, std::string cur, op_element const & op)
{
if (detail::is_elementwise_function(op))
os << acc << "=" << evaluate(op.type) << "(" << acc << "," << cur << ");" << std::endl;
@@ -196,7 +198,7 @@ void template_base::compute_reduction(kernel_generation_stream & os, std::string
os << acc << "= (" << acc << ")" << evaluate(op.type) << "(" << cur << ");" << std::endl;
}
void template_base::compute_index_reduction(kernel_generation_stream & os, std::string acc, std::string cur, std::string const & acc_value, std::string const & cur_value, op_element const & op)
void base::compute_index_reduction(kernel_generation_stream & os, std::string acc, std::string cur, std::string const & acc_value, std::string const & cur_value, op_element const & op)
{
// os << acc << " = " << cur_value << ">" << acc_value << "?" << cur << ":" << acc << ";" << std::endl;
os << acc << "= select(" << acc << "," << cur << "," << cur_value << ">" << acc_value << ");" << std::endl;
@@ -208,7 +210,7 @@ void template_base::compute_index_reduction(kernel_generation_stream & os, std::
os << "(" << acc_value << "," << cur_value << ");"<< std::endl;
}
void template_base::process_all(std::string const & type_key, std::string const & str,
void base::process_all(std::string const & type_key, std::string const & str,
kernel_generation_stream & stream, std::vector<mapping_type> const & mappings)
{
for (std::vector<mapping_type>::const_iterator mit = mappings.begin(); mit != mappings.end(); ++mit)
@@ -218,7 +220,7 @@ void template_base::process_all(std::string const & type_key, std::string const
}
void template_base::template_base::process_all_at(std::string const & type_key, std::string const & str,
void base::base::process_all_at(std::string const & type_key, std::string const & str,
kernel_generation_stream & stream, std::vector<mapping_type> const & mappings,
size_t root_idx, leaf_t leaf)
{
@@ -230,7 +232,7 @@ void template_base::template_base::process_all_at(std::string const & type_key,
}
}
std::string template_base::neutral_element(op_element const & op)
std::string base::neutral_element(op_element const & op)
{
switch (op.type)
{
@@ -250,7 +252,7 @@ std::string template_base::neutral_element(op_element const & op)
}
}
std::string template_base::generate_arguments(std::vector<mapping_type> const & mappings, std::multimap<std::string, std::string> const & accessors, symbolic_expressions_container const & symbolic_expressions)
std::string base::generate_arguments(std::vector<mapping_type> const & mappings, std::map<std::string, std::string> const & accessors, symbolic_expressions_container const & symbolic_expressions)
{
kernel_generation_stream stream;
process(stream, PARENT_NODE_TYPE, accessors, symbolic_expressions, mappings);
@@ -259,9 +261,9 @@ std::string template_base::generate_arguments(std::vector<mapping_type> const &
return res;
}
std::string template_base::generate_arguments(std::string const & data_type, std::vector<mapping_type> const & mappings, symbolic_expressions_container const & symbolic_expressions)
std::string base::generate_arguments(std::string const & data_type, std::vector<mapping_type> const & mappings, symbolic_expressions_container const & symbolic_expressions)
{
return generate_arguments(mappings, tools::make_map<std::multimap<std::string, std::string> >("scalar", "__global #scalartype* #pointer,")
return generate_arguments(mappings, tools::make_map<std::map<std::string, std::string> >("scalar", "__global #scalartype* #pointer,")
("host_scalar", "#scalartype #name,")
("array", "__global " + data_type + "* #pointer, uint #ld, uint #start1, uint #start2, uint #stride1, uint #stride2,")
("tuple4", "#scalartype #name0, #scalartype #name1, #scalartype #name2, #scalartype #name3,"), symbolic_expressions);
@@ -269,14 +271,14 @@ std::string template_base::generate_arguments(std::string const & data_type, std
void template_base::set_arguments(symbolic_expressions_container const & symbolic_expressions, cl::Kernel & kernel, unsigned int & current_arg)
void base::set_arguments(symbolic_expressions_container const & symbolic_expressions, cl::Kernel & kernel, unsigned int & current_arg)
{
tools::shared_ptr<symbolic_binder> binder = make_binder();
for (symbolic_expressions_container::data_type::const_iterator itt = symbolic_expressions.data().begin(); itt != symbolic_expressions.data().end(); ++itt)
traverse(**itt, (*itt)->root(), set_arguments_functor(*binder, current_arg, kernel), true);
}
void template_base::fill_kernel_name(char * ptr, unsigned int label, const char * suffix)
void base::fill_kernel_name(char * ptr, unsigned int label, const char * suffix)
{
*ptr++='k';
if (label==0)
@@ -292,18 +294,18 @@ void template_base::fill_kernel_name(char * ptr, unsigned int label, const char
*ptr++='\0';
}
template_base::invalid_exception::invalid_exception() : message_() {}
base::invalid_exception::invalid_exception() : message_() {}
template_base::invalid_exception::invalid_exception(std::string message) :
base::invalid_exception::invalid_exception(std::string message) :
message_("ViennaCL: Internal error: The generator cannot apply the given template to the given symbolic_expression: " + message + "\n"
"If you are using a builtin template, please report on viennacl-support@lists.sourceforge.net! We will provide a fix as soon as possible\n"
"If you are using your own template, please try using other parameters") {}
const char* template_base::invalid_exception::what() const throw() { return message_.c_str(); }
const char* base::invalid_exception::what() const throw() { return message_.c_str(); }
template_base::invalid_exception::~invalid_exception() throw() {}
base::invalid_exception::~invalid_exception() throw() {}
void template_base::fetching_loop_info(fetching_policy_type policy, std::string const & bound, kernel_generation_stream & stream, std::string & init, std::string & upper_bound, std::string & inc, std::string const & domain_id, std::string const & domain_size)
void base::fetching_loop_info(fetching_policy_type policy, std::string const & bound, kernel_generation_stream & stream, std::string & init, std::string & upper_bound, std::string & inc, std::string const & domain_id, std::string const & domain_size)
{
if (policy==FETCH_FROM_GLOBAL_STRIDED)
{
@@ -326,7 +328,7 @@ void template_base::fetching_loop_info(fetching_policy_type policy, std::string
}
}
bool template_base::is_node_trans(symbolic_expression::container_type const & array, size_t root_idx, leaf_t leaf_type)
bool base::is_node_trans(symbolic_expression::container_type const & array, size_t root_idx, leaf_t leaf_type)
{
bool res = false;
lhs_rhs_element symbolic_expression_node::*ptr;
@@ -344,7 +346,7 @@ bool template_base::is_node_trans(symbolic_expression::container_type const & ar
return res;
}
std::string template_base::append_simd_suffix(std::string const & str, unsigned int i)
std::string base::append_simd_suffix(std::string const & str, unsigned int i)
{
assert(i < 16);
char suffixes[] = {'0','1','2','3','4','5','6','7','8','9',
@@ -352,15 +354,16 @@ std::string template_base::append_simd_suffix(std::string const & str, unsigned
return str + tools::to_string(suffixes[i]);
}
bool template_base::is_offset_modifier(symbolic_expression_node const & node)
bool base::is_strided(symbolic_expression_node const & node)
{
return node.op.type==OPERATOR_VECTOR_DIAG_TYPE
return node.op.type==OPERATOR_VDIAG_TYPE
|| node.op.type==OPERATOR_MATRIX_DIAG_TYPE
|| node.op.type==OPERATOR_MATRIX_ROW_TYPE
|| node.op.type==OPERATOR_MATRIX_COLUMN_TYPE;
|| node.op.type==OPERATOR_MATRIX_COLUMN_TYPE
|| node.op.type==OPERATOR_OUTER_PROD_TYPE;
}
bool template_base::has_strided_access(symbolic_expressions_container const & symbolic_expressions) const
bool base::has_strided_access(symbolic_expressions_container const & symbolic_expressions) const
{
for (symbolic_expressions_container::data_type::const_iterator it = symbolic_expressions.data().begin(); it != symbolic_expressions.data().end(); ++it)
{
@@ -368,13 +371,13 @@ bool template_base::has_strided_access(symbolic_expressions_container const & sy
for (std::vector<lhs_rhs_element>::iterator itt = arrays.begin(); itt != arrays.end(); ++itt)
if(max(itt->array->stride())>1)
return true;
if(filter_nodes(&is_offset_modifier, **it, true).empty()==false)
if(filter_nodes(&is_strided, **it, true).empty()==false)
return true;
}
return false;
}
int_t template_base::vector_size(symbolic_expression_node const & node)
int_t base::vector_size(symbolic_expression_node const & node)
{
using namespace tools;
if (node.op.type==OPERATOR_MATRIX_DIAG_TYPE)
@@ -388,20 +391,20 @@ int_t template_base::vector_size(symbolic_expression_node const & node)
}
std::pair<int_t, int_t> template_base::matrix_size(symbolic_expression_node const & node)
std::pair<int_t, int_t> base::matrix_size(symbolic_expression_node const & node)
{
if (node.op.type==OPERATOR_VECTOR_DIAG_TYPE)
if (node.op.type==OPERATOR_VDIAG_TYPE)
{
int_t size = node.lhs.array->shape()._1;
return std::make_pair(size,size);
}
else if(node.op.type==OPERATOR_MATRIX_REPEAT_TYPE)
return std::make_pair(node.lhs.array->shape()._1*node.rhs.repeat_infos->rep._1, node.lhs.array->shape()._2*node.rhs.repeat_infos->rep._2);
else if(node.op.type==OPERATOR_REPEAT_TYPE)
return std::make_pair(node.lhs.array->shape()._1*node.rhs.tuple->rep._1, node.lhs.array->shape()._2*node.rhs.tuple->rep._2);
else
return std::make_pair(node.lhs.array->shape()._1,node.lhs.array->shape()._2);
}
void template_base::element_wise_loop_1D(kernel_generation_stream & stream, loop_body_base const & loop_body,
void base::element_wise_loop_1D(kernel_generation_stream & stream, loop_body_base const & loop_body,
fetching_policy_type fetch, unsigned int simd_width, std::string const & i, std::string const & bound, std::string const & domain_id, std::string const & domain_size)
{
std::string strwidth = tools::to_string(simd_width);
@@ -427,14 +430,14 @@ void template_base::element_wise_loop_1D(kernel_generation_stream & stream, loop
}
}
bool template_base::is_reduction(symbolic_expression_node const & node)
bool base::is_reduction(symbolic_expression_node const & node)
{
return node.op.type_family==OPERATOR_VECTOR_REDUCTION_TYPE_FAMILY
|| node.op.type_family==OPERATOR_COLUMNS_REDUCTION_TYPE_FAMILY
|| node.op.type_family==OPERATOR_ROWS_REDUCTION_TYPE_FAMILY;
}
bool template_base::is_index_reduction(op_element const & op)
bool base::is_index_reduction(op_element const & op)
{
return op.type==OPERATOR_ELEMENT_ARGFMAX_TYPE
|| op.type==OPERATOR_ELEMENT_ARGMAX_TYPE
@@ -442,7 +445,7 @@ bool template_base::is_index_reduction(op_element const & op)
|| op.type==OPERATOR_ELEMENT_ARGMIN_TYPE;
}
std::string template_base::vstore(unsigned int simd_width, std::string const & value, std::string const & offset, std::string const & ptr)
std::string base::vstore(unsigned int simd_width, std::string const & value, std::string const & offset, std::string const & ptr)
{
if (simd_width==1)
return "(" + ptr + ")[" + offset + "] = " + value;
@@ -450,7 +453,7 @@ std::string template_base::vstore(unsigned int simd_width, std::string const & v
return append_width("vstore", simd_width) + "(" + value + ", " + offset + ", " + ptr + ")";
}
std::string template_base::vload(unsigned int simd_width, std::string const & offset, std::string const & ptr)
std::string base::vload(unsigned int simd_width, std::string const & offset, std::string const & ptr)
{
if (simd_width==1)
return "(" + ptr + ")[" + offset + "]";
@@ -458,21 +461,21 @@ std::string template_base::vload(unsigned int simd_width, std::string const & of
return append_width("vload", simd_width) + "(" + offset + ", " + ptr + ")";
}
std::string template_base::append_width(std::string const & str, unsigned int width)
std::string base::append_width(std::string const & str, unsigned int width)
{
if (width==1)
return str;
return str + tools::to_string(width);
}
unsigned int template_base::align(unsigned int to_round, unsigned int base)
unsigned int base::align(unsigned int to_round, unsigned int base)
{
if (to_round % base == 0)
return to_round;
return (to_round + base - 1)/base * base;
}
inline tools::shared_ptr<symbolic_binder> template_base::make_binder()
inline tools::shared_ptr<symbolic_binder> base::make_binder()
{
if (binding_policy_==BIND_TO_HANDLE)
return tools::shared_ptr<symbolic_binder>(new bind_to_handle());
@@ -481,19 +484,19 @@ inline tools::shared_ptr<symbolic_binder> template_base::make_binder()
}
template_base::template_base(binding_policy_t binding_policy) : binding_policy_(binding_policy)
base::base(binding_policy_t binding_policy) : binding_policy_(binding_policy)
{}
unsigned int template_base::lmem_usage(symbolic_expressions_container const &) const
unsigned int base::lmem_usage(symbolic_expressions_container const &) const
{ return 0; }
unsigned int template_base::registers_usage(symbolic_expressions_container const &) const
unsigned int base::registers_usage(symbolic_expressions_container const &) const
{ return 0; }
template_base::~template_base()
base::~base()
{ }
std::vector<std::string> template_base::generate(unsigned int label, symbolic_expressions_container const & symbolic_expressions, cl::Device const & device)
std::vector<std::string> base::generate(unsigned int label, symbolic_expressions_container const & symbolic_expressions, cl::Device const & device)
{
symbolic_expressions_container::data_type::const_iterator sit;
std::vector<mapping_type>::iterator mit;
@@ -511,11 +514,11 @@ std::vector<std::string> template_base::generate(unsigned int label, symbolic_ex
}
template<class TType, class PType>
int template_base_impl<TType, PType>::check_invalid_impl(cl::Device const &, symbolic_expressions_container const &) const
int base_impl<TType, PType>::check_invalid_impl(cl::Device const &, symbolic_expressions_container const &) const
{ return TEMPLATE_VALID; }
template<class TType, class PType>
bool template_base_impl<TType, PType>::has_misaligned_offset(symbolic_expressions_container const & symbolic_expressions)
bool base_impl<TType, PType>::has_misaligned_offset(symbolic_expressions_container const & symbolic_expressions)
{
for (symbolic_expressions_container::data_type::const_iterator it = symbolic_expressions.data().begin(); it != symbolic_expressions.data().end(); ++it)
{
@@ -528,23 +531,23 @@ bool template_base_impl<TType, PType>::has_misaligned_offset(symbolic_expression
}
template<class TType, class PType>
template_base_impl<TType, PType>::template_base_impl(parameters_type const & parameters, binding_policy_t binding_policy) : template_base(binding_policy), p_(parameters)
base_impl<TType, PType>::base_impl(parameters_type const & parameters, binding_policy_t binding_policy) : base(binding_policy), p_(parameters)
{ }
template<class TType, class PType>
int_t template_base_impl<TType, PType>::local_size_0() const
int_t base_impl<TType, PType>::local_size_0() const
{ return p_.local_size_0; }
template<class TType, class PType>
int_t template_base_impl<TType, PType>::local_size_1() const
int_t base_impl<TType, PType>::local_size_1() const
{ return p_.local_size_1; }
template<class TType, class PType>
tools::shared_ptr<template_base> template_base_impl<TType, PType>::clone() const
{ return tools::shared_ptr<template_base>(new TType(*dynamic_cast<TType const *>(this))); }
tools::shared_ptr<base> base_impl<TType, PType>::clone() const
{ return tools::shared_ptr<base>(new TType(*dynamic_cast<TType const *>(this))); }
template<class TType, class PType>
int template_base_impl<TType, PType>::check_invalid(symbolic_expressions_container const & symbolic_expressions, cl::Device const & device) const
int base_impl<TType, PType>::check_invalid(symbolic_expressions_container const & symbolic_expressions, cl::Device const & device) const
{
//Query device informations
size_t lmem_available = device.getInfo<CL_DEVICE_LOCAL_MEM_SIZE>();
@@ -585,10 +588,10 @@ int template_base_impl<TType, PType>::check_invalid(symbolic_expressions_contain
return check_invalid_impl(device, symbolic_expressions);
}
template class template_base_impl<vaxpy, vaxpy_parameters>;
template class template_base_impl<reduction, reduction_parameters>;
template class template_base_impl<maxpy, maxpy_parameters>;
template class template_base_impl<mreduction, mreduction_parameters>;
template class template_base_impl<mproduct, mproduct_parameters>;
template class base_impl<vaxpy, vaxpy_parameters>;
template class base_impl<reduction, reduction_parameters>;
template class base_impl<maxpy, maxpy_parameters>;
template class base_impl<mreduction, mreduction_parameters>;
template class base_impl<mproduct, mproduct_parameters>;
}

View File

@@ -10,7 +10,7 @@ namespace atidlas
maxpy_parameters::maxpy_parameters(unsigned int _simd_width,
unsigned int _local_size_0, unsigned int _local_size_1,
unsigned int _num_groups_0, unsigned int _num_groups_1,
fetching_policy_type _fetching_policy) : template_base::parameters_type(_simd_width, _local_size_0, _local_size_1, 1), num_groups_0(_num_groups_0), num_groups_1(_num_groups_1), fetching_policy(_fetching_policy){ }
fetching_policy_type _fetching_policy) : base::parameters_type(_simd_width, _local_size_0, _local_size_1, 1), num_groups_0(_num_groups_0), num_groups_1(_num_groups_1), fetching_policy(_fetching_policy){ }
@@ -34,7 +34,7 @@ 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> >("scalar", "#scalartype #namereg = *#pointer;")
process(stream, PARENT_NODE_TYPE, tools::make_map<std::map<std::string, std::string> >("scalar", "#scalartype #namereg = *#pointer;")
("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)");
@@ -46,18 +46,22 @@ 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> >
process(stream, PARENT_NODE_TYPE, tools::make_map<std::map<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")
("matrix_repeat", "#namereg")
("scalar", "#namereg")
("vdiag", "#scalartype #namereg = ((i + ((#diag_offset<0)?#diag_offset:0))!=(j-((#diag_offset>0)?#diag_offset:0)))?0:$VALUE{min(i*#stride1, j*#stride1)};")
("repeat", "#scalartype #namereg = $VALUE{(i%#tuplearg0)*#stride1, (j%#tuplearg1)*#stride2};")
("outer", "#scalartype #namereg = ($LVALUE{i*#stride1})*($RVALUE{j*#stride1});")
, symbolic_expressions, mappings);
process(stream, LHS_NODE_TYPE, tools::make_map<std::multimap<std::string, std::string> >("array", "$VALUE{i*#stride1,j*#stride2} = #namereg;")
evaluate(stream, PARENT_NODE_TYPE, tools::make_map<std::map<std::string, std::string> >
("array", "#namereg")
("vdiag", "#namereg")
("repeat", "#namereg")
("scalar", "#namereg")
("outer", "#namereg")
, symbolic_expressions, mappings);
process(stream, LHS_NODE_TYPE, tools::make_map<std::map<std::string, std::string> >("array", "$VALUE{i*#stride1,j*#stride2} = #namereg;")
, symbolic_expressions, mappings);
stream.dec_tab();
@@ -81,12 +85,12 @@ std::vector<std::string> maxpy::generate_impl(unsigned int label, symbolic_expre
}
maxpy::maxpy(parameters_type const & parameters, binding_policy_t binding_policy) :
template_base_impl<maxpy, maxpy_parameters>(parameters, binding_policy){ }
base_impl<maxpy, maxpy_parameters>(parameters, binding_policy){ }
maxpy::maxpy(unsigned int simd, unsigned int ls1, unsigned int ls2,
unsigned int ng1, unsigned int ng2, fetching_policy_type fetch,
binding_policy_t bind):
template_base_impl<maxpy, maxpy_parameters>(maxpy_parameters(simd, ls1, ls2, ng1, ng2, fetch), bind)
base_impl<maxpy, maxpy_parameters>(maxpy_parameters(simd, ls1, ls2, ng1, ng2, fetch), bind)
{}
std::vector<int_t> maxpy::input_sizes(symbolic_expressions_container const & symbolic_expressions)
@@ -115,6 +119,6 @@ void maxpy::enqueue(cl::CommandQueue & queue,
queue.enqueueNDRangeKernel(kernel, cl::NullRange, grange, lrange);
}
template class template_base_impl<maxpy, maxpy_parameters>;
template class base_impl<maxpy, maxpy_parameters>;
}

View File

@@ -11,7 +11,7 @@ mproduct_parameters::mproduct_parameters(unsigned int simd_width
, int_t local_size_0, int_t KL, int_t local_size_1
, int_t ms, int_t ks, int_t ns
, fetching_policy_type A_fetching_policy, fetching_policy_type B_fetching_policy
, int_t local_fetch_0, int_t local_fetch_1): template_base::parameters_type(simd_width, local_size_0, local_size_1, 1),
, int_t local_fetch_0, int_t local_fetch_1): base::parameters_type(simd_width, local_size_0, local_size_1, 1),
kL(KL), mS(ms), kS(ks), nS(ns), A_fetching_policy(A_fetching_policy), B_fetching_policy(B_fetching_policy),
local_fetch_0(local_fetch_0), local_fetch_1(local_fetch_1),
mL(ms*local_size_0), nL(ns*local_size_1){}
@@ -625,7 +625,7 @@ mproduct_parameters::mproduct_parameters(unsigned int simd_width
return tools::make_vector<int_t>() << M << N << K;
}
mproduct::mproduct(mproduct_parameters const & parameters, char A_trans, char B_trans) : template_base_impl<mproduct, mproduct_parameters>(parameters, BIND_ALL_UNIQUE), A_trans_(A_trans), B_trans_(B_trans){ }
mproduct::mproduct(mproduct_parameters const & parameters, char A_trans, char B_trans) : base_impl<mproduct, mproduct_parameters>(parameters, BIND_ALL_UNIQUE), A_trans_(A_trans), B_trans_(B_trans){ }
std::vector<int_t> mproduct::input_sizes(symbolic_expressions_container const & symbolic_expressions)
{

View File

@@ -10,7 +10,7 @@ namespace atidlas
mreduction_parameters::mreduction_parameters(unsigned int _simd_width,
unsigned int _local_size_0, unsigned int _local_size_1,
unsigned int _num_groups_0, fetching_policy_type _fetch_policy): template_base::parameters_type(_simd_width, _local_size_0, _local_size_1, 1),
unsigned int _num_groups_0, fetching_policy_type _fetch_policy): base::parameters_type(_simd_width, _local_size_0, _local_size_1, 1),
num_groups_0(_num_groups_0), fetch_policy(_fetch_policy) { }
@@ -42,7 +42,7 @@ std::string mreduction::generate_impl(unsigned int label, symbolic_expressions_c
stream.inc_tab();
process(stream, PARENT_NODE_TYPE,
tools::make_map<std::multimap<std::string, std::string> >("scalar", "#scalartype #namereg = *#pointer;")
tools::make_map<std::map<std::string, std::string> >("scalar", "#scalartype #namereg = *#pointer;")
("array", "#pointer += #start1 + #start2*#ld;")
("array", "#ld *= #nldstride;")
("array", "#pointer += #start1;"), symbolic_expressions, mappings);
@@ -74,12 +74,12 @@ 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 = $VALUE{(r%#tuplearg0)*#stride1, (c%#tuplearg1)*#stride2};"));
std::map<std::string, std::string> accessors;
accessors["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")+";"));
accessors["array"] = data_type + " #namereg = " + vload(simd_width, "c*#stride1", "#pointer + r*#ld")+";";
else
accessors.insert(std::make_pair("array","#scalartype #namereg = #pointer[r*#stride1 + c*#ld];"));
accessors["array"] = "#scalartype #namereg = #pointer[r*#stride1 + c*#ld];";
(*it)->process_recursive(stream, PARENT_NODE_TYPE, accessors);
}
@@ -99,7 +99,7 @@ std::string mreduction::generate_impl(unsigned int label, symbolic_expressions_c
{
std::map<std::string, std::string> accessors;
accessors["array"] = str[a];
accessors["matrix_repeat"] = "#namereg";
accessors["repeat"] = "#namereg";
accessors["scalar"] = "#namereg";
std::string value = exprs[k]->evaluate_recursive(LHS_NODE_TYPE, accessors);
if (exprs[k]->is_index_reduction())
@@ -162,6 +162,7 @@ std::string mreduction::generate_impl(unsigned int label, symbolic_expressions_c
stream.dec_tab();
stream << "}" << std::endl;
return stream.str();
}
@@ -192,7 +193,7 @@ std::vector<std::string> mreduction::generate_impl(unsigned int label, symbolic_
mreduction::mreduction(mreduction::parameters_type const & parameters,
mreduction::reduction_type rtype,
binding_policy_t binding_policy) :
template_base_impl<mreduction, mreduction_parameters>(parameters, binding_policy),
base_impl<mreduction, mreduction_parameters>(parameters, binding_policy),
reduction_type_(rtype){ }
std::vector<int_t> mreduction::input_sizes(symbolic_expressions_container const & symbolic_expressions)
@@ -252,7 +253,7 @@ mreduction_cols::mreduction_cols(unsigned int simd, unsigned int ls1, unsigned i
mreduction(mreduction_parameters(simd, ls1, ls2, ng, fetch), REDUCE_COLUMNS, bind)
{}
template class template_base_impl<mreduction, mreduction_parameters>;
template class base_impl<mreduction, mreduction_parameters>;
}

View File

@@ -10,7 +10,7 @@ namespace atidlas
reduction_parameters::reduction_parameters(unsigned int _simd_width,
unsigned int _group_size, unsigned int _num_groups,
fetching_policy_type _fetching_policy) : template_base::parameters_type(_simd_width, _group_size, 1, 2), num_groups(_num_groups), fetching_policy(_fetching_policy)
fetching_policy_type _fetching_policy) : base::parameters_type(_simd_width, _group_size, 1, 2), num_groups(_num_groups), fetching_policy(_fetching_policy)
{ }
unsigned int reduction::lmem_usage(symbolic_expressions_container const & symbolic_expressions) const
@@ -91,7 +91,7 @@ std::string reduction::generate_impl(unsigned int label, char type, symbolic_exp
stream.inc_tab();
stream << "unsigned int lid = get_local_id(0);" << std::endl;
process(stream, PARENT_NODE_TYPE, tools::make_map<std::multimap<std::string, std::string> >("scalar", "#scalartype #namereg = *#pointer;")
process(stream, PARENT_NODE_TYPE, tools::make_map<std::map<std::string, std::string> >("scalar", "#scalartype #namereg = *#pointer;")
("array", "#pointer += #start1;"), symbolic_expressions, mappings);
for (unsigned int k = 0; k < N; ++k)
@@ -120,7 +120,7 @@ std::string reduction::generate_impl(unsigned int label, char type, symbolic_exp
std::string i = (simd_width==1)?"i*#stride1":"i";
//Fetch vector entry
for (std::vector<mapped_scalar_reduction*>::const_iterator it = exprs.begin(); it != exprs.end(); ++it)
(*it)->process_recursive(stream, PARENT_NODE_TYPE, tools::make_map<std::multimap<std::string, std::string> >("array", append_width("#scalartype",simd_width) + " #namereg = " + vload(simd_width,i,"#pointer")+";")
(*it)->process_recursive(stream, PARENT_NODE_TYPE, tools::make_map<std::map<std::string, std::string> >("array", append_width("#scalartype",simd_width) + " #namereg = " + vload(simd_width,i,"#pointer")+";")
("matrix_row", "#scalartype #namereg = #pointer[$OFFSET{#row*#stride1, i*#stride2}];")
("matrix_column", "#scalartype #namereg = #pointer[$OFFSET{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}];"));
@@ -263,12 +263,12 @@ std::vector<std::string> reduction::generate_impl(unsigned int label, symbolic_
}
reduction::reduction(reduction::parameters_type const & parameters,
binding_policy_t binding) : template_base_impl<reduction, reduction_parameters>(parameters, binding)
binding_policy_t binding) : base_impl<reduction, reduction_parameters>(parameters, binding)
{ }
reduction::reduction(unsigned int simd, unsigned int ls, unsigned int ng,
fetching_policy_type fetch, binding_policy_t bind):
template_base_impl<reduction, reduction_parameters>(reduction_parameters(simd,ls,ng,fetch), bind)
base_impl<reduction, reduction_parameters>(reduction_parameters(simd,ls,ng,fetch), bind)
{}
std::vector<int_t> reduction::input_sizes(symbolic_expressions_container const & symbolic_expressions)
@@ -343,6 +343,6 @@ void reduction::enqueue(cl::CommandQueue & queue,
queue.enqueueNDRangeKernel(kernels[k], cl::NullRange, grange[k], lrange[k]);
}
template class template_base_impl<reduction, reduction_parameters>;
template class base_impl<reduction, reduction_parameters>;
}

View File

@@ -12,7 +12,7 @@ namespace atidlas
vaxpy_parameters::vaxpy_parameters(unsigned int _simd_width,
unsigned int _group_size, unsigned int _num_groups,
fetching_policy_type _fetching_policy) :
template_base::parameters_type(_simd_width, _group_size, 1, 1), num_groups(_num_groups), fetching_policy(_fetching_policy)
base::parameters_type(_simd_width, _group_size, 1, 1), num_groups(_num_groups), fetching_policy(_fetching_policy)
{ }
@@ -39,7 +39,7 @@ 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> >("scalar", "#scalartype #namereg = *#pointer;")
tools::make_map<std::map<std::string, std::string> >("scalar", "#scalartype #namereg = *#pointer;")
("array", "#pointer += #start1 + #start2*#ld;")
("array", "#start1/=" + str_simd_width + ";"), symbolic_expressions, mappings);
@@ -49,7 +49,7 @@ std::vector<std::string> vaxpy::generate_impl(unsigned int label, symbolic_expre
stream << "{" << std::endl;
stream.inc_tab();
process(stream, PARENT_NODE_TYPE,
tools::make_map<std::multimap<std::string, std::string> >("array", data_type + " #namereg = #pointer[i*#stride1];")
tools::make_map<std::map<std::string, std::string> >("array", data_type + " #namereg = #pointer[i*#stride1];")
("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}];")
@@ -61,7 +61,7 @@ std::vector<std::string> vaxpy::generate_impl(unsigned int label, symbolic_expre
("matrix_diag", "#namereg")
("scalar", "#namereg"), symbolic_expressions, mappings);
process(stream, LHS_NODE_TYPE, tools::make_map<std::multimap<std::string, std::string> >("array", "#pointer[i*#stride1] = #namereg;")
process(stream, LHS_NODE_TYPE, tools::make_map<std::map<std::string, std::string> >("array", "#pointer[i*#stride1] = #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;")
@@ -73,7 +73,7 @@ std::vector<std::string> vaxpy::generate_impl(unsigned int label, symbolic_expre
stream << "if(get_global_id(0)==0)" << std::endl;
stream << "{" << std::endl;
stream.inc_tab();
process(stream, LHS_NODE_TYPE, tools::make_map<std::multimap<std::string, std::string> >("scalar", "*#pointer = #namereg;"), symbolic_expressions, mappings);
process(stream, LHS_NODE_TYPE, tools::make_map<std::map<std::string, std::string> >("scalar", "*#pointer = #namereg;"), symbolic_expressions, mappings);
stream.dec_tab();
stream << "}" << std::endl;
@@ -88,12 +88,12 @@ std::vector<std::string> vaxpy::generate_impl(unsigned int label, symbolic_expre
vaxpy::vaxpy(vaxpy_parameters const & parameters,
binding_policy_t binding_policy) :
template_base_impl<vaxpy, vaxpy_parameters>(parameters, binding_policy)
base_impl<vaxpy, vaxpy_parameters>(parameters, binding_policy)
{}
vaxpy::vaxpy(unsigned int simd, unsigned int ls, unsigned int ng,
fetching_policy_type fetch, binding_policy_t bind):
template_base_impl<vaxpy, vaxpy_parameters>(vaxpy_parameters(simd,ls,ng,fetch), bind)
base_impl<vaxpy, vaxpy_parameters>(vaxpy_parameters(simd,ls,ng,fetch), bind)
{}

View File

@@ -64,12 +64,15 @@ cl::Program program_map::add(cl::Context & context, std::string const & pname, s
res = cl::Program(context, cl::Program::Sources(1, std::make_pair(csrc, srclen)));
}
try{
err = res.build(devices);
}catch(cl::Error const & e){
if (err != CL_SUCCESS)
for(std::vector< cl::Device >::const_iterator it = devices.begin(); it != devices.end(); ++it)
std::cout << "Device : " << it->getInfo<CL_DEVICE_NAME>()
<< "Build Status = " << res.getBuildInfo<CL_PROGRAM_BUILD_STATUS>(*it) << std::endl
<< "Build Log = " << res.getBuildInfo<CL_PROGRAM_BUILD_LOG>(*it) << std::endl;
}
// Store the program in the cache

View File

@@ -69,14 +69,14 @@ std::vector<cl::lazy_compiler>& model::init(symbolic_expressions_container const
return to_init;
}
model::model(predictors::random_forest const & predictor, std::vector< tools::shared_ptr<template_base> > const & templates, cl::CommandQueue & queue) :
model::model(predictors::random_forest const & predictor, std::vector< tools::shared_ptr<base> > const & templates, cl::CommandQueue & queue) :
templates_(templates), predictor_(new predictors::random_forest(predictor)), queue_(queue)
{}
model::model(std::vector< tools::shared_ptr<template_base> > const & templates, cl::CommandQueue & queue) : templates_(templates), queue_(queue)
model::model(std::vector< tools::shared_ptr<base> > const & templates, cl::CommandQueue & queue) : templates_(templates), queue_(queue)
{}
model::model(template_base const & tp, cl::CommandQueue & queue) : templates_(1,tp.clone()), queue_(queue)
model::model(base const & tp, cl::CommandQueue & queue) : templates_(1,tp.clone()), queue_(queue)
{}
void model::execute(symbolic_expressions_container const & symbolic_expressions, bool bypass_predictor, bool force_recompilation)
@@ -160,24 +160,24 @@ namespace detail
throw "Unsupported operation";
}
static tools::shared_ptr<template_base> create(std::string const & template_name, std::vector<int> const & a)
static tools::shared_ptr<base> create(std::string const & template_name, std::vector<int> const & a)
{
fetching_policy_type fetch[] = {FETCH_FROM_LOCAL, FETCH_FROM_GLOBAL_STRIDED, FETCH_FROM_GLOBAL_CONTIGUOUS};
if(template_name=="vector-axpy")
return tools::shared_ptr<template_base>(new vaxpy( vaxpy_parameters(a[0], a[1], a[2], fetch[a[3]])));
return tools::shared_ptr<base>(new vaxpy( vaxpy_parameters(a[0], a[1], a[2], fetch[a[3]])));
else if(template_name=="reduction")
return tools::shared_ptr<template_base>(new reduction( reduction_parameters(a[0], a[1], a[2], fetch[a[3]])));
return tools::shared_ptr<base>(new reduction( reduction_parameters(a[0], a[1], a[2], fetch[a[3]])));
else if(template_name=="matrix-axpy")
return tools::shared_ptr<template_base>(new maxpy( maxpy_parameters(a[0], a[1], a[2], a[3], a[4], fetch[a[5]])));
return tools::shared_ptr<base>(new maxpy( maxpy_parameters(a[0], a[1], a[2], a[3], a[4], fetch[a[5]])));
else if(template_name.find("row-wise-reduction")!=std::string::npos)
{
return tools::shared_ptr<template_base>(new mreduction_rows( mreduction_parameters(a[0], a[1], a[2], a[3], fetch[a[4]])));
return tools::shared_ptr<base>(new mreduction_rows( mreduction_parameters(a[0], a[1], a[2], a[3], fetch[a[4]])));
}
else if(template_name.find("matrix-product")!=std::string::npos)
{
char A_trans = template_name[15];
char B_trans = template_name[16];
return tools::shared_ptr<template_base>(new mproduct( mproduct_parameters(a[0], a[1], a[2], a[3], a[4], a[5], a[6],
return tools::shared_ptr<base>(new mproduct( mproduct_parameters(a[0], a[1], a[2], a[3], a[4], a[5], a[6],
fetch[a[7]], fetch[a[8]], a[9], a[10]), A_trans, B_trans));
}
else
@@ -217,7 +217,7 @@ model_map_t import(std::string const & fname, cl::CommandQueue & queue)
numeric_type dtype = detail::get_dtype(*dt);
// Get profiles
std::vector<tools::shared_ptr<template_base> > templates;
std::vector<tools::shared_ptr<base> > templates;
js::Value const & profiles = document[opcstr][dtcstr]["profiles"];
for (js::SizeType id = 0 ; id < profiles.Size() ; ++id)
templates.push_back(detail::create(*op, tools::to_int_array<int>(profiles[id])));

View File

@@ -39,12 +39,12 @@ lhs_rhs_element::lhs_rhs_element(atidlas::value_scalar const & x)
vscalar = x.values();
}
lhs_rhs_element::lhs_rhs_element(atidlas::array_repeat_infos const & x)
lhs_rhs_element::lhs_rhs_element(atidlas::repeat_infos const & x)
{
type_family = INFOS_TYPE_FAMILY;
subtype = MATRIX_REPEAT_INFOS_TYPE;
subtype = REPEAT_INFOS_TYPE;
dtype = INVALID_NUMERIC_TYPE;
repeat_infos = (atidlas::array_repeat_infos*)&x;
tuple = (atidlas::repeat_infos*)&x;
}
//

View File

@@ -60,7 +60,7 @@ namespace detail
}
}
inline std::string express(atidlas::symbolic_expression const & s)
std::string to_string(atidlas::symbolic_expression const & s)
{
std::ostringstream os;
detail::print_node(os, s, s.root());

View File

@@ -530,7 +530,7 @@ void export_scalar()
void export_model()
{
bp::class_<atidlas::model>("model", bp::init<atd::template_base const &, atd::cl::CommandQueue&>())
bp::class_<atidlas::model>("model", bp::init<atd::base const &, atd::cl::CommandQueue&>())
.def("execute", &atd::model::execute);
bp::enum_<atidlas::fetching_policy_type>
@@ -542,17 +542,17 @@ void export_model()
//Base
{
#define __PROP(name) .def_readonly(#name, &atidlas::template_base::parameters_type::name)
bp::class_<atidlas::template_base, boost::noncopyable>("template_base", bp::no_init)
.def("lmem_usage", &atidlas::template_base::lmem_usage)
.def("registers_usage", &atidlas::template_base::registers_usage)
.def("check_invalid", &atidlas::template_base::check_invalid)
#define __PROP(name) .def_readonly(#name, &atidlas::base::parameters_type::name)
bp::class_<atidlas::base, boost::noncopyable>("base", bp::no_init)
.def("lmem_usage", &atidlas::base::lmem_usage)
.def("registers_usage", &atidlas::base::registers_usage)
.def("check_invalid", &atidlas::base::check_invalid)
;
#undef __PROP
}
#define WRAP_TEMPLATE(name, ...) bp::class_<atidlas::template_base_impl<atidlas::name, atidlas::name::parameters_type>, bp::bases<atidlas::template_base>, boost::noncopyable>(#name "_base_impl", bp::no_init);\
bp::class_<atidlas::name, bp::bases<atidlas::template_base_impl<atidlas::name, atidlas::name::parameters_type> > >(#name, bp::init<__VA_ARGS__>())\
#define WRAP_TEMPLATE(name, ...) bp::class_<atidlas::base_impl<atidlas::name, atidlas::name::parameters_type>, bp::bases<atidlas::base>, boost::noncopyable>(#name "_base_impl", bp::no_init);\
bp::class_<atidlas::name, bp::bases<atidlas::base_impl<atidlas::name, atidlas::name::parameters_type> > >(#name, bp::init<__VA_ARGS__>())\
.add_property("local_size_0", &atd::name::local_size_0)\
.add_property("local_size_1", &atd::name::local_size_1);

View File

@@ -161,23 +161,23 @@ bool failure_vector(VecType1 const & x, VecType2 const & y, typename VecType1::v
#define INIT_VECTOR(N, SUBN, START, STRIDE, CPREFIX, PREFIX) \
simple_vector<T> CPREFIX ## _vector(N);\
simple_vector_slice<T> CPREFIX ## _slice(CPREFIX ## _vector, START, START + STRIDE*SUBN, STRIDE);\
init_rand(CPREFIX ## _vector);\
atidlas::array PREFIX ## _vector(CPREFIX ## _vector.data());\
atidlas::array PREFIX ## _slice = PREFIX ## _vector[atidlas::_(START, START + STRIDE*SUBN, STRIDE)];
simple_vector<T> CPREFIX ## _full(N);\
simple_vector_slice<T> CPREFIX ## _slice(CPREFIX ## _full, START, START + STRIDE*SUBN, STRIDE);\
init_rand(CPREFIX ## _full);\
atidlas::array PREFIX ## _full(CPREFIX ## _full.data());\
atidlas::array PREFIX ## _slice = PREFIX ## _full[atidlas::_(START, START + STRIDE*SUBN, STRIDE)];
#define INIT_MATRIX(M, SUBM, START1, STRIDE1, N, SUBN, START2, STRIDE2, CPREFIX, PREFIX) \
simple_matrix<T> CPREFIX ## _matrix(M, N);\
simple_matrix_slice<T> CPREFIX ## _slice(CPREFIX ## _matrix, START1, START1 + STRIDE1*SUBM, STRIDE1,\
simple_matrix<T> CPREFIX ## _full(M, N);\
simple_matrix_slice<T> CPREFIX ## _slice(CPREFIX ## _full, START1, START1 + STRIDE1*SUBM, STRIDE1,\
START2, START2 + STRIDE2*SUBN, STRIDE2);\
init_rand(CPREFIX ## _matrix);\
atidlas::array PREFIX ## _matrix(M, N, CPREFIX ## _matrix.data());\
atidlas::array PREFIX ## _slice(PREFIX ## _matrix(atidlas::_(START1, START1 + STRIDE1*SUBM, STRIDE1),\
init_rand(CPREFIX ## _full);\
atidlas::array PREFIX ## _full(M, N, CPREFIX ## _full.data());\
atidlas::array PREFIX ## _slice(PREFIX ## _full(atidlas::_(START1, START1 + STRIDE1*SUBM, STRIDE1),\
atidlas::_(START2, START2 + STRIDE2*SUBN, STRIDE2)));\
simple_matrix<T> CPREFIX ## T_matrix = simple_trans(CPREFIX ## _matrix);\
atidlas::array PREFIX ## T_matrix(N, M, CPREFIX ## T_matrix.data());\
atidlas::array PREFIX ## T_slice(PREFIX ## T_matrix(atidlas::_(START2, START2 + STRIDE2*SUBN, STRIDE2),\
simple_matrix<T> CPREFIX ## T_full = simple_trans(CPREFIX ## _full);\
atidlas::array PREFIX ## T_full(N, M, CPREFIX ## T_full.data());\
atidlas::array PREFIX ## T_slice(PREFIX ## T_full(atidlas::_(START2, START2 + STRIDE2*SUBN, STRIDE2),\
atidlas::_(START1, START1 + STRIDE1*SUBM, STRIDE1)));\

View File

@@ -7,8 +7,8 @@ namespace ad = atidlas;
typedef atidlas::int_t int_t;
template<typename T>
void test(T epsilon, simple_matrix_base<T> & cA, simple_matrix_base<T>& cB, simple_matrix_base<T>& cC,
ad::array& A, ad::array& B, ad::array& C)
void test(T epsilon, simple_matrix_base<T> & cA, simple_matrix_base<T>& cB, simple_matrix_base<T>& cC, simple_vector_base<T>& cx, simple_vector_base<T>& cy,
ad::array& A, ad::array& B, ad::array& C, ad::array& x, ad::array& y)
{
using namespace std;
@@ -83,6 +83,8 @@ void test(T epsilon, simple_matrix_base<T> & cA, simple_matrix_base<T>& cB, simp
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()))
RUN_TEST("C = outer(x, y)", cC(i,j) = cx[i]*cy[j], C= outer(x,y))
#undef RUN_TEST
if(failure_count > 0)
@@ -102,14 +104,15 @@ void test_impl(T epsilon)
INIT_MATRIX(M, SUBM, 5, 3, N, SUBN, 7, 2, cA, A);
INIT_MATRIX(M, SUBM, 5, 3, N, SUBN, 7, 2, cB, B);
INIT_MATRIX(M, SUBM, 5, 3, N, SUBN, 7, 2, cC, C);
#define TEST_OPERATIONS(XTYPE, YTYPE, ZTYPE)\
test(epsilon, cA_ ## XTYPE, cB_ ## YTYPE, cC_ ## ZTYPE, A_ ## XTYPE, B_ ## YTYPE, C_ ## ZTYPE);\
INIT_VECTOR(M, SUBM, 5, 3, cx, x);
INIT_VECTOR(N, SUBN, 7, 2, cy, y);
#define TEST_OPERATIONS(TYPE)\
test(epsilon, cA_ ## TYPE, cB_ ## TYPE, cC_ ## TYPE, cx_ ## TYPE, cy_ ## TYPE, A_ ## TYPE, B_ ## TYPE, C_ ## TYPE, x_ ## TYPE, y_ ## TYPE);\
std::cout << "> standard..." << std::endl;
TEST_OPERATIONS(matrix, matrix, matrix);
TEST_OPERATIONS(full);
std::cout << "> slice..." << std::endl;
TEST_OPERATIONS(slice, slice, slice);
TEST_OPERATIONS(slice);
}
int main()