"vscode:/vscode.git/clone" did not exist on "797b96353ea495ad9bca5979f2436daddf839f3d"
eval_test.cpp 16.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

Paul's avatar
Paul committed
25
26
27
#include <migraphx/program.hpp>
#include <migraphx/iterator_for.hpp>
#include <migraphx/instruction.hpp>
Paul's avatar
Paul committed
28
#include <migraphx/stringutils.hpp>
29
#include <migraphx/compile_options.hpp>
Paul's avatar
Paul committed
30
#include <sstream>
Paul's avatar
Paul committed
31
#include "test.hpp"
Paul's avatar
Paul committed
32
#include <basic_ops.hpp>
Paul's avatar
Paul committed
33

Paul's avatar
Paul committed
34
35
struct id_target
{
Paul's avatar
Paul committed
36
37
38
39
40
    struct context
    {
        void finish() const {}
    };
    migraphx::context ctx = context{};
Paul's avatar
Paul committed
41
    std::string name() const { return "id"; }
42
43
44
45
46
    std::vector<migraphx::pass> get_passes(migraphx::context&,
                                           const migraphx::compile_options&) const
    {
        return {};
    }
Paul's avatar
Paul committed
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
    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
73
    migraphx::argument compute(const migraphx::shape&, std::vector<migraphx::argument> args) const
Paul's avatar
Paul committed
74
75
76
77
78
79
    {
        if(args.empty())
            return {};
        return args.front();
    }

Paul's avatar
Paul committed
80
81
82
    void finalize(id_target::context&, const migraphx::shape&, const std::vector<migraphx::shape>&)
    {
    }
Paul's avatar
Paul committed
83
84
85
86
87
88
89
90

    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
91
92
};

Paul's avatar
Paul committed
93
94
struct reverse_pass
{
Paul's avatar
Paul committed
95
    std::string name() const { return "reverse_pass"; }
Paul's avatar
Paul committed
96

Shucai Xiao's avatar
Shucai Xiao committed
97
    void apply(migraphx::module& m) const { std::reverse(m.begin(), m.end()); }
Paul's avatar
Paul committed
98
99
100
101
102
};

struct reverse_target
{
    std::string name() const { return "reverse"; }
103
104
105
106
107
    std::vector<migraphx::pass> get_passes(migraphx::context&,
                                           const migraphx::compile_options&) const
    {
        return {reverse_pass{}};
    }
Paul's avatar
Paul committed
108
109
110
111
112
113
114
    migraphx::context get_context() const { return {}; }
};

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

115
    void apply(migraphx::module& m) const
Paul's avatar
Paul committed
116
    {
117
        for(auto ins : migraphx::iterator_for(m))
Paul's avatar
Paul committed
118
        {
119
            if(ins->name() == "sum")
Paul's avatar
Paul committed
120
            {
121
                m.replace_instruction(ins, minus_op{}, ins->inputs());
Paul's avatar
Paul committed
122
            }
123
            else if(ins->name() == "minus")
Paul's avatar
Paul committed
124
            {
125
                m.replace_instruction(ins, sum_op{}, ins->inputs());
Paul's avatar
Paul committed
126
127
128
129
130
            }
        }
    }
};

Paul's avatar
Paul committed
131
struct invert_target
Paul's avatar
Paul committed
132
{
Paul's avatar
Paul committed
133
    std::string name() const { return "invert"; }
134
135
136
137
138
    std::vector<migraphx::pass> get_passes(migraphx::context&,
                                           const migraphx::compile_options&) const
    {
        return {invert_pass{}};
    }
Paul's avatar
Paul committed
139
    migraphx::context get_context() const { return {}; }
Paul's avatar
Paul committed
140
141
};

Paul's avatar
Paul committed
142
struct double_invert_target
Paul's avatar
Paul committed
143
{
Paul's avatar
Paul committed
144
    std::string name() const { return "double_invert"; }
145
146
    std::vector<migraphx::pass> get_passes(migraphx::context&,
                                           const migraphx::compile_options&) const
Paul's avatar
Paul committed
147
    {
Paul's avatar
Paul committed
148
        return {invert_pass{}, invert_pass{}};
Paul's avatar
Paul committed
149
    }
Paul's avatar
Paul committed
150
    migraphx::context get_context() const { return {}; }
Paul's avatar
Paul committed
151
152
};

