verify.cpp 6.66 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 "verify.hpp"
25
#include "perf.hpp"
Paul's avatar
Paul committed
26

27
#include <migraphx/register_target.hpp>
Paul's avatar
Paul committed
28
29
30
#include <migraphx/generate.hpp>
#include <migraphx/verify_args.hpp>
#include <migraphx/instruction.hpp>
31
#include <migraphx/compile_options.hpp>
kahmed10's avatar
kahmed10 committed
32
#include <migraphx/quantization.hpp>
33
#include <migraphx/ranges.hpp>
Paul's avatar
Paul committed
34
35
36
37
38

namespace migraphx {
namespace driver {
inline namespace MIGRAPHX_INLINE_NS {

39
std::vector<argument> run_ref(program p, const parameter_map& inputs)
Paul's avatar
Paul committed
40
{
41
    p.compile(migraphx::make_target("ref"));
42
    auto out = p.eval(inputs);
Paul's avatar
Paul committed
43
44
45
46
    std::cout << p << std::endl;
    return out;
}

kahmed10's avatar
kahmed10 committed
47
48
49
50
51
std::vector<argument> run_target(program p,
                                 const target& t,
                                 const compile_options& options,
                                 precision quantize,
                                 const parameter_map& inputs)
Paul's avatar
Paul committed
52
{
kahmed10's avatar
kahmed10 committed
53
54
55
56
    if(quantize == precision::fp16)
    {
        quantize_fp16(p);
    }
57
    p.compile(t, options);
Paul's avatar
Paul committed
58

59
    parameter_map m;
Paul's avatar
Paul committed
60
61
    for(auto&& x : p.get_parameter_shapes())
    {
62
        auto arg   = inputs.count(x.first) == 0 ? generate_argument(x.second) : inputs.at(x.first);
63
        m[x.first] = options.offload_copy ? arg : t.copy_to(arg);
Paul's avatar
Paul committed
64
    }
65
66
    auto gpu_out = p.eval(m);
    std::vector<argument> output(gpu_out.size());
Paul's avatar
Paul committed
67
    std::cout << p << std::endl;
68
    std::transform(gpu_out.begin(), gpu_out.end(), output.begin(), [&](auto& argu) {
69
        return options.offload_copy ? argu : t.copy_from(argu);
70
71
    });
    return output;
Paul's avatar
Paul committed
72
73
}

74
75
void verify_program(const std::string& name,
                    const program& p,
76
                    const target& t,
77
                    compile_options options,
kahmed10's avatar
kahmed10 committed
78
                    precision quantize,
79
                    const parameter_map& inputs,
80
                    verify::tolerance tols)
Paul's avatar
Paul committed
81
{
82
83
    auto ref_outs    = run_ref(p, inputs);
    auto target_outs = run_target(p, t, options, quantize, inputs);
84

85
    std::size_t output_num = ref_outs.size();
86
87
    for(std::size_t i = 0; i < output_num; ++i)
    {
88
89
        if(ref_outs[i].get_shape().type() != target_outs[i].get_shape().type() or
           ref_outs[i].get_shape().lens() != target_outs[i].get_shape().lens())
90
91
        {
            std::cout << "FAILED: " << name << std::endl;
92
93
            std::cout << "Shape mismatch {" << ref_outs[i].get_shape() << "} != {"
                      << target_outs[i].get_shape() << "}" << std::endl;
94
95
96
        }
        else
        {
97
            verify_args(name, target_outs[i], verify::expected{ref_outs[i]}, tols);
98
        }
99
    }
Paul's avatar
Paul committed
100
101
}

102
103
104
void verify_instructions(const program& prog,
                         const target& t,
                         compile_options options,
kahmed10's avatar
kahmed10 committed
105
                         precision quantize,
106
                         verify::tolerance tols)
Paul's avatar
Paul committed
107
{
108
109
    const auto* mm_prog = prog.get_main_module();
    for(auto&& ins : (*mm_prog))
Paul's avatar
Paul committed
110
111
112
113
114
115
116
117
118
    {
        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
119
120
        if(ins.name() == "undefined")
            continue;
Paul's avatar
Paul committed
121
        program p;
122
        auto* mm_p = p.get_main_module();
Paul's avatar
Paul committed
123
124
125
126
        std::vector<instruction_ref> inputs;
        for(auto&& arg : ins.inputs())
        {
            if(arg->name() == "@literal")
127
                inputs.push_back(mm_p->add_literal(arg->get_literal()));
Paul's avatar
Paul committed
128
            else
129
130
                inputs.push_back(
                    mm_p->add_parameter(std::to_string(inputs.size()), arg->get_shape()));
Paul's avatar
Paul committed
131
        }
132
        mm_p->add_instruction(ins.get_operator(), inputs);
Paul's avatar
Paul committed
133
134
135
136
        try
        {
            std::cout << "Verify: " << ins.name() << std::endl;
            std::cout << p << std::endl;
137
            verify_program(ins.name(), p, t, options, quantize, create_param_map(p, false), tols);
Paul's avatar
Paul committed
138
139
140
141
142
143
144
145
146
        }
        catch(...)
        {
            std::cout << "Instruction " << ins.name() << " threw an exception." << std::endl;
            throw;
        }
    }
}

147
148
void verify_reduced(program p,
                    int n,
149
                    const target& t,
150
                    compile_options options,
kahmed10's avatar
kahmed10 committed
151
                    precision quantize,
152
                    const parameter_map& inputs,
153
                    verify::tolerance tols)
Paul's avatar
Paul committed
154
{
155
    auto* mm  = p.get_main_module();
156
    auto last = std::prev(mm->end(), n);
Shucai Xiao's avatar
Shucai Xiao committed
157
    mm->remove_instructions(last, mm->end());
158
    std::cout << "Verify: " << n << std::endl;
Paul's avatar
Paul committed
159
    std::cout << p << std::endl;
160
161
    try
    {
162
        verify_program(std::to_string(n), p, t, options, quantize, inputs, tols);
163
164
165
166
167
168
    }
    catch(const std::exception& e)
    {
        std::cout << "FAILED: " << n << std::endl;
        std::cout << "Exception: " << e.what() << std::endl;
    }
Paul's avatar
Paul committed
169
170
}

171
void verify_reduced_program(const program& p,
172
                            const target& t,
173
                            compile_options options,
kahmed10's avatar
kahmed10 committed
174
                            precision quantize,
175
                            const parameter_map& inputs,
176
                            verify::tolerance tols)
Paul's avatar
Paul committed
177
{
Shucai Xiao's avatar
Shucai Xiao committed
178
179
    const auto* mm = p.get_main_module();
    auto n         = std::distance(mm->begin(), mm->end());
180
    std::cout << "Verify steps: " << n << std::endl;
181
    for(std::size_t i = 1; i < n; i++)
Paul's avatar
Paul committed
182
    {
183
184
185
186
187
188
        auto last = std::prev(mm->end(), i + 1);
        if(contains({"@literal", "@param"}, last->name()))
        {
            std::cout << "Skip: " << i << std::endl;
            continue;
        }
189
        verify_reduced(p, i, t, options, quantize, inputs, tols);
Paul's avatar
Paul committed
190
191
192
193
194
195
    }
}

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