Unverified Commit 8f184d4a authored by Charlie Lin's avatar Charlie Lin Committed by GitHub
Browse files

EyeLike Operator (#1087)

Adds EyeLike ONNX parser and unit tests.
parent a2e90b5d
#include <migraphx/onnx/op_parser.hpp>
#include <migraphx/onnx/checks.hpp>
#include <migraphx/ranges.hpp>
#include <migraphx/instruction.hpp>
#include <migraphx/make_op.hpp>
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
namespace onnx {
struct parse_eyelike : op_parser<parse_eyelike>
{
std::vector<op_desc> operators() const { return {{"EyeLike"}}; }
instruction_ref parse(const op_desc&,
const onnx_parser&,
const onnx_parser::node_info& info,
std::vector<instruction_ref> args) const
{
auto input_shape = args[0]->get_shape();
auto input_lens = input_shape.lens();
if(input_lens.size() != 2)
{
MIGRAPHX_THROW("EYELIKE: tensor input not of rank 2");
}
std::ptrdiff_t num_rows = input_lens.front();
std::ptrdiff_t num_cols = input_lens.back();
shape::type_t output_type = args[0]->get_shape().type();
if(contains(info.attributes, "dtype"))
{
output_type = get_type(info.attributes.at("dtype").i());
}
std::ptrdiff_t k = 0;
if(contains(info.attributes, "k"))
{
k = info.attributes.at("k").i();
}
if(k >= 0)
{
if(k >= num_cols)
{
std::ostringstream oss;
oss << "EYELIKE: positive k out of bounds, k = " << k << " num_cols = " << num_cols;
MIGRAPHX_THROW(oss.str());
}
}
else
{
if(std::abs(k) >= num_rows)
{
std::ostringstream oss;
oss << "EYELIKE: negative k out of bounds, k = " << k << " num_rows = " << num_cols;
MIGRAPHX_THROW(oss.str());
}
}
std::vector<char> eyelike_mat(num_rows * num_cols, 0);
for(std::ptrdiff_t i = 0; i < num_rows; ++i)
{
auto idx = i + k;
if(idx < num_cols and idx >= 0)
eyelike_mat[(num_cols + 1) * i + k] = char{1};
}
return info.add_literal(
migraphx::literal{migraphx::shape{output_type, input_lens}, eyelike_mat});
}
};
} // namespace onnx
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
eyelike_default_test:U

T1T2"EyeLikeeyelike_default_testZ
T1


b
T2


B
\ No newline at end of file
eyelike_double_test:T

T1T2"EyeLikeeyelike_double_testZ
T1
 

b
T2
 

B
\ No newline at end of file
eyelike_half_test:R

T1T2"EyeLikeeyelike_half_testZ
T1



b
T2



B
\ No newline at end of file
eyelike_k_outofbounds_neg_test:r
$
T1T2"EyeLike*
keyelike_k_outofbounds_neg_testZ
T1


b
T2


B
\ No newline at end of file
eyelike_k_outofbounds_pos_test:i

T1T2"EyeLike*
keyelike_k_outofbounds_pos_testZ
T1


b
T2


B
\ No newline at end of file
eyelike_k_test:Y

T1T2"EyeLike*
keyelike_k_testZ
T1


b
T2


B
\ No newline at end of file
eyelike_not_rank2_test:[

T1T2"EyeLikeeyelike_not_rank2_testZ
T1



b
T2


B
\ No newline at end of file
eyelike_set_dtype_test:e

T1T2"EyeLike*
dtype eyelike_set_dtype_testZ
T1


b
T2
 

B
\ No newline at end of file
eyelike_verify_negk_test:l
$
T1T2"EyeLike*
keyelike_verify_negk_testZ
T1


b
T2


B
\ No newline at end of file
eyelike_verify_test:^

T1T2"EyeLike*
keyelike_verify_testZ
T1


b
T2


B
\ No newline at end of file
...@@ -1381,6 +1381,114 @@ def expand_test(): ...@@ -1381,6 +1381,114 @@ def expand_test():
return ([shape_const, node], [x], [y]) return ([shape_const, node], [x], [y])
@onnx_test
def eyelike_default_test():
T1 = helper.make_tensor_value_info('T1', TensorProto.FLOAT, [3, 4])
T2 = helper.make_tensor_value_info('T2', TensorProto.FLOAT, [3, 4])
node = onnx.helper.make_node(
'EyeLike',
inputs=['T1'],
outputs=['T2'],
)
return ([node], [T1], [T2])
@onnx_test
def eyelike_double_test():
T1 = helper.make_tensor_value_info('T1', TensorProto.DOUBLE, [6, 15])
T2 = helper.make_tensor_value_info('T2', TensorProto.DOUBLE, [6, 15])
node = onnx.helper.make_node(
'EyeLike',
inputs=['T1'],
outputs=['T2'],
)
return ([node], [T1], [T2])
@onnx_test
def eyelike_half_test():
T1 = helper.make_tensor_value_info('T1', TensorProto.FLOAT16, [8, 8])
T2 = helper.make_tensor_value_info('T2', TensorProto.FLOAT16, [8, 8])
node = onnx.helper.make_node(
'EyeLike',
inputs=['T1'],
outputs=['T2'],
)
return ([node], [T1], [T2])
@onnx_test
def eyelike_k_test():
T1 = helper.make_tensor_value_info('T1', TensorProto.FLOAT, [3, 4])
T2 = helper.make_tensor_value_info('T2', TensorProto.FLOAT, [3, 4])
node = onnx.helper.make_node('EyeLike', inputs=['T1'], outputs=['T2'], k=1)
return ([node], [T1], [T2])
@onnx_test
def eyelike_k_outofbounds_neg_test():
T1 = helper.make_tensor_value_info('T1', TensorProto.FLOAT, [2, 4])
T2 = helper.make_tensor_value_info('T2', TensorProto.FLOAT, [2, 4])
node = onnx.helper.make_node('EyeLike',
inputs=['T1'],
outputs=['T2'],
k=-2)
return ([node], [T1], [T2])
@onnx_test
def eyelike_k_outofbounds_pos_test():
T1 = helper.make_tensor_value_info('T1', TensorProto.FLOAT, [3, 4])
T2 = helper.make_tensor_value_info('T2', TensorProto.FLOAT, [3, 4])
node = onnx.helper.make_node('EyeLike', inputs=['T1'], outputs=['T2'], k=4)
return ([node], [T1], [T2])
@onnx_test
def eyelike_not_rank2_test():
T1 = helper.make_tensor_value_info('T1', TensorProto.FLOAT, [3, 4, 2])
T2 = helper.make_tensor_value_info('T2', TensorProto.FLOAT, [3, 4])
node = onnx.helper.make_node(
'EyeLike',
inputs=['T1'],
outputs=['T2'],
)
return ([node], [T1], [T2])
@onnx_test
def eyelike_verify_test():
T1 = helper.make_tensor_value_info('T1', TensorProto.FLOAT, [3, 4])
T2 = helper.make_tensor_value_info('T2', TensorProto.FLOAT, [3, 4])
node = onnx.helper.make_node('EyeLike', inputs=['T1'], outputs=['T2'], k=1)
return ([node], [T1], [T2])
@onnx_test
def eyelike_verify_negk_test():
T1 = helper.make_tensor_value_info('T1', TensorProto.FLOAT, [3, 4])
T2 = helper.make_tensor_value_info('T2', TensorProto.FLOAT, [3, 4])
node = onnx.helper.make_node('EyeLike',
inputs=['T1'],
outputs=['T2'],
k=-2)
return ([node], [T1], [T2])
@onnx_test
def eyelike_set_dtype_test():
T1 = helper.make_tensor_value_info('T1', TensorProto.FLOAT, [3, 4])
T2 = helper.make_tensor_value_info('T2', TensorProto.DOUBLE, [3, 4])
node = onnx.helper.make_node('EyeLike',
inputs=['T1'],
outputs=['T2'],
dtype=TensorProto.DOUBLE)
return ([node], [T1], [T2])
@onnx_test @onnx_test
def flatten_test(): def flatten_test():
x = helper.make_tensor_value_info('0', TensorProto.FLOAT, [2, 3, 4, 5]) x = helper.make_tensor_value_info('0', TensorProto.FLOAT, [2, 3, 4, 5])
......
...@@ -46,6 +46,17 @@ migraphx::program optimize_onnx(const std::string& name, bool run_passes = false ...@@ -46,6 +46,17 @@ migraphx::program optimize_onnx(const std::string& name, bool run_passes = false
return prog; return prog;
} }
static std::vector<double> make_r_eyelike(size_t num_rows, size_t num_cols, size_t k)
{
std::vector<double> eyelike_mat(num_rows * num_cols, 0);
for(size_t i = 0; i < num_rows; ++i)
{
if(i + k < num_cols)
eyelike_mat[(num_cols + 1) * i + k] = 1.;
}
return eyelike_mat;
}
TEST_CASE(acos_test) TEST_CASE(acos_test)
{ {
migraphx::program p; migraphx::program p;
...@@ -1264,6 +1275,121 @@ TEST_CASE(external_data_diff_path_test) ...@@ -1264,6 +1275,121 @@ TEST_CASE(external_data_diff_path_test)
EXPECT(p == prog); EXPECT(p == prog);
} }
TEST_CASE(eyelike_default_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
std::vector<std::size_t> input_lens{3, 4};
const size_t k = 0;
auto num_rows = input_lens.front();
auto num_cols = input_lens.back();
auto input_type = migraphx::shape::float_type;
auto output_type = migraphx::shape::float_type;
migraphx::shape s{input_type, input_lens};
mm->add_parameter("T1", s);
auto eyelike_mat = make_r_eyelike(num_rows, num_cols, k);
mm->add_literal(migraphx::literal{migraphx::shape{output_type, input_lens}, eyelike_mat});
auto prog = optimize_onnx("eyelike_default_test.onnx");
EXPECT(p == prog);
}
TEST_CASE(eyelike_double_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
std::vector<std::size_t> input_lens{6, 15};
const size_t k = 0;
auto num_rows = input_lens.front();
auto num_cols = input_lens.back();
auto input_type = migraphx::shape::double_type;
auto output_type = migraphx::shape::double_type;
migraphx::shape s{input_type, input_lens};
mm->add_parameter("T1", s);
auto eyelike_mat = make_r_eyelike(num_rows, num_cols, k);
mm->add_literal(migraphx::literal{migraphx::shape{output_type, input_lens}, eyelike_mat});
auto prog = optimize_onnx("eyelike_double_test.onnx");
EXPECT(p == prog);
}
TEST_CASE(eyelike_half_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
std::vector<std::size_t> input_lens{8, 8};
const size_t k = 0;
auto num_rows = input_lens.front();
auto num_cols = input_lens.back();
auto input_type = migraphx::shape::half_type;
auto output_type = migraphx::shape::half_type;
migraphx::shape s{input_type, input_lens};
mm->add_parameter("T1", s);
auto eyelike_mat = make_r_eyelike(num_rows, num_cols, k);
mm->add_literal(migraphx::literal{migraphx::shape{output_type, input_lens}, eyelike_mat});
auto prog = optimize_onnx("eyelike_half_test.onnx");
EXPECT(p == prog);
}
TEST_CASE(eyelike_k_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
std::vector<std::size_t> input_lens{3, 4};
const size_t k = 1;
auto num_rows = input_lens.front();
auto num_cols = input_lens.back();
auto input_type = migraphx::shape::float_type;
auto output_type = migraphx::shape::float_type;
migraphx::shape s{input_type, input_lens};
mm->add_parameter("T1", s);
auto eyelike_mat = make_r_eyelike(num_rows, num_cols, k);
mm->add_literal(migraphx::literal{migraphx::shape{output_type, input_lens}, eyelike_mat});
auto prog = optimize_onnx("eyelike_k_test.onnx");
EXPECT(p == prog);
}
TEST_CASE(eyelike_k_outofbounds_neg_test)
{
EXPECT(test::throws([&] { migraphx::parse_onnx("eyelike_k_outofbounds_neg_test.onnx"); }));
}
TEST_CASE(eyelike_k_outofbounds_pos_test)
{
EXPECT(test::throws([&] { migraphx::parse_onnx("eyelike_k_outofbounds_pos_test.onnx"); }));
}
TEST_CASE(eyelike_not_rank2_test)
{
EXPECT(test::throws([&] { migraphx::parse_onnx("eyelike_not_rank2_test.onnx"); }));
}
TEST_CASE(eyelike_set_dtype_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
std::vector<std::size_t> input_lens{3, 4};
const size_t k = 0;
auto num_rows = input_lens.front();
auto num_cols = input_lens.back();
auto input_type = migraphx::shape::float_type;
auto output_type = migraphx::shape::double_type;
migraphx::shape s{input_type, input_lens};
mm->add_parameter("T1", s);
auto eyelike_mat = make_r_eyelike(num_rows, num_cols, k);
mm->add_literal(migraphx::literal{migraphx::shape{output_type, input_lens}, eyelike_mat});
auto prog = optimize_onnx("eyelike_set_dtype_test.onnx");
EXPECT(p == prog);
}
TEST_CASE(flatten_test) TEST_CASE(flatten_test)
{ {
migraphx::program p; migraphx::program p;
......
...@@ -103,6 +103,42 @@ TEST_CASE(spacetodepth_depthtospace_test) ...@@ -103,6 +103,42 @@ TEST_CASE(spacetodepth_depthtospace_test)
EXPECT(migraphx::verify_range(result_vector2, data_in)); EXPECT(migraphx::verify_range(result_vector2, data_in));
} }
TEST_CASE(eyelike_verify_test)
{
migraphx::program p = migraphx::parse_onnx("eyelike_verify_test.onnx");
p.compile(migraphx::ref::target{});
migraphx::shape s{migraphx::shape::float_type, {3, 4}};
std::vector<float> data{12, 0};
migraphx::parameter_map pp;
pp["T1"] = migraphx::argument(s, data.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> eyelike_mat = {0., 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1.};
EXPECT(migraphx::verify_range(result_vector, eyelike_mat));
}
TEST_CASE(eyelike_verify_negk_test)
{
migraphx::program p = migraphx::parse_onnx("eyelike_verify_negk_test.onnx");
p.compile(migraphx::ref::target{});
migraphx::shape s{migraphx::shape::float_type, {3, 4}};
std::vector<float> data{12, 0};
migraphx::parameter_map pp;
pp["T1"] = migraphx::argument(s, data.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> eyelike_mat = {0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0.};
EXPECT(migraphx::verify_range(result_vector, eyelike_mat));
}
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");
......
...@@ -111,6 +111,7 @@ def create_backend_test(testname=None, target_device=None): ...@@ -111,6 +111,7 @@ def create_backend_test(testname=None, target_device=None):
backend_test.include(r'.*test_equal.*') backend_test.include(r'.*test_equal.*')
backend_test.include(r'.*test_Embedding*') backend_test.include(r'.*test_Embedding*')
backend_test.include(r'.*test_exp.*') backend_test.include(r'.*test_exp.*')
backend_test.include(r'.*test_eyelike.*')
backend_test.include(r'.*test_flatten.*') backend_test.include(r'.*test_flatten.*')
backend_test.include(r'.*test_floor.*') backend_test.include(r'.*test_floor.*')
backend_test.include(r'.*test_gather.*') backend_test.include(r'.*test_gather.*')
......
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