Paul's avatar
Paul committed
153
TEST_CASE(literal_test1)
Paul's avatar
Paul committed
154
{
Paul's avatar
Paul committed
155
    migraphx::program p;
156
157
158
159
    auto* mm = p.get_main_module();
    auto one = mm->add_literal(1);
    auto two = mm->add_literal(2);
    mm->add_instruction(sum_op{}, one, two);
160
    auto result = p.eval({}).back();
Paul's avatar
Paul committed
161
162
    EXPECT(result == migraphx::literal{3});
    EXPECT(result != migraphx::literal{4});
Paul's avatar
Paul committed
163
164
}

Paul's avatar
Paul committed
165
TEST_CASE(literal_test2)
Paul's avatar
Paul committed
166
{
Paul's avatar
Paul committed
167
    migraphx::program p;
168
169
170
171
172
    auto* mm  = p.get_main_module();
    auto one  = mm->add_literal(1);
    auto two  = mm->add_literal(2);
    auto sum1 = mm->add_instruction(sum_op{}, one, two);
    mm->add_instruction(sum_op{}, sum1, two);
Paul's avatar
Paul committed
173

174
    auto result = p.eval({}).back();
Paul's avatar
Paul committed
175
176
    EXPECT(result == migraphx::literal{5});
    EXPECT(result != migraphx::literal{3});
Paul's avatar
Paul committed
177
178
}

Paul's avatar
Paul committed
179
TEST_CASE(print_test)
Paul's avatar
Paul committed
180
{
Paul's avatar
Paul committed
181
    migraphx::program p;
182
183
184
185
    auto* mm = p.get_main_module();
    auto x   = mm->add_parameter("x", {migraphx::shape::int32_type});
    auto two = mm->add_literal(2);
    mm->add_instruction(sum_op{}, x, two);
Paul's avatar
Paul committed
186
187
188
189

    std::stringstream ss;
    ss << p;
    std::string s = ss.str();
190
    EXPECT(not s.empty());
Paul's avatar
Paul committed
191
192
}

Paul's avatar
Paul committed
193
TEST_CASE(param_test)
Paul's avatar
Paul committed
194
{
Paul's avatar
Paul committed
195
    migraphx::program p;
196
197
198
    auto* mm = p.get_main_module();
    auto x   = mm->add_parameter("x", {migraphx::shape::int32_type});
    auto y   = mm->add_parameter("y", {migraphx::shape::int32_type});
Paul's avatar
Paul committed
199

200
    mm->add_instruction(sum_op{}, x, y);
201
202
203
    auto result = p.eval({{"x", migraphx::literal{1}.get_argument()},
                          {"y", migraphx::literal{2}.get_argument()}})
                      .back();
Paul's avatar
Paul committed
204
205
    EXPECT(result == migraphx::literal{3});
    EXPECT(result != migraphx::literal{4});
Paul's avatar
Paul committed
206
207
}

Paul's avatar
Paul committed
208
TEST_CASE(param_error_test)
Khalique's avatar
Khalique committed
209
{
Paul's avatar
Paul committed
210
    migraphx::program p;
211
212
213
    auto* mm = p.get_main_module();
    auto x   = mm->add_parameter("x", {migraphx::shape::int32_type});
    auto y   = mm->add_parameter("y", {migraphx::shape::int32_type});
Khalique's avatar
Khalique committed
214

215
    mm->add_instruction(sum_op{}, x, y);
Paul's avatar
Paul committed
216
    EXPECT(test::throws<migraphx::exception>(
Khalique's avatar
Khalique committed
217
        [&] {
Paul's avatar
Paul committed
218
            p.eval({{"x", migraphx::literal{1}.get_argument()}});
Khalique's avatar
Khalique committed
219
        },
220
        "Parameter not found: y"));
Khalique's avatar
Khalique committed
221
222
}

Paul's avatar
Paul committed
223
224
225
TEST_CASE(param_error_shape_test)
{
    migraphx::program p;
226
227
228
    auto* mm = p.get_main_module();
    auto x   = mm->add_parameter("x", {migraphx::shape::int32_type, {1, 1}});
    auto y   = mm->add_parameter("y", {migraphx::shape::int32_type, {1, 1}});
Paul's avatar
Paul committed
229

230
    mm->add_instruction(sum_op{}, x, y);
Paul's avatar
Paul committed
231
232
233
234
235
236
237
238
239
240
    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
241
TEST_CASE(get_param1)
Paul's avatar
Paul committed
242
243
{
    migraphx::program p;
244
    auto* mm = p.get_main_module();
Paul's avatar
Paul committed
245
    migraphx::shape s{migraphx::shape::int32_type, {1, 2}};
246
247
248
    auto x = mm->add_parameter("x", s);
    auto y = mm->add_parameter("y", s);
    mm->add_instruction(sum_op{}, x, y);
Paul's avatar
Paul committed
249
250
    EXPECT(bool{p.get_parameter("x") == x});
    EXPECT(bool{p.get_parameter("y") == y});
Shucai Xiao's avatar
Shucai Xiao committed
251
    EXPECT(bool{p.get_parameter("nonexistent") == mm->end()});
Paul's avatar
Paul committed
252
}
Paul's avatar
Paul committed
253

Paul's avatar
Paul committed
254
255
256
TEST_CASE(get_param2)
{
    migraphx::program p;
257
258
259
260
    auto* mm = p.get_main_module();
    auto one = mm->add_literal(1);
    auto two = mm->add_literal(2);
    mm->add_instruction(sum_op{}, one, two);
Shucai Xiao's avatar
Shucai Xiao committed
261
    EXPECT(bool{p.get_parameter("nonexistent") == mm->end()});
Paul's avatar
Paul committed
262
}
Paul's avatar
Paul committed
263

Paul's avatar
Paul committed
264
265
266
TEST_CASE(get_param_shapes)
{
    migraphx::program p;
267
    auto* mm = p.get_main_module();
Paul's avatar
Paul committed
268
    migraphx::shape s{migraphx::shape::int32_type, {1, 2}};
269
270
271
    auto x = mm->add_parameter("x", s);
    auto y = mm->add_parameter("y", s);
    mm->add_instruction(sum_op{}, x, y);
Paul's avatar
Paul committed
272
273
274
275
    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
276
277
}

Paul's avatar
Paul committed
278
TEST_CASE(replace_test)
Paul's avatar
Paul committed
279
{
Paul's avatar
Paul committed
280
    migraphx::program p;
281
282
283
284
285
    auto* mm = p.get_main_module();
    auto one = mm->add_literal(1);
    auto two = mm->add_literal(2);
    auto sum = mm->add_instruction(sum_op{}, one, two);
    mm->replace_instruction(sum, minus_op{}, two, one);
Shucai Xiao's avatar
Shucai Xiao committed
286
    EXPECT(bool{p.validate() == mm->end()});
Paul's avatar
Paul committed
287

288
    auto result = p.eval({}).back();
Paul's avatar
Paul committed
289
290
    EXPECT(result == migraphx::literal{1});
    EXPECT(result != migraphx::literal{3});
Paul's avatar
Paul committed
291
292
}

Paul's avatar
Paul committed
293
TEST_CASE(replace_ins_test)
Paul's avatar
Paul committed
294
{
Paul's avatar
Paul committed
295
    migraphx::program p;
296
297
298
299
300
301
    auto* mm   = p.get_main_module();
    auto one   = mm->add_literal(1);
    auto two   = mm->add_literal(2);
    auto sum   = mm->add_instruction(sum_op{}, one, two);
    auto minus = mm->add_instruction(minus_op{}, two, one);
    mm->replace_instruction(sum, minus);
Shucai Xiao's avatar
Shucai Xiao committed
302
    EXPECT(bool{p.validate() == mm->end()});
Paul's avatar
Paul committed
303

304
    auto result = p.eval({}).back();
Paul's avatar
Paul committed
305
306
    EXPECT(result == migraphx::literal{1});
    EXPECT(result != migraphx::literal{3});
Paul's avatar
Paul committed
307
308
}

Paul's avatar
Paul committed
309
TEST_CASE(replace_ins_test2)
Paul's avatar
Paul committed
310
{
Paul's avatar
Paul committed
311
    migraphx::program p;
312
313
314
315
316
317
318
    auto* mm   = p.get_main_module();
    auto one   = mm->add_literal(1);
    auto two   = mm->add_literal(2);
    auto sum   = mm->add_instruction(sum_op{}, one, two);
    auto minus = mm->add_instruction(minus_op{}, two, one);
    mm->add_instruction(pass_op{}, minus);
    mm->replace_instruction(two, sum);
Shucai Xiao's avatar
Shucai Xiao committed
319
    EXPECT(bool{p.validate() == mm->end()});
Paul's avatar
Paul committed
320

321
    auto result = p.eval({}).back();
Paul's avatar
Paul committed
322
323
    EXPECT(result == migraphx::literal{2});
    EXPECT(result != migraphx::literal{3});
Paul's avatar
Paul committed
324
325
}

Paul's avatar
Paul committed
326
327
328
TEST_CASE(replace_op_test)
{
    migraphx::program p;
329
330
331
332
    auto* mm = p.get_main_module();
    auto one = mm->add_literal(1);
    auto two = mm->add_literal(2);
    auto sum = mm->add_instruction(sum_op{}, two, one);
Paul's avatar
Paul committed
333
    sum->replace(minus_op{});
Shucai Xiao's avatar
Shucai Xiao committed
334
    EXPECT(bool{p.validate() == mm->end()});
Paul's avatar
Paul committed
335

336
    auto result = p.eval({}).back();
Paul's avatar
Paul committed
337
338
339
340
341
342
343
    EXPECT(result == migraphx::literal{1});
    EXPECT(result != migraphx::literal{3});
}

TEST_CASE(replace_op_recompute_shape_throw)
{
    migraphx::program p;
344
345
346
347
    auto* mm = p.get_main_module();
    auto one = mm->add_literal(1);
    auto two = mm->add_literal(2);
    auto sum = mm->add_instruction(sum_op{}, one, two);
Paul's avatar
Paul committed
348
    EXPECT(test::throws<migraphx::exception>([&] { sum->replace(unary_pass_op{}); }));
Paul's avatar
Paul committed
349
350
}

Paul's avatar
Paul committed
351
TEST_CASE(insert_replace_test)
Paul's avatar
Paul committed
352
{
Paul's avatar
Paul committed
353
    migraphx::program p;
354
355
356
357
358
359
360
361
    auto* mm  = p.get_main_module();
    auto one  = mm->add_literal(1);
    auto two  = mm->add_literal(2);
    auto sum1 = mm->add_instruction(sum_op{}, one, two);
    mm->add_instruction(sum_op{}, sum1, two);

    auto sum0 = mm->insert_instruction(sum1, sum_op{}, two, two);
    mm->replace_instruction(sum1, minus_op{}, sum0, two);
Shucai Xiao's avatar
Shucai Xiao committed
362
    EXPECT(bool{p.validate() == mm->end()});
Paul's avatar
Paul committed
363

364
    auto result = p.eval({}).back();
Paul's avatar
Paul committed
365
366
    EXPECT(result == migraphx::literal{4});
    EXPECT(result != migraphx::literal{5});
Paul's avatar
Paul committed
367
368
}

Paul's avatar
Paul committed
369
370
371
TEST_CASE(remove_test1)
{
    migraphx::program p;
372
373
374
375
376
377
    auto* mm     = p.get_main_module();
    auto one     = mm->add_literal(1);
    auto two     = mm->add_literal(2);
    auto sum     = mm->add_instruction(sum_op{}, one, two);
    auto removed = mm->add_instruction(minus_op{}, sum, one);
    mm->remove_instruction(removed);
Shucai Xiao's avatar
Shucai Xiao committed
378
    EXPECT(bool{p.validate() == mm->end()});
Paul's avatar
Paul committed
379

380
    auto result = p.eval({}).back();
Paul's avatar
Paul committed
381
382
383
384
385
386
387
    EXPECT(result == migraphx::literal{3});
    EXPECT(result != migraphx::literal{1});
}

TEST_CASE(remove_test2)
{
    migraphx::program p;
388
389
390
391
392
393
    auto* mm     = p.get_main_module();
    auto one     = mm->add_literal(1);
    auto two     = mm->add_literal(2);
    auto removed = mm->add_instruction(minus_op{}, two, one);
    mm->add_instruction(sum_op{}, one, two);
    mm->remove_instruction(removed);
Shucai Xiao's avatar
Shucai Xiao committed
394
    EXPECT(bool{p.validate() == mm->end()});
Paul's avatar
Paul committed
395

396
    auto result = p.eval({}).back();
Paul's avatar
Paul committed
397
398
399
400
    EXPECT(result == migraphx::literal{3});
    EXPECT(result != migraphx::literal{1});
}

Paul's avatar
Paul committed
401
TEST_CASE(target_test)
Paul's avatar
Paul committed
402
{
Paul's avatar
Paul committed
403
    migraphx::program p;
404
405
406
407
    auto* mm = p.get_main_module();
    auto one = mm->add_literal(1);
    auto two = mm->add_literal(2);
    mm->add_instruction(sum_op{}, one, two);
Paul's avatar
Paul committed
408
    p.compile(id_target{});
409
    auto result = p.eval({}).back();
Paul's avatar
Paul committed
410
411
    EXPECT(result == migraphx::literal{3});
    EXPECT(result != migraphx::literal{4});
Paul's avatar
Paul committed
412
413
}

Paul's avatar
Paul committed
414
TEST_CASE(invert_target_test)
Paul's avatar
Paul committed
415
{
Paul's avatar
Paul committed
416
    migraphx::program p;
417
418
419
420
    auto* mm = p.get_main_module();
    auto one = mm->add_literal(1);
    auto two = mm->add_literal(2);
    mm->add_instruction(sum_op{}, two, one);
Paul's avatar
Paul committed
421
    p.compile(invert_target{});
422
    auto result = p.eval({}).back();
Paul's avatar
Paul committed
423
424
    EXPECT(result == migraphx::literal{1});
    EXPECT(result != migraphx::literal{4});
Paul's avatar
Paul committed
425
426
}

Paul's avatar
Paul committed
427
TEST_CASE(double_invert_target_test)
Paul's avatar
Paul committed
428
{
Paul's avatar
Paul committed
429
    migraphx::program p;
430
431
432
433
    auto* mm = p.get_main_module();
    auto one = mm->add_literal(1);
    auto two = mm->add_literal(2);
    mm->add_instruction(sum_op{}, two, one);
Paul's avatar
Paul committed
434
    p.compile(double_invert_target{});
435
    auto result = p.eval({}).back();
Paul's avatar
Paul committed
436
437
    EXPECT(result == migraphx::literal{3});
    EXPECT(result != migraphx::literal{4});
Paul's avatar
Paul committed
438
439
}

Paul's avatar
Paul committed
440
441
442
TEST_CASE(reverse_target_test)
{
    migraphx::program p;
443
444
445
446
    auto* mm = p.get_main_module();
    auto one = mm->add_literal(1);
    auto two = mm->add_literal(2);
    mm->add_instruction(sum_op{}, one, two);
Paul's avatar
Paul committed
447
    EXPECT(test::throws<migraphx::exception>([&] { p.compile(reverse_target{}); }));
Paul's avatar
Paul committed
448
449
}

Paul's avatar
Paul committed
450
451
// Check that the program doesnt modify the context directly, and only the operators modify the
// context
Paul's avatar
Paul committed
452
453
454
TEST_CASE(eval_context1)
{
    migraphx::program p;
455
    auto* mm = p.get_main_module();
Paul's avatar
Paul committed
456
457
    id_target t{};
    EXPECT(is_shared(t.ctx, t.get_context()));
458
459
460
    auto one = mm->add_literal(1);
    auto two = mm->add_literal(2);
    mm->add_instruction(sum_op{}, one, two);
Paul's avatar
Paul committed
461
462
    p.compile(t);
    EXPECT(is_shared(t.ctx, p.get_context()));
463
    p.eval({}).back();
Paul's avatar
Paul committed
464
465
466
467
468
469
    EXPECT(is_shared(t.ctx, p.get_context()));
}

TEST_CASE(eval_context2)
{
    migraphx::program p;
470
    auto* mm = p.get_main_module();
Paul's avatar
Paul committed
471
472
    id_target t{};
    EXPECT(is_shared(t.ctx, t.get_context()));
473
474
475
    auto one = mm->add_literal(1);
    auto two = mm->add_literal(2);
    mm->add_instruction(id_ctx_op{}, one, two);
Paul's avatar
Paul committed
476
477
    p.compile(t);
    EXPECT(is_shared(t.ctx, p.get_context()));
478
    p.eval({}).back();
Paul's avatar
Paul committed
479
480
481
482
483
484
485
    // id_ctx_op will modify the context
    EXPECT(not is_shared(t.ctx, p.get_context()));
}

TEST_CASE(eval_context3)
{
    migraphx::program p;
486
    auto* mm = p.get_main_module();
Paul's avatar
Paul committed
487
488
    id_target t{};
    EXPECT(is_shared(t.ctx, t.get_context()));
489
490
491
    auto one = mm->add_literal(1);
    auto two = mm->add_literal(2);
    mm->add_instruction(id_ctx_final_op{}, one, two);
Paul's avatar
Paul committed
492
493
494
495
    p.compile(t);
    // Finalizer will modify the context
    EXPECT(not is_shared(t.ctx, p.get_context()));
    auto ctx = p.get_context();
496
    p.eval({}).back();
Paul's avatar
Paul committed
497
498
499
500
    EXPECT(is_shared(ctx, p.get_context()));
    EXPECT(not is_shared(t.ctx, p.get_context()));
}

Paul's avatar
Paul committed
501
502
503
504
505
506
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
507
508
    {
    }
Paul's avatar
Paul committed
509
    ~cout_redirect() { std::cout.rdbuf(old); }
Paul's avatar
Paul committed
510

Paul's avatar
Paul committed
511
512
    private:
    std::streambuf* old;
Paul's avatar
Paul committed
513
514
};

