api.cpp 10.1 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.
 */
24
#include <migraphx/execution_environment.hpp>
Paul Fultz II's avatar
Paul Fultz II committed
25
26
#include <migraphx/migraphx.h>
#include <migraphx/rank.hpp>
27
#include <migraphx/ranges.hpp>
Paul Fultz II's avatar
Paul Fultz II committed
28
29
30
#include <migraphx/shape.hpp>
#include <migraphx/program.hpp>
#include <migraphx/onnx.hpp>
kahmed10's avatar
kahmed10 committed
31
#include <migraphx/tf.hpp>
32
#include <migraphx/instruction_ref.hpp>
33
#include <migraphx/register_target.hpp>
Paul Fultz II's avatar
Paul Fultz II committed
34
#include <migraphx/generate.hpp>
Shucai Xiao's avatar
Shucai Xiao committed
35
#include <migraphx/quantization.hpp>
36
#include <migraphx/load_save.hpp>
37
#include <migraphx/make_op.hpp>
38
#include <migraphx/register_op.hpp>
39
40
41
#include <migraphx/json.hpp>
#include <migraphx/convert_to_json.hpp>
#include <algorithm>
42
#include <cstdarg>
Paul Fultz II's avatar
Paul Fultz II committed
43

44
45
static thread_local bool disable_exception_catch = false; // NOLINT

46
extern "C" MIGRAPHX_C_EXPORT void migraphx_test_private_disable_exception_catch(bool b)
47
48
49
50
{
    disable_exception_catch = b;
}

