rewrite_batchnorm_test.cpp 15.2 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
Paul's avatar
Paul committed
24
#include <migraphx/rewrite_batchnorm.hpp>
Paul's avatar
Paul committed
25
#include <migraphx/program.hpp>
26
#include <migraphx/ref/target.hpp>
27
28
#include <migraphx/op/convolution.hpp>
#include <migraphx/op/reshape.hpp>
29
#include <migraphx/op/batch_norm_inference.hpp>
Paul's avatar
Paul committed
30
#include <migraphx/instruction.hpp>
31
32
#include <migraphx/generate.hpp>
#include <migraphx/ranges.hpp>
33
#include <test.hpp>
34
35
36
37
#include <migraphx/make_op.hpp>

#include <migraphx/serialize.hpp>

Paul's avatar
Paul committed
38
#include <migraphx/verify.hpp>
39

Paul's avatar
Paul committed
40
bool is_batch_norm(migraphx::instruction& ins) { return ins.name() == "batch_norm_inference"; }
41

Paul's avatar
Paul committed
42
TEST_CASE(fwd_conv_batchnorm_rewrite_test)
Scott Thornton's avatar
Scott Thornton committed
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
{
    std::vector<float> xdata = {
        0.26485917, 0.61703885, 0.32762103, 0.2503367,  0.6552712,  0.07947932, 0.95442678,
        0.70892651, 0.890563,   0.80808088, 0.89540492, 0.52657048, 0.94614791, 0.64371508,
        0.0971229,  0.2475562,  0.47405955, 0.85538928, 0.05428386, 0.993078,   0.72771973,
        0.18312255, 0.3091522,  0.51396558, 0.35158192, 0.2419852,  0.83691474, 0.36355352,
        0.04769134, 0.08312604, 0.61804092, 0.0508887,  0.30987137, 0.81307629, 0.16398955,
        0.69886166, 0.02415926, 0.60608918, 0.81907569, 0.13208211, 0.48303735, 0.87533734,
        0.92998813, 0.65553674, 0.73223327, 0.99401001, 0.09850688, 0.76972609, 0.11118327,
        0.04392097, 0.39252306, 0.91129653, 0.89078693, 0.60571206, 0.98410397, 0.15290698,
        0.86992609, 0.7575111,  0.80583525, 0.23649562, 0.7478029,  0.62888878, 0.39886601,
        0.37066793, 0.72627947, 0.8745595,  0.13568234, 0.7413787,  0.5039495,  0.18945697,
        0.87046838, 0.63970494, 0.01124038, 0.27459063, 0.65745586, 0.69182619, 0.80470603,
        0.58039348, 0.36950583, 0.43634225, 0.01694425, 0.14099377, 0.77015849, 0.35809292,
        0.40547674, 0.46538817, 0.65835358, 0.2266954,  0.39057646, 0.64642207, 0.84491134,
        0.20998067, 0.41074121, 0.73055221, 0.26424874, 0.10612507, 0.24478521, 0.24091282,
        0.52536754, 0.57292341, 0.82190903, 0.51858515, 0.17162996, 0.52048114, 0.96624787,
        0.17527163, 0.56384485, 0.91991603};
    std::vector<float> wdata = {
        -1.12125056, 0.50228441,  1.12719446,  -2.61705068, -0.2027315,  -0.82199441, 0.05337102,
        -0.62146691, -2.40572931, -1.47175612, 1.49654601,  -1.07070376, -0.65908074, -0.28457694,
        1.60046717,  0.20677642,  -1.51844486, 0.41203847,  -0.01285751, 0.07948031,  -0.91507006,
        -1.59481079, -0.12856238, 0.39970482,  -1.89015158, 0.66969754,  0.10312618};
Paul's avatar
Paul committed
66
67
68
    migraphx::shape xs{migraphx::shape::float_type, {1, 3, 6, 6}};
    migraphx::shape ws{migraphx::shape::float_type, {1, 3, 3, 3}};
    migraphx::shape vars{migraphx::shape::float_type, {1}};
wsttiger's avatar
wsttiger committed
69

wsttiger's avatar
wsttiger committed
70
    auto create_program = [&]() {
Paul's avatar
Paul committed
71
        migraphx::program p;
72

73
74
75
76
77
78
79
80
        auto* mm  = p.get_main_module();
        auto x    = mm->add_literal(xs, xdata);
        auto w    = mm->add_literal(ws, wdata);
        auto conv = mm->add_instruction(
            migraphx::make_op("convolution",
                              {{"padding", {0, 0}}, {"stride", {1, 1}}, {"dilation", {1, 1}}}),
            x,
            w);
81
82
83
84
85
        auto scale    = mm->add_literal(migraphx::literal{vars, {3.0f}});
        auto bias     = mm->add_literal(migraphx::literal{vars, {8.1f}});
        auto mean     = mm->add_literal(migraphx::literal{vars, {4.0f}});
        auto variance = mm->add_literal(migraphx::literal{vars, {37.11f}});
        mm->add_instruction(
86
            migraphx::make_op("batch_norm_inference"), conv, scale, bias, mean, variance);
wsttiger's avatar
wsttiger committed
87
88
        return p;
    };
wsttiger's avatar
wsttiger committed
89

Paul's avatar
Paul committed
90
91
    migraphx::program p1 = create_program();
    migraphx::program p2 = create_program();
92

Paul's avatar
Paul committed
93
    migraphx::rewrite_batchnorm opt;
94
    opt.apply(*p2.get_main_module());
95
96
    p1.compile(migraphx::ref::target{});
    p2.compile(migraphx::ref::target{});
Scott Thornton's avatar
Scott Thornton committed
97

98
99
    auto result1 = p1.eval({}).back();
    auto result2 = p2.eval({}).back();
100
101
102
103
104

    std::vector<float> results_vector1;
    std::vector<float> results_vector2;
    result1.visit([&](auto output) { results_vector1.assign(output.begin(), output.end()); });
    result2.visit([&](auto output) { results_vector2.assign(output.begin(), output.end()); });
Paul's avatar
Paul committed
105
    EXPECT(migraphx::verify_range(results_vector1, results_vector2));
106
107
}

