decompose.cpp 2.95 KB
Newer Older
1
2
3
4
5
6
7
8
9
#include <migraphx/decompose.hpp>
#include <migraphx/program.hpp>
#include <migraphx/instruction.hpp>
#include <migraphx/iterator_for.hpp>
#include <migraphx/functional.hpp>
#include <migraphx/ranges.hpp>
#include <migraphx/float_equal.hpp>
#include <migraphx/matcher.hpp>
#include <migraphx/op/dot.hpp>
10
11
#include <migraphx/make_op.hpp>

12
13
14
15
16
17
18
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
namespace {
struct find_dot_add
{
    auto matcher() const { return match::name("dot")(match::nargs(3)); }

19
    void apply(module& p, const match::matcher_result& r) const
20
21
22
23
24
25
26
    {
        auto ins = r.result;
        auto dot = any_cast<op::dot>(ins->get_operator());
        if(not float_equal(dot.beta, 1) and
           not contains({shape::float_type, shape::half_type, shape::double_type},
                        ins->get_shape().type()))
            return;
27
28
29
30
31
32
33
34
35
36
37
38
39
40
        auto a_ins = ins->inputs()[0];
        auto b_ins = ins->inputs()[1];
        if(not float_equal(dot.alpha, 1))
        {
            auto alpha = p.add_literal(literal{shape{ins->get_shape().type()}, {dot.alpha}});
            auto alpha_broadcast = p.insert_instruction(
                ins,
                make_op("multibroadcast", {{"output_lens", a_ins->get_shape().lens()}}),
                alpha);
            a_ins = p.insert_instruction(ins, make_op("mul"), a_ins, alpha_broadcast);
        }
        auto dot_ins = p.insert_instruction(ins, make_op("dot", {{"beta", 0}}), a_ins, b_ins);

        auto c_ins = ins->inputs()[2];
41
42
43
        if(not float_equal(dot.beta, 1))
        {
            auto beta = p.add_literal(literal{shape{ins->get_shape().type()}, {dot.beta}});
44
45
46
            auto beta_broadcast = p.insert_instruction(
                ins, make_op("multibroadcast", {{"output_lens", ins->get_shape().lens()}}), beta);
            c_ins = p.insert_instruction(ins, make_op("mul"), c_ins, beta_broadcast);
47
        }
48
        p.replace_instruction(ins, make_op("add"), dot_ins, c_ins);
49
50
51
    }
};

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
struct find_dot_alpha
{
    auto matcher() const { return match::name("dot")(match::nargs(2)); }

    void apply(program& p, const match::matcher_result& r) const
    {
        auto ins   = r.result;
        auto dot   = any_cast<op::dot>(ins->get_operator());
        auto a_ins = ins->inputs()[0];
        auto b_ins = ins->inputs()[1];
        if(not float_equal(dot.alpha, 1))
        {
            auto alpha = p.add_literal(literal{shape{ins->get_shape().type()}, {dot.alpha}});
            auto alpha_broadcast = p.insert_instruction(
                ins,
                make_op("multibroadcast", {{"output_lens", a_ins->get_shape().lens()}}),
                alpha);
            a_ins = p.insert_instruction(ins, make_op("mul"), a_ins, alpha_broadcast);
        }
        p.replace_instruction(ins, make_op("dot", {{"beta", 0}}), a_ins, b_ins);
    }
};

75
76
} // namespace

77
void decompose::apply(module& p) const { match::find_matches(p, find_dot_add{}, find_dot_alpha{}); }
78
79
80

} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx