miopen.cpp 9.79 KB
Newer Older
Paul's avatar
Paul committed
1

Paul's avatar
Paul committed
2
3
4
5
#include <migraph/program.hpp>
#include <migraph/operators.hpp>
#include <migraph/generate.hpp>
#include <migraph/cpu/cpu_target.hpp>
Paul's avatar
Paul committed
6
7
8
#include <migraph/gpu/target.hpp>
#include <migraph/gpu/miopen.hpp>
#include <migraph/gpu/hip.hpp>
Paul's avatar
Paul committed
9
#include <migraph/manage_ptr.hpp>
Paul's avatar
Paul committed
10
#include <migraph/type_name.hpp>
Paul's avatar
Paul committed
11
12
13
14

#include <miopen/miopen.h>

#include "test.hpp"
Paul's avatar
Paul committed
15
#include "verify.hpp"
Paul's avatar
Paul committed
16

Paul's avatar
Paul committed
17
template <class V>
Paul's avatar
Paul committed
18
migraph::argument run_cpu()
Paul's avatar
Paul committed
19
{
Paul's avatar
Paul committed
20
21
    V v;
    auto p = v.create_program();
Paul's avatar
Paul committed
22
    p.compile(migraph::cpu::cpu_target{});
Paul's avatar
Paul committed
23
    migraph::program::parameter_map m;
Paul's avatar
Paul committed
24
    for(auto&& x : p.get_parameter_shapes())
Paul's avatar
Paul committed
25
26
27
28
    {
        m[x.first] = migraph::generate_argument(x.second);
    }
    return p.eval(m);
Paul's avatar
Paul committed
29
30
}

Paul's avatar
Paul committed
31
template <class V>
Paul's avatar
Paul committed
32
migraph::argument run_gpu()
Paul's avatar
Paul committed
33
{
Paul's avatar
Paul committed
34
35
    V v;
    auto p = v.create_program();
Paul's avatar
Paul committed
36
    p.compile(migraph::gpu::target{});
Paul's avatar
Paul committed
37

Paul's avatar
Paul committed
38
    migraph::program::parameter_map m;
Paul's avatar
Paul committed
39
    for(auto&& x : p.get_parameter_shapes())
Paul's avatar
Paul committed
40
    {
Paul's avatar
Paul committed
41
        m[x.first] = migraph::gpu::to_gpu(migraph::generate_argument(x.second));
Paul's avatar
Paul committed
42
43
    }

Paul's avatar
Paul committed
44
    return migraph::gpu::from_gpu(p.eval(m));
Paul's avatar
Paul committed
45
46
}

Paul's avatar
Paul committed
47
template <class V>
Paul's avatar
Paul committed
48
void verify_program()
Paul's avatar
Paul committed
49
{
Paul's avatar
Paul committed
50
51
    auto cpu_arg = run_cpu<V>();
    auto gpu_arg = run_gpu<V>();
Paul's avatar
Paul committed
52
53
54
    visit_all(cpu_arg, gpu_arg)([](auto cpu, auto gpu) {
        if(not test::verify_range(cpu, gpu))
        {
Paul's avatar
Paul committed
55
56
57
            std::cout << "FAILED: " << migraph::get_type_name<V>() << std::endl;
        }
    });
Paul's avatar
Paul committed
58
59
}

Paul's avatar
Paul committed
60
61
62
63
64
struct test_literals
{
    migraph::program create_program() const
    {
        migraph::program p;
Paul's avatar
Paul committed
65
66
67
68
        auto input = p.add_literal(
            generate_literal(migraph::shape{migraph::shape::float_type, {4, 3, 3, 3}}));
        auto weights = p.add_literal(
            generate_literal(migraph::shape{migraph::shape::float_type, {4, 3, 3, 3}}));
Paul's avatar
Paul committed
69
70
71
72
73
74
        auto conv = p.add_instruction(migraph::convolution{}, input, weights);
        p.add_instruction(migraph::activation{"relu"}, conv);
        return p;
    }
};

Paul's avatar
Paul committed
75
76
struct test_add
{
Paul's avatar
Paul committed
77
    migraph::program create_program() const
Paul's avatar
Paul committed
78
    {
Paul's avatar
Paul committed
79
80
        migraph::program p;
        migraph::shape s{migraph::shape::float_type, {3}};
Paul's avatar
Paul committed
81
82
        auto x = p.add_parameter("x", s);
        auto y = p.add_parameter("y", s);
Paul's avatar
Paul committed
83
        p.add_instruction(migraph::add{}, x, y);
Paul's avatar
Paul committed
84
85
86
87
88
89
        return p;
    }
};

struct test_add_broadcast
{
Paul's avatar
Paul committed
90
    migraph::program create_program() const
Paul's avatar
Paul committed
91
    {
Paul's avatar
Paul committed
92
93
94
95
96
97
        migraph::program p;
        migraph::shape s{migraph::shape::float_type, {3}};
        auto x  = p.add_parameter("x", {migraph::shape::float_type, {2, 2, 3}});
        auto y  = p.add_parameter("y", {migraph::shape::float_type, {2, 2}});
        auto by = p.add_instruction(migraph::broadcast{0}, x, y);
        p.add_instruction(migraph::add{}, x, by);
Paul's avatar
Paul committed
98
99
100
101
        return p;
    }
};

