"git@developer.sourcefind.cn:gaoqiong/migraphx.git" did not exist on "274c772b385003c4bef3bbe90b29de3dd2287dd7"
eval_test.cpp 13.3 KB
Newer Older
Paul's avatar
Paul committed
1

Paul's avatar
Paul committed
2
3
4
#include <migraphx/program.hpp>
#include <migraphx/iterator_for.hpp>
#include <migraphx/instruction.hpp>
Paul's avatar
Paul committed
5
#include <migraphx/stringutils.hpp>
Paul's avatar
Paul committed
6
#include <sstream>
Paul's avatar
Paul committed
7
#include "test.hpp"
Paul's avatar
Paul committed
8
#include <basic_ops.hpp>
Paul's avatar
Paul committed
9

Paul's avatar
Paul committed
10
11
struct id_target
{
Paul's avatar
Paul committed
12
13
14
15
16
    struct context
    {
        void finish() const {}
    };
    migraphx::context ctx = context{};
Paul's avatar
Paul committed
17
    std::string name() const { return "id"; }
Paul's avatar
Paul committed
18
    std::vector<migraphx::pass> get_passes(migraphx::context&) const { return {}; }
Paul's avatar
Paul committed
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
    migraphx::context get_context() const { return ctx; }
};

struct id_ctx_op
{
    std::string name() const { return "id_ctx_op"; }
    migraphx::argument
    compute(id_target::context&, const migraphx::shape&, std::vector<migraphx::argument> args) const
    {
        if(args.empty())
            return {};
        return args.front();
    }

    migraphx::shape compute_shape(std::vector<migraphx::shape> inputs) const
    {
        if(inputs.empty())
            return {};
        return inputs.front();
    }
    int output_alias(const std::vector<migraphx::shape>&) const { return 0; }
};

struct id_ctx_final_op
{
    std::string name() const { return "id_ctx_final_op"; }
Paul's avatar
Paul committed
45
    migraphx::argument compute(const migraphx::shape&, std::vector<migraphx::argument> args) const
Paul's avatar
Paul committed
46
47
48
49
50
51
    {
        if(args.empty())
            return {};
        return args.front();
    }

Paul's avatar
Paul committed
52
53
54
    void finalize(id_target::context&, const migraphx::shape&, const std::vector<migraphx::shape>&)
    {
    }
Paul's avatar
Paul committed
55
56
57
58
59
60
61
62

    migraphx::shape compute_shape(std::vector<migraphx::shape> inputs) const
    {
        if(inputs.empty())
            return {};
        return inputs.front();
    }
    int output_alias(const std::vector<migraphx::shape>&) const { return 0; }
Paul's avatar
Paul committed
63
64
};

Paul's avatar
Paul committed
65
66
struct reverse_pass
{
Paul's avatar
Paul committed
67
    std::string name() const { return "reverse_pass"; }
Paul's avatar
Paul committed
68

Paul's avatar
Paul committed
69
    void apply(migraphx::program& p) const { std::reverse(p.begin(), p.end()); }
Paul's avatar
Paul committed
70
71
72
73
74
75
76
77
78
79
80
81
82
};

struct reverse_target
{
    std::string name() const { return "reverse"; }
    std::vector<migraphx::pass> get_passes(migraphx::context&) const { return {reverse_pass{}}; }
    migraphx::context get_context() const { return {}; }
};

struct invert_pass
{
    std::string name() const { return "invert_pass"; }

Paul's avatar
Paul committed
83
    void apply(migraphx::program& p) const
Paul's avatar
Paul committed
84
    {
Paul's avatar
Paul committed
85
        for(auto ins : migraphx::iterator_for(p))
Paul's avatar
Paul committed
86
        {
87
            if(ins->name() == "sum")
Paul's avatar
Paul committed
88
            {
89
                p.replace_instruction(ins, minus_op{}, ins->inputs());
Paul's avatar
Paul committed
90
            }
91
            else if(ins->name() == "minus")
Paul's avatar
Paul committed
92
            {
93
                p.replace_instruction(ins, sum_op{}, ins->inputs());
Paul's avatar
Paul committed
94
95
96
97
98
            }
        }
    }
};