51
52
namespace migraphx {

Paul Fultz II's avatar
Paul Fultz II committed
53
54
55
template <class F>
migraphx_status try_(F f, bool output = true) // NOLINT
{
56
    if(disable_exception_catch)
Paul Fultz II's avatar
Paul Fultz II committed
57
58
59
    {
        f();
    }
60
    else
Paul Fultz II's avatar
Paul Fultz II committed
61
    {
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
        try
        {
            f();
        }
        catch(const migraphx::exception& ex)
        {
            if(output)
                std::cerr << "MIGraphX Error: " << ex.what() << std::endl;
            if(ex.error > 0)
                return migraphx_status(ex.error);
            else
                return migraphx_status_unknown_error;
        }
        catch(const std::exception& ex)
        {
            if(output)
                std::cerr << "MIGraphX Error: " << ex.what() << std::endl;
Paul Fultz II's avatar
Paul Fultz II committed
79
            return migraphx_status_unknown_error;
80
81
82
83
84
        }
        catch(...)
        {
            return migraphx_status_unknown_error;
        }
Paul Fultz II's avatar
Paul Fultz II committed
85
86
87
88
89
90
91
92
    }
    return migraphx_status_success;
}

shape::type_t to_shape_type(migraphx_shape_datatype_t t)
{
    switch(t)
    {
Paul Fultz II's avatar
Paul Fultz II committed
93
    case migraphx_shape_tuple_type: return shape::tuple_type;
Paul Fultz II's avatar
Paul Fultz II committed
94
95
96
97
98
99
100
101
102
103
104
105
#define MIGRAPHX_DETAIL_SHAPE_CASE_CONVERT(x, y) \
    case migraphx_shape_##x: return shape::x;
        MIGRAPHX_SHAPE_VISIT_TYPES(MIGRAPHX_DETAIL_SHAPE_CASE_CONVERT)
#undef MIGRAPHX_DETAIL_SHAPE_CASE_CONVERT
    }
    MIGRAPHX_THROW(migraphx_status_bad_param, "Unknown type");
}

migraphx_shape_datatype_t to_shape_type(shape::type_t t)
{
    switch(t)
    {
Paul Fultz II's avatar
Paul Fultz II committed
106
    case shape::tuple_type: return migraphx_shape_tuple_type;
Paul Fultz II's avatar
Paul Fultz II committed
107
108
109
110
111
112
113
114
#define MIGRAPHX_DETAIL_SHAPE_CASE_CONVERT(x, y) \
    case shape::x: return migraphx_shape_##x;
        MIGRAPHX_SHAPE_VISIT_TYPES(MIGRAPHX_DETAIL_SHAPE_CASE_CONVERT)
#undef MIGRAPHX_DETAIL_SHAPE_CASE_CONVERT
    }
    MIGRAPHX_THROW(migraphx_status_bad_param, "Unknown type");
}

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
template <class T>
auto to_obj_vector(const T* x, std::size_t n)
{
    std::vector<decltype((*x)->object)> result;
    std::transform(x, x + n, std::back_inserter(result), [&](auto&& y) { return y->object; });
    return result;
}

template <class T, class U>
auto to_objptr_vector(const U* x, std::size_t n)
{
    std::vector<T> result;
    std::transform(
        x, x + n, std::back_inserter(result), [&](auto&& y) { return std::addressof(y->object); });
    return result;
}

132
target get_target(const std::string& name) { return make_target(name); }
Paul Fultz II's avatar
Paul Fultz II committed
133

134
135
136
void set_offload_copy(compile_options& options, bool value) { options.offload_copy = value; }

void set_fast_math(compile_options& options, bool value) { options.fast_math = value; }
Paul Fultz II's avatar
Paul Fultz II committed
137

138
139
140
141
142
void set_exhaustive_tune_flag(compile_options& options, bool value)
{
    options.exhaustive_tune = value;
}

143
void set_file_format(file_options& options, const char* format) { options.format = format; }
144

145
void set_default_dim_value(onnx_options& options, size_t value)
Paul Fultz II's avatar
Paul Fultz II committed
146
{
147
148
149
    options.default_dim_value = value;
}

150
151
152
153
154
void set_default_dyn_dim_value(onnx_options& options, const shape::dynamic_dimension& dd)
{
    options.default_dyn_dim_value = dd;
}

Shucai Xiao's avatar
Shucai Xiao committed
155
156
157
158
159
void set_default_loop_iterations(onnx_options& options, int64_t value)
{
    options.max_loop_iterations = value;
}

kahmed10's avatar
kahmed10 committed
160
161
162
163
void set_nhwc(tf_options& options, bool is_nhwc) { options.is_nhwc = is_nhwc; }

void set_default_dim_value(tf_options& options, size_t value) { options.batch_size = value; }

164
165
void set_input_parameter_shape(onnx_options& options,
                               const char* name,
166
                               std::vector<std::size_t> dims)
167
{
168
    options.map_input_dims[std::string(name)] = std::move(dims);
Paul Fultz II's avatar
Paul Fultz II committed
169
170
}

171
172
173
174
175
176
177
void set_dyn_input_parameter_shape(onnx_options& options,
                                   const char* name,
                                   std::vector<shape::dynamic_dimension> dyn_dims)
{
    options.map_dyn_input_dims[std::string(name)] = std::move(dyn_dims);
}

kahmed10's avatar
kahmed10 committed
178
179
180
181
182
183
184
185
186
187
void set_input_parameter_shape(tf_options& options, const char* name, std::vector<std::size_t> dims)
{
    options.map_input_dims[std::string(name)] = std::move(dims);
}

void set_output_names(tf_options& options, std::vector<const char*> names)
{
    options.output_node_names = std::vector<std::string>(names.begin(), names.end());
}

188
189
190
191
192
193
194
std::vector<argument>
run_async(program& p, const parameter_map& params, void* s, std::string_view name)
{
    execution_environment exec_env{any_ptr(s, name), true};
    return p.eval(params, exec_env);
}

Paul Fultz II's avatar
Paul Fultz II committed
195
196
197
198
199
200
201
202
203
template <class Value>
std::vector<const char*> get_names(const std::unordered_map<std::string, Value>& m)
{
    std::vector<const char*> result;
    std::transform(
        m.begin(), m.end(), std::back_inserter(result), [](auto&& p) { return p.first.c_str(); });
    return result;
}

204
205
206
207
208
209
template <class T>
std::set<T> make_set(const T* x, std::size_t n)
{
    return {x, x + n};
}

Shucai Xiao's avatar
Shucai Xiao committed
210
211
212
213
214
215
216
217
218
219
220
221
void quantize_fp16_with_op_names(program& prog, std::vector<std::string>& names)
{
    if(names.empty())
    {
        names = {"all"};
    }

    migraphx::quantize_fp16(prog, names);
}

struct quantize_int8_options
{
222
223
    std::vector<parameter_map> calibration = {};
    std::vector<std::string> op_names      = {};
Shucai Xiao's avatar
Shucai Xiao committed
224
225
226
227
228
229
230
};

void add_op_name(quantize_int8_options& options, const char* name)
{
    options.op_names.push_back(name);
}

231
void add_calibration_data(quantize_int8_options& options, parameter_map& data)
Shucai Xiao's avatar
Shucai Xiao committed
232
233
234
235
236
237
238
239
240
241
242
243
244
245
{
    options.calibration.push_back(data);
}

void quantize_int8_wrap(program& prog, const target& t, quantize_int8_options& options)
{
    if(options.op_names.empty())
    {
        options.op_names = {"dot", "convolution"};
    }

    migraphx::quantize_int8(prog, t, options.calibration, options.op_names);
}

246
247
248
249
250
251
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-nonliteral"
#endif

operation create_op(const char* name, const char* attributes, va_list vlist)
252
{
253
254
255
    std::string sattributes = attributes == nullptr ? "" : attributes;
    std::vector<char> buffer(sattributes.size() * 2);
    std::vsnprintf(buffer.data(), buffer.size(), sattributes.c_str(), vlist);
256
257
258
    value v = value::object{};
    if(attributes != nullptr)
    {
259
        v = from_json_string(convert_to_json(std::string(buffer.data())));
260
261
262
263
264
265
    }
    auto op = make_op(name, v);

    return op;
}

266
267
268
269
#ifdef __clang__
#pragma clang diagnostic pop
#endif

Paul Fultz II's avatar
Paul Fultz II committed
270
271
272
273
274
275
template <class T>
bool equal(const T& x, const T& y)
{
    return x == y;
}

276
std::vector<argument> run(program& p, const parameter_map& params) { return p.eval(params); }
Paul Fultz II's avatar
Paul Fultz II committed
277

278
std::vector<shape> get_output_shapes(program& p) { return p.get_output_shapes(); }
Paul Fultz II's avatar
Paul Fultz II committed
279

Shucai Xiao's avatar
Shucai Xiao committed
280
281
282
void print_program(const program& p) { std::cout << p << std::endl; }

void print_module(const module& m) { std::cout << m << std::endl; }
Paul Fultz II's avatar
Paul Fultz II committed
283

284
285
286
287
288
migraphx::instruction_ref add_allocation(module& m, const migraphx::shape& s)
{
    return m.add_instruction(migraphx::make_op("allocate", {{"shape", migraphx::to_value(s)}}), {});
}

289
290
291
292
293
294
295
296
297
298
299
struct experimental_custom_op
{
    std::string name;
    experimental_custom_op() = default;

