Commit c9497134 authored by charlie's avatar charlie
Browse files

Merge branch 'develop' of github.com:ROCmSoftwarePlatform/AMDMIGraphX into select_module_op

parents e833a916 67f23675
......@@ -759,6 +759,22 @@ def concat_test():
return ([node], [x, y], [z])
@onnx_test()
def concat_dyn_test():
x = helper.make_tensor_value_info('0', TensorProto.FLOAT, [None, None, 3])
y = helper.make_tensor_value_info('1', TensorProto.FLOAT, [None, None, 3])
z = helper.make_tensor_value_info('2', TensorProto.FLOAT, [None, None, 3])
node = onnx.helper.make_node(
'Concat',
inputs=['0', '1'],
axis=0,
outputs=['2'],
)
return ([node], [x, y], [z])
@onnx_test()
def constant_test():
x = np.array([0, 1, 2])
......@@ -2053,6 +2069,40 @@ def gather_test():
return ([node], [x, i], [y])
@onnx_test()
def gather_scalar_test():
x = helper.make_tensor_value_info('data', TensorProto.FLOAT, [3, 4, 5, 6])
i = helper.make_tensor_value_info('indices', TensorProto.INT32, [])
y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [4, 5, 6])
node = onnx.helper.make_node(
'Gather',
inputs=['data', 'indices'],
outputs=['y'],
axis=1,
)
return ([node], [x, i], [y])
@onnx_test()
def gather_dyn_test():
x = helper.make_tensor_value_info('data', TensorProto.FLOAT,
[None, 4, 5, 6])
i = helper.make_tensor_value_info('indices', TensorProto.INT32,
[None, 3, 4, 5])
y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [2, 3, 4, 5])
node = onnx.helper.make_node(
'Gather',
inputs=['data', 'indices'],
outputs=['y'],
axis=1,
)
return ([node], [x, i], [y])
@onnx_test()
def gather_elements_axis0_test():
x = helper.make_tensor_value_info('data', TensorProto.FLOAT, [3, 4])
......@@ -2098,6 +2148,19 @@ def gathernd_test():
return ([node], [x, i], [y])
@onnx_test()
def gathernd_dyn_test():
x = helper.make_tensor_value_info('data', TensorProto.FLOAT, [None, 2])
i = helper.make_tensor_value_info('indices', TensorProto.INT64, [2, 2])
y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [2])
node = onnx.helper.make_node('GatherND',
inputs=['data', 'indices'],
outputs=['y'])
return ([node], [x, i], [y])
@onnx_test()
def gathernd_batch_dims_test():
x = helper.make_tensor_value_info('data', TensorProto.FLOAT, [2, 2, 2])
......@@ -2464,6 +2527,58 @@ def if_else_test():
x = onnx.helper.make_tensor_value_info('x', onnx.TensorProto.FLOAT, [2, 3])
y = onnx.helper.make_tensor_value_info('y', onnx.TensorProto.FLOAT, [2, 3])
then_out = onnx.helper.make_tensor_value_info('then_out',
onnx.TensorProto.FLOAT,
[2, 3])
else_out = onnx.helper.make_tensor_value_info('else_out',
onnx.TensorProto.FLOAT,
[2, 3])
xt = np.ones((2, 3)).astype(np.float)
xt_tensor = helper.make_tensor(name='xt',
data_type=TensorProto.FLOAT,
dims=xt.shape,
vals=xt.flatten().astype(np.float32))
yt = np.random.randn(2, 3).astype(np.float)
yt_tensor = helper.make_tensor(name='yt',
data_type=TensorProto.FLOAT,
dims=yt.shape,
vals=yt.flatten().astype(np.float32))
then_add_node = onnx.helper.make_node('Add',
inputs=['x', 'xt'],
outputs=['then_out'])
else_mul_node = onnx.helper.make_node('Mul',
inputs=['y', 'yt'],
outputs=['else_out'])
then_body = onnx.helper.make_graph([then_add_node], 'then_body', [],
[then_out])
else_body = onnx.helper.make_graph([else_mul_node], 'else_body', [],
[else_out])
cond_tensor = onnx.helper.make_tensor_value_info("cond",
onnx.TensorProto.BOOL,
[1])
res = onnx.helper.make_tensor_value_info('res', TensorProto.FLOAT, [])
node = onnx.helper.make_node('If',
inputs=['cond'],
outputs=['res'],
then_branch=then_body,
else_branch=else_body)
return ([node], [x, y, cond_tensor], [res], [xt_tensor, yt_tensor])
@onnx_test()
def if_else_test_inlined():
x = onnx.helper.make_tensor_value_info('x', onnx.TensorProto.FLOAT, [2, 3])
y = onnx.helper.make_tensor_value_info('y', onnx.TensorProto.FLOAT, [2, 3])
then_out = onnx.helper.make_tensor_value_info('then_out',
onnx.TensorProto.FLOAT,
[2, 3])
......@@ -2513,6 +2628,149 @@ def if_else_test():
return ([node], [x, y], [res], [cond_tensor, xt_tensor, yt_tensor])
@onnx_test()
def if_then_else_multi_output_shapes_inlined_test():
x = onnx.helper.make_tensor_value_info('x', onnx.TensorProto.FLOAT,
[2, 3, 1])
y = onnx.helper.make_tensor_value_info('y', onnx.TensorProto.FLOAT, [2, 3])
then_out = onnx.helper.make_tensor_value_info('then_out',
onnx.TensorProto.FLOAT,
[2, 3, 1])
then_out2 = onnx.helper.make_tensor_value_info('then_out2',
onnx.TensorProto.FLOAT,
[2, 3, 1])
else_out = onnx.helper.make_tensor_value_info('else_out',
onnx.TensorProto.FLOAT,
[2, 3])
else_out2 = onnx.helper.make_tensor_value_info('else_out2',
onnx.TensorProto.FLOAT,
[2, 3])
xt = np.ones((2, 3, 1)).astype(np.float)
xt_tensor = helper.make_tensor(name='xt',
data_type=TensorProto.FLOAT,
dims=xt.shape,
vals=xt.flatten().astype(np.float32))
yt = np.random.randn(2, 3).astype(np.float)
yt_tensor = helper.make_tensor(name='yt',
data_type=TensorProto.FLOAT,
dims=yt.shape,
vals=yt.flatten().astype(np.float32))
then_add_node = onnx.helper.make_node('Add',
inputs=['x', 'xt'],
outputs=['then_out'])
then_add_node2 = onnx.helper.make_node('Add',
inputs=['x', 'x'],
outputs=['then_out2'])
else_mul_node = onnx.helper.make_node('Mul',
inputs=['y', 'yt'],
outputs=['else_out'])
else_sub_node = onnx.helper.make_node('Sub',
inputs=['y', 'yt'],
outputs=['else_out2'])
then_body = onnx.helper.make_graph([then_add_node, then_add_node2],
'then_body', [], [then_out, then_out2])
else_body = onnx.helper.make_graph([else_mul_node, else_sub_node],
'else_body', [], [else_out, else_out2])
cond = np.array([1]).astype(np.bool)
cond_tensor = helper.make_tensor(name="cond",
data_type=TensorProto.BOOL,
dims=cond.shape,
vals=cond.astype(bool))
res1 = onnx.helper.make_tensor_value_info('res1', TensorProto.FLOAT, [])
res2 = onnx.helper.make_tensor_value_info('res2', TensorProto.FLOAT, [])
node = onnx.helper.make_node('If',
inputs=['cond'],
outputs=['res1', 'res2'],
then_branch=then_body,
else_branch=else_body)
return ([node], [x, y], [res1, res2], [cond_tensor, xt_tensor, yt_tensor])
@onnx_test()
def if_then_else_multi_output_shapes_test():
x = onnx.helper.make_tensor_value_info('x', onnx.TensorProto.FLOAT,
[2, 3, 1])
y = onnx.helper.make_tensor_value_info('y', onnx.TensorProto.FLOAT,
[2, 3, 1])
then_out = onnx.helper.make_tensor_value_info('then_out',
onnx.TensorProto.FLOAT,
[2, 3, 1])
then_out2 = onnx.helper.make_tensor_value_info('then_out2',
onnx.TensorProto.FLOAT,
[2, 3, 1])
else_out = onnx.helper.make_tensor_value_info('else_out',
onnx.TensorProto.FLOAT,
[2, 3, 1])
else_out2 = onnx.helper.make_tensor_value_info('else_out2',
onnx.TensorProto.FLOAT,
[2, 3, 1])
xt = np.ones((2, 3, 1)).astype(np.float)
xt_tensor = helper.make_tensor(name='xt',
data_type=TensorProto.FLOAT,
dims=xt.shape,
vals=xt.flatten().astype(np.float32))
yt = np.random.randn(2, 3, 1).astype(np.float)
yt_tensor = helper.make_tensor(name='yt',
data_type=TensorProto.FLOAT,
dims=yt.shape,
vals=yt.flatten().astype(np.float32))
then_add_node = onnx.helper.make_node('Add',
inputs=['x', 'xt'],
outputs=['then_out'])
then_add_node2 = onnx.helper.make_node('Add',
inputs=['x', 'x'],
outputs=['then_out2'])
else_mul_node = onnx.helper.make_node('Mul',
inputs=['y', 'yt'],
outputs=['else_out'])
else_sub_node = onnx.helper.make_node('Sub',
inputs=['y', 'yt'],
outputs=['else_out2'])
then_body = onnx.helper.make_graph([then_add_node, then_add_node2],
'then_body', [], [then_out, then_out2])
else_body = onnx.helper.make_graph([else_mul_node, else_sub_node],
'else_body', [], [else_out, else_out2])
cond_tensor = onnx.helper.make_tensor_value_info("cond",
onnx.TensorProto.BOOL,
[1])
res1 = onnx.helper.make_tensor_value_info('res1', TensorProto.FLOAT, [])
res2 = onnx.helper.make_tensor_value_info('res2', TensorProto.FLOAT, [])
node = onnx.helper.make_node('If',
inputs=['cond'],
outputs=['res1', 'res2'],
then_branch=then_body,
else_branch=else_body)
return ([node], [x, y, cond_tensor], [res1, res2], [xt_tensor, yt_tensor])
@onnx_test()
def if_literal_test():
then_out = onnx.helper.make_tensor_value_info('then_out',
......@@ -2773,6 +3031,59 @@ def if_then_test():
x = onnx.helper.make_tensor_value_info('x', onnx.TensorProto.FLOAT, [2, 3])
y = onnx.helper.make_tensor_value_info('y', onnx.TensorProto.FLOAT, [2, 3])
then_out = onnx.helper.make_tensor_value_info('then_out',
onnx.TensorProto.FLOAT,
[2, 3])
else_out = onnx.helper.make_tensor_value_info('else_out',
onnx.TensorProto.FLOAT,
[2, 3])
xt = np.ones((2, 3)).astype(np.float)
xt_tensor = helper.make_tensor(name='xt',
data_type=TensorProto.FLOAT,
dims=xt.shape,
vals=xt.flatten().astype(np.float32))
yt = np.random.randn(2, 3).astype(np.float)
yt_tensor = helper.make_tensor(name='yt',
data_type=TensorProto.FLOAT,
dims=yt.shape,
vals=yt.flatten().astype(np.float32))
then_add_node = onnx.helper.make_node('Add',
inputs=['x', 'xt'],
outputs=['then_out'])
else_mul_node = onnx.helper.make_node('Mul',
inputs=['y', 'yt'],
outputs=['else_out'])
then_body = onnx.helper.make_graph([then_add_node], 'then_body', [],
[then_out])
else_body = onnx.helper.make_graph([else_mul_node], 'else_body', [],
[else_out])
cond_tensor = onnx.helper.make_tensor_value_info("cond",
onnx.TensorProto.BOOL,
[1])
res = onnx.helper.make_tensor_value_info('res', TensorProto.FLOAT, [])
node = onnx.helper.make_node('If',
inputs=['cond'],
outputs=['res'],
then_branch=then_body,
else_branch=else_body)
return ([node], [x, y, cond_tensor], [res], [xt_tensor, yt_tensor])
@onnx_test()
def if_then_test_inlined():
x = onnx.helper.make_tensor_value_info('x', onnx.TensorProto.FLOAT, [2, 3])
y = onnx.helper.make_tensor_value_info('y', onnx.TensorProto.FLOAT, [2, 3])
then_out = onnx.helper.make_tensor_value_info('then_out',
onnx.TensorProto.FLOAT,
[2, 3])
......@@ -5673,6 +5984,24 @@ def scatternd_test():
return ([node], [data, indices, updates], [output])
@onnx_test()
def scatternd_dyn_test():
data = helper.make_tensor_value_info('data', TensorProto.FLOAT,
[None, 2, 2])
indices = helper.make_tensor_value_info('indices', TensorProto.INT64,
[None, 1, 2])
updates = helper.make_tensor_value_info('updates', TensorProto.FLOAT,
[None, 1, 2])
output = helper.make_tensor_value_info('output', TensorProto.FLOAT,
[None, 2, 2])
node = onnx.helper.make_node('ScatterND',
inputs=['data', 'indices', 'updates'],
outputs=['output'])
return ([node], [data, indices, updates], [output])
@onnx_test()
def selu_test():
x = helper.make_tensor_value_info('x', TensorProto.DOUBLE, [2, 3])
......@@ -6975,3 +7304,32 @@ def where_test():
outputs=['z'])
return ([node], [c, x, y], [z])
@onnx_test()
def where_dyn_test():
c = helper.make_tensor_value_info('c', TensorProto.BOOL, [None, 2, 2])
x = helper.make_tensor_value_info('x', TensorProto.FLOAT, [None, 2, 2])
y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [None, 2, 2])
z = helper.make_tensor_value_info('z', TensorProto.FLOAT, [None, 2, 2])
node = onnx.helper.make_node('Where',
inputs=['c', 'x', 'y'],
outputs=['z'])
return ([node], [c, x, y], [z])
@onnx_test()
def where_mixed_test():
# mixture of static and dynamic input shapes is not supported
c = helper.make_tensor_value_info('c', TensorProto.BOOL, [None, 2, 2])
x = helper.make_tensor_value_info('x', TensorProto.FLOAT, [None, 2, 2])
y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [3, 2, 2])
z = helper.make_tensor_value_info('z', TensorProto.FLOAT, [None, 2, 2])
node = onnx.helper.make_node('Where',
inputs=['c', 'x', 'y'],
outputs=['z'])
return ([node], [c, x, y], [z])
/*
* The MIT License (MIT)
*
* Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved.
* Copyright (c) 2015-2023 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
......@@ -840,6 +840,25 @@ TEST_CASE(concat_test)
EXPECT(p == prog);
}
TEST_CASE(concat_dyn_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
auto l0 = mm->add_parameter(
"0", migraphx::shape{migraphx::shape::float_type, {{1, 4, 0}, {1, 4, 0}, {3, 3, 0}}});
auto l1 = mm->add_parameter(
"1", migraphx::shape{migraphx::shape::float_type, {{1, 4, 0}, {1, 4, 0}, {3, 3, 0}}});
auto ret = mm->add_instruction(migraphx::make_op("concat"), l0, l1);
mm->add_return({ret});
migraphx::onnx_options options;
options.default_dyn_dim_value = {1, 4, 0};
auto prog = parse_onnx("concat_dyn_test.onnx", options);
EXPECT(p == prog);
}
TEST_CASE(constant_test)
{
migraphx::program p;
......@@ -2048,6 +2067,46 @@ TEST_CASE(gather_test)
EXPECT(p == prog);
}
TEST_CASE(gather_scalar_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
auto l0 = mm->add_parameter("data", migraphx::shape{migraphx::shape::float_type, {3, 4, 5, 6}});
std::vector<size_t> idims{1};
auto l1 =
mm->add_parameter("indices", migraphx::shape{migraphx::shape::int32_type, idims, {0}});
int axis = 1;
mm->add_instruction(migraphx::make_op("gather", {{"axis", axis}}), l0, l1);
auto prog = optimize_onnx("gather_scalar_test.onnx");
EXPECT(p == prog);
}
TEST_CASE(gather_dyn_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
auto l0 = mm->add_parameter(
"data",
migraphx::shape{migraphx::shape::float_type, {{1, 4, 0}, {4, 4, 0}, {5, 5, 0}, {6, 6, 0}}});
auto l1 = mm->add_parameter(
"indices",
migraphx::shape{migraphx::shape::int32_type, {{1, 4, 0}, {3, 3, 0}, {4, 4, 0}, {5, 5, 0}}});
auto cont_l0 = mm->add_instruction(migraphx::make_op("contiguous"), l0);
auto cont_l1 = mm->add_instruction(migraphx::make_op("contiguous"), l1);
int axis = 1;
auto gather_op = migraphx::make_op("gather", {{"axis", axis}});
auto ret = mm->add_instruction(gather_op, cont_l0, cont_l1);
mm->add_return({ret});
migraphx::onnx_options options;
options.default_dyn_dim_value = {1, 4, 0};
auto prog = parse_onnx("gather_dyn_test.onnx", options);
EXPECT(p == prog);
}
TEST_CASE(gather_elements_axis0_test)
{
migraphx::program p;
......@@ -2118,6 +2177,24 @@ TEST_CASE(gathernd_test)
EXPECT(p == prog);
}
TEST_CASE(gathernd_dyn_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
auto l0 = mm->add_parameter("data",
migraphx::shape{migraphx::shape::float_type, {{2, 4, 2}, {2, 4}}});
auto l1 = mm->add_parameter("indices",
migraphx::shape{migraphx::shape::int64_type, {{1, 3}, {2, 2}}});
auto r = mm->add_instruction(migraphx::make_op("gathernd"), l0, l1);
mm->add_return({r});
migraphx::onnx_options options;
options.map_dyn_input_dims["data"] = {{2, 4, 2}, {2, 4}};
options.map_dyn_input_dims["indices"] = {{1, 3}, {2, 2}};
auto prog = migraphx::parse_onnx("gathernd_dyn_test.onnx", options);
EXPECT(p == prog);
}
TEST_CASE(gathernd_batch_dims_test)
{
migraphx::program p;
......@@ -2632,14 +2709,16 @@ TEST_CASE(if_else_test)
migraphx::program p;
auto* mm = p.get_main_module();
migraphx::shape sc{migraphx::shape::bool_type, {1}};
auto cond = mm->add_literal(migraphx::literal(sc, {0}));
migraphx::shape s{migraphx::shape::float_type, {2, 3}};
std::vector<float> ones(s.elements(), 1.0f);
auto l1 = mm->add_literal(s, ones);
std::vector<float> rand = {-0.583375, 0.633757, 0.0668345, -0.479422, -0.604634, 0.0388589};
auto l2 = mm->add_literal(s, rand);
auto x = mm->add_parameter("x", s);
auto y = mm->add_parameter("y", s);
std::vector<float> rand = {1.3865, -0.494756, -0.283504, 0.200491, -0.490031, 1.32388};
auto l1 = mm->add_literal(s, ones);
auto l2 = mm->add_literal(s, rand);
auto x = mm->add_parameter("x", s);
auto y = mm->add_parameter("y", s);
auto cond = mm->add_parameter("cond", sc);
auto* then_mod = p.create_module("If_5_if");
auto rt = then_mod->add_instruction(migraphx::make_op("add"), x, l1);
......@@ -2653,15 +2732,32 @@ TEST_CASE(if_else_test)
auto r = mm->add_instruction(migraphx::make_op("get_tuple_elem", {{"index", 0}}), ret);
mm->add_return({r});
std::ifstream ifs("if_else_test.onnx", std::ios::binary);
ifs.seekg(0, std::ios::end);
auto length = ifs.tellg();
ifs.seekg(0, std::ios::beg);
std::vector<char> onnx_buffer(length);
ifs.read(onnx_buffer.data(), length);
ifs.close();
auto prog = migraphx::parse_onnx("if_else_test.onnx");
EXPECT(p == prog);
}
TEST_CASE(if_else_test_inlined)
{
migraphx::program p;
auto* mm = p.get_main_module();
migraphx::shape sc{migraphx::shape::bool_type, {1}};
mm->add_literal(migraphx::literal(sc, {0}));
auto prog = migraphx::parse_onnx_buffer(onnx_buffer.data(), length, {});
migraphx::shape s{migraphx::shape::float_type, {2, 3}};
std::vector<float> ones(s.elements(), 1.0f);
mm->add_literal(s, ones);
std::vector<float> rand = {0.811412, -0.949771, -0.169276, 0.36552, -0.14801, 2.07061};
auto l2 = mm->add_literal(s, rand);
mm->add_parameter("x", s);
auto y = mm->add_parameter("y", s);
auto re = mm->add_instruction(migraphx::make_op("mul"), y, l2);
mm->add_return({re});
auto prog = migraphx::parse_onnx("if_else_test_inlined.onnx");
EXPECT(p == prog);
}
......@@ -2734,6 +2830,70 @@ TEST_CASE(if_param_test)
EXPECT(p == prog);
}
TEST_CASE(if_then_else_multi_output_shapes_inlined_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
migraphx::shape sc{migraphx::shape::bool_type, {1}};
mm->add_literal(migraphx::literal(sc, {1}));
migraphx::shape s{migraphx::shape::float_type, {2, 3}};
migraphx::shape s_trail{migraphx::shape::float_type, {2, 3, 1}};
std::vector<float> ones(s.elements(), 1.0f);
auto l1 = mm->add_literal(s_trail, ones);
std::vector<float> rand = {-1.01837, -0.305541, -0.254105, 0.892955, 1.38714, -0.584205};
mm->add_literal(s, rand);
auto x = mm->add_parameter("x", s_trail);
mm->add_parameter("y", s);
auto rt = mm->add_instruction(migraphx::make_op("add"), x, l1);
auto rt2 = mm->add_instruction(migraphx::make_op("add"), x, x);
mm->add_return({rt, rt2});
auto prog = migraphx::parse_onnx("if_then_else_multi_output_shapes_inlined_test.onnx");
EXPECT(p == prog);
}
TEST_CASE(if_then_else_multi_output_shapes_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
migraphx::shape sc{migraphx::shape::bool_type, {1}};
migraphx::shape s{migraphx::shape::float_type, {2, 3, 1}};
migraphx::shape s_trail{migraphx::shape::float_type, {2, 3, 1}};
std::vector<float> ones(s.elements(), 1.0f);
auto l1 = mm->add_literal(s_trail, ones);
std::vector<float> rand = {-0.753997, 0.707831, -0.865795, 2.49574, 0.464937, -0.168745};
auto l2 = mm->add_literal(s, rand);
auto x = mm->add_parameter("x", s_trail);
auto y = mm->add_parameter("y", s);
auto cond = mm->add_parameter("cond", sc);
auto* then_mod = p.create_module("If_5_if");
auto rt = then_mod->add_instruction(migraphx::make_op("add"), x, l1);
auto rt2 = then_mod->add_instruction(migraphx::make_op("add"), x, x);
then_mod->add_return({rt, rt2});
auto* else_mod = p.create_module("If_5_else");
auto re = else_mod->add_instruction(migraphx::make_op("mul"), y, l2);
auto re2 = else_mod->add_instruction(migraphx::make_op("sub"), y, l2);
else_mod->add_return({re, re2});
auto ret = mm->add_instruction(migraphx::make_op("if"), {cond}, {then_mod, else_mod});
auto r1 = mm->add_instruction(migraphx::make_op("get_tuple_elem", {{"index", 0}}), ret);
auto r2 = mm->add_instruction(migraphx::make_op("get_tuple_elem", {{"index", 1}}), ret);
mm->add_return({r1, r2});
auto prog = migraphx::parse_onnx("if_then_else_multi_output_shapes_test.onnx");
EXPECT(p == prog);
}
TEST_CASE(if_pl_test)
{
migraphx::program p;
......@@ -2774,14 +2934,16 @@ TEST_CASE(if_then_test)
migraphx::program p;
auto* mm = p.get_main_module();
migraphx::shape sc{migraphx::shape::bool_type, {1}};
auto cond = mm->add_literal(migraphx::literal(sc, {1}));
migraphx::shape s{migraphx::shape::float_type, {2, 3}};
std::vector<float> ones(s.elements(), 1.0f);
auto l1 = mm->add_literal(s, ones);
std::vector<float> rand = {-1.26487, -2.42279, 0.990835, 1.63072, 0.812238, -0.174946};
auto l2 = mm->add_literal(s, rand);
auto x = mm->add_parameter("x", s);
auto y = mm->add_parameter("y", s);
std::vector<float> rand = {-0.266913, -0.180328, -0.124268, -1.23768, 0.312334, 1.18475};
auto l1 = mm->add_literal(s, ones);
auto l2 = mm->add_literal(s, rand);
auto x = mm->add_parameter("x", s);
auto y = mm->add_parameter("y", s);
auto cond = mm->add_parameter("cond", sc);
auto* then_mod = p.create_module("If_5_if");
auto rt = then_mod->add_instruction(migraphx::make_op("add"), x, l1);
......@@ -2799,6 +2961,32 @@ TEST_CASE(if_then_test)
EXPECT(p == prog);
}
TEST_CASE(if_then_test_inlined)
{
migraphx::program p;
auto* mm = p.get_main_module();
migraphx::shape sc{migraphx::shape::bool_type, {1}};
mm->add_literal(migraphx::literal(sc, {1}));
migraphx::shape s{migraphx::shape::float_type, {2, 3}};
std::vector<float> ones(s.elements(), 1.0f);
auto l1 = mm->add_literal(s, ones);
std::vector<float> rand = {-1.26487, -2.42279, 0.990835, 1.63072, 0.812238, -0.174946};
mm->add_literal(s, rand);
auto x = mm->add_parameter("x", s);
mm->add_parameter("y", s);
auto rt = mm->add_instruction(migraphx::make_op("add"), x, l1);
mm->add_return({rt});
auto prog = migraphx::parse_onnx("if_then_test_inlined.onnx");
EXPECT(p == prog);
}
TEST_CASE(if_tuple_test)
{
migraphx::program p;
......@@ -5599,53 +5787,67 @@ TEST_CASE(scatter_none_test)
TEST_CASE(scatternd_test)
{
{
migraphx::program p;
auto* mm = p.get_main_module();
auto l0 =
mm->add_parameter("data", migraphx::shape{migraphx::shape::float_type, {2, 2, 2}});
auto l1 =
mm->add_parameter("indices", migraphx::shape{migraphx::shape::int64_type, {2, 1, 2}});
auto l2 =
mm->add_parameter("updates", migraphx::shape{migraphx::shape::float_type, {2, 1, 2}});
auto r = mm->add_instruction(migraphx::make_op("scatternd_none"), l0, l1, l2);
mm->add_return({r});
auto prog = migraphx::parse_onnx("scatternd_test.onnx");
migraphx::program p;
auto* mm = p.get_main_module();
auto l0 = mm->add_parameter("data", migraphx::shape{migraphx::shape::float_type, {2, 2, 2}});
auto l1 = mm->add_parameter("indices", migraphx::shape{migraphx::shape::int64_type, {2, 1, 2}});
auto l2 = mm->add_parameter("updates", migraphx::shape{migraphx::shape::float_type, {2, 1, 2}});
auto r = mm->add_instruction(migraphx::make_op("scatternd_none"), l0, l1, l2);
mm->add_return({r});
auto prog = migraphx::parse_onnx("scatternd_test.onnx");
EXPECT(p == prog);
}
EXPECT(p == prog);
}
{
migraphx::program p;
auto* mm = p.get_main_module();
auto l0 =
mm->add_parameter("data", migraphx::shape{migraphx::shape::float_type, {2, 2, 2}});
auto l1 =
mm->add_parameter("indices", migraphx::shape{migraphx::shape::int64_type, {2, 1, 2}});
auto l2 =
mm->add_parameter("updates", migraphx::shape{migraphx::shape::float_type, {2, 1, 2}});
auto r = mm->add_instruction(migraphx::make_op("scatternd_add"), l0, l1, l2);
mm->add_return({r});
auto prog = migraphx::parse_onnx("scatternd_add_test.onnx");
TEST_CASE(scatternd_dyn_test)
{
// dynamic input.
migraphx::program p;
auto* mm = p.get_main_module();
// parameters with dynamic dimensions
auto l0 = mm->add_parameter(
"data", migraphx::shape{migraphx::shape::float_type, {{1, 3, 2}, {2, 2}, {2, 2}}});
auto l1 = mm->add_parameter(
"indices", migraphx::shape{migraphx::shape::int64_type, {{2, 1, 2}, {1, 1}, {2, 2}}});
auto l2 = mm->add_parameter(
"updates", migraphx::shape{migraphx::shape::float_type, {{2, 1, 2}, {1, 1}, {2, 2}}});
auto r = mm->add_instruction(migraphx::make_op("scatternd_none"), l0, l1, l2);
mm->add_return({r});
migraphx::onnx_options options;
options.map_dyn_input_dims["data"] = {{1, 3, 2}, {2, 2}, {2, 2}};
options.map_dyn_input_dims["indices"] = {{2, 1, 2}, {1, 1}, {2, 2}};
options.map_dyn_input_dims["updates"] = {{2, 1, 2}, {1, 1}, {2, 2}};
auto prog = migraphx::parse_onnx("scatternd_dyn_test.onnx", options);
EXPECT(p == prog);
}
EXPECT(p == prog);
}
{
migraphx::program p;
auto* mm = p.get_main_module();
auto l0 =
mm->add_parameter("data", migraphx::shape{migraphx::shape::float_type, {2, 2, 2}});
auto l1 =
mm->add_parameter("indices", migraphx::shape{migraphx::shape::int64_type, {2, 1, 2}});
auto l2 =
mm->add_parameter("updates", migraphx::shape{migraphx::shape::float_type, {2, 1, 2}});
auto r = mm->add_instruction(migraphx::make_op("scatternd_mul"), l0, l1, l2);
mm->add_return({r});
auto prog = migraphx::parse_onnx("scatternd_mul_test.onnx");
TEST_CASE(scatternd_add_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
auto l0 = mm->add_parameter("data", migraphx::shape{migraphx::shape::float_type, {2, 2, 2}});
auto l1 = mm->add_parameter("indices", migraphx::shape{migraphx::shape::int64_type, {2, 1, 2}});
auto l2 = mm->add_parameter("updates", migraphx::shape{migraphx::shape::float_type, {2, 1, 2}});
auto r = mm->add_instruction(migraphx::make_op("scatternd_add"), l0, l1, l2);
mm->add_return({r});
auto prog = migraphx::parse_onnx("scatternd_add_test.onnx");
EXPECT(p == prog);
}
EXPECT(p == prog);
}
TEST_CASE(scatternd_mul_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
auto l0 = mm->add_parameter("data", migraphx::shape{migraphx::shape::float_type, {2, 2, 2}});
auto l1 = mm->add_parameter("indices", migraphx::shape{migraphx::shape::int64_type, {2, 1, 2}});
auto l2 = mm->add_parameter("updates", migraphx::shape{migraphx::shape::float_type, {2, 1, 2}});
auto r = mm->add_instruction(migraphx::make_op("scatternd_mul"), l0, l1, l2);
mm->add_return({r});
auto prog = migraphx::parse_onnx("scatternd_mul_test.onnx");
EXPECT(p == prog);
}
TEST_CASE(selu_test)
......@@ -6765,4 +6967,35 @@ TEST_CASE(where_test)
EXPECT(p == prog);
}
TEST_CASE(where_dyn_test)
{
// TODO: broadcasting for dynamic shapes isn't implemented at time of writing.
// Update this test case to use shapes that require broadcasting, when available.
migraphx::program p;
auto* mm = p.get_main_module();
auto lc = mm->add_parameter(
"c", migraphx::shape{migraphx::shape::bool_type, {{1, 4, 0}, {2, 2, 0}, {2, 2, 0}}});
auto lx = mm->add_parameter(
"x", migraphx::shape{migraphx::shape::float_type, {{1, 4, 0}, {2, 2, 0}, {2, 2, 0}}});
auto ly = mm->add_parameter(
"y", migraphx::shape{migraphx::shape::float_type, {{1, 4, 0}, {2, 2, 0}, {2, 2, 0}}});
auto r = mm->add_instruction(migraphx::make_op("where"), lc, lx, ly);
mm->add_return({r});
migraphx::onnx_options options;
options.default_dyn_dim_value = {1, 4, 0};
auto prog = parse_onnx("where_dyn_test.onnx", options);
EXPECT(p == prog);
}
TEST_CASE(where_mixed_test)
{
// mixture of static and dynamic input shapes is not supported
migraphx::onnx_options options;
options.default_dyn_dim_value = {1, 4, 0};
EXPECT(test::throws([&] { migraphx::parse_onnx("where_mixed_test.onnx", options); }));
}
int main(int argc, const char* argv[]) { test::run(argc, argv); }
......@@ -590,6 +590,28 @@ TEST_CASE(if_else_test)
p.compile(migraphx::ref::target{});
migraphx::shape s_data{migraphx::shape::float_type, {2, 3}};
std::vector<float> data = {0.0625, 0.75, -0.0625, 0.125, -0.125, -0.5625};
migraphx::shape bool_data{migraphx::shape::bool_type, {1}};
bool b_data = false;
migraphx::parameter_map pp;
pp["x"] = migraphx::argument(s_data, data.data());
pp["y"] = migraphx::argument(s_data, data.data());
pp["cond"] = migraphx::argument(bool_data, &b_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.0866565, -0.371067, 0.017719, 0.0250614, 0.0612539, -0.744683};
EXPECT(migraphx::verify_range(result_vector, gold));
}
TEST_CASE(if_else_test_inlined)
{
migraphx::program p = migraphx::parse_onnx("if_else_test_inlined.onnx");
p.compile(migraphx::ref::target{});
migraphx::shape s_data{migraphx::shape::float_type, {2, 3}};
std::vector<float> data = {0.0625, 0.75, -0.0625, 0.125, -0.125, -0.5625};
migraphx::parameter_map pp;
pp["x"] = migraphx::argument(s_data, data.data());
......@@ -599,8 +621,49 @@ TEST_CASE(if_else_test)
std::vector<float> result_vector;
result.visit([&](auto output) { result_vector.assign(output.begin(), output.end()); });
std::vector<float> gold = {
-0.0364609435, 0.475317657, -0.00417715637, -0.0599277429, 0.0755792186, -0.0218581557};
std::vector<float> gold = {0.0507132, -0.712328, 0.0105797, 0.04569, 0.0185013, -1.16472};
EXPECT(migraphx::verify_range(result_vector, gold));
}
TEST_CASE(if_then_test)
{
migraphx::program p = migraphx::parse_onnx("if_then_test.onnx");
p.compile(migraphx::ref::target{});
migraphx::shape s_data{migraphx::shape::float_type, {2, 3}};
std::vector<float> data = {0.0625, 0.75, -0.0625, 0.125, -0.125, -0.5625};
migraphx::shape bool_data{migraphx::shape::bool_type, {1}};
bool b_data = true;
migraphx::parameter_map pp;
pp["x"] = migraphx::argument(s_data, data.data());
pp["y"] = migraphx::argument(s_data, data.data());
pp["cond"] = migraphx::argument(bool_data, &b_data);
auto result = p.eval(pp).back();
std::vector<float> result_vector;
result.visit([&](auto output) { result_vector.assign(output.begin(), output.end()); });
// onnx adds ones so result should be just + 1.0
std::vector<float> gold = {1.0625, 1.75, 0.9375, 1.125, 0.875, 0.4375};
EXPECT(migraphx::verify_range(result_vector, gold));
}
TEST_CASE(if_then_test_inlined)
{
migraphx::program p = migraphx::parse_onnx("if_then_test_inlined.onnx");
p.compile(migraphx::ref::target{});
migraphx::shape s_data{migraphx::shape::float_type, {2, 3}};
std::vector<float> data = {0.0625, 0.75, -0.0625, 0.125, -0.125, -0.5625};
migraphx::parameter_map pp;
pp["x"] = migraphx::argument(s_data, data.data());
pp["y"] = migraphx::argument(s_data, 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> gold = {1.0625, 1.75, 0.9375, 1.125, 0.875, 0.4375};
EXPECT(migraphx::verify_range(result_vector, gold));
}
......@@ -637,6 +700,67 @@ TEST_CASE(if_literal_test)
}
}
TEST_CASE(if_then_else_multi_output_shapes_inlined_test)
{
migraphx::program p =
migraphx::parse_onnx("if_then_else_multi_output_shapes_inlined_test.onnx");
p.compile(migraphx::ref::target{});
migraphx::shape x_data{migraphx::shape::float_type, {2, 3, 1}};
migraphx::shape y_data{migraphx::shape::float_type, {2, 3}};
std::vector<float> data = {0.0625, 0.75, -0.0625, 0.125, -0.125, -0.5625};
migraphx::parameter_map pp;
pp["x"] = migraphx::argument(x_data, data.data());
pp["y"] = migraphx::argument(y_data, data.data());
auto result_args = p.eval(pp);
auto result = result_args.front();
auto result_b = result_args.back();
std::vector<float> result_vector;
result.visit([&](auto output) { result_vector.assign(output.begin(), output.end()); });
std::vector<float> result_vector_back;
result_b.visit([&](auto output) { result_vector_back.assign(output.begin(), output.end()); });
result_vector.insert(result_vector.end(), result_vector_back.begin(), result_vector_back.end());
std::vector<float> gold = {
1.0625, 1.75, 0.9375, 1.125, 0.875, 0.4375, 0.125, 1.50, -0.125, 0.250, -0.250, -1.125};
EXPECT(migraphx::verify_range(result_vector, gold));
}
TEST_CASE(if_then_else_multi_output_shapes_test)
{
migraphx::program p = migraphx::parse_onnx("if_then_else_multi_output_shapes_test.onnx");
p.compile(migraphx::ref::target{});
migraphx::shape s_data{migraphx::shape::float_type, {2, 3, 1}};
std::vector<float> data = {0.0625, 0.75, -0.0625, 0.125, -0.125, -0.5625};
migraphx::shape bool_data{migraphx::shape::bool_type, {1}};
bool b_data = true;
migraphx::parameter_map pp;
pp["x"] = migraphx::argument(s_data, data.data());
pp["y"] = migraphx::argument(s_data, data.data());
pp["cond"] = migraphx::argument(bool_data, &b_data);
auto result_args = p.eval(pp);
auto result = result_args.front();
auto result_b = result_args.back();
std::vector<float> result_vector;
result.visit([&](auto output) { result_vector.assign(output.begin(), output.end()); });
std::vector<float> result_vector_back;
result_b.visit([&](auto output) { result_vector_back.assign(output.begin(), output.end()); });
result_vector.insert(result_vector.end(), result_vector_back.begin(), result_vector_back.end());
std::vector<float> gold = {
1.0625, 1.75, 0.9375, 1.125, 0.875, 0.4375, 0.125, 1.50, -0.125, 0.250, -0.250, -1.125};
EXPECT(migraphx::verify_range(result_vector, gold));
}
TEST_CASE(if_pl_test)
{
auto run_prog = [](bool cond) {
......
/*
* The MIT License (MIT)
*
* Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved.
* Copyright (c) 2015-2023 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
......@@ -831,6 +831,77 @@ TEST_CASE(gather)
}
}
TEST_CASE(gather_dyn0)
{
// Insert dynamic index into dynamic shape
migraphx::shape input{migraphx::shape::float_type,
{{2, 3, 2}, {3, 4, 3}, {6, 9, 7}, {12, 14, 13}}};
migraphx::shape indices{migraphx::shape::int32_type, {{2, 7, 3}, {3, 3, 0}}};
int axis = 1;
expect_shape(migraphx::shape{migraphx::shape::float_type,
{{2, 3, 2}, {2, 7, 3}, {3, 3, 0}, {6, 9, 7}, {12, 14, 13}}},
migraphx::make_op("gather", {{"axis", axis}}),
input,
indices);
}
TEST_CASE(gather_dyn1)
{
// Insert static index into dynamic shape
migraphx::shape input{migraphx::shape::float_type,
{{2, 3, 2}, {3, 4, 3}, {6, 9, 7}, {12, 14, 13}}};
migraphx::shape indices{migraphx::shape::int32_type, {2, 3}};
int axis = 1;
expect_shape(migraphx::shape{migraphx::shape::float_type,
{{2, 3, 2}, {2, 2, 0}, {3, 3, 0}, {6, 9, 7}, {12, 14, 13}}},
migraphx::make_op("gather", {{"axis", axis}}),
input,
indices);
}
TEST_CASE(gather_dyn2)
{
// Insert scalar (static) index into dynamic shape
migraphx::shape input{migraphx::shape::float_type,
{{2, 3, 2}, {3, 4, 3}, {6, 9, 7}, {12, 14, 13}}};
std::vector<std::size_t> mins;
std::vector<std::size_t> maxes;
std::vector<std::size_t> opts;
migraphx::shape indices{migraphx::shape::int32_type, mins, maxes, opts};
int axis = 1;
expect_shape(migraphx::shape{migraphx::shape::float_type, {{2, 3, 2}, {6, 9, 7}, {12, 14, 13}}},
migraphx::make_op("gather", {{"axis", axis}}),
input,
indices);
}
TEST_CASE(gather_dyn3)
{
// Insert dynamic index into static shape, axis 1
migraphx::shape input{migraphx::shape::float_type, {2, 3, 6, 12}};
migraphx::shape indices{migraphx::shape::int32_type, {{2, 3, 2}, {3, 4, 3}}};
int axis = 1;
expect_shape(migraphx::shape{migraphx::shape::float_type,
{{2, 2, 0}, {2, 3, 2}, {3, 4, 3}, {6, 6, 0}, {12, 12, 0}}},
migraphx::make_op("gather", {{"axis", axis}}),
input,
indices);
}
TEST_CASE(gather_dyn4)
{
// Insert dynamic index into static shape, axis 0
migraphx::shape input{migraphx::shape::float_type, {2, 3, 6, 12}};
migraphx::shape indices{migraphx::shape::int32_type, {{2, 3, 2}, {3, 4, 3}}};
int axis = 0;
expect_shape(migraphx::shape{migraphx::shape::float_type,
{{2, 3, 2}, {3, 4, 3}, {3, 3, 0}, {6, 6, 0}, {12, 12, 0}}},
migraphx::make_op("gather", {{"axis", axis}}),
input,
indices);
}
TEST_CASE(get_tuple_elem_test)
{
migraphx::shape s0{migraphx::shape::bool_type, {1, 1}};
......@@ -2418,27 +2489,359 @@ TEST_CASE(test_scalar_nelemnts)
throws_shape(migraphx::make_op("scalar", {{"scalar_bcst_dims", {2, 3, 4, 5}}}), input);
}
TEST_CASE(test_scatternd)
TEST_CASE(test_gathernd)
{
{
// k > r
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape is{itype, {2, 4}};
migraphx::shape ds{dtype, {8}};
migraphx::shape is{itype, {4, 2}};
migraphx::shape us{dtype, {4}};
throws_shape(migraphx::make_op("scatternd_none"), ds, is, us);
int batch_dims(1);
throws_shape(migraphx::make_op("gathernd", {{"batch_dims", batch_dims}}), ds, is);
}
{
// update.lens != indices.lens[0:q-1] ++ data.lens[k:r-1]
// k > r - batch_dims
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape ds{dtype, {8}};
migraphx::shape is{itype, {4, 1}};
migraphx::shape us{dtype, {2, 2}};
throws_shape(migraphx::make_op("scatternd_none"), ds, is, us);
migraphx::shape is{itype, {2, 4}};
migraphx::shape ds{dtype, {2}};
int batch_dims(1);
throws_shape(migraphx::make_op("gathernd", {{"batch_dims", batch_dims}}), ds, is);
}
{
// batch_dims >= r
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape is{itype, {2, 1}};
migraphx::shape ds{dtype, {2, 5, 6, 7}};
int batch_dims(3);
throws_shape(migraphx::make_op("gathernd", {{"batch_dims", batch_dims}}), ds, is);
}
{
// int(q) + r - k - batch_dims - 1 = 0 => returns a scalar
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape is{itype, {1}};
migraphx::shape ds{dtype, {2}};
migraphx::shape s0{dtype, {1}};
expect_shape(s0, migraphx::make_op("gathernd"), ds, is);
}
{
// See Example 4 at https://github.com/onnx/onnx/blob/main/docs/Operators.md#GatherND
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape is{itype, {2, 2}};
migraphx::shape ds{dtype, {2, 2}};
migraphx::shape s0{dtype, {2}};
expect_shape(s0, migraphx::make_op("gathernd"), ds, is);
}
{
// See Example 5 at https://github.com/onnx/onnx/blob/main/docs/Operators.md#GatherND
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape is{itype, {2, 1}};
migraphx::shape ds{dtype, {2, 2, 2}};
int batch_dims(1);
migraphx::shape s0{dtype, {2, 2}};
expect_shape(s0, migraphx::make_op("gathernd", {{"batch_dims", batch_dims}}), ds, is);
}
}
TEST_CASE(test_gathernd_dynamic0)
{
// k > r
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape is{itype, {2, 4}};
std::vector<migraphx::shape::dynamic_dimension> b{{8, 8, 0}};
migraphx::shape ds{dtype, b};
int batch_dims(1);
throws_shape(migraphx::make_op("gathernd", {{"batch_dims", batch_dims}}), ds, is);
}
TEST_CASE(test_gathernd_dynamic1)
{
// k > r - batch_dims
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape is{itype, {2, 4}};
std::vector<migraphx::shape::dynamic_dimension> b{{2, 2, 0}};
migraphx::shape ds{dtype, b};
int batch_dims(1);
throws_shape(migraphx::make_op("gathernd", {{"batch_dims", batch_dims}}), ds, is);
}
TEST_CASE(test_gathernd_dynamic2)
{
// batch_dims >= r
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape is{itype, {2, 1}};
migraphx::shape ds{dtype, {{2, 3, 3}, {5, 6, 5}, {6, 9, 7}, {7, 8, 8}}};
int batch_dims(3);
throws_shape(migraphx::make_op("gathernd", {{"batch_dims", batch_dims}}), ds, is);
}
TEST_CASE(test_gathernd_dynamic3)
{
// int(q) + r - k - batch_dims - 1 = 0 => returns a scalar
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape is{itype, {1}};
std::vector<migraphx::shape::dynamic_dimension> b{{2, 2, 0}};
migraphx::shape ds{dtype, b};
migraphx::shape::dynamic_dimension ddout{1, 1, 0};
migraphx::shape s0{dtype, {ddout}};
expect_shape(s0, migraphx::make_op("gathernd"), ds, is);
}
TEST_CASE(test_gathernd_dynamic4)
{
// See Example 1 at https://github.com/onnx/onnx/blob/main/docs/Operators.md#GatherND
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape is{itype, {2, 2}};
std::vector<migraphx::shape::dynamic_dimension> b{{2, 2, 0}, {2, 2, 0}};
migraphx::shape ds{dtype, b};
migraphx::shape::dynamic_dimension ddout{2, 2, 0};
migraphx::shape s0{dtype, {ddout}};
expect_shape(s0, migraphx::make_op("gathernd"), ds, is);
}
TEST_CASE(test_gathernd_dynamic5)
{
// See Example 5 at https://github.com/onnx/onnx/blob/main/docs/Operators.md#GatherND
// index static shape, data dynamic
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape is{itype, {2, 1}};
std::vector<migraphx::shape::dynamic_dimension> b{{2, 2, 0}, {2, 2, 0}, {2, 2, 0}};
migraphx::shape ds{dtype, b};
std::vector<migraphx::shape::dynamic_dimension> ddout{{2, 2, 0}, {2, 2, 0}};
int batch_dims(1);
migraphx::shape s0{dtype, {ddout}};
expect_shape(s0, migraphx::make_op("gathernd", {{"batch_dims", batch_dims}}), ds, is);
}
TEST_CASE(test_gathernd_dynamic6)
{
// See Example 5 at https://github.com/onnx/onnx/blob/main/docs/Operators.md#GatherND
// index dynamic shape, data static
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
std::vector<migraphx::shape::dynamic_dimension> b{{2, 3, 0}, {1, 1, 0}};
migraphx::shape is{itype, b};
migraphx::shape ds{dtype, {2, 2, 2}};
std::vector<migraphx::shape::dynamic_dimension> ddout{{2, 3, 0}, {2, 2, 0}};
int batch_dims(1);
migraphx::shape s0{dtype, {ddout}};
expect_shape(s0, migraphx::make_op("gathernd", {{"batch_dims", batch_dims}}), ds, is);
}
TEST_CASE(test_gathernd_dynamic6a)
{
// indices with non-fixed dynamic dimension k
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
std::vector<migraphx::shape::dynamic_dimension> b{{2, 2, 0}, {1, 3, 0}};
migraphx::shape is{itype, b};
migraphx::shape ds{dtype, {2, 2, 2}};
int batch_dims(1);
throws_shape(migraphx::make_op("gathernd", {{"batch_dims", batch_dims}}), ds, is);
}
TEST_CASE(test_gathernd_dynamic7)
{
// See Example 5 at https://github.com/onnx/onnx/blob/main/docs/Operators.md#GatherND
// index and data both dynamic shapes
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
std::vector<migraphx::shape::dynamic_dimension> idyn{{2, 5, 0}, {1, 1, 0}};
migraphx::shape is{itype, idyn};
std::vector<migraphx::shape::dynamic_dimension> bdyn{{1, 2, 0}, {1, 2, 0}, {1, 2, 0}};
migraphx::shape ds{dtype, bdyn};
std::vector<migraphx::shape::dynamic_dimension> ddout{{2, 5, 0}, {1, 2, 0}};
int batch_dims(1);
migraphx::shape s0{dtype, {ddout}};
expect_shape(s0, migraphx::make_op("gathernd", {{"batch_dims", batch_dims}}), ds, is);
}
TEST_CASE(test_gathernd_dynamic8)
{
// Same shapes as ref_ops_test gathernd_dynamic
// index static shape, data dynamic
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape is{itype, {2, 5, 1}};
std::vector<migraphx::shape::dynamic_dimension> b{{6, 7, 7}, {3, 3, 0}, {1, 4, 0}};
migraphx::shape ds{dtype, b};
std::vector<migraphx::shape::dynamic_dimension> ddout{{2, 2, 0}, {5, 5, 0}, {1, 4, 0}};
int batch_dims(1);
migraphx::shape s0{dtype, {ddout}};
expect_shape(s0, migraphx::make_op("gathernd", {{"batch_dims", batch_dims}}), ds, is);
}
TEST_CASE(test_scatternd0)
{
// good
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape ds{dtype, {8}};
migraphx::shape is{itype, {4, 1}};
migraphx::shape us{dtype, {4}};
expect_shape(ds, migraphx::make_op("scatternd_none"), ds, is, us);
}
TEST_CASE(test_scatternd1)
{
// good, broadcasted
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape ds{dtype, {8}};
migraphx::shape is{itype, {4, 1}, {4, 0}};
migraphx::shape us{dtype, {4}};
expect_shape(ds, migraphx::make_op("scatternd_none"), ds, is, us);
}
TEST_CASE(test_scatternd2)
{
// too many inputs
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape ds{dtype, {8}};
migraphx::shape is{itype, {4, 1}};
migraphx::shape us{dtype, {4}};
migraphx::shape zs{dtype, {4}};
throws_shape(migraphx::make_op("scatternd_none"), ds, is, us, zs);
}
TEST_CASE(test_scatternd3)
{
// q + r - k - 1 matches upd_lens.size(), but k > r
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape ds{dtype, {8}};
migraphx::shape is{itype, {5, 4, 2}};
migraphx::shape us{dtype, {4}};
throws_shape(migraphx::make_op("scatternd_none"), ds, is, us);
}
TEST_CASE(test_scatternd4)
{
// q + r - k - 1 != upd_lens.size()
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape ds{dtype, {8}};
migraphx::shape is{itype, {4, 1}};
migraphx::shape us{dtype, {2, 2}};
throws_shape(migraphx::make_op("scatternd_none"), ds, is, us);
}
TEST_CASE(test_scatternd5)
{
// dimensions don't match: update.lens != indices.lens[0:q-1]
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape ds{dtype, {8, 3}};
migraphx::shape is{itype, {4, 1}};
migraphx::shape us{dtype, {2, 2}};
throws_shape(migraphx::make_op("scatternd_none"), ds, is, us);
}
TEST_CASE(test_scatternd_dyn0)
{
// one dynamic input, invalid index
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape ds{dtype, {4}};
migraphx::shape is{itype, {4, 13}};
migraphx::shape::dynamic_dimension dd{4, 4, 0};
migraphx::shape us{dtype, {dd}};
throws_shape(migraphx::make_op("scatternd_none"), ds, is, us);
}
TEST_CASE(test_scatternd_dyn1)
{
// one dynamic input
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape ds{dtype, {8}};
migraphx::shape is{itype, {4, 1}};
migraphx::shape::dynamic_dimension dd{4, 4, 0};
migraphx::shape us{dtype, {dd}};
expect_shape(ds, migraphx::make_op("scatternd_none"), ds, is, us);
}
TEST_CASE(test_scatternd_dyn2)
{
// one dynamic input and broadcasted data
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape ds{dtype, {2, 3, 1, 4}, {0, 1, 1, 0}};
migraphx::shape ds_std{dtype, {2, 3, 1, 4}};
migraphx::shape is{itype, {4, 4}};
migraphx::shape::dynamic_dimension dd{4, 4, 0};
migraphx::shape us{dtype, {dd}};
expect_shape(ds_std, migraphx::make_op("scatternd_none"), ds, is, us);
}
TEST_CASE(test_scatternd_dyn3)
{
// one dynamic input and standard, static data
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape ds{dtype, {2, 3, 1, 4}};
migraphx::shape is{itype, {4, 4}};
migraphx::shape::dynamic_dimension dd{4, 4, 0};
migraphx::shape us{dtype, {dd}};
expect_shape(ds, migraphx::make_op("scatternd_none"), ds, is, us);
}
TEST_CASE(test_scatternd_dyn4)
{
// index is dynamic with last dimension not fixed
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape ds{dtype, {2, 3, 1, 4}};
migraphx::shape::dynamic_dimension dd{4, 5, 0};
migraphx::shape is{itype, {dd, dd}};
migraphx::shape us{dtype, {dd}};
throws_shape(migraphx::make_op("scatternd_none"), ds, is, us);
}
TEST_CASE(test_scatternd_dyn5)
{
// dimensions don't match: update.lens != indices.lens[0:q-1]
auto dtype = migraphx::shape::float_type;
auto itype = migraphx::shape::int64_type;
migraphx::shape ds{dtype, {2, 3, 1, 4}};
migraphx::shape::dynamic_dimension dd{4, 4, 0};
migraphx::shape::dynamic_dimension dbad{2, 3, 0};
migraphx::shape is{itype, {dd, dd}};
migraphx::shape us{dtype, {dbad}};
throws_shape(migraphx::make_op("scatternd_none"), ds, is, us);
}
TEST_CASE(test_squeeze)
......@@ -2766,6 +3169,42 @@ TEST_CASE(where_broadcast_input)
expect_shape(s2, migraphx::make_op("where"), s3, s1, s2);
}
TEST_CASE(where_dyn_input0)
{
// dynamic shapes not the same
migraphx::shape s1{migraphx::shape::float_type, {{2, 3, 0}, {3, 3, 0}}};
migraphx::shape s2{migraphx::shape::float_type, {{2, 3, 0}, {2, 3, 0}}};
migraphx::shape s3{migraphx::shape::bool_type, {2, 2}};
throws_shape(migraphx::make_op("where"), s3, s1, s2);
}
TEST_CASE(where_dyn_input1)
{
// mixed static/dynamic inputs (not allowed)
migraphx::shape s1{migraphx::shape::float_type, {2, 2}, {2, 1}};
migraphx::shape s2{migraphx::shape::float_type, {{2, 2, 0}, {2, 2, 0}}};
migraphx::shape s3{migraphx::shape::bool_type, {2, 2}, {2, 1}};
throws_shape(migraphx::make_op("where"), s3, s1, s2);
}
TEST_CASE(where_dyn_input2)
{
// dynamic shapes
migraphx::shape s1{migraphx::shape::float_type, {{2, 3, 0}, {3, 3, 0}}};
migraphx::shape s2{migraphx::shape::float_type, {{2, 3, 0}, {3, 3, 0}}};
migraphx::shape s3{migraphx::shape::bool_type, {{2, 3, 0}, {3, 3, 0}}};
expect_shape(s2, migraphx::make_op("where"), s3, s1, s2);
}
TEST_CASE(where_dyn_input3)
{
// dynamic shapes, predicate shape is different
migraphx::shape s1{migraphx::shape::float_type, {{2, 3, 0}, {3, 3, 0}}};
migraphx::shape s2{migraphx::shape::float_type, {{2, 3, 0}, {3, 3, 0}}};
migraphx::shape s3{migraphx::shape::bool_type, {{2, 3, 0}, {3, 4, 0}}};
throws_shape(migraphx::make_op("where"), s3, s1, s2);
}
TEST_CASE(roialign_test)
{
migraphx::shape sx{migraphx::shape::float_type, {3, 4, 5, 6}};
......@@ -2788,4 +3227,52 @@ TEST_CASE(roialign_test)
throws_shape(migraphx::make_op("roialign"), sx, srois2, sbi);
}
TEST_CASE(test_concat)
{
migraphx::shape sx{migraphx::shape::float_type, {3, 4, 5, 6}};
migraphx::shape sy{migraphx::shape::float_type, {3, 4, 1, 6}};
migraphx::shape sout{migraphx::shape::float_type, {3, 4, 6, 6}};
expect_shape(sout, migraphx::make_op("concat", {{"axis", 2}}), sx, sy);
// axis out of range
throws_shape(migraphx::make_op("concat", {{"axis", 11}}), sx, sy);
// 1 input; no-op
expect_shape(sx, migraphx::make_op("concat", {{"axis", 2}}), sx);
// rank doesn't match
migraphx::shape sbi1{migraphx::shape::int64_type, {2, 3}};
throws_shape(migraphx::make_op("concat", {{"axis", 0}}), sx, sbi1);
// non-matching dimension 2
throws_shape(migraphx::make_op("concat", {{"axis", 1}}), sx, sy);
// no input shapes (at least one is required)
throws_shape(migraphx::make_op("concat", {{"axis", 0}}));
}
TEST_CASE(test_dyn_concat)
{
migraphx::shape sx{migraphx::shape::float_type, {{1, 3, 3}, {4, 4}, {1, 5, 5}, {6, 6}}};
migraphx::shape sy{migraphx::shape::float_type, {{1, 3, 3}, {4, 4}, {1, 4, 4}, {6, 6}}};
migraphx::shape sout{migraphx::shape::float_type, {{1, 3, 3}, {4, 4, 0}, {2, 9, 0}, {6, 6}}};
expect_shape(sout, migraphx::make_op("concat", {{"axis", 2}}), sx, sy);
// axis out of range
throws_shape(migraphx::make_op("concat", {{"axis", 4}}), sx, sy);
// rank doesn't match
migraphx::shape srank{migraphx::shape::int64_type, {{1, 3, 3}, {4, 4}}};
throws_shape(migraphx::make_op("concat", {{"axis", 0}}), sx, srank);
// non-matching dimension 2
throws_shape(migraphx::make_op("concat", {{"axis", 1}}), sx, sy);
// static and dynamic shapes together
migraphx::shape sstat{migraphx::shape::float_type, {3, 4, 1, 6}};
throws_shape(migraphx::make_op("concat", {{"axis", 2}}), sx, sstat);
}
int main(int argc, const char* argv[]) { test::run(argc, argv); }
......@@ -51,7 +51,7 @@ class MIGraphXBackendTest(onnx.backend.test.BackendTest):
np.testing.assert_equal(ref_outputs[i].dtype,
outputs[i].dtype,
err_msg=prog_string)
if ref_outputs[i].dtype == np.object:
if ref_outputs[i].dtype == object:
np.testing.assert_array_equal(ref_outputs[i],
outputs[i],
err_msg=prog_string)
......
This diff is collapsed.
......@@ -60,7 +60,9 @@ struct reflectable_type
return migraphx::pack(f(self.value, "value"));
}
};
std::vector<nested_type> nested_types = {};
std::vector<nested_type> nested_types = {};
std::tuple<int, nested_type, std::string> tuple_items = std::make_tuple(0, nested_type{0}, "");
migraphx::optional<int> opt_value = migraphx::nullopt;
template <class Self, class F>
static auto reflect(Self& self, F f)
......@@ -71,7 +73,8 @@ struct reflectable_type
f(self.et, "et"),
f(self.se, "se"),
f(self.ce, "ce"),
f(self.nested_types, "nested_types"));
f(self.nested_types, "nested_types"),
f(self.tuple_items, "tuple_items"));
}
};
......@@ -83,7 +86,9 @@ TEST_CASE(serialize_reflectable_type)
{},
reflectable_type::simple1,
reflectable_type::class_enum::class2,
{{1}, {2}}};
{{1}, {2}},
{5, {4}, "hello"},
{migraphx::nullopt}};
migraphx::value v1 = migraphx::to_value(t1);
reflectable_type t2 = migraphx::from_value<reflectable_type>(v1);
migraphx::value v2 = migraphx::to_value(t2);
......@@ -125,6 +130,21 @@ TEST_CASE(serialize_empty_struct)
EXPECT(v.at("a").to<int>() == 1);
}
TEST_CASE(serialize_empty_optional)
{
migraphx::optional<int> x{};
migraphx::value v = migraphx::to_value(x);
EXPECT(v.is_null());
}
TEST_CASE(serialize_optional)
{
migraphx::optional<int> x{2};
migraphx::value v = migraphx::to_value(x);
EXPECT(v.is_int64());
EXPECT(v.to<int>() == 2);
}
TEST_CASE(from_value_binary)
{
std::vector<std::uint8_t> data(10);
......
......@@ -559,6 +559,32 @@ TEST_CASE(simplify_inner_broadcast2)
EXPECT(m1 == m2);
}
TEST_CASE(simplify_inner_broadcast_scalar)
{
auto b = migraphx::op::multibroadcast{{32, 384}};
migraphx::module m1;
{
auto x = m1.add_parameter("x", {migraphx::shape::int32_type, {1, 384}});
auto y = m1.add_parameter("y", {migraphx::shape::int32_type, {1, 1}});
auto xb = m1.add_instruction(b, x);
auto yb = m1.add_instruction(b, y);
auto sum = m1.add_instruction(migraphx::make_op("add"), xb, yb);
m1.add_instruction(pass_op{}, sum);
}
run_pass(m1);
migraphx::module m2;
{
auto x = m2.add_parameter("x", {migraphx::shape::int32_type, {1, 384}});
auto y = m2.add_parameter("y", {migraphx::shape::int32_type, {1, 1}});
auto yb = m2.add_instruction(migraphx::op::multibroadcast{{1, 384}}, y);
auto sum = m2.add_instruction(migraphx::make_op("add"), x, yb);
auto sumb = m2.add_instruction(b, sum);
m2.add_instruction(pass_op{}, sumb);
}
EXPECT(m1 == m2);
}
TEST_CASE(simplify_add_conv1)
{
migraphx::module m;
......@@ -1041,16 +1067,18 @@ TEST_CASE(simplify_neg_unit_mult_const)
{
migraphx::module m1;
{
auto x = m1.add_parameter("x", {migraphx::shape::int32_type, {1}});
auto unit = m1.add_literal(-1);
auto x = m1.add_parameter("x", {migraphx::shape::int32_type, {1, 6}});
auto unit = m1.add_literal(
migraphx::literal{{migraphx::shape::int32_type, {1, 6}}, std::vector<int>(6, -1)});
m1.add_instruction(migraphx::make_op("mul"), x, unit);
}
run_pass(m1);
migraphx::module m2;
{
auto x = m2.add_parameter("x", {migraphx::shape::int32_type, {1}});
m2.add_instruction(migraphx::make_op("neg"), x);
auto x = m2.add_parameter("x", {migraphx::shape::int32_type, {1, 6}});
auto x2 = m2.add_instruction(migraphx::make_op("neg"), x);
m2.add_instruction(migraphx::make_op("identity"), x2);
}
EXPECT((m1 == m2));
......@@ -1068,8 +1096,30 @@ TEST_CASE(simplify_neg_unit_mult_const2)
migraphx::module m2;
{
auto x = m2.add_parameter("x", {migraphx::shape::int32_type, {1}});
m2.add_instruction(migraphx::make_op("neg"), x);
auto x = m2.add_parameter("x", {migraphx::shape::int32_type, {1}});
auto x2 = m2.add_instruction(migraphx::make_op("neg"), x);
m2.add_instruction(migraphx::make_op("identity"), x2);
}
EXPECT((m1 == m2));
}
TEST_CASE(simplify_neg_unit_mult_const_add)
{
migraphx::module m1;
{
auto unit = m1.add_literal(-1);
auto x = m1.add_parameter("x", {migraphx::shape::int32_type, {1}});
auto x2 = m1.add_instruction(migraphx::make_op("mul"), unit, x);
m1.add_instruction(migraphx::make_op("add"), x2, x2);
}
run_pass(m1);
migraphx::module m2;
{
auto x = m2.add_parameter("x", {migraphx::shape::int32_type, {1}});
auto x2 = m2.add_instruction(migraphx::make_op("neg"), x);
m2.add_instruction(migraphx::make_op("add"), x2, x2);
}
EXPECT((m1 == m2));
......@@ -1091,8 +1141,9 @@ TEST_CASE(simplify_neg_unit_mul_const_vec)
migraphx::module m2;
{
auto x = m2.add_parameter("x", x_shape);
m2.add_instruction(migraphx::make_op("neg"), x);
auto x = m2.add_parameter("x", x_shape);
auto x2 = m2.add_instruction(migraphx::make_op("neg"), x);
m2.add_instruction(migraphx::make_op("identity"), x2);
}
EXPECT(m1 == m2);
......@@ -1114,8 +1165,9 @@ TEST_CASE(simplify_neg_unit_mul_const_vec2)
migraphx::module m2;
{
auto x = m2.add_parameter("x", x_shape);
m2.add_instruction(migraphx::make_op("neg"), x);
auto x = m2.add_parameter("x", x_shape);
auto x2 = m2.add_instruction(migraphx::make_op("neg"), x);
m2.add_instruction(migraphx::make_op("identity"), x2);
}
EXPECT(m1 == m2);
......@@ -1133,8 +1185,9 @@ TEST_CASE(simplify_neg_unit_div_const)
migraphx::module m2;
{
auto x = m2.add_parameter("x", {migraphx::shape::int32_type, {1}});
m2.add_instruction(migraphx::make_op("neg"), x);
auto x = m2.add_parameter("x", {migraphx::shape::int32_type, {1}});
auto x2 = m2.add_instruction(migraphx::make_op("neg"), x);
m2.add_instruction(migraphx::make_op("identity"), x2);
}
EXPECT(m1 == m2);
......@@ -1156,8 +1209,9 @@ TEST_CASE(simplify_neg_unit_div_const_vec)
migraphx::module m2;
{
auto x = m2.add_parameter("x", x_shape);
m2.add_instruction(migraphx::make_op("neg"), x);
auto x = m2.add_parameter("x", x_shape);
auto x2 = m2.add_instruction(migraphx::make_op("neg"), x);
m2.add_instruction(migraphx::make_op("identity"), x2);
}
EXPECT(m1 == m2);
......@@ -1216,8 +1270,9 @@ TEST_CASE(simplify_sub_neg_zero_const)
migraphx::module m2;
{
auto x = m2.add_parameter("x", {migraphx::shape::int32_type, {1}});
m2.add_instruction(migraphx::make_op("neg"), x);
auto x = m2.add_parameter("x", {migraphx::shape::int32_type, {1}});
auto x2 = m2.add_instruction(migraphx::make_op("neg"), x);
m2.add_instruction(migraphx::make_op("identity"), x2);
}
EXPECT(m1 == m2);
}
......@@ -1238,8 +1293,9 @@ TEST_CASE(simplify_sub_neg_zero_const_vec)
migraphx::module m2;
{
auto x = m2.add_parameter("x", x_shape);
m2.add_instruction(migraphx::make_op("neg"), x);
auto x = m2.add_parameter("x", x_shape);
auto x2 = m2.add_instruction(migraphx::make_op("neg"), x);
m2.add_instruction(migraphx::make_op("identity"), x2);
}
EXPECT(m1 == m2);
......
......@@ -25,6 +25,7 @@ import argparse
import numpy as np
import migraphx
import onnxruntime as ort
import sys
def parse_args():
......@@ -33,15 +34,13 @@ def parse_args():
'MIGraphX accuracy checker. Use to verify onnx files to ensure MIGraphX\'s output \
is within tolerance of onnx runtime\'s expected output.'
)
req_args = parser.add_argument_group(title='required arguments')
req_args.add_argument('--onnx',
type=str,
required=True,
help='path to onnx file')
req_args.add_argument('--provider',
type=str,
default='CPUExecutionProvider',
help='execution provider for onnx runtime \
file_args = parser.add_argument_group(title='file type arguments')
file_args.add_argument('--onnx', type=str, help='path to onnx file')
file_args.add_argument('--tf', type=str, help='path to tf pb file')
parser.add_argument('--provider',
type=str,
default='CPUExecutionProvider',
help='execution provider for onnx runtime \
(default = CPUExecutionProvider)')
parser.add_argument('--batch',
type=int,
......@@ -50,6 +49,9 @@ def parse_args():
parser.add_argument('--fill1',
action='store_true',
help='fill all arguments with a value of 1')
parser.add_argument('--fill0',
action='store_true',
help='fill all arguments with a value of 0')
parser.add_argument('--verbose',
action='store_true',
help='show verbose information (for debugging)')
......@@ -57,6 +59,12 @@ def parse_args():
type=float,
default=1e-3,
help='accuracy tolerance (default = 1e-3)')
parser.add_argument('--input-dim',
type=str,
action='append',
help='specify input parameter dimension \
with the following format --input_dim input_name:dim0,dim1,dim2...'
)
args = parser.parse_args()
return args
......@@ -111,42 +119,127 @@ def get_np_datatype(in_type):
def main():
args = parse_args()
use_onnx = True
if args.onnx == None:
use_onnx = False
if not use_onnx and args.tf == None:
print('Error: please specify either an onnx or tf pb file')
sys.exit(-1)
model_name = args.onnx
batch = args.batch
model = migraphx.parse_onnx(model_name, default_dim_value=batch)
custom_inputs = args.input_dim
input_dims = {}
if custom_inputs != None:
for input in custom_inputs:
input_dim = ''.join(input.split(':')[:-1])
dims = [int(dim) for dim in input.split(':')[-1].split(',')]
input_dims[input_dim] = dims
if use_onnx:
if not input_dims:
model = migraphx.parse_onnx(model_name, default_dim_value=batch)
else:
model = migraphx.parse_onnx(model_name,
default_dim_value=batch,
map_input_dims=input_dims)
else:
model_name = args.tf
if not input_dims:
model = migraphx.parse_tf(model_name, batch_size=batch)
else:
model = migraphx.parse_tf(model_name,
batch_size=batch,
map_input_dims=input_dims)
if args.verbose:
print(model)
model.compile(migraphx.get_target('gpu'), offload_copy=False)
model.compile(migraphx.get_target('gpu'))
params = {}
test_inputs = {}
for name, shape in model.get_parameter_shapes().items():
if args.verbose:
print('Parameter {} -> {}'.format(name, shape))
print(f'Parameter {name} -> {shape}')
in_shape = shape.lens()
in_type = shape.type_string()
if not args.fill1:
if not args.fill1 and not args.fill0:
test_input = np.random.rand(*(in_shape)).astype(
get_np_datatype(in_type))
else:
elif not args.fill0:
test_input = np.ones(in_shape).astype(get_np_datatype(in_type))
else:
test_input = np.zeros(in_shape).astype(get_np_datatype(in_type))
test_inputs[name] = test_input
params[name] = migraphx.to_gpu(migraphx.argument(test_input))
params[name] = migraphx.argument(test_input)
pred_migx = np.array(model.run(params)[-1])
pred_migx = np.array(migraphx.from_gpu(model.run(params)[-1]))
if use_onnx:
sess = ort.InferenceSession(model_name, providers=[args.provider])
sess = ort.InferenceSession(model_name, providers=[args.provider])
ort_params = {}
for input in sess.get_inputs():
ort_params[input.name] = test_inputs[input.name]
try:
pred_fw = sess.run(None, ort_params)[-1]
except Exception as e:
if any(input_dims):
print(
'Error: custom input dim may not be compatible with onnx runtime'
)
raise e
else:
import tensorflow as tf
def load_tf_graph(model_name):
with tf.io.gfile.GFile(model_name, 'rb') as f:
graph_def = tf.compat.v1.GraphDef()
graph_def.ParseFromString(f.read())
with tf.compat.v1.Graph().as_default() as graph:
tf.graph_util.import_graph_def(graph_def)
return graph
graph = load_tf_graph(model_name)
is_nhwc = False
graph_ops = []
for op in graph.get_operations():
graph_ops.append(op.name)
if 'Conv' in op.node_def.op:
if 'NHWC' in op.get_attr('data_format').decode('utf-8'):
is_nhwc = True
graph_ops_set = set(graph_ops)
tf_dict = {}
for name in test_inputs.keys():
# graph.get_operations() adds 'import/' to the op name
tf_name = f'import/{name}'
if tf_name not in graph_ops_set:
continue
x = graph.get_tensor_by_name(f'{tf_name}:0')
tf_input = test_inputs[name]
# transpose input for NHWC model
if tf_input.ndim == 4 and is_nhwc:
tf_dict[x] = np.transpose(tf_input, (0, 2, 3, 1))
else:
tf_dict[x] = tf_input
ort_params = {}
for input in sess.get_inputs():
ort_params[input.name] = test_inputs[input.name]
# assume last node in graph is output
# TODO: let user specify op name for output
y = graph.get_tensor_by_name(f'{graph_ops[-1]}:0')
pred_ort = sess.run(None, ort_params)[-1]
with tf.compat.v1.Session(graph=graph) as sess:
y_out = sess.run(y, feed_dict=tf_dict)
pred_fw = y_out
is_correct = check_correctness(pred_ort, pred_migx, args.tolerance,
is_correct = check_correctness(pred_fw, pred_migx, args.tolerance,
args.tolerance, args.verbose)
verbose_string = ' Rerun with --verbose for detailed information.' \
if not args.verbose else ''
......
......@@ -22,9 +22,12 @@
# THE SOFTWARE.
#####################################################################################
cd /onnxruntime
pip3 install -r requirements.txt
pip3 install -r requirements-dev.txt
# Add newer cmake to the path
export PATH="/opt/cmake/bin:$PATH"
export CXXFLAGS="-D__HIP_PLATFORM_HCC__=1 -w"
./build.sh --config Release --update --build --parallel --cmake_extra_defines ONNXRUNTIME_VERSION=$(cat ./VERSION_NUMBER) --test --use_migraphx
# pip3 install /code/onnxruntime/build/Linux/Release/dist/*.whl
./build.sh --config Release --cmake_extra_defines CMAKE_HIP_COMPILER=/opt/rocm/llvm/bin/clang++ --update --build --parallel --cmake_extra_defines ONNXRUNTIME_VERSION=$(cat ./VERSION_NUMBER) --skip_tests --rocm_home /opt/rocm --use_migraphx --migraphx_home /opt/rocm --rocm_version=`cat /opt/rocm/.info/version-dev`
cd build/Linux/Release
#Add test launcher for onnxrt tests
../../../tools/ci_build/github/pai/migraphx_test_launcher.sh
......@@ -26,10 +26,12 @@
if [ -z "$ONNX_HOME" ]
then
ONNX_HOME=$HOME
# The onnx library uses ONNX_HOME, by default if it doesn't exist
# the path of " ~/.onnx " is used
ONNX_HOME=$HOME/.onnx
fi
model_dir=$ONNX_HOME/.onnx/models
model_dir=$ONNX_HOME/models
tmp_dir=$ONNX_HOME/tmp/
mkdir -p $model_dir
mkdir -p $tmp_dir
......@@ -42,7 +44,6 @@ models="bvlc_alexnet \
for name in $models
do
curl https://s3.amazonaws.com/download.onnx/models/opset_9/$name.tar.gz --output $tmp_dir/$name.tar.gz
curl https://download.onnxruntime.ai/onnx/models/$name.tar.gz --output $tmp_dir/$name.tar.gz
tar -xzvf $tmp_dir/$name.tar.gz --directory $model_dir && rm $tmp_dir/$name.tar.gz
done
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