108
109
110
111
112
113
114
115
TEST_CASE(non_literal)
{

    migraphx::shape xs{migraphx::shape::float_type, {1, 3, 8, 8}};
    migraphx::shape ws{migraphx::shape::float_type, {4, 3, 1, 1}};
    migraphx::shape vars{migraphx::shape::float_type, {4}};
    auto create_program = [&]() {
        migraphx::program p;
116
117
118
        auto* mm      = p.get_main_module();
        auto x        = mm->add_parameter("x", xs);
        auto w        = mm->add_parameter("w", ws);
119
        auto conv     = mm->add_instruction(migraphx::make_op("convolution"), x, w);
120
121
122
123
124
        auto scale    = mm->add_literal(migraphx::abs(migraphx::generate_literal(vars, 1)));
        auto bias     = mm->add_literal(migraphx::abs(migraphx::generate_literal(vars, 2)));
        auto mean     = mm->add_literal(migraphx::abs(migraphx::generate_literal(vars, 3)));
        auto variance = mm->add_literal(migraphx::abs(migraphx::generate_literal(vars, 4)));
        mm->add_instruction(
125
            migraphx::make_op("batch_norm_inference"), conv, scale, bias, mean, variance);
126
127
128
129
130
        return p;
    };

    migraphx::program p1 = create_program();
    migraphx::program p2 = create_program();
131

Paul's avatar
Paul committed
132
    migraphx::rewrite_batchnorm opt;
133
    opt.apply(*p2.get_main_module());
Shucai Xiao's avatar
Shucai Xiao committed
134
135
    EXPECT(any_of(*p1.get_main_module(), &is_batch_norm));
    EXPECT(none_of(*p2.get_main_module(), &is_batch_norm));
136
137
138
139
140
141
142
143
144
145
}