Paul's avatar
Paul committed
99
struct invert_target
Paul's avatar
Paul committed
100
{
Paul's avatar
Paul committed
101
102
    std::string name() const { return "invert"; }
    std::vector<migraphx::pass> get_passes(migraphx::context&) const { return {invert_pass{}}; }
Paul's avatar
Paul committed
103
    migraphx::context get_context() const { return {}; }
Paul's avatar
Paul committed
104
105
};

Paul's avatar
Paul committed
106
struct double_invert_target
Paul's avatar
Paul committed
107
{
Paul's avatar
Paul committed
108
    std::string name() const { return "double_invert"; }
Paul's avatar
Paul committed
109
    std::vector<migraphx::pass> get_passes(migraphx::context&) const
Paul's avatar
Paul committed
110
    {
Paul's avatar
Paul committed
111
        return {invert_pass{}, invert_pass{}};
Paul's avatar
Paul committed
112
    }
Paul's avatar
Paul committed
113
    migraphx::context get_context() const { return {}; }
Paul's avatar
Paul committed
114
115
};

Paul's avatar
Paul committed
116
TEST_CASE(literal_test1)
Paul's avatar
Paul committed
117
{
Paul's avatar
Paul committed
118
    migraphx::program p;
Paul's avatar
Paul committed
119
120
121

    auto one = p.add_literal(1);
    auto two = p.add_literal(2);
Paul's avatar
Paul committed
122
    p.add_instruction(sum_op{}, one, two);
Paul's avatar
Paul committed
123
    auto result = p.eval({});
Paul's avatar
Paul committed
124
125
    EXPECT(result == migraphx::literal{3});
    EXPECT(result != migraphx::literal{4});
Paul's avatar
Paul committed
126
127
}

Paul's avatar
Paul committed
128
TEST_CASE(literal_test2)
Paul's avatar
Paul committed
129
{
Paul's avatar
Paul committed
130
    migraphx::program p;
Paul's avatar
Paul committed
131

Paul's avatar
Paul committed
132
133
    auto one  = p.add_literal(1);
    auto two  = p.add_literal(2);
Paul's avatar
Paul committed
134
135
136
137
    auto sum1 = p.add_instruction(sum_op{}, one, two);
    p.add_instruction(sum_op{}, sum1, two);

    auto result = p.eval({});
Paul's avatar
Paul committed
138
139
    EXPECT(result == migraphx::literal{5});
    EXPECT(result != migraphx::literal{3});
Paul's avatar
Paul committed
140
141
}

Paul's avatar
Paul committed
142
TEST_CASE(print_test)
Paul's avatar
Paul committed
143
{
Paul's avatar
Paul committed
144
    migraphx::program p;
Paul's avatar
Paul committed
145

Paul's avatar
Paul committed
146
    auto x   = p.add_parameter("x", {migraphx::shape::int32_type});
Paul's avatar
Paul committed
147
148
149
150
151
152
153
154
155
    auto two = p.add_literal(2);
    p.add_instruction(sum_op{}, x, two);

    std::stringstream ss;
    ss << p;
    std::string s = ss.str();
    EXPECT(!s.empty());
}

Paul's avatar
Paul committed
156
TEST_CASE(param_test)
Paul's avatar
Paul committed
157
{
Paul's avatar
Paul committed
158
    migraphx::program p;
Paul's avatar
Paul committed
159

Paul's avatar
Paul committed
160
161
    auto x = p.add_parameter("x", {migraphx::shape::int32_type});
    auto y = p.add_parameter("y", {migraphx::shape::int32_type});
Paul's avatar
Paul committed
162

Paul's avatar
Paul committed
163
    p.add_instruction(sum_op{}, x, y);
Paul's avatar
Paul committed
164
    auto result = p.eval(
Paul's avatar
Paul committed
165
166
167
        {{"x", migraphx::literal{1}.get_argument()}, {"y", migraphx::literal{2}.get_argument()}});
    EXPECT(result == migraphx::literal{3});
    EXPECT(result != migraphx::literal{4});
Paul's avatar
Paul committed
168
169
}

