main.cpp 4.98 KB
Newer Older
Paul's avatar
Paul committed
1
2
#include "argument_parser.hpp"
#include "command.hpp"
Paul's avatar
Paul committed
3
#include "verify.hpp"
Paul's avatar
Paul committed
4
#include "perf.hpp"
Paul's avatar
Paul committed
5

Paul's avatar
Paul committed
6
7
8
9
10
11
12
13
14
15
16
17
#include <migraphx/tf.hpp>
#include <migraphx/onnx.hpp>
#include <migraphx/stringutils.hpp>

namespace migraphx {
namespace driver {
inline namespace MIGRAPHX_INLINE_NS {

struct loader
{
    std::string file;
    std::string type;
Paul's avatar
Paul committed
18
    bool is_nhwc  = false;
Paul's avatar
Paul committed
19
    unsigned trim = 0;
Paul's avatar
Paul committed
20
21
22

    void parse(argument_parser& ap)
    {
Paul's avatar
Paul committed
23
24
25
26
        ap(file, {}, ap.metavar("<input file>"));
        ap(type, {"--onnx"}, ap.help("Load as onnx"), ap.set_value("onnx"));
        ap(type, {"--tf"}, ap.help("Load as tensorflow"), ap.set_value("tf"));
        ap(is_nhwc, {"--nhwc"}, ap.help("Treat tensorflow format as nhwc"), ap.set_value(true));
Paul's avatar
Paul committed
27
        ap(is_nhwc, {"--nchw"}, ap.help("Treat tensorflow format as nchw"), ap.set_value(false));
Paul's avatar
Paul committed
28
        ap(trim, {"--trim", "-t"}, ap.help("Trim instructions from the end"));
Paul's avatar
Paul committed
29
30
    }

Paul's avatar
Paul committed
31
    program load()
Paul's avatar
Paul committed
32
33
    {
        program p;
Paul's avatar
Paul committed
34
        if(type.empty())
Paul's avatar
Paul committed
35
        {
Paul's avatar
Paul committed
36
            if(ends_with(file, ".onnx"))
Paul's avatar
Paul committed
37
38
39
40
                type = "onnx";
            else
                type = "tf";
        }
Paul's avatar
Paul committed
41
        std::cout << "Reading: " << file << std::endl;
Paul's avatar
Paul committed
42
        if(type == "onnx")
Paul's avatar
Paul committed
43
            p = parse_onnx(file);
Paul's avatar
Paul committed
44
        else if(type == "tf")
Paul's avatar
Paul committed
45
            p = parse_tf(file, is_nhwc);
Paul's avatar
Paul committed
46
        if(trim > 0)
Paul's avatar
Paul committed
47
        {
Paul's avatar
Paul committed
48
            auto last = std::prev(p.end(), trim);
Paul's avatar
Paul committed
49
50
            p.remove_instructions(last, p.end());
        }
Paul's avatar
Paul committed
51
52
53
54
        return p;
    }
};

Paul's avatar
Paul committed
55
56
57
58
struct compiler
{
    loader l;
    bool gpu = true;
Paul's avatar
Paul committed
59
60
    void parse(argument_parser& ap)
    {
Paul's avatar
Paul committed
61
62
63
64
65
66
67
68
69
70
71
72
        l.parse(ap);
        ap(gpu, {"--gpu"}, ap.help("Compile on the gpu"), ap.set_value(true));
        ap(gpu, {"--cpu"}, ap.help("Compile on the cpu"), ap.set_value(false));
    }

    program compile()
    {
        auto p = l.load();
        compile_program(p, gpu);
        return p;
    }

Paul's avatar
Paul committed
73
    auto params(const program& p) { return create_param_map(p, gpu); }
Paul's avatar
Paul committed
74
75
};

Paul's avatar
Paul committed
76
77
78
struct read : command<read>
{
    loader l;
Paul's avatar
Paul committed
79
    void parse(argument_parser& ap) { l.parse(ap); }
Paul's avatar
Paul committed
80
81
82
83
84
85
86
87

    void run()
    {
        auto p = l.load();
        std::cout << p << std::endl;
    }
};

Paul's avatar
Paul committed
88
89
90
struct verify : command<verify>
{
    loader l;
Paul's avatar
Paul committed
91
    double tolerance     = 80;
Paul's avatar
Paul committed
92
    bool per_instruction = false;
Paul's avatar
Paul committed
93
94
95
    bool reduce          = false;
    void parse(argument_parser& ap)
    {
Paul's avatar
Paul committed
96
        l.parse(ap);
Paul's avatar
Paul committed
97
98
        ap(tolerance, {"--tolerance"}, ap.help("Tolerance for errors"));
        ap(per_instruction,
Paul's avatar
Paul committed
99
100
101
102
           {"-i", "--per-instruction"},
           ap.help("Verify each instruction"),
           ap.set_value(true));
        ap(reduce, {"-r", "--reduce"}, ap.help("Reduce program and verify"), ap.set_value(true));
Paul's avatar
Paul committed
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
    }

    void run()
    {
        auto p = l.load();
        std::cout << p << std::endl;

        if(per_instruction)
        {
            verify_instructions(p, tolerance);
        }
        else if(reduce)
        {
            verify_reduced_program(p, tolerance);
        }
        else
        {
            verify_program(l.file, p, tolerance);
        }
    }
};

Paul's avatar
Paul committed
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
struct compile : command<compile>
{
    compiler c;
    void parse(argument_parser& ap)
    {
        c.parse(ap);
    }

    void run()
    {
        std::cout << "Compiling ... " << std::endl;
        auto p = c.compile();
        std::cout << p << std::endl;
    }
};

struct run_cmd : command<run_cmd>
{
    compiler c;
    void parse(argument_parser& ap)
    {
        c.parse(ap);
    }

    void run()
    {
        std::cout << "Compiling ... " << std::endl;
        auto p = c.compile();
        std::cout << "Allocating params ... " << std::endl;
        auto m = c.params(p);
        std::cout << p << std::endl;
    }
};

Paul's avatar
Paul committed
159
160
161
162
struct perf : command<perf>
{
    compiler c;
    unsigned n = 100;
Paul's avatar
Paul committed
163
164
    void parse(argument_parser& ap)
    {
Paul's avatar
Paul committed
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
        c.parse(ap);
        ap(n, {"--iterations", "-n"}, ap.help("Number of iterations to run for perf report"));
    }

    void run()
    {
        std::cout << "Compiling ... " << std::endl;
        auto p = c.compile();
        std::cout << "Allocating params ... " << std::endl;
        auto m = c.params(p);
        std::cout << "Running performance report ... " << std::endl;
        p.perf_report(std::cout, n, m);
    }
};

Paul's avatar
Paul committed
180
181
182
183
184
struct main_command
{
    static std::string get_command_help()
    {
        std::string result = "Commands:\n";
Paul's avatar
Paul committed
185
        for(const auto& p : get_commands())
Paul's avatar
Paul committed
186
187
188
            result += "    " + p.first + "\n";
        return result;
    }
Paul's avatar
Paul committed
189
    void parse(argument_parser& ap)
Paul's avatar
Paul committed
190
    {
Paul's avatar
Paul committed
191
        ap(nullptr, {"-h", "--help"}, ap.help("Show help"), ap.show_help(get_command_help()));
Paul's avatar
Paul committed
192
193
194
195
196
    }

    void run() {}
};

Paul's avatar
Paul committed
197
198
199
200
201
} // namespace MIGRAPHX_INLINE_NS
} // namespace driver
} // namespace migraphx

using namespace migraphx::driver;
Paul's avatar
Paul committed
202
203
int main(int argc, const char* argv[])
{
Paul's avatar
Paul committed
204
    std::vector<std::string> args(argv + 1, argv + argc);
Paul's avatar
Paul committed
205
    if(args.empty())
Paul's avatar
Paul committed
206
        return 0;
Paul's avatar
Paul committed
207
    auto&& m = get_commands();
Paul's avatar
Paul committed
208
    auto cmd = args.front();
Paul's avatar
Paul committed
209
    if(m.count(cmd) > 0)
Paul's avatar
Paul committed
210
    {
Paul's avatar
Paul committed
211
        m.at(cmd)({args.begin() + 1, args.end()});
Paul's avatar
Paul committed
212
    }
Paul's avatar
Paul committed
213
    else
Paul's avatar
Paul committed
214
    {
Paul's avatar
Paul committed
215
        run_command<main_command>(args);
Paul's avatar
Paul committed
216
217
218
    }
    return 0;
}