Paul's avatar
Paul committed
102
struct test_conv_relu
Paul's avatar
Paul committed
103
{
Paul's avatar
Paul committed
104
    migraph::program create_program() const
Paul's avatar
Paul committed
105
    {
Paul's avatar
Paul committed
106
        migraph::program p;
Paul's avatar
Paul committed
107
108
109
110
        auto input = p.add_parameter("x", migraph::shape{migraph::shape::float_type, {4, 3, 3, 3}});
        auto weights =
            p.add_parameter("w", migraph::shape{migraph::shape::float_type, {4, 3, 3, 3}});
        auto conv = p.add_instruction(migraph::convolution{}, input, weights);
Paul's avatar
Paul committed
111
        p.add_instruction(migraph::activation{"relu"}, conv);
Paul's avatar
Paul committed
112
113
114
115
        return p;
    }
};

Paul's avatar
Paul committed
116
117
struct test_conv_pooling
{
Paul's avatar
Paul committed
118
    migraph::program create_program() const
Paul's avatar
Paul committed
119
    {
Paul's avatar
Paul committed
120
        migraph::program p;
Paul's avatar
Paul committed
121
122
123
124
        auto input =
            p.add_parameter("x", migraph::shape{migraph::shape::float_type, {4, 3, 32, 32}});
        auto weights =
            p.add_parameter("w", migraph::shape{migraph::shape::float_type, {4, 3, 3, 3}});
Paul's avatar
Paul committed
125
126
127
        auto conv    = p.add_instruction(migraph::convolution{}, input, weights);
        auto pooling = p.add_instruction(migraph::pooling{"max"}, conv);
        p.add_instruction(migraph::activation{"relu"}, pooling);
Paul's avatar
Paul committed
128
129
130
131
        return p;
    }
};

Paul's avatar
Paul committed
132
133
struct test_gemm
{
Paul's avatar
Paul committed
134
    migraph::program create_program() const
Paul's avatar
Paul committed
135
    {
Paul's avatar
Paul committed
136
137
138
139
        migraph::program p;
        auto a = p.add_parameter("a", migraph::shape{migraph::shape::float_type, {4, 5}});
        auto b = p.add_parameter("b", migraph::shape{migraph::shape::float_type, {5, 3}});
        p.add_instruction(migraph::gemm{}, a, b);
Paul's avatar
Paul committed
140
141
142
143
        return p;
    }
};

Paul's avatar
Paul committed
144
145
146
struct test_gemm_ld
{
    migraph::program create_program() const
Paul's avatar
Paul committed
147
    {
Paul's avatar
Paul committed
148
149
150
151
152
153
154
155
        migraph::program p;
        auto a = p.add_parameter("a", migraph::shape{migraph::shape::float_type, {4, 5}, {10, 1}});
        auto b = p.add_parameter("b", migraph::shape{migraph::shape::float_type, {5, 3}, {20, 1}});
        p.add_instruction(migraph::gemm{}, a, b);
        return p;
    }
};

156
157
158
159
160
struct test_gemm_transposeb
{
    migraph::program create_program() const
    {
        migraph::program p;
Paul's avatar
Paul committed
161
162
        auto a  = p.add_parameter("a", migraph::shape{migraph::shape::float_type, {4, 5}});
        auto b  = p.add_parameter("b", migraph::shape{migraph::shape::float_type, {3, 5}});
163
164
165
166
167
168
169
170
171
172
173
        auto bt = p.add_instruction(migraph::transpose{{1, 0}}, b);
        p.add_instruction(migraph::gemm{}, a, bt);
        return p;
    }
};

struct test_gemm_transposea
{
    migraph::program create_program() const
    {
        migraph::program p;
Paul's avatar
Paul committed
174
175
        auto a  = p.add_parameter("a", migraph::shape{migraph::shape::float_type, {5, 4}});
        auto b  = p.add_parameter("b", migraph::shape{migraph::shape::float_type, {5, 3}});
176
177
178
179
180
181
182
183
184
185
186
        auto at = p.add_instruction(migraph::transpose{{1, 0}}, a);
        p.add_instruction(migraph::gemm{}, at, b);
        return p;
    }
};

struct test_gemm_transposeab
{
    migraph::program create_program() const
    {
        migraph::program p;
Paul's avatar
Paul committed
187
188
        auto a  = p.add_parameter("a", migraph::shape{migraph::shape::float_type, {5, 4}});
        auto b  = p.add_parameter("b", migraph::shape{migraph::shape::float_type, {3, 5}});
189
190
191
192
        auto at = p.add_instruction(migraph::transpose{{1, 0}}, a);
        auto bt = p.add_instruction(migraph::transpose{{1, 0}}, b);
        p.add_instruction(migraph::gemm{}, at, bt);
        return p;
Paul's avatar
Paul committed
193
194
195
    }
};

196
197
198
199
200
struct test_contiguous
{
    migraph::program create_program() const
    {
        migraph::program p;
201
        migraph::shape s{migraph::shape::float_type, {4, 4, 4, 3}, {48, 4, 1, 16}};
202
203
204
205
206
207
        auto x = p.add_parameter("x", s);
        p.add_instruction(migraph::contiguous{}, x);
        return p;
    }
};

208
struct test_transpose
209
{
210
211
212
213
214
215
216
217
218
219
220
    migraph::program create_program() const
    {
        migraph::program p;
        migraph::shape s{migraph::shape::float_type, {4, 3, 4, 4}};
        auto x                    = p.add_parameter("x", s);
        std::vector<int64_t> perm = {0, 2, 3, 1};
        auto l                    = p.add_instruction(migraph::transpose{perm}, x);
        p.add_instruction(migraph::contiguous{}, l);
        return p;
    }
};
221

wsttiger's avatar
wsttiger committed
222
223
224
225
226
227
228
229
230
231
232
233
struct test_batchnorm_inference
{
    const size_t width    = 3;
    const size_t height   = 3;
    const size_t channels = 3;
    const size_t batches  = 4;

    migraph::program create_program() const
    {
        migraph::program p;

        migraph::shape s{migraph::shape::float_type, {batches, channels, height, width}};
234
        migraph::shape vars{migraph::shape::float_type, {channels}};
wsttiger's avatar
wsttiger committed
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
        auto x        = p.add_parameter("x", s);
        auto mean     = p.add_parameter("mean", vars);
        auto variance = p.add_parameter("variance", vars);
        auto scale    = p.add_parameter("scale", vars);
        auto bias     = p.add_parameter("bias", vars);
        p.add_instruction(migraph::batch_norm_inference{}, x, mean, variance, scale, bias);
        return p;
    }
};

void batch_norm_inference_test()
{
    migraph::program p;
    const size_t width = 2, height = 2, channels = 4, batches = 2;
    const float x_val = 8.0f, mean_val = 2.0f, variance_val = 4.0f, scale_val = 2.0f,
                bias_val   = 1.0f;
    const float output_val = scale_val * (x_val - mean_val) / (std::sqrt(variance_val)) + bias_val;

    migraph::shape s{migraph::shape::float_type, {batches, channels, height, width}};
254
    migraph::shape vars{migraph::shape::float_type, {channels}};
wsttiger's avatar
wsttiger committed
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
    std::vector<float> x_data(width * height * channels * batches);
    std::vector<float> scale_data(channels);
    std::vector<float> bias_data(channels);
    std::vector<float> mean_data(channels);
    std::vector<float> variance_data(channels);

    std::fill(x_data.begin(), x_data.end(), x_val);
    std::fill(mean_data.begin(), mean_data.end(), mean_val);
    std::fill(variance_data.begin(), variance_data.end(), variance_val);
    std::fill(scale_data.begin(), scale_data.end(), scale_val);
    std::fill(bias_data.begin(), bias_data.end(), bias_val);

    auto x        = p.add_literal(migraph::literal{s, x_data});
    auto scale    = p.add_literal(migraph::literal{vars, scale_data});
    auto bias     = p.add_literal(migraph::literal{vars, bias_data});
    auto mean     = p.add_literal(migraph::literal{vars, mean_data});
    auto variance = p.add_literal(migraph::literal{vars, variance_data});

    p.add_instruction(migraph::batch_norm_inference{}, x, mean, variance, scale, bias);
    p.compile(migraph::gpu::target{});
275
276
277
278

    migraph::program::parameter_map m;
    m["output"] = migraph::gpu::to_gpu(migraph::generate_argument(p.get_parameter_shape("output")));
    auto result = migraph::gpu::from_gpu(p.eval(m));
wsttiger's avatar
wsttiger committed
279
280
281
282
283
284
285
286
287

    std::vector<float> result_vector(width * height * channels * batches);
    std::vector<float> gold(width * height * channels * batches);
    std::fill(gold.begin(), gold.end(), output_val);
    result.visit([&](auto output) { result_vector.assign(output.begin(), output.end()); });

    EXPECT(test::verify_range(result_vector, gold));
}

Paul's avatar
Paul committed
288
289
int main()
{
wsttiger's avatar
wsttiger committed
290
291
292
293
294
295
296
297
298
299
300
    verify_program<test_add>();
    verify_program<test_add_broadcast>();
    verify_program<test_conv_relu>();
    verify_program<test_conv_pooling>();
    verify_program<test_gemm>();
    // verify_program<test_gemm_ld>();
    verify_program<test_gemm_transposeb>();
    verify_program<test_gemm_transposea>();
    verify_program<test_gemm_transposeab>();
    verify_program<test_contiguous>();
    verify_program<test_transpose>();
301
302
    verify_program<test_batchnorm_inference>();
    batch_norm_inference_test();
Paul's avatar
Paul committed
303
}