TEST_CASE(as_literal)
{

    migraphx::shape xs{migraphx::shape::float_type, {1, 3, 8, 8}};
    migraphx::shape ws{migraphx::shape::float_type, {4, 3, 1, 1}};
    migraphx::shape vars{migraphx::shape::float_type, {4}};
    auto create_program = [&]() {
        migraphx::program p;
146
147
148
        auto* mm      = p.get_main_module();
        auto x        = mm->add_literal(migraphx::generate_literal(xs, 1));
        auto w        = mm->add_literal(migraphx::generate_literal(ws, 1));
149
        auto conv     = mm->add_instruction(migraphx::make_op("convolution"), x, w);
150
151
152
153
154
        auto scale    = mm->add_literal(migraphx::abs(migraphx::generate_literal(vars, 1)));
        auto bias     = mm->add_literal(migraphx::abs(migraphx::generate_literal(vars, 2)));
        auto mean     = mm->add_literal(migraphx::abs(migraphx::generate_literal(vars, 3)));
        auto variance = mm->add_literal(migraphx::abs(migraphx::generate_literal(vars, 4)));
        mm->add_instruction(
155
            migraphx::make_op("batch_norm_inference"), conv, scale, bias, mean, variance);
156
157
158
159
160
        return p;
    };

    migraphx::program p1 = create_program();
    migraphx::program p2 = create_program();
Paul's avatar
Paul committed
161
    migraphx::rewrite_batchnorm opt;
162
    opt.apply(*p2.get_main_module());
Shucai Xiao's avatar
Shucai Xiao committed
163
164
    EXPECT(any_of(*p1.get_main_module(), &is_batch_norm));
    EXPECT(none_of(*p2.get_main_module(), &is_batch_norm));
165

166
167
    p1.compile(migraphx::ref::target{});
    p2.compile(migraphx::ref::target{});
168

169
170
    auto result1 = p1.eval({}).back();
    auto result2 = p2.eval({}).back();
Paul's avatar
Paul committed
171
    visit_all(result1, result2)([&](auto r1, auto r2) { EXPECT(migraphx::verify_range(r1, r2)); });
172
173
}

Shucai Xiao's avatar
Shucai Xiao committed
174
175
176
177
178
179
180
TEST_CASE(as_literal_1d)
{
    migraphx::shape xs{migraphx::shape::float_type, {1, 3, 8}};
    migraphx::shape ws{migraphx::shape::float_type, {4, 3, 1}};
    migraphx::shape vars{migraphx::shape::float_type, {4}};
    auto create_program = [&]() {
        migraphx::program p;
181
182
183
184
185
186
187
188
        auto* mm  = p.get_main_module();
        auto x    = mm->add_literal(migraphx::generate_literal(xs, 1));
        auto w    = mm->add_literal(migraphx::generate_literal(ws, 1));
        auto conv = mm->add_instruction(
            migraphx::make_op("convolution",
                              {{"padding", {0}}, {"stride", {1}}, {"dilation", {1}}}),
            x,
            w);
189
190
191
192
193
        auto scale    = mm->add_literal(migraphx::abs(migraphx::generate_literal(vars, 1)));
        auto bias     = mm->add_literal(migraphx::abs(migraphx::generate_literal(vars, 2)));
        auto mean     = mm->add_literal(migraphx::abs(migraphx::generate_literal(vars, 3)));
        auto variance = mm->add_literal(migraphx::abs(migraphx::generate_literal(vars, 4)));
        mm->add_instruction(
194
            migraphx::make_op("batch_norm_inference"), conv, scale, bias, mean, variance);
Shucai Xiao's avatar
Shucai Xiao committed
195
196
197
198
199
200
        return p;
    };

    migraphx::program p1 = create_program();
    migraphx::program p2 = create_program();
    migraphx::rewrite_batchnorm opt;
201
    opt.apply(*p2.get_main_module());
Shucai Xiao's avatar
Shucai Xiao committed
202
203
    EXPECT(any_of(*p1.get_main_module(), &is_batch_norm));
    EXPECT(none_of(*p2.get_main_module(), &is_batch_norm));
Shucai Xiao's avatar
Shucai Xiao committed
204

205
206
    p1.compile(migraphx::ref::target{});
    p2.compile(migraphx::ref::target{});
Shucai Xiao's avatar
Shucai Xiao committed
207
208
209
210
211
212
213
214
215
216
217
218
219

    auto result1 = p1.eval({}).back();
    auto result2 = p2.eval({}).back();
    visit_all(result1, result2)([&](auto r1, auto r2) { EXPECT(migraphx::verify_range(r1, r2)); });
}

TEST_CASE(as_literal_3d)
{
    migraphx::shape xs{migraphx::shape::float_type, {1, 3, 2, 4, 8}};
    migraphx::shape ws{migraphx::shape::float_type, {4, 3, 1, 1, 1}};
    migraphx::shape vars{migraphx::shape::float_type, {4}};
    auto create_program = [&]() {
        migraphx::program p;
220
        auto* mm = p.get_main_module();
Shucai Xiao's avatar
Shucai Xiao committed
221
222
223
224
225
        migraphx::op::convolution conv_op;
        conv_op.padding  = {0, 0, 0};
        conv_op.stride   = {1, 1, 1};
        conv_op.dilation = {1, 1, 1};

226
227
228
229
230
231
232
233
        auto x        = mm->add_literal(migraphx::generate_literal(xs, 1));
        auto w        = mm->add_literal(migraphx::generate_literal(ws, 1));
        auto conv     = mm->add_instruction(conv_op, x, w);
        auto scale    = mm->add_literal(migraphx::abs(migraphx::generate_literal(vars, 1)));
        auto bias     = mm->add_literal(migraphx::abs(migraphx::generate_literal(vars, 2)));
        auto mean     = mm->add_literal(migraphx::abs(migraphx::generate_literal(vars, 3)));
        auto variance = mm->add_literal(migraphx::abs(migraphx::generate_literal(vars, 4)));
        mm->add_instruction(
234
            migraphx::make_op("batch_norm_inference"), conv, scale, bias, mean, variance);
Shucai Xiao's avatar
Shucai Xiao committed
235
236
237
238
239
240
        return p;
    };

    migraphx::program p1 = create_program();
    migraphx::program p2 = create_program();
    migraphx::rewrite_batchnorm opt;
241
    opt.apply(*p2.get_main_module());
Shucai Xiao's avatar
Shucai Xiao committed
242
243
    EXPECT(any_of(*p1.get_main_module(), &is_batch_norm));
    EXPECT(none_of(*p2.get_main_module(), &is_batch_norm));
Shucai Xiao's avatar
Shucai Xiao committed
244

245
246
    p1.compile(migraphx::ref::target{});
    p2.compile(migraphx::ref::target{});
Shucai Xiao's avatar
Shucai Xiao committed
247
248
249
250
251
252

    auto result1 = p1.eval({}).back();
    auto result2 = p2.eval({}).back();
    visit_all(result1, result2)([&](auto r1, auto r2) { EXPECT(migraphx::verify_range(r1, r2)); });
}

253
254
255
256
257
258
259
260
TEST_CASE(literal_reshape)
{
    migraphx::shape xs{migraphx::shape::float_type, {1, 3, 8, 8}};
    migraphx::shape ws{migraphx::shape::float_type, {4, 3, 1, 1}};
    migraphx::shape vars{migraphx::shape::float_type, {4}};

    auto create_program = [&]() {
        migraphx::program p;
261
262
263
        auto* mm      = p.get_main_module();
        auto x        = mm->add_literal(migraphx::generate_literal(xs, 1));
        auto w        = mm->add_literal(migraphx::generate_literal(ws, 1));
264
        auto conv     = mm->add_instruction(migraphx::make_op("convolution"), x, w);
265
266
267
268
269
        auto scale    = mm->add_literal(migraphx::abs(migraphx::generate_literal(vars, 1)));
        auto bias     = mm->add_literal(migraphx::abs(migraphx::generate_literal(vars, 2)));
        auto mean     = mm->add_literal(migraphx::abs(migraphx::generate_literal(vars, 3)));
        auto variance = mm->add_literal(migraphx::abs(migraphx::generate_literal(vars, 4)));
        mm->add_instruction(
270
            migraphx::make_op("batch_norm_inference"), conv, scale, bias, mean, variance);
271
272
273
274
275
        return p;
    };

    migraphx::program p1 = create_program();
    migraphx::program p2 = create_program();
Paul's avatar
Paul committed
276
    migraphx::rewrite_batchnorm opt;
277
    opt.apply(*p2.get_main_module());
Shucai Xiao's avatar
Shucai Xiao committed
278
279
    EXPECT(any_of(*p1.get_main_module(), &is_batch_norm));
    EXPECT(none_of(*p2.get_main_module(), &is_batch_norm));
280

281
282
    p1.compile(migraphx::ref::target{});
    p2.compile(migraphx::ref::target{});
283

284
285
    auto result1 = p1.eval({}).back();
    auto result2 = p2.eval({}).back();
Paul's avatar
Paul committed
286
    visit_all(result1, result2)([&](auto r1, auto r2) { EXPECT(migraphx::verify_range(r1, r2)); });
287
288
}

