fuse_mlir.cpp 3.09 KB
Newer Older
Paul's avatar
Paul committed
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <migraphx/gpu/fuse_mlir.hpp>
#include <migraphx/gpu/mlir.hpp>
#include <migraphx/matcher.hpp>
#include <migraphx/pass_manager.hpp>
#include <migraphx/make_op.hpp>

namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {

struct module;

namespace gpu {

Paul's avatar
Paul committed
14
namespace {
Paul's avatar
Paul committed
15
16
17
18
19
struct find_conv_pointwise
{
    // Find a convolution followed by a pointwise operation.
    auto matcher() const
    {
Paul's avatar
Format  
Paul committed
20
21
22
        auto convolution =
            match::skip(match::name("contiguous"))(match::name("convolution").bind("convolution"));
        return match::name("pointwise")(match::any_of[match::inputs()](convolution.bind("x")));
Paul's avatar
Paul committed
23
24
25
26
    }

    void apply(module& m, match::matcher_result r) const
    {
Paul's avatar
Format  
Paul committed
27
        auto ins      = r.result;
Paul's avatar
Paul committed
28
        auto conv_ins = r.instructions["convolution"];
Paul's avatar
Format  
Paul committed
29
30
31
        auto x_ins    = r.instructions["x"]; // input after contiguous
        auto pm       = ins->module_inputs().front();
        auto names    = pm->get_parameter_names();
Paul's avatar
Paul committed
32
        // Whitelist pointwise operators
Paul's avatar
Format  
Paul committed
33
34
35
36
        if(std::any_of(pm->begin(), pm->end(), [](const auto& i) {
               return not contains({"@literal", "@param", "@return", "convolution", "add", "relu"},
                                   i.name());
           }))
Paul's avatar
Paul committed
37
            return;
Paul's avatar
Paul committed
38
39
40
        std::sort(names.begin(), names.end());
        module mm{};
        std::unordered_map<instruction_ref, instruction_ref> param_map;
Paul's avatar
Format  
Paul committed
41
42
43
44
        auto x    = mm.add_parameter("x" + std::to_string(names.size()),
                                  conv_ins->inputs().at(0)->get_shape());
        auto w    = mm.add_parameter("x" + std::to_string(names.size() + 1),
                                  conv_ins->inputs().at(1)->get_shape());
Paul's avatar
Paul committed
45
        auto conv = mm.add_instruction(conv_ins->get_operator(), {x, w});
Paul's avatar
Format  
Paul committed
46
47
48
49
50
51
52
53
54
55
        std::transform(names.begin(),
                       names.end(),
                       ins->inputs().begin(),
                       std::inserter(param_map, param_map.end()),
                       [&](auto name, auto input) {
                           if(input == x_ins)
                               return std::make_pair(pm->get_parameter(name), conv);
                           return std::make_pair(pm->get_parameter(name),
                                                 mm.add_parameter(name, input->get_shape()));
                       });
Paul's avatar
Paul committed
56
57
        mm.add_return(mm.insert_module_instructions(mm.end(), pm, param_map));

Paul's avatar
Paul committed
58
        std::vector<instruction_ref> inputs;
Paul's avatar
Format  
Paul committed
59
60
61
62
        std::copy_if(ins->inputs().begin(),
                     ins->inputs().end(),
                     std::back_inserter(inputs),
                     [&](auto input) { return input != conv_ins; });
Paul's avatar
Paul committed
63
        inputs.insert(inputs.end(), conv_ins->inputs().begin(), conv_ins->inputs().end());
Paul's avatar
Format  
Paul committed
64
65
        inputs.push_back(m.insert_instruction(
            ins, make_op("hip::allocate", {{"shape", to_value(ins->get_shape())}})));
Paul's avatar
Paul committed
66
67
68
69
        auto mlir = insert_mlir(m, ins, mm, inputs);
        m.replace_instruction(ins, mlir);
    }
};
Paul's avatar
Format  
Paul committed
70
} // namespace
Paul's avatar
Paul committed
71

Paul's avatar
Format  
Paul committed
72
void fuse_mlir::apply(module& m) const { match::find_matches(m, find_conv_pointwise{}); }
Paul's avatar
Paul committed
73

Paul's avatar
Format  
Paul committed
74
} // namespace gpu
Paul's avatar
Paul committed
75
76
77

} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx