Commit 4220eebf authored by Shucai Xiao's avatar Shucai Xiao
Browse files

merge changes from develop branch

parents 2e175fd8 767ca0cc
...@@ -74,3 +74,8 @@ ENV LD_LIBRARY_PATH=$PREFIX/lib ...@@ -74,3 +74,8 @@ ENV LD_LIBRARY_PATH=$PREFIX/lib
# Install doc requirements # Install doc requirements
ADD doc/requirements.txt /doc-requirements.txt ADD doc/requirements.txt /doc-requirements.txt
RUN pip install -r /doc-requirements.txt RUN pip install -r /doc-requirements.txt
# Setup ubsan environment to printstacktrace
RUN ln -s /usr/bin/llvm-symbolizer-5.0 /usr/local/bin/llvm-symbolizer
ENV UBSAN_OPTIONS=print_stacktrace=1
ENV ASAN_OPTIONS=detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1
...@@ -24,7 +24,7 @@ struct instruction ...@@ -24,7 +24,7 @@ struct instruction
instruction(literal l); instruction(literal l);
void replace(const shape& r); void replace(operation o);
void recompute_shape(); void recompute_shape();
...@@ -90,7 +90,8 @@ struct instruction ...@@ -90,7 +90,8 @@ struct instruction
// internal // internal
void replace_argument(instruction_ref old, instruction_ref new_ins); void replace_argument(instruction_ref old, instruction_ref new_ins);
private: void replace(const shape& r);
operation op; operation op;
shape result; shape result;
std::vector<instruction_ref> output; std::vector<instruction_ref> output;
......
...@@ -39,6 +39,11 @@ struct undefined ...@@ -39,6 +39,11 @@ struct undefined
struct unknown struct unknown
{ {
std::string op; std::string op;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return pack(f(self.op, "op"));
}
std::string name() const { return "unknown:" + op; } std::string name() const { return "unknown:" + op; }
shape compute_shape(std::vector<shape> input) const shape compute_shape(std::vector<shape> input) const
{ {
......
...@@ -19,6 +19,13 @@ namespace op { ...@@ -19,6 +19,13 @@ namespace op {
struct concat struct concat
{ {
std::size_t axis = 0; std::size_t axis = 0;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return pack(f(self.axis, "axis"));
}
std::string name() const { return "concat"; } std::string name() const { return "concat"; }
std::vector<std::size_t> compute_offsets(const shape& output_shape, std::vector<std::size_t> compute_offsets(const shape& output_shape,
const std::vector<argument>& args) const const std::vector<argument>& args) const
......
...@@ -18,19 +18,20 @@ namespace op { ...@@ -18,19 +18,20 @@ namespace op {
struct leaky_relu struct leaky_relu
{ {
std::string name() const { return "leaky_relu"; }
float alpha; float alpha;
shape compute_shape(std::vector<shape> inputs) const
{
check_shapes{inputs, *this}.has(1);
return inputs.front();
}
template <class Self, class F> template <class Self, class F>
static auto reflect(Self& self, F f) static auto reflect(Self& self, F f)
{ {
return pack(f(self.alpha, "alpha")); return pack(f(self.alpha, "alpha"));
} }
std::string name() const { return "leaky_relu"; }
shape compute_shape(std::vector<shape> inputs) const
{
check_shapes{inputs, *this}.has(1);
return inputs.front();
}
}; };
} // namespace op } // namespace op
......
...@@ -69,7 +69,7 @@ auto operator<<(std::ostream& os, const T& x) -> decltype(os << x.name()) ...@@ -69,7 +69,7 @@ auto operator<<(std::ostream& os, const T& x) -> decltype(os << x.name())
{ {
os << x.name(); os << x.name();
char delim = '['; char delim = '[';
reflect_each(x, [&](auto& y, auto name) { reflect_each(x, [&](auto&& y, auto name) {
os << delim; os << delim;
os << name << "="; os << name << "=";
stream_write_value(os, y); stream_write_value(os, y);
...@@ -87,6 +87,8 @@ namespace operation_equal { ...@@ -87,6 +87,8 @@ namespace operation_equal {
template <class T, class U> template <class T, class U>
auto operator==(const T& x, const U& y) -> decltype(x.name() == y.name()) auto operator==(const T& x, const U& y) -> decltype(x.name() == y.name())
{ {
static_assert(is_reflectable<T>{} or sizeof(T) <= 1,
"Missing equality operator or reflect method.");
if(x.name() != y.name()) if(x.name() != y.name())
return false; return false;
const auto& yy = any_cast<T>(y); const auto& yy = any_cast<T>(y);
......
...@@ -11,6 +11,15 @@ inline namespace MIGRAPHX_INLINE_NS { ...@@ -11,6 +11,15 @@ inline namespace MIGRAPHX_INLINE_NS {
namespace detail { namespace detail {
struct reflect_placeholder
{
template <class... Ts>
int operator()(Ts&&...) const
{
return 0;
}
};
template <class T, class Selector> template <class T, class Selector>
auto reflect_impl(rank<1>, T& x, Selector f) -> decltype(T::reflect(x, f)) auto reflect_impl(rank<1>, T& x, Selector f) -> decltype(T::reflect(x, f))
{ {
...@@ -23,8 +32,53 @@ auto reflect_impl(rank<0>, T&, Selector) ...@@ -23,8 +32,53 @@ auto reflect_impl(rank<0>, T&, Selector)
return pack(); return pack();
} }
template <class T>
auto reflectable_impl(rank<1>, T&& x)
-> decltype(T::reflect(x, reflect_placeholder{}), std::true_type{});
template <class T>
auto reflectable_impl(rank<0>, T &&) -> decltype(std::false_type{});
template <class T>
struct remove_rvalue_reference
{
using type = T;
};
template <class T>
struct remove_rvalue_reference<T&&>
{
using type = T;
};
template <class T>
struct wrapper
{
using type = typename remove_rvalue_reference<T>::type;
type data;
type get() const { return data; }
};
template <class T>
wrapper<T> wrap(std::remove_reference_t<T>& x)
{
return wrapper<T>{std::forward<T>(x)};
}
template <class... Ts>
using auto_tuple_t = std::tuple<typename remove_rvalue_reference<Ts>::type...>;
template <class... Ts>
auto_tuple_t<Ts...> auto_tuple(Ts&&... xs)
{
return auto_tuple_t<Ts...>{std::forward<Ts>(xs)...};
}
} // namespace detail } // namespace detail
template <class T>
using is_reflectable = decltype(detail::reflectable_impl(rank<1>{}, std::declval<T>()));
template <class T, class Selector> template <class T, class Selector>
auto reflect(T& x, Selector f) auto reflect(T& x, Selector f)
{ {
...@@ -34,15 +88,16 @@ auto reflect(T& x, Selector f) ...@@ -34,15 +88,16 @@ auto reflect(T& x, Selector f)
template <class T> template <class T>
auto reflect_tie(T& x) auto reflect_tie(T& x)
{ {
return reflect(x, [](auto&& y, auto&&...) { return std::ref(y); })( return reflect(x, [](auto&& y, auto&&...) { return detail::wrap<decltype(y)>(y); })(
[](auto&&... xs) { return std::tie(xs.get()...); }); [](auto&&... xs) { return detail::auto_tuple(xs.get()...); });
} }
template <class T, class F> template <class T, class F>
void reflect_each(T& x, F f) void reflect_each(T& x, F f)
{ {
return reflect(x, [](auto&& y, auto... ys) { return pack(std::ref(y), ys...); })( return reflect(x, [](auto&& y, auto... ys) {
[&](auto&&... xs) { return pack(detail::wrap<decltype(y)>(y), ys...);
})([&](auto&&... xs) {
each_args([&](auto p) { p([&](auto&& y, auto... ys) { f(y.get(), ys...); }); }, xs...); each_args([&](auto p) { p([&](auto&& y, auto... ys) { f(y.get(), ys...); }); }, xs...);
}); });
} }
......
...@@ -28,6 +28,12 @@ void instruction::replace(const shape& r) ...@@ -28,6 +28,12 @@ void instruction::replace(const shape& r)
} }
} }
void instruction::replace(operation o)
{
op = std::move(o);
recompute_shape();
}
void instruction::recompute_shape() { replace(compute_shape(op, arguments)); } void instruction::recompute_shape() { replace(compute_shape(op, arguments)); }
void instruction::clear_arguments() void instruction::clear_arguments()
......
...@@ -63,11 +63,16 @@ static void print_program(const program& p, F print_func) ...@@ -63,11 +63,16 @@ static void print_program(const program& p, F print_func)
for(auto ins : iterator_for(p)) for(auto ins : iterator_for(p))
{ {
std::string var_name = "@" + std::to_string(count); std::string var_name;
if(ins->name() == "@param") if(ins->name() == "@param")
{ {
var_name = any_cast<builtin::param>(ins->get_operator()).parameter; var_name = any_cast<builtin::param>(ins->get_operator()).parameter;
} }
else
{
var_name = "@" + std::to_string(count);
count++;
}
names.emplace(ins, var_name); names.emplace(ins, var_name);
// TODO: Use all_of // TODO: Use all_of
...@@ -78,8 +83,6 @@ static void print_program(const program& p, F print_func) ...@@ -78,8 +83,6 @@ static void print_program(const program& p, F print_func)
} }
print_func(ins, names); print_func(ins, names);
count++;
} }
} }
......
...@@ -48,6 +48,12 @@ struct cpu_batch_norm_inference ...@@ -48,6 +48,12 @@ struct cpu_batch_norm_inference
{ {
op::batch_norm_inference op; op::batch_norm_inference op;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return migraphx::reflect(self.op, f);
}
std::string name() const { return "cpu::batch_norm_inference"; } std::string name() const { return "cpu::batch_norm_inference"; }
shape compute_shape(const std::vector<shape>& inputs) const { return op.compute_shape(inputs); } shape compute_shape(const std::vector<shape>& inputs) const { return op.compute_shape(inputs); }
...@@ -107,6 +113,12 @@ struct cpu_lrn ...@@ -107,6 +113,12 @@ struct cpu_lrn
{ {
op::lrn op; op::lrn op;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return migraphx::reflect(self.op, f);
}
std::string name() const { return "cpu::lrn"; } std::string name() const { return "cpu::lrn"; }
shape compute_shape(const std::vector<shape>& inputs) const { return op.compute_shape(inputs); } shape compute_shape(const std::vector<shape>& inputs) const { return op.compute_shape(inputs); }
argument compute(context&, shape output_shape, std::vector<argument> args) const argument compute(context&, shape output_shape, std::vector<argument> args) const
...@@ -140,25 +152,16 @@ struct cpu_lrn ...@@ -140,25 +152,16 @@ struct cpu_lrn
} }
}; };
struct clip_op
{
op::clip op;
std::string name() const { return "cpu::clip"; }
auto fcn() const
{
auto max = op.max_val;
auto min = op.min_val;
return [max, min](auto x) {
using type = decltype(x);
return std::min(std::max(type(min), x), type(max));
};
}
};
struct cpu_convolution struct cpu_convolution
{ {
op::convolution op; op::convolution op;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return migraphx::reflect(self.op, f);
}
std::string name() const { return "cpu::convolution"; } std::string name() const { return "cpu::convolution"; }
shape compute_shape(const std::vector<shape>& inputs) const { return op.compute_shape(inputs); } shape compute_shape(const std::vector<shape>& inputs) const { return op.compute_shape(inputs); }
argument compute(context&, shape output_shape, std::vector<argument> args) const argument compute(context&, shape output_shape, std::vector<argument> args) const
...@@ -205,6 +208,12 @@ struct cpu_quant_convolution ...@@ -205,6 +208,12 @@ struct cpu_quant_convolution
{ {
op::quant_convolution op; op::quant_convolution op;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return migraphx::reflect(self.op, f);
}
std::string name() const { return "cpu::quant_convolution"; } std::string name() const { return "cpu::quant_convolution"; }
shape compute_shape(const std::vector<shape>& inputs) const { return op.compute_shape(inputs); } shape compute_shape(const std::vector<shape>& inputs) const { return op.compute_shape(inputs); }
argument compute(context&, shape output_shape, std::vector<argument> args) const argument compute(context&, shape output_shape, std::vector<argument> args) const
...@@ -251,6 +260,12 @@ struct cpu_im2col ...@@ -251,6 +260,12 @@ struct cpu_im2col
{ {
op::im2col op; op::im2col op;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return migraphx::reflect(self.op, f);
}
static std::string name() { return "cpu::im2col"; } static std::string name() { return "cpu::im2col"; }
shape compute_shape(const std::vector<shape>& inputs) const { return op.compute_shape(inputs); } shape compute_shape(const std::vector<shape>& inputs) const { return op.compute_shape(inputs); }
...@@ -332,6 +347,12 @@ struct cpu_pooling ...@@ -332,6 +347,12 @@ struct cpu_pooling
{ {
op::pooling op; op::pooling op;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return migraphx::reflect(self.op, f);
}
std::string name() const { return "cpu::pooling_" + Op::name(); } std::string name() const { return "cpu::pooling_" + Op::name(); }
shape compute_shape(const std::vector<shape>& inputs) const { return op.compute_shape(inputs); } shape compute_shape(const std::vector<shape>& inputs) const { return op.compute_shape(inputs); }
argument compute(context&, const shape& output_shape, std::vector<argument> args) const argument compute(context&, const shape& output_shape, std::vector<argument> args) const
...@@ -376,20 +397,35 @@ struct cpu_pooling ...@@ -376,20 +397,35 @@ struct cpu_pooling
} }
}; };
struct cpu_contiguous struct cpu_op
{ {
op::contiguous op; operation op;
std::string name() const { return "cpu::contiguous"; } std::string name() const { return "cpu::" + op.name(); }
shape compute_shape(const std::vector<shape>& inputs) const { return op.compute_shape(inputs); } shape compute_shape(const std::vector<shape>& inputs) const { return op.compute_shape(inputs); }
argument compute(context&, const shape& output_shape, std::vector<argument> args) const argument compute(context&, const shape& output_shape, const std::vector<argument>& args) const
{ {
return op.compute(output_shape, std::move(args)); return op.compute(output_shape, args);
} }
friend bool operator==(const cpu_op& x, const cpu_op& y) { return x.op == y.op; }
friend bool operator==(const cpu_op& x, const operation& y)
{
if(x.name() != y.name())
return false;
return x == any_cast<cpu_op>(y);
}
friend bool operator==(const operation& x, const cpu_op& y) { return y == x; }
}; };
struct cpu_pad struct cpu_pad
{ {
op::pad op; op::pad op;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return migraphx::reflect(self.op, f);
}
std::string name() const { return "cpu::contiguous"; } std::string name() const { return "cpu::contiguous"; }
shape compute_shape(const std::vector<shape>& inputs) const { return op.compute_shape(inputs); } shape compute_shape(const std::vector<shape>& inputs) const { return op.compute_shape(inputs); }
argument compute(context&, const shape& output_shape, std::vector<argument> args) const argument compute(context&, const shape& output_shape, std::vector<argument> args) const
...@@ -413,20 +449,15 @@ struct cpu_pad ...@@ -413,20 +449,15 @@ struct cpu_pad
} }
}; };
struct cpu_concat
{
op::concat op;
std::string name() const { return "cpu::concat"; }
shape compute_shape(const std::vector<shape>& inputs) const { return op.compute_shape(inputs); }
argument compute(context&, const shape& output_shape, std::vector<argument> args) const
{
return op.compute(output_shape, std::move(args));
}
};
struct cpu_gemm struct cpu_gemm
{ {
op::dot op; op::dot op;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return migraphx::reflect(self.op, f);
}
std::string name() const { return "cpu::dot"; } std::string name() const { return "cpu::dot"; }
shape compute_shape(const std::vector<shape>& inputs) const shape compute_shape(const std::vector<shape>& inputs) const
{ {
...@@ -472,6 +503,13 @@ struct cpu_gemm ...@@ -472,6 +503,13 @@ struct cpu_gemm
struct cpu_quant_gemm struct cpu_quant_gemm
{ {
op::quant_dot op; op::quant_dot op;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return migraphx::reflect(self.op, f);
}
std::string name() const { return "cpu::quant_dot"; } std::string name() const { return "cpu::quant_dot"; }
shape compute_shape(const std::vector<shape>& inputs) const shape compute_shape(const std::vector<shape>& inputs) const
{ {
...@@ -529,162 +567,6 @@ struct cpu_quant_gemm ...@@ -529,162 +567,6 @@ struct cpu_quant_gemm
} }
}; };
struct cpu_gather
{
op::gather op;
std::string name() const { return "cpu::gather"; }
shape compute_shape(const std::vector<shape>& inputs) const { return op.compute_shape(inputs); }
argument compute(context&, const shape& output_shape, std::vector<argument> args) const
{
return op.compute(output_shape, std::move(args));
}
};
struct identity_op
{
std::string name() const { return "cpu::identity"; }
auto fcn() const
{
return [](auto x) { return x; };
}
};
struct abs_op
{
std::string name() const { return "cpu::abs"; }
auto fcn() const
{
return [](auto x) { return std::abs(make_signed(x)); };
}
};
struct exp_op
{
std::string name() const { return "cpu::exp"; }
auto fcn() const
{
return [](auto x) { return std::exp(x); };
}
};
struct log_op
{
std::string name() const { return "cpu::log"; }
auto fcn() const
{
return [](auto x) { return std::log(x); };
}
};
struct sin_op
{
std::string name() const { return "cpu::sin"; }
auto fcn() const
{
return [](auto x) { return std::sin(x); };
}
};
struct cos_op
{
std::string name() const { return "cpu::cos"; }
auto fcn() const
{
return [](auto x) { return std::cos(x); };
}
};
struct tan_op
{
std::string name() const { return "cpu::tan"; }
auto fcn() const
{
return [](auto x) { return std::tan(x); };
}
};
struct asin_op
{
std::string name() const { return "cpu::asin"; }
auto fcn() const
{
return [](auto x) { return std::asin(x); };
}
};
struct acos_op
{
std::string name() const { return "cpu::acos"; }
auto fcn() const
{
return [](auto x) { return std::acos(x); };
}
};
struct atan_op
{
std::string name() const { return "cpu::atan"; }
auto fcn() const
{
return [](auto x) { return std::atan(x); };
}
};
struct sinh_op
{
std::string name() const { return "cpu::sinh"; }
auto fcn() const
{
return [](auto x) { return std::sinh(x); };
}
};
struct cosh_op
{
std::string name() const { return "cpu::cosh"; }
auto fcn() const
{
return [](auto x) { return std::cosh(x); };
}
};
struct tanh_op
{
std::string name() const { return "cpu::tanh"; }
auto fcn() const
{
return [](auto x) { return std::tanh(x); };
}
};
struct sigmoid_op
{
std::string name() const { return "cpu::sigmoid"; }
auto fcn() const
{
return [](auto x) { return 1.f / (1.f + std::exp(-x)); };
}
};
struct neg_op
{
std::string name() const { return "cpu::neg"; }
auto fcn() const
{
return [](auto x) { return -x; };
}
};
struct relu_op
{
std::string name() const { return "cpu::relu"; }
auto fcn() const
{
return [](auto x) { return std::max(decltype(x){0}, x); };
}
};
struct leaky_relu_op struct leaky_relu_op
{ {
op::leaky_relu op; op::leaky_relu op;
...@@ -711,6 +593,12 @@ template <typename Op> ...@@ -711,6 +593,12 @@ template <typename Op>
struct cpu_unary struct cpu_unary
{ {
Op op; Op op;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return migraphx::reflect(self.op.op, f);
}
std::string name() const { return op.name(); } std::string name() const { return op.name(); }
shape compute_shape(const std::vector<shape>& inputs) const shape compute_shape(const std::vector<shape>& inputs) const
{ {
...@@ -789,6 +677,13 @@ struct softmax2d ...@@ -789,6 +677,13 @@ struct softmax2d
struct cpu_logsoftmax struct cpu_logsoftmax
{ {
op::logsoftmax op; op::logsoftmax op;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return migraphx::reflect(self.op, f);
}
std::string name() const { return "cpu::logsoftmax"; } std::string name() const { return "cpu::logsoftmax"; }
shape compute_shape(const std::vector<shape>& inputs) const { return op.compute_shape(inputs); } shape compute_shape(const std::vector<shape>& inputs) const { return op.compute_shape(inputs); }
...@@ -855,104 +750,6 @@ struct cpu_logsoftmax ...@@ -855,104 +750,6 @@ struct cpu_logsoftmax
} }
}; };
struct add_op
{
std::string name() const { return "add"; }
auto fcn() const
{
return [](auto x, auto y) { return x + y; };
}
};
struct sub_op
{
std::string name() const { return "sub"; }
auto fcn() const
{
return [](auto x, auto y) { return x - y; };
}
};
struct mul_op
{
std::string name() const { return "mul"; }
auto fcn() const
{
return [](auto x, auto y) { return x * y; };
}
};
struct div_op
{
std::string name() const { return "div"; }
auto fcn() const
{
return [](auto x, auto y) { return x / y; };
}
};
struct max_op
{
std::string name() const { return "max"; }
auto fcn() const
{
return [](auto x, auto y) { return std::max(x, y); };
}
};
struct min_op
{
std::string name() const { return "min"; }
auto fcn() const
{
return [](auto x, auto y) { return std::min(x, y); };
}
};
template <typename Op>
struct cpu_binary
{
Op op;
std::string name() const { return "cpu::" + op.name(); }
shape compute_shape(const std::vector<shape>& inputs) const
{
check_shapes{inputs}.has(2).same_type().same_dims();
auto s0 = inputs.at(0);
auto s1 = inputs.at(1);
if(s0 == s1 and s0.packed())
{
return s0;
}
else
{
return {s0.type(), s0.lens()};
}
}
argument compute(context&, const shape& output_shape, std::vector<argument> args) const
{
argument result{output_shape};
visit_all(result, args[0], args[1])([&](auto output, auto input1, auto input2) {
auto s1 = input1.get_shape();
auto s2 = input2.get_shape();
if(s1 == s2 and s1.standard())
{
std::transform(
input1.begin(), input1.end(), input2.begin(), output.begin(), op.fcn());
}
else
{
shape_for_each(output.get_shape(), [&](const auto& idx) {
output(idx.begin(), idx.end()) =
op.fcn()(input1(idx.begin(), idx.end()), input2(idx.begin(), idx.end()));
});
}
});
return result;
}
};
struct cpu_apply struct cpu_apply
{ {
program* prog; program* prog;
...@@ -972,45 +769,18 @@ struct cpu_apply ...@@ -972,45 +769,18 @@ struct cpu_apply
void init() void init()
{ {
apply_map["im2col"] = extend_op<cpu_im2col, op::im2col>(); apply_map["batch_norm_inference"] =
extend_op<cpu_batch_norm_inference, op::batch_norm_inference>();
apply_map["convolution"] = extend_op<cpu_convolution, op::convolution>(); apply_map["convolution"] = extend_op<cpu_convolution, op::convolution>();
apply_map["quant_convolution"] = extend_op<cpu_quant_convolution, op::quant_convolution>();
apply_map["dot"] = extend_op<cpu_gemm, op::dot>(); apply_map["dot"] = extend_op<cpu_gemm, op::dot>();
apply_map["quant_dot"] = extend_op<cpu_quant_gemm, op::quant_dot>(); apply_map["quant_dot"] = extend_op<cpu_quant_gemm, op::quant_dot>();
apply_map["batch_norm_inference"] = apply_map["quant_convolution"] = extend_op<cpu_quant_convolution, op::quant_convolution>();
extend_op<cpu_batch_norm_inference, op::batch_norm_inference>(); apply_map["elu"] = extend_op<cpu_unary<elu_op>, op::elu>();
apply_map["im2col"] = extend_op<cpu_im2col, op::im2col>();
apply_map["leaky_relu"] = extend_op<cpu_unary<leaky_relu_op>, op::leaky_relu>();
apply_map["logsoftmax"] = extend_op<cpu_logsoftmax, op::logsoftmax>();
apply_map["lrn"] = extend_op<cpu_lrn, op::lrn>(); apply_map["lrn"] = extend_op<cpu_lrn, op::lrn>();
apply_map["clip"] = extend_op<cpu_unary<clip_op>, op::clip>();
apply_map["contiguous"] = extend_op<cpu_contiguous, op::contiguous>();
apply_map["pad"] = extend_op<cpu_pad, op::pad>(); apply_map["pad"] = extend_op<cpu_pad, op::pad>();
apply_map["concat"] = extend_op<cpu_concat, op::concat>();
apply_map["gather"] = extend_op<cpu_gather, op::gather>();
apply_map["logsoftmax"] = extend_op<cpu_logsoftmax, op::logsoftmax>();
apply_map["leaky_relu"] = extend_op<cpu_unary<leaky_relu_op>, op::leaky_relu>();
apply_map["elu"] = extend_op<cpu_unary<elu_op>, op::elu>();
apply_map["identity"] = simple_op<cpu_unary<identity_op>>();
apply_map["abs"] = simple_op<cpu_unary<abs_op>>();
apply_map["sinh"] = simple_op<cpu_unary<sinh_op>>();
apply_map["cosh"] = simple_op<cpu_unary<cosh_op>>();
apply_map["tanh"] = simple_op<cpu_unary<tanh_op>>();
apply_map["sigmoid"] = simple_op<cpu_unary<sigmoid_op>>();
apply_map["exp"] = simple_op<cpu_unary<exp_op>>();
apply_map["log"] = simple_op<cpu_unary<log_op>>();
apply_map["neg"] = simple_op<cpu_unary<neg_op>>();
apply_map["sin"] = simple_op<cpu_unary<sin_op>>();
apply_map["cos"] = simple_op<cpu_unary<cos_op>>();
apply_map["tan"] = simple_op<cpu_unary<tan_op>>();
apply_map["asin"] = simple_op<cpu_unary<asin_op>>();
apply_map["acos"] = simple_op<cpu_unary<acos_op>>();
apply_map["atan"] = simple_op<cpu_unary<atan_op>>();
apply_map["relu"] = simple_op<cpu_unary<relu_op>>();
apply_map["add"] = simple_op<cpu_binary<add_op>>();
apply_map["sub"] = simple_op<cpu_binary<sub_op>>();
apply_map["mul"] = simple_op<cpu_binary<mul_op>>();
apply_map["div"] = simple_op<cpu_binary<div_op>>();
apply_map["max"] = simple_op<cpu_binary<max_op>>();
apply_map["min"] = simple_op<cpu_binary<min_op>>();
apply_map["softmax"] = simple_op<softmax2d>(); apply_map["softmax"] = simple_op<softmax2d>();
} }
...@@ -1027,9 +797,18 @@ struct cpu_apply ...@@ -1027,9 +797,18 @@ struct cpu_apply
{ {
apply_map.at(it->name())(it); apply_map.at(it->name())(it);
} }
else if(is_context_free(it->get_operator()))
{
apply_cpu_op(it);
}
} }
} }
void apply_cpu_op(instruction_ref ins)
{
prog->replace_instruction(ins, cpu_op{ins->get_operator()}, ins->inputs());
}
template <class T> template <class T>
void apply_simple_op(instruction_ref ins) void apply_simple_op(instruction_ref ins)
{ {
......
...@@ -13,6 +13,13 @@ struct context; ...@@ -13,6 +13,13 @@ struct context;
struct miopen_abs struct miopen_abs
{ {
shared<activation_descriptor> ad; shared<activation_descriptor> ad;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return gpu::reflect(self.ad.get(), f);
}
std::string name() const { return "gpu::abs"; } std::string name() const { return "gpu::abs"; }
shape compute_shape(const std::vector<shape>& inputs) const; shape compute_shape(const std::vector<shape>& inputs) const;
argument argument
......
...@@ -13,6 +13,13 @@ struct context; ...@@ -13,6 +13,13 @@ struct context;
struct miopen_batch_norm_inference struct miopen_batch_norm_inference
{ {
op::batch_norm_inference op; op::batch_norm_inference op;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return migraphx::reflect(self.op, f);
}
std::string name() const { return "gpu::batch_norm_inference"; } std::string name() const { return "gpu::batch_norm_inference"; }
shape compute_shape(const std::vector<shape>& inputs) const; shape compute_shape(const std::vector<shape>& inputs) const;
argument argument
......
...@@ -13,6 +13,13 @@ struct context; ...@@ -13,6 +13,13 @@ struct context;
struct hip_clip struct hip_clip
{ {
op::clip op; op::clip op;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return migraphx::reflect(self.op, f);
}
std::string name() const { return "gpu::clip"; } std::string name() const { return "gpu::clip"; }
shape compute_shape(std::vector<shape> inputs) const; shape compute_shape(std::vector<shape> inputs) const;
argument argument
......
...@@ -14,6 +14,12 @@ struct hip_concat ...@@ -14,6 +14,12 @@ struct hip_concat
{ {
op::concat op; op::concat op;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return migraphx::reflect(self.op, f);
}
std::string name() const { return "gpu::concat"; } std::string name() const { return "gpu::concat"; }
shape compute_shape(std::vector<shape> inputs) const; shape compute_shape(std::vector<shape> inputs) const;
argument argument
......
...@@ -13,6 +13,13 @@ struct context; ...@@ -13,6 +13,13 @@ struct context;
struct miopen_contiguous struct miopen_contiguous
{ {
op::contiguous op; op::contiguous op;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return migraphx::reflect(self.op, f);
}
std::string name() const { return "gpu::contiguous"; } std::string name() const { return "gpu::contiguous"; }
shape compute_shape(const std::vector<shape>& inputs) const; shape compute_shape(const std::vector<shape>& inputs) const;
argument compute(context&, shape output_shape, const std::vector<argument>& args) const; argument compute(context&, shape output_shape, const std::vector<argument>& args) const;
......
...@@ -13,6 +13,13 @@ struct context; ...@@ -13,6 +13,13 @@ struct context;
struct miopen_elu struct miopen_elu
{ {
shared<activation_descriptor> ad; shared<activation_descriptor> ad;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return gpu::reflect(self.ad.get(), f);
}
std::string name() const { return "gpu::elu"; } std::string name() const { return "gpu::elu"; }
shape compute_shape(const std::vector<shape>& inputs) const; shape compute_shape(const std::vector<shape>& inputs) const;
argument argument
......
...@@ -14,6 +14,13 @@ struct context; ...@@ -14,6 +14,13 @@ struct context;
struct hip_gather struct hip_gather
{ {
op::gather op; op::gather op;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return migraphx::reflect(self.op, f);
}
std::string name() const { return "gpu::gather"; } std::string name() const { return "gpu::gather"; }
shape compute_shape(std::vector<shape> inputs) const; shape compute_shape(std::vector<shape> inputs) const;
argument argument
......
...@@ -13,6 +13,13 @@ struct context; ...@@ -13,6 +13,13 @@ struct context;
struct miopen_gemm struct miopen_gemm
{ {
op::dot op; op::dot op;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return migraphx::reflect(self.op, f);
}
std::string name() const { return "gpu::gemm"; } std::string name() const { return "gpu::gemm"; }
shape compute_shape(const std::vector<shape>& inputs) const; shape compute_shape(const std::vector<shape>& inputs) const;
argument argument
......
...@@ -28,6 +28,13 @@ struct hip_allocate ...@@ -28,6 +28,13 @@ struct hip_allocate
{ {
shape s; shape s;
std::string tag{}; std::string tag{};
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return pack(f(self.s, "shape"), f(self.tag, "tag"));
}
std::string name() const { return "hip::allocate"; } std::string name() const { return "hip::allocate"; }
shape compute_shape(const std::vector<shape>& inputs) const shape compute_shape(const std::vector<shape>& inputs) const
{ {
...@@ -43,6 +50,13 @@ struct hip_allocate ...@@ -43,6 +50,13 @@ struct hip_allocate
struct hip_sync struct hip_sync
{ {
std::string tag{}; std::string tag{};
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return pack(f(self.tag, "tag"));
}
std::string name() const { return "hip::sync"; } std::string name() const { return "hip::sync"; }
shape compute_shape(const std::vector<shape>& inputs) const shape compute_shape(const std::vector<shape>& inputs) const
{ {
......
...@@ -13,6 +13,13 @@ struct context; ...@@ -13,6 +13,13 @@ struct context;
struct miopen_leaky_relu struct miopen_leaky_relu
{ {
shared<activation_descriptor> ad; shared<activation_descriptor> ad;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return gpu::reflect(self.ad.get(), f);
}
std::string name() const { return "gpu::leaky_relu"; } std::string name() const { return "gpu::leaky_relu"; }
shape compute_shape(const std::vector<shape>& inputs) const; shape compute_shape(const std::vector<shape>& inputs) const;
argument argument
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment