Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 21 additions & 13 deletions src/onnx/parse_resize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,20 +267,28 @@ struct parse_resize : op_parser<parse_resize>
void set_aspect_ratio_policy(const onnx_parser::attribute_map& attr,
const std::vector<instruction_ref>& args) const
{
// TODO: Add support for this instead of keeping it as a check
if(contains(attr, "keep_aspect_ratio_policy"))
// Attribute introduced in opset 18; not present in opset <= 17.
if(not contains(attr, "keep_aspect_ratio_policy"))
return;

// 'stretch' is the opset-18 default and matches the existing per-axis
// semantics, so accept it as a no-op.
if(attr.at("keep_aspect_ratio_policy").s() == "stretch")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can have these as one if here and remove the above not check. Less code paths for the check and using and will guarantee if first check fails the second wont need to get checked.

Suggested change
if(attr.at("keep_aspect_ratio_policy").s() == "stretch")
if(not contains(attr, "keep_aspect_ratio_policy") and attr.at("keep_aspect_ratio_policy").s() == "stretch")

return;

// TODO: Add support for 'not_larger' and 'not_smaller' policies.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this an internal issue for us to track if this is a new TODO

shape last_arg_shape = args.back()->get_shape();
size_t last_arg_elements = last_arg_shape.elements();
// Check if the last arg is 'sizes' input.
// This attribute is only relevant if 'sizes' input is used.
// The shape constraints for 'sizes' are below:
if(last_arg_shape.type() == shape::int64_type and
(last_arg_elements == args.front()->get_shape().ndim() or
(is_axes_used() and last_arg_elements == r_attr.axes.size())))
{
shape last_arg_shape = args.back()->get_shape();
size_t last_arg_elements = last_arg_shape.elements();
// Check if the last arg is 'sizes' input.
// This attribute is only relevant if 'sizes' input is used.
// The shape constraints for 'sizes' are below:
if(last_arg_shape.type() == shape::int64_type and
(last_arg_elements == args.front()->get_shape().ndim() or
(is_axes_used() and last_arg_elements == r_attr.axes.size())))
{
MIGRAPHX_THROW("PARSE_RESIZE: keep_aspect_ratio_policy is not supported!");
}
MIGRAPHX_THROW("PARSE_RESIZE: keep_aspect_ratio_policy=\"" +
attr.at("keep_aspect_ratio_policy").s() +
"\" is not supported (only \"stretch\" is accepted)");
}
}

Expand Down
29 changes: 28 additions & 1 deletion test/onnx/gen_onnx.py
Original file line number Diff line number Diff line change
Expand Up @@ -14248,6 +14248,9 @@ def resize_upsample_pc_test():

@onnx_test()
def resize_aspect_ratio_err_test():
# The 'stretch' policy is now accepted as a no-op (matches pre-Resize-18
# semantics already implemented). This negative test exercises a policy
# value that is still unsupported.
sizes = np.array([1, 1, 3, 5], dtype=np.int64)
size_tensor = helper.make_tensor(name='sizes',
data_type=TensorProto.INT64,
Expand All @@ -14262,12 +14265,36 @@ def resize_aspect_ratio_err_test():
outputs=['Y'],
coordinate_transformation_mode='asymmetric',
mode='nearest',
keep_aspect_ratio_policy='stretch',
keep_aspect_ratio_policy='not_larger',
nearest_mode='ceil')

return ([node], [X], [Y], [size_tensor])


@onnx_test()
def resize_aspect_ratio_stretch_test():
# 'stretch' is the Resize-18 default and matches pre-18 per-axis semantics.
# ORT injects it for opset-18 exports, so the parser must accept it as a no-op.
sizes = np.array([1, 1, 4, 8], dtype=np.int64)
size_tensor = helper.make_tensor(name='sizes',
data_type=TensorProto.INT64,
dims=sizes.shape,
vals=sizes.flatten().astype(np.int64))

X = helper.make_tensor_value_info('X', TensorProto.FLOAT, [1, 1, 2, 4])
Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, [1, 1, 4, 8])

node = onnx.helper.make_node('Resize',
inputs=['X', '', '', 'sizes'],
outputs=['Y'],
coordinate_transformation_mode='asymmetric',
mode='nearest',
keep_aspect_ratio_policy='stretch',
nearest_mode='floor')

return ([node], [X], [Y], [size_tensor])


@onnx_test()
def resize_invalid_mode_test():
# Resize with unsupported mode "quadratic" should fail during parsing
Expand Down
55 changes: 55 additions & 0 deletions test/onnx/parse/resize_aspect_ratio_stretch_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2015-2026 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
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#include <onnx_test.hpp>

TEST_CASE(resize_aspect_ratio_stretch_test)
{
migraphx::program p;
auto* mm = p.get_main_module();

// These are from the ONNX file but not used by the 1-input resize
std::vector<int64_t> out_len = {1, 1, 4, 8};
migraphx::shape so{migraphx::shape::int64_type, {4}};
mm->add_literal(migraphx::literal(so, out_len));

migraphx::shape sx{migraphx::shape::float_type, {1, 1, 2, 4}};
auto inx = mm->add_parameter("X", sx);

mm->add_instruction(migraphx::make_op("undefined"));

// keep_aspect_ratio_policy="stretch" is accepted as a no-op: it is the
// Resize-18 default and matches the existing per-axis semantics.
auto r =
mm->add_instruction(migraphx::make_op("resize",
{{"sizes", {1, 1, 4, 8}},
{"nearest_mode", "floor"},
{"coordinate_transformation_mode", "asymmetric"}}),
inx);
mm->add_return({r});

auto prog = read_onnx("resize_aspect_ratio_stretch_test.onnx");

EXPECT(p == prog);
}
Binary file modified test/onnx/resize_aspect_ratio_err_test.onnx
Binary file not shown.
Binary file added test/onnx/resize_aspect_ratio_stretch_test.onnx
Binary file not shown.
Loading