lowering.cpp 8.94 KB
Newer Older
1
#include <rocblas.h>
Paul's avatar
Paul committed
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <migraphx/gpu/lowering.hpp>
#include <migraphx/manage_ptr.hpp>
#include <migraphx/instruction.hpp>
#include <migraphx/operators.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/shape_for_each.hpp>
#include <migraphx/gpu/miopen.hpp>
#include <migraphx/gpu/hip.hpp>
#include <migraphx/dfor.hpp>
#include <migraphx/gpu/device/contiguous.hpp>
#include <migraphx/gpu/device/add.hpp>
#include <migraphx/iterator_for.hpp>
#include <migraphx/gpu/rocblas.hpp>
#include <migraphx/gpu/context.hpp>
#include <migraphx/gpu/convolution.hpp>
#include <migraphx/gpu/contiguous.hpp>
#include <migraphx/gpu/relu.hpp>
Khalique's avatar
Khalique committed
19
20
21
#include <migraphx/gpu/sigmoid.hpp>
#include <migraphx/gpu/tanh.hpp>
#include <migraphx/gpu/abs.hpp>
Paul's avatar
Paul committed
22
23
24
25
26
27
28
29
#include <migraphx/gpu/leaky_relu.hpp>
#include <migraphx/gpu/softmax.hpp>
#include <migraphx/gpu/add.hpp>
#include <migraphx/gpu/mul.hpp>
#include <migraphx/gpu/batchnorm.hpp>
#include <migraphx/gpu/pooling.hpp>
#include <migraphx/gpu/gemm.hpp>
#include <migraphx/gpu/concat.hpp>
Paul's avatar
Paul committed
30
#include <utility>
Paul's avatar
Paul committed
31

