"examples/vscode:/vscode.git/clone" did not exist on "79ea77e8152c3019c96467d4d0a49440522ce65e"
Unverified Commit 4fe71058 authored by Shucai Xiao's avatar Shucai Xiao Committed by GitHub
Browse files

Resize linear mode support (#819)



* backup implementation of resize enhancement

* clang format

* code backup for the resize

* clang format

* fix build error for resize operator

* clang format

* tmp code backup

* clang format

* code backup

* clang format

* remove changes in parse_resize

* remove unnecessary changes

* clang format

* add unit test for the bug

* clang format

* remove print code

* remove a semi-colon

* clang format

* fix a tidy error

* clang format

* add contiguous for nonstd input for the resize operator

* clang format

* code backup

* clang format

* fix build error

* code backup

* clang format

* code backup

* code backup

* clang format

* add unit tests for resize_linear

* clang format

* refine a function name

* clang format

* fix cppcheck error

* clang format

* fix cppcheck error

* fix review comments

* clang format

* backup code changes

* clang format

* add unit tests for resize operator

* clang format

* remove an unused header file

* remove an unused header file

* remove unrelated unit tests

* refine parsing resize inputs

* clang format

* fix cppcheck error

* fix cppcheck error

* remove unnecessary code

* clang format

* fix cppcheck error

* clang format

* fixed a bug

* clang format

* fix review comments

* clang format
Co-authored-by: default avatarmvermeulen <5479696+mvermeulen@users.noreply.github.com>
parent 39bc6161
......@@ -55,7 +55,7 @@ const auto& get_original_idx_op(const std::string& mode)
}},
{"align_corners",
[=](std::size_t l_in, std::size_t l_out, std::size_t idx, double) {
return 1.0 * idx * (l_in - 1.0) / (l_out - 1.0);
return (l_out == 1) ? 0.0 : (1.0 * idx * (l_in - 1.0) / (l_out - 1.0));
}},
{"asymmetric",
[=](std::size_t, std::size_t, std::size_t idx, double scale) { return idx / scale; }},
......@@ -71,6 +71,96 @@ const auto& get_original_idx_op(const std::string& mode)
return idx_ops.at(mode);
}
static std::vector<int>
calc_neighbor_points(const std::vector<std::vector<std::vector<std::size_t>>>& vvv_ind,
int i_dim,
const std::vector<std::vector<std::size_t>>& vec_dims,
const shape& in_s)
{
if(i_dim == vvv_ind.size())
{
std::vector<int> vec_ind;
vec_ind.resize(vec_dims.size());
std::transform(vec_dims.begin(), vec_dims.end(), vec_ind.begin(), [&](auto idx) {
return static_cast<int>(in_s.index(idx));
});
return vec_ind;
}
const auto& vv_ind = vvv_ind[i_dim];
const auto& vv_lo = vv_ind.at(0);
std::vector<std::vector<std::size_t>> vec_dims1;
for(std::size_t start = 0; start < vec_dims.size(); start += vv_lo.size())
{
std::transform(vv_lo.begin(),
vv_lo.end(),
vec_dims.begin() + start,
std::back_inserter(vec_dims1),
[](auto i, auto dim) {
dim.push_back(i);
return dim;
});
}
const auto& vv_hi = vv_ind.at(1);
for(std::size_t start = 0; start < vec_dims.size(); start += vv_lo.size())
{
std::transform(vv_hi.begin(),
vv_hi.end(),
vec_dims.begin() + start,
std::back_inserter(vec_dims1),
[](auto i, auto dim) {
dim.push_back(i);
return dim;
});
}
return calc_neighbor_points(vvv_ind, i_dim + 1, vec_dims1, in_s);
}
static std::string get_coord_trans_mode(const onnx_parser::attribute_map& attr)
{
std::string coord_trans_mode = "half_pixel";
if(contains(attr, "coordinate_transformation_mode"))
{
coord_trans_mode = attr.at("coordinate_transformation_mode").s();
// does not support transformation mode "tf_crop_and_resize"
if(coord_trans_mode == "tf_crop_and_resize")
{
MIGRAPHX_THROW("PARSE_RESIZE: \"tf_crop_and_resize\" mode is not supported!");
}
}
return coord_trans_mode;
}
static std::string get_mode(const onnx_parser::attribute_map& attr)
{
std::string mode = "nearest";
if(contains(attr, "mode"))
{
mode = attr.at("mode").s();
if(mode != "nearest" and mode != "linear")
{
MIGRAPHX_THROW("PARSE_RESIZE: only nearest and linear modes are supported!");
}
}
return mode;
}
static std::string get_nearest_mode(const onnx_parser::attribute_map& attr)
{
std::string nearest_mode = "round_prefer_floor";
if(contains(attr, "nearest_mode"))
{
nearest_mode = attr.at("nearest_mode").s();
}
return nearest_mode;
}
struct parse_resize : op_parser<parse_resize>
{
std::vector<op_desc> operators() const { return {{"Resize"}}; }
......@@ -80,42 +170,20 @@ struct parse_resize : op_parser<parse_resize>
onnx_parser::node_info info,
std::vector<instruction_ref> args) const
{
std::string coord_trans_mode = "half_pixel";
if(contains(info.attributes, "coordinate_transformation_mode"))
{
coord_trans_mode = info.attributes.at("coordinate_transformation_mode").s();
// does not support transformation mode "tf_crop_and_resize"
if(coord_trans_mode == "tf_crop_and_resize")
{
MIGRAPHX_THROW("PARSE_RESIZE: \"tf_crop_and_resize\" mode is not supported!");
}
}
// coord transform mode
std::string coord_trans_mode = get_coord_trans_mode(info.attributes);
// mode: only nearest mode is supported for now
if(contains(info.attributes, "mode"))
{
auto mode = info.attributes.at("mode").s();
if(mode != "nearest")
{
MIGRAPHX_THROW("PARSE_RESIZE: only nearest mode is supported!");
}
}
// mode: only nearest and linear modes are supported for now
std::string mode = get_mode(info.attributes);
// nearest mode
std::string nearest_mode = "round_prefer_floor";
if(contains(info.attributes, "nearest_mode"))
{
nearest_mode = info.attributes.at("nearest_mode").s();
}
std::string nearest_mode = get_nearest_mode(info.attributes);
// check exclude_outside, only support 0
if(contains(info.attributes, "exclude_outside"))
if(contains(info.attributes, "exclude_outside") and
info.attributes.at("exclude_outside").i() == 1)
{
int exclude_outside = info.attributes.at("exclude_outside").i();
if(exclude_outside == 1)
{
MIGRAPHX_THROW("PARSE_RESIZE: exclude_outside 1 is not supported!");
}
MIGRAPHX_THROW("PARSE_RESIZE: exclude_outside 1 is not supported!");
}
// input data shape info
......@@ -128,74 +196,164 @@ struct parse_resize : op_parser<parse_resize>
// scale
std::vector<double> vec_scale;
// output size is specified in input, so use it as output size
if(args.size() == 4 and args.back()->name() != "undefined")
for(const auto& arg : args)
{
auto arg_out_s = args[3]->eval();
check_arg_empty(arg_out_s, "PARSE_RESIZE: dynamic output size is not supported!");
arg_out_s.visit([&](auto ol) { out_lens.assign(ol.begin(), ol.end()); });
if(out_lens.size() != in_lens.size())
if(arg->name() == "undefined" or arg == args.front())
{
MIGRAPHX_THROW("PARSE_RESIZE: specified output size does not match input size");
continue;
}
// compute the scale
vec_scale.resize(in_lens.size());
std::transform(in_lens.begin(),
in_lens.end(),
out_lens.begin(),
vec_scale.begin(),
[](auto iss, auto oss) { return 1.0 * oss / iss; });
}
// need to compute the output lens from input
else
{
auto arg_scale = args[2]->eval();
check_arg_empty(arg_scale, "PARSE_RESIZE: dynamic input scale is not supported!");
// skipped empty input
auto lens = arg->get_shape().lens();
if(lens.empty())
{
continue;
}
arg_scale.visit([&](auto v) { vec_scale.assign(v.begin(), v.end()); });
if(in_lens.size() != vec_scale.size())
auto type = arg->get_shape().type();
// output size
if(type == shape::int64_type)
{
MIGRAPHX_THROW("PARSE_RESIZE: ranks of input and scale are different!");
auto arg_out_s = arg->eval();
check_arg_empty(arg_out_s, "PARSE_RESIZE: dynamic output size is not supported!");
arg_out_s.visit([&](auto ol) { out_lens.assign(ol.begin(), ol.end()); });
if(out_lens.size() != in_lens.size())
{
MIGRAPHX_THROW("PARSE_RESIZE: specified output size does not match input size");
}
// compute the scale
vec_scale.resize(in_lens.size());
std::transform(in_lens.begin(),
in_lens.end(),
out_lens.begin(),
vec_scale.begin(),
[](auto iss, auto oss) { return 1.0 * oss / iss; });
}
else
{
// scale input
if(lens[0] == in_lens.size())
{
auto arg_scale = arg->eval();
check_arg_empty(arg_scale,
"PARSE_RESIZE: dynamic input scale is not supported!");
std::transform(
in_lens.begin(),
in_lens.end(),
vec_scale.begin(),
out_lens.begin(),
[&](auto idx, auto scale) { return static_cast<std::size_t>(idx * scale); });
arg_scale.visit([&](auto v) { vec_scale.assign(v.begin(), v.end()); });
if(in_lens.size() != vec_scale.size())
{
MIGRAPHX_THROW("PARSE_RESIZE: ranks of input and scale are different!");
}
std::transform(in_lens.begin(),
in_lens.end(),
vec_scale.begin(),
out_lens.begin(),
[&](auto idx, auto scale) {
return static_cast<std::size_t>(idx * scale);
});
}
}
}
shape out_s{in_s.type(), out_lens};
std::vector<int> ind(out_s.elements());
std::size_t out_elements = out_s.elements();
auto idx_op = get_original_idx_op(coord_trans_mode);
// map out_idx to in_idx
auto nearest_op = get_nearest_op(nearest_mode);
auto idx_op = get_original_idx_op(coord_trans_mode);
// reshape input to one-dimension
std::vector<int64_t> rsp_lens = {static_cast<int64_t>(in_s.elements())};
args[0] = info.make_contiguous(args[0]);
auto rsp = info.add_instruction(make_op("reshape", {{"dims", rsp_lens}}), args[0]);
if(mode == "nearest")
{
std::vector<int> ind(out_elements);
// map out_idx to in_idx
auto nearest_op = get_nearest_op(nearest_mode);
shape_for_each(out_s, [&](auto idx) {
auto in_idx = idx;
for(auto ii = 0; ii < in_lens.size(); ++ii)
{
auto idx_val = idx_op(in_lens[ii], out_lens[ii], idx[ii], vec_scale[ii]);
in_idx[ii] = nearest_op(in_lens[ii], idx_val);
}
ind[out_s.index(idx)] = static_cast<int64_t>(in_s.index(in_idx));
});
shape ind_s{shape::int32_type, out_lens};
auto ins_ind = info.add_literal(literal(ind_s, ind));
return info.add_instruction(make_op("gather", {{"axis", 0}}), rsp, ins_ind);
}
// linear mode
else
{
auto nearest_floor = get_nearest_op("floor");
auto nearest_ceil = get_nearest_op("ceil");
shape_for_each(out_s, [&](auto idx) {
auto in_idx = idx;
for(auto ii = 0; ii < in_lens.size(); ++ii)
// get the number of dimensions
std::size_t n_dim = out_lens.size();
std::vector<std::vector<std::size_t>> vv_ind(2, std::vector<std::size_t>(out_elements));
std::vector<std::vector<std::vector<std::size_t>>> vvv_ind(n_dim, vv_ind);
std::vector<std::vector<float>> delta(n_dim, std::vector<float>(out_elements));
shape_for_each(out_s, [&](auto idx) {
auto in_idx = idx;
auto out_idx = out_s.index(idx);
for(auto ii = 0; ii < in_lens.size(); ++ii)
{
auto idx_val = idx_op(in_lens[ii], out_lens[ii], idx[ii], vec_scale[ii]);
vvv_ind[ii][0][out_idx] = nearest_floor(in_lens[ii], idx_val);
vvv_ind[ii][1][out_idx] = nearest_ceil(in_lens[ii], idx_val);
delta[ii][out_idx] = idx_val - vvv_ind[ii][0][out_idx];
}
});
std::vector<std::vector<std::size_t>> vec_dims(out_elements);
auto ind = calc_neighbor_points(vvv_ind, 0, vec_dims, in_s);
auto ind_lens = out_lens;
ind_lens[0] *= (std::size_t{1} << n_dim);
shape ind_s{shape::int32_type, ind_lens};
auto ins_ind = info.add_literal(literal(ind_s, ind));
auto data = info.add_instruction(make_op("gather", {{"axis", 0}}), rsp, ins_ind);
auto dim_lens = out_lens;
dim_lens[0] *= (std::size_t{1} << (n_dim - 1));
for(std::size_t i = 0; i < n_dim; ++i)
{
auto idx_val = idx_op(in_lens[ii], out_lens[ii], in_idx[ii], vec_scale[ii]);
in_idx[ii] = nearest_op(in_lens[ii], idx_val);
}
shape dim_s{shape::float_type, dim_lens};
const auto& dim_delta = delta[n_dim - i - 1];
std::vector<float> delta_data;
for(std::size_t j = 0; j < dim_lens[0] / out_lens[0]; ++j)
{
delta_data.insert(delta_data.begin(), dim_delta.begin(), dim_delta.end());
}
auto ins_delta = info.add_literal(dim_s, delta_data);
ind[out_s.index(idx)] = static_cast<int64_t>(in_s.index(in_idx));
});
// slice the data
int64_t slc_stride = static_cast<int64_t>(dim_lens[0]);
auto low = info.add_instruction(
make_op("slice", {{"axes", {0}}, {"starts", {0}}, {"ends", {slc_stride}}}),
data);
auto hi = info.add_instruction(
make_op("slice",
{{"axes", {0}}, {"starts", {slc_stride}}, {"ends", {2 * slc_stride}}}),
data);
auto diff = info.add_instruction(make_op("sub"), hi, low);
auto ddf = info.add_instruction(make_op("mul"), diff, ins_delta);
data = info.add_instruction(make_op("add"), ddf, low);
dim_lens[0] /= 2;
}
// reshape input to one-dimension
std::vector<int64_t> rsp_lens = {static_cast<int64_t>(in_s.elements())};
shape ind_s{shape::int32_type, out_lens};
auto arg_cont = info.make_contiguous(args[0]);
auto rsp = info.add_instruction(make_op("reshape", {{"dims", rsp_lens}}), arg_cont);
auto ins_ind = info.add_literal(literal(ind_s, ind));
return info.add_instruction(make_op("gather", {{"axis", 0}}), rsp, ins_ind);
return data;
}
}
};
} // namespace onnx
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
......@@ -3102,7 +3102,7 @@ def resize_downsample_f_test():
vals=scales.flatten().astype(np.float32))
X = helper.make_tensor_value_info('X', TensorProto.FLOAT, [1, 1, 2, 4])
Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, [1, 1, 1, 2])
Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, [])
node = onnx.helper.make_node(
'Resize',
......@@ -3136,6 +3136,25 @@ def resize_downsample_c_test():
return ([node], [X], [Y], [scale_tensor])
@onnx_test
def resize_downsample_linear_test():
scales = np.array([1.0, 1.0, 0.6, 0.5], dtype=np.float32)
scale_tensor = helper.make_tensor(name='scales',
data_type=TensorProto.FLOAT,
dims=scales.shape,
vals=scales.flatten().astype(np.float32))
X = helper.make_tensor_value_info('X', TensorProto.FLOAT, [1, 1, 2, 4])
Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, [])
node = onnx.helper.make_node('Resize',
inputs=['X', '', 'scales'],
outputs=['Y'],
mode='linear')
return ([node], [X], [Y], [scale_tensor])
@onnx_test
def resize_nonstd_input_test():
scales = np.array([1.0, 1.0, 0.6, 0.6], dtype=np.float32)
......@@ -3185,6 +3204,46 @@ def resize_outsize_test():
return ([node], [X], [Y], [out_lens_tensor])
@onnx_test
def resize_upsample_linear_ac_test():
scales = np.array([1.0, 1.0, 2.0, 2.0], dtype=np.float32)
scales_tensor = helper.make_tensor(name='scales',
data_type=TensorProto.FLOAT,
dims=scales.shape,
vals=scales.flatten().astype(
np.float32))
X = helper.make_tensor_value_info('X', TensorProto.FLOAT, [1, 1, 2, 2])
Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, [])
node = onnx.helper.make_node(
'Resize',
inputs=['X', '', 'scales'],
outputs=['Y'],
mode='linear',
coordinate_transformation_mode='align_corners')
return ([node], [X], [Y], [scales_tensor])
@onnx_test
def resize_upsample_linear_test():
scales = np.array([1.0, 1.0, 2.0, 2.0], dtype=np.float32)
scales_tensor = helper.make_tensor(name='scales',
data_type=TensorProto.FLOAT,
dims=scales.shape,
vals=scales.flatten().astype(
np.float32))
X = helper.make_tensor_value_info('X', TensorProto.FLOAT, [1, 1, 2, 2])
Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, [])
node = onnx.helper.make_node('Resize',
inputs=['X', '', 'scales'],
outputs=['Y'],
mode='linear')
return ([node], [X], [Y], [scales_tensor])
@onnx_test
def resize_upsample_pf_test():
scales = np.array([1.0, 1.0, 2.0, 3.0], dtype=np.float32)
......
......@@ -2670,10 +2670,11 @@ TEST_CASE(reshape_non_standard_test)
EXPECT(p == prog);
}
TEST_CASE(resize_downsample_f_test)
TEST_CASE(resize_downsample_c_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
auto* mm = p.get_main_module();
std::vector<float> ds = {1.0f, 1.0f, 0.6f, 0.6f};
migraphx::shape ss{migraphx::shape::float_type, {4}};
mm->add_literal(migraphx::literal{ss, ds});
......@@ -2684,23 +2685,22 @@ TEST_CASE(resize_downsample_f_test)
mm->add_instruction(migraphx::make_op("undefined"));
migraphx::shape si{migraphx::shape::int32_type, {1, 1, 1, 2}};
std::vector<int> ind = {4, 7};
std::vector<int> ind = {0, 2};
auto li = mm->add_literal(migraphx::literal(si, ind));
auto lrsp = mm->add_instruction(migraphx::make_op("reshape", {{"dims", {8}}}), inx);
auto r = mm->add_instruction(migraphx::make_op("gather", {{"axis", 0}}), lrsp, li);
mm->add_return({r});
auto prog = migraphx::parse_onnx("resize_downsample_f_test.onnx");
auto prog = migraphx::parse_onnx("resize_downsample_c_test.onnx");
EXPECT(p == prog);
}
TEST_CASE(resize_downsample_c_test)
TEST_CASE(resize_downsample_f_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
auto* mm = p.get_main_module();
std::vector<float> ds = {1.0f, 1.0f, 0.6f, 0.6f};
migraphx::shape ss{migraphx::shape::float_type, {4}};
mm->add_literal(migraphx::literal{ss, ds});
......@@ -2711,15 +2711,83 @@ TEST_CASE(resize_downsample_c_test)
mm->add_instruction(migraphx::make_op("undefined"));
migraphx::shape si{migraphx::shape::int32_type, {1, 1, 1, 2}};
std::vector<int> ind = {0, 2};
std::vector<int> ind = {0, 3};
auto li = mm->add_literal(migraphx::literal(si, ind));
auto lrsp = mm->add_instruction(migraphx::make_op("reshape", {{"dims", {8}}}), inx);
auto r = mm->add_instruction(migraphx::make_op("gather", {{"axis", 0}}), lrsp, li);
mm->add_return({r});
auto prog = migraphx::parse_onnx("resize_downsample_c_test.onnx");
auto prog = migraphx::parse_onnx("resize_downsample_f_test.onnx");
EXPECT(p == prog);
}
TEST_CASE(resize_downsample_linear_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
migraphx::shape ss{migraphx::shape::float_type, {4}};
std::vector<float> ds = {1, 1, 0.6, 0.5};
mm->add_literal(migraphx::literal(ss, ds));
migraphx::shape sx{migraphx::shape::float_type, {1, 1, 2, 4}};
auto x = mm->add_parameter("X", sx);
migraphx::shape s_ind{migraphx::shape::int32_type, {16, 1, 1, 2}};
std::vector<int> d_ind = {0, 2, 0, 2, 0, 2, 0, 2, 4, 6, 4, 6, 4, 6, 4, 6,
1, 3, 1, 3, 1, 3, 1, 3, 5, 7, 5, 7, 5, 7, 5, 7};
auto l_ind = mm->add_literal(migraphx::literal(s_ind, d_ind));
migraphx::shape s8{migraphx::shape::float_type, {8, 1, 1, 2}};
std::vector<float> d8(16, 0.5f);
auto l8 = mm->add_literal(migraphx::literal(s8, d8));
migraphx::shape s4{migraphx::shape::float_type, {4, 1, 1, 2}};
std::vector<float> d4(8, 1.0f / 3.0f);
auto l4 = mm->add_literal(migraphx::literal(s4, d4));
migraphx::shape s2{migraphx::shape::float_type, {2, 1, 1, 2}};
std::vector<float> d2(4, 0);
auto l2 = mm->add_literal(migraphx::literal(s2, d2));
migraphx::shape s1{migraphx::shape::float_type, {1, 1, 1, 2}};
std::vector<float> d1(2, 0.0f);
auto l1 = mm->add_literal(migraphx::literal(s1, d1));
mm->add_instruction(migraphx::make_op("undefined"));
auto rsp = mm->add_instruction(migraphx::make_op("reshape", {{"dims", {8}}}), x);
auto data = mm->add_instruction(migraphx::make_op("gather", {{"axis", 0}}), rsp, l_ind);
auto slc80 = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0}}, {"starts", {0}}, {"ends", {8}}}), data);
auto slc81 = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0}}, {"starts", {8}}, {"ends", {16}}}), data);
auto diff8 = mm->add_instruction(migraphx::make_op("sub"), slc81, slc80);
auto mul8 = mm->add_instruction(migraphx::make_op("mul"), diff8, l8);
auto add8 = mm->add_instruction(migraphx::make_op("add"), mul8, slc80);
auto slc40 = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0}}, {"starts", {0}}, {"ends", {4}}}), add8);
auto slc41 = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0}}, {"starts", {4}}, {"ends", {8}}}), add8);
auto diff4 = mm->add_instruction(migraphx::make_op("sub"), slc41, slc40);
auto mul4 = mm->add_instruction(migraphx::make_op("mul"), diff4, l4);
auto add4 = mm->add_instruction(migraphx::make_op("add"), mul4, slc40);
auto slc20 = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0}}, {"starts", {0}}, {"ends", {2}}}), add4);
auto slc21 = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0}}, {"starts", {2}}, {"ends", {4}}}), add4);
auto diff2 = mm->add_instruction(migraphx::make_op("sub"), slc21, slc20);
auto mul2 = mm->add_instruction(migraphx::make_op("mul"), diff2, l2);
auto add2 = mm->add_instruction(migraphx::make_op("add"), mul2, slc20);
auto slc10 = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0}}, {"starts", {0}}, {"ends", {1}}}), add2);
auto slc11 = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0}}, {"starts", {1}}, {"ends", {2}}}), add2);
auto diff1 = mm->add_instruction(migraphx::make_op("sub"), slc11, slc10);
auto mul1 = mm->add_instruction(migraphx::make_op("mul"), diff1, l1);
auto add1 = mm->add_instruction(migraphx::make_op("add"), mul1, slc10);
mm->add_return({add1});
auto prog = migraphx::parse_onnx("resize_downsample_linear_test.onnx");
EXPECT(p == prog);
}
......@@ -2779,6 +2847,196 @@ TEST_CASE(resize_nonstd_input_test)
EXPECT(p == prog);
}
TEST_CASE(resize_upsample_linear_ac_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
migraphx::shape ss{migraphx::shape::float_type, {4}};
std::vector<float> ds = {1, 1, 2, 2};
mm->add_literal(migraphx::literal(ss, ds));
migraphx::shape sx{migraphx::shape::float_type, {1, 1, 2, 2}};
auto x = mm->add_parameter("X", sx);
migraphx::shape s_ind{migraphx::shape::int32_type, {16, 1, 4, 4}};
std::vector<int> d_ind = {
0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 2, 2, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 2,
2, 2, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 2, 2, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0,
0, 1, 2, 2, 2, 3, 0, 0, 0, 1, 2, 2, 2, 3, 2, 2, 2, 3, 2, 2, 2, 3, 0, 0, 0, 1, 2, 2, 2,
3, 2, 2, 2, 3, 2, 2, 2, 3, 0, 0, 0, 1, 2, 2, 2, 3, 2, 2, 2, 3, 2, 2, 2, 3, 0, 0, 0, 1,
2, 2, 2, 3, 2, 2, 2, 3, 2, 2, 2, 3, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 2, 3, 3, 3, 0,
1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 2, 3, 3, 3, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 2, 3,
3, 3, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 2, 3, 3, 3, 0, 1, 1, 1, 2, 3, 3, 3, 2, 3, 3,
3, 2, 3, 3, 3, 0, 1, 1, 1, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 0, 1, 1, 1, 2, 3, 3, 3,
2, 3, 3, 3, 2, 3, 3, 3, 0, 1, 1, 1, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3};
auto l_ind = mm->add_literal(migraphx::literal(s_ind, d_ind));
migraphx::shape s8{migraphx::shape::float_type, {8, 1, 4, 4}};
std::vector<float> d8 = {
0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0,
0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0,
0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0,
0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0,
0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0,
0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0,
0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0,
0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0,
0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0,
0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0,
0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0};
auto l8 = mm->add_literal(migraphx::literal(s8, d8));
migraphx::shape s4{migraphx::shape::float_type, {4, 1, 4, 4}};
std::vector<float> d4 = {
0, 0, 0, 0, 1.0f / 3, 1.0f / 3, 1.0f / 3, 1.0f / 3,
2.0f / 3, 2.0f / 3, 2.0f / 3, 2.0f / 3, 0, 0, 0, 0,
0, 0, 0, 0, 1.0f / 3, 1.0f / 3, 1.0f / 3, 1.0f / 3,
2.0f / 3, 2.0f / 3, 2.0f / 3, 2.0f / 3, 0, 0, 0, 0,
0, 0, 0, 0, 1.0f / 3, 1.0f / 3, 1.0f / 3, 1.0f / 3,
2.0f / 3, 2.0f / 3, 2.0f / 3, 2.0f / 3, 0, 0, 0, 0,
0, 0, 0, 0, 1.0f / 3, 1.0f / 3, 1.0f / 3, 1.0f / 3,
2.0f / 3, 2.0f / 3, 2.0f / 3, 2.0f / 3, 0, 0, 0, 0};
auto l4 = mm->add_literal(migraphx::literal(s4, d4));
migraphx::shape s2{migraphx::shape::float_type, {2, 1, 4, 4}};
std::vector<float> d2(32, 0);
auto l2 = mm->add_literal(migraphx::literal(s2, d2));
migraphx::shape s1{migraphx::shape::float_type, {1, 1, 4, 4}};
std::vector<float> d1(16, 0.0f);
auto l1 = mm->add_literal(migraphx::literal(s1, d1));
mm->add_instruction(migraphx::make_op("undefined"));
auto rsp = mm->add_instruction(migraphx::make_op("reshape", {{"dims", {4}}}), x);
auto data = mm->add_instruction(migraphx::make_op("gather", {{"axis", 0}}), rsp, l_ind);
auto slc80 = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0}}, {"starts", {0}}, {"ends", {8}}}), data);
auto slc81 = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0}}, {"starts", {8}}, {"ends", {16}}}), data);
auto diff8 = mm->add_instruction(migraphx::make_op("sub"), slc81, slc80);
auto mul8 = mm->add_instruction(migraphx::make_op("mul"), diff8, l8);
auto add8 = mm->add_instruction(migraphx::make_op("add"), mul8, slc80);
auto slc40 = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0}}, {"starts", {0}}, {"ends", {4}}}), add8);
auto slc41 = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0}}, {"starts", {4}}, {"ends", {8}}}), add8);
auto diff4 = mm->add_instruction(migraphx::make_op("sub"), slc41, slc40);
auto mul4 = mm->add_instruction(migraphx::make_op("mul"), diff4, l4);
auto add4 = mm->add_instruction(migraphx::make_op("add"), mul4, slc40);
auto slc20 = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0}}, {"starts", {0}}, {"ends", {2}}}), add4);
auto slc21 = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0}}, {"starts", {2}}, {"ends", {4}}}), add4);
auto diff2 = mm->add_instruction(migraphx::make_op("sub"), slc21, slc20);
auto mul2 = mm->add_instruction(migraphx::make_op("mul"), diff2, l2);
auto add2 = mm->add_instruction(migraphx::make_op("add"), mul2, slc20);
auto slc10 = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0}}, {"starts", {0}}, {"ends", {1}}}), add2);
auto slc11 = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0}}, {"starts", {1}}, {"ends", {2}}}), add2);
auto diff1 = mm->add_instruction(migraphx::make_op("sub"), slc11, slc10);
auto mul1 = mm->add_instruction(migraphx::make_op("mul"), diff1, l1);
auto add1 = mm->add_instruction(migraphx::make_op("add"), mul1, slc10);
mm->add_return({add1});
auto prog = migraphx::parse_onnx("resize_upsample_linear_ac_test.onnx");
EXPECT(p == prog);
}
TEST_CASE(resize_upsample_linear_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
migraphx::shape ss{migraphx::shape::float_type, {4}};
std::vector<float> ds = {1, 1, 2, 2};
mm->add_literal(migraphx::literal(ss, ds));
migraphx::shape sx{migraphx::shape::float_type, {1, 1, 2, 2}};
auto x = mm->add_parameter("X", sx);
migraphx::shape s_ind{migraphx::shape::int32_type, {16, 1, 4, 4}};
std::vector<int> d_ind = {
0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 2, 2, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 2,
2, 2, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 2, 2, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0,
0, 1, 2, 2, 2, 3, 0, 0, 0, 1, 2, 2, 2, 3, 2, 2, 2, 3, 2, 2, 2, 3, 0, 0, 0, 1, 2, 2, 2,
3, 2, 2, 2, 3, 2, 2, 2, 3, 0, 0, 0, 1, 2, 2, 2, 3, 2, 2, 2, 3, 2, 2, 2, 3, 0, 0, 0, 1,
2, 2, 2, 3, 2, 2, 2, 3, 2, 2, 2, 3, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 2, 3, 3, 3, 0,
1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 2, 3, 3, 3, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 2, 3,
3, 3, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 2, 3, 3, 3, 0, 1, 1, 1, 2, 3, 3, 3, 2, 3, 3,
3, 2, 3, 3, 3, 0, 1, 1, 1, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 0, 1, 1, 1, 2, 3, 3, 3,
2, 3, 3, 3, 2, 3, 3, 3, 0, 1, 1, 1, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3};
auto l_ind = mm->add_literal(migraphx::literal(s_ind, d_ind));
migraphx::shape s8{migraphx::shape::float_type, {8, 1, 4, 4}};
std::vector<float> d8 = {
0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0,
0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0,
0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0,
0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0,
0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0,
0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0,
0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0,
0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0,
0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0,
0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0,
0, 1.0f / 3, 2.0f / 3, 0, 0, 1.0f / 3, 2.0f / 3, 0};
auto l8 = mm->add_literal(migraphx::literal(s8, d8));
migraphx::shape s4{migraphx::shape::float_type, {4, 1, 4, 4}};
std::vector<float> d4 = {
0, 0, 0, 0, 1.0f / 3, 1.0f / 3, 1.0f / 3, 1.0f / 3,
2.0f / 3, 2.0f / 3, 2.0f / 3, 2.0f / 3, 0, 0, 0, 0,
0, 0, 0, 0, 1.0f / 3, 1.0f / 3, 1.0f / 3, 1.0f / 3,
2.0f / 3, 2.0f / 3, 2.0f / 3, 2.0f / 3, 0, 0, 0, 0,
0, 0, 0, 0, 1.0f / 3, 1.0f / 3, 1.0f / 3, 1.0f / 3,
2.0f / 3, 2.0f / 3, 2.0f / 3, 2.0f / 3, 0, 0, 0, 0,
0, 0, 0, 0, 1.0f / 3, 1.0f / 3, 1.0f / 3, 1.0f / 3,
2.0f / 3, 2.0f / 3, 2.0f / 3, 2.0f / 3, 0, 0, 0, 0};
auto l4 = mm->add_literal(migraphx::literal(s4, d4));
migraphx::shape s2{migraphx::shape::float_type, {2, 1, 4, 4}};
std::vector<float> d2(32, 0);
auto l2 = mm->add_literal(migraphx::literal(s2, d2));
migraphx::shape s1{migraphx::shape::float_type, {1, 1, 4, 4}};
std::vector<float> d1(16, 0.0f);
auto l1 = mm->add_literal(migraphx::literal(s1, d1));
mm->add_instruction(migraphx::make_op("undefined"));
auto rsp = mm->add_instruction(migraphx::make_op("reshape", {{"dims", {4}}}), x);
auto data = mm->add_instruction(migraphx::make_op("gather", {{"axis", 0}}), rsp, l_ind);
auto slc80 = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0}}, {"starts", {0}}, {"ends", {8}}}), data);
auto slc81 = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0}}, {"starts", {8}}, {"ends", {16}}}), data);
auto diff8 = mm->add_instruction(migraphx::make_op("sub"), slc81, slc80);
auto mul8 = mm->add_instruction(migraphx::make_op("mul"), diff8, l8);
auto add8 = mm->add_instruction(migraphx::make_op("add"), mul8, slc80);
auto slc40 = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0}}, {"starts", {0}}, {"ends", {4}}}), add8);
auto slc41 = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0}}, {"starts", {4}}, {"ends", {8}}}), add8);
auto diff4 = mm->add_instruction(migraphx::make_op("sub"), slc41, slc40);
auto mul4 = mm->add_instruction(migraphx::make_op("mul"), diff4, l4);
auto add4 = mm->add_instruction(migraphx::make_op("add"), mul4, slc40);
auto slc20 = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0}}, {"starts", {0}}, {"ends", {2}}}), add4);
auto slc21 = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0}}, {"starts", {2}}, {"ends", {4}}}), add4);
auto diff2 = mm->add_instruction(migraphx::make_op("sub"), slc21, slc20);
auto mul2 = mm->add_instruction(migraphx::make_op("mul"), diff2, l2);
auto add2 = mm->add_instruction(migraphx::make_op("add"), mul2, slc20);
auto slc10 = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0}}, {"starts", {0}}, {"ends", {1}}}), add2);
auto slc11 = mm->add_instruction(
migraphx::make_op("slice", {{"axes", {0}}, {"starts", {1}}, {"ends", {2}}}), add2);
auto diff1 = mm->add_instruction(migraphx::make_op("sub"), slc11, slc10);
auto mul1 = mm->add_instruction(migraphx::make_op("mul"), diff1, l1);
auto add1 = mm->add_instruction(migraphx::make_op("add"), mul1, slc10);
mm->add_return({add1});
auto prog = migraphx::parse_onnx("resize_upsample_linear_test.onnx");
EXPECT(p == prog);
}
TEST_CASE(resize_upsample_pc_test)
{
migraphx::program p;
......
......@@ -240,7 +240,84 @@ TEST_CASE(lessorequal_test)
EXPECT(migraphx::verify_range(result_vector, gold));
}
TEST_CASE(resize_test)
TEST_CASE(resize_downsample_f_test)
{
migraphx::program p = migraphx::parse_onnx("resize_downsample_f_test.onnx");
p.compile(migraphx::ref::target{});
migraphx::shape sx{migraphx::shape::float_type, {1, 1, 2, 4}};
std::vector<float> dx(sx.elements());
std::iota(dx.begin(), dx.end(), 0.0f);
migraphx::parameter_map pp;
pp["X"] = migraphx::argument(sx, dx.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.0f, 3.0f};
EXPECT(migraphx::verify_range(result_vector, gold));
}
TEST_CASE(resize_upsample_linear_ac_test)
{
migraphx::program p = migraphx::parse_onnx("resize_upsample_linear_ac_test.onnx");
p.compile(migraphx::ref::target{});
migraphx::shape sx{migraphx::shape::float_type, {1, 1, 2, 2}};
std::vector<float> dx = {1.0f, 2.0f, 3.0f, 4.0f};
migraphx::parameter_map pp;
pp["X"] = migraphx::argument(sx, dx.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,
4.0f / 3,
5.0f / 3,
2,
5.0f / 3,
2,
7.0f / 3,
8.0f / 3,
7.0f / 3,
8.0f / 3,
3,
10.0f / 3,
3,
10.0f / 3,
11.0f / 3,
4};
EXPECT(migraphx::verify_range(result_vector, gold));
}
TEST_CASE(resize_upsample_linear_test)
{
migraphx::program p = migraphx::parse_onnx("resize_upsample_linear_test.onnx");
p.compile(migraphx::ref::target{});
migraphx::shape sx{migraphx::shape::float_type, {1, 1, 2, 2}};
std::vector<float> dx = {1.0f, 2.0f, 3.0f, 4.0f};
migraphx::parameter_map pp;
pp["X"] = migraphx::argument(sx, dx.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, 1.25, 1.75, 2, 1.5, 1.75, 2.25, 2.5, 2.5, 2.75, 3.25, 3.5, 3, 3.25, 3.75, 4};
EXPECT(migraphx::verify_range(result_vector, gold));
}
TEST_CASE(resize_upsample_pf_test)
{
migraphx::program p = migraphx::parse_onnx("resize_upsample_pf_test.onnx");
p.compile(migraphx::ref::target{});
......
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