From 262e5c68bbd18e19c7c40ff94727633d4c1f269c Mon Sep 17 00:00:00 2001 From: Eddie Liao Date: Tue, 5 May 2026 23:03:19 +0000 Subject: [PATCH 1/4] Add warnings for dim and value not set --- src/driver/main.cpp | 23 +++++++++++++++++++++++ src/onnx/onnx_parser.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/src/driver/main.cpp b/src/driver/main.cpp index 1e1e774b7d6..2d297e614af 100644 --- a/src/driver/main.cpp +++ b/src/driver/main.cpp @@ -64,6 +64,7 @@ #include #include +#include #include namespace { @@ -593,6 +594,25 @@ struct program_params return map_load_args; } + void warn_unset_inputs(const std::unordered_map& param_shapes) const + { + std::set load_arg_names; + for(auto&& x : load_args_info) + if(not x.empty() and x[0] == '@') + load_arg_names.insert(x.substr(1)); + std::set unset; + for(const auto& param : param_shapes) + if(not contains(param.first, "#output_") and not contains(fill0, param.first) and + not contains(fill1, param.first) and not contains(load_arg_names, param.first)) + unset.insert(param.first); + if(unset.empty()) + return; + log::warn() << "Input(s) without explicit values: " << join_strings(unset, ", ") + << ". These will be filled with random data and may cause unexpected behavior. " + "Use `--fill0 `, `--fill1 `, or " + "`--load-arg @ ` if the program fails to run."; + } + auto generate(const program& p, const target& t, bool offload, @@ -615,6 +635,9 @@ struct program_params m[s] = fill_argument(static_param_shapes.at(s), 0); for(auto&& s : fill1) m[s] = fill_argument(static_param_shapes.at(s), 1); + + warn_unset_inputs(param_shapes); + fill_param_map(m, static_param_shapes, t, offload); auto load_arg_map = program_params::parse_load_args(load_args_info, t, offload); for(auto&& arg : load_arg_map) diff --git a/src/onnx/onnx_parser.cpp b/src/onnx/onnx_parser.cpp index 38cd7827bc0..be5b87cb361 100644 --- a/src/onnx/onnx_parser.cpp +++ b/src/onnx/onnx_parser.cpp @@ -37,8 +37,10 @@ #include #include #include +#include #include #include +#include #include namespace migraphx { @@ -259,6 +261,31 @@ void onnx_parser::parse_undefined(module* mod, const std::string& name) } } +static void warn_unresolved_dim_params(const onnx_parser& parser, const onnx::GraphProto& graph) +{ + std::set unresolved; + for(const auto& input : graph.input()) + { + if(contains(parser.map_input_dims, input.name()) or + contains(parser.map_dyn_input_dims, input.name())) + continue; + for(const auto& d : input.type().tensor_type().shape().dim()) + { + // Skip batch dims and dims that are already set + if(d.has_dim_param() and not contains(parser.dim_params, d.dim_param()) and + to_lower(d.dim_param()).find("batch") == std::string::npos) + unresolved.insert(d.dim_param()); + } + } + if(unresolved.empty()) + return; + log::warn() << "Model has unbound symbolic dimension(s): " << join_strings(unresolved, ", ") + << ". These default to " << parser.default_dyn_dim_value + << " and may cause unexpected behavior. " + << "Try setting `--dim-param @ ` or `--input-dim @ ` " + "if program compilation fails."; +} + void onnx_parser::parse_from(std::istream& is, std::string name) { auto* mm = prog.get_main_module(); @@ -275,6 +302,7 @@ void onnx_parser::parse_from(std::istream& is, std::string name) if(model.has_graph()) { + warn_unresolved_dim_params(*this, model.graph()); (void)this->parse_graph(mm, model.graph()); } } @@ -295,6 +323,7 @@ void onnx_parser::parse_from(const void* data, std::size_t size) if(model.has_graph()) { + warn_unresolved_dim_params(*this, model.graph()); (void)this->parse_graph(mm, model.graph()); } } From d4c164039863b9ece0eb7227e1d10a04eca7e1c4 Mon Sep 17 00:00:00 2001 From: Eddie Liao Date: Thu, 7 May 2026 22:04:27 +0000 Subject: [PATCH 2/4] Use std::move --- src/driver/main.cpp | 2 +- src/onnx/onnx_parser.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/driver/main.cpp b/src/driver/main.cpp index 2d297e614af..69f38f87d03 100644 --- a/src/driver/main.cpp +++ b/src/driver/main.cpp @@ -607,7 +607,7 @@ struct program_params unset.insert(param.first); if(unset.empty()) return; - log::warn() << "Input(s) without explicit values: " << join_strings(unset, ", ") + log::warn() << "Input(s) without explicit values: " << join_strings(std::move(unset), ", ") << ". These will be filled with random data and may cause unexpected behavior. " "Use `--fill0 `, `--fill1 `, or " "`--load-arg @ ` if the program fails to run."; diff --git a/src/onnx/onnx_parser.cpp b/src/onnx/onnx_parser.cpp index be5b87cb361..3d386b0237d 100644 --- a/src/onnx/onnx_parser.cpp +++ b/src/onnx/onnx_parser.cpp @@ -279,9 +279,9 @@ static void warn_unresolved_dim_params(const onnx_parser& parser, const onnx::Gr } if(unresolved.empty()) return; - log::warn() << "Model has unbound symbolic dimension(s): " << join_strings(unresolved, ", ") - << ". These default to " << parser.default_dyn_dim_value - << " and may cause unexpected behavior. " + log::warn() << "Model has unbound symbolic dimension(s): " + << join_strings(std::move(unresolved), ", ") << ". These default to " + << parser.default_dyn_dim_value << " and may cause unexpected behavior. " << "Try setting `--dim-param @ ` or `--input-dim @ ` " "if program compilation fails."; } From a567dc212668b928fc906af3363f6bda03655238 Mon Sep 17 00:00:00 2001 From: Eddie Liao Date: Wed, 13 May 2026 16:43:31 +0000 Subject: [PATCH 3/4] Add warning suppresion if default dim set --- src/api/api.cpp | 2 + src/driver/main.cpp | 1 + src/include/migraphx/onnx.hpp | 1 + .../include/migraphx/onnx/onnx_parser.hpp | 1 + src/onnx/onnx.cpp | 1 + src/onnx/onnx_parser.cpp | 2 + test/api/CMakeLists.txt | 1 + test/api/test_parser_warning.cpp | 76 +++++++++++++++++++ tools/api/api.cpp | 2 + 9 files changed, 87 insertions(+) create mode 100644 test/api/test_parser_warning.cpp diff --git a/src/api/api.cpp b/src/api/api.cpp index f6115375e08..f54ab7f8a16 100644 --- a/src/api/api.cpp +++ b/src/api/api.cpp @@ -159,11 +159,13 @@ static void set_file_format(file_options& options, const char* format) { options static void set_default_dim_value(onnx_options& options, size_t value) { options.default_dim_value = value; + options.default_set = true; } static void set_default_dyn_dim_value(onnx_options& options, const shape::dynamic_dimension& dd) { options.default_dyn_dim_value = dd; + options.default_set = true; } static void set_default_loop_iterations(onnx_options& options, int64_t value) diff --git a/src/driver/main.cpp b/src/driver/main.cpp index 69f38f87d03..a6978e569db 100644 --- a/src/driver/main.cpp +++ b/src/driver/main.cpp @@ -409,6 +409,7 @@ struct loader { auto v = from_json_string(convert_to_json(default_dyn_dim)); options.default_dyn_dim_value = from_value(v); + options.default_set = true; } options.skip_unknown_operators = skip_unknown_operators; options.print_program_on_error = true; diff --git a/src/include/migraphx/onnx.hpp b/src/include/migraphx/onnx.hpp index 13745994fd7..b90cd04a149 100644 --- a/src/include/migraphx/onnx.hpp +++ b/src/include/migraphx/onnx.hpp @@ -39,6 +39,7 @@ struct onnx_options /// Default dynamic dimension size (if both default_dim_value and default_dyn_dim_value set /// parser throws) shape::dynamic_dimension default_dyn_dim_value = {1, 1}; + bool default_set = false; /// Explicitly specify the dims of an input std::unordered_map> map_input_dims = {}; /// Explicitly specify a symbolic named parameter dimension diff --git a/src/onnx/include/migraphx/onnx/onnx_parser.hpp b/src/onnx/include/migraphx/onnx/onnx_parser.hpp index 4f58cd085a9..5a2f41407f1 100644 --- a/src/onnx/include/migraphx/onnx/onnx_parser.hpp +++ b/src/onnx/include/migraphx/onnx/onnx_parser.hpp @@ -99,6 +99,7 @@ struct onnx_parser std::unordered_map instructions; program prog = program(); shape::dynamic_dimension default_dyn_dim_value = {1, 1}; + bool default_set = false; std::unordered_map> map_input_dims; std::unordered_map dim_params; std::unordered_map> map_dyn_input_dims; diff --git a/src/onnx/onnx.cpp b/src/onnx/onnx.cpp index a14b4b3c581..7bff63f8e9f 100644 --- a/src/onnx/onnx.cpp +++ b/src/onnx/onnx.cpp @@ -64,6 +64,7 @@ static program parse_onnx_from(const onnx_options& options, Ts&&... xs) { parser.default_dyn_dim_value = options.default_dyn_dim_value; } + parser.default_set = options.default_set; if(not options.map_input_dims.empty() and not options.map_dyn_input_dims.empty()) { MIGRAPHX_THROW("PARSE_ONNX_FROM: both map_input_dims and map_dyn_input_dims non-empty, only" diff --git a/src/onnx/onnx_parser.cpp b/src/onnx/onnx_parser.cpp index 3d386b0237d..34f4d9d0102 100644 --- a/src/onnx/onnx_parser.cpp +++ b/src/onnx/onnx_parser.cpp @@ -263,6 +263,8 @@ void onnx_parser::parse_undefined(module* mod, const std::string& name) static void warn_unresolved_dim_params(const onnx_parser& parser, const onnx::GraphProto& graph) { + if(parser.default_set) + return; std::set unresolved; for(const auto& input : graph.input()) { diff --git a/test/api/CMakeLists.txt b/test/api/CMakeLists.txt index 61d4211b576..a1879c7db72 100644 --- a/test/api/CMakeLists.txt +++ b/test/api/CMakeLists.txt @@ -65,6 +65,7 @@ add_api_test(op test_op_construct.cpp ${TEST_ONNX_DIR}) add_c_api_test(c_op test_c_op_construct.c ${TEST_ONNX_DIR}) add_api_test(custom_op test_custom_op.cpp ${TEST_ONNX_DIR}) add_api_test(tf_parser test_tf_parser.cpp ${TEST_TF_DIR}) +add_api_test(parser_warning test_parser_warning.cpp ${TEST_ONNX_DIR}) add_api_test(onnx_op_list test_onnx_op_list.cpp ${TEST_ONNX_DIR}) add_api_test(trace_callback test_trace_callback.cpp ${TEST_ONNX_DIR}) # GPU-based tests diff --git a/test/api/test_parser_warning.cpp b/test/api/test_parser_warning.cpp new file mode 100644 index 00000000000..6e4776d0eac --- /dev/null +++ b/test/api/test_parser_warning.cpp @@ -0,0 +1,76 @@ +/* + * 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 +#include +#include "test.hpp" + +namespace { +struct warning_sink +{ + std::vector messages; + std::size_t id; + + warning_sink() + { + id = migraphx::log::add_sink( + [this](migraphx::log::severity, std::string_view msg, migraphx::source_location) { + messages.emplace_back(msg); + }, + migraphx::log::severity::warn); + } + + ~warning_sink() { migraphx::log::remove_sink(id); } + + bool any_unbound_dim_warning() const + { + return std::any_of(messages.begin(), messages.end(), [](const std::string& m) { + return m.find("unbound symbolic dimension") != std::string::npos; + }); + } +}; +} // namespace + +TEST_CASE(set_default_dim_value_suppresses_unbound_dim_warning) +{ + warning_sink sink; + migraphx::onnx_options opts; + opts.set_default_dim_value(4); + (void)read_onnx("dim_param_test.onnx", opts); + + EXPECT(not sink.any_unbound_dim_warning()); +} + +TEST_CASE(set_default_dyn_dim_value_suppresses_unbound_dim_warning) +{ + warning_sink sink; + migraphx::onnx_options opts; + opts.set_default_dyn_dim_value(migraphx::dynamic_dimension{1, 1}); + (void)read_onnx("dim_param_test.onnx", opts); + + EXPECT(not sink.any_unbound_dim_warning()); +} + +int main(int argc, const char* argv[]) { test::run(argc, argv); } diff --git a/tools/api/api.cpp b/tools/api/api.cpp index 79f5785357e..dbd65f74fb1 100644 --- a/tools/api/api.cpp +++ b/tools/api/api.cpp @@ -159,11 +159,13 @@ static void set_file_format(file_options& options, const char* format) { options static void set_default_dim_value(onnx_options& options, size_t value) { options.default_dim_value = value; + options.default_set = true; } static void set_default_dyn_dim_value(onnx_options& options, const shape::dynamic_dimension& dd) { options.default_dyn_dim_value = dd; + options.default_set = true; } static void set_default_loop_iterations(onnx_options& options, int64_t value) From fdbbc0b9308b60441f651967d00b4086f280ce39 Mon Sep 17 00:00:00 2001 From: Eddie Liao Date: Thu, 14 May 2026 19:53:49 +0000 Subject: [PATCH 4/4] Add tests --- test/api/test_parser_warning.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/api/test_parser_warning.cpp b/test/api/test_parser_warning.cpp index 6e4776d0eac..5ad04eca758 100644 --- a/test/api/test_parser_warning.cpp +++ b/test/api/test_parser_warning.cpp @@ -73,4 +73,12 @@ TEST_CASE(set_default_dyn_dim_value_suppresses_unbound_dim_warning) EXPECT(not sink.any_unbound_dim_warning()); } +TEST_CASE(unbound_dim_param_emits_warning) +{ + warning_sink sink; + (void)read_onnx("dim_param_test.onnx"); + + EXPECT(sink.any_unbound_dim_warning()); +} + int main(int argc, const char* argv[]) { test::run(argc, argv); }