Paul's avatar
Paul committed
32
namespace migraphx {
33
inline namespace MIGRAPH_INLINE_NS {
Paul's avatar
Paul committed
34
namespace gpu {
Paul's avatar
Paul committed
35
36
37

struct miopen_apply
{
Paul's avatar
Paul committed
38
    program* prog = nullptr;
Paul's avatar
Paul committed
39
    context ctx{};
Paul's avatar
Paul committed
40

Paul's avatar
Paul committed
41
42
43
44
45
46
47
    void check_shape(shape x, instruction_ref i)
    {
        assert(x == i->get_shape());
        (void)x;
        (void)i;
    }

Paul's avatar
Paul committed
48
49
    void apply()
    {
Paul's avatar
Paul committed
50
51
        for(auto it = prog->begin(); it != prog->end(); it++)
        {
Paul's avatar
Paul committed
52
            auto s = it->get_shape();
Paul's avatar
Paul committed
53
            if(it->name() == "convolution")
Paul's avatar
Paul committed
54
            {
Paul's avatar
Paul committed
55
                check_shape(s, apply_convolution(it));
Paul's avatar
Paul committed
56
            }
Khalique's avatar
Khalique committed
57
            else if(it->name() == "relu")
Paul's avatar
Paul committed
58
            {
Khalique's avatar
Khalique committed
59
                check_shape(s, apply_relu(it));
Paul's avatar
Paul committed
60
            }
Khalique's avatar
Khalique committed
61
62
63
64
65
66
67
68
69
70
71
72
            else if(it->name() == "sigmoid")
            {
                check_shape(s, apply_sigmoid(it));
            }
            else if(it->name() == "tanh")
            {
                check_shape(s, apply_tanh(it));
            }
            else if(it->name() == "abs")
            {
                check_shape(s, apply_abs(it));
            }
Khalique's avatar
Khalique committed
73
74
75
76
            else if(it->name() == "leaky_relu")
            {
                check_shape(s, apply_leaky_relu(it));
            }
Paul's avatar
Paul committed
77
            else if(it->name() == "pooling")
Paul's avatar
Paul committed
78
            {
Paul's avatar
Paul committed
79
                check_shape(s, apply_pooling(it));
Paul's avatar
Paul committed
80
            }
Paul's avatar
Paul committed
81
            else if(it->name() == "add")
Paul's avatar
Paul committed
82
            {
Paul's avatar
Paul committed
83
                check_shape(s, apply_add(it));
Paul's avatar
Paul committed
84
            }
Khalique's avatar
Khalique committed
85
86
87
88
            else if(it->name() == "mul")
            {
                check_shape(s, apply_mul(it));
            }
Shucai Xiao's avatar
Shucai Xiao committed
89
            else if(it->name() == "dot")
Paul's avatar
Paul committed
90
            {
Paul's avatar
Paul committed
91
                check_shape(s, apply_gemm(it));
Paul's avatar
Paul committed
92
            }
Paul's avatar
Paul committed
93
            else if(it->name() == "contiguous")
94
            {
Paul's avatar
Paul committed
95
                check_shape(s, apply_contiguous(it));
96
            }
97
98
99
100
            else if(it->name() == "concat")
            {
                check_shape(s, apply_concat(it));
            }
Paul's avatar
Paul committed
101
            else if(it->name() == "batch_norm_inference")
102
            {
Paul's avatar
Paul committed
103
                check_shape(s, apply_batch_norm_inference(it));
104
            }
Paul's avatar
Paul committed
105
106
107
108
            else if(it->name() == "softmax")
            {
                check_shape(s, apply_softmax(it));
            }
Paul's avatar
Paul committed
109
110
111
        }
    }

Paul's avatar
Paul committed
112
    instruction_ref insert_allocation(instruction_ref ins, const shape& s, std::string tag = "")
Paul's avatar
Paul committed
113
    {
Paul's avatar
Paul committed
114
        if(ins == --prog->end() and tag.empty())
Paul's avatar
Paul committed
115
116
117
118
119
        {
            return prog->add_parameter("output", s);
        }
        else
        {
Paul's avatar
Paul committed
120
            auto is     = prog->add_outline(s);
Paul's avatar
Paul committed
121
            auto result = prog->insert_instruction(ins, hip_allocate{std::move(tag)}, is);
Paul's avatar
Paul committed
122
123
124
125
            return result;
        }
    }

Paul's avatar
Paul committed
126
    instruction_ref apply_convolution(instruction_ref ins)
Paul's avatar
Paul committed
127
    {
wsttiger's avatar
wsttiger committed
128
        auto&& op = any_cast<op::convolution>(ins->get_operator());
Paul's avatar
Paul committed
129

Paul's avatar
Paul committed
130
        auto conv = miopen_convolution{op, make_conv(op)};
Paul's avatar
Paul committed
131
        auto ws   = conv.compile(ctx, ins->get_shape(), ins->inputs());
Paul's avatar
Paul committed
132

133
        auto workspace = insert_allocation(ins, ws, "workspace");
Paul's avatar
Paul committed
134
        auto output    = insert_allocation(ins, ins->get_shape());
Paul's avatar
Paul committed
135

Paul's avatar
Paul committed
136
        return prog->replace_instruction(
Paul's avatar
Paul committed
137
            ins, conv, ins->inputs().at(0), ins->inputs().at(1), workspace, output);
Paul's avatar
Paul committed
138
139
    }

Paul's avatar
Paul committed
140
    instruction_ref apply_pooling(instruction_ref ins)
Paul's avatar
Paul committed
141
    {
wsttiger's avatar
wsttiger committed
142
        auto&& op   = any_cast<op::pooling>(ins->get_operator());
Paul's avatar
Paul committed
143
        auto pd     = make_pooling(op);
Paul's avatar
Paul committed
144
        auto output = insert_allocation(ins, ins->get_shape());
Paul's avatar
Paul committed
145

Paul's avatar
Paul committed
146
        return prog->replace_instruction(
Paul's avatar
Paul committed
147
            ins, miopen_pooling{op, std::move(pd)}, ins->inputs().at(0), output);
Paul's avatar
Paul committed
148
149
    }

Khalique's avatar
Khalique committed
150
    instruction_ref apply_relu(instruction_ref ins)
Paul's avatar
Paul committed
151
    {
Khalique's avatar
Khalique committed
152
        auto ad = make_relu();
Khalique's avatar
Khalique committed
153
154
155
156

        auto output = insert_allocation(ins, ins->get_shape());
        return prog->replace_instruction(
            ins, miopen_relu{std::move(ad)}, ins->inputs().at(0), output);
Paul's avatar
Paul committed
157
    }
158

Khalique's avatar
Khalique committed
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
    instruction_ref apply_sigmoid(instruction_ref ins)
    {
        auto ad = make_sigmoid();

        auto output = insert_allocation(ins, ins->get_shape());
        return prog->replace_instruction(
            ins, miopen_sigmoid{std::move(ad)}, ins->inputs().at(0), output);
    }

    instruction_ref apply_tanh(instruction_ref ins)
    {
        auto ad = make_tanh();

        auto output = insert_allocation(ins, ins->get_shape());
        return prog->replace_instruction(
            ins, miopen_tanh{std::move(ad)}, ins->inputs().at(0), output);
    }

    instruction_ref apply_abs(instruction_ref ins)
    {
        auto ad = make_abs();

        auto output = insert_allocation(ins, ins->get_shape());
        return prog->replace_instruction(
            ins, miopen_abs{std::move(ad)}, ins->inputs().at(0), output);
    }

Khalique's avatar
Khalique committed
186
187
188
189
    instruction_ref apply_leaky_relu(instruction_ref ins)
    {
        auto&& op = any_cast<op::leaky_relu>(ins->get_operator());
        auto ad   = make_leaky_relu(op.alpha);
190

Khalique's avatar
Khalique committed
191
192
193
194
        auto output = insert_allocation(ins, ins->get_shape());
        return prog->replace_instruction(
            ins, miopen_leaky_relu{std::move(ad)}, ins->inputs().at(0), output);
    }
Paul's avatar
Paul committed
195

Paul's avatar
Paul committed
196
197
    instruction_ref apply_softmax(instruction_ref ins)
    {
wsttiger's avatar
wsttiger committed
198
        auto&& op   = any_cast<op::softmax>(ins->get_operator());
Paul's avatar
Paul committed
199
        auto output = insert_allocation(ins, ins->get_shape());
Paul's avatar
Paul committed
200
        return prog->replace_instruction(ins, miopen_softmax{op}, ins->inputs().at(0), output);
Paul's avatar
Paul committed
201
202
    }

Paul's avatar
Paul committed
203
    instruction_ref apply_add(instruction_ref ins)
Paul's avatar
Paul committed
204
    {
Paul's avatar
Paul committed
205
        auto output = insert_allocation(ins, ins->get_shape());
Paul's avatar
Paul committed
206
        return prog->replace_instruction(
Paul's avatar
Paul committed
207
            ins, hip_add{}, ins->inputs().at(0), ins->inputs().at(1), output);
Paul's avatar
Paul committed
208
    }
Paul's avatar
Paul committed
209

Khalique's avatar
Khalique committed
210
211
212
213
214
215
216
    instruction_ref apply_mul(instruction_ref ins)
    {
        auto output = insert_allocation(ins, ins->get_shape());
        return prog->replace_instruction(
            ins, hip_mul{}, ins->inputs().at(0), ins->inputs().at(1), output);
    }

Paul's avatar
Paul committed
217
    instruction_ref apply_gemm(instruction_ref ins)
Paul's avatar
Paul committed
218
    {
Shucai Xiao's avatar
Shucai Xiao committed
219
        auto&& op   = any_cast<op::dot>(ins->get_operator());
Paul's avatar
Paul committed
220
        auto output = insert_allocation(ins, ins->get_shape());
Paul's avatar
Paul committed
221
        return prog->replace_instruction(
Paul's avatar
Paul committed
222
            ins, miopen_gemm{op}, ins->inputs().at(0), ins->inputs().at(1), output);
Paul's avatar
Paul committed
223
    }
224

Paul's avatar
Paul committed
225
    instruction_ref apply_contiguous(instruction_ref ins)
226
    {
wsttiger's avatar
wsttiger committed
227
        auto&& op   = any_cast<op::contiguous>(ins->get_operator());
Paul's avatar
Paul committed
228
        auto output = insert_allocation(ins, ins->get_shape());
Paul's avatar
Paul committed
229
        return prog->replace_instruction(ins, miopen_contiguous{op}, ins->inputs().at(0), output);
230
    }
231

232
233
    instruction_ref apply_concat(instruction_ref ins)
    {
wsttiger's avatar
wsttiger committed
234
235
        auto&& op                         = any_cast<op::concat>(ins->get_operator());
        auto output                       = insert_allocation(ins, ins->get_shape());
236
237
238
239
240
        std::vector<instruction_ref> refs = ins->inputs();
        refs.push_back(output);
        return prog->replace_instruction(ins, hip_concat{op}, refs);
    }

Paul's avatar
Paul committed
241
    instruction_ref apply_batch_norm_inference(instruction_ref ins)
242
    {
wsttiger's avatar
wsttiger committed
243
        auto&& op       = any_cast<op::batch_norm_inference>(ins->get_operator());
Paul's avatar
Paul committed
244
        auto output     = insert_allocation(ins, ins->get_shape());
Paul's avatar
Paul committed
245
        shape old_shape = ins->inputs().at(1)->get_shape();
wsttiger's avatar
wsttiger committed
246
        std::vector<int64_t> new_shape{1, static_cast<int64_t>(old_shape.elements()), 1, 1};
wsttiger's avatar
wsttiger committed
247
        auto reshape_op = op::reshape{new_shape};
Paul's avatar
Paul committed
248
        std::vector<instruction_ref> reshapes;
Paul's avatar
Paul committed
249
250
        std::transform(ins->inputs().begin() + 1,
                       ins->inputs().end(),
Paul's avatar
Paul committed
251
252
                       std::back_inserter(reshapes),
                       [&](auto i) { return prog->insert_instruction(ins, reshape_op, i); });
Paul's avatar
Paul committed
253
        return prog->replace_instruction(ins,
Paul's avatar
Paul committed
254
                                         miopen_batch_norm_inference{op},
Paul's avatar
Paul committed
255
                                         ins->inputs().at(0),
Paul's avatar
Paul committed
256
257
258
259
260
                                         reshapes[0],
                                         reshapes[1],
                                         reshapes[2],
                                         reshapes[3],
                                         output);
261
    }
Paul's avatar
Paul committed
262
263
};

Paul's avatar
Paul committed
264
void lowering::apply(program& p) const { miopen_apply{&p, ctx}.apply(); }
Paul's avatar
Paul committed
265
} // namespace gpu
266
} // namespace MIGRAPH_INLINE_NS
Paul's avatar
Paul committed
267
} // namespace migraphx