verify.cpp 4.16 KB
Newer Older
Paul's avatar
Paul committed
1
#include "verify.hpp"
2
#include "perf.hpp"
Paul's avatar
Paul committed
3

4
#include <migraphx/ref/target.hpp>
Paul's avatar
Paul committed
5
6
7
#include <migraphx/generate.hpp>
#include <migraphx/verify_args.hpp>
#include <migraphx/instruction.hpp>
8
#include <migraphx/compile_options.hpp>
Paul's avatar
Paul committed
9
10
11
12
13

namespace migraphx {
namespace driver {
inline namespace MIGRAPHX_INLINE_NS {

14
std::vector<argument> run_ref(program p, const parameter_map& inputs)
Paul's avatar
Paul committed
15
{
16
    p.compile(ref::target{});
17
    auto out = p.eval(inputs);
Paul's avatar
Paul committed
18
19
20
21
    std::cout << p << std::endl;
    return out;
}

22
23
std::vector<argument>
run_target(program p, const target& t, const compile_options& options, const parameter_map& inputs)
Paul's avatar
Paul committed
24
{
25
    p.compile(t, options);
Paul's avatar
Paul committed
26

27
    parameter_map m;
Paul's avatar
Paul committed
28
29
    for(auto&& x : p.get_parameter_shapes())
    {
30
        auto arg   = inputs.count(x.first) == 0 ? generate_argument(x.second) : inputs.at(x.first);
31
        m[x.first] = options.offload_copy ? arg : t.copy_to(arg);
Paul's avatar
Paul committed
32
    }
33
34
    auto gpu_out = p.eval(m);
    std::vector<argument> output(gpu_out.size());
Paul's avatar
Paul committed
35
    std::cout << p << std::endl;
36
    std::transform(gpu_out.begin(), gpu_out.end(), output.begin(), [&](auto& argu) {
37
        return options.offload_copy ? argu : t.copy_from(argu);
38
39
    });
    return output;
Paul's avatar
Paul committed
40
41
}

42
43
void verify_program(const std::string& name,
                    const program& p,
44
                    const target& t,
45
                    compile_options options,
46
                    const parameter_map& inputs,
47
                    double tolerance)
Paul's avatar
Paul committed
48
{
49
50
    auto x = run_ref(p, inputs);
    auto y = run_target(p, t, options, inputs);
51
52
53
54
55
56

    std::size_t output_num = x.size();
    for(std::size_t i = 0; i < output_num; ++i)
    {
        verify_args(name, x[i], y[i], tolerance);
    }
Paul's avatar
Paul committed
57
58
59
60
    // std::cout << "cpu: " << x << std::endl;
    // std::cout << "gpu: " << y << std::endl;
}

61
62
63
64
void verify_instructions(const program& prog,
                         const target& t,
                         compile_options options,
                         double tolerance)
Paul's avatar
Paul committed
65
{
66
67
    const auto* mm_prog = prog.get_main_module();
    for(auto&& ins : (*mm_prog))
Paul's avatar
Paul committed
68
69
70
71
72
73
74
75
76
    {
        if(ins.name().front() == '@')
            continue;
        if(ins.name() == "broadcast")
            continue;
        if(ins.name() == "transpose")
            continue;
        if(ins.name() == "reshape")
            continue;
Shucai Xiao's avatar
Shucai Xiao committed
77
78
        if(ins.name() == "undefined")
            continue;
Paul's avatar
Paul committed
79
        program p;
80
        auto* mm_p = p.get_main_module();
Paul's avatar
Paul committed
81
82
83
84
        std::vector<instruction_ref> inputs;
        for(auto&& arg : ins.inputs())
        {
            if(arg->name() == "@literal")
85
                inputs.push_back(mm_p->add_literal(arg->get_literal()));
Paul's avatar
Paul committed
86
            else
87
88
                inputs.push_back(
                    mm_p->add_parameter(std::to_string(inputs.size()), arg->get_shape()));
Paul's avatar
Paul committed
89
        }
90
        mm_p->add_instruction(ins.get_operator(), inputs);
Paul's avatar
Paul committed
91
92
93
94
        try
        {
            std::cout << "Verify: " << ins.name() << std::endl;
            std::cout << p << std::endl;
95
            verify_program(ins.name(), p, t, options, create_param_map(p, false), tolerance);
Paul's avatar
Paul committed
96
97
98
99
100
101
102
103
104
        }
        catch(...)
        {
            std::cout << "Instruction " << ins.name() << " threw an exception." << std::endl;
            throw;
        }
    }
}

105
106
void verify_reduced(program p,
                    int n,
107
                    const target& t,
108
                    compile_options options,
109
                    const parameter_map& inputs,
110
                    double tolerance)
Paul's avatar
Paul committed
111
{
112
    auto* mm  = p.get_main_module();
Shucai Xiao's avatar
Shucai Xiao committed
113
114
    auto last = std::prev(mm->end(), n + 1);
    mm->remove_instructions(last, mm->end());
Paul's avatar
Paul committed
115
116
    std::cout << "Verify: " << std::endl;
    std::cout << p << std::endl;
117
    verify_program(std::to_string(n), p, t, options, inputs, tolerance);
Paul's avatar
Paul committed
118
119
}

120
void verify_reduced_program(const program& p,
121
                            const target& t,
122
                            compile_options options,
123
                            const parameter_map& inputs,
124
                            double tolerance)
Paul's avatar
Paul committed
125
{
Shucai Xiao's avatar
Shucai Xiao committed
126
127
    const auto* mm = p.get_main_module();
    auto n         = std::distance(mm->begin(), mm->end());
Paul's avatar
Paul committed
128
129
    for(std::size_t i = 0; i < n; i++)
    {
130
        verify_reduced(p, i, t, options, inputs, tolerance);
Paul's avatar
Paul committed
131
132
133
134
135
136
    }
}

} // namespace MIGRAPHX_INLINE_NS
} // namespace driver
} // namespace migraphx