Paul's avatar
Paul committed
170
TEST_CASE(param_error_test)
Khalique's avatar
Khalique committed
171
{
Paul's avatar
Paul committed
172
    migraphx::program p;
Khalique's avatar
Khalique committed
173

Paul's avatar
Paul committed
174
175
    auto x = p.add_parameter("x", {migraphx::shape::int32_type});
    auto y = p.add_parameter("y", {migraphx::shape::int32_type});
Khalique's avatar
Khalique committed
176
177

    p.add_instruction(sum_op{}, x, y);
Paul's avatar
Paul committed
178
    EXPECT(test::throws<migraphx::exception>(
Khalique's avatar
Khalique committed
179
        [&] {
Paul's avatar
Paul committed
180
            p.eval({{"x", migraphx::literal{1}.get_argument()}});
Khalique's avatar
Khalique committed
181
        },
182
        "Parameter not found: y"));
Khalique's avatar
Khalique committed
183
184
}

Paul's avatar
Paul committed
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
TEST_CASE(param_error_shape_test)
{
    migraphx::program p;

    auto x = p.add_parameter("x", {migraphx::shape::int32_type, {1, 1}});
    auto y = p.add_parameter("y", {migraphx::shape::int32_type, {1, 1}});

    p.add_instruction(sum_op{}, x, y);
    EXPECT(test::throws<migraphx::exception>(
        [&] {
            p.eval({
                {"x", migraphx::literal{1}.get_argument()},
                {"y", migraphx::literal{{migraphx::shape::int32_type, {1, 1}}, {2}}.get_argument()},
            });
        },
        "Incorrect shape {int32_type, {1}, {0}} for parameter: x"));
}

Paul's avatar
Paul committed
203
TEST_CASE(get_param1)
Paul's avatar
Paul committed
204
205
{
    migraphx::program p;
Paul's avatar
Paul committed
206
207
208
209
210
211
212
213
    migraphx::shape s{migraphx::shape::int32_type, {1, 2}};
    auto x = p.add_parameter("x", s);
    auto y = p.add_parameter("y", s);
    p.add_instruction(sum_op{}, x, y);
    EXPECT(bool{p.get_parameter("x") == x});
    EXPECT(bool{p.get_parameter("y") == y});
    EXPECT(bool{p.get_parameter("nonexistent") == p.end()});
}
Paul's avatar
Paul committed
214

Paul's avatar
Paul committed
215
216
217
218
219
220
221
222
TEST_CASE(get_param2)
{
    migraphx::program p;
    auto one = p.add_literal(1);
    auto two = p.add_literal(2);
    p.add_instruction(sum_op{}, one, two);
    EXPECT(bool{p.get_parameter("nonexistent") == p.end()});
}
Paul's avatar
Paul committed
223

Paul's avatar
Paul committed
224
225
226
227
228
229
TEST_CASE(get_param_shapes)
{
    migraphx::program p;
    migraphx::shape s{migraphx::shape::int32_type, {1, 2}};
    auto x = p.add_parameter("x", s);
    auto y = p.add_parameter("y", s);
Paul's avatar
Paul committed
230
    p.add_instruction(sum_op{}, x, y);
Paul's avatar
Paul committed
231
232
233
234
    auto m = p.get_parameter_shapes();
    EXPECT(m.count("nonexistent") == 0);
    EXPECT(m.at("x") == s);
    EXPECT(m.at("y") == s);
Paul's avatar
Paul committed
235
236
}

Paul's avatar
Paul committed
237
TEST_CASE(replace_test)
Paul's avatar
Paul committed
238
{
Paul's avatar
Paul committed
239
    migraphx::program p;
Paul's avatar
Paul committed
240
241
242
243
244

    auto one = p.add_literal(1);
    auto two = p.add_literal(2);
    auto sum = p.add_instruction(sum_op{}, one, two);
    p.replace_instruction(sum, minus_op{}, two, one);
Paul's avatar
Paul committed
245
    EXPECT(bool{p.validate() == p.end()});
Paul's avatar
Paul committed
246
247

    auto result = p.eval({});
Paul's avatar
Paul committed
248
249
    EXPECT(result == migraphx::literal{1});
    EXPECT(result != migraphx::literal{3});
Paul's avatar
Paul committed
250
251
}

Paul's avatar
Paul committed
252
TEST_CASE(replace_ins_test)
Paul's avatar
Paul committed
253
{
Paul's avatar
Paul committed
254
    migraphx::program p;
Paul's avatar
Paul committed
255

Paul's avatar
Paul committed
256
257
258
    auto one   = p.add_literal(1);
    auto two   = p.add_literal(2);
    auto sum   = p.add_instruction(sum_op{}, one, two);
Paul's avatar
Paul committed
259
260
    auto minus = p.add_instruction(minus_op{}, two, one);
    p.replace_instruction(sum, minus);
Paul's avatar
Paul committed
261
    EXPECT(bool{p.validate() == p.end()});
Paul's avatar
Paul committed
262
263

    auto result = p.eval({});
Paul's avatar
Paul committed
264
265
    EXPECT(result == migraphx::literal{1});
    EXPECT(result != migraphx::literal{3});
Paul's avatar
Paul committed
266
267
}

Paul's avatar
Paul committed
268
TEST_CASE(replace_ins_test2)
Paul's avatar
Paul committed
269
{
Paul's avatar
Paul committed
270
    migraphx::program p;
Paul's avatar
Paul committed
271

Paul's avatar
Paul committed
272
273
274
    auto one   = p.add_literal(1);
    auto two   = p.add_literal(2);
    auto sum   = p.add_instruction(sum_op{}, one, two);
Paul's avatar
Paul committed
275
276
    auto minus = p.add_instruction(minus_op{}, two, one);
    p.add_instruction(pass_op{}, minus);
Paul's avatar
Paul committed
277
    p.replace_instruction(two, sum);
Paul's avatar
Paul committed
278
    EXPECT(bool{p.validate() == p.end()});
Paul's avatar
Paul committed
279
280

    auto result = p.eval({});
Paul's avatar
Paul committed
281
282
    EXPECT(result == migraphx::literal{2});
    EXPECT(result != migraphx::literal{3});
Paul's avatar
Paul committed
283
284
}

Paul's avatar
Paul committed
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
TEST_CASE(replace_op_test)
{
    migraphx::program p;

    auto one = p.add_literal(1);
    auto two = p.add_literal(2);
    auto sum = p.add_instruction(sum_op{}, two, one);
    sum->replace(minus_op{});
    EXPECT(bool{p.validate() == p.end()});

    auto result = p.eval({});
    EXPECT(result == migraphx::literal{1});
    EXPECT(result != migraphx::literal{3});
}

TEST_CASE(replace_op_recompute_shape_throw)
{
    migraphx::program p;

    auto one = p.add_literal(1);
    auto two = p.add_literal(2);
    auto sum = p.add_instruction(sum_op{}, one, two);
Paul's avatar
Paul committed
307
    EXPECT(test::throws<migraphx::exception>([&] { sum->replace(unary_pass_op{}); }));
Paul's avatar
Paul committed
308
309
}

Paul's avatar
Paul committed
310
TEST_CASE(insert_replace_test)
Paul's avatar
Paul committed
311
{
Paul's avatar
Paul committed
312
    migraphx::program p;
Paul's avatar
Paul committed
313

Paul's avatar
Paul committed
314
315
    auto one  = p.add_literal(1);
    auto two  = p.add_literal(2);
Paul's avatar
Paul committed
316
317
318
319
320
    auto sum1 = p.add_instruction(sum_op{}, one, two);
    p.add_instruction(sum_op{}, sum1, two);

    auto sum0 = p.insert_instruction(sum1, sum_op{}, two, two);
    p.replace_instruction(sum1, minus_op{}, sum0, two);
Paul's avatar
Paul committed
321
    EXPECT(bool{p.validate() == p.end()});
Paul's avatar
Paul committed
322
323

    auto result = p.eval({});
Paul's avatar
Paul committed
324
325
    EXPECT(result == migraphx::literal{4});
    EXPECT(result != migraphx::literal{5});
Paul's avatar
Paul committed
326
327
}

Paul's avatar
Paul committed
328
329
330
331
TEST_CASE(remove_test1)
{
    migraphx::program p;

Paul's avatar
Paul committed
332
333
334
    auto one     = p.add_literal(1);
    auto two     = p.add_literal(2);
    auto sum     = p.add_instruction(sum_op{}, one, two);
Paul's avatar
Paul committed
335
336
337
338
339
340
341
342
343
344
345
346
347
    auto removed = p.add_instruction(minus_op{}, sum, one);
    p.remove_instruction(removed);
    EXPECT(bool{p.validate() == p.end()});

    auto result = p.eval({});
    EXPECT(result == migraphx::literal{3});
    EXPECT(result != migraphx::literal{1});
}

TEST_CASE(remove_test2)
{
    migraphx::program p;

Paul's avatar
Paul committed
348
349
    auto one     = p.add_literal(1);
    auto two     = p.add_literal(2);
Paul's avatar
Paul committed
350
351
352
353
354
355
356
357
358
359
    auto removed = p.add_instruction(minus_op{}, two, one);
    p.add_instruction(sum_op{}, one, two);
    p.remove_instruction(removed);
    EXPECT(bool{p.validate() == p.end()});

    auto result = p.eval({});
    EXPECT(result == migraphx::literal{3});
    EXPECT(result != migraphx::literal{1});
}

Paul's avatar
Paul committed
360
TEST_CASE(target_test)
Paul's avatar
Paul committed
361
{
Paul's avatar
Paul committed
362
    migraphx::program p;
Paul's avatar
Paul committed
363
364
365
366
367
368

    auto one = p.add_literal(1);
    auto two = p.add_literal(2);
    p.add_instruction(sum_op{}, one, two);
    p.compile(id_target{});
    auto result = p.eval({});
Paul's avatar
Paul committed
369
370
    EXPECT(result == migraphx::literal{3});
    EXPECT(result != migraphx::literal{4});
Paul's avatar
Paul committed
371
372
}

Paul's avatar
Paul committed
373
TEST_CASE(invert_target_test)
Paul's avatar
Paul committed
374
{
Paul's avatar
Paul committed
375
    migraphx::program p;
Paul's avatar
Paul committed
376
377
378
379

    auto one = p.add_literal(1);
    auto two = p.add_literal(2);
    p.add_instruction(sum_op{}, two, one);
Paul's avatar
Paul committed
380
    p.compile(invert_target{});
Paul's avatar
Paul committed
381
    auto result = p.eval({});
Paul's avatar
Paul committed
382
383
    EXPECT(result == migraphx::literal{1});
    EXPECT(result != migraphx::literal{4});
Paul's avatar
Paul committed
384
385
}

Paul's avatar
Paul committed
386
TEST_CASE(double_invert_target_test)
Paul's avatar
Paul committed
387
{
Paul's avatar
Paul committed
388
    migraphx::program p;
Paul's avatar
Paul committed
389
390
391
392

    auto one = p.add_literal(1);
    auto two = p.add_literal(2);
    p.add_instruction(sum_op{}, two, one);
Paul's avatar
Paul committed
393
    p.compile(double_invert_target{});
Paul's avatar
Paul committed
394
    auto result = p.eval({});
Paul's avatar
Paul committed
395
396
    EXPECT(result == migraphx::literal{3});
    EXPECT(result != migraphx::literal{4});
Paul's avatar
Paul committed
397
398
}

