From 3b461ad3646c624c803bf06e2d16053b5a02f7d3 Mon Sep 17 00:00:00 2001 From: charlie Date: Fri, 26 Jun 2026 11:59:13 -0500 Subject: [PATCH 1/8] Initial --- src/include/migraphx/op/slice.hpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/include/migraphx/op/slice.hpp b/src/include/migraphx/op/slice.hpp index ab601ec0ed5..215f508cdbf 100644 --- a/src/include/migraphx/op/slice.hpp +++ b/src/include/migraphx/op/slice.hpp @@ -277,7 +277,15 @@ struct slice return not input_shape.dyn_dims()[axis].is_fixed(); })) { - MIGRAPHX_THROW("SLICE 1_arg: slicing is not allowed on non-fixed dynamic input axis "); + if(inputs_shape.symbolic()) + MIGRAPHX_THROW("SLICE 1_arg: slicing is not allowed on non-fixed symbolic input axis "); + // attributes are not normalized for this case. + auto dds = input_shape.dyn_dims(); + auto new_dds = dds; + std::transform(dds.begin(), dds.end(), new_dds.begin(), [&](auto dd){ + return {0, dd.get_interval().max()} + }); + return shape{input_shape.type(), new_dds}; } auto new_lens = lens_calc(input_shape.max_lens(), this->starts, this->ends, this->axes); From 670e261b0e072d1d200d003ec619282815a0676a Mon Sep 17 00:00:00 2001 From: charlie Date: Fri, 26 Jun 2026 12:28:53 -0500 Subject: [PATCH 2/8] add test and fixes --- src/include/migraphx/op/slice.hpp | 12 +++---- test/op_shape_test.cpp | 53 ++++++++++++++++++++++++++----- 2 files changed, 51 insertions(+), 14 deletions(-) diff --git a/src/include/migraphx/op/slice.hpp b/src/include/migraphx/op/slice.hpp index 215f508cdbf..f3cd386b07d 100644 --- a/src/include/migraphx/op/slice.hpp +++ b/src/include/migraphx/op/slice.hpp @@ -277,15 +277,15 @@ struct slice return not input_shape.dyn_dims()[axis].is_fixed(); })) { - if(inputs_shape.symbolic()) + if(input_shape.symbolic()) MIGRAPHX_THROW("SLICE 1_arg: slicing is not allowed on non-fixed symbolic input axis "); // attributes are not normalized for this case. auto dds = input_shape.dyn_dims(); - auto new_dds = dds; - std::transform(dds.begin(), dds.end(), new_dds.begin(), [&](auto dd){ - return {0, dd.get_interval().max()} - }); - return shape{input_shape.type(), new_dds}; + for(auto axis : this->axes) + { + dds[axis] = {0, dds[axis].get_interval().max}; + } + return shape{input_shape.type(), dds}; } auto new_lens = lens_calc(input_shape.max_lens(), this->starts, this->ends, this->axes); diff --git a/test/op_shape_test.cpp b/test/op_shape_test.cpp index d4c521f7369..85b172356f1 100644 --- a/test/op_shape_test.cpp +++ b/test/op_shape_test.cpp @@ -5217,16 +5217,12 @@ TEST_CASE(slice_dyn_shape2) TEST_CASE(slice_dyn_shape3) { - // TODO: When non-fixed dimension slicing is allowed, Slice to a size smaller than min. - // Until then, this action is an error. + // Slicing a non-fixed dynamic dimension relaxes only the sliced axis to {0, max}; + // non-sliced axes are left unchanged. migraphx::shape input{migraphx::shape::int32_type, {{2, 3}, {7, 8}, {2, 3}}}; - throws_shape(migraphx::make_op("slice", {{"axes", {1}}, {"starts", {0}}, {"ends", {1}}}), + expect_shape(migraphx::shape{migraphx::shape::int32_type, {{2, 3}, {0, 8}, {2, 3}}}, + migraphx::make_op("slice", {{"axes", {1}}, {"starts", {0}}, {"ends", {1}}}), input); - // clang-format off - // expect_shape(migraphx::shape{migraphx::shape::int32_type, {{2, 3}, {1, 1}, {2, 3}}}, - // migraphx::make_op("slice", {{"axes", {1}}, {"starts", {0}}, {"ends", {1}}}), - // input); - // clang-format on } TEST_CASE(slice_dyn_shape4) @@ -5258,6 +5254,47 @@ TEST_CASE(slice_dyn_preserves_optimals) input); } +TEST_CASE(slice_dyn_nonfixed_axis) +{ + // Slicing a single non-fixed dynamic axis relaxes only that axis to {0, max}. + migraphx::shape input{migraphx::shape::int32_type, {{2, 3}, {7, 8}, {2, 3}}}; + expect_shape(migraphx::shape{migraphx::shape::int32_type, {{2, 3}, {0, 8}, {2, 3}}}, + migraphx::make_op("slice", {{"axes", {1}}, {"starts", {1}}, {"ends", {4}}}), + input); +} + +TEST_CASE(slice_dyn_nonfixed_multi_axis) +{ + // Slicing multiple axes where one is non-fixed: only the sliced axes are relaxed, + // the non-sliced axis (2) is left unchanged. + migraphx::shape input{migraphx::shape::int32_type, {{2, 4}, {7, 8}, {2, 3}}}; + expect_shape( + migraphx::shape{migraphx::shape::int32_type, {{0, 4}, {0, 8}, {2, 3}}}, + migraphx::make_op("slice", {{"axes", {0, 1}}, {"starts", {1, 1}}, {"ends", {2, 4}}}), + input); +} + +TEST_CASE(slice_dyn_fixed_axis_with_nonfixed_neighbors) +{ + // Only a fixed axis (1) is sliced; the non-fixed neighbors (0, 2) are not sliced, + // so the relax branch is not taken and the slice computes normally. + migraphx::shape input{migraphx::shape::int32_type, {{2, 4}, {7, 7}, {2, 5}}}; + expect_shape(migraphx::shape{migraphx::shape::int32_type, {{2, 4}, {3, 3}, {2, 5}}}, + migraphx::make_op("slice", {{"axes", {1}}, {"starts", {1}}, {"ends", {4}}}), + input); +} + +TEST_CASE(slice_dyn_nonfixed_keeps_other_optimals) +{ + // Non-sliced axes keep their optimals; the sliced non-fixed axis is relaxed to {0, max}. + migraphx::shape input{migraphx::shape::int32_type, {dd{2, 4, {3}}, dd{7, 8}, dd{2, 5, {3, 4}}}}; + migraphx::shape expected{migraphx::shape::int32_type, + {dd{2, 4, {3}}, dd{0, 8}, dd{2, 5, {3, 4}}}}; + expect_shape(expected, + migraphx::make_op("slice", {{"axes", {1}}, {"starts", {1}}, {"ends", {4}}}), + input); +} + TEST_CASE(slice_sym) { auto n = var("n", {1, 8}); From 49ddbb4a40cf6261e07bdedc30a9d7580d864815 Mon Sep 17 00:00:00 2001 From: charlie Date: Fri, 26 Jun 2026 12:31:32 -0500 Subject: [PATCH 3/8] Add changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a23322b27b..d0f177bb0a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,7 @@ Full documentation for MIGraphX is available at * Updated `QLinearConv` bias handling to dequantize bias using the product of input and weight scales before adding to the convolution output. * Updated netron output to create an ONNX-like protobuff. Now also includes debug symbols if enabled. (#4701) * Updated python API to allow getting and adding debug symbols from instructions. (#4803) +* Allow for 1 arg slicing over a dynamic dimension. (#5015) ### Resolved issues From 9a96c6beab114d57575465c73ce4e11d1534d912 Mon Sep 17 00:00:00 2001 From: charlie Date: Fri, 26 Jun 2026 12:49:19 -0500 Subject: [PATCH 4/8] Formatting --- src/include/migraphx/op/slice.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/include/migraphx/op/slice.hpp b/src/include/migraphx/op/slice.hpp index f3cd386b07d..b56e55bb871 100644 --- a/src/include/migraphx/op/slice.hpp +++ b/src/include/migraphx/op/slice.hpp @@ -278,7 +278,10 @@ struct slice })) { if(input_shape.symbolic()) - MIGRAPHX_THROW("SLICE 1_arg: slicing is not allowed on non-fixed symbolic input axis "); + { + MIGRAPHX_THROW( + "SLICE 1_arg: slicing is not allowed on non-fixed symbolic input axis "); + } // attributes are not normalized for this case. auto dds = input_shape.dyn_dims(); for(auto axis : this->axes) From e41bad6a26808a2b59dd3a4d8568980f85cbc0b2 Mon Sep 17 00:00:00 2001 From: charlie Date: Fri, 26 Jun 2026 13:25:51 -0500 Subject: [PATCH 5/8] formatting --- src/include/migraphx/op/slice.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/migraphx/op/slice.hpp b/src/include/migraphx/op/slice.hpp index b56e55bb871..bb5e69c7da8 100644 --- a/src/include/migraphx/op/slice.hpp +++ b/src/include/migraphx/op/slice.hpp @@ -280,7 +280,7 @@ struct slice if(input_shape.symbolic()) { MIGRAPHX_THROW( - "SLICE 1_arg: slicing is not allowed on non-fixed symbolic input axis "); + "SLICE 1_arg: slicing is not allowed on non-fixed symbolic input axis "); } // attributes are not normalized for this case. auto dds = input_shape.dyn_dims(); From bf908f8dfe6246e75798999e868bd771f6a87af8 Mon Sep 17 00:00:00 2001 From: charlie Date: Fri, 26 Jun 2026 14:31:56 -0500 Subject: [PATCH 6/8] Fix onnx test --- test/onnx/parse/slice_step_dyn_test.cpp | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/test/onnx/parse/slice_step_dyn_test.cpp b/test/onnx/parse/slice_step_dyn_test.cpp index bfc6819d595..603125d454b 100644 --- a/test/onnx/parse/slice_step_dyn_test.cpp +++ b/test/onnx/parse/slice_step_dyn_test.cpp @@ -26,9 +26,28 @@ TEST_CASE(slice_step_dyn_test) { - // A slice command with non-default steps will have a "Step" instruction added in parsing. - // At the time of writing, Step doesn't support dynamic shape input. + // A slice command with non-default steps will have a "step" instruction added in parsing. + // Slicing over a non-fixed dynamic dimension and the step op both support dynamic shapes, + // so parsing succeeds. + migraphx::program p; + auto* mm = p.get_main_module(); + auto l0 = + mm->add_parameter("0", migraphx::shape{migraphx::shape::float_type, {{1, 4}, {5, 5}}}); + // literals from parser + mm->add_literal({{migraphx::shape::int32_type, {2}}, {2, 1}}); + mm->add_literal({{migraphx::shape::int32_type, {2}}, {-1, -2}}); + mm->add_literal({{migraphx::shape::int32_type, {2}}, {-1, -1}}); + mm->add_literal({{migraphx::shape::int32_type, {2}}, {-5, -3}}); + auto slice_out = mm->add_instruction( + migraphx::make_op("slice", {{"axes", {-1, -2}}, {"starts", {-5, -3}}, {"ends", {-1, -1}}}), + l0); + auto step_out = mm->add_instruction( + migraphx::make_op("step", {{"axes", {-1, -2}}, {"steps", {2, 1}}}), slice_out); + mm->add_return({step_out}); + migraphx::onnx_options options; options.default_dyn_dim_value = {1, 4}; - EXPECT(test::throws([&] { read_onnx("slice_step_dyn_test.onnx", options); })); + auto prog = read_onnx("slice_step_dyn_test.onnx", options); + + EXPECT(p == prog); } From 3dcc98437b483e6b55f9796531b2168d9d7c567a Mon Sep 17 00:00:00 2001 From: charlie Date: Mon, 29 Jun 2026 12:08:30 -0500 Subject: [PATCH 7/8] Add comment about dimension bound. Licensing --- src/include/migraphx/op/slice.hpp | 3 ++- test/onnx/parse/slice_step_dyn_test.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/include/migraphx/op/slice.hpp b/src/include/migraphx/op/slice.hpp index bb5e69c7da8..9f1a1b316e0 100644 --- a/src/include/migraphx/op/slice.hpp +++ b/src/include/migraphx/op/slice.hpp @@ -282,7 +282,8 @@ struct slice MIGRAPHX_THROW( "SLICE 1_arg: slicing is not allowed on non-fixed symbolic input axis "); } - // attributes are not normalized for this case. + // Attributes are not normalized for this case, so they can be negative or out-of-bounds. + // Using a relaxed dimension bound for now instead of calculating the tightest possible bound. auto dds = input_shape.dyn_dims(); for(auto axis : this->axes) { diff --git a/test/onnx/parse/slice_step_dyn_test.cpp b/test/onnx/parse/slice_step_dyn_test.cpp index 603125d454b..d01e7e3acf5 100644 --- a/test/onnx/parse/slice_step_dyn_test.cpp +++ b/test/onnx/parse/slice_step_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-2026 Advanced Micro Devices, Inc. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal From 7388641c9faff507d005f670663ce13de2559c13 Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Mon, 29 Jun 2026 13:21:27 -0400 Subject: [PATCH 8/8] Update src/include/migraphx/op/slice.hpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- src/include/migraphx/op/slice.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/include/migraphx/op/slice.hpp b/src/include/migraphx/op/slice.hpp index 9f1a1b316e0..2654561c42b 100644 --- a/src/include/migraphx/op/slice.hpp +++ b/src/include/migraphx/op/slice.hpp @@ -282,8 +282,9 @@ struct slice MIGRAPHX_THROW( "SLICE 1_arg: slicing is not allowed on non-fixed symbolic input axis "); } - // Attributes are not normalized for this case, so they can be negative or out-of-bounds. - // Using a relaxed dimension bound for now instead of calculating the tightest possible bound. + // Attributes are not normalized for this case, so they can be negative or + // out-of-bounds. Using a relaxed dimension bound for now instead of calculating the + // tightest possible bound. auto dds = input_shape.dyn_dims(); for(auto axis : this->axes) {