Paul's avatar
Paul committed
515
template <class F>
Paul's avatar
Paul committed
516
517
518
519
520
521
522
523
524
525
526
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;
527
528
    auto* mm                                    = p.get_main_module();
    auto one                                    = mm->add_literal(1);
Paul's avatar
Paul committed
529
    std::vector<migraphx::instruction_ref> onev = {one};
Paul's avatar
Paul committed
530
531

    migraphx::program p2;
532
533
    auto* mm2 = p2.get_main_module();
    auto one2 = mm2->add_literal(1);
Paul's avatar
Paul committed
534

Shucai Xiao's avatar
Shucai Xiao committed
535
536
537
538
539
    auto program_out = migraphx::trim(capture_output([&] { mm->debug_print(); }));
    auto ins_out     = migraphx::trim(capture_output([&] { mm->debug_print(one); }));
    auto inss_out    = migraphx::trim(capture_output([&] { mm->debug_print(onev); }));
    auto end_out     = migraphx::trim(capture_output([&] { mm->debug_print(mm->end()); }));
    auto p2_ins_out  = migraphx::trim(capture_output([&] { mm->debug_print(one2); }));
Paul's avatar
Paul committed
540
541
542
543

    EXPECT(program_out == ins_out);
    EXPECT(inss_out == ins_out);
    EXPECT(end_out == "End instruction");
Shucai Xiao's avatar
Shucai Xiao committed
544
    EXPECT(p2_ins_out == "Instruction not part of module");
Paul's avatar
Paul committed
545
546
}

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