Paul's avatar
Paul committed
399
400
401
402
403
404
405
TEST_CASE(reverse_target_test)
{
    migraphx::program p;

    auto one = p.add_literal(1);
    auto two = p.add_literal(2);
    p.add_instruction(sum_op{}, one, two);
Paul's avatar
Paul committed
406
    EXPECT(test::throws<migraphx::exception>([&] { p.compile(reverse_target{}); }));
Paul's avatar
Paul committed
407
408
}

Paul's avatar
Paul committed
409
410
// Check that the program doesnt modify the context directly, and only the operators modify the
// context
Paul's avatar
Paul committed
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
TEST_CASE(eval_context1)
{
    migraphx::program p;
    id_target t{};
    EXPECT(is_shared(t.ctx, t.get_context()));
    auto one = p.add_literal(1);
    auto two = p.add_literal(2);
    p.add_instruction(sum_op{}, one, two);
    p.compile(t);
    EXPECT(is_shared(t.ctx, p.get_context()));
    p.eval({});
    EXPECT(is_shared(t.ctx, p.get_context()));
}

TEST_CASE(eval_context2)
{
    migraphx::program p;
    id_target t{};
    EXPECT(is_shared(t.ctx, t.get_context()));
    auto one = p.add_literal(1);
    auto two = p.add_literal(2);
    p.add_instruction(id_ctx_op{}, one, two);
    p.compile(t);
    EXPECT(is_shared(t.ctx, p.get_context()));
    p.eval({});
    // id_ctx_op will modify the context
    EXPECT(not is_shared(t.ctx, p.get_context()));
}

TEST_CASE(eval_context3)
{
    migraphx::program p;
    id_target t{};
    EXPECT(is_shared(t.ctx, t.get_context()));
    auto one = p.add_literal(1);
    auto two = p.add_literal(2);
    p.add_instruction(id_ctx_final_op{}, one, two);
    p.compile(t);
    // Finalizer will modify the context
    EXPECT(not is_shared(t.ctx, p.get_context()));
    auto ctx = p.get_context();
    p.eval({});
    EXPECT(is_shared(ctx, p.get_context()));
    EXPECT(not is_shared(t.ctx, p.get_context()));
}

Paul's avatar
Paul committed
457
458
459
460
461
462
struct cout_redirect
{
    cout_redirect()                     = delete;
    cout_redirect(const cout_redirect&) = delete;
    template <class T>
    cout_redirect(T& stream) : old(std::cout.rdbuf(stream.rdbuf()))
Paul's avatar
Paul committed
463
464
    {
    }
Paul's avatar
Paul committed
465
    ~cout_redirect() { std::cout.rdbuf(old); }
Paul's avatar
Paul committed
466

Paul's avatar
Paul committed
467
468
    private:
    std::streambuf* old;
Paul's avatar
Paul committed
469
470
};

Paul's avatar
Paul committed
471
template <class F>
Paul's avatar
Paul committed
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
std::string capture_output(F f)
{
    std::stringstream ss;
    cout_redirect cr{ss};
    f();
    return ss.str();
}

TEST_CASE(debug_print_test)
{
    migraphx::program p;
    auto one = p.add_literal(1);

    migraphx::program p2;
    auto one2 = p2.add_literal(1);

Paul's avatar
Paul committed
488
489
490
491
492
    auto program_out = migraphx::trim(capture_output([&] { p.debug_print(); }));
    auto ins_out     = migraphx::trim(capture_output([&] { p.debug_print(one); }));
    auto inss_out    = migraphx::trim(capture_output([&] { p.debug_print({one}); }));
    auto end_out     = migraphx::trim(capture_output([&] { p.debug_print(p.end()); }));
    auto p2_ins_out  = migraphx::trim(capture_output([&] { p.debug_print(one2); }));
Paul's avatar
Paul committed
493
494
495
496
497
498
499

    EXPECT(program_out == ins_out);
    EXPECT(inss_out == ins_out);
    EXPECT(end_out == "End instruction");
    EXPECT(p2_ins_out == "Instruction not part of program");
}

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