From 04014571a28fbf6d5449b078d8f1a9beaf53df16 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 7 Oct 2025 08:32:23 -0500 Subject: [PATCH 01/70] implementing op builder for binary operators --- src/onnx/parse_binary_op.cpp | 33 +++++------- src/op/builder/binary.cpp | 98 ++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 21 deletions(-) create mode 100644 src/op/builder/binary.cpp diff --git a/src/onnx/parse_binary_op.cpp b/src/onnx/parse_binary_op.cpp index 58d01a566dd..7a0cf96c89d 100644 --- a/src/onnx/parse_binary_op.cpp +++ b/src/onnx/parse_binary_op.cpp @@ -23,8 +23,7 @@ */ #include #include -#include -#include +#include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { @@ -52,31 +51,23 @@ struct parse_binary_op : op_parser { if(args.size() != 2) MIGRAPHX_THROW("binary operators should have 2 operands"); + + value options = {}; if(contains(info.attributes, "broadcast") and contains(info.attributes, "axis")) { - uint64_t broadcasted = - parser.parse_value(info.attributes.at("broadcast")).at(); + options.insert({"is_broadcasted", true}); + + const uint64_t broadcasted = parser.parse_value(info.attributes.at("broadcast")).at(); + options.insert({"broadcasted", broadcasted}); + if(broadcasted != 0) { - if(std::any_of( - args.cbegin(), args.cend(), [](auto a) { return a->get_shape().dynamic(); })) - { - MIGRAPHX_THROW( - "Binary op broadcast attribute not supported for dynamic input shapes"); - } - uint64_t axis = parser.parse_value(info.attributes.at("axis")).at(); - auto l = info.add_instruction( - make_op("broadcast", - {{"axis", axis}, {"out_lens", args[0]->get_shape().lens()}}), - args[1]); - return info.add_instruction(make_op(opd.op_name), args[0], l); + const uint64_t axis = parser.parse_value(info.attributes.at("axis")).at(); + options.insert({"axis", axis}); } - return info.add_instruction(make_op(opd.op_name), args); - } - else - { - return info.add_broadcastable_binary_op(opd.op_name, args[0], args[1]); } + + return op::builder::add(opd.op_name, *info.mod, args, options).at(0); } }; diff --git a/src/op/builder/binary.cpp b/src/op/builder/binary.cpp new file mode 100644 index 00000000000..7ec42212f5d --- /dev/null +++ b/src/op/builder/binary.cpp @@ -0,0 +1,98 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2025 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 + +namespace migraphx { +inline namespace MIGRAPHX_INLINE_NS { +namespace op { +namespace builder { + +template +struct binary_base : op_builder +{ + uint64_t broadcasted = 0; + uint64_t axis = 0; + bool is_broadcasted = false; + + template + static auto reflect(Self& self, F f) + { + return pack(f(self.broadcasted, "broadcasted"), + f(self.axis, "axis"), + f(self.is_broadcasted, "is_broadcasted")); + } + + std::vector + insert(module& m, instruction_ref ins, const std::vector& args) const + { + if (is_broadcasted) + { + if (broadcasted != 0) + { + if(std::any_of(args.cbegin(), args.cend(), [](auto a) { return a->get_shape().dynamic(); })) + { + MIGRAPHX_THROW("Binary op broadcast attribute not supported for dynamic input shapes"); + } + auto l = m.add_instruction(migraphx::make_op("broadcast",{{"axis", axis}, {"out_lens", args[0]->get_shape().lens()}}),args[1]); + return {m.add_instruction(migraphx::make_op(Derived::name()), args[0], l)}; + } + return {m.add_instruction(migraphx::make_op(Derived::name()), args)}; + } + else + { + return {insert_common_op(m, ins, migraphx::make_op(Derived::name()), {args[0], args[1]})}; + } + } +}; + +#define DECLARE_BINARY_OP_BUILDER(op_name) \ +struct op_name : binary_base \ +{ \ + static std::string name() { return #op_name; } \ +\ + std::vector \ + insert(module& m, instruction_ref ins, const std::vector& args) \ + { \ + return binary_base::insert(m, ins, args); \ + } \ +}; + +DECLARE_BINARY_OP_BUILDER(add) +DECLARE_BINARY_OP_BUILDER(div) +DECLARE_BINARY_OP_BUILDER(logical_and) +DECLARE_BINARY_OP_BUILDER(logical_or) +DECLARE_BINARY_OP_BUILDER(logical_xor) +DECLARE_BINARY_OP_BUILDER(bitwise_and) +DECLARE_BINARY_OP_BUILDER(mul) +DECLARE_BINARY_OP_BUILDER(prelu) +DECLARE_BINARY_OP_BUILDER(sub) + +} // namespace builder +} // namespace op +} // namespace MIGRAPHX_INLINE_NS +} // namespace migraphx From cad9f1850f79a348ad02dc5587a5ea672bbeaf98 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 7 Oct 2025 08:55:18 -0500 Subject: [PATCH 02/70] removing macro magic; adding the operator name as a parameter for the op-builder class --- src/onnx/parse_binary_op.cpp | 6 ++++-- src/op/builder/binary.cpp | 42 ++++++++++++------------------------ 2 files changed, 18 insertions(+), 30 deletions(-) diff --git a/src/onnx/parse_binary_op.cpp b/src/onnx/parse_binary_op.cpp index 7a0cf96c89d..46bdb3e4358 100644 --- a/src/onnx/parse_binary_op.cpp +++ b/src/onnx/parse_binary_op.cpp @@ -53,6 +53,8 @@ struct parse_binary_op : op_parser MIGRAPHX_THROW("binary operators should have 2 operands"); value options = {}; + options.insert({"op_name", opd.op_name}); + if(contains(info.attributes, "broadcast") and contains(info.attributes, "axis")) { options.insert({"is_broadcasted", true}); @@ -66,8 +68,8 @@ struct parse_binary_op : op_parser options.insert({"axis", axis}); } } - - return op::builder::add(opd.op_name, *info.mod, args, options).at(0); + + return op::builder::add("binary", *info.mod, args, options).at(0); } }; diff --git a/src/op/builder/binary.cpp b/src/op/builder/binary.cpp index 7ec42212f5d..061639c2be9 100644 --- a/src/op/builder/binary.cpp +++ b/src/op/builder/binary.cpp @@ -32,24 +32,32 @@ inline namespace MIGRAPHX_INLINE_NS { namespace op { namespace builder { -template -struct binary_base : op_builder +struct binary : op_builder { uint64_t broadcasted = 0; uint64_t axis = 0; bool is_broadcasted = false; + std::string op_name = ""; + + static std::string name() { return "binary"; } template static auto reflect(Self& self, F f) { return pack(f(self.broadcasted, "broadcasted"), f(self.axis, "axis"), - f(self.is_broadcasted, "is_broadcasted")); + f(self.is_broadcasted, "is_broadcasted"), + f(self.op_name, "op_name")); } std::vector insert(module& m, instruction_ref ins, const std::vector& args) const { + if (op_name.empty()) + { + MIGRAPHX_THROW("Binary op missing op_name attribute"); + } + if (is_broadcasted) { if (broadcasted != 0) @@ -59,39 +67,17 @@ struct binary_base : op_builder MIGRAPHX_THROW("Binary op broadcast attribute not supported for dynamic input shapes"); } auto l = m.add_instruction(migraphx::make_op("broadcast",{{"axis", axis}, {"out_lens", args[0]->get_shape().lens()}}),args[1]); - return {m.add_instruction(migraphx::make_op(Derived::name()), args[0], l)}; + return {m.add_instruction(migraphx::make_op(op_name), args[0], l)}; } - return {m.add_instruction(migraphx::make_op(Derived::name()), args)}; + return {m.add_instruction(migraphx::make_op(op_name), args)}; } else { - return {insert_common_op(m, ins, migraphx::make_op(Derived::name()), {args[0], args[1]})}; + return {insert_common_op(m, ins, migraphx::make_op(op_name), {args[0], args[1]})}; } } }; -#define DECLARE_BINARY_OP_BUILDER(op_name) \ -struct op_name : binary_base \ -{ \ - static std::string name() { return #op_name; } \ -\ - std::vector \ - insert(module& m, instruction_ref ins, const std::vector& args) \ - { \ - return binary_base::insert(m, ins, args); \ - } \ -}; - -DECLARE_BINARY_OP_BUILDER(add) -DECLARE_BINARY_OP_BUILDER(div) -DECLARE_BINARY_OP_BUILDER(logical_and) -DECLARE_BINARY_OP_BUILDER(logical_or) -DECLARE_BINARY_OP_BUILDER(logical_xor) -DECLARE_BINARY_OP_BUILDER(bitwise_and) -DECLARE_BINARY_OP_BUILDER(mul) -DECLARE_BINARY_OP_BUILDER(prelu) -DECLARE_BINARY_OP_BUILDER(sub) - } // namespace builder } // namespace op } // namespace MIGRAPHX_INLINE_NS From 0b1673304c8402538c437f118f4479bf90534436 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 7 Oct 2025 10:33:16 -0500 Subject: [PATCH 03/70] testing framwork for op builders --- test/CMakeLists.txt | 6 ++- test/op/CMakeLists.txt | 30 ++++++++++++++ test/op/builder/main.cpp | 26 ++++++++++++ test/op/include/op_builder_test_utils.hpp | 49 +++++++++++++++++++++++ 4 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 test/op/CMakeLists.txt create mode 100644 test/op/builder/main.cpp create mode 100644 test/op/include/op_builder_test_utils.hpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c14e4091c22..5d55331a1c3 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,7 +1,7 @@ # #################################################################################### # The MIT License (MIT) # -# Copyright (c) 2015-2024 Advanced Micro Devices, Inc. All rights reserved. +# Copyright (c) 2015-2025 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 @@ -96,6 +96,10 @@ if(MIGRAPHX_ENABLE_PYTHON) add_subdirectory(py) endif() +# Op builder test +set(TEST_OP_BUILDER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/op) +add_subdirectory(op) + # multitarget test if(MIGRAPHX_ENABLE_GPU AND MIGRAPHX_ENABLE_CPU AND MIGRAPHX_ENABLE_FPGA) set(TEST_MULTI_TARGET_DIR ${CMAKE_CURRENT_SOURCE_DIR}/multi_target) diff --git a/test/op/CMakeLists.txt b/test/op/CMakeLists.txt new file mode 100644 index 00000000000..e850f58b94f --- /dev/null +++ b/test/op/CMakeLists.txt @@ -0,0 +1,30 @@ +##################################################################################### +# The MIT License (MIT) +# +# Copyright (c) 2015-2025 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. +##################################################################################### + +file(GLOB OP_BUILDER_TESTS CONFIGURE_DEPENDS builder/*.cpp) + +rocm_add_test_executable(test_op_builder_test ${OP_BUILDER_TESTS}) +target_include_directories(test_op_builder_test PUBLIC ../include include) +target_link_libraries(test_op_builder_test migraphx migraphx_ref) +rocm_clang_tidy_check(test_op_builder_test) diff --git a/test/op/builder/main.cpp b/test/op/builder/main.cpp new file mode 100644 index 00000000000..4761f5c1d7b --- /dev/null +++ b/test/op/builder/main.cpp @@ -0,0 +1,26 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2025 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 "test.hpp" + +int main(int argc, const char* argv[]) { test::run(argc, argv); } \ No newline at end of file diff --git a/test/op/include/op_builder_test_utils.hpp b/test/op/include/op_builder_test_utils.hpp new file mode 100644 index 00000000000..879a8a1b7b4 --- /dev/null +++ b/test/op/include/op_builder_test_utils.hpp @@ -0,0 +1,49 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2025 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. + */ + +#ifndef MIGRAPHX_GUARD_TEST_OPBUILDER_TEST_UTILS_HPP +#define MIGRAPHX_GUARD_TEST_OPBUILDER_TEST_UTILS_HPP + +#include +#include +#include + +inline migraphx::module make_op_module(const std::string& op_builder_name, + const migraphx::value& options, + const std::vector& params) +{ + migraphx::module mm_op_built; + + const std::vector& args{params.rbegin(), params.rend()}; + mm_op_built.add_instructions(args); + + const auto& params2 = mm_op_built.get_parameters(); + const std::vector& args2{params2.rbegin(), params2.rend()}; + + migraphx::op::builder::add(op_builder_name, mm_op_built, args2, options); + + return mm_op_built; +} + +#endif From 7a26766f8b33e7060544a7ea5188b55ace89d8d7 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 7 Oct 2025 10:34:07 -0500 Subject: [PATCH 04/70] adding unit tests for the binary op-builder --- test/op/builder/binary_test.cpp | 91 +++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 test/op/builder/binary_test.cpp diff --git a/test/op/builder/binary_test.cpp b/test/op/builder/binary_test.cpp new file mode 100644 index 00000000000..a1bac48a974 --- /dev/null +++ b/test/op/builder/binary_test.cpp @@ -0,0 +1,91 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2025 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 + +TEST_CASE(binary_no_op_name_specified_test) +{ + migraphx::module mm; + + EXPECT(test::throws( + [&] { make_op_module("binary", {}, mm.get_parameters()); }, + "Binary op missing op_name attribute")); +} + +TEST_CASE(binary_dynamic_input_shape_test) +{ + migraphx::module mm; + + migraphx::shape::dynamic_dimension dd{1, 4}; + std::vector dyn_dims{dd, dd}; + + mm.add_parameter("a", {migraphx::shape::float_type, dyn_dims}); + mm.add_parameter("b", {migraphx::shape::float_type, dyn_dims}); + + EXPECT(test::throws( + [&] { make_op_module("binary", + {{"op_name", "DONTCARE"}, {"is_broadcasted", true}, {"broadcasted", 1}}, + mm.get_parameters()); }, + "Binary op broadcast attribute not supported for dynamic input shapes")); +} + +TEST_CASE(binary_not_broadcasted_test) +{ + migraphx::module mm; + auto a_arg = mm.add_parameter("a", {migraphx::shape::float_type, {2, 4}}); + auto b_arg = mm.add_parameter("b", {migraphx::shape::float_type, {2, 4}}); + + add_common_op(mm, migraphx::make_op("add"), {a_arg, b_arg}); + + EXPECT(mm == make_op_module("binary", + {{"op_name", "add"}}, + mm.get_parameters())); +} + +TEST_CASE(binary_zero_broadcasted_test) +{ + migraphx::module mm; + auto a_arg = mm.add_parameter("a", {migraphx::shape::float_type, {2, 4}}); + auto b_arg = mm.add_parameter("b", {migraphx::shape::float_type, {2, 4}}); + + mm.add_instruction(migraphx::make_op("add"), {a_arg, b_arg}); + + EXPECT(mm == make_op_module("binary", + {{"op_name", "add"}, {"is_broadcasted", true}, {"broadcasted", 0}}, + mm.get_parameters())); +} + +TEST_CASE(binary_non_zero_broadcasted_test) +{ + migraphx::module mm; + auto a_arg = mm.add_parameter("a", {migraphx::shape::float_type, {2, 4}}); + auto b_arg = mm.add_parameter("b", {migraphx::shape::float_type, {2, 4}}); + + auto l = mm.add_instruction(migraphx::make_op("broadcast",{{"axis", 0}, {"out_lens", {2, 4}}}), b_arg); + mm.add_instruction(migraphx::make_op("add"), {a_arg, l}); + + EXPECT(mm == make_op_module("binary", + {{"op_name", "add"}, {"is_broadcasted", true}, {"broadcasted", 1}, {"axis", 0}}, + mm.get_parameters())); +} From a65f30cd923bac9b8efc651552ba8c96966088d2 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Sun, 12 Oct 2025 10:28:21 -0500 Subject: [PATCH 05/70] modifying op-builder registration: op-builders will be able to register multiple numbers of op-builders --- src/onnx/parse_binary_op.cpp | 4 +- src/op/builder/binary.cpp | 13 +---- .../migraphx/op/builder/op_builder.hpp | 55 +++++++++++++++---- 3 files changed, 47 insertions(+), 25 deletions(-) diff --git a/src/onnx/parse_binary_op.cpp b/src/onnx/parse_binary_op.cpp index 46bdb3e4358..7631bb8b6d7 100644 --- a/src/onnx/parse_binary_op.cpp +++ b/src/onnx/parse_binary_op.cpp @@ -53,8 +53,6 @@ struct parse_binary_op : op_parser MIGRAPHX_THROW("binary operators should have 2 operands"); value options = {}; - options.insert({"op_name", opd.op_name}); - if(contains(info.attributes, "broadcast") and contains(info.attributes, "axis")) { options.insert({"is_broadcasted", true}); @@ -69,7 +67,7 @@ struct parse_binary_op : op_parser } } - return op::builder::add("binary", *info.mod, args, options).at(0); + return op::builder::add(opd.op_name, *info.mod, args, options).at(0); } }; diff --git a/src/op/builder/binary.cpp b/src/op/builder/binary.cpp index 061639c2be9..2e25b8e38e4 100644 --- a/src/op/builder/binary.cpp +++ b/src/op/builder/binary.cpp @@ -37,27 +37,20 @@ struct binary : op_builder uint64_t broadcasted = 0; uint64_t axis = 0; bool is_broadcasted = false; - std::string op_name = ""; - static std::string name() { return "binary"; } + static std::vector names() { return {"add", "div", "logical_and", "logical_or", "logical_xor", "bitwise_and", "mul", "prelu", "sub"}; } template static auto reflect(Self& self, F f) { return pack(f(self.broadcasted, "broadcasted"), f(self.axis, "axis"), - f(self.is_broadcasted, "is_broadcasted"), - f(self.op_name, "op_name")); + f(self.is_broadcasted, "is_broadcasted")); } std::vector - insert(module& m, instruction_ref ins, const std::vector& args) const + insert(const std::string& op_name, module& m, instruction_ref ins, const std::vector& args) const { - if (op_name.empty()) - { - MIGRAPHX_THROW("Binary op missing op_name attribute"); - } - if (is_broadcasted) { if (broadcasted != 0) diff --git a/src/op/builder/include/migraphx/op/builder/op_builder.hpp b/src/op/builder/include/migraphx/op/builder/op_builder.hpp index f3a651e56dc..bc8320379db 100644 --- a/src/op/builder/include/migraphx/op/builder/op_builder.hpp +++ b/src/op/builder/include/migraphx/op/builder/op_builder.hpp @@ -46,7 +46,8 @@ using builder_func = MIGRAPHX_EXPORT void register_builder(const std::string& name, builder_func f); template -auto invoke_builder(module& m, +auto invoke_builder(std::string /*name*/, + module& m, instruction_ref ins, const std::vector& args, const std::vector& module_args, @@ -57,7 +58,8 @@ auto invoke_builder(module& m, } template -auto invoke_builder(module& m, +auto invoke_builder(std::string /*name*/, + module& m, instruction_ref ins, const std::vector& args, const std::vector& module_args, @@ -69,17 +71,46 @@ auto invoke_builder(module& m, return x.insert(m, ins, args); } +template +auto invoke_builder(std::string name, + module& m, + instruction_ref ins, + const std::vector& args, + const std::vector& module_args, + const value& options) -> decltype(T{}.insert(name, m, ins, args, module_args)) +{ + auto x = from_value(options); + return x.insert(name, m, ins, args, module_args); +} + +template +auto invoke_builder(std::string name, + module& m, + instruction_ref ins, + const std::vector& args, + const std::vector& module_args, + const value& options) -> decltype(T{}.insert(name, m, ins, args)) +{ + if(not module_args.empty()) + MIGRAPHX_THROW("Module args should be empty"); + auto x = from_value(options); + return x.insert(name, m, ins, args); +} + template void register_builder() { - builder_func f = [](module& m, - instruction_ref ins, - const std::vector& args, - const std::vector& module_args, - const value& options) { - return invoke_builder(m, ins, args, module_args, options); - }; - register_builder(T::name(), std::move(f)); + for(const auto& name:T::names()) + { + builder_func f = [=](module& m, + instruction_ref ins, + const std::vector& args, + const std::vector& module_args, + const value& options) { + return invoke_builder(name, m, ins, args, module_args, options); + }; + register_builder(name, std::move(f)); + } } struct register_builder_action @@ -94,10 +125,10 @@ struct register_builder_action template struct op_builder : auto_register { - static std::string name() + static std::vector names() { static const std::string& name = get_type_name(); - return name.substr(name.rfind("::") + 2); + return {name.substr(name.rfind("::") + 2)}; } }; From 3e98d881e4fc352179a09817da223d8a94f424f2 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Sun, 12 Oct 2025 11:19:35 -0500 Subject: [PATCH 06/70] change the way how we invoke insert_common_op. so we can see that it is essentially the same how add_instruction is called a few lines above --- src/op/builder/binary.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/op/builder/binary.cpp b/src/op/builder/binary.cpp index 2e25b8e38e4..61fa35965e1 100644 --- a/src/op/builder/binary.cpp +++ b/src/op/builder/binary.cpp @@ -66,7 +66,7 @@ struct binary : op_builder } else { - return {insert_common_op(m, ins, migraphx::make_op(op_name), {args[0], args[1]})}; + return {insert_common_op(m, ins, migraphx::make_op(op_name), args)}; } } }; From 8819399c60861eb8719e2f7953d6c9123c26cd72 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Mon, 13 Oct 2025 02:02:46 -0500 Subject: [PATCH 07/70] changing test; op_name parameter has been removed. also making sure that the tests run not for only one kind of binary operator --- test/op/builder/binary_test.cpp | 48 ++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/test/op/builder/binary_test.cpp b/test/op/builder/binary_test.cpp index a1bac48a974..c0ac1d81952 100644 --- a/test/op/builder/binary_test.cpp +++ b/test/op/builder/binary_test.cpp @@ -23,19 +23,21 @@ */ #include +#include -TEST_CASE(binary_no_op_name_specified_test) +std::string pick_op_name() { - migraphx::module mm; - - EXPECT(test::throws( - [&] { make_op_module("binary", {}, mm.get_parameters()); }, - "Binary op missing op_name attribute")); + static const std::vector op_names_set{"add", "div", "logical_and", "logical_or", "logical_xor", "bitwise_and", "mul", "prelu", "sub"}; + static std::random_device rd; + static std::mt19937 gen(rd()); + static std::uniform_int_distribution<> dis(0, op_names_set.size() - 1); + return op_names_set[dis(gen)]; } TEST_CASE(binary_dynamic_input_shape_test) { migraphx::module mm; + const std::string& op_name = pick_op_name(); migraphx::shape::dynamic_dimension dd{1, 4}; std::vector dyn_dims{dd, dd}; @@ -44,8 +46,8 @@ TEST_CASE(binary_dynamic_input_shape_test) mm.add_parameter("b", {migraphx::shape::float_type, dyn_dims}); EXPECT(test::throws( - [&] { make_op_module("binary", - {{"op_name", "DONTCARE"}, {"is_broadcasted", true}, {"broadcasted", 1}}, + [&] { make_op_module(op_name, + {{"is_broadcasted", true}, {"broadcasted", 1}}, mm.get_parameters()); }, "Binary op broadcast attribute not supported for dynamic input shapes")); } @@ -53,39 +55,43 @@ TEST_CASE(binary_dynamic_input_shape_test) TEST_CASE(binary_not_broadcasted_test) { migraphx::module mm; + const std::string& op_name = pick_op_name(); + auto a_arg = mm.add_parameter("a", {migraphx::shape::float_type, {2, 4}}); auto b_arg = mm.add_parameter("b", {migraphx::shape::float_type, {2, 4}}); - add_common_op(mm, migraphx::make_op("add"), {a_arg, b_arg}); + add_common_op(mm, migraphx::make_op(op_name), {a_arg, b_arg}); - EXPECT(mm == make_op_module("binary", - {{"op_name", "add"}}, - mm.get_parameters())); + EXPECT(mm == make_op_module(op_name, {}, mm.get_parameters())); } TEST_CASE(binary_zero_broadcasted_test) { migraphx::module mm; + const std::string& op_name = pick_op_name(); + auto a_arg = mm.add_parameter("a", {migraphx::shape::float_type, {2, 4}}); auto b_arg = mm.add_parameter("b", {migraphx::shape::float_type, {2, 4}}); - mm.add_instruction(migraphx::make_op("add"), {a_arg, b_arg}); + mm.add_instruction(migraphx::make_op(op_name), {a_arg, b_arg}); - EXPECT(mm == make_op_module("binary", - {{"op_name", "add"}, {"is_broadcasted", true}, {"broadcasted", 0}}, + EXPECT(mm == make_op_module(op_name, + {{"is_broadcasted", true}, {"broadcasted", 0}}, mm.get_parameters())); } TEST_CASE(binary_non_zero_broadcasted_test) { migraphx::module mm; - auto a_arg = mm.add_parameter("a", {migraphx::shape::float_type, {2, 4}}); - auto b_arg = mm.add_parameter("b", {migraphx::shape::float_type, {2, 4}}); + const std::string& op_name = pick_op_name(); + + auto a_arg = mm.add_parameter("a", {migraphx::shape::float_type, {2, 3, 4, 5}}); + auto b_arg = mm.add_parameter("b", {migraphx::shape::float_type, {3, 4}}); - auto l = mm.add_instruction(migraphx::make_op("broadcast",{{"axis", 0}, {"out_lens", {2, 4}}}), b_arg); - mm.add_instruction(migraphx::make_op("add"), {a_arg, l}); + auto l = mm.add_instruction(migraphx::make_op("broadcast",{{"axis", 1}, {"out_lens", {2, 3, 4, 5}}}), b_arg); + mm.add_instruction(migraphx::make_op(op_name), {a_arg, l}); - EXPECT(mm == make_op_module("binary", - {{"op_name", "add"}, {"is_broadcasted", true}, {"broadcasted", 1}, {"axis", 0}}, + EXPECT(mm == make_op_module(op_name, + {{"is_broadcasted", true}, {"broadcasted", 1}, {"axis", 1}}, mm.get_parameters())); } From 2658ef67b5d7131cbbbb34292a371707582de81f Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Mon, 13 Oct 2025 02:35:10 -0500 Subject: [PATCH 08/70] add implicit broadcast test --- test/op/builder/binary_test.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/op/builder/binary_test.cpp b/test/op/builder/binary_test.cpp index c0ac1d81952..27a7cc3edd0 100644 --- a/test/op/builder/binary_test.cpp +++ b/test/op/builder/binary_test.cpp @@ -65,6 +65,20 @@ TEST_CASE(binary_not_broadcasted_test) EXPECT(mm == make_op_module(op_name, {}, mm.get_parameters())); } +TEST_CASE(binary_not_broadcasted_implicit_broadcast) +{ + migraphx::module mm; + const std::string& op_name = pick_op_name(); + + auto a_arg = mm.add_parameter("a", {migraphx::shape::float_type, {2, 4}}); + auto b_arg = mm.add_parameter("b", {migraphx::shape::float_type, {2, 1}}); + + add_common_op(mm, migraphx::make_op(op_name), {a_arg, b_arg}); + + EXPECT(mm == make_op_module(op_name, {}, mm.get_parameters())); +} + + TEST_CASE(binary_zero_broadcasted_test) { migraphx::module mm; From 2719c04c513d9df4d602347f39b8de515a21368e Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Mon, 13 Oct 2025 03:07:54 -0500 Subject: [PATCH 09/70] removing broadcast and is_broadcasted parameter; also making the axis parameter optional on the op-builder side --- src/onnx/parse_binary_op.cpp | 12 ++++++----- src/op/builder/binary.cpp | 22 +++++-------------- test/op/builder/binary_test.cpp | 38 +-------------------------------- 3 files changed, 13 insertions(+), 59 deletions(-) diff --git a/src/onnx/parse_binary_op.cpp b/src/onnx/parse_binary_op.cpp index 7631bb8b6d7..b546c590000 100644 --- a/src/onnx/parse_binary_op.cpp +++ b/src/onnx/parse_binary_op.cpp @@ -24,6 +24,7 @@ #include #include #include +#include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { @@ -55,15 +56,16 @@ struct parse_binary_op : op_parser value options = {}; if(contains(info.attributes, "broadcast") and contains(info.attributes, "axis")) { - options.insert({"is_broadcasted", true}); - const uint64_t broadcasted = parser.parse_value(info.attributes.at("broadcast")).at(); - options.insert({"broadcasted", broadcasted}); - if(broadcasted != 0) { + if (std::any_of(args.cbegin(), args.cend(), [](auto a) { return a->get_shape().dynamic(); })) + { + MIGRAPHX_THROW("Binary op broadcast attribute not supported for dynamic input shapes"); + } + const uint64_t axis = parser.parse_value(info.attributes.at("axis")).at(); - options.insert({"axis", axis}); + options.insert({"broadcasted_axis", axis}); } } diff --git a/src/op/builder/binary.cpp b/src/op/builder/binary.cpp index 61fa35965e1..ed64004d0f4 100644 --- a/src/op/builder/binary.cpp +++ b/src/op/builder/binary.cpp @@ -34,35 +34,23 @@ namespace builder { struct binary : op_builder { - uint64_t broadcasted = 0; - uint64_t axis = 0; - bool is_broadcasted = false; + std::optional broadcasted_axis = std::nullopt; static std::vector names() { return {"add", "div", "logical_and", "logical_or", "logical_xor", "bitwise_and", "mul", "prelu", "sub"}; } template static auto reflect(Self& self, F f) { - return pack(f(self.broadcasted, "broadcasted"), - f(self.axis, "axis"), - f(self.is_broadcasted, "is_broadcasted")); + return pack(f(self.broadcasted_axis, "broadcasted_axis")); } std::vector insert(const std::string& op_name, module& m, instruction_ref ins, const std::vector& args) const { - if (is_broadcasted) + if (broadcasted_axis.has_value()) { - if (broadcasted != 0) - { - if(std::any_of(args.cbegin(), args.cend(), [](auto a) { return a->get_shape().dynamic(); })) - { - MIGRAPHX_THROW("Binary op broadcast attribute not supported for dynamic input shapes"); - } - auto l = m.add_instruction(migraphx::make_op("broadcast",{{"axis", axis}, {"out_lens", args[0]->get_shape().lens()}}),args[1]); - return {m.add_instruction(migraphx::make_op(op_name), args[0], l)}; - } - return {m.add_instruction(migraphx::make_op(op_name), args)}; + auto l = m.add_instruction(migraphx::make_op("broadcast",{{"axis", broadcasted_axis.value()}, {"out_lens", args[0]->get_shape().lens()}}),args[1]); + return {m.add_instruction(migraphx::make_op(op_name), args[0], l)}; } else { diff --git a/test/op/builder/binary_test.cpp b/test/op/builder/binary_test.cpp index 27a7cc3edd0..9e9b313162d 100644 --- a/test/op/builder/binary_test.cpp +++ b/test/op/builder/binary_test.cpp @@ -34,24 +34,6 @@ std::string pick_op_name() return op_names_set[dis(gen)]; } -TEST_CASE(binary_dynamic_input_shape_test) -{ - migraphx::module mm; - const std::string& op_name = pick_op_name(); - - migraphx::shape::dynamic_dimension dd{1, 4}; - std::vector dyn_dims{dd, dd}; - - mm.add_parameter("a", {migraphx::shape::float_type, dyn_dims}); - mm.add_parameter("b", {migraphx::shape::float_type, dyn_dims}); - - EXPECT(test::throws( - [&] { make_op_module(op_name, - {{"is_broadcasted", true}, {"broadcasted", 1}}, - mm.get_parameters()); }, - "Binary op broadcast attribute not supported for dynamic input shapes")); -} - TEST_CASE(binary_not_broadcasted_test) { migraphx::module mm; @@ -78,22 +60,6 @@ TEST_CASE(binary_not_broadcasted_implicit_broadcast) EXPECT(mm == make_op_module(op_name, {}, mm.get_parameters())); } - -TEST_CASE(binary_zero_broadcasted_test) -{ - migraphx::module mm; - const std::string& op_name = pick_op_name(); - - auto a_arg = mm.add_parameter("a", {migraphx::shape::float_type, {2, 4}}); - auto b_arg = mm.add_parameter("b", {migraphx::shape::float_type, {2, 4}}); - - mm.add_instruction(migraphx::make_op(op_name), {a_arg, b_arg}); - - EXPECT(mm == make_op_module(op_name, - {{"is_broadcasted", true}, {"broadcasted", 0}}, - mm.get_parameters())); -} - TEST_CASE(binary_non_zero_broadcasted_test) { migraphx::module mm; @@ -105,7 +71,5 @@ TEST_CASE(binary_non_zero_broadcasted_test) auto l = mm.add_instruction(migraphx::make_op("broadcast",{{"axis", 1}, {"out_lens", {2, 3, 4, 5}}}), b_arg); mm.add_instruction(migraphx::make_op(op_name), {a_arg, l}); - EXPECT(mm == make_op_module(op_name, - {{"is_broadcasted", true}, {"broadcasted", 1}, {"axis", 1}}, - mm.get_parameters())); + EXPECT(mm == make_op_module(op_name, {{"broadcasted_axis", 1}}, mm.get_parameters())); } From d55923684b6bf6d0ba82df7d6829c3c729715798 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Mon, 13 Oct 2025 06:11:09 -0500 Subject: [PATCH 10/70] formatting document; change copyright date; remove const so less difference would be there --- src/onnx/parse_binary_op.cpp | 15 +++++++++------ src/op/builder/binary.cpp | 27 ++++++++++++++++++++++----- test/op/builder/binary_test.cpp | 13 +++++++++++-- 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/onnx/parse_binary_op.cpp b/src/onnx/parse_binary_op.cpp index b546c590000..29b2a22a339 100644 --- a/src/onnx/parse_binary_op.cpp +++ b/src/onnx/parse_binary_op.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2024 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2025 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 @@ -52,19 +52,22 @@ struct parse_binary_op : op_parser { if(args.size() != 2) MIGRAPHX_THROW("binary operators should have 2 operands"); - + value options = {}; if(contains(info.attributes, "broadcast") and contains(info.attributes, "axis")) { - const uint64_t broadcasted = parser.parse_value(info.attributes.at("broadcast")).at(); + uint64_t broadcasted = + parser.parse_value(info.attributes.at("broadcast")).at(); if(broadcasted != 0) { - if (std::any_of(args.cbegin(), args.cend(), [](auto a) { return a->get_shape().dynamic(); })) + if(std::any_of( + args.cbegin(), args.cend(), [](auto a) { return a->get_shape().dynamic(); })) { - MIGRAPHX_THROW("Binary op broadcast attribute not supported for dynamic input shapes"); + MIGRAPHX_THROW( + "Binary op broadcast attribute not supported for dynamic input shapes"); } - const uint64_t axis = parser.parse_value(info.attributes.at("axis")).at(); + uint64_t axis = parser.parse_value(info.attributes.at("axis")).at(); options.insert({"broadcasted_axis", axis}); } } diff --git a/src/op/builder/binary.cpp b/src/op/builder/binary.cpp index ed64004d0f4..84a18620845 100644 --- a/src/op/builder/binary.cpp +++ b/src/op/builder/binary.cpp @@ -36,7 +36,18 @@ struct binary : op_builder { std::optional broadcasted_axis = std::nullopt; - static std::vector names() { return {"add", "div", "logical_and", "logical_or", "logical_xor", "bitwise_and", "mul", "prelu", "sub"}; } + static std::vector names() + { + return {"add", + "div", + "logical_and", + "logical_or", + "logical_xor", + "bitwise_and", + "mul", + "prelu", + "sub"}; + } template static auto reflect(Self& self, F f) @@ -44,12 +55,18 @@ struct binary : op_builder return pack(f(self.broadcasted_axis, "broadcasted_axis")); } - std::vector - insert(const std::string& op_name, module& m, instruction_ref ins, const std::vector& args) const + std::vector insert(const std::string& op_name, + module& m, + instruction_ref ins, + const std::vector& args) const { - if (broadcasted_axis.has_value()) + if(broadcasted_axis.has_value()) { - auto l = m.add_instruction(migraphx::make_op("broadcast",{{"axis", broadcasted_axis.value()}, {"out_lens", args[0]->get_shape().lens()}}),args[1]); + auto l = + m.add_instruction(migraphx::make_op("broadcast", + {{"axis", broadcasted_axis.value()}, + {"out_lens", args[0]->get_shape().lens()}}), + args[1]); return {m.add_instruction(migraphx::make_op(op_name), args[0], l)}; } else diff --git a/test/op/builder/binary_test.cpp b/test/op/builder/binary_test.cpp index 9e9b313162d..416f74dfd57 100644 --- a/test/op/builder/binary_test.cpp +++ b/test/op/builder/binary_test.cpp @@ -27,7 +27,15 @@ std::string pick_op_name() { - static const std::vector op_names_set{"add", "div", "logical_and", "logical_or", "logical_xor", "bitwise_and", "mul", "prelu", "sub"}; + static const std::vector op_names_set{"add", + "div", + "logical_and", + "logical_or", + "logical_xor", + "bitwise_and", + "mul", + "prelu", + "sub"}; static std::random_device rd; static std::mt19937 gen(rd()); static std::uniform_int_distribution<> dis(0, op_names_set.size() - 1); @@ -68,7 +76,8 @@ TEST_CASE(binary_non_zero_broadcasted_test) auto a_arg = mm.add_parameter("a", {migraphx::shape::float_type, {2, 3, 4, 5}}); auto b_arg = mm.add_parameter("b", {migraphx::shape::float_type, {3, 4}}); - auto l = mm.add_instruction(migraphx::make_op("broadcast",{{"axis", 1}, {"out_lens", {2, 3, 4, 5}}}), b_arg); + auto l = mm.add_instruction( + migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {2, 3, 4, 5}}}), b_arg); mm.add_instruction(migraphx::make_op(op_name), {a_arg, l}); EXPECT(mm == make_op_module(op_name, {{"broadcasted_axis", 1}}, mm.get_parameters())); From 0a92c4e69d476a6610313d6ee1c1f192864cbce3 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Mon, 13 Oct 2025 07:19:12 -0500 Subject: [PATCH 11/70] modifying tf binary parser to use the op-builder --- src/op/builder/binary.cpp | 2 ++ src/tf/parse_binary_op.cpp | 8 +++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/op/builder/binary.cpp b/src/op/builder/binary.cpp index 84a18620845..9827e0d4f78 100644 --- a/src/op/builder/binary.cpp +++ b/src/op/builder/binary.cpp @@ -45,7 +45,9 @@ struct binary : op_builder "logical_xor", "bitwise_and", "mul", + "pow", "prelu", + "sqdiff", "sub"}; } diff --git a/src/tf/parse_binary_op.cpp b/src/tf/parse_binary_op.cpp index 0aa30f76533..0a3008d47d3 100644 --- a/src/tf/parse_binary_op.cpp +++ b/src/tf/parse_binary_op.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2025 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 @@ -22,9 +22,7 @@ * THE SOFTWARE. */ #include -#include -#include -#include +#include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { @@ -50,7 +48,7 @@ struct parse_binary_op : op_parser { if(args.size() != 2) MIGRAPHX_THROW("binary operators should have 2 operands"); - return info.add_broadcastable_binary_op(opd.op_name, args[0], args[1]); + return op::builder::add(opd.op_name, *info.mm, args, {}).at(0); } }; From 915921392c93f07f074234b9d2a16df81e18a6aa Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 14 Oct 2025 10:07:51 -0500 Subject: [PATCH 12/70] cherry picking modifications from the upstream/feature/op_bldr_unit_tests_1 branch --- test/op/include/op_builder_test_utils.hpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/op/include/op_builder_test_utils.hpp b/test/op/include/op_builder_test_utils.hpp index 879a8a1b7b4..f5d13915ff1 100644 --- a/test/op/include/op_builder_test_utils.hpp +++ b/test/op/include/op_builder_test_utils.hpp @@ -26,8 +26,10 @@ #define MIGRAPHX_GUARD_TEST_OPBUILDER_TEST_UTILS_HPP #include +#include #include #include +#include inline migraphx::module make_op_module(const std::string& op_builder_name, const migraphx::value& options, @@ -35,8 +37,11 @@ inline migraphx::module make_op_module(const std::string& op_builder_name, { migraphx::module mm_op_built; - const std::vector& args{params.rbegin(), params.rend()}; - mm_op_built.add_instructions(args); + for(auto param : migraphx::range(params.rbegin(), params.rend())) + { + auto param_name = migraphx::any_cast(param->get_operator()).parameter; + mm_op_built.add_parameter(param_name, param->get_shape()); + } const auto& params2 = mm_op_built.get_parameters(); const std::vector& args2{params2.rbegin(), params2.rend()}; From d6acc431fe603e5d6f7be5a10ad168f294134905 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 14 Oct 2025 10:19:28 -0500 Subject: [PATCH 13/70] modifying tf parser for AddN to use the binary op-builder --- src/tf/parse_addn.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tf/parse_addn.cpp b/src/tf/parse_addn.cpp index 7967d25912e..32583380509 100644 --- a/src/tf/parse_addn.cpp +++ b/src/tf/parse_addn.cpp @@ -25,6 +25,7 @@ #include #include #include +#include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { @@ -43,7 +44,7 @@ struct parse_addn : op_parser instruction_ref sum = args[0]; for(auto i = 1; i < args.size(); i++) { - sum = info.add_instruction(make_op("add"), sum, args[i]); + sum = op::builder::add("add", *info.mm, {sum, args[i]}, {}).at(0); } return sum; } From 12e24f61988e2285f3820b11382f8e9a055cd11f Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Wed, 15 Oct 2025 03:58:03 -0500 Subject: [PATCH 14/70] remove unnecessary header files --- src/tf/parse_addn.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/tf/parse_addn.cpp b/src/tf/parse_addn.cpp index 32583380509..5d79ce738b7 100644 --- a/src/tf/parse_addn.cpp +++ b/src/tf/parse_addn.cpp @@ -22,9 +22,6 @@ * THE SOFTWARE. */ #include -#include -#include -#include #include namespace migraphx { From d7a7d5394d318b20810e5e15ef1c10b0683f18d1 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Wed, 15 Oct 2025 04:00:31 -0500 Subject: [PATCH 15/70] introducing 'convert' op-builder --- src/onnx/parse_cast.cpp | 4 +-- src/op/builder/convert.cpp | 56 ++++++++++++++++++++++++++++++++++++++ src/tf/parse_cast.cpp | 6 ++-- 3 files changed, 60 insertions(+), 6 deletions(-) create mode 100644 src/op/builder/convert.cpp diff --git a/src/onnx/parse_cast.cpp b/src/onnx/parse_cast.cpp index 6c2de3fac70..ab2617bc247 100644 --- a/src/onnx/parse_cast.cpp +++ b/src/onnx/parse_cast.cpp @@ -23,7 +23,7 @@ */ #include #include -#include +#include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { @@ -45,7 +45,7 @@ struct parse_cast : op_parser int to_type = parser.parse_value(info.attributes.at("to")).at(); shape::type_t type = get_type(to_type); - return info.add_instruction(make_op("convert", {{"target_type", type}}), args); + return op::builder::add("convert", *info.mod, args, {{"target_type", type}}).at(0); } }; diff --git a/src/op/builder/convert.cpp b/src/op/builder/convert.cpp new file mode 100644 index 00000000000..cae698f81a9 --- /dev/null +++ b/src/op/builder/convert.cpp @@ -0,0 +1,56 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2025 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 + +namespace migraphx { +inline namespace MIGRAPHX_INLINE_NS { +namespace op { +namespace builder { + +struct convert : op_builder +{ + shape::type_t target_type; + + template + static auto reflect(Self& self, F f) + { + return pack(f(self.target_type, "target_type")); + } + + std::vector + insert(module& m, instruction_ref /*ins*/, const std::vector& args) const + { + return { + m.add_instruction(migraphx::make_op("convert", {{"target_type", target_type}}), args)}; + } +}; + +} // namespace builder +} // namespace op +} // namespace MIGRAPHX_INLINE_NS +} // namespace migraphx diff --git a/src/tf/parse_cast.cpp b/src/tf/parse_cast.cpp index 4bcd2905f6f..147b44d5a71 100644 --- a/src/tf/parse_cast.cpp +++ b/src/tf/parse_cast.cpp @@ -23,9 +23,7 @@ */ #include #include -#include -#include -#include +#include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { @@ -41,7 +39,7 @@ struct parse_cast : op_parser const std::vector& args) const { shape::type_t type = parser.parse_type(info.attributes.at("DstT").type()); - return info.add_instruction(make_op("convert", {{"target_type", type}}), args); + return op::builder::add("convert", *info.mm, args, {{"target_type", type}}).at(0); } }; From 8caa3828e5b7db026005045c0a97efa98bb6d58e Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Wed, 15 Oct 2025 04:22:48 -0500 Subject: [PATCH 16/70] introducing 'concat' op-builder --- src/op/builder/concat.cpp | 56 +++++++++++++++++++++++++++++++++++++++ src/tf/parse_concat.cpp | 8 ++---- 2 files changed, 58 insertions(+), 6 deletions(-) create mode 100644 src/op/builder/concat.cpp diff --git a/src/op/builder/concat.cpp b/src/op/builder/concat.cpp new file mode 100644 index 00000000000..a6515608270 --- /dev/null +++ b/src/op/builder/concat.cpp @@ -0,0 +1,56 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2025 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 + +namespace migraphx { +inline namespace MIGRAPHX_INLINE_NS { +namespace op { +namespace builder { + +struct concat : op_builder +{ + int64_t axis; + + template + static auto reflect(Self& self, F f) + { + return pack(f(self.axis, "axis")); + } + + std::vector + insert(module& m, instruction_ref /*ins*/, const std::vector& args) const + { + // return only first N arguments (assuming last index is the axis value) + return {m.add_instruction( + migraphx::make_op("concat", {{"axis", axis}}), + std::vector(args.begin(), args.begin() + args.size() - 1))}; + } +}; + +} // namespace builder +} // namespace op +} // namespace MIGRAPHX_INLINE_NS +} // namespace migraphx diff --git a/src/tf/parse_concat.cpp b/src/tf/parse_concat.cpp index 5b0fbb124c1..6cd664048ea 100644 --- a/src/tf/parse_concat.cpp +++ b/src/tf/parse_concat.cpp @@ -23,9 +23,8 @@ */ #include #include -#include #include -#include +#include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { @@ -43,10 +42,7 @@ struct parse_concat : op_parser // get index for axis within args size_t axis_idx = info.attributes.at("N").i(); int64_t axis = args[axis_idx]->eval().at(); - auto op = make_op("concat", {{"axis", axis}}); - // return only first N arguments (assuming last index is the axis value) - return info.add_instruction( - op, std::vector(args.begin(), args.begin() + args.size() - 1)); + return op::builder::add("concat", *info.mm, args, {{"axis", axis}}).at(0); } }; From 955a6cad76fdbee94bbaaa1fec3d5c7a100d2f88 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Wed, 15 Oct 2025 04:47:01 -0500 Subject: [PATCH 17/70] cherry pickjing modification from a different feature branch: making a default value for the 'options' parameter for an op-builder --- src/onnx/parse_clip.cpp | 2 +- src/onnx/parse_gelu.cpp | 4 ++-- src/op/builder/clip.cpp | 6 ------ src/op/builder/gelu.cpp | 14 +------------- .../builder/include/migraphx/op/builder/insert.hpp | 8 ++++---- 5 files changed, 8 insertions(+), 26 deletions(-) diff --git a/src/onnx/parse_clip.cpp b/src/onnx/parse_clip.cpp index 412bfd2d89d..91addfb76b3 100644 --- a/src/onnx/parse_clip.cpp +++ b/src/onnx/parse_clip.cpp @@ -49,7 +49,7 @@ struct parse_clip : op_parser args.push_back(info.add_literal(max_val)); } - return op::builder::add("clip", *info.mod, args, {}).at(0); + return op::builder::add("clip", *info.mod, args).at(0); } }; diff --git a/src/onnx/parse_gelu.cpp b/src/onnx/parse_gelu.cpp index 226b8985d71..a4f364adc74 100644 --- a/src/onnx/parse_gelu.cpp +++ b/src/onnx/parse_gelu.cpp @@ -88,7 +88,7 @@ struct parse_gelu : op_parser { // add should've been inserted from previous conditional statement assert(args.size() == 2); - return op::builder::add("gelu_split", *info.mod, {x}, {}).at(0); + return op::builder::add("gelu_split", *info.mod, {x}).at(0); } if(approximate == "tanh") @@ -97,7 +97,7 @@ struct parse_gelu : op_parser } else { - return op::builder::add("gelu_erf", *info.mod, {x}, {}).at(0); + return op::builder::add("gelu_erf", *info.mod, {x}).at(0); } } }; diff --git a/src/op/builder/clip.cpp b/src/op/builder/clip.cpp index b3b781775aa..469be009f18 100644 --- a/src/op/builder/clip.cpp +++ b/src/op/builder/clip.cpp @@ -35,12 +35,6 @@ namespace builder { struct clip : op_builder { - template - static auto reflect(Self&, F) - { - return pack(); - } - std::vector insert(module& m, instruction_ref ins, const std::vector& args) const { diff --git a/src/op/builder/gelu.cpp b/src/op/builder/gelu.cpp index 8f39ac2f163..dd8fddfebed 100644 --- a/src/op/builder/gelu.cpp +++ b/src/op/builder/gelu.cpp @@ -57,12 +57,6 @@ struct gelu_quick : op_builder struct gelu_erf : op_builder { - template - static auto reflect(Self&, F) - { - return pack(); - } - std::vector insert(module& m, instruction_ref ins, const std::vector& args) const { @@ -130,12 +124,6 @@ struct gelu_tanh : op_builder struct gelu_split : op_builder { - template - static auto reflect(Self&, F) - { - return pack(); - } - std::vector insert(module& m, instruction_ref ins, const std::vector& args) const { @@ -155,7 +143,7 @@ struct gelu_split : op_builder {{"axes", {-1}}, {"starts", {last_dim_size / 2}}, {"ends", {last_dim_size}}}), x); - auto gelu_erf = op::builder::add("gelu_erf", m, {split_right}, {}).at(0); + auto gelu_erf = op::builder::add("gelu_erf", m, {split_right}).at(0); return {insert_common_op(m, ins, "mul", split_left, gelu_erf)}; } }; diff --git a/src/op/builder/include/migraphx/op/builder/insert.hpp b/src/op/builder/include/migraphx/op/builder/insert.hpp index 4d9178bf0d3..91d3c46edc0 100644 --- a/src/op/builder/include/migraphx/op/builder/insert.hpp +++ b/src/op/builder/include/migraphx/op/builder/insert.hpp @@ -39,25 +39,25 @@ MIGRAPHX_EXPORT std::vector insert(const std::string& name, module& m, instruction_ref ins, const std::vector& args, - const value& options); + const value& options = value("", {}, false)); MIGRAPHX_EXPORT std::vector insert(const std::string& name, module& m, instruction_ref ins, const std::vector& args, const std::vector& module_args, - const value& options); + const value& options = value("", {}, false)); MIGRAPHX_EXPORT std::vector add(const std::string& name, module& m, const std::vector& args, - const value& options); + const value& options = value("", {}, false)); MIGRAPHX_EXPORT std::vector add(const std::string& name, module& m, const std::vector& args, const std::vector& module_args, - const value& options); + const value& options = value("", {}, false)); template instruction_ref insert_common_op(module& m, instruction_ref ins, const std::string& op_name, Ins... args) From 4d335bd36977e1bb2a703bc4860125f1cbdfd971 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Wed, 15 Oct 2025 04:47:34 -0500 Subject: [PATCH 18/70] missing from the last commit. --- src/tf/parse_binary_op.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tf/parse_binary_op.cpp b/src/tf/parse_binary_op.cpp index 0a3008d47d3..55b19cea284 100644 --- a/src/tf/parse_binary_op.cpp +++ b/src/tf/parse_binary_op.cpp @@ -48,7 +48,7 @@ struct parse_binary_op : op_parser { if(args.size() != 2) MIGRAPHX_THROW("binary operators should have 2 operands"); - return op::builder::add(opd.op_name, *info.mm, args, {}).at(0); + return op::builder::add(opd.op_name, *info.mm, args).at(0); } }; From 288c0a9388c9902858ff9f628200913d7eb65566 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Wed, 15 Oct 2025 04:49:00 -0500 Subject: [PATCH 19/70] introducing 'addn' op-builder --- src/op/builder/addn.cpp | 50 +++++++++++++++++++++++++++++++++++++++++ src/tf/parse_addn.cpp | 7 +----- 2 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 src/op/builder/addn.cpp diff --git a/src/op/builder/addn.cpp b/src/op/builder/addn.cpp new file mode 100644 index 00000000000..d3cb84d7e37 --- /dev/null +++ b/src/op/builder/addn.cpp @@ -0,0 +1,50 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2025 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 + +namespace migraphx { +inline namespace MIGRAPHX_INLINE_NS { +namespace op { +namespace builder { + +struct addn : op_builder +{ + std::vector + insert(module& m, instruction_ref /*ins*/, const std::vector& args) const + { + instruction_ref sum = args[0]; + for(auto i = 1; i < args.size(); i++) + { + sum = op::builder::add("add", m, {sum, args[i]}).at(0); + } + return {sum}; + } +}; + +} // namespace builder +} // namespace op +} // namespace MIGRAPHX_INLINE_NS +} // namespace migraphx diff --git a/src/tf/parse_addn.cpp b/src/tf/parse_addn.cpp index 5d79ce738b7..0ada578ce3f 100644 --- a/src/tf/parse_addn.cpp +++ b/src/tf/parse_addn.cpp @@ -38,12 +38,7 @@ struct parse_addn : op_parser const tf_parser::node_info& info, std::vector args) const { - instruction_ref sum = args[0]; - for(auto i = 1; i < args.size(); i++) - { - sum = op::builder::add("add", *info.mm, {sum, args[i]}, {}).at(0); - } - return sum; + return op::builder::add("addn", *info.mm, args).at(0); } }; From d0f1023be53287878e93f87c1350c4fce6e033ef Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Wed, 15 Oct 2025 07:03:20 -0500 Subject: [PATCH 20/70] introducing 'tile' op-builder --- src/onnx/parse_tile.cpp | 16 ++--------- src/op/builder/tile.cpp | 63 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 13 deletions(-) create mode 100644 src/op/builder/tile.cpp diff --git a/src/onnx/parse_tile.cpp b/src/onnx/parse_tile.cpp index ae1614b796c..76eb671c612 100644 --- a/src/onnx/parse_tile.cpp +++ b/src/onnx/parse_tile.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2025 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 @@ -23,9 +23,8 @@ */ #include #include -#include #include -#include +#include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { @@ -45,16 +44,7 @@ struct parse_tile : op_parser std::vector repeats; arg_s.visit([&](auto input) { repeats.assign(input.begin(), input.end()); }); - auto l0 = args[0]; - for(int i = 0; i < repeats.size(); i++) - { - auto l1 = l0; - for(int j = 1; j < repeats[i]; j++) - { - l0 = info.add_instruction(make_op("concat", {{"axis", i}}), l0, l1); - } - } - return l0; + return op::builder::add("tile", *info.mod, args, {{"repeats", repeats}}).at(0); } }; diff --git a/src/op/builder/tile.cpp b/src/op/builder/tile.cpp new file mode 100644 index 00000000000..53af50d841b --- /dev/null +++ b/src/op/builder/tile.cpp @@ -0,0 +1,63 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2025 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 + +namespace migraphx { +inline namespace MIGRAPHX_INLINE_NS { +namespace op { +namespace builder { + +struct tile : op_builder +{ + std::vector repeats; + + template + static auto reflect(Self& self, F f) + { + return pack(f(self.repeats, "repeats")); + } + + std::vector + insert(module& m, instruction_ref /*ins*/, const std::vector& args) const + { + auto l0 = args[0]; + for(int i = 0; i < repeats.size(); i++) + { + auto l1 = l0; + for(int j = 1; j < repeats[i]; j++) + { + l0 = op::builder::add("concat", m, {l0, l1, {}}, {{"axis", i}}).at(0); + } + } + return {l0}; + } +}; + +} // namespace builder +} // namespace op +} // namespace MIGRAPHX_INLINE_NS +} // namespace migraphx From cf62641985ab3637c1ca581eddc5fcc86eebd9ee Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Wed, 15 Oct 2025 07:15:15 -0500 Subject: [PATCH 21/70] fixing document formatting --- test/op/include/op_builder_test_utils.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/op/include/op_builder_test_utils.hpp b/test/op/include/op_builder_test_utils.hpp index f5d13915ff1..5807ea6a4de 100644 --- a/test/op/include/op_builder_test_utils.hpp +++ b/test/op/include/op_builder_test_utils.hpp @@ -39,7 +39,8 @@ inline migraphx::module make_op_module(const std::string& op_builder_name, for(auto param : migraphx::range(params.rbegin(), params.rend())) { - auto param_name = migraphx::any_cast(param->get_operator()).parameter; + auto param_name = + migraphx::any_cast(param->get_operator()).parameter; mm_op_built.add_parameter(param_name, param->get_shape()); } From ba4220d9ecc7ee38accee75453ae9e95b66acce6 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 21 Oct 2025 14:21:54 -0500 Subject: [PATCH 22/70] introducing 'constant' op-builder --- src/onnx/parse_constant.cpp | 14 ++++++----- src/op/builder/constant.cpp | 48 +++++++++++++++++++++++++++++++++++++ src/serialize.cpp | 9 ++++++- src/tf/parse_constant.cpp | 9 ++++--- 4 files changed, 68 insertions(+), 12 deletions(-) create mode 100644 src/op/builder/constant.cpp diff --git a/src/onnx/parse_constant.cpp b/src/onnx/parse_constant.cpp index 1396cd4ca9f..16d06faeb97 100644 --- a/src/onnx/parse_constant.cpp +++ b/src/onnx/parse_constant.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2025 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 @@ -24,8 +24,8 @@ #include #include #include -#include #include +#include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { @@ -38,7 +38,7 @@ struct parse_constant : op_parser instruction_ref parse(const op_desc& /*opd*/, const onnx_parser& parser, onnx_parser::node_info info, - const std::vector& /*args*/) const + const std::vector& args) const { static const std::vector attributes = { "value", "value_float", "value_floats", "value_int", "value_ints"}; @@ -67,17 +67,19 @@ struct parse_constant : op_parser // return empty literal if(v.get_shape().elements() == 0) { - return info.add_literal(literal{v.get_shape().type()}); + const literal lit{v.get_shape().type()}; + return op::builder::add("constant", *info.mod, args, migraphx::to_value(lit)).at(0); } // if dim_size is 0, it is a scalar if(attr.has_t() and attr.t().dims_size() == 0) { migraphx::shape scalar_shape{v.get_shape().type()}; - return info.add_literal(migraphx::literal{scalar_shape, v.data()}); + const literal lit{scalar_shape, v.data()}; + return op::builder::add("constant", *info.mod, args, migraphx::to_value(lit)).at(0); } - return info.add_literal(v); + return op::builder::add("constant", *info.mod, args, migraphx::to_value(v)).at(0); } }; diff --git a/src/op/builder/constant.cpp b/src/op/builder/constant.cpp new file mode 100644 index 00000000000..f142bf9640d --- /dev/null +++ b/src/op/builder/constant.cpp @@ -0,0 +1,48 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2025 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 + +namespace migraphx { +inline namespace MIGRAPHX_INLINE_NS { +namespace op { +namespace builder { + +struct constant : op_builder +{ + literal lit; + + void from_value(const value& v) { lit = migraphx::from_value(v); } + + std::vector + insert(module& m, instruction_ref /*ins*/, const std::vector& /*args*/) const + { + return {m.add_literal(lit)}; + } +}; + +} // namespace builder +} // namespace op +} // namespace MIGRAPHX_INLINE_NS +} // namespace migraphx diff --git a/src/serialize.cpp b/src/serialize.cpp index ddc3550a937..06e2d9128e7 100644 --- a/src/serialize.cpp +++ b/src/serialize.cpp @@ -45,7 +45,14 @@ void migraphx_to_value(value& v, const literal& l) { raw_data_to_value(v, l); } void migraphx_from_value(const value& v, literal& l) { auto s = migraphx::from_value(v.at("shape")); - l = literal(s, v.at("data").get_binary().data()); + if(v.contains("data")) + { + l = literal(s, v.at("data").get_binary().data()); + } + else + { + l = literal{s.type()}; + } } void migraphx_to_value(value& v, const argument& a) { raw_data_to_value(v, a); } diff --git a/src/tf/parse_constant.cpp b/src/tf/parse_constant.cpp index 5b1400b15b2..06c010dfbff 100644 --- a/src/tf/parse_constant.cpp +++ b/src/tf/parse_constant.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2025 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 @@ -23,8 +23,7 @@ */ #include #include -#include -#include +#include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { @@ -38,10 +37,10 @@ struct parse_constant_op : op_parser instruction_ref parse(const op_desc& /*opd*/, const tf_parser& parser, tf_parser::node_info info, - const std::vector& /*args*/) const + const std::vector& args) const { literal v = parser.parse_tensor(info.attributes.at("value").tensor()); - return info.add_literal(v); + return op::builder::add("constant", *info.mm, args, migraphx::to_value(v)).at(0); } }; From d721bf18c80f04c31970681ff3238143e75cad5c Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Wed, 22 Oct 2025 13:20:10 -0500 Subject: [PATCH 23/70] fixing an issue: theconcat op-builder will use the input argument vector as it arrives; in case of the TF parser we have to modify the input vector that will be passed to the op-builder. We won't need the last item. --- src/op/builder/concat.cpp | 5 +---- src/op/builder/tile.cpp | 2 +- src/tf/parse_concat.cpp | 6 ++++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/op/builder/concat.cpp b/src/op/builder/concat.cpp index a6515608270..8ba61271fb2 100644 --- a/src/op/builder/concat.cpp +++ b/src/op/builder/concat.cpp @@ -43,10 +43,7 @@ struct concat : op_builder std::vector insert(module& m, instruction_ref /*ins*/, const std::vector& args) const { - // return only first N arguments (assuming last index is the axis value) - return {m.add_instruction( - migraphx::make_op("concat", {{"axis", axis}}), - std::vector(args.begin(), args.begin() + args.size() - 1))}; + return {m.add_instruction(migraphx::make_op("concat", {{"axis", axis}}), args)}; } }; diff --git a/src/op/builder/tile.cpp b/src/op/builder/tile.cpp index 53af50d841b..1730cbcd709 100644 --- a/src/op/builder/tile.cpp +++ b/src/op/builder/tile.cpp @@ -50,7 +50,7 @@ struct tile : op_builder auto l1 = l0; for(int j = 1; j < repeats[i]; j++) { - l0 = op::builder::add("concat", m, {l0, l1, {}}, {{"axis", i}}).at(0); + l0 = op::builder::add("concat", m, {l0, l1}, {{"axis", i}}).at(0); } } return {l0}; diff --git a/src/tf/parse_concat.cpp b/src/tf/parse_concat.cpp index 6cd664048ea..1055457e400 100644 --- a/src/tf/parse_concat.cpp +++ b/src/tf/parse_concat.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2025 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 @@ -42,7 +42,9 @@ struct parse_concat : op_parser // get index for axis within args size_t axis_idx = info.attributes.at("N").i(); int64_t axis = args[axis_idx]->eval().at(); - return op::builder::add("concat", *info.mm, args, {{"axis", axis}}).at(0); + const auto& concat_args = + std::vector{args.begin(), args.begin() + args.size() - 1}; + return op::builder::add("concat", *info.mm, concat_args, {{"axis", axis}}).at(0); } }; From 6543a3d3eec6edd396bc032cee428f1e0858f5c4 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Wed, 22 Oct 2025 13:22:33 -0500 Subject: [PATCH 24/70] introducing 'general_op' op-builder. this implements a bunch of single-parameter functions --- src/onnx/parse_generic_op.cpp | 16 +------ src/op/builder/generic_op.cpp | 88 +++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 14 deletions(-) create mode 100644 src/op/builder/generic_op.cpp diff --git a/src/onnx/parse_generic_op.cpp b/src/onnx/parse_generic_op.cpp index 023a3a41f3d..804e3fa5a99 100644 --- a/src/onnx/parse_generic_op.cpp +++ b/src/onnx/parse_generic_op.cpp @@ -22,8 +22,7 @@ * THE SOFTWARE. */ #include -#include -#include +#include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { @@ -72,24 +71,13 @@ struct parse_generic_op : op_parser // clang-format on } - bool needs_contiguous(const std::string& op_name) const - { - return contains({"flatten", "gather", "scatter"}, op_name); - } - instruction_ref parse(const op_desc& opd, const onnx_parser& parser, onnx_parser::node_info info, std::vector args) const { auto op = parser.load(opd.op_name, info); - if(needs_contiguous(opd.op_name)) - { - std::transform(args.begin(), args.end(), args.begin(), [&](auto arg) { - return info.make_contiguous(arg); - }); - } - return info.add_instruction(op, args); + return op::builder::add(opd.op_name, *info.mod, args, to_value(op)).at(0); } }; diff --git a/src/op/builder/generic_op.cpp b/src/op/builder/generic_op.cpp new file mode 100644 index 00000000000..12c6f25846e --- /dev/null +++ b/src/op/builder/generic_op.cpp @@ -0,0 +1,88 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2025 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 + +namespace migraphx { +inline namespace MIGRAPHX_INLINE_NS { +namespace op { +namespace builder { + +struct generic_op : op_builder +{ + operation op; + + void from_value(const value& v) { op = migraphx::from_value(v); } + + static std::vector names() + { + return {"abs", "acos", "acosh", "asin", "asinh", "atan", "atanh", + "ceil", "cos", "cosh", "elu", "erf", "exp", "flatten", + "floor", "gather", "gathernd", "identity", "isnan", "leaky_relu", "log", + "lrn", "neg", "recip", "relu", "nearbyint", "rsqrt", "sigmoid", + "sign", "sin", "sinh", "sqrt", "tan", "tanh", "not"}; + } + + std::vector insert(const std::string& op_name, + module& m, + instruction_ref /*ins*/, + const std::vector& args) const + { + std::vector args_copy = args; + if(needs_contiguous(op_name)) + { + std::transform(args_copy.begin(), args_copy.end(), args_copy.begin(), [&](auto arg) { + return make_contiguous(m, arg); + }); + } + + return {m.add_instruction(op, args_copy)}; + } + + private: + bool needs_contiguous(const std::string& op_name) const + { + return contains({"flatten", "gather", "scatter"}, op_name); + } + + instruction_ref make_contiguous(module& m, instruction_ref ins) const + { + auto attr = ins->get_operator().to_value(); + std::string key = "require_std_shape"; + if((attr.get(key, false)) or (not ins->get_shape().standard())) + { + return m.add_instruction(make_op("contiguous"), ins); + } + + return ins; + } +}; + +} // namespace builder +} // namespace op +} // namespace MIGRAPHX_INLINE_NS +} // namespace migraphx From 777620b2e66313a88c3809f285b3d717d7d6a61f Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Wed, 22 Oct 2025 13:35:54 -0500 Subject: [PATCH 25/70] changing copyright date + change to const ref variable --- src/onnx/parse_generic_op.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/onnx/parse_generic_op.cpp b/src/onnx/parse_generic_op.cpp index 804e3fa5a99..e3f5fbc5fd8 100644 --- a/src/onnx/parse_generic_op.cpp +++ b/src/onnx/parse_generic_op.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2024 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2025 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 @@ -76,7 +76,7 @@ struct parse_generic_op : op_parser onnx_parser::node_info info, std::vector args) const { - auto op = parser.load(opd.op_name, info); + const auto& op = parser.load(opd.op_name, info); return op::builder::add(opd.op_name, *info.mod, args, to_value(op)).at(0); } }; From 6429412efa51b0965b2f807e0fab04a69d1e06e1 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Wed, 22 Oct 2025 13:36:40 -0500 Subject: [PATCH 26/70] make us of op-builders in TF parser as well --- src/tf/parse_generic_op.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tf/parse_generic_op.cpp b/src/tf/parse_generic_op.cpp index 863d4f4a26b..2fd2111b81e 100644 --- a/src/tf/parse_generic_op.cpp +++ b/src/tf/parse_generic_op.cpp @@ -23,8 +23,8 @@ */ #include #include -#include #include +#include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { @@ -50,7 +50,8 @@ struct parse_generic_op : op_parser const tf_parser::node_info& info, const std::vector& args) const { - return info.add_instruction(make_op(opd.op_name), args); + const auto& op = make_op(opd.op_name); + return op::builder::add(opd.op_name, *info.mm, args, to_value(op)).at(0); } }; From 31910e92ddf3b7d7a0ef46e73f7cd9239bdf7416 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Mon, 27 Oct 2025 11:17:47 -0500 Subject: [PATCH 27/70] fix license date --- src/tf/parse_cast.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tf/parse_cast.cpp b/src/tf/parse_cast.cpp index 147b44d5a71..01b341d7980 100644 --- a/src/tf/parse_cast.cpp +++ b/src/tf/parse_cast.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2025 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 From 8902bf8751677f3f475987bc72dd18ae84d576e7 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Mon, 27 Oct 2025 11:20:09 -0500 Subject: [PATCH 28/70] fixing formatting warning --- .../include/migraphx/op/builder/op_builder.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/op/builder/include/migraphx/op/builder/op_builder.hpp b/src/op/builder/include/migraphx/op/builder/op_builder.hpp index bc8320379db..2ff3c8cf724 100644 --- a/src/op/builder/include/migraphx/op/builder/op_builder.hpp +++ b/src/op/builder/include/migraphx/op/builder/op_builder.hpp @@ -72,7 +72,7 @@ auto invoke_builder(std::string /*name*/, } template -auto invoke_builder(std::string name, +auto invoke_builder(std::string name, module& m, instruction_ref ins, const std::vector& args, @@ -100,13 +100,13 @@ auto invoke_builder(std::string name, template void register_builder() { - for(const auto& name:T::names()) + for(const auto& name : T::names()) { builder_func f = [=](module& m, - instruction_ref ins, - const std::vector& args, - const std::vector& module_args, - const value& options) { + instruction_ref ins, + const std::vector& args, + const std::vector& module_args, + const value& options) { return invoke_builder(name, m, ins, args, module_args, options); }; register_builder(name, std::move(f)); From 650829ecc3e4417ee6557748421d9a13725ff5c9 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Mon, 27 Oct 2025 11:21:39 -0500 Subject: [PATCH 29/70] fix. adding newline at the end of file --- test/op/builder/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/op/builder/main.cpp b/test/op/builder/main.cpp index 4761f5c1d7b..1c2129e3161 100644 --- a/test/op/builder/main.cpp +++ b/test/op/builder/main.cpp @@ -23,4 +23,4 @@ */ #include "test.hpp" -int main(int argc, const char* argv[]) { test::run(argc, argv); } \ No newline at end of file +int main(int argc, const char* argv[]) { test::run(argc, argv); } From 2662fd9cb74027c3aa985a35cd9c290652e174f4 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Mon, 27 Oct 2025 11:25:00 -0500 Subject: [PATCH 30/70] change shape type. for bitwise operations only integer types are supported --- test/op/builder/binary_test.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/op/builder/binary_test.cpp b/test/op/builder/binary_test.cpp index 416f74dfd57..a4079847d1e 100644 --- a/test/op/builder/binary_test.cpp +++ b/test/op/builder/binary_test.cpp @@ -47,8 +47,8 @@ TEST_CASE(binary_not_broadcasted_test) migraphx::module mm; const std::string& op_name = pick_op_name(); - auto a_arg = mm.add_parameter("a", {migraphx::shape::float_type, {2, 4}}); - auto b_arg = mm.add_parameter("b", {migraphx::shape::float_type, {2, 4}}); + auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 4}}); + auto b_arg = mm.add_parameter("b", {migraphx::shape::int64_type, {2, 4}}); add_common_op(mm, migraphx::make_op(op_name), {a_arg, b_arg}); @@ -60,8 +60,8 @@ TEST_CASE(binary_not_broadcasted_implicit_broadcast) migraphx::module mm; const std::string& op_name = pick_op_name(); - auto a_arg = mm.add_parameter("a", {migraphx::shape::float_type, {2, 4}}); - auto b_arg = mm.add_parameter("b", {migraphx::shape::float_type, {2, 1}}); + auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 4}}); + auto b_arg = mm.add_parameter("b", {migraphx::shape::int64_type, {2, 1}}); add_common_op(mm, migraphx::make_op(op_name), {a_arg, b_arg}); @@ -73,8 +73,8 @@ TEST_CASE(binary_non_zero_broadcasted_test) migraphx::module mm; const std::string& op_name = pick_op_name(); - auto a_arg = mm.add_parameter("a", {migraphx::shape::float_type, {2, 3, 4, 5}}); - auto b_arg = mm.add_parameter("b", {migraphx::shape::float_type, {3, 4}}); + auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 3, 4, 5}}); + auto b_arg = mm.add_parameter("b", {migraphx::shape::int64_type, {3, 4}}); auto l = mm.add_instruction( migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {2, 3, 4, 5}}}), b_arg); From c5e24fe03fc2e7f4834ed42c89c0f0186756599f Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Mon, 27 Oct 2025 11:32:24 -0500 Subject: [PATCH 31/70] fixing license date --- src/onnx/parse_cast.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/onnx/parse_cast.cpp b/src/onnx/parse_cast.cpp index ab2617bc247..6babb8c7203 100644 --- a/src/onnx/parse_cast.cpp +++ b/src/onnx/parse_cast.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2025 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 From 5ed73168996cda70af79b6a386c4aae086cf3105 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Mon, 27 Oct 2025 11:39:27 -0500 Subject: [PATCH 32/70] renaming tests; apply op-builder postfix --- test/op/builder/binary_test.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/op/builder/binary_test.cpp b/test/op/builder/binary_test.cpp index a4079847d1e..cf12ad59d8a 100644 --- a/test/op/builder/binary_test.cpp +++ b/test/op/builder/binary_test.cpp @@ -42,7 +42,7 @@ std::string pick_op_name() return op_names_set[dis(gen)]; } -TEST_CASE(binary_not_broadcasted_test) +TEST_CASE(binary_not_broadcasted_op_builder_test) { migraphx::module mm; const std::string& op_name = pick_op_name(); @@ -55,7 +55,7 @@ TEST_CASE(binary_not_broadcasted_test) EXPECT(mm == make_op_module(op_name, {}, mm.get_parameters())); } -TEST_CASE(binary_not_broadcasted_implicit_broadcast) +TEST_CASE(binary_not_broadcasted_implicit_broadcast_op_builder_test) { migraphx::module mm; const std::string& op_name = pick_op_name(); @@ -68,7 +68,7 @@ TEST_CASE(binary_not_broadcasted_implicit_broadcast) EXPECT(mm == make_op_module(op_name, {}, mm.get_parameters())); } -TEST_CASE(binary_non_zero_broadcasted_test) +TEST_CASE(binary_non_zero_broadcasted_op_builder_test) { migraphx::module mm; const std::string& op_name = pick_op_name(); From a1d75622e05b0f00eb0d555907ab9bca907b7f91 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Mon, 27 Oct 2025 11:54:23 -0500 Subject: [PATCH 33/70] remove randomness --- test/op/builder/binary_test.cpp | 62 +++++++++++++-------------------- 1 file changed, 25 insertions(+), 37 deletions(-) diff --git a/test/op/builder/binary_test.cpp b/test/op/builder/binary_test.cpp index cf12ad59d8a..ccbbc582129 100644 --- a/test/op/builder/binary_test.cpp +++ b/test/op/builder/binary_test.cpp @@ -23,62 +23,50 @@ */ #include -#include -std::string pick_op_name() -{ - static const std::vector op_names_set{"add", - "div", - "logical_and", - "logical_or", - "logical_xor", - "bitwise_and", - "mul", - "prelu", - "sub"}; - static std::random_device rd; - static std::mt19937 gen(rd()); - static std::uniform_int_distribution<> dis(0, op_names_set.size() - 1); - return op_names_set[dis(gen)]; -} +static const std::vector op_names_set{ + "add", "div", "logical_and", "logical_or", "logical_xor", "bitwise_and", "mul", "prelu", "sub"}; TEST_CASE(binary_not_broadcasted_op_builder_test) { - migraphx::module mm; - const std::string& op_name = pick_op_name(); + std::for_each(op_names_set.begin(), op_names_set.end(), [&](const std::string& op_name) { + migraphx::module mm; - auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 4}}); - auto b_arg = mm.add_parameter("b", {migraphx::shape::int64_type, {2, 4}}); + auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 4}}); + auto b_arg = mm.add_parameter("b", {migraphx::shape::int64_type, {2, 4}}); - add_common_op(mm, migraphx::make_op(op_name), {a_arg, b_arg}); + add_common_op(mm, migraphx::make_op(op_name), {a_arg, b_arg}); - EXPECT(mm == make_op_module(op_name, {}, mm.get_parameters())); + EXPECT(mm == make_op_module(op_name, {}, mm.get_parameters())); + }); } TEST_CASE(binary_not_broadcasted_implicit_broadcast_op_builder_test) { - migraphx::module mm; - const std::string& op_name = pick_op_name(); + std::for_each(op_names_set.begin(), op_names_set.end(), [&](const std::string& op_name) { + migraphx::module mm; - auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 4}}); - auto b_arg = mm.add_parameter("b", {migraphx::shape::int64_type, {2, 1}}); + auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 4}}); + auto b_arg = mm.add_parameter("b", {migraphx::shape::int64_type, {2, 1}}); - add_common_op(mm, migraphx::make_op(op_name), {a_arg, b_arg}); + add_common_op(mm, migraphx::make_op(op_name), {a_arg, b_arg}); - EXPECT(mm == make_op_module(op_name, {}, mm.get_parameters())); + EXPECT(mm == make_op_module(op_name, {}, mm.get_parameters())); + }); } TEST_CASE(binary_non_zero_broadcasted_op_builder_test) { - migraphx::module mm; - const std::string& op_name = pick_op_name(); + std::for_each(op_names_set.begin(), op_names_set.end(), [&](const std::string& op_name) { + migraphx::module mm; - auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 3, 4, 5}}); - auto b_arg = mm.add_parameter("b", {migraphx::shape::int64_type, {3, 4}}); + auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 3, 4, 5}}); + auto b_arg = mm.add_parameter("b", {migraphx::shape::int64_type, {3, 4}}); - auto l = mm.add_instruction( - migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {2, 3, 4, 5}}}), b_arg); - mm.add_instruction(migraphx::make_op(op_name), {a_arg, l}); + auto l = mm.add_instruction( + migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {2, 3, 4, 5}}}), b_arg); + mm.add_instruction(migraphx::make_op(op_name), {a_arg, l}); - EXPECT(mm == make_op_module(op_name, {{"broadcasted_axis", 1}}, mm.get_parameters())); + EXPECT(mm == make_op_module(op_name, {{"broadcasted_axis", 1}}, mm.get_parameters())); + }); } From b020e0ef9fbb16846836e79eb57fba3c8a0bb668 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 28 Oct 2025 05:26:25 -0500 Subject: [PATCH 34/70] adding tests for the 'generic_op' op-builder --- test/op/builder/generic_op_test.cpp | 81 +++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 test/op/builder/generic_op_test.cpp diff --git a/test/op/builder/generic_op_test.cpp b/test/op/builder/generic_op_test.cpp new file mode 100644 index 00000000000..ddfbc0eecfd --- /dev/null +++ b/test/op/builder/generic_op_test.cpp @@ -0,0 +1,81 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2025 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 + +static const std::vector op_names_set{ + "abs", "acos", "acosh", "asin", "asinh", "atan", "atanh", "ceil", + "cos", "cosh", "elu", "erf", "exp", "floor", "identity", "isnan", + "leaky_relu", "log", "lrn", "neg", "recip", "relu", "nearbyint", "rsqrt", + "sigmoid", "sign", "sin", "sinh", "sqrt", "tan", "tanh", "not"}; + +TEST_CASE(generic_not_continous_op_builder_test) +{ + std::for_each(op_names_set.begin(), op_names_set.end(), [&](const std::string& op_name) { + migraphx::module mm; + auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 4, 3, 5}}); + const auto& op = migraphx::make_op(op_name); + mm.add_instruction(op, a_arg); + + EXPECT(mm == make_op_module(op_name, migraphx::to_value(op), mm.get_parameters())); + }); +} + +TEST_CASE(generic_not_continous_gathernd_op_builder_test) +{ + migraphx::module mm; + auto l0 = mm.add_parameter("data", migraphx::shape{migraphx::shape::float_type, {2, 2}}); + auto l1 = mm.add_parameter("indices", migraphx::shape{migraphx::shape::int64_type, {2, 2}}); + const auto& op = migraphx::make_op("gathernd"); + mm.add_instruction(op, l0, l1); + + EXPECT(mm == make_op_module("gathernd", migraphx::to_value(op), mm.get_parameters())); +} + +TEST_CASE(generic_continous_flatten_op_builder_test) +{ + migraphx::module mm; + auto l0 = mm.add_parameter( + "0", migraphx::shape{migraphx::shape::float_type, {{1, 4}, {4, 4}, {5, 5}, {6, 6}}}); + auto cont_l0 = mm.add_instruction(migraphx::make_op("contiguous"), l0); + const auto& op = migraphx::make_op("flatten"); + mm.add_instruction(op, cont_l0); + + EXPECT(mm == make_op_module("flatten", migraphx::to_value(op), mm.get_parameters())); +} + +TEST_CASE(generic_continous_gather_op_builder_test) +{ + migraphx::module mm; + auto l0 = mm.add_parameter( + "data", migraphx::shape{migraphx::shape::float_type, {{1, 4}, {4, 4}, {5, 5}, {6, 6}}}); + auto l1 = mm.add_parameter( + "indices", migraphx::shape{migraphx::shape::int32_type, {{1, 4}, {3, 3}, {4, 4}, {5, 5}}}); + auto cont_l0 = mm.add_instruction(migraphx::make_op("contiguous"), l0); + auto cont_l1 = mm.add_instruction(migraphx::make_op("contiguous"), l1); + const auto& op = migraphx::make_op("gather", {{"axis", 1}}); + mm.add_instruction(op, cont_l0, cont_l1); + + EXPECT(mm == make_op_module("gather", migraphx::to_value(op), mm.get_parameters())); +} From 25cb2776019a2485e620ccd67d4ce9809fc96e25 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 28 Oct 2025 05:31:30 -0500 Subject: [PATCH 35/70] fix tidy-check warning --- test/op/builder/binary_test.cpp | 2 +- test/op/builder/generic_op_test.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/op/builder/binary_test.cpp b/test/op/builder/binary_test.cpp index ccbbc582129..154aab2bd19 100644 --- a/test/op/builder/binary_test.cpp +++ b/test/op/builder/binary_test.cpp @@ -24,7 +24,7 @@ #include -static const std::vector op_names_set{ +const std::vector op_names_set{ "add", "div", "logical_and", "logical_or", "logical_xor", "bitwise_and", "mul", "prelu", "sub"}; TEST_CASE(binary_not_broadcasted_op_builder_test) diff --git a/test/op/builder/generic_op_test.cpp b/test/op/builder/generic_op_test.cpp index ddfbc0eecfd..77dc97149f8 100644 --- a/test/op/builder/generic_op_test.cpp +++ b/test/op/builder/generic_op_test.cpp @@ -24,7 +24,7 @@ #include -static const std::vector op_names_set{ +const std::vector op_names_set{ "abs", "acos", "acosh", "asin", "asinh", "atan", "atanh", "ceil", "cos", "cosh", "elu", "erf", "exp", "floor", "identity", "isnan", "leaky_relu", "log", "lrn", "neg", "recip", "relu", "nearbyint", "rsqrt", From 51257e1959ca033712669c2ec52ba614bb8d0eaa Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 28 Oct 2025 06:16:23 -0500 Subject: [PATCH 36/70] adding test for 'addn' op-builder --- test/op/builder/addn_test.cpp | 37 +++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 test/op/builder/addn_test.cpp diff --git a/test/op/builder/addn_test.cpp b/test/op/builder/addn_test.cpp new file mode 100644 index 00000000000..ae96fdaa1cb --- /dev/null +++ b/test/op/builder/addn_test.cpp @@ -0,0 +1,37 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2025 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 + +TEST_CASE(addn_op_builder_test) +{ + migraphx::module mm; + auto arg0 = mm.add_parameter("0", {migraphx::shape::float_type, {2, 4, 5}}); + auto arg1 = mm.add_parameter("1", {migraphx::shape::float_type, {2, 4, 5}}); + auto arg2 = mm.add_parameter("2", {migraphx::shape::float_type, {2, 4, 5}}); + auto add1 = mm.add_instruction(migraphx::make_op("add"), {arg0, arg1}); + mm.add_instruction(migraphx::make_op("add"), {add1, arg2}); + + EXPECT(mm == make_op_module("addn", migraphx::value("", {}, false), mm.get_parameters())); +} From d5ea6cde32de18d40ff738b82ecba3f4270a9c6d Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 28 Oct 2025 08:15:23 -0500 Subject: [PATCH 37/70] adding tests for the 'clip' op-builder --- test/op/builder/clip_test.cpp | 72 +++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 test/op/builder/clip_test.cpp diff --git a/test/op/builder/clip_test.cpp b/test/op/builder/clip_test.cpp new file mode 100644 index 00000000000..33cfa243c72 --- /dev/null +++ b/test/op/builder/clip_test.cpp @@ -0,0 +1,72 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2025 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 + +TEST_CASE(clip_max_and_min_op_builder_test) +{ + migraphx::module mm; + auto arg0 = mm.add_parameter("0", {migraphx::shape::float_type, {2, 4, 5}}); + auto arg1 = mm.add_parameter("1", {migraphx::shape::float_type, {2, 4, 5}}); + auto arg2 = mm.add_parameter("2", {migraphx::shape::float_type, {2, 4, 5}}); + add_common_op(mm, migraphx::make_op("clip"), {arg0, arg1, arg2}); + + EXPECT(mm == make_op_module("clip", migraphx::value("", {}, false), mm.get_parameters())); +} + +TEST_CASE(clip_only_max_op_builder_test) +{ + migraphx::module mm; + auto arg0 = mm.add_parameter("0", {migraphx::shape::float_type, {2, 4, 5}}); + mm.add_instruction(migraphx::make_op("undefined")); + auto arg2 = mm.add_parameter("2", {migraphx::shape::float_type, {2, 4, 5}}); + add_common_op(mm, migraphx::make_op("min"), {arg0, arg2}); + + migraphx::module mm_op_built; + auto arg0_op = mm_op_built.add_parameter("0", {migraphx::shape::float_type, {2, 4, 5}}); + auto arg1_op = mm_op_built.add_instruction(migraphx::make_op("undefined")); + auto arg2_op = mm_op_built.add_parameter("2", {migraphx::shape::float_type, {2, 4, 5}}); + + migraphx::op::builder::add("clip", mm_op_built, {arg0_op, arg1_op, arg2_op}); + EXPECT(mm == mm_op_built); +} + +TEST_CASE(clip_only_min_op_builder_test) +{ + migraphx::module mm; + auto arg0 = mm.add_parameter("0", {migraphx::shape::float_type, {2, 4, 5}}); + auto arg1 = mm.add_parameter("1", {migraphx::shape::float_type, {2, 4, 5}}); + add_common_op(mm, migraphx::make_op("max"), {arg0, arg1}); + + EXPECT(mm == make_op_module("clip", migraphx::value("", {}, false), mm.get_parameters())); +} + +TEST_CASE(clip_identity_op_builder_test) +{ + migraphx::module mm; + auto arg0 = mm.add_parameter("0", {migraphx::shape::float_type, {2, 4, 5}}); + add_common_op(mm, migraphx::make_op("identity"), {arg0}); + + EXPECT(mm == make_op_module("clip", migraphx::value("", {}, false), mm.get_parameters())); +} From 61329980f73914f0fe410723f048b5965be9e5a8 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 28 Oct 2025 08:24:38 -0500 Subject: [PATCH 38/70] adding test for the 'concat' op-builder --- test/op/builder/concat_test.cpp | 35 +++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 test/op/builder/concat_test.cpp diff --git a/test/op/builder/concat_test.cpp b/test/op/builder/concat_test.cpp new file mode 100644 index 00000000000..0130bca9712 --- /dev/null +++ b/test/op/builder/concat_test.cpp @@ -0,0 +1,35 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2025 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 + +TEST_CASE(concat_op_builder_test) +{ + migraphx::module mm; + auto arg0 = mm.add_parameter("0", {migraphx::shape::float_type, {2, 4, 3}}); + auto arg1 = mm.add_parameter("1", {migraphx::shape::float_type, {7, 4, 3}}); + migraphx::op::builder::add("concat", mm, {arg0, arg1}, migraphx::value("axis", 0)); + + EXPECT(mm == make_op_module("concat", migraphx::value("axis", 0), mm.get_parameters())); +} From 5ff9956623250739a1f5a91ce8685d7432d197a4 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 28 Oct 2025 08:34:30 -0500 Subject: [PATCH 39/70] adding test for the 'constant' op-builder --- test/op/builder/constant_test.cpp | 34 +++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 test/op/builder/constant_test.cpp diff --git a/test/op/builder/constant_test.cpp b/test/op/builder/constant_test.cpp new file mode 100644 index 00000000000..cb56a6a5e16 --- /dev/null +++ b/test/op/builder/constant_test.cpp @@ -0,0 +1,34 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2025 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 + +TEST_CASE(constant_op_builder_test) +{ + migraphx::module mm; + migraphx::literal lit; + mm.add_literal(lit); + + EXPECT(mm == make_op_module("constant", migraphx::to_value(lit), {})); +} From dafe01a8b40f4bf95297e5f90dbf837456932ad9 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 28 Oct 2025 08:46:04 -0500 Subject: [PATCH 40/70] adding test for the 'convert' op-builder --- test/op/builder/convert_test.cpp | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 test/op/builder/convert_test.cpp diff --git a/test/op/builder/convert_test.cpp b/test/op/builder/convert_test.cpp new file mode 100644 index 00000000000..6c355e9a975 --- /dev/null +++ b/test/op/builder/convert_test.cpp @@ -0,0 +1,35 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2025 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 + +TEST_CASE(convert_op_builder_test) +{ + migraphx::module mm; + migraphx::shape::type_t target_type = migraphx::shape::float_type; + auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 3, 4, 5}}); + mm.add_instruction(migraphx::make_op("convert", {{"target_type", target_type}}), a_arg); + + EXPECT(mm == make_op_module("convert", {{"target_type", target_type}}, mm.get_parameters())); +} From f121e41a6d4a22c84754dcb82739154b96268b28 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 28 Oct 2025 09:00:31 -0500 Subject: [PATCH 41/70] fixing tidy warnings --- test/op/builder/binary_test.cpp | 21 ++++++++++++++++----- test/op/builder/generic_op_test.cpp | 16 ++++++++++------ 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/test/op/builder/binary_test.cpp b/test/op/builder/binary_test.cpp index 154aab2bd19..541b09a1975 100644 --- a/test/op/builder/binary_test.cpp +++ b/test/op/builder/binary_test.cpp @@ -24,12 +24,23 @@ #include -const std::vector op_names_set{ - "add", "div", "logical_and", "logical_or", "logical_xor", "bitwise_and", "mul", "prelu", "sub"}; +std::vector op_names() +{ + static const std::vector op_names_set{"add", + "div", + "logical_and", + "logical_or", + "logical_xor", + "bitwise_and", + "mul", + "prelu", + "sub"}; + return op_names_set; +} TEST_CASE(binary_not_broadcasted_op_builder_test) { - std::for_each(op_names_set.begin(), op_names_set.end(), [&](const std::string& op_name) { + std::for_each(op_names().begin(), op_names().end(), [&](const std::string& op_name) { migraphx::module mm; auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 4}}); @@ -43,7 +54,7 @@ TEST_CASE(binary_not_broadcasted_op_builder_test) TEST_CASE(binary_not_broadcasted_implicit_broadcast_op_builder_test) { - std::for_each(op_names_set.begin(), op_names_set.end(), [&](const std::string& op_name) { + std::for_each(op_names().begin(), op_names().end(), [&](const std::string& op_name) { migraphx::module mm; auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 4}}); @@ -57,7 +68,7 @@ TEST_CASE(binary_not_broadcasted_implicit_broadcast_op_builder_test) TEST_CASE(binary_non_zero_broadcasted_op_builder_test) { - std::for_each(op_names_set.begin(), op_names_set.end(), [&](const std::string& op_name) { + std::for_each(op_names().begin(), op_names().end(), [&](const std::string& op_name) { migraphx::module mm; auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 3, 4, 5}}); diff --git a/test/op/builder/generic_op_test.cpp b/test/op/builder/generic_op_test.cpp index 77dc97149f8..885e84d2304 100644 --- a/test/op/builder/generic_op_test.cpp +++ b/test/op/builder/generic_op_test.cpp @@ -24,15 +24,19 @@ #include -const std::vector op_names_set{ - "abs", "acos", "acosh", "asin", "asinh", "atan", "atanh", "ceil", - "cos", "cosh", "elu", "erf", "exp", "floor", "identity", "isnan", - "leaky_relu", "log", "lrn", "neg", "recip", "relu", "nearbyint", "rsqrt", - "sigmoid", "sign", "sin", "sinh", "sqrt", "tan", "tanh", "not"}; +std::vector op_names() +{ + static const std::vector op_names_set{ + "abs", "acos", "acosh", "asin", "asinh", "atan", "atanh", "ceil", + "cos", "cosh", "elu", "erf", "exp", "floor", "identity", "isnan", + "leaky_relu", "log", "lrn", "neg", "recip", "relu", "nearbyint", "rsqrt", + "sigmoid", "sign", "sin", "sinh", "sqrt", "tan", "tanh", "not"}; + return op_names_set; +} TEST_CASE(generic_not_continous_op_builder_test) { - std::for_each(op_names_set.begin(), op_names_set.end(), [&](const std::string& op_name) { + std::for_each(op_names().begin(), op_names().end(), [&](const std::string& op_name) { migraphx::module mm; auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 4, 3, 5}}); const auto& op = migraphx::make_op(op_name); From 8508b374376dea46ddb7a35152d8c7178716769d Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 28 Oct 2025 10:24:09 -0500 Subject: [PATCH 42/70] fixing a runtime crash --- test/op/builder/binary_test.cpp | 31 ++++++++++++++++------------- test/op/builder/generic_op_test.cpp | 19 ++++++++++-------- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/test/op/builder/binary_test.cpp b/test/op/builder/binary_test.cpp index 541b09a1975..5d325bbec9b 100644 --- a/test/op/builder/binary_test.cpp +++ b/test/op/builder/binary_test.cpp @@ -24,23 +24,26 @@ #include -std::vector op_names() +namespace { - static const std::vector op_names_set{"add", - "div", - "logical_and", - "logical_or", - "logical_xor", - "bitwise_and", - "mul", - "prelu", - "sub"}; - return op_names_set; + const std::vector& binary_op_names() + { + static const std::vector op_names_set{"add", + "div", + "logical_and", + "logical_or", + "logical_xor", + "bitwise_and", + "mul", + "prelu", + "sub"}; + return op_names_set; + } } TEST_CASE(binary_not_broadcasted_op_builder_test) { - std::for_each(op_names().begin(), op_names().end(), [&](const std::string& op_name) { + std::for_each(binary_op_names().begin(), binary_op_names().end(), [&](const std::string& op_name) { migraphx::module mm; auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 4}}); @@ -54,7 +57,7 @@ TEST_CASE(binary_not_broadcasted_op_builder_test) TEST_CASE(binary_not_broadcasted_implicit_broadcast_op_builder_test) { - std::for_each(op_names().begin(), op_names().end(), [&](const std::string& op_name) { + std::for_each(binary_op_names().begin(), binary_op_names().end(), [&](const std::string& op_name) { migraphx::module mm; auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 4}}); @@ -68,7 +71,7 @@ TEST_CASE(binary_not_broadcasted_implicit_broadcast_op_builder_test) TEST_CASE(binary_non_zero_broadcasted_op_builder_test) { - std::for_each(op_names().begin(), op_names().end(), [&](const std::string& op_name) { + std::for_each(binary_op_names().begin(), binary_op_names().end(), [&](const std::string& op_name) { migraphx::module mm; auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 3, 4, 5}}); diff --git a/test/op/builder/generic_op_test.cpp b/test/op/builder/generic_op_test.cpp index 885e84d2304..bc40808e26d 100644 --- a/test/op/builder/generic_op_test.cpp +++ b/test/op/builder/generic_op_test.cpp @@ -24,19 +24,22 @@ #include -std::vector op_names() +namespace { - static const std::vector op_names_set{ - "abs", "acos", "acosh", "asin", "asinh", "atan", "atanh", "ceil", - "cos", "cosh", "elu", "erf", "exp", "floor", "identity", "isnan", - "leaky_relu", "log", "lrn", "neg", "recip", "relu", "nearbyint", "rsqrt", - "sigmoid", "sign", "sin", "sinh", "sqrt", "tan", "tanh", "not"}; - return op_names_set; + const std::vector& generic_op_names() + { + static const std::vector op_names_set{ + "abs", "acos", "acosh", "asin", "asinh", "atan", "atanh", "ceil", + "cos", "cosh", "elu", "erf", "exp", "floor", "identity", "isnan", + "leaky_relu", "log", "lrn", "neg", "recip", "relu", "nearbyint", "rsqrt", + "sigmoid", "sign", "sin", "sinh", "sqrt", "tan", "tanh", "not"}; + return op_names_set; + } } TEST_CASE(generic_not_continous_op_builder_test) { - std::for_each(op_names().begin(), op_names().end(), [&](const std::string& op_name) { + std::for_each(generic_op_names().begin(), generic_op_names().end(), [&](const std::string& op_name) { migraphx::module mm; auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 4, 3, 5}}); const auto& op = migraphx::make_op(op_name); From 438d5bef14ea3b717f3c9dfc7135c5c2b64595d1 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 28 Oct 2025 10:29:00 -0500 Subject: [PATCH 43/70] fixing formatting --- test/op/builder/binary_test.cpp | 76 +++++++++++++++-------------- test/op/builder/generic_op_test.cpp | 34 ++++++------- 2 files changed, 56 insertions(+), 54 deletions(-) diff --git a/test/op/builder/binary_test.cpp b/test/op/builder/binary_test.cpp index 5d325bbec9b..8e56bb8ab0a 100644 --- a/test/op/builder/binary_test.cpp +++ b/test/op/builder/binary_test.cpp @@ -24,63 +24,65 @@ #include -namespace +namespace { +const std::vector& binary_op_names() { - const std::vector& binary_op_names() - { - static const std::vector op_names_set{"add", - "div", - "logical_and", - "logical_or", - "logical_xor", - "bitwise_and", - "mul", - "prelu", - "sub"}; - return op_names_set; - } + static const std::vector op_names_set{"add", + "div", + "logical_and", + "logical_or", + "logical_xor", + "bitwise_and", + "mul", + "prelu", + "sub"}; + return op_names_set; } +} // namespace TEST_CASE(binary_not_broadcasted_op_builder_test) { - std::for_each(binary_op_names().begin(), binary_op_names().end(), [&](const std::string& op_name) { - migraphx::module mm; + std::for_each( + binary_op_names().begin(), binary_op_names().end(), [&](const std::string& op_name) { + migraphx::module mm; - auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 4}}); - auto b_arg = mm.add_parameter("b", {migraphx::shape::int64_type, {2, 4}}); + auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 4}}); + auto b_arg = mm.add_parameter("b", {migraphx::shape::int64_type, {2, 4}}); - add_common_op(mm, migraphx::make_op(op_name), {a_arg, b_arg}); + add_common_op(mm, migraphx::make_op(op_name), {a_arg, b_arg}); - EXPECT(mm == make_op_module(op_name, {}, mm.get_parameters())); - }); + EXPECT(mm == make_op_module(op_name, {}, mm.get_parameters())); + }); } TEST_CASE(binary_not_broadcasted_implicit_broadcast_op_builder_test) { - std::for_each(binary_op_names().begin(), binary_op_names().end(), [&](const std::string& op_name) { - migraphx::module mm; + std::for_each( + binary_op_names().begin(), binary_op_names().end(), [&](const std::string& op_name) { + migraphx::module mm; - auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 4}}); - auto b_arg = mm.add_parameter("b", {migraphx::shape::int64_type, {2, 1}}); + auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 4}}); + auto b_arg = mm.add_parameter("b", {migraphx::shape::int64_type, {2, 1}}); - add_common_op(mm, migraphx::make_op(op_name), {a_arg, b_arg}); + add_common_op(mm, migraphx::make_op(op_name), {a_arg, b_arg}); - EXPECT(mm == make_op_module(op_name, {}, mm.get_parameters())); - }); + EXPECT(mm == make_op_module(op_name, {}, mm.get_parameters())); + }); } TEST_CASE(binary_non_zero_broadcasted_op_builder_test) { - std::for_each(binary_op_names().begin(), binary_op_names().end(), [&](const std::string& op_name) { - migraphx::module mm; + std::for_each( + binary_op_names().begin(), binary_op_names().end(), [&](const std::string& op_name) { + migraphx::module mm; - auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 3, 4, 5}}); - auto b_arg = mm.add_parameter("b", {migraphx::shape::int64_type, {3, 4}}); + auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 3, 4, 5}}); + auto b_arg = mm.add_parameter("b", {migraphx::shape::int64_type, {3, 4}}); - auto l = mm.add_instruction( - migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {2, 3, 4, 5}}}), b_arg); - mm.add_instruction(migraphx::make_op(op_name), {a_arg, l}); + auto l = mm.add_instruction( + migraphx::make_op("broadcast", {{"axis", 1}, {"out_lens", {2, 3, 4, 5}}}), b_arg); + mm.add_instruction(migraphx::make_op(op_name), {a_arg, l}); - EXPECT(mm == make_op_module(op_name, {{"broadcasted_axis", 1}}, mm.get_parameters())); - }); + EXPECT(mm == make_op_module(op_name, {{"broadcasted_axis", 1}}, mm.get_parameters())); + }); } diff --git a/test/op/builder/generic_op_test.cpp b/test/op/builder/generic_op_test.cpp index bc40808e26d..c216e5e014e 100644 --- a/test/op/builder/generic_op_test.cpp +++ b/test/op/builder/generic_op_test.cpp @@ -24,29 +24,29 @@ #include -namespace +namespace { +const std::vector& generic_op_names() { - const std::vector& generic_op_names() - { - static const std::vector op_names_set{ - "abs", "acos", "acosh", "asin", "asinh", "atan", "atanh", "ceil", - "cos", "cosh", "elu", "erf", "exp", "floor", "identity", "isnan", - "leaky_relu", "log", "lrn", "neg", "recip", "relu", "nearbyint", "rsqrt", - "sigmoid", "sign", "sin", "sinh", "sqrt", "tan", "tanh", "not"}; - return op_names_set; - } + static const std::vector op_names_set{ + "abs", "acos", "acosh", "asin", "asinh", "atan", "atanh", "ceil", + "cos", "cosh", "elu", "erf", "exp", "floor", "identity", "isnan", + "leaky_relu", "log", "lrn", "neg", "recip", "relu", "nearbyint", "rsqrt", + "sigmoid", "sign", "sin", "sinh", "sqrt", "tan", "tanh", "not"}; + return op_names_set; } +} // namespace TEST_CASE(generic_not_continous_op_builder_test) { - std::for_each(generic_op_names().begin(), generic_op_names().end(), [&](const std::string& op_name) { - migraphx::module mm; - auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 4, 3, 5}}); - const auto& op = migraphx::make_op(op_name); - mm.add_instruction(op, a_arg); + std::for_each( + generic_op_names().begin(), generic_op_names().end(), [&](const std::string& op_name) { + migraphx::module mm; + auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 4, 3, 5}}); + const auto& op = migraphx::make_op(op_name); + mm.add_instruction(op, a_arg); - EXPECT(mm == make_op_module(op_name, migraphx::to_value(op), mm.get_parameters())); - }); + EXPECT(mm == make_op_module(op_name, migraphx::to_value(op), mm.get_parameters())); + }); } TEST_CASE(generic_not_continous_gathernd_op_builder_test) From 476622da395e52cf599d3d9bce60b738d77e262c Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 28 Oct 2025 11:41:21 -0500 Subject: [PATCH 44/70] adding test case; this is an edge case about which the coverage checker complained; this is when the vector of modules are not empty when it supposed to be --- test/op/builder/op_builder_test.cpp | 45 +++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 test/op/builder/op_builder_test.cpp diff --git a/test/op/builder/op_builder_test.cpp b/test/op/builder/op_builder_test.cpp new file mode 100644 index 00000000000..4b07827c4e9 --- /dev/null +++ b/test/op/builder/op_builder_test.cpp @@ -0,0 +1,45 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2025 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 + +TEST_CASE(op_builder_module_args_not_empty_no_name_param_op_builder_test) +{ + migraphx::module mm_dummy; + std::vector module_args{&mm_dummy}; + + EXPECT(test::throws( + [&] { migraphx::op::builder::add("clip", mm_dummy, {}, module_args); }, + "Module args should be empty")); +} + +TEST_CASE(op_builder_module_args_not_empty_op_builder_test) +{ + migraphx::module mm_dummy; + std::vector module_args{&mm_dummy}; + + EXPECT(test::throws( + [&] { migraphx::op::builder::add("abs", mm_dummy, {}, module_args); }, + "Module args should be empty")); +} From 3446027aa165a2d83cdbd62551a57b9ac02a3faf Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 28 Oct 2025 11:41:50 -0500 Subject: [PATCH 45/70] fix formatting --- test/op/builder/op_builder_test.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/op/builder/op_builder_test.cpp b/test/op/builder/op_builder_test.cpp index 4b07827c4e9..d4ece862e4a 100644 --- a/test/op/builder/op_builder_test.cpp +++ b/test/op/builder/op_builder_test.cpp @@ -30,8 +30,8 @@ TEST_CASE(op_builder_module_args_not_empty_no_name_param_op_builder_test) std::vector module_args{&mm_dummy}; EXPECT(test::throws( - [&] { migraphx::op::builder::add("clip", mm_dummy, {}, module_args); }, - "Module args should be empty")); + [&] { migraphx::op::builder::add("clip", mm_dummy, {}, module_args); }, + "Module args should be empty")); } TEST_CASE(op_builder_module_args_not_empty_op_builder_test) @@ -40,6 +40,6 @@ TEST_CASE(op_builder_module_args_not_empty_op_builder_test) std::vector module_args{&mm_dummy}; EXPECT(test::throws( - [&] { migraphx::op::builder::add("abs", mm_dummy, {}, module_args); }, - "Module args should be empty")); + [&] { migraphx::op::builder::add("abs", mm_dummy, {}, module_args); }, + "Module args should be empty")); } From fb388441aaafa34ceb929769b6ab427068108ab9 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 28 Oct 2025 11:54:27 -0500 Subject: [PATCH 46/70] adding test for the 'tile' op-builder --- test/op/builder/tile_test.cpp | 36 +++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 test/op/builder/tile_test.cpp diff --git a/test/op/builder/tile_test.cpp b/test/op/builder/tile_test.cpp new file mode 100644 index 00000000000..3994ce8622e --- /dev/null +++ b/test/op/builder/tile_test.cpp @@ -0,0 +1,36 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015-2025 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 + +TEST_CASE(tile_op_builder_test) +{ + migraphx::module mm; + auto input = mm.add_parameter("x", migraphx::shape{migraphx::shape::float_type, {2, 2}}); + auto l0 = mm.add_instruction(migraphx::make_op("concat", {{"axis", 0}}), input, input); + auto l1 = mm.add_instruction(migraphx::make_op("concat", {{"axis", 0}}), l0, input); + mm.add_instruction(migraphx::make_op("concat", {{"axis", 1}}), l1, l1); + + EXPECT(mm == make_op_module("tile", {{"repeats", {3, 2}}}, mm.get_parameters())); +} From ea4cea2d1c1569b1a6f60abb2c9af1a6f38f24ce Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 28 Oct 2025 15:01:34 -0500 Subject: [PATCH 47/70] fixing tidy check warnings --- src/onnx/parse_binary_op.cpp | 2 +- src/onnx/parse_generic_op.cpp | 4 ++-- src/op/builder/include/migraphx/op/builder/op_builder.hpp | 8 ++++---- src/tf/parse_addn.cpp | 2 +- src/tf/parse_binary_op.cpp | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/onnx/parse_binary_op.cpp b/src/onnx/parse_binary_op.cpp index 29b2a22a339..81032ba1154 100644 --- a/src/onnx/parse_binary_op.cpp +++ b/src/onnx/parse_binary_op.cpp @@ -48,7 +48,7 @@ struct parse_binary_op : op_parser instruction_ref parse(const op_desc& opd, const onnx_parser& parser, onnx_parser::node_info info, - std::vector args) const + const std::vector& args) const { if(args.size() != 2) MIGRAPHX_THROW("binary operators should have 2 operands"); diff --git a/src/onnx/parse_generic_op.cpp b/src/onnx/parse_generic_op.cpp index e3f5fbc5fd8..391b0061c65 100644 --- a/src/onnx/parse_generic_op.cpp +++ b/src/onnx/parse_generic_op.cpp @@ -73,8 +73,8 @@ struct parse_generic_op : op_parser instruction_ref parse(const op_desc& opd, const onnx_parser& parser, - onnx_parser::node_info info, - std::vector args) const + const onnx_parser::node_info& info, + const std::vector& args) const { const auto& op = parser.load(opd.op_name, info); return op::builder::add(opd.op_name, *info.mod, args, to_value(op)).at(0); diff --git a/src/op/builder/include/migraphx/op/builder/op_builder.hpp b/src/op/builder/include/migraphx/op/builder/op_builder.hpp index 2ff3c8cf724..ff6a0305034 100644 --- a/src/op/builder/include/migraphx/op/builder/op_builder.hpp +++ b/src/op/builder/include/migraphx/op/builder/op_builder.hpp @@ -46,7 +46,7 @@ using builder_func = MIGRAPHX_EXPORT void register_builder(const std::string& name, builder_func f); template -auto invoke_builder(std::string /*name*/, +auto invoke_builder(const std::string& /*name*/, module& m, instruction_ref ins, const std::vector& args, @@ -58,7 +58,7 @@ auto invoke_builder(std::string /*name*/, } template -auto invoke_builder(std::string /*name*/, +auto invoke_builder(const std::string& /*name*/, module& m, instruction_ref ins, const std::vector& args, @@ -72,7 +72,7 @@ auto invoke_builder(std::string /*name*/, } template -auto invoke_builder(std::string name, +auto invoke_builder(const std::string& name, module& m, instruction_ref ins, const std::vector& args, @@ -84,7 +84,7 @@ auto invoke_builder(std::string name, } template -auto invoke_builder(std::string name, +auto invoke_builder(const std::string& name, module& m, instruction_ref ins, const std::vector& args, diff --git a/src/tf/parse_addn.cpp b/src/tf/parse_addn.cpp index 0ada578ce3f..257b16d9ff6 100644 --- a/src/tf/parse_addn.cpp +++ b/src/tf/parse_addn.cpp @@ -36,7 +36,7 @@ struct parse_addn : op_parser instruction_ref parse(const op_desc& /*opd*/, const tf_parser& /*parser*/, const tf_parser::node_info& info, - std::vector args) const + const std::vector& args) const { return op::builder::add("addn", *info.mm, args).at(0); } diff --git a/src/tf/parse_binary_op.cpp b/src/tf/parse_binary_op.cpp index 55b19cea284..42b84f83396 100644 --- a/src/tf/parse_binary_op.cpp +++ b/src/tf/parse_binary_op.cpp @@ -44,7 +44,7 @@ struct parse_binary_op : op_parser instruction_ref parse(const op_desc& opd, const tf_parser& /*parser*/, const tf_parser::node_info& info, - std::vector args) const + const std::vector& args) const { if(args.size() != 2) MIGRAPHX_THROW("binary operators should have 2 operands"); From efb02bc552a0103224cf76466c25f0be7e2ce679 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 4 Nov 2025 05:30:39 -0600 Subject: [PATCH 48/70] fixing spelling typo --- test/op/builder/generic_op_test.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/op/builder/generic_op_test.cpp b/test/op/builder/generic_op_test.cpp index c216e5e014e..8674c57933f 100644 --- a/test/op/builder/generic_op_test.cpp +++ b/test/op/builder/generic_op_test.cpp @@ -36,7 +36,7 @@ const std::vector& generic_op_names() } } // namespace -TEST_CASE(generic_not_continous_op_builder_test) +TEST_CASE(generic_not_continuous_op_builder_test) { std::for_each( generic_op_names().begin(), generic_op_names().end(), [&](const std::string& op_name) { @@ -49,7 +49,7 @@ TEST_CASE(generic_not_continous_op_builder_test) }); } -TEST_CASE(generic_not_continous_gathernd_op_builder_test) +TEST_CASE(generic_not_continuous_gathernd_op_builder_test) { migraphx::module mm; auto l0 = mm.add_parameter("data", migraphx::shape{migraphx::shape::float_type, {2, 2}}); @@ -60,7 +60,7 @@ TEST_CASE(generic_not_continous_gathernd_op_builder_test) EXPECT(mm == make_op_module("gathernd", migraphx::to_value(op), mm.get_parameters())); } -TEST_CASE(generic_continous_flatten_op_builder_test) +TEST_CASE(generic_continuous_flatten_op_builder_test) { migraphx::module mm; auto l0 = mm.add_parameter( @@ -72,7 +72,7 @@ TEST_CASE(generic_continous_flatten_op_builder_test) EXPECT(mm == make_op_module("flatten", migraphx::to_value(op), mm.get_parameters())); } -TEST_CASE(generic_continous_gather_op_builder_test) +TEST_CASE(generic_continuous_gather_op_builder_test) { migraphx::module mm; auto l0 = mm.add_parameter( From d8f6178f2571291e19acef5dafe6ea8e34d4d013 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Wed, 5 Nov 2025 06:15:48 -0600 Subject: [PATCH 49/70] adding verifier test for "tile" op-builder --- test/op/builder/tile_test.cpp | 48 +++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/test/op/builder/tile_test.cpp b/test/op/builder/tile_test.cpp index 3994ce8622e..75fa2699abc 100644 --- a/test/op/builder/tile_test.cpp +++ b/test/op/builder/tile_test.cpp @@ -24,6 +24,10 @@ #include +#include +#include +#include + TEST_CASE(tile_op_builder_test) { migraphx::module mm; @@ -34,3 +38,47 @@ TEST_CASE(tile_op_builder_test) EXPECT(mm == make_op_module("tile", {{"repeats", {3, 2}}}, mm.get_parameters())); } + +TEST_CASE(tile_verify_op_builder_test) +{ + migraphx::module mm; + + const migraphx::shape sh_data = migraphx::shape{migraphx::shape::float_type, {2, 2}}; + + auto a0 = mm.add_parameter("0", sh_data); + migraphx::op::builder::add("tile", mm, {a0}, {{"repeats", {3, 2}}}); + + migraphx::program p{mm}; + p.compile(migraphx::make_target("ref")); + + std::vector data = {1.0, 2.0, 3.0, 4.0}; + migraphx::parameter_map pp; + pp["0"] = migraphx::argument(sh_data, data.data()); + + auto result = p.eval(pp).back(); + std::vector result_vector; + result.visit([&](auto output) { result_vector.assign(output.begin(), output.end()); }); + + /* + from: + [ 1.0, 2.0, + 3.0, 4.0 ] + + to: + [ 1.0, 2.0, 1.0, 2.0, + 3.0, 4.0, 3.0, 4.0, + + 1.0, 2.0, 1.0, 2.0, + 3.0, 4.0, 3.0, 4.0, + + 1.0, 2.0, 1.0, 2.0, + 3.0, 4.0, 3.0, 4.0 ] + */ + + const std::vector expected_result = { + 1.0, 2.0, 1.0, 2.0, 3.0, 4.0, 3.0, 4.0, 1.0, 2.0, 1.0, 2.0, + 3.0, 4.0, 3.0, 4.0, 1.0, 2.0, 1.0, 2.0, 3.0, 4.0, 3.0, 4.0, + }; + + EXPECT(migraphx::verify::verify_rms_range(result_vector, expected_result)); +} From cc32ca6cc75140ce9429bbd6686a64447b7a30e0 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Mon, 10 Nov 2025 05:08:03 -0600 Subject: [PATCH 50/70] fixing a crash that happened in "test_py_3.10_backend" test --- src/op/builder/concat.cpp | 53 ----------------------------------- src/op/builder/generic_op.cpp | 11 ++++---- src/op/builder/tile.cpp | 3 +- src/tf/parse_concat.cpp | 3 +- 4 files changed, 10 insertions(+), 60 deletions(-) delete mode 100644 src/op/builder/concat.cpp diff --git a/src/op/builder/concat.cpp b/src/op/builder/concat.cpp deleted file mode 100644 index 8ba61271fb2..00000000000 --- a/src/op/builder/concat.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2015-2025 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 - -namespace migraphx { -inline namespace MIGRAPHX_INLINE_NS { -namespace op { -namespace builder { - -struct concat : op_builder -{ - int64_t axis; - - template - static auto reflect(Self& self, F f) - { - return pack(f(self.axis, "axis")); - } - - std::vector - insert(module& m, instruction_ref /*ins*/, const std::vector& args) const - { - return {m.add_instruction(migraphx::make_op("concat", {{"axis", axis}}), args)}; - } -}; - -} // namespace builder -} // namespace op -} // namespace MIGRAPHX_INLINE_NS -} // namespace migraphx diff --git a/src/op/builder/generic_op.cpp b/src/op/builder/generic_op.cpp index 12c6f25846e..ecb6e5dab69 100644 --- a/src/op/builder/generic_op.cpp +++ b/src/op/builder/generic_op.cpp @@ -40,11 +40,12 @@ struct generic_op : op_builder static std::vector names() { - return {"abs", "acos", "acosh", "asin", "asinh", "atan", "atanh", - "ceil", "cos", "cosh", "elu", "erf", "exp", "flatten", - "floor", "gather", "gathernd", "identity", "isnan", "leaky_relu", "log", - "lrn", "neg", "recip", "relu", "nearbyint", "rsqrt", "sigmoid", - "sign", "sin", "sinh", "sqrt", "tan", "tanh", "not"}; + return {"abs", "acos", "acosh", "asin", "asinh", "atan", + "atanh", "ceil", "concat", "cos", "cosh", "elu", + "erf", "exp", "flatten", "floor", "gather", "gathernd", + "identity", "isnan", "leaky_relu", "log", "lrn", "neg", + "recip", "relu", "nearbyint", "rsqrt", "sigmoid", "sign", + "sin", "sinh", "sqrt", "tan", "tanh", "not"}; } std::vector insert(const std::string& op_name, diff --git a/src/op/builder/tile.cpp b/src/op/builder/tile.cpp index 1730cbcd709..dc915c3cb32 100644 --- a/src/op/builder/tile.cpp +++ b/src/op/builder/tile.cpp @@ -50,7 +50,8 @@ struct tile : op_builder auto l1 = l0; for(int j = 1; j < repeats[i]; j++) { - l0 = op::builder::add("concat", m, {l0, l1}, {{"axis", i}}).at(0); + auto op = make_op("concat", {{"axis", i}}); + l0 = op::builder::add(op.name(), m, {l0, l1}, to_value(op)).at(0); } } return {l0}; diff --git a/src/tf/parse_concat.cpp b/src/tf/parse_concat.cpp index 1055457e400..5fb25b9f626 100644 --- a/src/tf/parse_concat.cpp +++ b/src/tf/parse_concat.cpp @@ -44,7 +44,8 @@ struct parse_concat : op_parser int64_t axis = args[axis_idx]->eval().at(); const auto& concat_args = std::vector{args.begin(), args.begin() + args.size() - 1}; - return op::builder::add("concat", *info.mm, concat_args, {{"axis", axis}}).at(0); + auto op = make_op("concat", {{"axis", axis}}); + return op::builder::add(op.name(), *info.mm, concat_args, to_value(op)).at(0); } }; From 8336e34438398fb78e32956b7749409eecbaedd5 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Mon, 10 Nov 2025 07:04:42 -0600 Subject: [PATCH 51/70] adding op-builder helper function overload --- test/op/builder/concat_test.cpp | 35 ----------------------- test/op/builder/gelu_test.cpp | 8 +++--- test/op/builder/gemm_test.cpp | 2 +- test/op/builder/generic_op_test.cpp | 8 +++--- test/op/include/op_builder_test_utils.hpp | 6 ++++ 5 files changed, 15 insertions(+), 44 deletions(-) delete mode 100644 test/op/builder/concat_test.cpp diff --git a/test/op/builder/concat_test.cpp b/test/op/builder/concat_test.cpp deleted file mode 100644 index 0130bca9712..00000000000 --- a/test/op/builder/concat_test.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2015-2025 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 - -TEST_CASE(concat_op_builder_test) -{ - migraphx::module mm; - auto arg0 = mm.add_parameter("0", {migraphx::shape::float_type, {2, 4, 3}}); - auto arg1 = mm.add_parameter("1", {migraphx::shape::float_type, {7, 4, 3}}); - migraphx::op::builder::add("concat", mm, {arg0, arg1}, migraphx::value("axis", 0)); - - EXPECT(mm == make_op_module("concat", migraphx::value("axis", 0), mm.get_parameters())); -} diff --git a/test/op/builder/gelu_test.cpp b/test/op/builder/gelu_test.cpp index 0cf51e71c74..a249c4e6b6f 100644 --- a/test/op/builder/gelu_test.cpp +++ b/test/op/builder/gelu_test.cpp @@ -54,7 +54,7 @@ TEST_CASE(gelu_erf_happy_path_op_builder_test) auto add_one = add_common_op(mm, migraphx::make_op("add"), {erf, one}); add_common_op(mm, migraphx::make_op("mul"), {mul_half, add_one}); - EXPECT(mm == make_op_module("gelu_erf", {}, mm.get_parameters())); + EXPECT(mm == make_op_module("gelu_erf", mm.get_parameters())); } TEST_CASE(gelu_tanh_fast_happy_path_op_builder_test) @@ -129,7 +129,7 @@ TEST_CASE(gelu_split_happy_path_op_builder_path) const size_t last_dim_size = x->get_shape().lens().back(); auto split_left = mm.add_instruction( migraphx::make_op("slice", - {{"axes", {-1}}, {"starts", {0}}, {"ends", {last_dim_size / 2}}}), + {{"axes", {-1}}, {"starts", {0}}, {"ends", {last_dim_size / 2}}}), x); auto split_right = mm.add_instruction( migraphx::make_op( @@ -152,7 +152,7 @@ TEST_CASE(gelu_split_happy_path_op_builder_path) add_common_op(mm, migraphx::make_op("mul"), {split_left, gelu_erf}); - EXPECT(mm == make_op_module("gelu_split", {}, mm.get_parameters())); + EXPECT(mm == make_op_module("gelu_split", mm.get_parameters())); } TEST_CASE(gelu_split_invalid_dimension_op_builder_path) @@ -160,6 +160,6 @@ TEST_CASE(gelu_split_invalid_dimension_op_builder_path) migraphx::module mm; mm.add_parameter("x", {migraphx::shape::float_type, {3, 3}}); EXPECT(test::throws( - [&] { make_op_module("gelu_split", {}, mm.get_parameters()); }, + [&] { make_op_module("gelu_split", mm.get_parameters()); }, "gelu_split op_builder: BiasSplitGelu must have even last dimension which is >= 2")); } diff --git a/test/op/builder/gemm_test.cpp b/test/op/builder/gemm_test.cpp index 1ad24a073f8..5002071b094 100644 --- a/test/op/builder/gemm_test.cpp +++ b/test/op/builder/gemm_test.cpp @@ -32,7 +32,7 @@ TEST_CASE(gemm_invalid_input_dim_op_builder_test) mm.add_parameter("b", {migraphx::shape::float_type, {3, 3, 3}}); EXPECT(test::throws( - [&] { make_op_module("gemm", {}, mm.get_parameters()); }, + [&] { make_op_module("gemm", mm.get_parameters()); }, "gemm op_builder: A and B should be rank 2, A is rank 1, B is rank 3")); } diff --git a/test/op/builder/generic_op_test.cpp b/test/op/builder/generic_op_test.cpp index 8674c57933f..7f7f40b6b06 100644 --- a/test/op/builder/generic_op_test.cpp +++ b/test/op/builder/generic_op_test.cpp @@ -28,10 +28,10 @@ namespace { const std::vector& generic_op_names() { static const std::vector op_names_set{ - "abs", "acos", "acosh", "asin", "asinh", "atan", "atanh", "ceil", - "cos", "cosh", "elu", "erf", "exp", "floor", "identity", "isnan", - "leaky_relu", "log", "lrn", "neg", "recip", "relu", "nearbyint", "rsqrt", - "sigmoid", "sign", "sin", "sinh", "sqrt", "tan", "tanh", "not"}; + "abs", "acos", "acosh", "asin", "asinh", "atan", "atanh", "ceil", "concat", + "cos", "cosh", "elu", "erf", "exp", "floor", "identity", "isnan", "leaky_relu", + "log", "lrn", "neg", "recip", "relu", "nearbyint", "rsqrt", "sigmoid", "sign", + "sin", "sinh", "sqrt", "tan", "tanh", "not"}; return op_names_set; } } // namespace diff --git a/test/op/include/op_builder_test_utils.hpp b/test/op/include/op_builder_test_utils.hpp index e3b151c92e7..a585f6c6e96 100644 --- a/test/op/include/op_builder_test_utils.hpp +++ b/test/op/include/op_builder_test_utils.hpp @@ -51,4 +51,10 @@ inline migraphx::module make_op_module(const std::string& op_builder_name, return mm_op_built; } +inline migraphx::module make_op_module(const std::string& op_builder_name, + const std::vector& params) +{ + return make_op_module(op_builder_name, migraphx::value("", {}, false), params); +} + #endif From b7879acca5d1eb85ccf4d5972fbb451ad0508325 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Mon, 10 Nov 2025 07:37:19 -0600 Subject: [PATCH 52/70] fix formatting warning --- test/op/builder/gelu_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/op/builder/gelu_test.cpp b/test/op/builder/gelu_test.cpp index a249c4e6b6f..0afdbd5483c 100644 --- a/test/op/builder/gelu_test.cpp +++ b/test/op/builder/gelu_test.cpp @@ -129,7 +129,7 @@ TEST_CASE(gelu_split_happy_path_op_builder_path) const size_t last_dim_size = x->get_shape().lens().back(); auto split_left = mm.add_instruction( migraphx::make_op("slice", - {{"axes", {-1}}, {"starts", {0}}, {"ends", {last_dim_size / 2}}}), + {{"axes", {-1}}, {"starts", {0}}, {"ends", {last_dim_size / 2}}}), x); auto split_right = mm.add_instruction( migraphx::make_op( From 8efbbc7774ee6fee902c17ba6fbb0d55b435fca2 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Wed, 12 Nov 2025 03:10:57 -0600 Subject: [PATCH 53/70] modifying the tile op-builder. instead of O(N^2); the number generated instructions will be O(1) --- src/op/builder/tile.cpp | 40 ++++++++++++++----- test/onnx/parse/tile_test.cpp | 9 +++-- test/onnx/parse/tile_test_3x2.cpp | 11 +++--- test/op/builder/tile_test.cpp | 64 +++++++++++++++++++++++-------- 4 files changed, 92 insertions(+), 32 deletions(-) diff --git a/src/op/builder/tile.cpp b/src/op/builder/tile.cpp index dc915c3cb32..7344f64d2b6 100644 --- a/src/op/builder/tile.cpp +++ b/src/op/builder/tile.cpp @@ -25,6 +25,7 @@ #include #include #include +#include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { @@ -44,17 +45,38 @@ struct tile : op_builder std::vector insert(module& m, instruction_ref /*ins*/, const std::vector& args) const { - auto l0 = args[0]; - for(int i = 0; i < repeats.size(); i++) + const auto& input_shape = args[0]->get_shape(); + const auto& input_lens = input_shape.lens(); + + if(not(repeats.size() == input_lens.size())) { - auto l1 = l0; - for(int j = 1; j < repeats[i]; j++) - { - auto op = make_op("concat", {{"axis", i}}); - l0 = op::builder::add(op.name(), m, {l0, l1}, to_value(op)).at(0); - } + MIGRAPHX_THROW("tile op-builder: repeats size mismatch with input shape"); } - return {l0}; + + std::vector unsq_axes(input_lens.size()); + std::iota(unsq_axes.begin(), unsq_axes.end(), 0); + std::transform( + unsq_axes.begin(), unsq_axes.end(), unsq_axes.begin(), [](auto x) { return 2 * x; }); + + auto unsq = + m.add_instruction(migraphx::make_op("unsqueeze", {{"axes", unsq_axes}}), args[0]); + + std::vector bcast_shape_lens = unsq->get_shape().lens(); + std::for_each(unsq_axes.begin(), unsq_axes.end(), [&](int64_t axis_idx) { + bcast_shape_lens[axis_idx] = repeats[axis_idx / 2]; + }); + migraphx::shape bcast_shape{input_shape.type(), bcast_shape_lens}; + + auto mbcast = m.add_instruction( + migraphx::make_op("multibroadcast", {{"out_lens", bcast_shape.lens()}}), unsq); + + std::vector reshape_dims(bcast_shape_lens.size() / 2); + for(size_t i = 0; i < reshape_dims.size(); i++) + { + reshape_dims[i] = bcast_shape_lens[i * 2] * bcast_shape_lens[i * 2 + 1]; + } + + return {m.add_instruction(migraphx::make_op("reshape", {{"dims", reshape_dims}}), mbcast)}; } }; diff --git a/test/onnx/parse/tile_test.cpp b/test/onnx/parse/tile_test.cpp index a94d4560fef..07f01b51b4a 100644 --- a/test/onnx/parse/tile_test.cpp +++ b/test/onnx/parse/tile_test.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2025 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,8 +29,11 @@ TEST_CASE(tile_test) migraphx::program p; auto* mm = p.get_main_module(); mm->add_literal(migraphx::literal{migraphx::shape{migraphx::shape::int64_type, {2}}, {1, 2}}); - auto input = mm->add_parameter("x", migraphx::shape{migraphx::shape::float_type, {2, 2}}); - mm->add_instruction(migraphx::make_op("concat", {{"axis", 1}}), input, input); + auto input = mm->add_parameter("x", migraphx::shape{migraphx::shape::float_type, {2, 2}}); + auto unsq = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {0, 2}}}), input); + auto mbcast = mm->add_instruction( + migraphx::make_op("multibroadcast", {{"out_lens", {1, 2, 2, 2}}}), unsq); + mm->add_instruction(migraphx::make_op("reshape", {{"dims", {2, 4}}}), mbcast); auto prog = optimize_onnx("tile_test.onnx"); diff --git a/test/onnx/parse/tile_test_3x2.cpp b/test/onnx/parse/tile_test_3x2.cpp index 39a0446b60e..0547d04d941 100644 --- a/test/onnx/parse/tile_test_3x2.cpp +++ b/test/onnx/parse/tile_test_3x2.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2025 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,11 @@ TEST_CASE(tile_test_3x2) migraphx::program p; auto* mm = p.get_main_module(); mm->add_literal(migraphx::literal{migraphx::shape{migraphx::shape::int64_type, {2}}, {3, 2}}); - auto input = mm->add_parameter("x", migraphx::shape{migraphx::shape::float_type, {2, 2}}); - auto l0 = mm->add_instruction(migraphx::make_op("concat", {{"axis", 0}}), input, input); - auto l1 = mm->add_instruction(migraphx::make_op("concat", {{"axis", 0}}), l0, input); - mm->add_instruction(migraphx::make_op("concat", {{"axis", 1}}), l1, l1); + auto input = mm->add_parameter("x", migraphx::shape{migraphx::shape::float_type, {2, 2}}); + auto unsq = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {0, 2}}}), input); + auto mbcast = mm->add_instruction( + migraphx::make_op("multibroadcast", {{"out_lens", {3, 2, 2, 2}}}), unsq); + mm->add_instruction(migraphx::make_op("reshape", {{"dims", {6, 4}}}), mbcast); auto prog = optimize_onnx("tile_test_3x2.onnx"); diff --git a/test/op/builder/tile_test.cpp b/test/op/builder/tile_test.cpp index 75fa2699abc..0851def684d 100644 --- a/test/op/builder/tile_test.cpp +++ b/test/op/builder/tile_test.cpp @@ -28,36 +28,57 @@ #include #include +namespace { +std::vector +run_with_data(migraphx::module m, const migraphx::shape& input_shape, std::vector data) +{ + migraphx::program p{m}; + p.compile(migraphx::make_target("ref")); + + migraphx::parameter_map pp; + pp["x"] = migraphx::argument(input_shape, data.data()); + + migraphx::argument result = p.eval(pp).back(); + std::vector result_vector; + result.visit([&](auto output) { result_vector.assign(output.begin(), output.end()); }); + + return result_vector; +} +} // namespace + TEST_CASE(tile_op_builder_test) { migraphx::module mm; auto input = mm.add_parameter("x", migraphx::shape{migraphx::shape::float_type, {2, 2}}); - auto l0 = mm.add_instruction(migraphx::make_op("concat", {{"axis", 0}}), input, input); - auto l1 = mm.add_instruction(migraphx::make_op("concat", {{"axis", 0}}), l0, input); - mm.add_instruction(migraphx::make_op("concat", {{"axis", 1}}), l1, l1); + auto unsq = mm.add_instruction(migraphx::make_op("unsqueeze", {{"axes", {0, 2}}}), input); + auto mbcast = + mm.add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {3, 2, 2, 2}}}), unsq); + mm.add_instruction(migraphx::make_op("reshape", {{"dims", {6, 4}}}), mbcast); EXPECT(mm == make_op_module("tile", {{"repeats", {3, 2}}}, mm.get_parameters())); } -TEST_CASE(tile_verify_op_builder_test) +TEST_CASE(tile_repeats_size_mismatch_op_builder_test) { migraphx::module mm; + mm.add_parameter("x", migraphx::shape{migraphx::shape::float_type, {2, 2}}); + EXPECT(test::throws( + [&] { + make_op_module("tile", {{"repeats", {2}}}, mm.get_parameters()); + }, + "repeats size mismatch with input shape")); +} + +TEST_CASE(tile_verify_2d_op_builder_test) +{ + migraphx::module mm; const migraphx::shape sh_data = migraphx::shape{migraphx::shape::float_type, {2, 2}}; - auto a0 = mm.add_parameter("0", sh_data); + auto a0 = mm.add_parameter("x", sh_data); migraphx::op::builder::add("tile", mm, {a0}, {{"repeats", {3, 2}}}); - migraphx::program p{mm}; - p.compile(migraphx::make_target("ref")); - - std::vector data = {1.0, 2.0, 3.0, 4.0}; - migraphx::parameter_map pp; - pp["0"] = migraphx::argument(sh_data, data.data()); - - auto result = p.eval(pp).back(); - std::vector result_vector; - result.visit([&](auto output) { result_vector.assign(output.begin(), output.end()); }); + const std::vector result_vector = run_with_data(mm, sh_data, {1.0, 2.0, 3.0, 4.0}); /* from: @@ -82,3 +103,16 @@ TEST_CASE(tile_verify_op_builder_test) EXPECT(migraphx::verify::verify_rms_range(result_vector, expected_result)); } + +TEST_CASE(tile_verify_1d_op_builder_test) +{ + migraphx::module mm; + const migraphx::shape sh_data = migraphx::shape{migraphx::shape::float_type, {1}}; + + auto a0 = mm.add_parameter("x", sh_data); + migraphx::op::builder::add("tile", mm, {a0}, {{"repeats", {5}}}); + const std::vector result_vector = run_with_data(mm, sh_data, {1.0}); + const std::vector expected_result = {1.0, 1.0, 1.0, 1.0, 1.0}; + + EXPECT(migraphx::verify::verify_rms_range(result_vector, expected_result)); +} From 9b73bf685e0c96daeeaa05f07b51e09d24d764bb Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Wed, 12 Nov 2025 05:17:47 -0600 Subject: [PATCH 54/70] fix formatting warning --- test/op/builder/tile_test.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/op/builder/tile_test.cpp b/test/op/builder/tile_test.cpp index 0851def684d..c5968db30f6 100644 --- a/test/op/builder/tile_test.cpp +++ b/test/op/builder/tile_test.cpp @@ -64,9 +64,7 @@ TEST_CASE(tile_repeats_size_mismatch_op_builder_test) mm.add_parameter("x", migraphx::shape{migraphx::shape::float_type, {2, 2}}); EXPECT(test::throws( - [&] { - make_op_module("tile", {{"repeats", {2}}}, mm.get_parameters()); - }, + [&] { make_op_module("tile", {{"repeats", {2}}}, mm.get_parameters()); }, "repeats size mismatch with input shape")); } From 170245ce3aa4b07da477413768aaf33509fea0d0 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Wed, 12 Nov 2025 05:20:32 -0600 Subject: [PATCH 55/70] fix tidy check warning --- test/op/builder/tile_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/op/builder/tile_test.cpp b/test/op/builder/tile_test.cpp index c5968db30f6..4ae554f67f8 100644 --- a/test/op/builder/tile_test.cpp +++ b/test/op/builder/tile_test.cpp @@ -32,7 +32,7 @@ namespace { std::vector run_with_data(migraphx::module m, const migraphx::shape& input_shape, std::vector data) { - migraphx::program p{m}; + migraphx::program p{std::move(m)}; p.compile(migraphx::make_target("ref")); migraphx::parameter_map pp; From bc2cef728efd604081fc0c962cd540f66047a132 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Fri, 14 Nov 2025 05:14:47 -0600 Subject: [PATCH 56/70] addressing review comments --- src/onnx/parse_constant.cpp | 14 ++++----- src/op/builder/addn.cpp | 50 ------------------------------- src/op/builder/constant.cpp | 48 ----------------------------- src/op/builder/tile.cpp | 8 +++++ src/tf/parse_addn.cpp | 11 +++++-- src/tf/parse_constant.cpp | 9 +++--- test/op/builder/addn_test.cpp | 37 ----------------------- test/op/builder/constant_test.cpp | 34 --------------------- 8 files changed, 28 insertions(+), 183 deletions(-) delete mode 100644 src/op/builder/addn.cpp delete mode 100644 src/op/builder/constant.cpp delete mode 100644 test/op/builder/addn_test.cpp delete mode 100644 test/op/builder/constant_test.cpp diff --git a/src/onnx/parse_constant.cpp b/src/onnx/parse_constant.cpp index 16d06faeb97..1396cd4ca9f 100644 --- a/src/onnx/parse_constant.cpp +++ b/src/onnx/parse_constant.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2025 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 @@ -24,8 +24,8 @@ #include #include #include +#include #include -#include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { @@ -38,7 +38,7 @@ struct parse_constant : op_parser instruction_ref parse(const op_desc& /*opd*/, const onnx_parser& parser, onnx_parser::node_info info, - const std::vector& args) const + const std::vector& /*args*/) const { static const std::vector attributes = { "value", "value_float", "value_floats", "value_int", "value_ints"}; @@ -67,19 +67,17 @@ struct parse_constant : op_parser // return empty literal if(v.get_shape().elements() == 0) { - const literal lit{v.get_shape().type()}; - return op::builder::add("constant", *info.mod, args, migraphx::to_value(lit)).at(0); + return info.add_literal(literal{v.get_shape().type()}); } // if dim_size is 0, it is a scalar if(attr.has_t() and attr.t().dims_size() == 0) { migraphx::shape scalar_shape{v.get_shape().type()}; - const literal lit{scalar_shape, v.data()}; - return op::builder::add("constant", *info.mod, args, migraphx::to_value(lit)).at(0); + return info.add_literal(migraphx::literal{scalar_shape, v.data()}); } - return op::builder::add("constant", *info.mod, args, migraphx::to_value(v)).at(0); + return info.add_literal(v); } }; diff --git a/src/op/builder/addn.cpp b/src/op/builder/addn.cpp deleted file mode 100644 index d3cb84d7e37..00000000000 --- a/src/op/builder/addn.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2015-2025 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 - -namespace migraphx { -inline namespace MIGRAPHX_INLINE_NS { -namespace op { -namespace builder { - -struct addn : op_builder -{ - std::vector - insert(module& m, instruction_ref /*ins*/, const std::vector& args) const - { - instruction_ref sum = args[0]; - for(auto i = 1; i < args.size(); i++) - { - sum = op::builder::add("add", m, {sum, args[i]}).at(0); - } - return {sum}; - } -}; - -} // namespace builder -} // namespace op -} // namespace MIGRAPHX_INLINE_NS -} // namespace migraphx diff --git a/src/op/builder/constant.cpp b/src/op/builder/constant.cpp deleted file mode 100644 index f142bf9640d..00000000000 --- a/src/op/builder/constant.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2015-2025 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 - -namespace migraphx { -inline namespace MIGRAPHX_INLINE_NS { -namespace op { -namespace builder { - -struct constant : op_builder -{ - literal lit; - - void from_value(const value& v) { lit = migraphx::from_value(v); } - - std::vector - insert(module& m, instruction_ref /*ins*/, const std::vector& /*args*/) const - { - return {m.add_literal(lit)}; - } -}; - -} // namespace builder -} // namespace op -} // namespace MIGRAPHX_INLINE_NS -} // namespace migraphx diff --git a/src/op/builder/tile.cpp b/src/op/builder/tile.cpp index 7344f64d2b6..efc0fde9f6a 100644 --- a/src/op/builder/tile.cpp +++ b/src/op/builder/tile.cpp @@ -53,6 +53,14 @@ struct tile : op_builder MIGRAPHX_THROW("tile op-builder: repeats size mismatch with input shape"); } + /* + input_lens: {l0, l1, l2, ..., lN-1} - size: N + repeats: {r0, r1, r2, ..., rN-1} - size: N + after unsqueeze: {1, l0, 1, l1, 1, l2, ..., 1, lN-1}; - size: 2*N; putting 1 before each dimension + after multibroadcast: {r0, l0, r1, l1, r2, l2, ..., rN-1, lN-1}; - size: 2*N; putting r_i before each dimension + after reshape: {r0*l0, r1*l1, r2*l2, ..., rN-1*lN-1}; - size: N again; multiplying each pair of dimensions + */ + std::vector unsq_axes(input_lens.size()); std::iota(unsq_axes.begin(), unsq_axes.end(), 0); std::transform( diff --git a/src/tf/parse_addn.cpp b/src/tf/parse_addn.cpp index 257b16d9ff6..5c11e044d1a 100644 --- a/src/tf/parse_addn.cpp +++ b/src/tf/parse_addn.cpp @@ -22,7 +22,9 @@ * THE SOFTWARE. */ #include -#include +#include +#include +#include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { @@ -38,7 +40,12 @@ struct parse_addn : op_parser const tf_parser::node_info& info, const std::vector& args) const { - return op::builder::add("addn", *info.mm, args).at(0); + instruction_ref sum = args[0]; + for(auto i = 1; i < args.size(); i++) + { + sum = info.add_instruction(make_op("add"), sum, args[i]); + } + return sum; } }; diff --git a/src/tf/parse_constant.cpp b/src/tf/parse_constant.cpp index 06c010dfbff..5b1400b15b2 100644 --- a/src/tf/parse_constant.cpp +++ b/src/tf/parse_constant.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2025 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2022 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 @@ -23,7 +23,8 @@ */ #include #include -#include +#include +#include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { @@ -37,10 +38,10 @@ struct parse_constant_op : op_parser instruction_ref parse(const op_desc& /*opd*/, const tf_parser& parser, tf_parser::node_info info, - const std::vector& args) const + const std::vector& /*args*/) const { literal v = parser.parse_tensor(info.attributes.at("value").tensor()); - return op::builder::add("constant", *info.mm, args, migraphx::to_value(v)).at(0); + return info.add_literal(v); } }; diff --git a/test/op/builder/addn_test.cpp b/test/op/builder/addn_test.cpp deleted file mode 100644 index ae96fdaa1cb..00000000000 --- a/test/op/builder/addn_test.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2015-2025 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 - -TEST_CASE(addn_op_builder_test) -{ - migraphx::module mm; - auto arg0 = mm.add_parameter("0", {migraphx::shape::float_type, {2, 4, 5}}); - auto arg1 = mm.add_parameter("1", {migraphx::shape::float_type, {2, 4, 5}}); - auto arg2 = mm.add_parameter("2", {migraphx::shape::float_type, {2, 4, 5}}); - auto add1 = mm.add_instruction(migraphx::make_op("add"), {arg0, arg1}); - mm.add_instruction(migraphx::make_op("add"), {add1, arg2}); - - EXPECT(mm == make_op_module("addn", migraphx::value("", {}, false), mm.get_parameters())); -} diff --git a/test/op/builder/constant_test.cpp b/test/op/builder/constant_test.cpp deleted file mode 100644 index cb56a6a5e16..00000000000 --- a/test/op/builder/constant_test.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2015-2025 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 - -TEST_CASE(constant_op_builder_test) -{ - migraphx::module mm; - migraphx::literal lit; - mm.add_literal(lit); - - EXPECT(mm == make_op_module("constant", migraphx::to_value(lit), {})); -} From ea7e704da58681120e631368b4245ddd08f1005e Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Fri, 14 Nov 2025 06:25:20 -0600 Subject: [PATCH 57/70] addressing review comments: broadcast should be applied to the shorter input --- src/op/builder/binary.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/op/builder/binary.cpp b/src/op/builder/binary.cpp index 9827e0d4f78..b7c4c0ec8b7 100644 --- a/src/op/builder/binary.cpp +++ b/src/op/builder/binary.cpp @@ -64,12 +64,16 @@ struct binary : op_builder { if(broadcasted_axis.has_value()) { - auto l = - m.add_instruction(migraphx::make_op("broadcast", - {{"axis", broadcasted_axis.value()}, - {"out_lens", args[0]->get_shape().lens()}}), - args[1]); - return {m.add_instruction(migraphx::make_op(op_name), args[0], l)}; + const size_t shorter_instr_idx = + args[0]->get_shape().ndim() < args[1]->get_shape().ndim() ? 0 : 1; + const size_t longer_instr_idx = shorter_instr_idx == 0 ? 1 : 0; + + auto l = m.add_instruction( + migraphx::make_op("broadcast", + {{"axis", broadcasted_axis.value()}, + {"out_lens", args[longer_instr_idx]->get_shape().lens()}}), + args[shorter_instr_idx]); + return {m.add_instruction(migraphx::make_op(op_name), args[longer_instr_idx], l)}; } else { From e91dc8f5db713ddc606a72a441530a04f54a4869 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Fri, 14 Nov 2025 08:26:06 -0600 Subject: [PATCH 58/70] addressing review comments: remove convert op-builder --- src/onnx/parse_cast.cpp | 6 ++-- src/op/builder/convert.cpp | 56 -------------------------------- src/tf/parse_cast.cpp | 8 +++-- test/op/builder/convert_test.cpp | 35 -------------------- 4 files changed, 8 insertions(+), 97 deletions(-) delete mode 100644 src/op/builder/convert.cpp delete mode 100644 test/op/builder/convert_test.cpp diff --git a/src/onnx/parse_cast.cpp b/src/onnx/parse_cast.cpp index 6babb8c7203..6c2de3fac70 100644 --- a/src/onnx/parse_cast.cpp +++ b/src/onnx/parse_cast.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2025 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2022 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 @@ -23,7 +23,7 @@ */ #include #include -#include +#include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { @@ -45,7 +45,7 @@ struct parse_cast : op_parser int to_type = parser.parse_value(info.attributes.at("to")).at(); shape::type_t type = get_type(to_type); - return op::builder::add("convert", *info.mod, args, {{"target_type", type}}).at(0); + return info.add_instruction(make_op("convert", {{"target_type", type}}), args); } }; diff --git a/src/op/builder/convert.cpp b/src/op/builder/convert.cpp deleted file mode 100644 index cae698f81a9..00000000000 --- a/src/op/builder/convert.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2015-2025 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 - -namespace migraphx { -inline namespace MIGRAPHX_INLINE_NS { -namespace op { -namespace builder { - -struct convert : op_builder -{ - shape::type_t target_type; - - template - static auto reflect(Self& self, F f) - { - return pack(f(self.target_type, "target_type")); - } - - std::vector - insert(module& m, instruction_ref /*ins*/, const std::vector& args) const - { - return { - m.add_instruction(migraphx::make_op("convert", {{"target_type", target_type}}), args)}; - } -}; - -} // namespace builder -} // namespace op -} // namespace MIGRAPHX_INLINE_NS -} // namespace migraphx diff --git a/src/tf/parse_cast.cpp b/src/tf/parse_cast.cpp index 01b341d7980..4bcd2905f6f 100644 --- a/src/tf/parse_cast.cpp +++ b/src/tf/parse_cast.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2025 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2022 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 @@ -23,7 +23,9 @@ */ #include #include -#include +#include +#include +#include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { @@ -39,7 +41,7 @@ struct parse_cast : op_parser const std::vector& args) const { shape::type_t type = parser.parse_type(info.attributes.at("DstT").type()); - return op::builder::add("convert", *info.mm, args, {{"target_type", type}}).at(0); + return info.add_instruction(make_op("convert", {{"target_type", type}}), args); } }; diff --git a/test/op/builder/convert_test.cpp b/test/op/builder/convert_test.cpp deleted file mode 100644 index 6c355e9a975..00000000000 --- a/test/op/builder/convert_test.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2015-2025 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 - -TEST_CASE(convert_op_builder_test) -{ - migraphx::module mm; - migraphx::shape::type_t target_type = migraphx::shape::float_type; - auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 3, 4, 5}}); - mm.add_instruction(migraphx::make_op("convert", {{"target_type", target_type}}), a_arg); - - EXPECT(mm == make_op_module("convert", {{"target_type", target_type}}, mm.get_parameters())); -} From c9ecda0a376831f89c2aaf3528610addb8977cb8 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Fri, 14 Nov 2025 08:36:19 -0600 Subject: [PATCH 59/70] addressing review comments: rename binary op-bldr to pointwise --- src/op/builder/{binary.cpp => pointwise.cpp} | 2 +- .../{binary_test.cpp => pointwise_test.cpp} | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) rename src/op/builder/{binary.cpp => pointwise.cpp} (98%) rename test/op/builder/{binary_test.cpp => pointwise_test.cpp} (85%) diff --git a/src/op/builder/binary.cpp b/src/op/builder/pointwise.cpp similarity index 98% rename from src/op/builder/binary.cpp rename to src/op/builder/pointwise.cpp index b7c4c0ec8b7..8521e81855d 100644 --- a/src/op/builder/binary.cpp +++ b/src/op/builder/pointwise.cpp @@ -32,7 +32,7 @@ inline namespace MIGRAPHX_INLINE_NS { namespace op { namespace builder { -struct binary : op_builder +struct pointwise : op_builder { std::optional broadcasted_axis = std::nullopt; diff --git a/test/op/builder/binary_test.cpp b/test/op/builder/pointwise_test.cpp similarity index 85% rename from test/op/builder/binary_test.cpp rename to test/op/builder/pointwise_test.cpp index 8e56bb8ab0a..11ff509e6c2 100644 --- a/test/op/builder/binary_test.cpp +++ b/test/op/builder/pointwise_test.cpp @@ -25,7 +25,7 @@ #include namespace { -const std::vector& binary_op_names() +const std::vector& pointwise_op_names() { static const std::vector op_names_set{"add", "div", @@ -40,10 +40,10 @@ const std::vector& binary_op_names() } } // namespace -TEST_CASE(binary_not_broadcasted_op_builder_test) +TEST_CASE(pointwise_not_broadcasted_op_builder_test) { std::for_each( - binary_op_names().begin(), binary_op_names().end(), [&](const std::string& op_name) { + pointwise_op_names().begin(), pointwise_op_names().end(), [&](const std::string& op_name) { migraphx::module mm; auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 4}}); @@ -55,10 +55,10 @@ TEST_CASE(binary_not_broadcasted_op_builder_test) }); } -TEST_CASE(binary_not_broadcasted_implicit_broadcast_op_builder_test) +TEST_CASE(pointwise_not_broadcasted_implicit_broadcast_op_builder_test) { std::for_each( - binary_op_names().begin(), binary_op_names().end(), [&](const std::string& op_name) { + pointwise_op_names().begin(), pointwise_op_names().end(), [&](const std::string& op_name) { migraphx::module mm; auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 4}}); @@ -70,10 +70,10 @@ TEST_CASE(binary_not_broadcasted_implicit_broadcast_op_builder_test) }); } -TEST_CASE(binary_non_zero_broadcasted_op_builder_test) +TEST_CASE(pointwise_non_zero_broadcasted_op_builder_test) { std::for_each( - binary_op_names().begin(), binary_op_names().end(), [&](const std::string& op_name) { + pointwise_op_names().begin(), pointwise_op_names().end(), [&](const std::string& op_name) { migraphx::module mm; auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 3, 4, 5}}); From b72e682cac865d33e4873cd3b29d106668b19cbc Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Fri, 14 Nov 2025 09:54:38 -0600 Subject: [PATCH 60/70] addressing review comments: copilot advised change --- src/onnx/parse_binary_op.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/onnx/parse_binary_op.cpp b/src/onnx/parse_binary_op.cpp index 81032ba1154..4c076a1d512 100644 --- a/src/onnx/parse_binary_op.cpp +++ b/src/onnx/parse_binary_op.cpp @@ -53,7 +53,7 @@ struct parse_binary_op : op_parser if(args.size() != 2) MIGRAPHX_THROW("binary operators should have 2 operands"); - value options = {}; + value options("", {}, false); if(contains(info.attributes, "broadcast") and contains(info.attributes, "axis")) { uint64_t broadcasted = From f5fb0e947672beae9b2c6fa56bbd88710ead4862 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Fri, 14 Nov 2025 10:15:39 -0600 Subject: [PATCH 61/70] addressing review comments: getting rid of contiguous case in generic-op op-builder and modify tests accrodingly --- src/op/builder/generic_op.cpp | 30 ++--------------------- test/onnx/parse/flatten_dyn_test.cpp | 5 ++-- test/onnx/parse/flatten_nonstd_test.cpp | 8 +++--- test/onnx/parse/gather_dyn_test.cpp | 6 ++--- test/onnx/parse/transpose_gather_test.cpp | 16 +++--------- test/op/builder/generic_op_test.cpp | 27 -------------------- 6 files changed, 12 insertions(+), 80 deletions(-) diff --git a/src/op/builder/generic_op.cpp b/src/op/builder/generic_op.cpp index ecb6e5dab69..8c330e74258 100644 --- a/src/op/builder/generic_op.cpp +++ b/src/op/builder/generic_op.cpp @@ -48,38 +48,12 @@ struct generic_op : op_builder "sin", "sinh", "sqrt", "tan", "tanh", "not"}; } - std::vector insert(const std::string& op_name, + std::vector insert(const std::string& /*op_name*/, module& m, instruction_ref /*ins*/, const std::vector& args) const { - std::vector args_copy = args; - if(needs_contiguous(op_name)) - { - std::transform(args_copy.begin(), args_copy.end(), args_copy.begin(), [&](auto arg) { - return make_contiguous(m, arg); - }); - } - - return {m.add_instruction(op, args_copy)}; - } - - private: - bool needs_contiguous(const std::string& op_name) const - { - return contains({"flatten", "gather", "scatter"}, op_name); - } - - instruction_ref make_contiguous(module& m, instruction_ref ins) const - { - auto attr = ins->get_operator().to_value(); - std::string key = "require_std_shape"; - if((attr.get(key, false)) or (not ins->get_shape().standard())) - { - return m.add_instruction(make_op("contiguous"), ins); - } - - return ins; + return {m.add_instruction(op, args)}; } }; diff --git a/test/onnx/parse/flatten_dyn_test.cpp b/test/onnx/parse/flatten_dyn_test.cpp index dbd844fb36c..2593d66a53a 100644 --- a/test/onnx/parse/flatten_dyn_test.cpp +++ b/test/onnx/parse/flatten_dyn_test.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2024 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2025 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 @@ -30,8 +30,7 @@ TEST_CASE(flatten_dyn_test) auto* mm = p.get_main_module(); auto l0 = mm->add_parameter( "0", migraphx::shape{migraphx::shape::float_type, {{1, 4}, {3, 3}, {4, 4}, {5, 5}}}); - auto c0 = mm->add_instruction(migraphx::make_op("contiguous"), l0); - auto ret = mm->add_instruction(migraphx::make_op("flatten", {{"axis", 2}}), c0); + auto ret = mm->add_instruction(migraphx::make_op("flatten", {{"axis", 2}}), l0); mm->add_return({ret}); migraphx::onnx_options options; diff --git a/test/onnx/parse/flatten_nonstd_test.cpp b/test/onnx/parse/flatten_nonstd_test.cpp index f2d0af5542e..44118602bb3 100644 --- a/test/onnx/parse/flatten_nonstd_test.cpp +++ b/test/onnx/parse/flatten_nonstd_test.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2025 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 @@ -31,10 +31,8 @@ TEST_CASE(flatten_nonstd_test) auto l0 = mm->add_parameter("0", migraphx::shape{migraphx::shape::float_type, {2, 3, 5, 4}}); auto l1 = mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {0, 1, 3, 2}}}), l0); - auto l2 = mm->add_instruction(migraphx::make_op("contiguous"), l1); - mm->add_instruction(migraphx::make_op("flatten", {{"axis", 2}}), l2); - auto l3 = mm->add_instruction(migraphx::make_op("contiguous"), l1); - mm->add_instruction(migraphx::make_op("flatten", {{"axis", 1}}), l3); + mm->add_instruction(migraphx::make_op("flatten", {{"axis", 2}}), l1); + mm->add_instruction(migraphx::make_op("flatten", {{"axis", 1}}), l1); auto prog = optimize_onnx("flatten_nonstd_test.onnx"); EXPECT(p == prog); diff --git a/test/onnx/parse/gather_dyn_test.cpp b/test/onnx/parse/gather_dyn_test.cpp index dc2bf5c4a76..06832d86977 100644 --- a/test/onnx/parse/gather_dyn_test.cpp +++ b/test/onnx/parse/gather_dyn_test.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2024 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2025 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 @@ -32,12 +32,10 @@ TEST_CASE(gather_dyn_test) "data", migraphx::shape{migraphx::shape::float_type, {{1, 4}, {4, 4}, {5, 5}, {6, 6}}}); auto l1 = mm->add_parameter( "indices", migraphx::shape{migraphx::shape::int32_type, {{1, 4}, {3, 3}, {4, 4}, {5, 5}}}); - 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); + auto ret = mm->add_instruction(gather_op, l0, l1); mm->add_return({ret}); migraphx::onnx_options options; diff --git a/test/onnx/parse/transpose_gather_test.cpp b/test/onnx/parse/transpose_gather_test.cpp index 03b49d0a7e3..f065aa00436 100644 --- a/test/onnx/parse/transpose_gather_test.cpp +++ b/test/onnx/parse/transpose_gather_test.cpp @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2015-2025 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 @@ -27,15 +27,7 @@ TEST_CASE(transpose_gather_test) { migraphx::program p; - auto* mm = p.get_main_module(); - auto make_contiguous = [&mm](migraphx::instruction_ref ins) { - if(ins->get_shape().standard()) - { - return ins; - } - - return mm->add_instruction(migraphx::make_op("contiguous"), ins); - }; + auto* mm = p.get_main_module(); auto data = mm->add_parameter("data", migraphx::shape{migraphx::shape::float_type, {3, 5, 4, 6}}); @@ -46,9 +38,7 @@ TEST_CASE(transpose_gather_test) auto tr_ind = mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {0, 2, 1, 3}}}), ind); int axis = 1; - mm->add_instruction(migraphx::make_op("gather", {{"axis", axis}}), - make_contiguous(tr_data), - make_contiguous(tr_ind)); + mm->add_instruction(migraphx::make_op("gather", {{"axis", axis}}), tr_data, tr_ind); auto prog = optimize_onnx("transpose_gather_test.onnx"); diff --git a/test/op/builder/generic_op_test.cpp b/test/op/builder/generic_op_test.cpp index 7f7f40b6b06..6548db71994 100644 --- a/test/op/builder/generic_op_test.cpp +++ b/test/op/builder/generic_op_test.cpp @@ -59,30 +59,3 @@ TEST_CASE(generic_not_continuous_gathernd_op_builder_test) EXPECT(mm == make_op_module("gathernd", migraphx::to_value(op), mm.get_parameters())); } - -TEST_CASE(generic_continuous_flatten_op_builder_test) -{ - migraphx::module mm; - auto l0 = mm.add_parameter( - "0", migraphx::shape{migraphx::shape::float_type, {{1, 4}, {4, 4}, {5, 5}, {6, 6}}}); - auto cont_l0 = mm.add_instruction(migraphx::make_op("contiguous"), l0); - const auto& op = migraphx::make_op("flatten"); - mm.add_instruction(op, cont_l0); - - EXPECT(mm == make_op_module("flatten", migraphx::to_value(op), mm.get_parameters())); -} - -TEST_CASE(generic_continuous_gather_op_builder_test) -{ - migraphx::module mm; - auto l0 = mm.add_parameter( - "data", migraphx::shape{migraphx::shape::float_type, {{1, 4}, {4, 4}, {5, 5}, {6, 6}}}); - auto l1 = mm.add_parameter( - "indices", migraphx::shape{migraphx::shape::int32_type, {{1, 4}, {3, 3}, {4, 4}, {5, 5}}}); - auto cont_l0 = mm.add_instruction(migraphx::make_op("contiguous"), l0); - auto cont_l1 = mm.add_instruction(migraphx::make_op("contiguous"), l1); - const auto& op = migraphx::make_op("gather", {{"axis", 1}}); - mm.add_instruction(op, cont_l0, cont_l1); - - EXPECT(mm == make_op_module("gather", migraphx::to_value(op), mm.get_parameters())); -} From f106462f57c52820a52d48d52d18724ecbd13118 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Fri, 14 Nov 2025 10:18:12 -0600 Subject: [PATCH 62/70] addressing review comments: copilot advised change for readibility --- src/op/builder/tile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/op/builder/tile.cpp b/src/op/builder/tile.cpp index efc0fde9f6a..aad1060870b 100644 --- a/src/op/builder/tile.cpp +++ b/src/op/builder/tile.cpp @@ -48,7 +48,7 @@ struct tile : op_builder const auto& input_shape = args[0]->get_shape(); const auto& input_lens = input_shape.lens(); - if(not(repeats.size() == input_lens.size())) + if(repeats.size() != input_lens.size()) { MIGRAPHX_THROW("tile op-builder: repeats size mismatch with input shape"); } From 9ddd7f64efcaa11a8d95d849a664ab032d28369f Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Mon, 17 Nov 2025 06:29:22 -0600 Subject: [PATCH 63/70] addressing review comments: remove general_op op-builder; also introducing default op-builder when it's not amongst the registered ones --- src/op/builder/generic_op.cpp | 63 ----------------------------- src/op/builder/op_builder.cpp | 22 +++++++--- test/op/builder/generic_op_test.cpp | 61 ---------------------------- test/op/builder/op_builder_test.cpp | 10 ----- 4 files changed, 16 insertions(+), 140 deletions(-) delete mode 100644 src/op/builder/generic_op.cpp delete mode 100644 test/op/builder/generic_op_test.cpp diff --git a/src/op/builder/generic_op.cpp b/src/op/builder/generic_op.cpp deleted file mode 100644 index 8c330e74258..00000000000 --- a/src/op/builder/generic_op.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2015-2025 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 - -namespace migraphx { -inline namespace MIGRAPHX_INLINE_NS { -namespace op { -namespace builder { - -struct generic_op : op_builder -{ - operation op; - - void from_value(const value& v) { op = migraphx::from_value(v); } - - static std::vector names() - { - return {"abs", "acos", "acosh", "asin", "asinh", "atan", - "atanh", "ceil", "concat", "cos", "cosh", "elu", - "erf", "exp", "flatten", "floor", "gather", "gathernd", - "identity", "isnan", "leaky_relu", "log", "lrn", "neg", - "recip", "relu", "nearbyint", "rsqrt", "sigmoid", "sign", - "sin", "sinh", "sqrt", "tan", "tanh", "not"}; - } - - std::vector insert(const std::string& /*op_name*/, - module& m, - instruction_ref /*ins*/, - const std::vector& args) const - { - return {m.add_instruction(op, args)}; - } -}; - -} // namespace builder -} // namespace op -} // namespace MIGRAPHX_INLINE_NS -} // namespace migraphx diff --git a/src/op/builder/op_builder.cpp b/src/op/builder/op_builder.cpp index 6d8b06a80b6..f3f35e1a5a6 100644 --- a/src/op/builder/op_builder.cpp +++ b/src/op/builder/op_builder.cpp @@ -43,13 +43,21 @@ void register_builder(const std::string& name, builder_func f) builder_map()[name] = std::move(f); } +std::vector +default_op_builder(module& m, const std::vector& args, const value& options) +{ + const auto& op = migraphx::from_value(options); + return {m.add_instruction(op, args)}; +} + std::vector insert(const std::string& name, module& m, instruction_ref ins, const std::vector& args, const value& options) { - return at(builder_map(), name, "Builder not found: " + name)(m, ins, args, {}, options); + return contains(builder_map(), name) ? builder_map()[name](m, ins, args, {}, options) + : default_op_builder(m, args, options); } std::vector insert(const std::string& name, @@ -59,8 +67,8 @@ std::vector insert(const std::string& name, const std::vector& module_args, const value& options) { - return at(builder_map(), name, "Builder not found: " + name)( - m, ins, args, module_args, options); + return contains(builder_map(), name) ? builder_map()[name](m, ins, args, module_args, options) + : default_op_builder(m, args, options); } std::vector add(const std::string& name, @@ -68,7 +76,8 @@ std::vector add(const std::string& name, const std::vector& args, const value& options) { - return at(builder_map(), name, "Builder not found: " + name)(m, m.end(), args, {}, options); + return contains(builder_map(), name) ? builder_map()[name](m, m.end(), args, {}, options) + : default_op_builder(m, args, options); } std::vector add(const std::string& name, @@ -77,8 +86,9 @@ std::vector add(const std::string& name, const std::vector& module_args, const value& options) { - return at(builder_map(), name, "Builder not found: " + name)( - m, m.end(), args, module_args, options); + return contains(builder_map(), name) + ? builder_map()[name](m, m.end(), args, module_args, options) + : default_op_builder(m, args, options); } } // namespace builder diff --git a/test/op/builder/generic_op_test.cpp b/test/op/builder/generic_op_test.cpp deleted file mode 100644 index 6548db71994..00000000000 --- a/test/op/builder/generic_op_test.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2015-2025 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 - -namespace { -const std::vector& generic_op_names() -{ - static const std::vector op_names_set{ - "abs", "acos", "acosh", "asin", "asinh", "atan", "atanh", "ceil", "concat", - "cos", "cosh", "elu", "erf", "exp", "floor", "identity", "isnan", "leaky_relu", - "log", "lrn", "neg", "recip", "relu", "nearbyint", "rsqrt", "sigmoid", "sign", - "sin", "sinh", "sqrt", "tan", "tanh", "not"}; - return op_names_set; -} -} // namespace - -TEST_CASE(generic_not_continuous_op_builder_test) -{ - std::for_each( - generic_op_names().begin(), generic_op_names().end(), [&](const std::string& op_name) { - migraphx::module mm; - auto a_arg = mm.add_parameter("a", {migraphx::shape::int64_type, {2, 4, 3, 5}}); - const auto& op = migraphx::make_op(op_name); - mm.add_instruction(op, a_arg); - - EXPECT(mm == make_op_module(op_name, migraphx::to_value(op), mm.get_parameters())); - }); -} - -TEST_CASE(generic_not_continuous_gathernd_op_builder_test) -{ - migraphx::module mm; - auto l0 = mm.add_parameter("data", migraphx::shape{migraphx::shape::float_type, {2, 2}}); - auto l1 = mm.add_parameter("indices", migraphx::shape{migraphx::shape::int64_type, {2, 2}}); - const auto& op = migraphx::make_op("gathernd"); - mm.add_instruction(op, l0, l1); - - EXPECT(mm == make_op_module("gathernd", migraphx::to_value(op), mm.get_parameters())); -} diff --git a/test/op/builder/op_builder_test.cpp b/test/op/builder/op_builder_test.cpp index d4ece862e4a..6adabc77b1d 100644 --- a/test/op/builder/op_builder_test.cpp +++ b/test/op/builder/op_builder_test.cpp @@ -33,13 +33,3 @@ TEST_CASE(op_builder_module_args_not_empty_no_name_param_op_builder_test) [&] { migraphx::op::builder::add("clip", mm_dummy, {}, module_args); }, "Module args should be empty")); } - -TEST_CASE(op_builder_module_args_not_empty_op_builder_test) -{ - migraphx::module mm_dummy; - std::vector module_args{&mm_dummy}; - - EXPECT(test::throws( - [&] { migraphx::op::builder::add("abs", mm_dummy, {}, module_args); }, - "Module args should be empty")); -} From a045e9812e92821b9b46657154a095cb8cce41f6 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Mon, 17 Nov 2025 08:53:22 -0600 Subject: [PATCH 64/70] fixing formatting warning --- src/op/builder/tile.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/op/builder/tile.cpp b/src/op/builder/tile.cpp index aad1060870b..1dadb654ffd 100644 --- a/src/op/builder/tile.cpp +++ b/src/op/builder/tile.cpp @@ -56,9 +56,10 @@ struct tile : op_builder /* input_lens: {l0, l1, l2, ..., lN-1} - size: N repeats: {r0, r1, r2, ..., rN-1} - size: N - after unsqueeze: {1, l0, 1, l1, 1, l2, ..., 1, lN-1}; - size: 2*N; putting 1 before each dimension - after multibroadcast: {r0, l0, r1, l1, r2, l2, ..., rN-1, lN-1}; - size: 2*N; putting r_i before each dimension - after reshape: {r0*l0, r1*l1, r2*l2, ..., rN-1*lN-1}; - size: N again; multiplying each pair of dimensions + after unsqueeze: {1, l0, 1, l1, 1, l2, ..., 1, lN-1}; - size: 2*N; putting 1 before + each dimension after multibroadcast: {r0, l0, r1, l1, r2, l2, ..., rN-1, lN-1}; - size: 2*N; + putting r_i before each dimension after reshape: {r0*l0, r1*l1, r2*l2, ..., + rN-1*lN-1}; - size: N again; multiplying each pair of dimensions */ std::vector unsq_axes(input_lens.size()); From 49a88e97fe24ea64e5cd904714b7065c657138cd Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Mon, 17 Nov 2025 08:58:11 -0600 Subject: [PATCH 65/70] fixing tidy-check warning --- src/op/builder/op_builder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/op/builder/op_builder.cpp b/src/op/builder/op_builder.cpp index f3f35e1a5a6..da9af09024c 100644 --- a/src/op/builder/op_builder.cpp +++ b/src/op/builder/op_builder.cpp @@ -43,7 +43,7 @@ void register_builder(const std::string& name, builder_func f) builder_map()[name] = std::move(f); } -std::vector +static std::vector default_op_builder(module& m, const std::vector& args, const value& options) { const auto& op = migraphx::from_value(options); From 3ee9274ea702496782bd652ba4b0d12ea68ed170 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Mon, 1 Dec 2025 07:52:36 -0600 Subject: [PATCH 66/70] addressing new review comments --- .../include/migraphx/onnx/onnx_parser.hpp | 1 + src/onnx/onnx_parser.cpp | 10 +++++++-- src/onnx/parse_generic_op.cpp | 4 ++-- .../include/migraphx/op/builder/insert.hpp | 10 +++++---- src/op/builder/op_builder.cpp | 22 +++++++++++++------ 5 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/onnx/include/migraphx/onnx/onnx_parser.hpp b/src/onnx/include/migraphx/onnx/onnx_parser.hpp index bdf0e4f610b..b60be93f336 100644 --- a/src/onnx/include/migraphx/onnx/onnx_parser.hpp +++ b/src/onnx/include/migraphx/onnx/onnx_parser.hpp @@ -110,6 +110,7 @@ struct onnx_parser std::unordered_map ops; onnx_parser(); + value load_to_value(const std::string& name, const node_info& info) const; operation load(const std::string& name, const node_info& info) const; void parse_undefined(module* mod, const std::string& name); diff --git a/src/onnx/onnx_parser.cpp b/src/onnx/onnx_parser.cpp index 11c5b0bb307..39e3502a120 100644 --- a/src/onnx/onnx_parser.cpp +++ b/src/onnx/onnx_parser.cpp @@ -204,7 +204,7 @@ onnx_parser::onnx_parser() ops.emplace(name, get_op_parser(name)); } -operation onnx_parser::load(const std::string& name, const node_info& info) const +value onnx_parser::load_to_value(const std::string& name, const node_info& info) const { auto op = make_op(name); auto v = op.to_value(); @@ -228,7 +228,13 @@ operation onnx_parser::load(const std::string& name, const node_info& info) cons s.visit([&](auto y) { x = y.front(); }); } } - op.from_value(v); + return v; +} + +operation onnx_parser::load(const std::string& name, const node_info& info) const +{ + auto op = make_op(name); + op.from_value(load_to_value(name, info)); return op; } diff --git a/src/onnx/parse_generic_op.cpp b/src/onnx/parse_generic_op.cpp index 391b0061c65..416a1f4a5e6 100644 --- a/src/onnx/parse_generic_op.cpp +++ b/src/onnx/parse_generic_op.cpp @@ -76,8 +76,8 @@ struct parse_generic_op : op_parser const onnx_parser::node_info& info, const std::vector& args) const { - const auto& op = parser.load(opd.op_name, info); - return op::builder::add(opd.op_name, *info.mod, args, to_value(op)).at(0); + const auto& val = parser.load_to_value(opd.op_name, info); + return op::builder::add(opd.op_name, *info.mod, args, val).at(0); } }; diff --git a/src/op/builder/include/migraphx/op/builder/insert.hpp b/src/op/builder/include/migraphx/op/builder/insert.hpp index 91d3c46edc0..dcc9020cfe1 100644 --- a/src/op/builder/include/migraphx/op/builder/insert.hpp +++ b/src/op/builder/include/migraphx/op/builder/insert.hpp @@ -35,29 +35,31 @@ inline namespace MIGRAPHX_INLINE_NS { namespace op { namespace builder { +value get_default_options(); + MIGRAPHX_EXPORT std::vector insert(const std::string& name, module& m, instruction_ref ins, const std::vector& args, - const value& options = value("", {}, false)); + const value& options = get_default_options()); MIGRAPHX_EXPORT std::vector insert(const std::string& name, module& m, instruction_ref ins, const std::vector& args, const std::vector& module_args, - const value& options = value("", {}, false)); + const value& options = get_default_options()); MIGRAPHX_EXPORT std::vector add(const std::string& name, module& m, const std::vector& args, - const value& options = value("", {}, false)); + const value& options = get_default_options()); MIGRAPHX_EXPORT std::vector add(const std::string& name, module& m, const std::vector& args, const std::vector& module_args, - const value& options = value("", {}, false)); + const value& options = get_default_options()); template instruction_ref insert_common_op(module& m, instruction_ref ins, const std::string& op_name, Ins... args) diff --git a/src/op/builder/op_builder.cpp b/src/op/builder/op_builder.cpp index da9af09024c..151f2fbaf9f 100644 --- a/src/op/builder/op_builder.cpp +++ b/src/op/builder/op_builder.cpp @@ -32,6 +32,12 @@ inline namespace MIGRAPHX_INLINE_NS { namespace op { namespace builder { +value get_default_options() +{ + value default_value = value("", {}, false); + return default_value; +} + static std::unordered_map& builder_map() { static std::unordered_map m; // NOLINT @@ -43,10 +49,12 @@ void register_builder(const std::string& name, builder_func f) builder_map()[name] = std::move(f); } -static std::vector -default_op_builder(module& m, const std::vector& args, const value& options) +static std::vector default_op_builder(module& m, + const std::vector& args, + const std::string& name, + const value& options) { - const auto& op = migraphx::from_value(options); + const auto& op = make_op(name, options); return {m.add_instruction(op, args)}; } @@ -57,7 +65,7 @@ std::vector insert(const std::string& name, const value& options) { return contains(builder_map(), name) ? builder_map()[name](m, ins, args, {}, options) - : default_op_builder(m, args, options); + : default_op_builder(m, args, name, options); } std::vector insert(const std::string& name, @@ -68,7 +76,7 @@ std::vector insert(const std::string& name, const value& options) { return contains(builder_map(), name) ? builder_map()[name](m, ins, args, module_args, options) - : default_op_builder(m, args, options); + : default_op_builder(m, args, name, options); } std::vector add(const std::string& name, @@ -77,7 +85,7 @@ std::vector add(const std::string& name, const value& options) { return contains(builder_map(), name) ? builder_map()[name](m, m.end(), args, {}, options) - : default_op_builder(m, args, options); + : default_op_builder(m, args, name, options); } std::vector add(const std::string& name, @@ -88,7 +96,7 @@ std::vector add(const std::string& name, { return contains(builder_map(), name) ? builder_map()[name](m, m.end(), args, module_args, options) - : default_op_builder(m, args, options); + : default_op_builder(m, args, name, options); } } // namespace builder From 70564e05c98e47bb46352852d8acd5426068e85f Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 2 Dec 2025 03:47:11 -0600 Subject: [PATCH 67/70] fixing failing test after review comment related modifications --- src/tf/parse_concat.cpp | 2 +- src/tf/parse_generic_op.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tf/parse_concat.cpp b/src/tf/parse_concat.cpp index 5fb25b9f626..7093265fb81 100644 --- a/src/tf/parse_concat.cpp +++ b/src/tf/parse_concat.cpp @@ -45,7 +45,7 @@ struct parse_concat : op_parser const auto& concat_args = std::vector{args.begin(), args.begin() + args.size() - 1}; auto op = make_op("concat", {{"axis", axis}}); - return op::builder::add(op.name(), *info.mm, concat_args, to_value(op)).at(0); + return op::builder::add(op.name(), *info.mm, concat_args, op.to_value()).at(0); } }; diff --git a/src/tf/parse_generic_op.cpp b/src/tf/parse_generic_op.cpp index 2fd2111b81e..0c8c06ffb54 100644 --- a/src/tf/parse_generic_op.cpp +++ b/src/tf/parse_generic_op.cpp @@ -51,7 +51,7 @@ struct parse_generic_op : op_parser const std::vector& args) const { const auto& op = make_op(opd.op_name); - return op::builder::add(opd.op_name, *info.mm, args, to_value(op)).at(0); + return op::builder::add(opd.op_name, *info.mm, args, op.to_value()).at(0); } }; From 141562063c67770836fe4b63cb84130545596b23 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 2 Dec 2025 07:11:57 -0600 Subject: [PATCH 68/70] fixing cppcheck error --- src/op/builder/op_builder.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/op/builder/op_builder.cpp b/src/op/builder/op_builder.cpp index 151f2fbaf9f..f9dc326fe43 100644 --- a/src/op/builder/op_builder.cpp +++ b/src/op/builder/op_builder.cpp @@ -32,11 +32,7 @@ inline namespace MIGRAPHX_INLINE_NS { namespace op { namespace builder { -value get_default_options() -{ - value default_value = value("", {}, false); - return default_value; -} +value get_default_options() { return value("", {}, false); } static std::unordered_map& builder_map() { From aca3da2bdef13e4d1a89c5ff342571a42de9d282 Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Tue, 2 Dec 2025 08:06:59 -0600 Subject: [PATCH 69/70] the only way to avoid tidy-check failure is to disable it for this line; otherwise the wrong constructor would be called --- src/op/builder/op_builder.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/op/builder/op_builder.cpp b/src/op/builder/op_builder.cpp index f9dc326fe43..5bbde49405f 100644 --- a/src/op/builder/op_builder.cpp +++ b/src/op/builder/op_builder.cpp @@ -32,6 +32,7 @@ inline namespace MIGRAPHX_INLINE_NS { namespace op { namespace builder { +// NOLINTNEXTLINE(modernize-return-braced-init-list) value get_default_options() { return value("", {}, false); } static std::unordered_map& builder_map() From 9349d7ca3bb9e0159dd6a9837f46e3d5727ea53c Mon Sep 17 00:00:00 2001 From: Gyula Chinoradszki Date: Wed, 17 Dec 2025 02:59:06 -0600 Subject: [PATCH 70/70] addressing review comments: new function registered for op-builder to be able to convert them into value objects --- src/onnx/onnx_parser.cpp | 24 ++++++++++--- .../migraphx/op/builder/op_builder.hpp | 22 ++++++++++-- src/op/builder/op_builder.cpp | 34 ++++++++++++------- 3 files changed, 60 insertions(+), 20 deletions(-) diff --git a/src/onnx/onnx_parser.cpp b/src/onnx/onnx_parser.cpp index 39e3502a120..947bf317993 100644 --- a/src/onnx/onnx_parser.cpp +++ b/src/onnx/onnx_parser.cpp @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include #include @@ -206,8 +208,20 @@ onnx_parser::onnx_parser() value onnx_parser::load_to_value(const std::string& name, const node_info& info) const { - auto op = make_op(name); - auto v = op.to_value(); + value v{}; + if(has_op(name)) + { + v = make_op(name).to_value(); + } + else if(op::builder::has_op_builder(name)) + { + v = op::builder::get_op_builder_value(name); + } + else + { + MIGRAPHX_THROW("LOAD_TO_VALUE: Operator|OpBuilder not found: " + name); + } + for(auto&& x : v) { if(info.attributes.count(x.get_key()) == 0) @@ -672,9 +686,9 @@ static shape parse_tensor_shape(const onnx::TensorProto& t) literal onnx_parser::parse_tensor(const onnx::TensorProto& t) const { - auto tensor_shape = parse_tensor_shape(t); - const auto& dims = tensor_shape.lens(); - auto type = tensor_shape.type(); + auto tensor_shape = parse_tensor_shape(t); + const auto& dims = tensor_shape.lens(); + auto type = tensor_shape.type(); const auto& external_data = t.external_data(); if(not external_data.empty()) diff --git a/src/op/builder/include/migraphx/op/builder/op_builder.hpp b/src/op/builder/include/migraphx/op/builder/op_builder.hpp index ff6a0305034..f7e10e26ed4 100644 --- a/src/op/builder/include/migraphx/op/builder/op_builder.hpp +++ b/src/op/builder/include/migraphx/op/builder/op_builder.hpp @@ -43,7 +43,15 @@ using builder_func = const std::vector& module_args, const value& options)>; -MIGRAPHX_EXPORT void register_builder(const std::string& name, builder_func f); +using to_value_func = std::function; + +struct op_builder_if +{ + builder_func bld_func; + to_value_func to_val_func; +}; + +MIGRAPHX_EXPORT void register_builder(const std::string& name, op_builder_if opb_if); template auto invoke_builder(const std::string& /*name*/, @@ -97,6 +105,12 @@ auto invoke_builder(const std::string& name, return x.insert(name, m, ins, args); } +template +value get_op_builder_value() +{ + return migraphx::to_value(T{}); +} + template void register_builder() { @@ -109,7 +123,8 @@ void register_builder() const value& options) { return invoke_builder(name, m, ins, args, module_args, options); }; - register_builder(name, std::move(f)); + to_value_func tvf = []() { return get_op_builder_value(); }; + register_builder(name, op_builder_if{std::move(f), std::move(tvf)}); } } @@ -132,6 +147,9 @@ struct op_builder : auto_register } }; +MIGRAPHX_EXPORT bool has_op_builder(const std::string& name); +MIGRAPHX_EXPORT value get_op_builder_value(const std::string& name); + } // namespace builder } // namespace op } // namespace MIGRAPHX_INLINE_NS diff --git a/src/op/builder/op_builder.cpp b/src/op/builder/op_builder.cpp index 5bbde49405f..b1c06c0c2ae 100644 --- a/src/op/builder/op_builder.cpp +++ b/src/op/builder/op_builder.cpp @@ -23,7 +23,6 @@ */ #include -#include #include #include @@ -35,15 +34,24 @@ namespace builder { // NOLINTNEXTLINE(modernize-return-braced-init-list) value get_default_options() { return value("", {}, false); } -static std::unordered_map& builder_map() +static std::unordered_map& builder_map() { - static std::unordered_map m; // NOLINT + static std::unordered_map m; // NOLINT return m; } -void register_builder(const std::string& name, builder_func f) +bool has_op_builder(const std::string& name) { return builder_map().count(name) == 1; } + +void register_builder(const std::string& name, op_builder_if opb_if) +{ + builder_map()[name] = std::move(opb_if); +} + +value get_op_builder_value(const std::string& name) { - builder_map()[name] = std::move(f); + if(not has_op_builder(name)) + MIGRAPHX_THROW("GET_OP_BUILDER_VALUE: OpBuilder not found: " + name); + return builder_map().at(name).to_val_func(); } static std::vector default_op_builder(module& m, @@ -61,8 +69,8 @@ std::vector insert(const std::string& name, const std::vector& args, const value& options) { - return contains(builder_map(), name) ? builder_map()[name](m, ins, args, {}, options) - : default_op_builder(m, args, name, options); + return has_op_builder(name) ? builder_map()[name].bld_func(m, ins, args, {}, options) + : default_op_builder(m, args, name, options); } std::vector insert(const std::string& name, @@ -72,8 +80,8 @@ std::vector insert(const std::string& name, const std::vector& module_args, const value& options) { - return contains(builder_map(), name) ? builder_map()[name](m, ins, args, module_args, options) - : default_op_builder(m, args, name, options); + return has_op_builder(name) ? builder_map()[name].bld_func(m, ins, args, module_args, options) + : default_op_builder(m, args, name, options); } std::vector add(const std::string& name, @@ -81,8 +89,8 @@ std::vector add(const std::string& name, const std::vector& args, const value& options) { - return contains(builder_map(), name) ? builder_map()[name](m, m.end(), args, {}, options) - : default_op_builder(m, args, name, options); + return has_op_builder(name) ? builder_map()[name].bld_func(m, m.end(), args, {}, options) + : default_op_builder(m, args, name, options); } std::vector add(const std::string& name, @@ -91,8 +99,8 @@ std::vector add(const std::string& name, const std::vector& module_args, const value& options) { - return contains(builder_map(), name) - ? builder_map()[name](m, m.end(), args, module_args, options) + return has_op_builder(name) + ? builder_map()[name].bld_func(m, m.end(), args, module_args, options) : default_op_builder(m, args, name, options); }