Shucai Xiao's avatar
Shucai Xiao committed
289
290
291
292
293
294
295
296
TEST_CASE(literal_reshape_per_actv)
{
    migraphx::shape xs{migraphx::shape::float_type, {1, 3, 8, 7, 4}};
    migraphx::shape ws{migraphx::shape::float_type, {4, 3, 1, 1, 1}};
    migraphx::shape vars{migraphx::shape::float_type, {4, 8, 7, 4}};

    auto create_program = [&]() {
        migraphx::program p;
297
298
299
300
301
302
303
304
305
        auto* mm  = p.get_main_module();
        auto x    = mm->add_literal(migraphx::generate_literal(xs, 1));
        auto w    = mm->add_literal(migraphx::generate_literal(ws, 1));
        auto conv = mm->add_instruction(
            migraphx::make_op(
                "convolution",
                {{"padding", {0, 0, 0}}, {"stride", {1, 1, 1}}, {"dilation", {1, 1, 1}}}),
            x,
            w);
306
307
308
309
310
        auto scale    = mm->add_literal(migraphx::abs(migraphx::generate_literal(vars, 1)));
        auto bias     = mm->add_literal(migraphx::abs(migraphx::generate_literal(vars, 2)));
        auto mean     = mm->add_literal(migraphx::abs(migraphx::generate_literal(vars, 3)));
        auto variance = mm->add_literal(migraphx::abs(migraphx::generate_literal(vars, 4)));
        mm->add_instruction(
311
312
313
314
315
316
            migraphx::make_op(
                "batch_norm_inference",
                {{"epsilon", 1.0e-5},
                 {"momentum", 0.88},
                 {"bn_mode",
                  migraphx::to_value(migraphx::op::batch_norm_inference::per_activation)}}),
Shucai Xiao's avatar
Shucai Xiao committed
317
318
319
320
321
322
323
324
325
326
327
            conv,
            scale,
            bias,
            mean,
            variance);
        return p;
    };

    migraphx::program p1 = create_program();
    migraphx::program p2 = create_program();
    migraphx::rewrite_batchnorm opt;
328
    opt.apply(*p2.get_main_module());
Shucai Xiao's avatar
Shucai Xiao committed
329
330
    EXPECT(any_of(*p1.get_main_module(), &is_batch_norm));
    EXPECT(none_of(*p2.get_main_module(), &is_batch_norm));
Shucai Xiao's avatar
Shucai Xiao committed
331

332
333
    p1.compile(migraphx::ref::target{});
    p2.compile(migraphx::ref::target{});
Shucai Xiao's avatar
Shucai Xiao committed
334
335
336
337
338
339

    auto result1 = p1.eval({}).back();
    auto result2 = p2.eval({}).back();
    visit_all(result1, result2)([&](auto r1, auto r2) { EXPECT(migraphx::verify_range(r1, r2)); });
}

Paul's avatar
Paul committed
340
int main(int argc, const char* argv[]) { test::run(argc, argv); }