    experimental_custom_op(std::string pname) : name(std::move(pname)) {}
};

template <class CustomOp>
struct custom_operation
{
300

301
302
303
304
305
    template <class Self, class F>
    static auto reflect(Self&, F)
    {
        return pack();
    }
306
307
308
309
310
311

    value attributes() const
    {
        return {{"custom_op", true}, {"target", op.runs_on_offload_target() ? "gpu" : "cpu"}};
    }

312
313
314
315
316
317
318
319
    CustomOp op;
    std::string name() const { return op.xobject.name; }

    shape compute_shape(std::vector<shape> inputs) const
    {
        return op.compute_shape(std::move(inputs));
    }

320
321
322
323
324
325
    // TODO: Compute method with module_args
    argument
    compute(migraphx::context ctx, migraphx::shape output_shape, std::vector<argument> inputs) const
    {
        return op.compute(std::move(ctx), std::move(output_shape), std::move(inputs));
    }
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342

    std::ptrdiff_t output_alias(std::vector<shape> inputs) const
    {
        auto alias_vec = op.output_alias(std::move(inputs));
        // TODO: For now, only support one output alias
        if(alias_vec.empty())
        {
            return -1;
        }
        if(alias_vec.size() > 1)
        {
            MIGRAPHX_THROW("Currently, CustomOps in MIGraphX only supports one output_alias");
        }
        return alias_vec.front();
    }

    bool runs_on_offload_target() const { return op.runs_on_offload_target(); }
343
344
345
346
347
348
349
350
};

template <class CustomOp>
void register_custom_op(const CustomOp& op)
{
    register_op(custom_operation<CustomOp>{op});
}

kahmed10's avatar
kahmed10 committed
351
352
migraphx::context get_context(const program& p) { return p.get_context(); }

Paul Fultz II's avatar
Paul Fultz II committed
353
354
355
} // namespace migraphx

<% generate_c_api_body() %>