Commit eb0d8fee authored by Paul's avatar Paul
Browse files

Merge branch 'develop' into driver

parents 65ef35cd 0d796941
...@@ -18,6 +18,11 @@ struct check_shapes ...@@ -18,6 +18,11 @@ struct check_shapes
{ {
} }
template <class Op>
check_shapes(const shape* b, const shape* e, const Op& op) : begin(b), end(e), name(op.name())
{
}
check_shapes(const std::vector<shape>& s) : begin(s.data()), end(s.data() + s.size()) {} check_shapes(const std::vector<shape>& s) : begin(s.data()), end(s.data() + s.size()) {}
template <class Op> template <class Op>
...@@ -98,6 +103,13 @@ struct check_shapes ...@@ -98,6 +103,13 @@ struct check_shapes
return *this; return *this;
} }
const check_shapes& standard_or_scalar() const
{
if(!this->all_of([](const shape& s) { return s.standard() or s.scalar(); }))
MIGRAPHX_THROW(prefix() + "Shapes are not a scalar or in standard layout");
return *this;
}
const check_shapes& packed() const const check_shapes& packed() const
{ {
if(!this->all_of([](const shape& s) { return s.packed(); })) if(!this->all_of([](const shape& s) { return s.packed(); }))
...@@ -119,6 +131,13 @@ struct check_shapes ...@@ -119,6 +131,13 @@ struct check_shapes
return *this; return *this;
} }
const check_shapes& elements(std::size_t n) const
{
if(!this->all_of([&](const shape& s) { return s.elements() == n; }))
MIGRAPHX_THROW(prefix() + "Wrong number of elements");
return *this;
}
template <class F> template <class F>
bool same(F f) const bool same(F f) const
{ {
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include <utility> #include <utility>
#include <migraphx/operation.hpp> #include <migraphx/operation.hpp>
#include <migraphx/operators.hpp> #include <migraphx/op/concat.hpp>
#include <migraphx/config.hpp> #include <migraphx/config.hpp>
namespace migraphx { namespace migraphx {
......
#ifndef MIGRAPHX_GUARD_RTGLIB_ELIMINATE_IDENTITY_HPP
#define MIGRAPHX_GUARD_RTGLIB_ELIMINATE_IDENTITY_HPP
#include <string>
#include <migraphx/instruction_ref.hpp>
#include <migraphx/config.hpp>
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
struct program;
/**
* Remove identity instructions. Currently when used as the last pass, it will
* preserve the semantics of previous program state, therefore dead code elimination
* should not be used afterwards.
*/
struct eliminate_identity
{
std::string name() const { return "eliminate_identity"; }
void apply(program& p) const;
};
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
#endif
#ifndef MIGRAPHX_GUARD_RTGLIB_ELIMINATE_PAD_HPP
#define MIGRAPHX_GUARD_RTGLIB_ELIMINATE_PAD_HPP
#include <string>
#include <vector>
#include <array>
#include <migraphx/instruction_ref.hpp>
#include <migraphx/config.hpp>
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
struct program;
/**
* Remove pads if they can be written as an
* attribute to another op (im2col, convolution, pooling)
*/
struct eliminate_pad
{
std::string name() const { return "eliminate_pad"; }
void apply(program& p) const;
template <class T>
void update_op(T, const instruction_ref& input, const instruction_ref& ins, program& p) const;
};
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
#endif
...@@ -19,6 +19,8 @@ bool enabled(const char* name); ...@@ -19,6 +19,8 @@ bool enabled(const char* name);
bool disabled(const char* name); bool disabled(const char* name);
std::vector<std::string> env(const char* name); std::vector<std::string> env(const char* name);
std::size_t value_of(const char* name);
template <class T> template <class T>
bool enabled(T) bool enabled(T)
{ {
...@@ -33,6 +35,13 @@ bool disabled(T) ...@@ -33,6 +35,13 @@ bool disabled(T)
return result; return result;
} }
template <class T>
std::size_t value_of(T)
{
static const std::size_t result = value_of(T::value());
return result;
}
} // namespace MIGRAPHX_INLINE_NS } // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx } // namespace migraphx
......
...@@ -137,6 +137,18 @@ auto fold(F f) ...@@ -137,6 +137,18 @@ auto fold(F f)
return [=](auto&&... xs) { return fold_impl(f, std::forward<decltype(xs)>(xs)...); }; return [=](auto&&... xs) { return fold_impl(f, std::forward<decltype(xs)>(xs)...); };
} }
template <class F, class Proj>
auto by(F f, Proj proj)
{
return [=](auto&&... xs) { return f(proj(std::forward<decltype(xs)>(xs))...); };
}
template <class T>
auto index_of(T& x)
{
return [&](auto&& y) { return x[y]; };
}
} // namespace MIGRAPHX_INLINE_NS } // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx } // namespace migraphx
......
...@@ -17,7 +17,7 @@ constexpr T normalize(unsigned long z) ...@@ -17,7 +17,7 @@ constexpr T normalize(unsigned long z)
return T(0); return T(0);
const auto max = 32; const auto max = 32;
const double range = max / 2; // NOLINT const double range = max / 2; // NOLINT
double result = (z % max) / range; double result = double(z % max) / range;
result -= 1; result -= 1;
return T(result); return T(result);
} }
......
...@@ -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();
...@@ -72,7 +72,9 @@ struct instruction ...@@ -72,7 +72,9 @@ struct instruction
static void static void
replace(instruction_ref ins, operation o, const shape& r, std::vector<instruction_ref> args); replace(instruction_ref ins, operation o, const shape& r, std::vector<instruction_ref> args);
argument eval() const; bool can_eval() const;
argument eval(bool check_eval = true) const;
void finalize(context& ctx); void finalize(context& ctx);
...@@ -88,7 +90,8 @@ struct instruction ...@@ -88,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;
......
#ifndef MIGRAPHX_GUARD_RTGLIB_INT_DIVIDE_HPP
#define MIGRAPHX_GUARD_RTGLIB_INT_DIVIDE_HPP
#include <migraphx/config.hpp>
#include <cmath>
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
template <class R, class T, class U>
R floor_divide(T x, U y)
{
return R(std::floor(double(x) / double(y)));
}
template <class R, class T, class U>
R ceil_divide(T x, U y)
{
return R(std::ceil(double(x) / double(y)));
}
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
#endif
...@@ -3,21 +3,64 @@ ...@@ -3,21 +3,64 @@
#include <cassert> #include <cassert>
#include <type_traits> #include <type_traits>
#include <iterator>
#include <migraphx/config.hpp> #include <migraphx/config.hpp>
namespace migraphx { namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS { inline namespace MIGRAPHX_INLINE_NS {
template <class T> struct iterator_for_select
{
template <class T>
static T deref(T x)
{
return x;
}
template <class T>
static auto begin(T* x)
{
return x->begin();
}
template <class T>
static auto end(T* x)
{
return x->end();
}
};
struct iterator_for_select_reverse
{
template <class T>
static auto deref(T x)
{
return std::prev(x.base());
}
template <class T>
static auto begin(T* x)
{
return std::make_reverse_iterator(x->end());
}
template <class T>
static auto end(T* x)
{
return std::make_reverse_iterator(x->begin());
}
};
template <class T, class Selector = iterator_for_select>
struct iterator_for_range struct iterator_for_range
{ {
T* base; T* base;
using base_iterator = std::remove_reference_t<decltype(base->begin())>; using base_iterator = std::remove_reference_t<decltype(Selector::begin(base))>;
struct iterator struct iterator
{ {
base_iterator i; base_iterator i;
base_iterator operator*() const { return i; } auto operator*() const { return Selector::deref(i); }
base_iterator operator++() { return ++i; } base_iterator operator++() { return ++i; }
bool operator!=(const iterator& rhs) const { return i != rhs.i; } bool operator!=(const iterator& rhs) const { return i != rhs.i; }
}; };
...@@ -25,12 +68,12 @@ struct iterator_for_range ...@@ -25,12 +68,12 @@ struct iterator_for_range
iterator begin() iterator begin()
{ {
assert(base != nullptr); assert(base != nullptr);
return {base->begin()}; return {Selector::begin(base)};
} }
iterator end() iterator end()
{ {
assert(base != nullptr); assert(base != nullptr);
return {base->end()}; return {Selector::end(base)};
} }
}; };
template <class T> template <class T>
...@@ -39,6 +82,12 @@ iterator_for_range<T> iterator_for(T& x) ...@@ -39,6 +82,12 @@ iterator_for_range<T> iterator_for(T& x)
return {&x}; return {&x};
} }
template <class T>
iterator_for_range<T, iterator_for_select_reverse> reverse_iterator_for(T& x)
{
return {&x};
}
} // namespace MIGRAPHX_INLINE_NS } // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx } // namespace migraphx
......
...@@ -22,8 +22,8 @@ struct literal : raw_data<literal> ...@@ -22,8 +22,8 @@ struct literal : raw_data<literal>
{ {
literal() {} literal() {}
template <class U, class T = deduce<U>> template <class U, class T = deduce<U>, shape::type_t ShapeType = shape::get_type<T>{}>
literal(U x) : buffer(make_shared_array<char>(sizeof(T))), m_shape(shape::get_type<T>{}) literal(U x) : buffer(make_shared_array<char>(sizeof(T))), m_shape(ShapeType)
{ {
static_assert(std::is_trivially_copyable<T>{}, "Literals can only be trivial types"); static_assert(std::is_trivially_copyable<T>{}, "Literals can only be trivial types");
*(reinterpret_cast<T*>(buffer.get())) = x; *(reinterpret_cast<T*>(buffer.get())) = x;
......
#ifndef MIGRAPHX_GUARD_RTGLIB_MAKE_SIGNED_HPP
#define MIGRAPHX_GUARD_RTGLIB_MAKE_SIGNED_HPP
#include <migraphx/config.hpp>
#include <type_traits>
#include <utility>
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
template <class T>
typename std::conditional_t<std::is_integral<T>{}, std::make_signed<T>, std::enable_if<true, T>>::
type
make_signed(T x)
{
return x;
}
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
#endif
...@@ -7,24 +7,6 @@ ...@@ -7,24 +7,6 @@
namespace migraphx { namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS { inline namespace MIGRAPHX_INLINE_NS {
struct unknown
{
std::string op;
std::string name() const { return "unknown:" + op; }
shape compute_shape(std::vector<shape> input) const
{
if(input.empty())
return {};
else
return input.front();
}
friend std::ostream& operator<<(std::ostream& os, const unknown& x)
{
os << x.name();
return os;
}
};
/// Create a program from an onnx file /// Create a program from an onnx file
program parse_onnx(const std::string& name); program parse_onnx(const std::string& name);
......
#ifndef MIGRAPHX_GUARD_OPERATORS_ABNORMAL_OPS_HPP
#define MIGRAPHX_GUARD_OPERATORS_ABNORMAL_OPS_HPP
#include <array>
#include <migraphx/operation.hpp>
#include <migraphx/check_shapes.hpp>
#include <migraphx/stringutils.hpp>
#include <migraphx/streamutils.hpp>
#include <migraphx/literal.hpp>
#include <migraphx/shape_for_each.hpp>
#include <migraphx/config.hpp>
#include <cmath>
#include <utility>
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
namespace op {
struct not_computable
{
argument compute(const shape&, const std::vector<argument>&) const
{
MIGRAPHX_THROW("not computable");
}
};
struct undefined
{
std::string name() const { return "undefined"; }
shape compute_shape(const std::vector<shape>& inputs) const
{
check_shapes{inputs, *this}.has(0);
return {};
}
argument compute(const shape&, const std::vector<argument>&) const { return {{}, nullptr}; }
};
struct unknown
{
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; }
shape compute_shape(std::vector<shape> input) const
{
if(input.empty())
return {};
else
return input.front();
}
friend std::ostream& operator<<(std::ostream& os, const unknown& x)
{
os << x.name();
return os;
}
};
} // namespace op
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
#endif
#ifndef MIGRAPHX_GUARD_OPERATORS_ABS_HPP
#define MIGRAPHX_GUARD_OPERATORS_ABS_HPP
#include <array>
#include <migraphx/op/unary.hpp>
#include <migraphx/operation.hpp>
#include <migraphx/check_shapes.hpp>
#include <migraphx/stringutils.hpp>
#include <migraphx/streamutils.hpp>
#include <migraphx/literal.hpp>
#include <migraphx/shape_for_each.hpp>
#include <migraphx/config.hpp>
#include <migraphx/make_signed.hpp>
#include <cmath>
#include <utility>
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
namespace op {
struct abs : unary<abs>
{
auto apply() const
{
return [](auto x) { return std::abs(make_signed(x)); };
}
};
} // namespace op
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
#endif
#ifndef MIGRAPHX_GUARD_OPERATORS_ACOS_HPP
#define MIGRAPHX_GUARD_OPERATORS_ACOS_HPP
#include <array>
#include <migraphx/op/unary.hpp>
#include <migraphx/operation.hpp>
#include <migraphx/check_shapes.hpp>
#include <migraphx/stringutils.hpp>
#include <migraphx/streamutils.hpp>
#include <migraphx/literal.hpp>
#include <migraphx/shape_for_each.hpp>
#include <migraphx/config.hpp>
#include <cmath>
#include <utility>
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
namespace op {
struct acos : unary<acos>
{
auto apply() const
{
return [](auto x) { return std::acos(x); };
}
};
} // namespace op
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
#endif
#ifndef MIGRAPHX_GUARD_OPERATORS_ADD_HPP
#define MIGRAPHX_GUARD_OPERATORS_ADD_HPP
#include <array>
#include <migraphx/op/binary.hpp>
#include <migraphx/operation.hpp>
#include <migraphx/check_shapes.hpp>
#include <migraphx/stringutils.hpp>
#include <migraphx/streamutils.hpp>
#include <migraphx/literal.hpp>
#include <migraphx/shape_for_each.hpp>
#include <migraphx/config.hpp>
#include <cmath>
#include <utility>
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
namespace op {
struct add : binary<add>
{
auto apply() const
{
return [](auto x, auto y) { return x + y; };
}
};
} // namespace op
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
#endif
#ifndef MIGRAPHX_GUARD_OPERATORS_AS_SHAPE_HPP
#define MIGRAPHX_GUARD_OPERATORS_AS_SHAPE_HPP
#include <array>
#include <migraphx/operation.hpp>
#include <migraphx/check_shapes.hpp>
#include <migraphx/stringutils.hpp>
#include <migraphx/streamutils.hpp>
#include <migraphx/literal.hpp>
#include <migraphx/shape_for_each.hpp>
#include <migraphx/config.hpp>
#include <cmath>
#include <utility>
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
namespace op {
struct as_shape
{
shape s;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return pack(f(self.s, "shape"));
}
std::string name() const { return "as_shape"; }
shape compute_shape(const std::vector<shape>& inputs) const
{
check_shapes{inputs, *this}.has(1).standard();
assert(inputs.front().elements() == s.elements());
return s;
}
argument compute(shape output_shape, std::vector<argument> args) const
{
return {std::move(output_shape), std::move(args.front().data)};
}
std::ptrdiff_t output_alias(const std::vector<shape>&) const { return 0; }
};
} // namespace op
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
#endif
#ifndef MIGRAPHX_GUARD_OPERATORS_ASIN_HPP
#define MIGRAPHX_GUARD_OPERATORS_ASIN_HPP
#include <array>
#include <migraphx/op/unary.hpp>
#include <migraphx/operation.hpp>
#include <migraphx/check_shapes.hpp>
#include <migraphx/stringutils.hpp>
#include <migraphx/streamutils.hpp>
#include <migraphx/literal.hpp>
#include <migraphx/shape_for_each.hpp>
#include <migraphx/config.hpp>
#include <cmath>
#include <utility>
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
namespace op {
struct asin : unary<asin>
{
auto apply() const
{
return [](auto x) { return std::asin(x); };
}
};
} // namespace op
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
#endif
#ifndef MIGRAPHX_GUARD_OPERATORS_ATAN_HPP
#define MIGRAPHX_GUARD_OPERATORS_ATAN_HPP
#include <array>
#include <migraphx/op/unary.hpp>
#include <migraphx/operation.hpp>
#include <migraphx/check_shapes.hpp>
#include <migraphx/stringutils.hpp>
#include <migraphx/streamutils.hpp>
#include <migraphx/literal.hpp>
#include <migraphx/shape_for_each.hpp>
#include <migraphx/config.hpp>
#include <cmath>
#include <utility>
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
namespace op {
struct atan : unary<atan>
{
auto apply() const
{
return [](auto x) { return std::atan(x); };
}
};
} // namespace op
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
#endif
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