lowering.cpp 9.78 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
#include <migraphx/gpu/leaky_relu.hpp>
Khalique's avatar
Khalique committed
23
#include <migraphx/gpu/elu.hpp>
Paul's avatar
Paul committed
24
25
#include <migraphx/gpu/softmax.hpp>
#include <migraphx/gpu/add.hpp>
26
#include <migraphx/gpu/sin.hpp>
Paul's avatar
Paul committed
27
28
29
30
31
#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
32
#include <utility>
Paul's avatar
Paul committed
33

Paul's avatar
Paul committed
34
namespace migraphx {
35
inline namespace MIGRAPH_INLINE_NS {
Paul's avatar
Paul committed
36
namespace gpu {
Paul's avatar
Paul committed
37
38
39

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

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

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

Paul's avatar
Paul committed
122
    instruction_ref insert_allocation(instruction_ref ins, const shape& s, std::string tag = "")
Paul's avatar
Paul committed
123
    {
Paul's avatar
Paul committed
124
        if(ins == --prog->end() and tag.empty())
Paul's avatar
Paul committed
125
126
127
128
129
        {
            return prog->add_parameter("output", s);
        }
        else
        {
Paul's avatar
Paul committed
130
            auto is     = prog->add_outline(s);
Paul's avatar
Paul committed
131
            auto result = prog->insert_instruction(ins, hip_allocate{std::move(tag)}, is);
Paul's avatar
Paul committed
132
133
134
135
            return result;
        }
    }

Paul's avatar
Paul committed
136
    instruction_ref apply_convolution(instruction_ref ins)
Paul's avatar
Paul committed
137
    {
wsttiger's avatar
wsttiger committed
138
        auto&& op = any_cast<op::convolution>(ins->get_operator());
Paul's avatar
Paul committed
139

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

143
        auto workspace = insert_allocation(ins, ws, "workspace");
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, conv, ins->inputs().at(0), ins->inputs().at(1), workspace, output);
Paul's avatar
Paul committed
148
149
    }

Paul's avatar
Paul committed
150
    instruction_ref apply_pooling(instruction_ref ins)
Paul's avatar
Paul committed
151
    {
wsttiger's avatar
wsttiger committed
152
        auto&& op   = any_cast<op::pooling>(ins->get_operator());
Paul's avatar
Paul committed
153
        auto pd     = make_pooling(op);
Paul's avatar
Paul committed
154
        auto output = insert_allocation(ins, ins->get_shape());
Paul's avatar
Paul committed
155

Paul's avatar
Paul committed
156
        return prog->replace_instruction(
Paul's avatar
Paul committed
157
            ins, miopen_pooling{op, std::move(pd)}, ins->inputs().at(0), output);
Paul's avatar
Paul committed
158
159
    }

Khalique's avatar
Khalique committed
160
    instruction_ref apply_relu(instruction_ref ins)
Paul's avatar
Paul committed
161
    {
Khalique's avatar
Khalique committed
162
        auto ad = make_relu();
Khalique's avatar
Khalique committed
163
164
165
166

        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
167
    }
168

Khalique's avatar
Khalique committed
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
    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
196
197
198
199
    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);
200

Khalique's avatar
Khalique committed
201
202
203
204
        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
205

Khalique's avatar
Khalique committed
206
207
208
209
210
211
212
213
214
215
    instruction_ref apply_elu(instruction_ref ins)
    {
        auto&& op = any_cast<op::leaky_relu>(ins->get_operator());
        auto ad   = make_elu(op.alpha);

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

Paul's avatar
Paul committed
216
217
    instruction_ref apply_softmax(instruction_ref ins)
    {
wsttiger's avatar
wsttiger committed
218
        auto&& op   = any_cast<op::softmax>(ins->get_operator());
Paul's avatar
Paul committed
219
        auto output = insert_allocation(ins, ins->get_shape());
Paul's avatar
Paul committed
220
        return prog->replace_instruction(ins, miopen_softmax{op}, ins->inputs().at(0), output);
Paul's avatar
Paul committed
221
222
    }

Paul's avatar
Paul committed
223
    instruction_ref apply_add(instruction_ref ins)
Paul's avatar
Paul committed
224
    {
Paul's avatar
Paul committed
225
        auto output = insert_allocation(ins, ins->get_shape());
Paul's avatar
Paul committed
226
        return prog->replace_instruction(
Paul's avatar
Paul committed
227
            ins, hip_add{}, ins->inputs().at(0), ins->inputs().at(1), output);
Paul's avatar
Paul committed
228
    }
Paul's avatar
Paul committed
229

230
231
232
    instruction_ref apply_sin(instruction_ref ins)
    {
        auto output = insert_allocation(ins, ins->get_shape());
Shucai Xiao's avatar
Shucai Xiao committed
233
        return prog->replace_instruction(ins, hip_sin{}, ins->inputs().at(0), output);
234
235
    }

Khalique's avatar
Khalique committed
236
237
238
239
240
241
242
    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
243
    instruction_ref apply_gemm(instruction_ref ins)
Paul's avatar
Paul committed
244
    {
Shucai Xiao's avatar
Shucai Xiao committed
245
        auto&& op   = any_cast<op::dot>(ins->get_operator());
Paul's avatar
Paul committed
246
        auto output = insert_allocation(ins, ins->get_shape());
Paul's avatar
Paul committed
247
        return prog->replace_instruction(
Paul's avatar
Paul committed
248
            ins, miopen_gemm{op}, ins->inputs().at(0), ins->inputs().at(1), output);
Paul's avatar
Paul committed
249
    }
250

Paul's avatar
Paul committed
251
    instruction_ref apply_contiguous(instruction_ref ins)
252
    {
wsttiger's avatar
wsttiger committed
253
        auto&& op   = any_cast<op::contiguous>(ins->get_operator());
Paul's avatar
Paul committed
254
        auto output = insert_allocation(ins, ins->get_shape());
Paul's avatar
Paul committed
255
        return prog->replace_instruction(ins, miopen_contiguous{op}, ins->inputs().at(0), output);
256
    }
257

258
259
    instruction_ref apply_concat(instruction_ref ins)
    {
wsttiger's avatar
wsttiger committed
260
261
        auto&& op                         = any_cast<op::concat>(ins->get_operator());
        auto output                       = insert_allocation(ins, ins->get_shape());
262
263
264
265
266
        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
267
    instruction_ref apply_batch_norm_inference(instruction_ref ins)
268
    {
wsttiger's avatar
wsttiger committed
269
        auto&& op       = any_cast<op::batch_norm_inference>(ins->get_operator());
Paul's avatar
Paul committed
270
        auto output     = insert_allocation(ins, ins->get_shape());
Paul's avatar
Paul committed
271
        shape old_shape = ins->inputs().at(1)->get_shape();
wsttiger's avatar
wsttiger committed
272
        std::vector<int64_t> new_shape{1, static_cast<int64_t>(old_shape.elements()), 1, 1};
wsttiger's avatar
wsttiger committed
273
        auto reshape_op = op::reshape{new_shape};
Paul's avatar
Paul committed
274
        std::vector<instruction_ref> reshapes;
Paul's avatar
Paul committed
275
276
        std::transform(ins->inputs().begin() + 1,
                       ins->inputs().end(),
Paul's avatar
Paul committed
277
278
                       std::back_inserter(reshapes),
                       [&](auto i) { return prog->insert_instruction(ins, reshape_op, i); });
Paul's avatar
Paul committed
279
        return prog->replace_instruction(ins,
Paul's avatar
Paul committed
280
                                         miopen_batch_norm_inference{op},
Paul's avatar
Paul committed
281
                                         ins->inputs().at(0),
Paul's avatar
Paul committed
282
283
284
285
286
                                         reshapes[0],
                                         reshapes[1],
                                         reshapes[2],
                                         reshapes[3],
                                         output);
287
    }
Paul's avatar
Paul committed
288
289
};

Paul's avatar
Paul committed
290
void lowering::apply(program& p) const { miopen_apply{&p, ctx}.apply(); }
Paul's avatar
Paul committed
291
} // namespace gpu
292
} // namespace MIGRAPH_INLINE_NS
Paul's avatar
Paul committed
293
} // namespace migraphx