Commit d49d4f66 authored by Paul's avatar Paul
Browse files

Merge branch 'develop' into mlir-c

parents 7d248d46 4d82d761
#include <migraphx/program.hpp>
#include <migraphx/ref/target.hpp>
#include <migraphx/ranges.hpp>
#include <migraphx/make_op.hpp>
#include <migraphx/marker.hpp>
#include <migraphx/instruction.hpp>
#include "test.hpp"
struct mock_marker
{
std::shared_ptr<std::stringstream> ss = std::make_shared<std::stringstream>();
void mark_start(migraphx::instruction_ref ins_ref)
{
std::string text = "Mock marker instruction start:" + ins_ref->name();
(*ss) << text;
}
void mark_stop(migraphx::instruction_ref)
{
std::string text = "Mock marker instruction stop.";
(*ss) << text;
}
void mark_start(const migraphx::program&)
{
std::string text = "Mock marker program start.";
(*ss) << text;
}
void mark_stop(const migraphx::program&)
{
std::string text = "Mock marker program stop.";
(*ss) << text;
}
};
TEST_CASE(marker)
{
migraphx::program p;
auto* mm = p.get_main_module();
auto one = mm->add_literal(1);
auto two = mm->add_literal(2);
mm->add_instruction(migraphx::make_op("add"), one, two);
p.compile(migraphx::ref::target{});
mock_marker temp_marker;
p.mark({}, temp_marker);
std::string output = temp_marker.ss->str();
EXPECT(migraphx::contains(output, "Mock marker instruction start:@literal"));
EXPECT(migraphx::contains(output, "Mock marker instruction start:ref::op"));
EXPECT(migraphx::contains(output, "Mock marker instruction stop."));
EXPECT(migraphx::contains(output, "Mock marker program start."));
EXPECT(migraphx::contains(output, "Mock marker program stop."));
}
int main(int argc, const char* argv[]) { test::run(argc, argv); }
...@@ -1061,6 +1061,62 @@ def depthtospace_crd_test(): ...@@ -1061,6 +1061,62 @@ def depthtospace_crd_test():
return ([node], [x], [y]) return ([node], [x], [y])
@onnx_test
def spacetodepth_test():
x = helper.make_tensor_value_info('x', TensorProto.float, [2, 2, 10, 10])
y = helper.make_tensor_value_info('y', TensorProto.float, [2, 8, 5, 5])
node = onnx.helper.make_node('spacetodepth',
inputs=['x'],
outputs=['y'],
blocksize=2)
return ([node], [x], [y])
@onnx_test
def spacetodepth_simple_test():
x = helper.make_tensor_value_info('x', TensorProto.FLOAT, [1, 2, 4, 6])
y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 8, 2, 3])
node = onnx.helper.make_node('SpaceToDepth',
inputs=['x'],
outputs=['y'],
blocksize=2)
return ([node], [x], [y])
@onnx_test
def spacetodepth_invalid_blocksize_test():
x = helper.make_tensor_value_info('x', TensorProto.FLOAT, [1, 2, 4, 6])
y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 8, 2, 3])
node = onnx.helper.make_node('SpaceToDepth',
inputs=['x'],
outputs=['y'],
blocksize=0.3)
return ([node], [x], [y])
@onnx_test
def spacetodepth_nondivisibility_test():
x = helper.make_tensor_value_info('x', TensorProto.FLOAT, [1, 2, 5, 5])
y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1, 8, 2, 2])
node = onnx.helper.make_node('SpaceToDepth',
inputs=['x'],
outputs=['y'],
blocksize=2)
return ([node], [x], [y])
@onnx_test @onnx_test
def dequantizelinear_test(): def dequantizelinear_test():
arg0 = helper.make_tensor_value_info('0', TensorProto.INT8, [5]) arg0 = helper.make_tensor_value_info('0', TensorProto.INT8, [5])
......
...@@ -965,6 +965,46 @@ TEST_CASE(depthtospace_simple_test) ...@@ -965,6 +965,46 @@ TEST_CASE(depthtospace_simple_test)
EXPECT(p == prog); EXPECT(p == prog);
} }
TEST_CASE(spacetodepth_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
auto l0 = mm->add_parameter("x", {migraphx::shape::float_type, {2, 2, 10, 10}});
auto tmp1 =
mm->add_instruction(migraphx::make_op("reshape", {{"dims", {2, 2, 5, 2, 5, 2}}}), l0);
auto tmp2 = mm->add_instruction(
migraphx::make_op("transpose", {{"permutation", {0, 3, 5, 1, 2, 4}}}), tmp1);
auto tmp3 = mm->add_instruction(migraphx::make_op("contiguous"), tmp2);
mm->add_instruction(migraphx::make_op("reshape", {{"dims", {2, 8, 5, 5}}}), tmp3);
auto prog = optimize_onnx("spacetodepth_test.onnx");
EXPECT(p == prog);
}
TEST_CASE(spacetodepth_simple_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
auto l0 = mm->add_parameter("x", {migraphx::shape::float_type, {1, 2, 4, 6}});
auto tmp1 =
mm->add_instruction(migraphx::make_op("reshape", {{"dims", {1, 2, 2, 2, 3, 2}}}), l0);
auto tmp2 = mm->add_instruction(
migraphx::make_op("transpose", {{"permutation", {0, 3, 5, 1, 2, 4}}}), tmp1);
auto tmp3 = mm->add_instruction(migraphx::make_op("contiguous"), tmp2);
mm->add_instruction(migraphx::make_op("reshape", {{"dims", {1, 8, 2, 3}}}), tmp3);
auto prog = optimize_onnx("spacetodepth_simple_test.onnx");
EXPECT(p == prog);
}
TEST_CASE(spacetodepth_invalid_blocksize)
{
EXPECT(test::throws([&] { migraphx::parse_onnx("spacetodepth_invalid_blocksize_test.onnx"); }));
}
TEST_CASE(spacetodepth_nondivisibility_test)
{
EXPECT(test::throws([&] { migraphx::parse_onnx("spacetodepth_nondivisibility_test.onnx"); }));
}
TEST_CASE(dequantizelinear_test) TEST_CASE(dequantizelinear_test)
{ {
migraphx::program p; migraphx::program p;
......
#spacetodepth_invalid_blocksize_test:
)
xy" SpaceToDepth*
blocksize>#spacetodepth_invalid_blocksize_testZ
x




b
y




B
\ No newline at end of file
!spacetodepth_nondivisibility_test:
&
xy" SpaceToDepth*
blocksize!spacetodepth_nondivisibility_testZ
x




b
y




B
\ No newline at end of file
spacetodepth_simple_test:|
&
xy" SpaceToDepth*
blocksizespacetodepth_simple_testZ
x




b
y




B
\ No newline at end of file
spacetodepth_test:u
&
xy" SpaceToDepth*
blocksizespacetodepth_testZ
x





b
y




B
\ No newline at end of file
...@@ -63,6 +63,46 @@ TEST_CASE(depthtospace_simple_test) ...@@ -63,6 +63,46 @@ TEST_CASE(depthtospace_simple_test)
EXPECT(migraphx::verify_range(result_vector, gold)); EXPECT(migraphx::verify_range(result_vector, gold));
} }
TEST_CASE(spacetodepth_simple_test)
{
auto p = migraphx::parse_onnx("spacetodepth_simple_test.onnx");
p.compile(migraphx::ref::target{});
std::vector<float> data_in(48);
std::iota(std::begin(data_in), std::end(data_in), 0);
migraphx::shape s_x{migraphx::shape::float_type, {1, 2, 4, 6}};
migraphx::parameter_map pp;
pp["x"] = migraphx::argument(s_x, data_in.data());
auto result = p.eval(pp).back();
std::vector<float> result_vector;
result.visit([&](auto output) { result_vector.assign(output.begin(), output.end()); });
std::vector<float> gold = {0, 2, 4, 12, 14, 16, 24, 26, 28, 36, 38, 40, 1, 3, 5, 13,
15, 17, 25, 27, 29, 37, 39, 41, 6, 8, 10, 18, 20, 22, 30, 32,
34, 42, 44, 46, 7, 9, 11, 19, 21, 23, 31, 33, 35, 43, 45, 47};
EXPECT(migraphx::verify_range(result_vector, gold));
}
TEST_CASE(spacetodepth_depthtospace_test)
{
// space to depth
auto p1 = migraphx::parse_onnx("spacetodepth_simple_test.onnx");
p1.compile(migraphx::ref::target{});
std::vector<float> data_in(48);
std::iota(std::begin(data_in), std::end(data_in), 0);
migraphx::shape s_x_1{migraphx::shape::float_type, {1, 2, 4, 6}};
migraphx::parameter_map pp1;
pp1["x"] = migraphx::argument(s_x_1, data_in.data());
auto result1 = p1.eval(pp1).back();
// depth to space
auto p2 = migraphx::parse_onnx("depthtospace_simple_test.onnx");
p2.compile(migraphx::ref::target{});
migraphx::parameter_map pp2;
pp2["x"] = result1;
auto result2 = p2.eval(pp2).back();
std::vector<float> result_vector2;
result2.visit([&](auto output) { result_vector2.assign(output.begin(), output.end()); });
EXPECT(migraphx::verify_range(result_vector2, data_in));
}
TEST_CASE(gather_elements) TEST_CASE(gather_elements)
{ {
migraphx::program p = migraphx::parse_onnx("gather_elements_axis0_test.onnx"); migraphx::program p = migraphx::parse_onnx("gather_elements_axis0_test.onnx");
......
...@@ -2865,6 +2865,26 @@ TEST_CASE(pad_test_lowest_half) ...@@ -2865,6 +2865,26 @@ TEST_CASE(pad_test_lowest_half)
EXPECT(migraphx::verify_range(results_vector, gold)); EXPECT(migraphx::verify_range(results_vector, gold));
} }
TEST_CASE(pointwise_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
migraphx::shape s{migraphx::shape::float_type, {3}};
auto l1 = mm->add_literal(migraphx::literal{s, {-1, 0, 1}});
auto l2 = mm->add_literal(migraphx::literal{s, {1, 2, 3}});
auto* pm = p.create_module("pointwise");
auto x1 = pm->add_parameter("x1", {migraphx::shape::float_type});
auto x2 = pm->add_parameter("x2", {migraphx::shape::float_type});
pm->add_instruction(migraphx::make_op("add"), x1, x2);
mm->add_instruction(migraphx::make_op("pointwise"), {l1, l2}, {pm});
p.compile(migraphx::ref::target{});
auto result = p.eval({}).back();
std::vector<float> results_vector(3);
result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); });
std::vector<float> gold = {0, 2, 4};
EXPECT(migraphx::verify_range(results_vector, gold));
}
TEST_CASE(pow_test) TEST_CASE(pow_test)
{ {
migraphx::program p; migraphx::program p;
......
...@@ -35,6 +35,9 @@ class Type: ...@@ -35,6 +35,9 @@ class Type:
def is_const(self): def is_const(self):
return self.name.startswith('const ') return self.name.startswith('const ')
def is_variadic(self):
return self.name.startswith('...')
def add_pointer(self): def add_pointer(self):
return Type(self.name + '*') return Type(self.name + '*')
...@@ -101,9 +104,10 @@ ${error_type} ${name}(${params}); ...@@ -101,9 +104,10 @@ ${error_type} ${name}(${params});
c_api_impl = Template(''' c_api_impl = Template('''
extern "C" ${error_type} ${name}(${params}) extern "C" ${error_type} ${name}(${params})
{ {
return ${try_wrap}([&] { ${va_start}auto api_error_result = ${try_wrap}([&] {
${body}; ${body};
}); });
${va_end}return api_error_result;
} }
''') ''')
...@@ -113,6 +117,8 @@ class CFunction: ...@@ -113,6 +117,8 @@ class CFunction:
self.name = name self.name = name
self.params = [] self.params = []
self.body = [] self.body = []
self.va_start = []
self.va_end = []
def add_param(self, type, pname): def add_param(self, type, pname):
self.params.append('{} {}'.format(type, pname)) self.params.append('{} {}'.format(type, pname))
...@@ -120,12 +126,23 @@ class CFunction: ...@@ -120,12 +126,23 @@ class CFunction:
def add_statement(self, stmt): def add_statement(self, stmt):
self.body.append(stmt) self.body.append(stmt)
def add_vlist(self, name):
last_param = self.params[-1].split()[-1]
self.va_start = [
'va_list {};'.format(name),
'va_start({}, {});'.format(name, last_param)
]
self.va_end = ['va_end({});'.format(name)]
self.add_param('...', '')
def substitute(self, form): def substitute(self, form):
return form.substitute(error_type=error_type, return form.substitute(error_type=error_type,
try_wrap=try_wrap, try_wrap=try_wrap,
name=self.name, name=self.name,
params=', '.join(self.params), params=', '.join(self.params),
body=";\n ".join(self.body)) body=";\n ".join(self.body),
va_start="\n ".join(self.va_start),
va_end="\n ".join(self.va_end))
def generate_header(self): def generate_header(self):
return self.substitute(header_function) return self.substitute(header_function)
...@@ -256,6 +273,9 @@ class Parameter: ...@@ -256,6 +273,9 @@ class Parameter:
def add_to_cfunction(self, cfunction): def add_to_cfunction(self, cfunction):
for t, name in self.cparams: for t, name in self.cparams:
if t.startswith('...'):
cfunction.add_vlist(name)
else:
cfunction.add_param(self.substitute(t), self.substitute(name)) cfunction.add_param(self.substitute(t), self.substitute(name))
if self.bad_param_check: if self.bad_param_check:
msg = 'Bad parameter {name}: {msg}'.format( msg = 'Bad parameter {name}: {msg}'.format(
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <migraphx/json.hpp> #include <migraphx/json.hpp>
#include <migraphx/convert_to_json.hpp> #include <migraphx/convert_to_json.hpp>
#include <algorithm> #include <algorithm>
#include <cstdarg>
namespace migraphx { namespace migraphx {
...@@ -155,18 +156,30 @@ void quantize_int8_wrap(program& prog, const target& t, quantize_int8_options& o ...@@ -155,18 +156,30 @@ void quantize_int8_wrap(program& prog, const target& t, quantize_int8_options& o
migraphx::quantize_int8(prog, t, options.calibration, options.op_names); migraphx::quantize_int8(prog, t, options.calibration, options.op_names);
} }
operation create_op(const char* name, const char* attributes) #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)
{ {
std::string sattributes = attributes == nullptr ? "" : attributes;
std::vector<char> buffer(sattributes.size() * 2);
std::vsnprintf(buffer.data(), buffer.size(), sattributes.c_str(), vlist);
value v = value::object{}; value v = value::object{};
if(attributes != nullptr) if(attributes != nullptr)
{ {
v = from_json_string(convert_to_json(std::string(attributes))); v = from_json_string(convert_to_json(std::string(buffer.data())));
} }
auto op = make_op(name, v); auto op = make_op(name, v);
return op; return op;
} }
#ifdef __clang__
#pragma clang diagnostic pop
#endif
template <class T> template <class T>
bool equal(const T& x, const T& y) bool equal(const T& x, const T& y)
{ {
......
#ifndef MIGRAPHX_GUARD_MARKER_HPP
#define MIGRAPHX_GUARD_MARKER_HPP
#include <cassert>
#include <string>
#include <functional>
#include <memory>
#include <type_traits>
#include <utility>
#include <migraphx/config.hpp>
#include <migraphx/instruction_ref.hpp>
#include <migraphx/program.hpp>
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
#ifdef DOXYGEN
/// Marker is an interface to general marking functions, such as rocTX markers.
#else
<%
interface('marker',
virtual('mark_start', ins_ref = 'instruction_ref', returns = 'void'),
virtual('mark_start', prog = 'const program&', returns = 'void'),
virtual('mark_stop', ins = 'instruction_ref', returns = 'void'),
virtual('mark_stop', prog = 'const program&', returns = 'void')
) %>
#endif
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment