Unverified Commit d655ef50 authored by Paul Fultz II's avatar Paul Fultz II Committed by GitHub
Browse files

Merge branch 'develop' into scatter-op

parents 2cb895a5 eacf042e
dequantizelinear_test: dequantizelinear_test:k

0 0
1 1out"DequantizeLineardequantizelinear_testZ
2out"DequantizeLineardequantizelinear_testZ
0 0
 
...@@ -10,12 +9,8 @@ ...@@ -10,12 +9,8 @@
1 1
 
Z
2

b b
out out
 
B B
\ No newline at end of file \ No newline at end of file
 dequantizelinear_zero_point_test:
0
1
2out"DequantizeLinear dequantizelinear_zero_point_testZ
0

Z
1

Z
2

b
out

B
\ No newline at end of file
...@@ -1021,6 +1021,21 @@ def deconv_stride_test(): ...@@ -1021,6 +1021,21 @@ def deconv_stride_test():
@onnx_test @onnx_test
def dequantizelinear_test(): def dequantizelinear_test():
arg0 = helper.make_tensor_value_info('0', TensorProto.INT8, [5])
arg1 = helper.make_tensor_value_info('1', TensorProto.FLOAT, [1])
arg_out = helper.make_tensor_value_info('out', TensorProto.FLOAT, [5])
node = onnx.helper.make_node(
'DequantizeLinear',
inputs=['0', '1'],
outputs=['out'],
)
return ([node], [arg0, arg1], [arg_out])
@onnx_test
def dequantizelinear_zero_point_test():
arg0 = helper.make_tensor_value_info('0', TensorProto.INT8, [5]) arg0 = helper.make_tensor_value_info('0', TensorProto.INT8, [5])
arg1 = helper.make_tensor_value_info('1', TensorProto.FLOAT, [1]) arg1 = helper.make_tensor_value_info('1', TensorProto.FLOAT, [1])
arg2 = helper.make_tensor_value_info('2', TensorProto.INT8, [1]) arg2 = helper.make_tensor_value_info('2', TensorProto.INT8, [1])
...@@ -2751,6 +2766,36 @@ def prelu_brcst_test(): ...@@ -2751,6 +2766,36 @@ def prelu_brcst_test():
@onnx_test @onnx_test
def quantizelinear_test(): def quantizelinear_test():
arg0 = helper.make_tensor_value_info('0', TensorProto.FLOAT, [5])
arg1 = helper.make_tensor_value_info('1', TensorProto.FLOAT, [1])
arg_out = helper.make_tensor_value_info('out', TensorProto.INT8, [5])
node = onnx.helper.make_node(
'QuantizeLinear',
inputs=['0', '1'],
outputs=['out'],
)
return ([node], [arg0, arg1], [arg_out])
@onnx_test
def quantizelinear_int32_test():
arg0 = helper.make_tensor_value_info('0', TensorProto.INT32, [5])
arg1 = helper.make_tensor_value_info('1', TensorProto.FLOAT, [1])
arg_out = helper.make_tensor_value_info('out', TensorProto.INT8, [5])
node = onnx.helper.make_node(
'QuantizeLinear',
inputs=['0', '1'],
outputs=['out'],
)
return ([node], [arg0, arg1], [arg_out])
@onnx_test
def quantizelinear_zero_point_test():
arg0 = helper.make_tensor_value_info('0', TensorProto.FLOAT, [5]) arg0 = helper.make_tensor_value_info('0', TensorProto.FLOAT, [5])
arg1 = helper.make_tensor_value_info('1', TensorProto.FLOAT, [1]) arg1 = helper.make_tensor_value_info('1', TensorProto.FLOAT, [1])
arg2 = helper.make_tensor_value_info('2', TensorProto.INT8, [1]) arg2 = helper.make_tensor_value_info('2', TensorProto.INT8, [1])
......
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <vector> #include <vector>
#include <migraphx/common.hpp>
#include <migraphx/literal.hpp> #include <migraphx/literal.hpp>
#include <migraphx/operators.hpp>
#include <migraphx/program.hpp> #include <migraphx/program.hpp>
#include <migraphx/instruction.hpp> #include <migraphx/instruction.hpp>
#include <migraphx/instruction_ref.hpp> #include <migraphx/instruction_ref.hpp>
#include <migraphx/pass_manager.hpp> #include <migraphx/pass_manager.hpp>
#include <migraphx/dead_code_elimination.hpp> #include <migraphx/dead_code_elimination.hpp>
#include <migraphx/rewrite_quantization.hpp>
#include <migraphx/eliminate_identity.hpp> #include <migraphx/eliminate_identity.hpp>
#include <migraphx/onnx.hpp> #include <migraphx/onnx.hpp>
#include <migraphx/make_op.hpp> #include <migraphx/make_op.hpp>
#include <migraphx/op/convolution.hpp>
#include <migraphx/op/pad.hpp>
#include <migraphx/op/pooling.hpp>
#include <migraphx/op/lrn.hpp>
#include <migraphx/op/reshape.hpp>
#include <migraphx/op/unknown.hpp>
#include <migraphx/serialize.hpp> #include <migraphx/serialize.hpp>
#include "test.hpp" #include "test.hpp"
migraphx::program optimize_onnx(const std::string& name, bool eliminate_deadcode = false) migraphx::program optimize_onnx(const std::string& name, bool run_passes = false)
{ {
migraphx::onnx_options options; migraphx::onnx_options options;
options.skip_unknown_operators = true; options.skip_unknown_operators = true;
auto prog = migraphx::parse_onnx(name, options); auto prog = migraphx::parse_onnx(name, options);
auto* mm = prog.get_main_module(); auto* mm = prog.get_main_module();
if(eliminate_deadcode) if(run_passes)
migraphx::run_passes(*mm, {migraphx::dead_code_elimination{}}); migraphx::run_passes(*mm,
{migraphx::rewrite_quantization{}, migraphx::dead_code_elimination{}});
// remove the last identity instruction // remove the last identity instruction
auto last_ins = std::prev(mm->end()); auto last_ins = std::prev(mm->end());
...@@ -914,29 +922,42 @@ TEST_CASE(dequantizelinear_test) ...@@ -914,29 +922,42 @@ TEST_CASE(dequantizelinear_test)
auto* mm = p.get_main_module(); auto* mm = p.get_main_module();
auto l0 = mm->add_parameter("0", {migraphx::shape::int8_type, {5}}); auto l0 = mm->add_parameter("0", {migraphx::shape::int8_type, {5}});
auto l1 = mm->add_parameter("1", {migraphx::shape::float_type, {1}}); auto l1 = mm->add_parameter("1", {migraphx::shape::float_type, {1}});
auto l2 = mm->add_parameter("2", {migraphx::shape::int8_type, {1}});
auto l1_mbcast = auto l1_mbcast =
mm->add_instruction(migraphx::make_op("multibroadcast", {{"output_lens", {5}}}), l1); mm->add_instruction(migraphx::make_op("multibroadcast", {{"output_lens", {5}}}), l1);
l2 = mm->add_instruction( auto dequant = mm->add_instruction(
migraphx::make_op("convert", migraphx::make_op("convert",
{{"target_type", migraphx::to_value(migraphx::shape::int32_type)}}), {{"target_type", migraphx::to_value(migraphx::shape::float_type)}}),
l2); l0);
mm->add_instruction(migraphx::make_op("mul"), dequant, l1_mbcast);
auto prog = optimize_onnx("dequantizelinear_test.onnx", true);
EXPECT(p.sort() == prog.sort());
}
TEST_CASE(dequantizelinear_zero_point_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
auto l0 = mm->add_parameter("0", {migraphx::shape::int8_type, {5}});
auto l1 = mm->add_parameter("1", {migraphx::shape::float_type, {1}});
auto l2 = mm->add_parameter("2", {migraphx::shape::int8_type, {1}});
auto l1_mbcast =
mm->add_instruction(migraphx::make_op("multibroadcast", {{"output_lens", {5}}}), l1);
auto l2_mbcast = auto l2_mbcast =
mm->add_instruction(migraphx::make_op("multibroadcast", {{"output_lens", {5}}}), l2); mm->add_instruction(migraphx::make_op("multibroadcast", {{"output_lens", {5}}}), l2);
l0 = mm->add_instruction( l2_mbcast = mm->add_instruction(
migraphx::make_op("convert", migraphx::make_op("convert",
{{"target_type", migraphx::to_value(migraphx::shape::int32_type)}}), {{"target_type", migraphx::to_value(migraphx::shape::float_type)}}),
l0); l2_mbcast);
l0 = mm->add_instruction(
auto sub = mm->add_instruction(migraphx::make_op("sub"), l0, l2_mbcast);
auto dequant = mm->add_instruction(
migraphx::make_op("convert", migraphx::make_op("convert",
{{"target_type", migraphx::to_value(migraphx::shape::float_type)}}), {{"target_type", migraphx::to_value(migraphx::shape::float_type)}}),
sub); l0);
mm->add_instruction(migraphx::make_op("mul"), dequant, l1_mbcast); auto sub = mm->add_instruction(migraphx::make_op("sub"), l0, l2_mbcast);
mm->add_instruction(migraphx::make_op("mul"), sub, l1_mbcast);
auto prog = optimize_onnx("dequantizelinear_test.onnx"); auto prog = optimize_onnx("dequantizelinear_zero_point_test.onnx", true);
EXPECT(p.sort() == prog.sort()); EXPECT(p.sort() == prog.sort());
} }
...@@ -955,19 +976,15 @@ migraphx::program make_dequantizelinear_axis_prog() ...@@ -955,19 +976,15 @@ migraphx::program make_dequantizelinear_axis_prog()
migraphx::make_op("broadcast", {{"axis", axis}, {"dims", input_lens}}), l2); migraphx::make_op("broadcast", {{"axis", axis}, {"dims", input_lens}}), l2);
l2_bcast = mm->add_instruction( l2_bcast = mm->add_instruction(
migraphx::make_op("convert", migraphx::make_op("convert",
{{"target_type", migraphx::to_value(migraphx::shape::int32_type)}}), {{"target_type", migraphx::to_value(migraphx::shape::float_type)}}),
l2_bcast); l2_bcast);
l0 = mm->add_instruction( l0 = mm->add_instruction(
migraphx::make_op("convert",
{{"target_type", migraphx::to_value(migraphx::shape::int32_type)}}),
l0);
auto sub = mm->add_instruction(migraphx::make_op("sub"), l0, l2_bcast);
auto dequant = mm->add_instruction(
migraphx::make_op("convert", migraphx::make_op("convert",
{{"target_type", migraphx::to_value(migraphx::shape::float_type)}}), {{"target_type", migraphx::to_value(migraphx::shape::float_type)}}),
sub); l0);
auto sub = mm->add_instruction(migraphx::make_op("sub"), l0, l2_bcast);
mm->add_instruction(migraphx::make_op("mul"), dequant, l1_bcast); mm->add_instruction(migraphx::make_op("mul"), sub, l1_bcast);
return p; return p;
} }
...@@ -975,7 +992,7 @@ TEST_CASE(dequantizelinear_axis_test) ...@@ -975,7 +992,7 @@ TEST_CASE(dequantizelinear_axis_test)
{ {
migraphx::program p = make_dequantizelinear_axis_prog(); migraphx::program p = make_dequantizelinear_axis_prog();
auto prog = optimize_onnx("dequantizelinear_axis_test.onnx"); auto prog = optimize_onnx("dequantizelinear_axis_test.onnx", true);
EXPECT(p.sort() == prog.sort()); EXPECT(p.sort() == prog.sort());
} }
...@@ -983,7 +1000,7 @@ TEST_CASE(dequantizelinear_neg_axis_test) ...@@ -983,7 +1000,7 @@ TEST_CASE(dequantizelinear_neg_axis_test)
{ {
migraphx::program p = make_dequantizelinear_axis_prog(); migraphx::program p = make_dequantizelinear_axis_prog();
auto prog = optimize_onnx("dequantizelinear_neg_axis_test.onnx"); auto prog = optimize_onnx("dequantizelinear_neg_axis_test.onnx", true);
EXPECT(p.sort() == prog.sort()); EXPECT(p.sort() == prog.sort());
} }
...@@ -1252,19 +1269,28 @@ TEST_CASE(gather_elements_axis1_test) ...@@ -1252,19 +1269,28 @@ TEST_CASE(gather_elements_axis1_test)
TEST_CASE(gemm_test) TEST_CASE(gemm_test)
{ {
migraphx::program p; migraphx::program p;
auto* mm = p.get_main_module(); auto* mm = p.get_main_module();
auto l0 = mm->add_parameter("0", migraphx::shape{migraphx::shape::float_type, {5, 7}}); auto l0 = mm->add_parameter("0", migraphx::shape{migraphx::shape::float_type, {5, 7}});
auto l1 = mm->add_parameter("1", migraphx::shape{migraphx::shape::float_type, {11, 5}}); auto l1 = mm->add_parameter("1", migraphx::shape{migraphx::shape::float_type, {11, 5}});
auto l2 = mm->add_parameter("2", migraphx::shape{migraphx::shape::float_type}); auto l2 = mm->add_parameter("2", migraphx::shape{migraphx::shape::float_type});
auto t0 = mm->add_instruction(migraphx::make_op("transpose", {{"dims", {1, 0}}}), l0);
auto t1 = mm->add_instruction(migraphx::make_op("transpose", {{"dims", {1, 0}}}), l1);
auto bl2 =
mm->add_instruction(migraphx::make_op("multibroadcast", {{"output_lens", {7, 11}}}), l2);
auto alpha = 2.f; auto alpha = 2.f;
auto beta = 2.0f; auto beta = 2.0f;
mm->add_instruction(migraphx::make_op("dot", {{"alpha", alpha}, {"beta", beta}}), t0, t1, bl2); auto a_l = mm->add_literal(alpha);
auto t_a = add_common_op(*mm, migraphx::make_op("mul"), {a_l, l0});
t_a = mm->add_instruction(
migraphx::make_op("convert", {{"target_type", l1->get_shape().type()}}), t_a);
t_a = mm->add_instruction(migraphx::make_op("transpose", {{"dims", {1, 0}}}), t_a);
auto t1 = mm->add_instruction(migraphx::make_op("transpose", {{"dims", {1, 0}}}), l1);
auto b_l = mm->add_literal(beta);
auto l2_b =
mm->add_instruction(migraphx::make_op("multibroadcast", {{"output_lens", {7, 11}}}), l2);
auto b_b = mm->add_instruction(
migraphx::make_op("multibroadcast", {{"output_lens", l2_b->get_shape().lens()}}), b_l);
auto l2_bb = mm->add_instruction(migraphx::make_op("mul"), l2_b, b_b);
mm->add_instruction(
migraphx::make_op("dot", {{"alpha", 1.0f}, {"beta", 1.0f}}), t_a, t1, l2_bb);
auto prog = optimize_onnx("gemm_test.onnx"); auto prog = optimize_onnx("gemm_test.onnx");
EXPECT(p == prog); EXPECT(p == prog);
} }
...@@ -1275,10 +1301,21 @@ TEST_CASE(gemm_ex_test) ...@@ -1275,10 +1301,21 @@ TEST_CASE(gemm_ex_test)
auto l0 = mm->add_parameter("1", migraphx::shape{migraphx::shape::float_type, {1, 1, 8, 6}}); auto l0 = mm->add_parameter("1", migraphx::shape{migraphx::shape::float_type, {1, 1, 8, 6}});
auto l1 = mm->add_parameter("2", migraphx::shape{migraphx::shape::float_type, {1, 1, 8, 7}}); auto l1 = mm->add_parameter("2", migraphx::shape{migraphx::shape::float_type, {1, 1, 8, 7}});
auto l2 = mm->add_parameter("3", migraphx::shape{migraphx::shape::float_type, {1, 1, 6, 7}}); auto l2 = mm->add_parameter("3", migraphx::shape{migraphx::shape::float_type, {1, 1, 6, 7}});
auto t0 = mm->add_instruction(migraphx::make_op("transpose", {{"dims", {0, 1, 3, 2}}}), l0);
auto alpha = 0.5f; auto alpha = 0.5f;
auto beta = 0.8f; auto beta = 0.8f;
mm->add_instruction(migraphx::make_op("dot", {{"alpha", alpha}, {"beta", beta}}), t0, l1, l2); auto a_l = mm->add_literal(alpha);
auto t_a = add_common_op(*mm, migraphx::make_op("mul"), {a_l, l0});
t_a = mm->add_instruction(
migraphx::make_op("convert", {{"target_type", l1->get_shape().type()}}), t_a);
t_a = mm->add_instruction(migraphx::make_op("transpose", {{"dims", {0, 1, 3, 2}}}), t_a);
auto b_l = mm->add_literal(beta);
auto b_b = mm->add_instruction(
migraphx::make_op("multibroadcast", {{"output_lens", l2->get_shape().lens()}}), b_l);
auto l2_b = mm->add_instruction(migraphx::make_op("mul"), l2, b_b);
mm->add_instruction(migraphx::make_op("dot", {{"alpha", 1.0f}, {"beta", 1.0f}}), t_a, l1, l2_b);
auto prog = optimize_onnx("gemm_ex_test.onnx"); auto prog = optimize_onnx("gemm_ex_test.onnx");
EXPECT(p == prog); EXPECT(p == prog);
...@@ -1291,13 +1328,25 @@ TEST_CASE(gemm_ex_brcst_test) ...@@ -1291,13 +1328,25 @@ TEST_CASE(gemm_ex_brcst_test)
auto l0 = mm->add_parameter("1", migraphx::shape{migraphx::shape::float_type, {1, 1, 5, 6}}); auto l0 = mm->add_parameter("1", migraphx::shape{migraphx::shape::float_type, {1, 1, 5, 6}});
auto l1 = mm->add_parameter("2", migraphx::shape{migraphx::shape::float_type, {1, 1, 5, 7}}); auto l1 = mm->add_parameter("2", migraphx::shape{migraphx::shape::float_type, {1, 1, 5, 7}});
auto l2 = mm->add_parameter("3", migraphx::shape{migraphx::shape::float_type, {1, 1, 6, 1}}); auto l2 = mm->add_parameter("3", migraphx::shape{migraphx::shape::float_type, {1, 1, 6, 1}});
auto t0 = mm->add_instruction(migraphx::make_op("transpose", {{"dims", {0, 1, 3, 2}}}), l0);
std::vector<std::size_t> out_lens{1, 1, 6, 7}; std::vector<std::size_t> out_lens{1, 1, 6, 7};
auto t2 =
mm->add_instruction(migraphx::make_op("multibroadcast", {{"output_lens", out_lens}}), l2);
auto alpha = 0.5f; auto alpha = 0.5f;
auto beta = 0.8f; auto beta = 0.8f;
mm->add_instruction(migraphx::make_op("dot", {{"alpha", alpha}, {"beta", beta}}), t0, l1, t2); auto a_l = mm->add_literal(alpha);
auto t_a = add_common_op(*mm, migraphx::make_op("mul"), {a_l, l0});
t_a = mm->add_instruction(
migraphx::make_op("convert", {{"target_type", l1->get_shape().type()}}), t_a);
t_a = mm->add_instruction(migraphx::make_op("transpose", {{"dims", {0, 1, 3, 2}}}), t_a);
auto b_l = mm->add_literal(beta);
auto l2_b =
mm->add_instruction(migraphx::make_op("multibroadcast", {{"output_lens", out_lens}}), l2);
auto b_b = mm->add_instruction(
migraphx::make_op("multibroadcast", {{"output_lens", l2_b->get_shape().lens()}}), b_l);
auto l2_bb = mm->add_instruction(migraphx::make_op("mul"), l2_b, b_b);
mm->add_instruction(
migraphx::make_op("dot", {{"alpha", 1.0f}, {"beta", 1.0f}}), t_a, l1, l2_bb);
auto prog = optimize_onnx("gemm_ex_brcst_test.onnx"); auto prog = optimize_onnx("gemm_ex_brcst_test.onnx");
EXPECT(p == prog); EXPECT(p == prog);
...@@ -2378,41 +2427,87 @@ TEST_CASE(prelu_brcst_test) ...@@ -2378,41 +2427,87 @@ TEST_CASE(prelu_brcst_test)
TEST_CASE(quantizelinear_test) TEST_CASE(quantizelinear_test)
{ {
migraphx::program p; migraphx::program p;
auto* mm = p.get_main_module(); auto* mm = p.get_main_module();
auto l0 = mm->add_parameter("0", {migraphx::shape::float_type, {5}}); auto l0 = mm->add_parameter("0", {migraphx::shape::float_type, {5}});
auto l1 = mm->add_parameter("1", {migraphx::shape::float_type, {1}}); auto l1 = mm->add_parameter("1", {migraphx::shape::float_type, {1}});
auto l2 = mm->add_parameter("2", {migraphx::shape::int8_type, {1}});
auto min_val = mm->add_literal(-128);
auto max_val = mm->add_literal(127);
auto l1_mbcast = auto l1_mbcast =
mm->add_instruction(migraphx::make_op("multibroadcast", {{"output_lens", {5}}}), l1); mm->add_instruction(migraphx::make_op("multibroadcast", {{"output_lens", {5}}}), l1);
auto div = mm->add_instruction(migraphx::make_op("div"), l0, l1_mbcast);
auto round = mm->add_instruction(migraphx::make_op("round"), div);
auto s = round->get_shape();
std::vector<int> min_data(s.elements(), 0);
std::vector<int> max_data(s.elements(), 255);
auto min_arg = mm->add_literal(s, min_data);
auto max_arg = mm->add_literal(s, max_data);
auto clip = mm->add_instruction(migraphx::make_op("clip"), round, min_arg, max_arg);
mm->add_instruction(
migraphx::make_op("convert",
{{"target_type", migraphx::to_value(migraphx::shape::uint8_type)}}),
clip);
auto prog = optimize_onnx("quantizelinear_test.onnx", true);
EXPECT(p.sort() == prog.sort());
}
TEST_CASE(quantizelinear_int32_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
auto l0 = mm->add_parameter("0", {migraphx::shape::int32_type, {5}});
auto l1 = mm->add_parameter("1", {migraphx::shape::float_type, {1}});
auto l1_mbcast =
mm->add_instruction(migraphx::make_op("multibroadcast", {{"output_lens", {5}}}), l1);
l0 = mm->add_instruction(
migraphx::make_op("convert",
{{"target_type", migraphx::to_value(migraphx::shape::float_type)}}),
l0);
auto div = mm->add_instruction(migraphx::make_op("div"), l0, l1_mbcast); auto div = mm->add_instruction(migraphx::make_op("div"), l0, l1_mbcast);
auto round = mm->add_instruction(migraphx::make_op("round"), div); auto round = mm->add_instruction(migraphx::make_op("round"), div);
l2 = mm->add_instruction( auto s = round->get_shape();
std::vector<int> min_data(s.elements(), 0);
std::vector<int> max_data(s.elements(), 255);
auto min_arg = mm->add_literal(s, min_data);
auto max_arg = mm->add_literal(s, max_data);
auto clip = mm->add_instruction(migraphx::make_op("clip"), round, min_arg, max_arg);
mm->add_instruction(
migraphx::make_op("convert", migraphx::make_op("convert",
{{"target_type", migraphx::to_value(migraphx::shape::int32_type)}}), {{"target_type", migraphx::to_value(migraphx::shape::uint8_type)}}),
l2); clip);
auto prog = optimize_onnx("quantizelinear_int32_test.onnx", true);
EXPECT(p.sort() == prog.sort());
}
TEST_CASE(quantizelinear_zero_point_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
auto l0 = mm->add_parameter("0", {migraphx::shape::float_type, {5}});
auto l1 = mm->add_parameter("1", {migraphx::shape::float_type, {1}});
auto l2 = mm->add_parameter("2", {migraphx::shape::int8_type, {1}});
auto l1_mbcast =
mm->add_instruction(migraphx::make_op("multibroadcast", {{"output_lens", {5}}}), l1);
auto div = mm->add_instruction(migraphx::make_op("div"), l0, l1_mbcast);
auto round = mm->add_instruction(migraphx::make_op("round"), div);
auto l2_mbcast = auto l2_mbcast =
mm->add_instruction(migraphx::make_op("multibroadcast", {{"output_lens", {5}}}), l2); mm->add_instruction(migraphx::make_op("multibroadcast", {{"output_lens", {5}}}), l2);
l2_mbcast = mm->add_instruction(
round = mm->add_instruction(
migraphx::make_op("convert", migraphx::make_op("convert",
{{"target_type", migraphx::to_value(migraphx::shape::int32_type)}}), {{"target_type", migraphx::to_value(migraphx::shape::float_type)}}),
round); l2_mbcast);
auto add = mm->add_instruction(migraphx::make_op("add"), round, l2_mbcast); auto add = mm->add_instruction(migraphx::make_op("add"), round, l2_mbcast);
min_val = auto s = round->get_shape();
mm->add_instruction(migraphx::make_op("multibroadcast", {{"output_lens", {5}}}), min_val); std::vector<int> min_data(s.elements(), -128);
max_val = std::vector<int> max_data(s.elements(), 127);
mm->add_instruction(migraphx::make_op("multibroadcast", {{"output_lens", {5}}}), max_val); auto min_arg = mm->add_literal(s, min_data);
auto clip = mm->add_instruction(migraphx::make_op("clip"), add, min_val, max_val); auto max_arg = mm->add_literal(s, max_data);
auto clip = mm->add_instruction(migraphx::make_op("clip"), add, min_arg, max_arg);
mm->add_instruction( mm->add_instruction(
migraphx::make_op("convert", migraphx::make_op("convert",
{{"target_type", migraphx::to_value(migraphx::shape::int8_type)}}), {{"target_type", migraphx::to_value(migraphx::shape::int8_type)}}),
clip); clip);
auto prog = optimize_onnx("quantizelinear_test.onnx"); auto prog = optimize_onnx("quantizelinear_zero_point_test.onnx", true);
EXPECT(p.sort() == prog.sort()); EXPECT(p.sort() == prog.sort());
} }
...@@ -2423,12 +2518,9 @@ migraphx::program make_quantizelinear_axis_prog() ...@@ -2423,12 +2518,9 @@ migraphx::program make_quantizelinear_axis_prog()
int axis = 2; int axis = 2;
auto* mm = p.get_main_module(); auto* mm = p.get_main_module();
auto l0 = mm->add_parameter("0", {migraphx::shape::float_type, input_lens}); auto l0 = mm->add_parameter("0", {migraphx::shape::float_type, input_lens});
auto l1 = mm->add_parameter("1", {migraphx::shape::float_type, {5}}); auto l1 = mm->add_parameter("1", {migraphx::shape::float_type, {5}});
auto l2 = mm->add_parameter("2", {migraphx::shape::int8_type, {5}}); auto l2 = mm->add_parameter("2", {migraphx::shape::int8_type, {5}});
auto min_val = mm->add_literal(-128);
auto max_val = mm->add_literal(127);
auto l1_bcast = mm->add_instruction( auto l1_bcast = mm->add_instruction(
migraphx::make_op("broadcast", {{"axis", axis}, {"dims", input_lens}}), l1); migraphx::make_op("broadcast", {{"axis", axis}, {"dims", input_lens}}), l1);
...@@ -2438,18 +2530,15 @@ migraphx::program make_quantizelinear_axis_prog() ...@@ -2438,18 +2530,15 @@ migraphx::program make_quantizelinear_axis_prog()
migraphx::make_op("broadcast", {{"axis", axis}, {"dims", input_lens}}), l2); migraphx::make_op("broadcast", {{"axis", axis}, {"dims", input_lens}}), l2);
l2_bcast = mm->add_instruction( l2_bcast = mm->add_instruction(
migraphx::make_op("convert", migraphx::make_op("convert",
{{"target_type", migraphx::to_value(migraphx::shape::int32_type)}}), {{"target_type", migraphx::to_value(migraphx::shape::float_type)}}),
l2_bcast); l2_bcast);
round = mm->add_instruction(
migraphx::make_op("convert",
{{"target_type", migraphx::to_value(migraphx::shape::int32_type)}}),
round);
auto add = mm->add_instruction(migraphx::make_op("add"), round, l2_bcast); auto add = mm->add_instruction(migraphx::make_op("add"), round, l2_bcast);
min_val = mm->add_instruction( auto s = round->get_shape();
migraphx::make_op("multibroadcast", {{"output_lens", {1, 1, 5, 1}}}), min_val); std::vector<int> min_data(s.elements(), -128);
max_val = mm->add_instruction( std::vector<int> max_data(s.elements(), 127);
migraphx::make_op("multibroadcast", {{"output_lens", {1, 1, 5, 1}}}), max_val); auto min_arg = mm->add_literal(s, min_data);
auto clip = mm->add_instruction(migraphx::make_op("clip"), add, min_val, max_val); auto max_arg = mm->add_literal(s, max_data);
auto clip = mm->add_instruction(migraphx::make_op("clip"), add, min_arg, max_arg);
mm->add_instruction( mm->add_instruction(
migraphx::make_op("convert", migraphx::make_op("convert",
{{"target_type", migraphx::to_value(migraphx::shape::int8_type)}}), {{"target_type", migraphx::to_value(migraphx::shape::int8_type)}}),
...@@ -2461,7 +2550,7 @@ TEST_CASE(quantizelinear_axis_test) ...@@ -2461,7 +2550,7 @@ TEST_CASE(quantizelinear_axis_test)
{ {
migraphx::program p = make_quantizelinear_axis_prog(); migraphx::program p = make_quantizelinear_axis_prog();
auto prog = optimize_onnx("quantizelinear_axis_test.onnx"); auto prog = optimize_onnx("quantizelinear_axis_test.onnx", true);
EXPECT(p.sort() == prog.sort()); EXPECT(p.sort() == prog.sort());
} }
...@@ -2469,7 +2558,7 @@ TEST_CASE(quantizelinear_neg_axis_test) ...@@ -2469,7 +2558,7 @@ TEST_CASE(quantizelinear_neg_axis_test)
{ {
migraphx::program p = make_quantizelinear_axis_prog(); migraphx::program p = make_quantizelinear_axis_prog();
auto prog = optimize_onnx("quantizelinear_neg_axis_test.onnx"); auto prog = optimize_onnx("quantizelinear_neg_axis_test.onnx", true);
EXPECT(p.sort() == prog.sort()); EXPECT(p.sort() == prog.sort());
} }
......
...@@ -23,4 +23,4 @@ ...@@ -23,4 +23,4 @@
 
 
 
B B
\ No newline at end of file \ No newline at end of file
quantizelinear_int32_test:m

0
1out"QuantizeLinearquantizelinear_int32_testZ
0

Z
1

b
out

B
\ No newline at end of file
...@@ -23,4 +23,4 @@ ...@@ -23,4 +23,4 @@
 
 
 
B B
\ No newline at end of file \ No newline at end of file
quantizelinear_test:{ quantizelinear_test:g
 
0 0
1 1out"QuantizeLinearquantizelinear_testZ
2out"QuantizeLinearquantizelinear_testZ
0 0
 
...@@ -10,12 +9,8 @@ ...@@ -10,12 +9,8 @@
1 1
 
Z
2

b b
out out
 
B B
\ No newline at end of file \ No newline at end of file
quantizelinear_zero_point_test:

0
1
2out"QuantizeLinearquantizelinear_zero_point_testZ
0

Z
1

Z
2

b
out

B
\ No newline at end of file
...@@ -1233,6 +1233,58 @@ TEST_CASE(deconv_test) ...@@ -1233,6 +1233,58 @@ TEST_CASE(deconv_test)
EXPECT(migraphx::verify_range(results_vector, gold)); EXPECT(migraphx::verify_range(results_vector, gold));
} }
TEST_CASE(dequantizelinear)
{
{ /*uint8*/
migraphx::shape xs{migraphx::shape::uint8_type, {1, 3, 3}};
std::vector<uint8_t> xv = {0, 1, 2, 5, 10, 50, 100, 150, 250};
migraphx::shape ss{migraphx::shape::float_type, {1, 3, 3}};
std::vector<float> sv = {2, 2, 2, 2, 2, 2, 2, 2, 2};
migraphx::shape zs{migraphx::shape::uint8_type, {1, 3, 3}};
std::vector<uint8_t> zv = {0, 0, 0, 0, 0, 0, 0, 0, 0};
auto create_program = [&]() {
migraphx::program p;
auto* mm = p.get_main_module();
auto x = mm->add_literal(xs, xv);
auto s = mm->add_literal(ss, sv);
auto z = mm->add_literal(zs, zv);
mm->add_instruction(migraphx::make_op("dequantizelinear"), x, s, z);
return p;
};
migraphx::program p1 = create_program();
p1.compile(migraphx::ref::target{});
auto result = p1.eval({}).back();
std::vector<float> results_vector(9);
result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); });
std::vector<float> gold{0, 2, 4, 10, 20, 100, 200, 300, 500};
EXPECT(results_vector == gold);
}
{ /*int8*/
migraphx::shape xs{migraphx::shape::int8_type, {1, 3, 3}};
std::vector<int8_t> xv = {-128, -100, -50, -1, 0, 1, 50, 100, 127};
migraphx::shape ss{migraphx::shape::float_type, {1, 3, 3}};
std::vector<float> sv = {2, 2, 2, 2, 2, 2, 2, 2, 2};
auto create_program = [&]() {
migraphx::program p;
auto* mm = p.get_main_module();
auto x = mm->add_literal(xs, xv);
auto s = mm->add_literal(ss, sv);
mm->add_instruction(migraphx::make_op("dequantizelinear"), x, s);
return p;
};
migraphx::program p1 = create_program();
p1.compile(migraphx::ref::target{});
auto result = p1.eval({}).back();
std::vector<float> results_vector(9);
result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); });
std::vector<float> gold{-256, -200, -100, -2, 0, 2, 100, 200, 254};
EXPECT(results_vector == gold);
}
}
TEST_CASE(div_test) TEST_CASE(div_test)
{ {
migraphx::program p; migraphx::program p;
...@@ -3287,6 +3339,61 @@ TEST_CASE(quant_conv2d_test) ...@@ -3287,6 +3339,61 @@ TEST_CASE(quant_conv2d_test)
EXPECT(migraphx::verify_range(results_vector, s)); EXPECT(migraphx::verify_range(results_vector, s));
} }
TEST_CASE(quantizelinear)
{
{
migraphx::shape xs{migraphx::shape::float_type, {2, 3, 3}};
std::vector<float> xv = {
-300, 600, 129, -1000, 4, 3, -6, 600, 550, -300, 600, 129, -1000, 4, 3, -6, 600, 550};
migraphx::shape ss{migraphx::shape::float_type, {2, 3, 3}};
std::vector<float> sv = {2, 2, 2, 4, 4, 4, 6, 6, 6, 2, 2, 2, 4, 4, 4, 6, 6, 6};
migraphx::shape zs{migraphx::shape::int8_type, {2, 3, 3}};
std::vector<uint8_t> zv = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
auto create_program = [&]() {
migraphx::program p;
auto* mm = p.get_main_module();
auto x = mm->add_literal(xs, xv);
auto s = mm->add_literal(ss, sv);
auto z = mm->add_literal(zs, zv);
mm->add_instruction(migraphx::make_op("quantizelinear"), x, s, z);
return p;
};
migraphx::program p1 = create_program();
p1.compile(migraphx::ref::target{});
auto result = p1.eval({}).back();
std::vector<float> results_vector(18);
result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); });
std::vector<float> gold{
-128, 127, 65, -128, 1, 1, -1, 100, 92, -128, 127, 65, -128, 1, 1, -1, 100, 92};
EXPECT(results_vector == gold);
}
{
migraphx::shape xs{migraphx::shape::float_type, {2, 3, 3}};
std::vector<float> xv = {
-300, 600, 129, -1000, 4, 3, -6, 600, 550, -300, 600, 129, -1000, 4, 3, -6, 600, 550};
migraphx::shape ss{migraphx::shape::float_type, {2, 3, 3}};
std::vector<float> sv = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
auto create_program = [&]() {
migraphx::program p;
auto* mm = p.get_main_module();
auto x = mm->add_literal(xs, xv);
auto s = mm->add_literal(ss, sv);
mm->add_instruction(migraphx::make_op("quantizelinear"), x, s);
return p;
};
migraphx::program p1 = create_program();
p1.compile(migraphx::ref::target{});
auto result = p1.eval({}).back();
std::vector<float> results_vector(18);
result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); });
std::vector<float> gold{0, 255, 65, 0, 2, 2, 0, 255, 255, 0, 255, 65, 0, 2, 2, 0, 255, 255};
EXPECT(results_vector == gold);
}
}
TEST_CASE(recip_test) TEST_CASE(recip_test)
{ {
migraphx::program p; migraphx::program p;
......
#include <migraphx/rewrite_quantization.hpp>
#include <migraphx/program.hpp>
#include <migraphx/ref/target.hpp>
#include <migraphx/op/convolution.hpp>
#include <migraphx/op/reshape.hpp>
#include <migraphx/instruction.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/ranges.hpp>
#include <test.hpp>
#include <migraphx/make_op.hpp>
#include <migraphx/serialize.hpp>
#include <migraphx/verify.hpp>
bool is_quantizelinear(migraphx::instruction& ins) { return ins.name() == "quantizelinear"; }
bool is_dequantizelinear(migraphx::instruction& ins) { return ins.name() == "dequantizelinear"; }
TEST_CASE(quantizelinear)
{
migraphx::shape xs{migraphx::shape::float_type, {1, 3, 3}};
std::vector<float> xv = {-300, 200, 129, 1, 2, 3, 500, 1000, 50};
migraphx::shape ss{migraphx::shape::float_type, {1, 3, 3}};
std::vector<float> sv = {2, 2, 2, 2, 2, 2, 2, 2, 2};
auto create_program = [&]() {
migraphx::program p;
auto* mm = p.get_main_module();
auto x = mm->add_literal(xs, xv);
auto s = mm->add_literal(ss, sv);
mm->add_instruction(migraphx::make_op("quantizelinear"), x, s);
return p;
};
migraphx::program p1 = create_program();
migraphx::program p2 = create_program();
migraphx::rewrite_quantization opt;
opt.apply(*p2.get_main_module());
EXPECT(any_of(*p1.get_main_module(), &is_quantizelinear));
EXPECT(none_of(*p2.get_main_module(), &is_quantizelinear));
}
TEST_CASE(dequantizelinear)
{
migraphx::shape xs{migraphx::shape::float_type, {1, 3, 3}};
std::vector<float> xv = {0, 1, 2, 5, 10, 50, 100, 150, 250};
migraphx::shape ss{migraphx::shape::float_type, {1, 3, 3}};
std::vector<float> sv = {2, 2, 2, 2, 2, 2, 2, 2, 2};
migraphx::shape zs{migraphx::shape::uint8_type, {1, 3, 3}};
std::vector<uint8_t> zv = {0, 0, 0, 0, 0, 0, 0, 0, 0};
auto create_program = [&]() {
migraphx::program p;
auto* mm = p.get_main_module();
auto x = mm->add_literal(xs, xv);
auto s = mm->add_literal(ss, sv);
auto z = mm->add_literal(zs, zv);
mm->add_instruction(migraphx::make_op("dequantizelinear"), x, s, z);
return p;
};
migraphx::program p1 = create_program();
migraphx::program p2 = create_program();
migraphx::rewrite_quantization opt;
opt.apply(*p2.get_main_module());
EXPECT(any_of(*p1.get_main_module(), &is_dequantizelinear));
EXPECT(none_of(*p2.get_main_module(), &is_dequantizelinear));
}
int main(int argc, const char* argv[]) { test::run(argc, argv); }
...@@ -6,11 +6,15 @@ ...@@ -6,11 +6,15 @@
#include <migraphx/simplify_reshapes.hpp> #include <migraphx/simplify_reshapes.hpp>
#include <migraphx/dead_code_elimination.hpp> #include <migraphx/dead_code_elimination.hpp>
#include <migraphx/eliminate_identity.hpp> #include <migraphx/eliminate_identity.hpp>
#include <migraphx/operators.hpp>
#include <migraphx/program.hpp> #include <migraphx/program.hpp>
#include <migraphx/instruction.hpp> #include <migraphx/instruction.hpp>
#include <migraphx/tf.hpp> #include <migraphx/tf.hpp>
#include <migraphx/make_op.hpp> #include <migraphx/make_op.hpp>
#include <migraphx/op/batch_norm_inference.hpp>
#include <migraphx/op/convolution.hpp>
#include <migraphx/op/reduce_mean.hpp>
#include <migraphx/op/pooling.hpp>
#include <migraphx/op/slice.hpp>
#include <migraphx/serialize.hpp> #include <migraphx/serialize.hpp>
......
...@@ -27,7 +27,7 @@ std::future<typename std::result_of<Function()>::type> detach_async(Function&& f ...@@ -27,7 +27,7 @@ std::future<typename std::result_of<Function()>::type> detach_async(Function&& f
std::packaged_task<result_type()> task(std::forward<Function>(f)); std::packaged_task<result_type()> task(std::forward<Function>(f));
auto fut = task.get_future(); auto fut = task.get_future();
std::thread(std::move(task)).detach(); std::thread(std::move(task)).detach();
return std::move(fut); return fut;
} }
return std::async(std::launch::deferred, std::forward<Function>(f)); return std::async(std::launch::deferred, std::forward<Function>(f));
} }
......
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/make_op.hpp>
struct test_dequantizelinear : verify_program<test_dequantizelinear>
{
migraphx::program create_program() const
{
migraphx::program p;
auto* mm = p.get_main_module();
migraphx::shape sx{migraphx::shape::int8_type, {2, 2, 2}};
migraphx::shape ss{migraphx::shape::float_type, {2, 2, 2}};
migraphx::shape sz{migraphx::shape::int8_type, {2, 2, 2}};
auto input1 = mm->add_parameter("x", sx);
auto input2 = mm->add_parameter("x_scale", ss);
auto input3 = mm->add_parameter("x_zero_point", sz);
auto r = mm->add_instruction(migraphx::make_op("dequantizelinear"), input1, input2, input3);
mm->add_return({r});
return p;
};
};
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/make_op.hpp>
struct test_quantizelinear : verify_program<test_quantizelinear>
{
migraphx::program create_program() const
{
migraphx::program p;
auto* mm = p.get_main_module();
migraphx::shape sx{migraphx::shape::float_type, {2, 2, 2}};
migraphx::shape ss{migraphx::shape::float_type, {2, 2, 2}};
migraphx::shape sz{migraphx::shape::int8_type, {2, 2, 2}};
auto input1 = mm->add_parameter("x", sx);
auto input2 = mm->add_parameter("y_scale", ss);
auto input3 = mm->add_parameter("y_zero_point", sz);
auto r = mm->add_instruction(migraphx::make_op("quantizelinear"), input1, input2, input3);
mm->add_return({r});
return p;
};
};
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/make_op.hpp>
struct test_quantizelinear_int32 : verify_program<test_quantizelinear_int32>
{
migraphx::program create_program() const
{
migraphx::program p;
auto* mm = p.get_main_module();
migraphx::shape sx{migraphx::shape::int32_type, {2, 2, 2}};
migraphx::shape ss{migraphx::shape::float_type, {2, 2, 2}};
migraphx::shape sz{migraphx::shape::int8_type, {2, 2, 2}};
auto input1 = mm->add_parameter("x", sx);
auto input2 = mm->add_parameter("y_scale", ss);
auto input3 = mm->add_parameter("y_zero_point", sz);
auto r = mm->add_instruction(migraphx::make_op("quantizelinear"), input1, input2, input3);
mm->add_return({r});
return p;
};
};
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