diff --git a/src/include/migraphx/op/multibroadcast.hpp b/src/include/migraphx/op/multibroadcast.hpp index 707f91bbe9b..bf6d1c2ca0a 100644 --- a/src/include/migraphx/op/multibroadcast.hpp +++ b/src/include/migraphx/op/multibroadcast.hpp @@ -29,11 +29,45 @@ #include #include #include +#include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { namespace op { +inline bool is_broadcastable_lens(std::vector s0, std::vector s1) +{ + if(s0 == s1) + return true; + if(s0.size() > s1.size()) + s0.swap(s1); + const auto offset = s1.size() - s0.size(); + return std::equal(s0.begin(), s0.end(), s1.begin() + offset, s1.end(), [](auto a, auto b) { + return a == b or a == 1 or b == 1; + }); +} + +inline std::vector +fixed_dyn_dims_lens(const std::vector& dims) +{ + std::vector target_lens; + target_lens.reserve(dims.size()); + std::transform(dims.begin(), dims.end(), std::back_inserter(target_lens), [](const auto& d) { + return shape::static_dim_value(d); + }); + return target_lens; +} + +inline shape broadcast_to_fixed_dims(const shape& s0, + shape::type_t t, + const std::vector& fixed_dims) +{ + const auto target_lens = fixed_dyn_dims_lens(fixed_dims); + if(is_broadcastable_lens(s0.lens(), target_lens)) + return make_bcast_shape(s0, compute_broadcasted_lens(s0.lens(), target_lens)); + return {t, target_lens}; +} + /** * Broadcast multiple dimensions between two tensors. * Two versions of this operator: 1 input and 2+ inputs. @@ -71,6 +105,16 @@ struct multibroadcast if(inputs.size() == 1) { + if(not output_dyn_dims.empty() and not s0.dynamic()) + { + if(std::all_of(output_dyn_dims.begin(), output_dyn_dims.end(), [](const auto& d) { + return d.is_fixed(); + })) + { + return broadcast_to_fixed_dims(s0, t, output_dyn_dims); + } + } + // Symbolic 1-input mode: opt-in via a fully-symbolic output_dyn_dims attribute. // Input may be static (bridged via to_symbolic()) or already symbolic. // Range-based dynamic input is not allowed. @@ -128,6 +172,17 @@ struct multibroadcast } else { + if(not output_dyn_dims.empty()) + { + if(std::all_of(output_dyn_dims.begin(), + output_dyn_dims.end(), + [](const auto& d) { return d.is_fixed(); })) + { + return broadcast_to_fixed_dims(s0, t, output_dyn_dims); + } + auto bcast_lens = compute_common_lens(inputs); + return make_bcast_shape(s0, bcast_lens); + } // output_lens will not be set for 2+ input version auto bcast_lens = compute_common_lens(inputs); return make_bcast_shape(s0, bcast_lens); diff --git a/src/include/migraphx/shape.hpp b/src/include/migraphx/shape.hpp index 9fca95bec28..2195dd6e9bb 100644 --- a/src/include/migraphx/shape.hpp +++ b/src/include/migraphx/shape.hpp @@ -182,7 +182,8 @@ struct MIGRAPHX_EXPORT shape { if(this->sym_expr == other.sym_expr) return *this; - return nullopt; + if(not other.is_fixed()) + return nullopt; } auto this_interval = this->get_interval(); auto other_interval = other.get_interval(); diff --git a/src/onnx/parse_expand.cpp b/src/onnx/parse_expand.cpp index e468cad1005..50c6805a1e8 100644 --- a/src/onnx/parse_expand.cpp +++ b/src/onnx/parse_expand.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2024 Advanced Micro Devices, Inc. All rights reserved. + * 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 @@ -50,14 +50,18 @@ struct parse_expand : op_parser else { const shape& shape_0 = args[0]->get_shape(); + std::vector dims; + arg_s.visit([&](auto input) { dims.assign(input.begin(), input.end()); }); if(shape_0.dynamic()) { - MIGRAPHX_THROW( - "PARSE_EXPAND: dynamic input tensor with fixed dims input not supported"); + shape target_shape{shape_0.type(), dims}; + auto out_dyn_dims = compute_broadcasted_dyn_dims(shape_0, target_shape); + return info.add_instruction( + make_op("multibroadcast", {{"out_dyn_dims", to_value(out_dyn_dims)}}), + args[0], + args[0]); } const auto& in_lens = shape_0.lens(); - std::vector dims; - arg_s.visit([&](auto input) { dims.assign(input.begin(), input.end()); }); auto out_lens = compute_broadcasted_lens(in_lens, dims); return info.add_instruction(make_op("multibroadcast", {{"out_lens", out_lens}}), args[0]); diff --git a/src/onnx/parse_shape.cpp b/src/onnx/parse_shape.cpp index 8f6115196ed..79859936cac 100644 --- a/src/onnx/parse_shape.cpp +++ b/src/onnx/parse_shape.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2025 Advanced Micro Devices, Inc. All rights reserved. + * 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 @@ -33,8 +33,7 @@ namespace onnx { /** * If static shape input, creates a literal in migraphx. - * If dynamic shape input, creates a dimensions_of operator in migraphx (runtime evaluation of - * shape). + * If dynamic shape input, creates a compile-time literal with -1 for non-fixed dimensions. */ struct parse_shape : op_parser { @@ -74,8 +73,16 @@ struct parse_shape : op_parser if(input_shape.dynamic()) { - return info.add_instruction(make_op("dimensions_of", {{"start", start}, {"end", end}}), - args[0]); + std::size_t output_ndim = end - start; + auto dyn_dims = input_shape.dyn_dims(); + std::vector vec_shape(output_ndim); + std::transform( + dyn_dims.begin() + start, + dyn_dims.begin() + end, + vec_shape.begin(), + [](const auto& dd) { return dd.is_fixed() ? dd.get_interval().max : -1; }); + return info.add_literal(migraphx::literal{ + migraphx::shape{migraphx::shape::int64_type, {output_ndim}}, vec_shape}); } else { diff --git a/src/simplify_dyn_ops.cpp b/src/simplify_dyn_ops.cpp index 6a90d97fe70..383ca2088c8 100644 --- a/src/simplify_dyn_ops.cpp +++ b/src/simplify_dyn_ops.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -146,6 +147,19 @@ struct find_static_2in_broadcasts : match::supports_dynamic_shapes { broadcast_op.from_value({{"out_lens", out_lens}}); } + else if(broadcast_op.name() == "multibroadcast") + { + const auto& mb = migraphx::any_cast(broadcast_op); + if(not mb.output_dyn_dims.empty()) + { + broadcast_op.from_value( + {{"out_lens", out_lens}, {"out_dyn_dims", to_value(mb.output_dyn_dims)}}); + } + else + { + broadcast_op.from_value({{"out_lens", out_lens}, {"out_dyn_dims", {}}}); + } + } else { broadcast_op.from_value({{"out_lens", out_lens}, {"out_dyn_dims", {}}}); diff --git a/test/onnx/expand_dyn_input_dyn_output_test.onnx b/test/onnx/expand_dyn_input_dyn_output_test.onnx index 3ce449811d8..7c7a5aa5d88 100644 Binary files a/test/onnx/expand_dyn_input_dyn_output_test.onnx and b/test/onnx/expand_dyn_input_dyn_output_test.onnx differ diff --git a/test/onnx/expand_dyn_input_static_dims_throw.onnx b/test/onnx/expand_dyn_input_static_dims_throw.onnx index 66d04e6f238..b2b785faca0 100644 Binary files a/test/onnx/expand_dyn_input_static_dims_throw.onnx and b/test/onnx/expand_dyn_input_static_dims_throw.onnx differ diff --git a/test/onnx/parse/expand_test.cpp b/test/onnx/parse/expand_test.cpp index 6933b31c768..f0bee14fa02 100644 --- a/test/onnx/parse/expand_test.cpp +++ b/test/onnx/parse/expand_test.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2024 Advanced Micro Devices, Inc. All rights reserved. + * 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 @@ -69,9 +69,23 @@ TEST_CASE(expand_dyn_input_dyn_output_test) EXPECT(p == prog); } -TEST_CASE(expand_dyn_input_static_dims_throw) +TEST_CASE(expand_dyn_input_static_dims_test) { + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s(migraphx::shape::float_type, {{3, 8}, {1, 1}, {1, 1}}); + auto param = mm->add_parameter("x", s); + mm->add_literal( + migraphx::literal(migraphx::shape{migraphx::shape::int32_type, {3}}, {3, 4, 4})); + std::vector out_dyn_dims{{3, 3}, {4, 4}, {4, 4}}; + auto ret = mm->add_instruction( + migraphx::make_op("multibroadcast", {{"out_dyn_dims", migraphx::to_value(out_dyn_dims)}}), + param, + param); + mm->add_return({ret}); + migraphx::onnx_options options; options.default_dyn_dim_value = {3, 8}; - EXPECT(test::throws([&] { read_onnx("expand_dyn_input_static_dims_throw.onnx", options); })); + auto prog = read_onnx("expand_dyn_input_static_dims_throw.onnx", options); + EXPECT(p == prog); } diff --git a/test/onnx/parse/shape_dyn_test0.cpp b/test/onnx/parse/shape_dyn_test0.cpp index aea6c056e47..ac156089234 100644 --- a/test/onnx/parse/shape_dyn_test0.cpp +++ b/test/onnx/parse/shape_dyn_test0.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2024 Advanced Micro Devices, Inc. All rights reserved. + * 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 @@ -29,9 +29,9 @@ TEST_CASE(shape_dyn_test0) migraphx::program p; auto* mm = p.get_main_module(); migraphx::shape s{migraphx::shape::float_type, {{1, 4, {1, 4}}, {4, 4}, {2, 4}, {2, 4}}}; - auto p0 = mm->add_parameter("x", s); + mm->add_parameter("x", s); migraphx::shape s_shape{migraphx::shape::int64_type, {4}}; - auto ret = mm->add_instruction(migraphx::make_op("dimensions_of", {{"end", 4}}), p0); + auto ret = mm->add_literal(migraphx::literal{s_shape, {-1, 4, -1, -1}}); mm->add_return({ret}); migraphx::onnx_options options; diff --git a/test/onnx/parse/shape_dyn_test1.cpp b/test/onnx/parse/shape_dyn_test1.cpp index 6e9c057c319..30bcb85cd44 100644 --- a/test/onnx/parse/shape_dyn_test1.cpp +++ b/test/onnx/parse/shape_dyn_test1.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2024 Advanced Micro Devices, Inc. All rights reserved. + * 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 @@ -29,10 +29,9 @@ TEST_CASE(shape_dyn_test1) migraphx::program p; auto* mm = p.get_main_module(); migraphx::shape s{migraphx::shape::float_type, {{1, 4, {1, 4}}, {4, 4}, {2, 4}, {2, 4}}}; - auto p0 = mm->add_parameter("x", s); - migraphx::shape s_shape{migraphx::shape::int64_type, {4}}; - auto ret = - mm->add_instruction(migraphx::make_op("dimensions_of", {{"start", 2}, {"end", 4}}), p0); + mm->add_parameter("x", s); + migraphx::shape s_shape{migraphx::shape::int64_type, {2}}; + auto ret = mm->add_literal(migraphx::literal{s_shape, {-1, -1}}); mm->add_return({ret}); migraphx::onnx_options options; diff --git a/test/onnx/parse/shape_dyn_test2.cpp b/test/onnx/parse/shape_dyn_test2.cpp index d9bae44760a..7c3c74e60ea 100644 --- a/test/onnx/parse/shape_dyn_test2.cpp +++ b/test/onnx/parse/shape_dyn_test2.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2024 Advanced Micro Devices, Inc. All rights reserved. + * 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 @@ -29,10 +29,9 @@ TEST_CASE(shape_dyn_test2) migraphx::program p; auto* mm = p.get_main_module(); migraphx::shape s{migraphx::shape::float_type, {{1, 4, {1, 4}}, {4, 4}, {2, 4}, {2, 4}}}; - auto p0 = mm->add_parameter("x", s); - migraphx::shape s_shape{migraphx::shape::int64_type, {4}}; - auto ret = - mm->add_instruction(migraphx::make_op("dimensions_of", {{"start", 2}, {"end", 4}}), p0); + mm->add_parameter("x", s); + migraphx::shape s_shape{migraphx::shape::int64_type, {2}}; + auto ret = mm->add_literal(migraphx::literal{s_shape, {-1, -1}}); mm->add_return({ret}); migraphx::onnx_options options; diff --git a/test/onnx/parse/shape_dyn_test3.cpp b/test/onnx/parse/shape_dyn_test3.cpp index c5bd4a4073b..871f3ff1261 100644 --- a/test/onnx/parse/shape_dyn_test3.cpp +++ b/test/onnx/parse/shape_dyn_test3.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2024 Advanced Micro Devices, Inc. All rights reserved. + * 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 @@ -29,10 +29,9 @@ TEST_CASE(shape_dyn_test3) migraphx::program p; auto* mm = p.get_main_module(); migraphx::shape s{migraphx::shape::float_type, {{1, 4, {1, 4}}, {4, 4}, {2, 4}, {2, 4}}}; - auto p0 = mm->add_parameter("x", s); - migraphx::shape s_shape{migraphx::shape::int64_type, {4}}; - auto ret = - mm->add_instruction(migraphx::make_op("dimensions_of", {{"start", 1}, {"end", 2}}), p0); + mm->add_parameter("x", s); + migraphx::shape s_shape{migraphx::shape::int64_type, {1}}; + auto ret = mm->add_literal(migraphx::literal{s_shape, {4}}); mm->add_return({ret}); migraphx::onnx_options options; diff --git a/test/onnx/parse/shape_end_oob_test.cpp b/test/onnx/parse/shape_end_oob_test.cpp index 82727995df9..c2b221ac64d 100644 --- a/test/onnx/parse/shape_end_oob_test.cpp +++ b/test/onnx/parse/shape_end_oob_test.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2024 Advanced Micro Devices, Inc. All rights reserved. + * 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 @@ -29,9 +29,9 @@ TEST_CASE(shape_end_oob_test) migraphx::program p; auto* mm = p.get_main_module(); migraphx::shape s{migraphx::shape::float_type, {{1, 4, {1, 4}}, {4, 4}, {2, 4}, {2, 4}}}; - auto p0 = mm->add_parameter("x", s); + mm->add_parameter("x", s); migraphx::shape s_shape{migraphx::shape::int64_type, {4}}; - auto ret = mm->add_instruction(migraphx::make_op("dimensions_of", {{"end", 4}}), p0); + auto ret = mm->add_literal(migraphx::literal{s_shape, {-1, 4, -1, -1}}); mm->add_return({ret}); migraphx::onnx_options options; diff --git a/test/onnx/parse/shape_start_oob_test.cpp b/test/onnx/parse/shape_start_oob_test.cpp index 06b91a6eddc..12782295c9a 100644 --- a/test/onnx/parse/shape_start_oob_test.cpp +++ b/test/onnx/parse/shape_start_oob_test.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2024 Advanced Micro Devices, Inc. All rights reserved. + * 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 @@ -29,9 +29,9 @@ TEST_CASE(shape_start_oob_test) migraphx::program p; auto* mm = p.get_main_module(); migraphx::shape s{migraphx::shape::float_type, {{1, 4, {1, 4}}, {4, 4}, {2, 4}, {2, 4}}}; - auto p0 = mm->add_parameter("x", s); + mm->add_parameter("x", s); migraphx::shape s_shape{migraphx::shape::int64_type, {4}}; - auto ret = mm->add_instruction(migraphx::make_op("dimensions_of", {{"end", 4}}), p0); + auto ret = mm->add_literal(migraphx::literal{s_shape, {-1, 4, -1, -1}}); mm->add_return({ret}); migraphx::onnx_options options; diff --git a/test/onnx/shape_dyn_test0.onnx b/test/onnx/shape_dyn_test0.onnx index fa088e90fe2..6c598540cd2 100644 Binary files a/test/onnx/shape_dyn_test0.onnx and b/test/onnx/shape_dyn_test0.onnx differ diff --git a/test/onnx/shape_dyn_test1.onnx b/test/onnx/shape_dyn_test1.onnx index b202cdc02e7..995c1a92ce2 100644 Binary files a/test/onnx/shape_dyn_test1.onnx and b/test/onnx/shape_dyn_test1.onnx differ diff --git a/test/onnx/shape_dyn_test2.onnx b/test/onnx/shape_dyn_test2.onnx index dc53adabcee..5575401e3c1 100644 Binary files a/test/onnx/shape_dyn_test2.onnx and b/test/onnx/shape_dyn_test2.onnx differ diff --git a/test/onnx/shape_dyn_test3.onnx b/test/onnx/shape_dyn_test3.onnx index 5fb2e1a7e71..19a54710329 100644 Binary files a/test/onnx/shape_dyn_test3.onnx and b/test/onnx/shape_dyn_test3.onnx differ diff --git a/test/onnx/shape_end_oob_test.onnx b/test/onnx/shape_end_oob_test.onnx index 87b3b95e274..e710839a7c8 100644 Binary files a/test/onnx/shape_end_oob_test.onnx and b/test/onnx/shape_end_oob_test.onnx differ diff --git a/test/onnx/shape_start_oob_test.onnx b/test/onnx/shape_start_oob_test.onnx index 40314dcaa33..b553b3a3c4a 100644 Binary files a/test/onnx/shape_start_oob_test.onnx and b/test/onnx/shape_start_oob_test.onnx differ diff --git a/test/onnx/verify/expand_dyn_static_dims_test.cpp b/test/onnx/verify/expand_dyn_static_dims_test.cpp new file mode 100644 index 00000000000..5669e20c9ee --- /dev/null +++ b/test/onnx/verify/expand_dyn_static_dims_test.cpp @@ -0,0 +1,61 @@ +/* + * 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 +#include +#include + +static std::vector run_onnx() +{ + migraphx::onnx_options options; + options.default_dyn_dim_value = {3, 8}; + options.use_symbolic_shapes = true; + auto p = read_onnx("expand_dyn_input_static_dims_throw.onnx", options); + p.compile(migraphx::make_target("ref")); + + migraphx::shape sx{migraphx::shape::float_type, {3, 1, 1}}; + std::vector data(sx.elements()); + std::iota(data.begin(), data.end(), 1.0f); + migraphx::parameter_map pp; + pp["x"] = migraphx::argument(sx, data.data()); + auto result = p.eval(pp).back(); + + std::vector result_vector; + result.visit([&](auto output) { result_vector.assign(output.begin(), output.end()); }); + return result_vector; +} + +TEST_CASE(expand_dyn_input_static_dims_test) +{ + std::vector gold(48); + for(std::size_t i = 0; i < 3; ++i) + { + const float v = i + 1; + std::fill_n(gold.begin() + i * 16, 16, v); + } + + auto ref_result = run_onnx(); + + EXPECT(migraphx::verify::verify_rms_range(ref_result, gold)); +} diff --git a/test/onnx/verify/shape_dyn_test.cpp b/test/onnx/verify/shape_dyn_test.cpp new file mode 100644 index 00000000000..f1d463ad1ee --- /dev/null +++ b/test/onnx/verify/shape_dyn_test.cpp @@ -0,0 +1,65 @@ +/* + * 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 +#include +#include + +TEST_CASE(shape_dyn_test0) +{ + migraphx::onnx_options options; + options.map_dyn_input_dims["x"] = {{1, 4, {1, 4}}, {4, 4}, {2, 4}, {2, 4}}; + auto p = read_onnx("shape_dyn_test0.onnx", options); + p.compile(migraphx::make_target("ref")); + + migraphx::shape sx{migraphx::shape::float_type, {2, 4, 3, 3}}; + std::vector data(sx.elements(), 1.0f); + migraphx::parameter_map pp; + pp["x"] = migraphx::argument(sx, data.data()); + auto result = p.eval(pp).back(); + + std::vector gold{-1, 4, -1, -1}; + std::vector result_vector(gold.size()); + result.visit([&](auto output) { result_vector.assign(output.begin(), output.end()); }); + EXPECT(result_vector == gold); +} + +TEST_CASE(shape_dyn_test3) +{ + migraphx::onnx_options options; + options.map_dyn_input_dims["x"] = {{1, 4, {1, 4}}, {4, 4}, {2, 4}, {2, 4}}; + auto p = read_onnx("shape_dyn_test3.onnx", options); + p.compile(migraphx::make_target("ref")); + + migraphx::shape sx{migraphx::shape::float_type, {2, 4, 3, 3}}; + std::vector data(sx.elements(), 1.0f); + migraphx::parameter_map pp; + pp["x"] = migraphx::argument(sx, data.data()); + auto result = p.eval(pp).back(); + + std::vector gold{4}; + std::vector result_vector(gold.size()); + result.visit([&](auto output) { result_vector.assign(output.begin(), output.end()); }); + EXPECT(result_vector == gold); +} diff --git a/test/verify/test_expand_dyn_static_dims.cpp b/test/verify/test_expand_dyn_static_dims.cpp new file mode 100644 index 00000000000..3ad65877b3f --- /dev/null +++ b/test/verify/test_expand_dyn_static_dims.cpp @@ -0,0 +1,46 @@ +/* + * 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 + * 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 "verify_program.hpp" +#include +#include + +// Regression: multibroadcast with fixed output_dyn_dims on a static-shape input. +// The matching expand_dyn_input_static_dims_test in test/onnx/verify/ keeps the +// ONNX parser path honest end-to-end from the ONNX parser. +struct test_expand_dyn_static_dims : verify_program +{ + migraphx::program create_program() const + { + migraphx::program p; + auto* mm = p.get_main_module(); + migraphx::shape s{migraphx::shape::float_type, {3, 1, 1}}; + auto param = mm->add_parameter("x", s); + std::vector out_dyn_dims{{3, 3}, {4, 4}, {4, 4}}; + auto ret = mm->add_instruction( + migraphx::make_op("multibroadcast", + {{"out_dyn_dims", migraphx::to_value(out_dyn_dims)}}), + param); + mm->add_return({ret}); + return p; + } +};